diff options
Diffstat (limited to 'source/luametatex')
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  | 
