summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/luametatex/source/lua/lmtfontlib.c14
-rw-r--r--source/luametatex/source/lua/lmtnodelib.c12
-rw-r--r--source/luametatex/source/lua/lmtstatuslib.c222
-rw-r--r--source/luametatex/source/lua/lmttexlib.c33
-rw-r--r--source/luametatex/source/luametatex.h2
-rw-r--r--source/luametatex/source/tex/texarithmetic.c30
-rw-r--r--source/luametatex/source/tex/texbuildpage.c18
-rw-r--r--source/luametatex/source/tex/texcommands.c3
-rw-r--r--source/luametatex/source/tex/texdumpdata.h2
-rw-r--r--source/luametatex/source/tex/texequivalents.c4
-rw-r--r--source/luametatex/source/tex/texequivalents.h4
-rw-r--r--source/luametatex/source/tex/texfont.c32
-rw-r--r--source/luametatex/source/tex/texlinebreak.c22
-rw-r--r--source/luametatex/source/tex/texlinebreak.h2
-rw-r--r--source/luametatex/source/tex/texmaincontrol.c40
-rw-r--r--source/luametatex/source/tex/texmath.c48
-rw-r--r--source/luametatex/source/tex/texmath.h59
-rw-r--r--source/luametatex/source/tex/texmlist.c187
-rw-r--r--source/luametatex/source/tex/texnesting.c2
-rw-r--r--source/luametatex/source/tex/texnodes.c17
-rw-r--r--source/luametatex/source/tex/texnodes.h3
-rw-r--r--source/luametatex/source/tex/texpackaging.c46
-rw-r--r--source/luametatex/source/tex/texprinting.c4
-rw-r--r--source/luametatex/source/tex/textextcodes.c2
-rw-r--r--source/luametatex/source/tex/textypes.h17
25 files changed, 506 insertions, 319 deletions
diff --git a/source/luametatex/source/lua/lmtfontlib.c b/source/luametatex/source/lua/lmtfontlib.c
index f743f960e..042772b32 100644
--- a/source/luametatex/source/lua/lmtfontlib.c
+++ b/source/luametatex/source/lua/lmtfontlib.c
@@ -263,7 +263,7 @@ static void fontlib_aux_font_char_from_lua(lua_State *L, halfword f, int i, int
set_charinfo_depth(co, target);
set_numeric_field_by_index(target, italic, 0);
set_charinfo_italic(co, target);
- set_numeric_field_by_index(target, expansion, 1000);
+ set_numeric_field_by_index(target, expansion, scaling_factor);
set_charinfo_expansion(co, target);
set_numeric_field_by_index(target, compression, target);
set_charinfo_compression(co, target);
@@ -631,15 +631,15 @@ static int lmt_font_from_lua(lua_State *L, int f)
if (fstep > 0) {
int fstretch = 0;
int fshrink = 0;
- if (fstep > 100) {
- fstep = 100;
+ if (fstep > max_font_adjust_step) {
+ fstep = max_font_adjust_step;
}
set_numeric_field_by_index(fshrink, shrink, 0);
set_numeric_field_by_index(fstretch, stretch, 0);
if (fshrink < 0) {
fshrink = 0;
- } else if (fshrink > 500) {
- fshrink = 500;
+ } else if (fshrink > max_font_adjust_shrink_factor) {
+ fshrink = max_font_adjust_shrink_factor;
}
fshrink -= (fshrink % fstep);
if (fshrink < 0) {
@@ -647,8 +647,8 @@ static int lmt_font_from_lua(lua_State *L, int f)
}
if (fstretch < 0) {
fstretch = 0;
- } else if (fstretch > 1000) {
- fstretch = 1000;
+ } else if (fstretch > max_font_adjust_stretch_factor) {
+ fstretch = max_font_adjust_stretch_factor;
}
fstretch -= (fstretch % fstep);
if (fstretch < 0) {
diff --git a/source/luametatex/source/lua/lmtnodelib.c b/source/luametatex/source/lua/lmtnodelib.c
index 66cf528fc..531d6d857 100644
--- a/source/luametatex/source/lua/lmtnodelib.c
+++ b/source/luametatex/source/lua/lmtnodelib.c
@@ -1704,19 +1704,19 @@ static int nodelib_direct_setscales(lua_State *L)
if (lua_type(L, 2) == LUA_TNUMBER) {
glyph_scale(n) = (halfword) lmt_roundnumber(L, 2);
if (! glyph_scale(n)) {
- glyph_scale(n) = 1000;
+ glyph_scale(n) = scaling_factor;
}
}
if (lua_type(L, 3) == LUA_TNUMBER) {
glyph_x_scale(n) = (halfword) lmt_roundnumber(L, 3);
if (! glyph_x_scale(n)) {
- glyph_x_scale(n) = 1000;
+ glyph_x_scale(n) = scaling_factor;
}
}
if (lua_type(L, 4) == LUA_TNUMBER) {
glyph_y_scale(n) = (halfword) lmt_roundnumber(L, 4);
if (! glyph_y_scale(n)) {
- glyph_y_scale(n) = 1000;
+ glyph_y_scale(n) = scaling_factor;
}
}
}
@@ -7134,17 +7134,17 @@ static int nodelib_common_setfield(lua_State *L, int direct, halfword n)
} else if (lua_key_eq(s, scale)) {
glyph_scale(n) = (halfword) lmt_roundnumber(L, 3);
if (! glyph_scale(n)) {
- glyph_scale(n) = 1000;
+ glyph_scale(n) = scaling_factor;
}
} else if (lua_key_eq(s, xscale)) {
glyph_x_scale(n) = (halfword) lmt_roundnumber(L, 3);
if (! glyph_x_scale(n)) {
- glyph_x_scale(n) = 1000;
+ glyph_x_scale(n) = scaling_factor;
}
} else if (lua_key_eq(s, yscale)) {
glyph_y_scale(n) = (halfword) lmt_roundnumber(L, 3);
if (! glyph_y_scale(n)) {
- glyph_y_scale(n) = 1000;
+ glyph_y_scale(n) = scaling_factor;
}
} else if (lua_key_eq(s, data)) {
glyph_data(n) = lmt_opthalfword(L, 3, unused_attribute_value);
diff --git a/source/luametatex/source/lua/lmtstatuslib.c b/source/luametatex/source/lua/lmtstatuslib.c
index 921832d8b..38e81c1c4 100644
--- a/source/luametatex/source/lua/lmtstatuslib.c
+++ b/source/luametatex/source/lua/lmtstatuslib.c
@@ -251,113 +251,121 @@ static int statslib_getconstants(lua_State *L)
{
lua_createtable(L, 0, 100);
- lua_set_integer_by_key(L, "no_catcode_table", no_catcode_table_preset);
- lua_set_integer_by_key(L, "default_catcode_table", default_catcode_table_preset);
-
- lua_set_cardinal_by_key(L,"max_cardinal", max_cardinal);
- lua_set_cardinal_by_key(L,"min_cardinal", min_cardinal);
- lua_set_integer_by_key(L, "max_integer", max_integer);
- lua_set_integer_by_key(L, "min_integer", min_integer);
- lua_set_integer_by_key(L, "max_dimen", max_dimen);
- lua_set_integer_by_key(L, "min_dimen", min_dimen);
- lua_set_integer_by_key(L, "min_data_value", min_data_value);
- lua_set_integer_by_key(L, "max_data_value", max_data_value);
- lua_set_integer_by_key(L, "max_half_value", max_half_value);
-
- lua_set_integer_by_key(L, "max_limited_scale", max_limited_scale);
-
- lua_set_integer_by_key(L, "one_bp", one_bp);
-
- lua_set_integer_by_key(L, "infinity", max_infinity);
- lua_set_integer_by_key(L, "min_infinity", min_infinity);
- lua_set_integer_by_key(L, "awful_bad", awful_bad);
- lua_set_integer_by_key(L, "infinite_bad", infinite_bad);
- lua_set_integer_by_key(L, "infinite_penalty", infinite_penalty);
- lua_set_integer_by_key(L, "eject_penalty", eject_penalty);
- lua_set_integer_by_key(L, "deplorable", deplorable);
- lua_set_integer_by_key(L, "large_width_excess", large_width_excess);
- lua_set_integer_by_key(L, "small_stretchability", small_stretchability);
- lua_set_integer_by_key(L, "decent_criterion", decent_criterion);
- lua_set_integer_by_key(L, "loose_criterion", loose_criterion);
-
- lua_set_integer_by_key(L, "default_rule", default_rule);
- lua_set_integer_by_key(L, "ignore_depth", ignore_depth);
-
- lua_set_integer_by_key(L, "min_quarterword", min_quarterword);
- lua_set_integer_by_key(L, "max_quarterword", max_quarterword);
-
- lua_set_integer_by_key(L, "min_halfword", min_halfword);
- lua_set_integer_by_key(L, "max_halfword", max_halfword);
-
- lua_set_integer_by_key(L, "null_flag", null_flag);
- lua_set_integer_by_key(L, "zero_glue", zero_glue);
- lua_set_integer_by_key(L, "unity", unity);
- lua_set_integer_by_key(L, "two", two);
- lua_set_integer_by_key(L, "null", null);
- lua_set_integer_by_key(L, "null_font", null_font);
-
- lua_set_integer_by_key(L, "unused_attribute_value", unused_attribute_value);
- lua_set_integer_by_key(L, "unused_state_value", unused_state_value);
- lua_set_integer_by_key(L, "unused_script_value", unused_script_value);
-
- lua_set_integer_by_key(L, "preset_rule_thickness", preset_rule_thickness);
- lua_set_integer_by_key(L, "running_rule", null_flag);
-
- lua_set_integer_by_key(L, "max_char_code", max_char_code);
- lua_set_integer_by_key(L, "min_space_factor", min_space_factor);
- lua_set_integer_by_key(L, "max_space_factor", max_space_factor);
- lua_set_integer_by_key(L, "default_space_factor", default_space_factor);
- lua_set_integer_by_key(L, "default_tolerance", default_tolerance);
- lua_set_integer_by_key(L, "default_hangafter", default_hangafter);
- lua_set_integer_by_key(L, "default_deadcycles", default_deadcycles);
- lua_set_integer_by_key(L, "default_pre_display_gap", default_pre_display_gap);
- lua_set_integer_by_key(L, "default_eqno_gap_step", default_eqno_gap_step);
-
- lua_set_integer_by_key(L, "default_output_box", default_output_box);
-
- lua_set_integer_by_key(L, "max_n_of_fonts", max_n_of_fonts);
- lua_set_integer_by_key(L, "max_n_of_bytecodes", max_n_of_bytecodes);
- lua_set_integer_by_key(L, "max_n_of_math_families", max_n_of_math_families);
- lua_set_integer_by_key(L, "max_n_of_languages", max_n_of_languages);
- lua_set_integer_by_key(L, "max_n_of_catcode_tables", max_n_of_catcode_tables);
- /* lua_set_integer_by_key(L, "max_n_of_hjcode_tables", max_n_of_hjcode_tables); */ /* meaningless */
- lua_set_integer_by_key(L, "max_n_of_marks", max_n_of_marks);
-
- lua_set_integer_by_key(L, "max_character_code", max_character_code);
- lua_set_integer_by_key(L, "max_mark_index", max_mark_index);
-
- lua_set_integer_by_key(L, "max_toks_register_index", max_toks_register_index);
- lua_set_integer_by_key(L, "max_box_register_index", max_box_register_index);
- lua_set_integer_by_key(L, "max_int_register_index", max_int_register_index);
- lua_set_integer_by_key(L, "max_float_register_index", max_posit_register_index);
- lua_set_integer_by_key(L, "max_dimen_register_index", max_dimen_register_index);
- lua_set_integer_by_key(L, "max_attribute_register_index", max_attribute_register_index);
- lua_set_integer_by_key(L, "max_glue_register_index", max_glue_register_index);
- lua_set_integer_by_key(L, "max_mu_glue_register_index", max_mu_glue_register_index);
-
- lua_set_integer_by_key(L, "max_bytecode_index", max_bytecode_index);
- lua_set_integer_by_key(L, "max_math_family_index", max_math_family_index);
- lua_set_integer_by_key(L, "max_math_class_code", max_math_class_code);
- lua_set_integer_by_key(L, "max_function_reference", max_function_reference);
- lua_set_integer_by_key(L, "max_category_code", max_category_code);
-
- lua_set_integer_by_key(L, "max_newline_character", max_newline_character);
-
- lua_set_integer_by_key(L, "max_size_of_word", max_size_of_word);
-
- lua_set_integer_by_key(L, "tex_hash_size", hash_size);
- lua_set_integer_by_key(L, "tex_hash_prime", hash_prime);
- lua_set_integer_by_key(L, "tex_eqtb_size", eqtb_size);
-
- lua_set_integer_by_key(L, "math_begin_class", math_begin_class);
- lua_set_integer_by_key(L, "math_end_class", math_end_class);
- lua_set_integer_by_key(L, "unused_math_family", unused_math_family);
- lua_set_integer_by_key(L, "unused_math_style", unused_math_style);
- lua_set_integer_by_key(L, "assumed_math_control", assumed_math_control);
-
- lua_set_integer_by_key(L, "undefined_math_parameter", undefined_math_parameter);
-
- lua_set_integer_by_key(L, "max_calculated_badness", max_calculated_badness);
+ lua_set_integer_by_key(L, "no_catcode_table", no_catcode_table_preset);
+ lua_set_integer_by_key(L, "default_catcode_table", default_catcode_table_preset);
+
+ lua_set_cardinal_by_key(L,"max_cardinal", max_cardinal);
+ lua_set_cardinal_by_key(L,"min_cardinal", min_cardinal);
+ lua_set_integer_by_key(L, "max_integer", max_integer);
+ lua_set_integer_by_key(L, "min_integer", min_integer);
+ lua_set_integer_by_key(L, "max_dimen", max_dimen);
+ lua_set_integer_by_key(L, "min_dimen", min_dimen);
+ lua_set_integer_by_key(L, "min_data_value", min_data_value);
+ lua_set_integer_by_key(L, "max_data_value", max_data_value);
+ lua_set_integer_by_key(L, "max_half_value", max_half_value);
+
+ lua_set_integer_by_key(L, "max_limited_scale", max_limited_scale);
+
+ lua_set_integer_by_key(L, "one_bp", one_bp);
+
+ lua_set_integer_by_key(L, "infinity", max_infinity);
+ lua_set_integer_by_key(L, "min_infinity", min_infinity);
+ lua_set_integer_by_key(L, "awful_bad", awful_bad);
+ lua_set_integer_by_key(L, "infinite_bad", infinite_bad);
+ lua_set_integer_by_key(L, "infinite_penalty", infinite_penalty);
+ lua_set_integer_by_key(L, "eject_penalty", eject_penalty);
+ lua_set_integer_by_key(L, "deplorable", deplorable);
+ lua_set_integer_by_key(L, "large_width_excess", large_width_excess);
+ lua_set_integer_by_key(L, "small_stretchability", small_stretchability);
+ lua_set_integer_by_key(L, "decent_criterion", decent_criterion);
+ lua_set_integer_by_key(L, "loose_criterion", loose_criterion);
+
+ lua_set_integer_by_key(L, "default_rule", default_rule);
+ lua_set_integer_by_key(L, "ignore_depth", ignore_depth);
+
+ lua_set_integer_by_key(L, "min_quarterword", min_quarterword);
+ lua_set_integer_by_key(L, "max_quarterword", max_quarterword);
+
+ lua_set_integer_by_key(L, "min_halfword", min_halfword);
+ lua_set_integer_by_key(L, "max_halfword", max_halfword);
+
+ lua_set_integer_by_key(L, "null_flag", null_flag);
+ lua_set_integer_by_key(L, "zero_glue", zero_glue);
+ lua_set_integer_by_key(L, "unity", unity);
+ lua_set_integer_by_key(L, "two", two);
+ lua_set_integer_by_key(L, "null", null);
+ lua_set_integer_by_key(L, "null_font", null_font);
+
+ lua_set_integer_by_key(L, "unused_attribute_value", unused_attribute_value);
+ lua_set_integer_by_key(L, "unused_state_value", unused_state_value);
+ lua_set_integer_by_key(L, "unused_script_value", unused_script_value);
+
+ lua_set_integer_by_key(L, "preset_rule_thickness", preset_rule_thickness);
+ lua_set_integer_by_key(L, "running_rule", null_flag);
+
+ lua_set_integer_by_key(L, "max_char_code", max_char_code);
+ lua_set_integer_by_key(L, "min_space_factor", min_space_factor);
+ lua_set_integer_by_key(L, "max_space_factor", max_space_factor);
+ lua_set_integer_by_key(L, "default_space_factor", default_space_factor);
+ lua_set_integer_by_key(L, "default_tolerance", default_tolerance);
+ lua_set_integer_by_key(L, "default_hangafter", default_hangafter);
+ lua_set_integer_by_key(L, "default_deadcycles", default_deadcycles);
+ lua_set_integer_by_key(L, "default_pre_display_gap", default_pre_display_gap);
+ lua_set_integer_by_key(L, "default_eqno_gap_step", default_eqno_gap_step);
+
+ lua_set_integer_by_key(L, "default_output_box", default_output_box);
+
+ lua_set_integer_by_key(L, "max_n_of_fonts", max_n_of_fonts);
+ lua_set_integer_by_key(L, "max_n_of_bytecodes", max_n_of_bytecodes);
+ lua_set_integer_by_key(L, "max_n_of_math_families", max_n_of_math_families);
+ lua_set_integer_by_key(L, "max_n_of_languages", max_n_of_languages);
+ lua_set_integer_by_key(L, "max_n_of_catcode_tables", max_n_of_catcode_tables);
+ /* lua_set_integer_by_key(L, "max_n_of_hjcode_tables", max_n_of_hjcode_tables); */ /* meaningless */
+ lua_set_integer_by_key(L, "max_n_of_marks", max_n_of_marks);
+
+ lua_set_integer_by_key(L, "max_character_code", max_character_code);
+ lua_set_integer_by_key(L, "max_mark_index", max_mark_index);
+
+ lua_set_integer_by_key(L, "max_toks_register_index", max_toks_register_index);
+ lua_set_integer_by_key(L, "max_box_register_index", max_box_register_index);
+ lua_set_integer_by_key(L, "max_int_register_index", max_int_register_index);
+ lua_set_integer_by_key(L, "max_float_register_index", max_posit_register_index);
+ lua_set_integer_by_key(L, "max_dimen_register_index", max_dimen_register_index);
+ lua_set_integer_by_key(L, "max_attribute_register_index", max_attribute_register_index);
+ lua_set_integer_by_key(L, "max_glue_register_index", max_glue_register_index);
+ lua_set_integer_by_key(L, "max_mu_glue_register_index", max_mu_glue_register_index);
+
+ lua_set_integer_by_key(L, "max_bytecode_index", max_bytecode_index);
+ lua_set_integer_by_key(L, "max_math_family_index", max_math_family_index);
+ lua_set_integer_by_key(L, "max_math_class_code", max_math_class_code);
+ lua_set_integer_by_key(L, "max_function_reference", max_function_reference);
+ lua_set_integer_by_key(L, "max_category_code", max_category_code);
+
+ lua_set_integer_by_key(L, "max_newline_character", max_newline_character);
+
+ lua_set_integer_by_key(L, "max_size_of_word", max_size_of_word);
+
+ lua_set_integer_by_key(L, "tex_hash_size", hash_size);
+ lua_set_integer_by_key(L, "tex_hash_prime", hash_prime);
+ lua_set_integer_by_key(L, "tex_eqtb_size", eqtb_size);
+
+ lua_set_integer_by_key(L, "math_begin_class", math_begin_class);
+ lua_set_integer_by_key(L, "math_end_class", math_end_class);
+ lua_set_integer_by_key(L, "unused_math_family", unused_math_family);
+ lua_set_integer_by_key(L, "unused_math_style", unused_math_style);
+ lua_set_integer_by_key(L, "assumed_math_control", assumed_math_control);
+
+ lua_set_integer_by_key(L, "undefined_math_parameter", undefined_math_parameter);
+
+ lua_set_integer_by_key(L, "max_calculated_badness", max_calculated_badness);
+
+ lua_set_integer_by_key(L, "max_math_scaling_factor", max_math_scaling_factor);
+ lua_set_integer_by_key(L, "math_default_penalty", math_default_penalty);
+
+ lua_set_integer_by_key(L, "max_font_adjust_step", max_font_adjust_step);
+ lua_set_integer_by_key(L, "max_font_adjust_stretch_factor", max_font_adjust_stretch_factor);
+ lua_set_integer_by_key(L, "max_font_adjust_shrink_factor", max_font_adjust_shrink_factor);
+
return 1;
}
diff --git a/source/luametatex/source/lua/lmttexlib.c b/source/luametatex/source/lua/lmttexlib.c
index 4f2ecbb5c..603454bfe 100644
--- a/source/luametatex/source/lua/lmttexlib.c
+++ b/source/luametatex/source/lua/lmttexlib.c
@@ -1077,21 +1077,21 @@ static const char *texlib_aux_scan_dimen_part(lua_State * L, const char *ss, int
goto ATTACH_FRACTION;
}
SPECIAL:
- result = tex_nx_plus_y(result, special, tex_xn_over_d_r(special, fraction, 0200000, &remainder));
+ result = tex_nx_plus_y(result, special, tex_xn_over_d_r(special, fraction, 0x10000, &remainder));
goto DONE;
CONVERSION:
result = tex_xn_over_d_r(result, numerator, denominator, &remainder);
- fraction = (numerator * fraction + 0200000 * remainder) / denominator;
- result = result + (fraction / 0200000);
- fraction = fraction % 0200000;
+ fraction = (numerator * fraction + 0x10000 * remainder) / denominator;
+ result = result + (fraction / 0x10000);
+ fraction = fraction % 0x10000;
ATTACH_FRACTION:
- if (result >= 040000) {
+ if (result >= 0x4000) {
lmt_scanner_state.arithmic_error = 1;
} else {
- result = result * 65536 + fraction;
+ result = result * 0x10000 + fraction;
}
DONE:
- if (lmt_scanner_state.arithmic_error || (abs(result) >= 010000000000)) {
+ if (lmt_scanner_state.arithmic_error || (abs(result) >= 0x40000000)) {
result = max_dimen;
luaL_error(L, "dimension too large");
}
@@ -3855,15 +3855,15 @@ static int texlib_preparelinebreak(lua_State *L)
halfword parinit_right_skip_glue = null;
halfword parfill_left_skip_glue = null;
halfword parfill_right_skip_glue = null;
- halfword final_penalty = null;
- tex_line_break_prepare(par, &tail, &parinit_left_skip_glue, &parinit_right_skip_glue, &parfill_left_skip_glue, &parfill_right_skip_glue, &final_penalty);
+ halfword final_line_penalty = null;
+ tex_line_break_prepare(par, &tail, &parinit_left_skip_glue, &parinit_right_skip_glue, &parfill_left_skip_glue, &parfill_right_skip_glue, &final_line_penalty);
lmt_push_directornode(L, par, direct);
lmt_push_directornode(L, tail, direct);
lmt_push_directornode(L, parinit_left_skip_glue, direct);
lmt_push_directornode(L, parinit_right_skip_glue, direct);
lmt_push_directornode(L, parfill_left_skip_glue , direct);
lmt_push_directornode(L, parfill_right_skip_glue, direct);
- /* lmt_push_directornode(L, final_penalty, direct); */ /*tex Not that relevant to know. */
+ /* lmt_push_directornode(L, final_line_penalty, direct); */ /*tex Not that relevant to know. */
return 6;
}
}
@@ -4021,7 +4021,7 @@ static int texlib_linebreak(lua_State *L)
get_penalties_par(properties.orphan_penalties, orphanpenalties, tex_get_par_par(par, par_orphan_penalties_code), orphan_penalties_code);
if (! prepared) {
halfword attr_template = tail;
- halfword final_penalty = tex_new_penalty_node(infinite_penalty, line_penalty_subtype);
+ halfword final_line_penalty = tex_new_penalty_node(infinite_penalty, line_penalty_subtype);
/* */
get_glue_par(properties.parfill_left_skip, parfillleftskip, tex_get_par_par(par, par_par_fill_left_skip_code));
get_glue_par(properties.parfill_right_skip, parfillrightskip, tex_get_par_par(par, par_par_fill_right_skip_code));
@@ -4030,11 +4030,11 @@ static int texlib_linebreak(lua_State *L)
/* */
properties.parfill_left_skip = tex_new_glue_node(properties.parfill_left_skip, par_fill_left_skip_glue);
properties.parfill_right_skip = tex_new_glue_node(properties.parfill_right_skip, par_fill_right_skip_glue);
- tex_attach_attribute_list_copy(final_penalty, attr_template);
+ tex_attach_attribute_list_copy(final_line_penalty, attr_template);
tex_attach_attribute_list_copy(properties.parfill_left_skip, attr_template);
tex_attach_attribute_list_copy(properties.parfill_right_skip, attr_template);
- tex_couple_nodes(tail, final_penalty);
- tex_couple_nodes(final_penalty, properties.parfill_left_skip);
+ tex_couple_nodes(tail, final_line_penalty);
+ tex_couple_nodes(final_line_penalty, properties.parfill_left_skip);
tex_couple_nodes(properties.parfill_left_skip, properties.parfill_right_skip);
if (node_next(par)) { /* test can go, also elsewhere */
halfword n = node_next(par);
@@ -5178,7 +5178,7 @@ static int texlib_getspecialmathclassvalues(lua_State *L)
static int texlib_getmathclassoptionvalues(lua_State *L)
{
- lua_createtable(L, 2, 20);
+ lua_createtable(L, 2, 25);
lua_set_string_by_index(L, no_pre_slack_class_option, "nopreslack");
lua_set_string_by_index(L, no_post_slack_class_option, "nopostslack");
lua_set_string_by_index(L, left_top_kern_class_option, "lefttopkern");
@@ -5206,6 +5206,9 @@ static int texlib_getmathclassoptionvalues(lua_State *L)
lua_set_string_by_index(L, remove_italic_correction_class_option, "removeitaliccorrection");
lua_set_string_by_index(L, operator_italic_correction_class_option, "operatoritaliccorrection");
lua_set_string_by_index(L, short_inline_class_option, "shortinline");
+ lua_set_string_by_index(L, push_nesting_class_option, "pushnesting");
+ lua_set_string_by_index(L, pop_nesting_class_option, "popnesting");
+ lua_set_string_by_index(L, obey_nesting_class_option, "obeynesting");
return 1;
}
diff --git a/source/luametatex/source/luametatex.h b/source/luametatex/source/luametatex.h
index a6e9b5295..68820d24d 100644
--- a/source/luametatex/source/luametatex.h
+++ b/source/luametatex/source/luametatex.h
@@ -92,7 +92,7 @@
# define luametatex_version 210
# define luametatex_revision 9
# define luametatex_version_string "2.10.09"
-# define luametatex_development_id 20230530
+# define luametatex_development_id 20230531
# define luametatex_name_camelcase "LuaMetaTeX"
# define luametatex_name_lowercase "luametatex"
diff --git a/source/luametatex/source/tex/texarithmetic.c b/source/luametatex/source/tex/texarithmetic.c
index d9cf9859d..3a53985d5 100644
--- a/source/luametatex/source/tex/texarithmetic.c
+++ b/source/luametatex/source/tex/texarithmetic.c
@@ -196,13 +196,13 @@ scaled tex_xn_over_d_r(scaled x, int n, int d, int *remainder)
}
xx = (unsigned int) x;
dd = (unsigned int) d;
- t = ((xx % 0100000) * (unsigned int) n);
- u = ((xx / 0100000) * (unsigned int) n + (t / 0100000));
- v = (u % dd) * 0100000 + (t % 0100000);
- if (u / dd >= 0100000) {
+ t = ((xx % 0x8000) * (unsigned int) n);
+ u = ((xx / 0x8000) * (unsigned int) n + (t / 0x8000));
+ v = (u % dd) * 0x8000 + (t % 0x8000);
+ if (u / dd >= 0x8000) {
lmt_scanner_state.arithmic_error = 1;
} else {
- u = 0100000 * (u / dd) + (v / dd);
+ u = 0x8000 * (u / dd) + (v / dd);
}
if (positive) {
if (remainder) {
@@ -245,13 +245,13 @@ scaled tex_xn_over_d(scaled x, int n, int d)
}
xx = (unsigned int) x;
dd = (unsigned int) d;
- t = ((xx % 0100000) * (unsigned int) n);
- u = ((xx / 0100000) * (unsigned int) n + (t / 0100000));
- v = (u % dd) * 0100000 + (t % 0100000);
- if (u / dd >= 0100000) {
+ t = ((xx % 0x8000) * (unsigned int) n);
+ u = ((xx / 0x8000) * (unsigned int) n + (t / 0x8000));
+ v = (u % dd) * 0x8000 + (t % 0x8000);
+ if (u / dd >= 0x8000) {
lmt_scanner_state.arithmic_error = 1;
} else {
- u = 0100000 * (u / dd) + (v / dd);
+ u = 0x8000 * (u / dd) + (v / dd);
}
if (positive) {
return (scaled) u;
@@ -306,13 +306,13 @@ scaled tex_round_xn_over_d(scaled x, int n, unsigned int d)
positive = ! positive;
n = -n;
}
- t = (unsigned) ((x % 0100000) * n);
- u = (unsigned) (((unsigned) (x) / 0100000) * (unsigned) n + (t / 0100000));
- v = (u % d) * 0100000 + (t % 0100000);
- if (u / d >= 0100000) {
+ t = (unsigned) ((x % 0x8000) * n);
+ u = (unsigned) (((unsigned) (x) / 0x8000) * (unsigned) n + (t / 0x8000));
+ v = (u % d) * 0x8000 + (t % 0x8000);
+ if (u / d >= 0x8000) {
scanner_state.arithmic_error = 1;
} else {
- u = 0100000 * (u / d) + (v / d);
+ u = 0x8000 * (u / d) + (v / d);
}
v = v % d;
if (2 * v >= d) {
diff --git a/source/luametatex/source/tex/texbuildpage.c b/source/luametatex/source/tex/texbuildpage.c
index a2d9051db..6773ed52b 100644
--- a/source/luametatex/source/tex/texbuildpage.c
+++ b/source/luametatex/source/tex/texbuildpage.c
@@ -600,10 +600,10 @@ void tex_build_page(void)
box_height(location) = 0;
}
split_best_insert(location) = null;
- if (multiplier == 1000) {
+ if (multiplier == scaling_factor) {
advance = box_height(location);
} else {
- advance = tex_x_over_n(box_height(location), 1000) * multiplier;
+ advance = tex_x_over_n(box_height(location), scaling_factor) * multiplier;
}
advance += glue_amount(distance);
update_page_goal(index, 0, advance); /*tex Here gets no height added! */
@@ -633,9 +633,9 @@ void tex_build_page(void)
scaled needed = insert_total_height(current);
split_last_insert(location) = current;
/*tex This much room is left if we shrink the maximum. */
- if (multiplier != 1000) {
+ if (multiplier != scaling_factor) {
/*tex This much room is needed. */
- needed = tex_x_over_n(needed, 1000) * multiplier;
+ needed = tex_x_over_n(needed, scaling_factor) * multiplier;
}
if ((needed <= 0 || needed <= delta) && (insert_total_height(current) + box_height(location) <= limit)) {
update_page_goal(index, insert_total_height(current), needed);
@@ -665,8 +665,8 @@ void tex_build_page(void)
height = max_dimen;
} else {
height = page_goal - page_total - page_depth;
- if (multiplier != 1000) {
- height = tex_x_over_n(height, multiplier) * 1000;
+ if (multiplier != scaling_factor) {
+ height = tex_x_over_n(height, multiplier) * scaling_factor;
}
}
if (height > limit - box_height(location)) {
@@ -678,8 +678,8 @@ void tex_build_page(void)
if (tracing_pages_par > 0) {
tex_aux_display_insertion_split_cost(index, height, penalty);
}
- if (multiplier != 1000) {
- lmt_packaging_state.best_height_plus_depth = tex_x_over_n(lmt_packaging_state.best_height_plus_depth, 1000) * multiplier;
+ if (multiplier != scaling_factor) {
+ lmt_packaging_state.best_height_plus_depth = tex_x_over_n(lmt_packaging_state.best_height_plus_depth, scaling_factor) * multiplier;
}
update_page_goal(index, lmt_packaging_state.best_height_plus_depth, lmt_packaging_state.best_height_plus_depth);
node_subtype(location) = insert_split_subtype;
@@ -736,7 +736,7 @@ void tex_build_page(void)
} else {
criterion = deplorable;
}
- if (lmt_page_builder_state.insert_penalties >= 10000) {
+ if (lmt_page_builder_state.insert_penalties >= infinite_penalty) {
criterion = awful_bad;
}
{
diff --git a/source/luametatex/source/tex/texcommands.c b/source/luametatex/source/tex/texcommands.c
index 1423c80d0..ae22f9794 100644
--- a/source/luametatex/source/tex/texcommands.c
+++ b/source/luametatex/source/tex/texcommands.c
@@ -270,6 +270,8 @@ void tex_initialize_commands(void)
tex_primitive(luatex_command, "mathendclass", internal_int_cmd, math_end_class_code, internal_int_base);
tex_primitive(luatex_command, "mathleftclass", internal_int_cmd, math_left_class_code, internal_int_base);
tex_primitive(luatex_command, "mathrightclass", internal_int_cmd, math_right_class_code, internal_int_base);
+ tex_primitive(luatex_command, "mathdisplaypenaltyfactor", internal_int_cmd, math_display_penalty_factor_code, internal_int_base);
+ tex_primitive(luatex_command, "mathinlinepenaltyfactor", internal_int_cmd, math_inline_penalty_factor_code, internal_int_base);
tex_primitive(luatex_command, "supmarkmode", internal_int_cmd, sup_mark_mode_code, internal_int_base);
tex_primitive(luatex_command, "overloadmode", internal_int_cmd, overload_mode_code, internal_int_base);
tex_primitive(luatex_command, "autoparagraphmode", internal_int_cmd, auto_paragraph_mode_code, internal_int_base);
@@ -347,6 +349,7 @@ void tex_initialize_commands(void)
tex_primitive(luatex_command, "protrusionboundary", boundary_cmd, protrusion_boundary, 0);
tex_primitive(luatex_command, "wordboundary", boundary_cmd, word_boundary, 0);
tex_primitive(luatex_command, "pageboundary", boundary_cmd, page_boundary, 0);
+ tex_primitive(luatex_command, "mathboundary", boundary_cmd, math_boundary, 0);
/* tex_primitive(luatex_command, "parboundary", boundary_cmd, par_boundary, 0); */
tex_primitive(tex_command, "penalty", penalty_cmd, normal_penalty_code, 0);
diff --git a/source/luametatex/source/tex/texdumpdata.h b/source/luametatex/source/tex/texdumpdata.h
index c0a55c2fe..94a153374 100644
--- a/source/luametatex/source/tex/texdumpdata.h
+++ b/source/luametatex/source/tex/texdumpdata.h
@@ -55,7 +55,7 @@
*/
-# define luametatex_format_fingerprint 691
+# define luametatex_format_fingerprint 692
/* These end up in the string pool. */
diff --git a/source/luametatex/source/tex/texequivalents.c b/source/luametatex/source/tex/texequivalents.c
index 4f8f789b7..036a4a3d5 100644
--- a/source/luametatex/source/tex/texequivalents.c
+++ b/source/luametatex/source/tex/texequivalents.c
@@ -1535,6 +1535,10 @@ void tex_save_for_after_group(halfword t)
void tex_unsave(void)
{
if (end_of_group_par) {
+ /*tex
+ This is not yet always ok, and looks like we can get weird commands (in some group
+ ending situations)! But I need a better example of a failure. (low priority)
+ */
tex_begin_inserted_list(tex_get_available_token(token_val(end_local_cmd, 0)));
tex_begin_token_list(end_of_group_par, end_of_group_text);
if (tracing_nesting_par > 2) {
diff --git a/source/luametatex/source/tex/texequivalents.h b/source/luametatex/source/tex/texequivalents.h
index 384a17e06..af3d98000 100644
--- a/source/luametatex/source/tex/texequivalents.h
+++ b/source/luametatex/source/tex/texequivalents.h
@@ -561,6 +561,8 @@ typedef enum int_codes {
math_end_class_code,
math_left_class_code,
math_right_class_code,
+ math_inline_penalty_factor_code,
+ math_display_penalty_factor_code,
sup_mark_mode_code,
par_direction_code,
text_direction_code,
@@ -1659,6 +1661,8 @@ typedef enum hyphenation_mode_bits {
# define math_left_class_par count_parameter(math_left_class_code)
# define math_right_class_par count_parameter(math_right_class_code)
# define sup_mark_mode_par count_parameter(sup_mark_mode_code)
+# define math_display_penalty_factor_par count_parameter(math_display_penalty_factor_code)
+# define math_inline_penalty_factor_par count_parameter(math_inline_penalty_factor_code)
# define glyph_data_par count_parameter(glyph_data_code)
# define glyph_state_par count_parameter(glyph_state_code)
diff --git a/source/luametatex/source/tex/texfont.c b/source/luametatex/source/tex/texfont.c
index b274b3ae9..33445122b 100644
--- a/source/luametatex/source/tex/texfont.c
+++ b/source/luametatex/source/tex/texfont.c
@@ -342,7 +342,7 @@ charinfo *tex_get_charinfo(halfword f, int c)
if (tglyph >= lmt_font_state.fonts[f]->chardata_size) {
tex_font_malloc_charinfo(f, 256);
}
- lmt_font_state.fonts[f]->chardata[tglyph].expansion = 1000;
+ lmt_font_state.fonts[f]->chardata[tglyph].expansion = scaling_factor;
sa_value.int_value = tglyph;
/*tex 1 means global */
sa_set_item_4(lmt_font_state.fonts[f]->characters, c, sa_value, 1);
@@ -495,7 +495,7 @@ int tex_get_math_char(halfword f, int c, int size, scaled *scale, int direction)
if (scale) {
*scale = tex_get_math_font_scale(f, size);
if (! *scale) {
- *scale = 1000;
+ *scale = scaling_factor;
}
}
return c;
@@ -826,18 +826,18 @@ halfword tex_checked_font_adjust(halfword adjust_spacing, halfword adjust_spacin
lmt_font_state.adjust_step = adjust_spacing_step;
lmt_font_state.adjust_shrink = adjust_spacing_shrink;
lmt_font_state.adjust_stretch = adjust_spacing_stretch;
- if (lmt_font_state.adjust_step > 100) {
- lmt_font_state.adjust_step = 100;
+ if (lmt_font_state.adjust_step > max_font_adjust_step) {
+ lmt_font_state.adjust_step = max_font_adjust_step;
}
if (lmt_font_state.adjust_shrink < 0) {
lmt_font_state.adjust_shrink = 0;
- } else if (lmt_font_state.adjust_shrink > 500) {
- lmt_font_state.adjust_shrink = 500;
+ } else if (lmt_font_state.adjust_shrink > max_font_adjust_shrink_factor) {
+ lmt_font_state.adjust_shrink = max_font_adjust_shrink_factor;
}
if (lmt_font_state.adjust_stretch < 0) {
lmt_font_state.adjust_stretch = 0;
- } else if (lmt_font_state.adjust_stretch > 1000) {
- lmt_font_state.adjust_stretch = 1000;
+ } else if (lmt_font_state.adjust_stretch > max_font_adjust_stretch_factor) {
+ lmt_font_state.adjust_stretch = max_font_adjust_stretch_factor;
}
return adjust_spacing;
}
@@ -1651,7 +1651,7 @@ int tex_tex_def_font(int a)
/*tex This runs through existing fonts. */
halfword f;
/*tex Stated 'at' size, or negative of scaled magnification. */
- scaled s = -1000;
+ scaled s = -scaling_factor;
char *fn;
/*tex Here |a| determines if we define global or not. */
if (is_global(a)) {
@@ -1665,7 +1665,7 @@ int tex_tex_def_font(int a)
if (tex_scan_keyword("at")) {
/*tex Put the positive 'at' size into |s|. */
s = tex_scan_dimen(0, 0, 0, 0, NULL);
- if ((s <= 0) || (s >= 01000000000)) {
+ if ((s <= 0) || (s >= 0x8000000)) {
tex_handle_error(
normal_error_type,
"Improper 'at' size (%D), replaced by 10pt",
@@ -1678,14 +1678,14 @@ int tex_tex_def_font(int a)
}
} else if (tex_scan_keyword("scaled")) {
s = tex_scan_int(0, NULL);
- if ((s <= 0) || (s > 32768)) {
+ if ((s <= 0) || (s > 0x8000)) {
tex_handle_error(
normal_error_type,
"Illegal magnification has been changed to 1000 (%i)",
s,
"The magnification ratio must be between 1 and 32768."
);
- s = -1000;
+ s = -scaling_factor;
} else {
s = -s;
}
@@ -2021,14 +2021,14 @@ scaled tex_char_width_italic_from_glyph(halfword g)
scaled tex_calculated_char_width(halfword f, halfword c, halfword ex)
{
scaled wd = tex_aux_char_info(f, c)->width;
- return ex ? tex_round_xn_over_d(wd, 1000 + ex, 1000) : wd;
+ return ex ? tex_round_xn_over_d(wd, scaling_factor + ex, scaling_factor) : wd;
}
scaled tex_calculated_glyph_width(halfword g, halfword ex)
{
charinfo *ci = tex_aux_char_info(glyph_font(g), glyph_character(g));
scaled wd = tex_aux_glyph_x_scaled(g, ci->width);
- return ex ? tex_round_xn_over_d(wd, 1000 + ex, 1000) : wd;
+ return ex ? tex_round_xn_over_d(wd, scaling_factor + ex, scaling_factor) : wd;
}
/* Checkers: */
@@ -2101,13 +2101,13 @@ void tex_set_font_original(halfword f, const char *s)
scaled tex_get_math_font_scale(halfword f, halfword size)
{
- scaled scale = 1000;
+ scaled scale = scaling_factor;
switch (size) {
case 2: scale = lmt_font_state.fonts[f]->mathscales[2] ? lmt_font_state.fonts[f]->mathscales[2] : glyph_scriptscript_scale_par; break;
case 1: scale = lmt_font_state.fonts[f]->mathscales[1] ? lmt_font_state.fonts[f]->mathscales[1] : glyph_script_scale_par; break;
case 0: scale = lmt_font_state.fonts[f]->mathscales[0] ? lmt_font_state.fonts[f]->mathscales[0] : glyph_text_scale_par; break;
}
- return scale ? scale : 1000;
+ return scale ? scale : scaling_factor;
}
/*tex
diff --git a/source/luametatex/source/tex/texlinebreak.c b/source/luametatex/source/tex/texlinebreak.c
index 93a537ca7..48cf470eb 100644
--- a/source/luametatex/source/tex/texlinebreak.c
+++ b/source/luametatex/source/tex/texlinebreak.c
@@ -147,7 +147,7 @@ void tex_line_break_prepare(
halfword *parinit_right_skip_glue,
halfword *parfill_left_skip_glue,
halfword *parfill_right_skip_glue,
- halfword *final_penalty
+ halfword *final_line_penalty
)
{
/* too much testing of next */
@@ -159,7 +159,7 @@ void tex_line_break_prepare(
tex_end_diagnostic();
}
*tail = *tail ? *tail : tex_tail_of_node_list(par);
- *final_penalty = tex_new_penalty_node(infinite_penalty, line_penalty_subtype);
+ *final_line_penalty = tex_new_penalty_node(infinite_penalty, line_penalty_subtype);
*parfill_left_skip_glue = tex_new_glue_node(tex_get_par_par(par, par_par_fill_left_skip_code), par_fill_left_skip_glue);
*parfill_right_skip_glue = tex_new_glue_node(tex_get_par_par(par, par_par_fill_right_skip_code), par_fill_right_skip_glue);
*parinit_left_skip_glue = null;
@@ -170,11 +170,11 @@ void tex_line_break_prepare(
tex_flush_node(*tail);
*tail = prev;
}
- tex_attach_attribute_list_copy(*final_penalty, par);
+ tex_attach_attribute_list_copy(*final_line_penalty, par);
tex_attach_attribute_list_copy(*parfill_left_skip_glue, par);
tex_attach_attribute_list_copy(*parfill_right_skip_glue, par);
- tex_try_couple_nodes(*tail, *final_penalty);
- tex_try_couple_nodes(*final_penalty, *parfill_left_skip_glue);
+ tex_try_couple_nodes(*tail, *final_line_penalty);
+ tex_try_couple_nodes(*final_line_penalty, *parfill_left_skip_glue);
tex_try_couple_nodes(*parfill_left_skip_glue, *parfill_right_skip_glue);
*tail = *parfill_right_skip_glue;
if (node_next(par)) {
@@ -247,8 +247,8 @@ void tex_line_break(int d, int line_break_context)
halfword parinit_right_skip_glue = null;
halfword parfill_left_skip_glue = null;
halfword parfill_right_skip_glue = null;
- halfword final_penalty = null;
- tex_line_break_prepare(par, &tail, &parinit_left_skip_glue, &parinit_right_skip_glue, &parfill_left_skip_glue, &parfill_right_skip_glue, &final_penalty);
+ halfword final_line_penalty = null;
+ tex_line_break_prepare(par, &tail, &parinit_left_skip_glue, &parinit_right_skip_glue, &parfill_left_skip_glue, &parfill_right_skip_glue, &final_line_penalty);
cur_list.tail = tail;
/*tex
We start with a prepared list. If you mess with that the linebreak routine might not
@@ -1479,9 +1479,9 @@ halfword tex_badness(scaled t, scaled s)
} else {
/*tex 297*297*297 == 26198073 / 100 => 261981 */
/*tex This is $t^3 / 2^{18}$, rounded to the nearest integer */
- return (t * t * t + 0400000) / 01000000; /* 0400000/01000000 == 1/2 */
+ // return (t * t * t + 0400000) / 01000000; /* 0400000/01000000 == 1/2 */
// return (t * t * t + 0x20000) / 0x40000;
- // return (t * t * t + 131072) / 262144;
+ return (t * t * t + 131072) / 262144;
}
}
}
@@ -2046,8 +2046,8 @@ static void tex_aux_try_break(
} else {
/*tex Compute the demerits, |d|, from |r| to |cur_p|. */
demerits = properties->line_penalty + badness;
- if (abs(demerits) >= 10000) {
- demerits = 100000000;
+ if (abs(demerits) >= infinite_bad) {
+ demerits = extremely_deplorable;
} else {
demerits = demerits * demerits;
}
diff --git a/source/luametatex/source/tex/texlinebreak.h b/source/luametatex/source/tex/texlinebreak.h
index 850d98da0..cf551bebe 100644
--- a/source/luametatex/source/tex/texlinebreak.h
+++ b/source/luametatex/source/tex/texlinebreak.h
@@ -121,7 +121,7 @@ void tex_line_break_prepare (
halfword *parinit_right_skip_glue,
halfword *parfill_left_skip_glue,
halfword *parfill_right_skip_glue,
- halfword *final_penalty
+ halfword *final_line_penalty
);
extern void tex_line_break (
diff --git a/source/luametatex/source/tex/texmaincontrol.c b/source/luametatex/source/tex/texmaincontrol.c
index c51a636b3..29b652ab7 100644
--- a/source/luametatex/source/tex/texmaincontrol.c
+++ b/source/luametatex/source/tex/texmaincontrol.c
@@ -429,8 +429,8 @@ static void tex_aux_run_space(void) {
if (cur_list.space_factor >= 2000) {
glue_amount(p) += tex_get_scaled_extra_space(cur_font);
}
- glue_stretch(p) = tex_xn_over_d(glue_stretch(p), cur_list.space_factor, 1000);
- glue_shrink(p) = tex_xn_over_d(glue_shrink(p), 1000, cur_list.space_factor);
+ glue_stretch(p) = tex_xn_over_d(glue_stretch(p), cur_list.space_factor, scaling_factor);
+ glue_shrink(p) = tex_xn_over_d(glue_shrink(p), scaling_factor, cur_list.space_factor);
}
} else if (tex_glue_is_zero(space_skip_par)) {
/*tex Find the glue specification for text spaces in the current font. */
@@ -1216,11 +1216,27 @@ static void tex_aux_run_math_boundary(void) {
switch (cur_chr) {
case user_boundary:
{
- halfword n = tex_new_node(boundary_node, user_boundary);
+ halfword n = tex_new_node(boundary_node, cur_chr);
boundary_data(n) = tex_scan_int(0, NULL);
tex_tail_append(n);
break;
}
+ case math_boundary:
+ {
+ halfword n = tex_new_node(boundary_node, cur_chr);
+ boundary_data(n) = tex_scan_int(0, NULL);
+ switch (boundary_data(n)) {
+ case 0: case 1:
+ /* valid */
+ break;
+ case 2: case 3:
+ /* valid, penalty to add */
+ boundary_reserved(n) = tex_scan_int(0, NULL);
+ break;
+ }
+ tex_tail_append(n);
+ break;
+ }
case protrusion_boundary:
case page_boundary:
/*tex We just ignore the values. */
@@ -2006,17 +2022,19 @@ static void tex_aux_run_end_job(void) {
if ((page_head == lmt_page_builder_state.page_tail)
&& (cur_list.head == cur_list.tail)
&& (lmt_page_builder_state.dead_cycles == 0)) {
- /*tex this is the only way out */
+ /*tex This is the only way out. */
lmt_main_control_state.control_state = goto_return_state;
} else {
- /*tex we will try to end again after ejecting residual material */
+ /*tex
+ We will try to end again after ejecting residual material and append |\hbox to \hsize
+ {}\vfill\penalty-'10000000000|.
+ */
tex_back_input(cur_tok);
tex_tail_append(tex_new_null_box_node(hlist_node, unknown_list));
box_width(cur_list.tail) = hsize_par;
tex_tail_append(tex_new_glue_node(fill_glue, user_skip_glue)); /* todo: subtype, final_skip_glue? */
- tex_tail_append(tex_new_penalty_node(-010000000000, final_penalty_subtype)); /* -0x40000000 */
+ tex_tail_append(tex_new_penalty_node(final_penalty, final_penalty_subtype));
lmt_page_filter_callback(end_page_context, 0);
- /*tex append |\hbox to \hsize{}\vfill\penalty-'10000000000| */
tex_build_page();
}
}
@@ -6697,15 +6715,17 @@ void tex_initialize_variables(void)
math_double_script_mode_par = -1,
math_glue_mode_par = default_math_glue_mode;
hyphenation_mode_par = default_hyphenation_mode;
- glyph_scale_par = 1000;
- glyph_x_scale_par = 1000;
- glyph_y_scale_par = 1000;
+ glyph_scale_par = scaling_factor;
+ glyph_x_scale_par = scaling_factor;
+ glyph_y_scale_par = scaling_factor;
glyph_x_offset_par = 0;
glyph_y_offset_par = 0;
math_begin_class_par = math_begin_class;
math_end_class_par = math_end_class;
math_left_class_par = unset_noad_class;
math_right_class_par = unset_noad_class;
+ math_display_penalty_factor_par = scaling_factor;
+ math_inline_penalty_factor_par = scaling_factor;
pre_inline_penalty_par = max_integer;
post_inline_penalty_par = max_integer;
pre_short_inline_penalty_par = max_integer;
diff --git a/source/luametatex/source/tex/texmath.c b/source/luametatex/source/tex/texmath.c
index 923ffa56e..e93714000 100644
--- a/source/luametatex/source/tex/texmath.c
+++ b/source/luametatex/source/tex/texmath.c
@@ -120,7 +120,7 @@ math_state_info lmt_math_state = {
.last_left = 0,
.last_right = 0,
.last_atom = 0,
- .scale = 1000,
+ .scale = scaling_factor,
};
static int tex_aux_scan_math (halfword p, halfword style, int usetextfont, halfword toks, halfword toks_text, int nocomponent, halfword cls, halfword all);
@@ -1410,8 +1410,8 @@ static void tex_aux_enter_display_math(halfword cmd)
size = - max_dimen;
} else {
tex_line_break(1, math_display_group);
- // size = tex_actual_box_width(lmt_linebreak_state.just_box, tex_x_over_n(tex_get_font_em_width(cur_font_par), 1000) * math_pre_display_gap_factor_par);
- size = tex_actual_box_width(lmt_linebreak_state.just_box, scaledround((tex_get_font_em_width(cur_font_par) / 1000.0) * math_pre_display_gap_factor_par));
+ // size = tex_actual_box_width(lmt_linebreak_state.just_box, tex_x_over_n(tex_get_font_em_width(cur_font_par), scaling_factor) * math_pre_display_gap_factor_par);
+ size = tex_actual_box_width(lmt_linebreak_state.just_box, scaledround((tex_get_font_em_width(cur_font_par) / scaling_factor_double) * math_pre_display_gap_factor_par));
}
/*tex
Now we are in vertical mode, working on the list that will contain the display. A displayed
@@ -3655,8 +3655,8 @@ void tex_run_math_fraction(void)
halfword mathclass = fraction_noad_subtype;
halfword rulethickness = preset_rule_thickness;
int ruledone = 0;
- fraction_h_factor(fraction) = 1000;
- fraction_v_factor(fraction) = 1000;
+ fraction_h_factor(fraction) = scaling_factor;
+ fraction_v_factor(fraction) = scaling_factor;
switch (code) {
case math_above_code:
case math_above_delimited_code:
@@ -4553,7 +4553,7 @@ static void tex_aux_finish_displayed_math(int atleft, halfword eqnumber, halfwor
if (eqnumber) {
number_width = box_width(eqnumber);
eqno_width = number_width;
- number_plus_gap_width = number_width + tex_round_xn_over_d(math_eqno_gap_step_par, tex_get_math_quad_style(text_style), 1000);
+ number_plus_gap_width = number_width + tex_round_xn_over_d(math_eqno_gap_step_par, tex_get_math_quad_style(text_style), scaling_factor);
node_subtype(eqnumber) = equation_number_list;
/*tex attach_current_attribute_list(eqno_box); */
} else {
@@ -5200,14 +5200,14 @@ static void tex_aux_define_all_math_parameters(int size, int param, scaled value
# define big_operator_spacing5(A) mathex(A,13) /*tex padding above and below displayed limits */
/*tex
- Somehow a scale > 1000 results in extreme values.
+ Somehow a scale > scaling_factor results in extreme values.
*/
/*
inline static int tex_aux_get_font_math_parameter(scaled scale, halfword f, int id)
{
scaled v = get_font_math_par(f, id);
-// return scale == 1000 ? v : round_xn_over_d(v, scale, 1000);
+// return scale == scaling_factor ? v : round_xn_over_d(v, scale, scaling_factor);
if (v) {
double d = 0.001 * scale * v;
return (d < 0.0) ? (int) (d - 0.5) : (int) (d + 0.5);
@@ -5218,7 +5218,7 @@ inline static int tex_aux_get_font_math_parameter(scaled scale, halfword f, int
inline static int tex_aux_get_font_math_quantity(scaled scale, halfword v)
{
-// return scale == 1000 ? v : round_xn_over_d(v, scale, 1000);
+// return scale == scaling_factor ? v : round_xn_over_d(v, scale, scaling_factor);
if (v) {
double d = 0.001 * scale * v;
return (d < 0.0) ? (int) (d - 0.5) : (int) (d + 0.5);
@@ -5328,8 +5328,8 @@ void tex_fixup_math_parameters(int fam, int size, int f, int level)
/*tex Not all are official \OPENTYPE: */
- tex_aux_define_all_math_parameters(size, math_parameter_x_scale, 1000, level);
- tex_aux_define_all_math_parameters(size, math_parameter_y_scale, 1000, level);
+ tex_aux_define_all_math_parameters(size, math_parameter_x_scale, scaling_factor, level);
+ tex_aux_define_all_math_parameters(size, math_parameter_y_scale, scaling_factor, level);
/*tex Most are zero and have to be set at by the macro package (if at all):. */
@@ -5508,16 +5508,26 @@ static void tex_aux_set_math_atom_rule(halfword left, halfword right, halfword n
tex_set_all_styles(math_parameter_rules_pair(left, right), (newleft << 16) + newright, level_one, indirect_math_regular);
}
+/*tex
+
+ Originally a penalty of 10000 signaled that no penalty has to be included but because we want
+ to control penalties in nested sequences (like open and close bound sequences) we need to be
+ able to go up (multiply by a factor) or down (divide by a factor). Therefore we need to be able
+ to set a penalty to 10000 as a start. so that it will be ignored unless we apply a factor. For
+ that reason we now use 10001 instead.
+
+*/
+
void tex_initialize_math_spacing(void)
{
for (int mathclass = 0; mathclass <= max_math_class_code; mathclass++) {
tex_set_math_class_default(mathclass, mathclass, no_class_options);
/*tex We do this here as there is no real need for yet another initializer. */
- tex_word_define(0, internal_int_location(first_math_pre_penalty_code + mathclass), infinite_penalty);
- tex_word_define(0, internal_int_location(first_math_post_penalty_code + mathclass), infinite_penalty);
- tex_word_define(0, internal_int_location(first_math_display_pre_penalty_code + mathclass), infinite_penalty);
- tex_word_define(0, internal_int_location(first_math_display_post_penalty_code + mathclass), infinite_penalty);
+ tex_word_define(0, internal_int_location(first_math_pre_penalty_code + mathclass), math_default_penalty);
+ tex_word_define(0, internal_int_location(first_math_post_penalty_code + mathclass), math_default_penalty);
+ tex_word_define(0, internal_int_location(first_math_display_pre_penalty_code + mathclass), math_default_penalty);
+ tex_word_define(0, internal_int_location(first_math_display_post_penalty_code + mathclass), math_default_penalty);
}
tex_reset_all_styles(level_one);
@@ -5658,8 +5668,8 @@ void tex_initialize_math_spacing(void)
/* */
- tex_set_all_styles (math_parameter_x_scale, 1000, level_one, indirect_math_regular);
- tex_set_all_styles (math_parameter_y_scale, 1000, level_one, indirect_math_regular);
+ tex_set_all_styles (math_parameter_x_scale, scaling_factor, level_one, indirect_math_regular);
+ tex_set_all_styles (math_parameter_y_scale, scaling_factor, level_one, indirect_math_regular);
/* could be initialize_math_defaults */
@@ -5734,8 +5744,8 @@ static void tex_aux_math_parameter_error(int style, int param, const char *name)
inline static scaled tex_aux_max_scale(int style, int param)
{
scaled scale = tex_get_math_parameter(style, param, NULL);
- if (scale > 5000) {
- return 5000;
+ if (scale > max_math_scaling_factor) {
+ return max_math_scaling_factor;
} else if (scale < 0) {
return 0;
} else {
diff --git a/source/luametatex/source/tex/texmath.h b/source/luametatex/source/tex/texmath.h
index 65f706a3c..8e847540d 100644
--- a/source/luametatex/source/tex/texmath.h
+++ b/source/luametatex/source/tex/texmath.h
@@ -246,34 +246,37 @@ typedef enum math_parameters {
# define math_default_rules_parameter 0
typedef enum math_class_options {
- no_pre_slack_class_option = 0x0000001,
- no_post_slack_class_option = 0x0000002,
- left_top_kern_class_option = 0x0000004,
- right_top_kern_class_option = 0x0000008,
- left_bottom_kern_class_option = 0x0000010,
- right_bottom_kern_class_option = 0x0000020,
- look_ahead_for_end_class_option = 0x0000040,
- no_italic_correction_class_option = 0x0000080,
- check_ligature_class_option = 0x0000100,
- check_italic_correction_class_option = 0x0000200,
- check_kern_pair_class_option = 0x0000400,
- flatten_class_option = 0x0000800,
- omit_penalty_class_option = 0x0001000,
- unpack_class_option = 0x0002000,
- raise_prime_option = 0x0004000,
- // open_fence_class_option = 0x0000100,
- // close_fence_class_option = 0x0000200,
- // middle_fence_class_option = 0x0000400,
- carry_over_left_top_kern_class_option = 0x0008000,
- carry_over_right_top_kern_class_option = 0x0010000,
- carry_over_left_bottom_kern_class_option = 0x0020000,
- carry_over_right_bottom_kern_class_option = 0x0040000,
- prefer_delimiter_dimensions_class_option = 0x0080000,
- auto_inject_class_option = 0x0100000,
- remove_italic_correction_class_option = 0x0200000,
- operator_italic_correction_class_option = 0x0400000,
- short_inline_class_option = 0x0800000,
- no_class_options = 0xF000000,
+ no_pre_slack_class_option = 0x00000001,
+ no_post_slack_class_option = 0x00000002,
+ left_top_kern_class_option = 0x00000004,
+ right_top_kern_class_option = 0x00000008,
+ left_bottom_kern_class_option = 0x00000010,
+ right_bottom_kern_class_option = 0x00000020,
+ look_ahead_for_end_class_option = 0x00000040,
+ no_italic_correction_class_option = 0x00000080,
+ check_ligature_class_option = 0x00000100,
+ check_italic_correction_class_option = 0x00000200,
+ check_kern_pair_class_option = 0x00000400,
+ flatten_class_option = 0x00000800,
+ omit_penalty_class_option = 0x00001000,
+ unpack_class_option = 0x00002000,
+ raise_prime_option = 0x00004000,
+ // open_fence_class_option = 0x00000100,
+ // close_fence_class_option = 0x00000200,
+ // middle_fence_class_option = 0x00000400,
+ carry_over_left_top_kern_class_option = 0x00008000,
+ carry_over_right_top_kern_class_option = 0x00010000,
+ carry_over_left_bottom_kern_class_option = 0x00020000,
+ carry_over_right_bottom_kern_class_option = 0x00040000,
+ prefer_delimiter_dimensions_class_option = 0x00080000,
+ auto_inject_class_option = 0x00100000,
+ remove_italic_correction_class_option = 0x00200000,
+ operator_italic_correction_class_option = 0x00400000,
+ short_inline_class_option = 0x00800000,
+ push_nesting_class_option = 0x01000000,
+ pop_nesting_class_option = 0x02000000,
+ obey_nesting_class_option = 0x04000000,
+ no_class_options = 0xF0000000,
} math_class_options;
extern int tex_math_has_class_option(halfword cls, int option);
diff --git a/source/luametatex/source/tex/texmlist.c b/source/luametatex/source/tex/texmlist.c
index d91ee50ae..13085dca1 100644
--- a/source/luametatex/source/tex/texmlist.c
+++ b/source/luametatex/source/tex/texmlist.c
@@ -2,6 +2,52 @@
See license.txt in the root of this project.
*/
+
+/*tex
+
+ Before we get to the code is is good to notice that what we have here is an extension of the
+ math rendering as implemented in \TEX. There are several reason for additions and changes. One
+ is that we need to support \OPENTYPE\ fonts and after more than a decade struggling with the
+ fact that many fonts are a mix between what the \OPENTYPE\ specification describes (its
+ accuracy evolved a bit over time) and what traditional \TEX\ fonts do. Think of the role that
+ italic correction plays in \TEX\ and kerns in \OPENTYPE\ math.
+
+ In \LUATEX\ this has resulted in a way to control various elements of the engine so that one
+ can adapt to the font. Here even more properties can be controlled. However, in the end we
+ decided that fonts are too inconsistent and unlikely to be fixed, so in \CONTEXT\ we settled
+ on a combination of engine control and patching fonts runtime (aka goodie tweaks). This does
+ actually mean that in principle we can remove most of the code related to italic correction
+ and simplify kerning, which makes for cleaner code. We can then also ditch many control
+ options. It could also make some of the resulting constructs les scomplex (this is something
+ that might happen eventually anyway).
+
+ In addition to this, the machinery below also has opened up atoms, fractions, accents, fences,
+ radicals and more beyond what \LUATEX\ already added. We have more classes (including user
+ ones), more spacing and penalty control, positioning features, etc. Most of that is not
+ described here but in documents that come with \CONTEXT\ and articles in user group journals.
+
+ It is unlikely that users will set up the engine beyond what a macro package provides, which
+ should be reasonable defaults. Keep in mind that the math machinery has never be part of
+ discussing extensions to \TEX\ and that the math subengine was never touched. So, while
+ \CONTEXT\ users sort of expect this upgrade path, this is not true for other macro packages,
+ especially when they are considered standard and provide standard behaviour. This means that
+ we can go a bit further in setting up the engine (by options and parametsrs) in ways that
+ provide better output. This means that even with the same input, the output that \CONTEXT\
+ produces will look different and hopefully somewhat better.
+
+ One can of course wonder why we think the rendering can be improved and part of the answer is
+ in the fact that we have double linked node lists. This means that we can go back and forward
+ over the result. Another apects is that we have less constraints in memory and processor
+ capabilities, so we can carry around more information and spend more time on analysing and
+ calculations. Nodes are way bigger and the font system is more dynamic, which comes at a
+ price not possible when original \TEX\ showed up. One can therefore only admire even more
+ what Don Knuth came up with, which still performs very well, and what is the robust core of
+ what we see below!
+
+ HH & MS
+
+*/
+
/*tex
The code here has to deal with traditional \TEX\ fonts as well as the more modern \OPENTYPE\
@@ -474,7 +520,7 @@ halfword tex_math_font_char_dp(halfword fnt, halfword chr, halfword style)
}
inline static halfword tex_aux_new_math_glyph(halfword fnt, halfword chr, quarterword subtype) {
- halfword scale = 1000;
+ halfword scale = scaling_factor;
halfword glyph = tex_new_glyph_node(subtype, fnt, tex_get_math_char(fnt, chr, lmt_math_state.size, &scale, math_direction_par), null); /* todo: data */;
set_glyph_options(glyph, glyph_options_par);
glyph_scale(glyph) = tex_aux_math_glyph_scale(scale);
@@ -1511,7 +1557,7 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int
}
}
goto FOUND;
- } else if (count > 1000) {
+ } else if (count > scaling_factor) {
tex_formatted_warning("fonts", "endless loop in extensible character %U of font %F", curchr, curfnt);
goto FOUND;
} else if (tex_char_has_tag_from_font(curfnt, curchr, list_tag)) {
@@ -2964,7 +3010,7 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal
scaled overshoot = 0;
extinfo *extended = NULL;
halfword attrlist = node_attr(target);
- scaled fraction = accent_fraction(target) > 0 ? accent_fraction(target) : 1000;
+ scaled fraction = accent_fraction(target) > 0 ? accent_fraction(target) : scaling_factor;
scaled skew = 0;
scaled offset = 0;
scaled innery = 0;
@@ -3047,7 +3093,7 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal
}
}
if (fraction > 0) {
- target = tex_xn_over_d(target, fraction, 1000);
+ target = tex_xn_over_d(target, fraction, scaling_factor);
}
while (1) {
if (tex_char_has_tag_from_font(accentfnt, accentchr, extensible_tag)) {
@@ -3448,8 +3494,8 @@ static void tex_aux_calculate_fraction_shifts(halfword target, int style, int si
(void) size;
*shift_up = tex_get_math_y_parameter_checked(style, up);
*shift_down = tex_get_math_y_parameter_checked(style, down);
- *shift_up = tex_round_xn_over_d(*shift_up, fraction_v_factor(target), 1000);
- *shift_down = tex_round_xn_over_d(*shift_down, fraction_v_factor(target), 1000);
+ *shift_up = tex_round_xn_over_d(*shift_up, fraction_v_factor(target), scaling_factor);
+ *shift_down = tex_round_xn_over_d(*shift_down, fraction_v_factor(target), scaling_factor);
}
static void tex_aux_calculate_fraction_shifts_stack(halfword target, int style, int size, halfword numerator, halfword denominator, scaled *shift_up, scaled *shift_down, scaled *delta)
@@ -3584,7 +3630,7 @@ static halfword tex_aux_make_skewed_fraction(halfword target, int style, int siz
delimiterextremes extremes = { .tfont = null_font, .tchar = 0, .bfont = null_font, .bchar = 0, .height = 0, .depth = 0 };
scaled tolerance = tex_get_math_y_parameter_default(style, math_parameter_skewed_delimiter_tolerance, 0);
scaled shift_up = tex_get_math_y_parameter_checked(style, math_parameter_skewed_fraction_vgap);
- scaled shift_down = tex_round_xn_over_d(shift_up, fraction_v_factor(target), 1000);
+ scaled shift_down = tex_round_xn_over_d(shift_up, fraction_v_factor(target), scaling_factor);
(void) kerns;
shift_up = shift_down; /*tex The |shift_up| value might change later. */
tex_aux_wrap_fraction_parts(target, style, size, &numerator, &denominator, 0);
@@ -3598,7 +3644,7 @@ static halfword tex_aux_make_skewed_fraction(halfword target, int style, int siz
Construct a hlist box for the fraction, according to |hgap| and |vgap|.
*/
hgap = tex_get_math_x_parameter_checked(style, math_parameter_skewed_fraction_hgap);
- hgap = tex_round_xn_over_d(hgap, fraction_h_factor(target), 1000);
+ hgap = tex_round_xn_over_d(hgap, fraction_h_factor(target), scaling_factor);
{
scaled ht = box_height(numerator) + shift_up;
scaled dp = box_depth(numerator) - shift_up;
@@ -3828,8 +3874,8 @@ static void tex_aux_get_shifts(int mode, int style, scaled delta, scaled *top, s
break;
case 1:
/*tex |MathConstants| driven */
- *top = tex_round_xn_over_d(delta, tex_get_math_parameter_default(style, math_parameter_nolimit_sup_factor, 0), 1000);
- *bot = -tex_round_xn_over_d(delta, tex_get_math_parameter_default(style, math_parameter_nolimit_sub_factor, 0), 1000);
+ *top = tex_round_xn_over_d(delta, tex_get_math_parameter_default(style, math_parameter_nolimit_sup_factor, 0), scaling_factor);
+ *bot = -tex_round_xn_over_d(delta, tex_get_math_parameter_default(style, math_parameter_nolimit_sub_factor, 0), scaling_factor);
break ;
case 2:
/*tex no correction */
@@ -3849,7 +3895,7 @@ static void tex_aux_get_shifts(int mode, int style, scaled delta, scaled *top, s
default :
/*tex above 15: for quickly testing values */
*top = 0;
- *bot = (mode > 15) ? -tex_round_xn_over_d(delta, mode, 1000) : 0;
+ *bot = (mode > 15) ? -tex_round_xn_over_d(delta, mode, scaling_factor) : 0;
break;
}
}
@@ -6831,6 +6877,11 @@ static void tex_mlist_to_hlist_size_fences(mliststate *state)
}
}
+/*tex
+ The mathboundary feature, where 0/2 push, 1/3 pop, 2/3 take an penalty delta, is only there for
+ special testing by MS and me, so don't depend on that for now.
+*/
+
static void tex_mlist_to_hlist_finalize_list(mliststate *state)
{
halfword recent = null; /*tex Watch out: can be wiped, so more a signal! */
@@ -6848,6 +6899,10 @@ static void tex_mlist_to_hlist_finalize_list(mliststate *state)
halfword current = state->mlist;
halfword p = temp_head;
halfword ghost = null;
+ int boundarylevel = 0;
+ int boundaryfactor = scaling_factor;
+ int nestinglevel = 0;
+ int nestingfactor = scaling_factor;
node_next(p) = null;
tex_aux_set_current_math_size(current_style);
tex_aux_set_current_math_scale(state->scale);
@@ -7019,10 +7074,38 @@ static void tex_mlist_to_hlist_finalize_list(mliststate *state)
default:
break;
}
+ case boundary_node:
+ if (node_subtype(current) == math_boundary) {
+ halfword l = boundary_data(current);
+ switch(l) {
+ case 0:
+ case 2:
+ boundarylevel++;
+ if (l == 2) {
+ boundaryfactor = boundary_reserved(current) ? boundary_reserved(current) : scaling_factor;
+ }
+ break;
+ case 1:
+ case 3:
+ if (boundarylevel > 0) {
+ boundarylevel--;
+ if (l == 2) {
+ boundaryfactor = boundary_reserved(current) ? boundary_reserved(current) : scaling_factor;
+ }
+ } else {
+ tex_formatted_warning("math", "invalid math boundary %i nesting", l);
+ }
+ break;
+ default:
+ tex_formatted_warning("math", "invalid math boundary value");
+ /* error */
+ break;
+ }
+ }
+ goto PICKUP;
// case glyph_node:
case disc_node:
case hlist_node:
- case boundary_node:
case whatsit_node:
case penalty_node:
case rule_node:
@@ -7031,6 +7114,7 @@ static void tex_mlist_to_hlist_finalize_list(mliststate *state)
case mark_node:
case par_node:
case kern_node:
+ PICKUP:
tex_couple_nodes(p, current);
p = current;
current = node_next(current);
@@ -7201,16 +7285,40 @@ static void tex_mlist_to_hlist_finalize_list(mliststate *state)
/*tex
Do we still want this check in infinite.
*/
- if (state->penalties && pre_penalty < infinite_penalty && node_type(last) != penalty_node) {
- /*tex no checking of prev node type */
- halfword penalty = tex_new_penalty_node(pre_penalty, math_pre_penalty_subtype);
- tex_attach_attribute_list_copy(penalty, current);
- tex_couple_nodes(p, penalty);
- p = penalty;
- if (tracing_math_par >= 2) {
- tex_begin_diagnostic();
- tex_print_format("[math: pre penalty, left %n, right %n, amount %i]", recent_subtype, current_subtype, penalty_amount(penalty));
- tex_end_diagnostic();
+ if (tex_math_has_class_option(current_subtype, push_nesting_class_option)) {
+ nestinglevel++;
+ switch (current_style) {
+ case display_style:
+ case cramped_display_style:
+ nestingfactor = math_display_penalty_factor_par ? math_display_penalty_factor_par : scaling_factor;
+ break;
+ default:
+ nestingfactor = math_inline_penalty_factor_par ? math_inline_penalty_factor_par : scaling_factor;
+ break;
+ }
+ } else if (tex_math_has_class_option(current_subtype, pop_nesting_class_option) && nestinglevel > 0) {
+ nestinglevel--;
+ if (nestinglevel == 0) {
+ nestingfactor = scaling_factor;
+ }
+ }
+ if (state->penalties && node_type(last) != penalty_node && pre_penalty <= infinite_penalty && (! boundarylevel || (boundaryfactor != scaling_factor || nestingfactor != scaling_factor))) {
+ if (boundaryfactor != scaling_factor) {
+ pre_penalty = tex_xn_over_d(pre_penalty, boundaryfactor, scaling_factor);
+ } else if (nestingfactor != scaling_factor && tex_math_has_class_option(current_subtype, obey_nesting_class_option)) {
+ pre_penalty = tex_xn_over_d(pre_penalty, nestingfactor, scaling_factor);
+ }
+ if (pre_penalty < infinite_penalty) {
+ /*tex no checking of prev node type */
+ halfword penalty = tex_new_penalty_node(pre_penalty, math_pre_penalty_subtype);
+ tex_attach_attribute_list_copy(penalty, current);
+ tex_couple_nodes(p, penalty);
+ p = penalty;
+ if (tracing_math_par >= 2) {
+ tex_begin_diagnostic();
+ tex_print_format("[math: pre penalty, left %n, right %n, amount %i]", recent_subtype, current_subtype, penalty_amount(penalty));
+ tex_end_diagnostic();
+ }
}
}
if (tex_math_has_class_option(current_subtype, remove_italic_correction_class_option)) {
@@ -7298,20 +7406,27 @@ static void tex_mlist_to_hlist_finalize_list(mliststate *state)
We can actually drop the omit check because we pair by class.
*/
- if (state->penalties && node_next(current) && post_penalty < infinite_penalty) {
- halfword recent = node_next(current);
- recent_type = node_type(recent);
- recent_subtype = node_subtype(recent);
- /* todo: maybe also check the mainclass of the recent */
- if ((recent_type != penalty_node) && ! (recent_type == simple_noad && tex_math_has_class_option(recent_subtype, omit_penalty_class_option))) {
- halfword penalty = tex_new_penalty_node(post_penalty, math_post_penalty_subtype);
- tex_attach_attribute_list_copy(penalty, current);
- tex_couple_nodes(p, penalty);
- p = penalty;
- if (tracing_math_par >= 2) {
- tex_begin_diagnostic();
- tex_print_format("[math: post penalty, left %n, right %n, amount %i]", recent_subtype, current_subtype, penalty_amount(penalty));
- tex_end_diagnostic();
+ if (state->penalties && node_next(current) && post_penalty <= infinite_penalty && (! boundarylevel || (boundaryfactor != scaling_factor || nestingfactor != scaling_factor))) {
+ if (boundaryfactor != scaling_factor) {
+ post_penalty = tex_xn_over_d(post_penalty, boundaryfactor, scaling_factor);
+ } else if (nestingfactor != scaling_factor && tex_math_has_class_option(current_subtype, obey_nesting_class_option)) {
+ post_penalty = tex_xn_over_d(post_penalty, nestingfactor, scaling_factor);
+ }
+ if (post_penalty < infinite_penalty) {
+ halfword recent = node_next(current);
+ recent_type = node_type(recent);
+ recent_subtype = node_subtype(recent);
+ /* todo: maybe also check the mainclass of the recent */
+ if ((recent_type != penalty_node) && ! (recent_type == simple_noad && tex_math_has_class_option(recent_subtype, omit_penalty_class_option))) {
+ halfword penalty = tex_new_penalty_node(post_penalty, math_post_penalty_subtype);
+ tex_attach_attribute_list_copy(penalty, current);
+ tex_couple_nodes(p, penalty);
+ p = penalty;
+ if (tracing_math_par >= 2) {
+ tex_begin_diagnostic();
+ tex_print_format("[math: post penalty, left %n, right %n, amount %i]", recent_subtype, current_subtype, penalty_amount(penalty));
+ tex_end_diagnostic();
+ }
}
}
}
diff --git a/source/luametatex/source/tex/texnesting.c b/source/luametatex/source/tex/texnesting.c
index 65e32a333..1f2995942 100644
--- a/source/luametatex/source/tex/texnesting.c
+++ b/source/luametatex/source/tex/texnesting.c
@@ -337,7 +337,7 @@ void tex_show_activities(void)
while (r != page_insert_head) {
halfword index = insert_index(r);
halfword multiplier = tex_get_insert_multiplier(index);
- halfword size = multiplier == 1000 ? insert_total_height(r) : tex_x_over_n(insert_total_height(r), 1000) * multiplier;
+ halfword size = multiplier == scaling_factor ? insert_total_height(r) : tex_x_over_n(insert_total_height(r), scaling_factor) * multiplier;
if (node_type(r) == split_node && node_subtype(r) == insert_split_subtype) {
halfword q = page_head;
halfword n = 0;
diff --git a/source/luametatex/source/tex/texnodes.c b/source/luametatex/source/tex/texnodes.c
index 650e0cee2..48a1bd2db 100644
--- a/source/luametatex/source/tex/texnodes.c
+++ b/source/luametatex/source/tex/texnodes.c
@@ -157,14 +157,15 @@ void lmt_nodelib_initialize(void) {
set_value_entry_key(subtypes_glue, g_leaders, gleaders)
set_value_entry_key(subtypes_glue, u_leaders, uleaders)
- subtypes_boundary = lmt_aux_allocate_value_info(par_boundary);
+ subtypes_boundary = lmt_aux_allocate_value_info(math_boundary);
set_value_entry_key(subtypes_boundary, cancel_boundary, cancel)
set_value_entry_key(subtypes_boundary, user_boundary, user)
set_value_entry_key(subtypes_boundary, protrusion_boundary, protrusion)
set_value_entry_key(subtypes_boundary, word_boundary, word)
set_value_entry_key(subtypes_boundary, page_boundary, page)
- set_value_entry_key(subtypes_boundary, par_boundary, par)
+ set_value_entry_key(subtypes_boundary, math_boundary, math)
+ /* set_value_entry_key(subtypes_boundary, par_boundary, par) */
subtypes_penalty = lmt_aux_allocate_value_info(equation_number_penalty_subtype);
@@ -2595,13 +2596,13 @@ void tex_show_node_list(halfword p, int threshold, int max)
if (glyph_expansion(p)) {
tex_print_format(", expansion %i", glyph_expansion(p));
}
- if (glyph_scale(p) && glyph_scale(p) != 1000) {
+ if (glyph_scale(p) && glyph_scale(p) != scaling_factor) {
tex_print_format(", scale %i", glyph_scale(p));
}
- if (glyph_x_scale(p) && glyph_x_scale(p) != 1000) {
+ if (glyph_x_scale(p) && glyph_x_scale(p) != scaling_factor) {
tex_print_format(", xscale %i", glyph_x_scale(p));
}
- if (glyph_y_scale(p) && glyph_y_scale(p) != 1000) {
+ if (glyph_y_scale(p) && glyph_y_scale(p) != scaling_factor) {
tex_print_format(", yscale %i", glyph_y_scale(p));
}
if (glyph_data(p)) {
@@ -3371,7 +3372,7 @@ scaled tex_glyph_width_ex(halfword p)
}
w -= (glyph_left(p) + glyph_right(p));
if (glyph_expansion(p)) {
- w = w + tex_ext_xn_over_d(w, 1000000 + glyph_expansion(p), 1000000);
+ w = w + tex_ext_xn_over_d(w, scaling_factor_squared + glyph_expansion(p), scaling_factor_squared);
}
return w;
}
@@ -3442,7 +3443,7 @@ scaledwhd tex_glyph_dimensions_ex(halfword p)
whd.dp = 0;
}
if (whd.wd && glyph_expansion(p)) {
- whd.wd = tex_ext_xn_over_d(whd.wd, 1000000 + glyph_expansion(p), 1000000);
+ whd.wd = tex_ext_xn_over_d(whd.wd, scaling_factor_squared + glyph_expansion(p), scaling_factor_squared);
}
return whd;
}
@@ -3478,7 +3479,7 @@ halfword tex_kern_dimension_ex(halfword p)
{
halfword k = kern_amount(p);
if (k && kern_expansion(p)) {
- k = tex_ext_xn_over_d(k, 1000000 + kern_expansion(p), 1000000);
+ k = tex_ext_xn_over_d(k, scaling_factor_squared + kern_expansion(p), scaling_factor_squared);
}
return k;
}
diff --git a/source/luametatex/source/tex/texnodes.h b/source/luametatex/source/tex/texnodes.h
index 3550e7345..492e220f2 100644
--- a/source/luametatex/source/tex/texnodes.h
+++ b/source/luametatex/source/tex/texnodes.h
@@ -2147,11 +2147,12 @@ typedef enum boundary_subtypes {
protrusion_boundary, /* 1=left, 2=right, 3=both */
word_boundary,
page_boundary,
+ math_boundary,
par_boundary,
} boundary_subtypes;
# define last_boundary_subtype word_boundary
-# define last_boundary_code page_boundary
+# define last_boundary_code math_boundary
# define boundary_node_size 3
# define boundary_data(a) vinfo(a,2)
diff --git a/source/luametatex/source/tex/texpackaging.c b/source/luametatex/source/tex/texpackaging.c
index 9f66232a7..8d2f0d87a 100644
--- a/source/luametatex/source/tex/texpackaging.c
+++ b/source/luametatex/source/tex/texpackaging.c
@@ -425,7 +425,7 @@ scaled tex_char_stretch(halfword p) /* todo: move this to texfont.c and make it
if (e > 0) {
scaled dw = tex_calculated_glyph_width(p, m) - tex_char_width_from_glyph(p);
if (dw > 0) {
- return tex_round_xn_over_d(dw, e, 1000);
+ return tex_round_xn_over_d(dw, e, scaling_factor);
}
}
}
@@ -444,7 +444,7 @@ scaled tex_char_shrink(halfword p) /* todo: move this to texfont.c and make it m
if (e > 0) {
scaled dw = tex_char_width_from_glyph(p) - tex_calculated_glyph_width(p, -m);
if (dw > 0) {
- return tex_round_xn_over_d(dw, e, 1000);
+ return tex_round_xn_over_d(dw, e, scaling_factor);
}
}
}
@@ -462,9 +462,9 @@ scaled tex_kern_stretch(halfword p)
if (m > 0) {
scaled e = tex_char_ef_from_font(glyph_font(l), glyph_character(l));
if (e > 0) {
- scaled dw = w - tex_round_xn_over_d(w, 1000 + m, 1000);
+ scaled dw = w - tex_round_xn_over_d(w, scaling_factor + m, scaling_factor);
if (dw > 0) {
- return tex_round_xn_over_d(dw, e, 1000);
+ return tex_round_xn_over_d(dw, e, scaling_factor);
}
}
}
@@ -483,9 +483,9 @@ scaled tex_kern_shrink(halfword p)
if (m > 0) {
scaled e = tex_char_cf_from_font(glyph_font(l), glyph_character(l));
if (e > 0) {
- scaled dw = tex_round_xn_over_d(w, 1000 - m, 1000) - w;
+ scaled dw = tex_round_xn_over_d(w, scaling_factor - m, scaling_factor) - w;
if (dw > 0) {
- return tex_round_xn_over_d(dw, e, 1000);
+ return tex_round_xn_over_d(dw, e, scaling_factor);
}
}
}
@@ -507,8 +507,8 @@ static void tex_aux_set_kern_expansion(halfword p, halfword ex_ratio)
if (e > 0) {
halfword m = font_max_stretch(f);
if (m > 0) {
- e = tex_ext_xn_over_d(ex_ratio * e, m, 1000000);
- kern_expansion(p) = tex_fix_expand_value(f, e) * 1000;
+ e = tex_ext_xn_over_d(ex_ratio * e, m, scaling_factor_squared);
+ kern_expansion(p) = tex_fix_expand_value(f, e) * scaling_factor;
}
}
} else if (ex_ratio < 0) {
@@ -516,8 +516,8 @@ static void tex_aux_set_kern_expansion(halfword p, halfword ex_ratio)
if (e > 0) {
halfword m = font_max_shrink(f);
if (m > 0) {
- e = tex_ext_xn_over_d(ex_ratio * e, m, 1000000);
- kern_expansion(p) = tex_fix_expand_value(f, e) * 1000;
+ e = tex_ext_xn_over_d(ex_ratio * e, m, scaling_factor_squared);
+ kern_expansion(p) = tex_fix_expand_value(f, e) * scaling_factor;
}
}
}
@@ -537,8 +537,8 @@ static void tex_aux_set_glyph_expansion(halfword p, int ex_ratio)
if (e > 0) {
halfword m = font_max_stretch(f);
if (m > 0) {
- e = tex_ext_xn_over_d(ex_ratio * e, m, 1000000);
- glyph_expansion(p) = tex_fix_expand_value(f, e) * 1000;
+ e = tex_ext_xn_over_d(ex_ratio * e, m, scaling_factor_squared);
+ glyph_expansion(p) = tex_fix_expand_value(f, e) * scaling_factor;
}
}
} else if (ex_ratio < 0) {
@@ -548,8 +548,8 @@ static void tex_aux_set_glyph_expansion(halfword p, int ex_ratio)
if (e > 0) {
halfword m = font_max_shrink(f);
if (m > 0) {
- e = tex_ext_xn_over_d(ex_ratio * e, m, 1000000);
- glyph_expansion(p) = tex_fix_expand_value(f, e) * 1000;
+ e = tex_ext_xn_over_d(ex_ratio * e, m, scaling_factor_squared);
+ glyph_expansion(p) = tex_fix_expand_value(f, e) * scaling_factor;
}
}
}
@@ -1100,10 +1100,10 @@ halfword tex_hpack(halfword p, scaled w, int m, singleword pack_direction, int r
/*tex Why not always: */
lmt_packaging_state.previous_char_ptr = null;
} else if (m == packing_adapted) {
- if (w > 1000) {
- w = 1000;
- } else if (w < -1000) {
- w = -1000;
+ if (w > scaling_factor) {
+ w = scaling_factor;
+ } else if (w < -scaling_factor) {
+ w = -scaling_factor;
}
}
for (int i = normal_glue_order; i <= filll_glue_order; i++) {
@@ -1423,7 +1423,7 @@ halfword tex_hpack(halfword p, scaled w, int m, singleword pack_direction, int r
*/
halfword o = tex_aux_used_order(lmt_packaging_state.total_stretch);
if ((m == packing_expanded) && (o == normal_glue_order) && (font_stretch > 0)) {
- lmt_packaging_state.font_expansion_ratio = tex_divide_scaled_n(x, font_stretch, 1000.0);
+ lmt_packaging_state.font_expansion_ratio = tex_divide_scaled_n(x, font_stretch, scaling_factor_double);
goto EXIT;
}
box_glue_order(r) = o;
@@ -1476,7 +1476,7 @@ halfword tex_hpack(halfword p, scaled w, int m, singleword pack_direction, int r
*/
halfword o = tex_aux_used_order(lmt_packaging_state.total_shrink);
if ((m == packing_expanded) && (o == normal_glue_order) && (font_shrink > 0)) {
- lmt_packaging_state.font_expansion_ratio = tex_divide_scaled_n(x, font_shrink, 1000.0);
+ lmt_packaging_state.font_expansion_ratio = tex_divide_scaled_n(x, font_shrink, scaling_factor_double);
goto EXIT;
}
box_glue_order(r) = o;
@@ -1491,7 +1491,7 @@ halfword tex_hpack(halfword p, scaled w, int m, singleword pack_direction, int r
if (o == normal_glue_order && box_list(r)) {
if (lmt_packaging_state.total_shrink[o] < -x) {
int overshoot = -x - lmt_packaging_state.total_shrink[normal_glue_order];
- lmt_packaging_state.last_badness = 1000000;
+ lmt_packaging_state.last_badness = scaling_factor_squared;
lmt_packaging_state.last_overshoot = overshoot;
/*tex Use the maximum shrinkage */
box_glue_set(r) = 1.0;
@@ -1574,7 +1574,7 @@ halfword tex_hpack(halfword p, scaled w, int m, singleword pack_direction, int r
}
EXIT:
if ((m == packing_expanded) && (lmt_packaging_state.font_expansion_ratio != 0)) {
- lmt_packaging_state.font_expansion_ratio = fix_int(lmt_packaging_state.font_expansion_ratio, -1000, 1000);
+ lmt_packaging_state.font_expansion_ratio = fix_int(lmt_packaging_state.font_expansion_ratio, -scaling_factor, scaling_factor);
q = box_list(r);
box_list(r) = null;
tex_flush_node(r);
@@ -2237,7 +2237,7 @@ halfword tex_vpack(halfword p, scaled h, int m, scaled l, singleword pack_direct
if (o == normal_glue_order && box_list(r)) {
if (lmt_packaging_state.total_shrink[o] < -x) {
int overshoot = -x - lmt_packaging_state.total_shrink[normal_glue_order];
- lmt_packaging_state.last_badness = 1000000;
+ lmt_packaging_state.last_badness = scaling_factor_squared;
lmt_packaging_state.last_overshoot = overshoot;
/*tex Use the maximum shrinkage */
box_glue_set(r) = 1.0;
diff --git a/source/luametatex/source/tex/texprinting.c b/source/luametatex/source/tex/texprinting.c
index 518f1cf43..f79a47a87 100644
--- a/source/luametatex/source/tex/texprinting.c
+++ b/source/luametatex/source/tex/texprinting.c
@@ -529,8 +529,8 @@ void tex_print_dimension(scaled s, int unit)
s = 10 * (s % unity) + 5;
do {
if (delta > unity) {
- /*tex Round the last digit. */
- s = s + 0100000 - 50000;
+ /*tex Round the last digit, so: |s + 32768 - 50000| it is. */
+ s = s + 0x8000 - 50000;
}
buffer[i++] = (unsigned char) ('0' + (s / unity));
s = 10 * (s % unity);
diff --git a/source/luametatex/source/tex/textextcodes.c b/source/luametatex/source/tex/textextcodes.c
index e76329685..73e9f7867 100644
--- a/source/luametatex/source/tex/textextcodes.c
+++ b/source/luametatex/source/tex/textextcodes.c
@@ -216,7 +216,7 @@ static void tex_aux_free_catcodes(void)
# define UCCODEDEFAULT 0
# define SFCODESTACK 8
-# define SFCODEDEFAULT 1000
+# define SFCODEDEFAULT scaling_factor
# define HCCODESTACK 8
# define HCCODEDEFAULT 0
diff --git a/source/luametatex/source/tex/textypes.h b/source/luametatex/source/tex/textypes.h
index 683ee2e5a..5a4dce7e8 100644
--- a/source/luametatex/source/tex/textypes.h
+++ b/source/luametatex/source/tex/textypes.h
@@ -162,11 +162,13 @@ extern halfword tex_badness(
# define max_infinity 0x7FFFFFFF /*tex the largest positive value that \TEX\ knows */
# define min_infinity -0x7FFFFFFF
-# define awful_bad 07777777777 /*tex more than a billion demerits |0x3FFFFFFF| */
+ # define awful_bad 0x3FFFFFFF /*tex more than a billion demerits |07777777777| */
# define infinite_bad 10000 /*tex infinitely bad value */
# define infinite_penalty infinite_bad /*tex infinite penalty value */
# define eject_penalty -infinite_penalty /*tex negatively infinite penalty value */
+# define final_penalty -0x40000000 /*tex in the output routine */
# define deplorable 100000 /*tex more than |inf_bad|, but less than |awful_bad| */
+# define extremely_deplorable 100000000
# define large_width_excess 7230584
# define small_stretchability 1663497
# define loose_criterion 99
@@ -213,6 +215,19 @@ extern halfword tex_badness(
# define default_output_box 255
+# define scaling_factor 1000
+# define scaling_factor_squared 1000000
+# define scaling_factor_double 1000.0
+//define scaling_multiplier_double 0.001
+
+# define max_math_scaling_factor 5000
+
+# define max_font_adjust_step 100
+# define max_font_adjust_stretch_factor 1000
+# define max_font_adjust_shrink_factor 500
+
+# define math_default_penalty (infinite_penalty+1)
+
/*tex
For practical reasons all these registers were max'd to 64K but that really makes no sense for