From 1bcb61ec8c01b503740bfeb8cc9d5f62553b3f72 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Sun, 28 May 2023 19:47:52 +0200 Subject: 2023-05-28 18:57:00 --- source/luametatex/source/lua/lmtnodelib.c | 58 +++++++++++--------- source/luametatex/source/luametatex.h | 2 +- source/luametatex/source/tex/texcommands.c | 1 + source/luametatex/source/tex/texdumpdata.h | 2 +- source/luametatex/source/tex/texequivalents.h | 4 +- source/luametatex/source/tex/texlinebreak.c | 5 +- source/luametatex/source/tex/texmath.c | 79 ++++++++++++++++++++++++--- source/luametatex/source/tex/texmlist.c | 1 + source/luametatex/source/tex/texnodes.c | 10 ++-- source/luametatex/source/tex/texnodes.h | 4 +- source/luametatex/source/tex/texpackaging.c | 8 ++- source/luametatex/source/tex/textypes.h | 5 +- 12 files changed, 130 insertions(+), 49 deletions(-) (limited to 'source') diff --git a/source/luametatex/source/lua/lmtnodelib.c b/source/luametatex/source/lua/lmtnodelib.c index ba2d0f0ba..c9ab9678c 100644 --- a/source/luametatex/source/lua/lmtnodelib.c +++ b/source/luametatex/source/lua/lmtnodelib.c @@ -4623,7 +4623,7 @@ static int nodelib_direct_dimensions(lua_State *L) { int top = lua_gettop(L); if (top > 0) { - scaledwhd siz = { 0, 0, 0, 0 }; + scaledwhd siz = { .wd = 0, .ht = 0, .dp = 0, .ns = 0 }; glueratio g_mult = normal_glue_multiplier; int vertical = 0; int g_sign = normal_glue_sign; @@ -4654,7 +4654,8 @@ static int nodelib_direct_dimensions(lua_State *L) lua_pushinteger(L, siz.wd); lua_pushinteger(L, siz.ht); lua_pushinteger(L, siz.dp); - return 3; + lua_pushinteger(L, siz.ns); + return 4; } else { return luaL_error(L, "missing argument to 'dimensions' (direct node expected)"); } @@ -4664,7 +4665,7 @@ static int nodelib_direct_rangedimensions(lua_State *L) /* parent, first, last * { int top = lua_gettop(L); if (top > 1) { - scaledwhd siz = { 0, 0, 0, 0 }; + scaledwhd siz = { .wd = 0, .ht = 0, .dp = 0, .ns = 0 }; int vertical = 0; halfword l = nodelib_valid_direct_from_index(L, 1); /* parent */ halfword n = nodelib_valid_direct_from_index(L, 2); /* first */ @@ -4685,7 +4686,8 @@ static int nodelib_direct_rangedimensions(lua_State *L) /* parent, first, last * lua_pushinteger(L, siz.wd); lua_pushinteger(L, siz.ht); lua_pushinteger(L, siz.dp); - return 3; + lua_pushinteger(L, siz.ns); + return 4; } else { return luaL_error(L, "missing argument to 'rangedimensions' (2 or more direct nodes expected)"); } @@ -9049,9 +9051,9 @@ static int nodelib_direct_isvalid(lua_State *L) /* getlinestuff : LS RS LH RH ID PF FIRST LAST */ -inline static halfword set_effective_width(halfword source, halfword sign, halfword order, double glue) +inline static scaled set_effective_width(halfword source, halfword sign, halfword order, double glue) { - halfword amount = glue_amount(source); + scaled amount = glue_amount(source); switch (sign) { case stretching_glue_sign: if (glue_stretch_order(source) == order) { @@ -9075,18 +9077,19 @@ static int nodelib_direct_getnormalizedline(lua_State *L) if (n && node_type(n) == hlist_node && node_subtype(n) == line_list) { halfword head = box_list(n); halfword tail = head; - halfword first = head; - halfword last = tail; + halfword first = head; /* the first special glue before the content */ + halfword last = tail; /* the first special glue after the content */ halfword current = head; - halfword ls = 0; - halfword rs = 0; - halfword is = 0; - halfword pr = 0; - halfword pl = 0; - halfword ir = 0; - halfword il = 0; - halfword lh = 0; - halfword rh = 0; + scaled ls = 0; + scaled rs = 0; + scaled is = 0; + scaled pr = 0; + scaled pl = 0; + scaled ir = 0; + scaled il = 0; + scaled lh = 0; + scaled rh = 0; + scaled cs = 0; halfword sign = box_glue_sign(n); halfword order = box_glue_order(n); double glue = box_glue_set(n); @@ -9094,19 +9097,21 @@ static int nodelib_direct_getnormalizedline(lua_State *L) tail = current ; if (node_type(current) == glue_node) { switch (node_subtype(current)) { - case left_skip_glue : ls = set_effective_width(current, sign, order, glue); break; - case right_skip_glue : rs = set_effective_width(current, sign, order, glue); break; - case par_fill_left_skip_glue : pl = set_effective_width(current, sign, order, glue); break; - case par_fill_right_skip_glue : pr = set_effective_width(current, sign, order, glue); break; - case par_init_left_skip_glue : il = set_effective_width(current, sign, order, glue); break; - case par_init_right_skip_glue : ir = set_effective_width(current, sign, order, glue); break; - case indent_skip_glue : is = set_effective_width(current, sign, order, glue); break; - case left_hang_skip_glue : lh = set_effective_width(current, sign, order, glue); break; - case right_hang_skip_glue : rh = set_effective_width(current, sign, order, glue); break; + case left_skip_glue : ls = set_effective_width(current, sign, order, glue); break; // first = current; break; + case right_skip_glue : rs = set_effective_width(current, sign, order, glue); break; // if (last == tail) { last = current; } break; + case par_fill_left_skip_glue : pl = set_effective_width(current, sign, order, glue); break; // first = current; break; + case par_fill_right_skip_glue : pr = set_effective_width(current, sign, order, glue); break; // if (last == tail) { last = current; } break; + case par_init_left_skip_glue : il = set_effective_width(current, sign, order, glue); break; // first = current; break; + case par_init_right_skip_glue : ir = set_effective_width(current, sign, order, glue); break; // if (last == tail) { last = current; } break; + case indent_skip_glue : is = set_effective_width(current, sign, order, glue); break; // first = current; break; + case left_hang_skip_glue : lh = set_effective_width(current, sign, order, glue); break; // first = current; break; + case right_hang_skip_glue : rh = set_effective_width(current, sign, order, glue); break; // if (last == tail) { last = current; } break; + case correction_skip_glue : cs = set_effective_width(current, sign, order, glue); break; // break; } } current = node_next(current); } + /* The next two loops can be integrated in the above but for now we keep this . */ current = head; while (current) { if (node_type(current) == glue_node) { @@ -9156,6 +9161,7 @@ static int nodelib_direct_getnormalizedline(lua_State *L) lua_push_integer_at_key(L, parfillrightskip, pr); lua_push_integer_at_key(L, parinitleftskip, il); lua_push_integer_at_key(L, parinitrightskip, ir); + lua_push_integer_at_key(L, correctionskip, cs); lua_push_integer_at_key(L, first, first); /* points to a skip */ lua_push_integer_at_key(L, last, last); /* points to a skip */ lua_push_integer_at_key(L, head, head); diff --git a/source/luametatex/source/luametatex.h b/source/luametatex/source/luametatex.h index 2a99867e8..f5b2f1984 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 20230525 +# define luametatex_development_id 20230528 # define luametatex_name_camelcase "LuaMetaTeX" # define luametatex_name_lowercase "luametatex" diff --git a/source/luametatex/source/tex/texcommands.c b/source/luametatex/source/tex/texcommands.c index ddc57f0bd..239394859 100644 --- a/source/luametatex/source/tex/texcommands.c +++ b/source/luametatex/source/tex/texcommands.c @@ -311,6 +311,7 @@ void tex_initialize_commands(void) tex_primitive(luatex_command, "tabsize", internal_dimen_cmd, tab_size_code, internal_dimen_base); tex_primitive(luatex_command, "pageextragoal", internal_dimen_cmd, page_extra_goal_code, internal_dimen_base); tex_primitive(luatex_command, "ignoredepthcriterium", internal_dimen_cmd, ignore_depth_criterium_code, internal_dimen_base); /* mostly for myself, tutorials etc */ + tex_primitive(luatex_command, "shortinlinemaththreshold", internal_dimen_cmd, short_inline_math_threshold_code, internal_dimen_base); /*tex Probably never used with \UNICODE\ omnipresent now: */ diff --git a/source/luametatex/source/tex/texdumpdata.h b/source/luametatex/source/tex/texdumpdata.h index be45c0045..c0a55c2fe 100644 --- a/source/luametatex/source/tex/texdumpdata.h +++ b/source/luametatex/source/tex/texdumpdata.h @@ -55,7 +55,7 @@ */ -# define luametatex_format_fingerprint 690 +# define luametatex_format_fingerprint 691 /* These end up in the string pool. */ diff --git a/source/luametatex/source/tex/texequivalents.h b/source/luametatex/source/tex/texequivalents.h index 5ecf73ee0..4aeb32a81 100644 --- a/source/luametatex/source/tex/texequivalents.h +++ b/source/luametatex/source/tex/texequivalents.h @@ -640,12 +640,13 @@ typedef enum dimen_codes { tab_size_code, page_extra_goal_code, ignore_depth_criterium_code, + short_inline_math_threshold_code, /*tex total number of dimension parameters */ number_dimen_pars, } dimen_codes; # define first_dimen_code par_indent_code -# define last_dimen_code tab_size_code +# define last_dimen_code short_inline_math_threshold_code typedef enum attribute_codes { /*tex total number of attribute parameters */ @@ -1395,6 +1396,7 @@ extern void tex_forced_word_define (int g, halfword p, singleword flag, halfword # define overfull_rule_par dimen_parameter(overfull_rule_code) # define box_max_depth_par dimen_parameter(box_max_depth_code) # define ignore_depth_criterium_par dimen_parameter(ignore_depth_criterium_code) +# define short_inline_math_threshold_par dimen_parameter(short_inline_math_threshold_code) # define top_skip_par glue_parameter(top_skip_code) # define split_top_skip_par glue_parameter(split_top_skip_code) diff --git a/source/luametatex/source/tex/texlinebreak.c b/source/luametatex/source/tex/texlinebreak.c index e009d3e50..821613c60 100644 --- a/source/luametatex/source/tex/texlinebreak.c +++ b/source/luametatex/source/tex/texlinebreak.c @@ -2573,9 +2573,10 @@ void tex_do_line_break(line_break_properties *properties) case explicit_kern_subtype: case italic_kern_subtype: { - /* there used to a ! is_char_node(node_next(cur_p)) test */ + /*tex There used to be a |! is_char_node(node_next(cur_p))| test here. */ + /*tex We catch |\emph{test} $\hat{x}$| aka |test\kern5pt\hskip10pt$\hat{x}$|. */ halfword nxt = node_next(cur_p); - if (nxt && node_type(nxt) == glue_node && ! tex_has_glue_option(nxt, glue_option_no_auto_break)) { + if (nxt && node_type(nxt) == glue_node && ! tex_aux_upcoming_penalty(nxt) && ! tex_has_glue_option(nxt, glue_option_no_auto_break)) { tex_aux_try_break(properties, 0, unhyphenated_node, first_p, cur_p, callback_id, pass); } } diff --git a/source/luametatex/source/tex/texmath.c b/source/luametatex/source/tex/texmath.c index a4ec71e5d..e2b4f9c39 100644 --- a/source/luametatex/source/tex/texmath.c +++ b/source/luametatex/source/tex/texmath.c @@ -4761,26 +4761,91 @@ static void tex_aux_finish_displayed_math(int atleft, halfword eqnumber, halfwor */ +/* make propper mappers (see 5967 in texmlist) */ + static inline int tex_aux_class_from_glyph(halfword n) { return node_subtype(n) - (node_subtype(n) > glyph_math_extra_subtype ? glyph_math_extra_subtype : glyph_math_ordinary_subtype); } +static inline int tex_aux_class_from_list(halfword n) { + switch (node_subtype(n)) { + case math_fraction_list: + return fraction_noad_subtype; + case math_accent_list: + return accent_noad_subtype; + case math_radical_list: + return radical_noad_subtype; + default: + return 0; + } +} + static int tex_aux_short_math(halfword m) { // tex_show_node_list(m,10000,10000); if (m) { - /* kern[] glyph[subtype -> class] vlist[scripts] kern[] */ - if (node_type(m) == kern_node) { - m = node_next(m); + /*tex + These are the cases we catch, the class option drives succes. + + \starttyping + kern[] glyph[subtype -> class] vlist[scripts] kern[] + hlist[subtype -> class] + vlist[subtype -> class] + \stoptyping + + */ + switch (node_type(m)) { + case kern_node: + /*tex Do we need to test for some size here? */ + m = node_next(m); + break; + case hlist_node: + case vlist_node: + /*tex + These are actually more extensive constructs that we don't want to analyze any + further (for being single characters). + */ + if (! node_next(m) && tex_math_has_class_option(tex_aux_class_from_list(m), short_inline_class_option)) { + scaled threshold = short_inline_math_threshold_par; + if (threshold > 0 && box_width(m) <= threshold) { + return 1; + } + } + return 0; } - if (m && node_type(m) == glyph_node && tex_math_has_class_option(tex_aux_class_from_glyph(m), short_inline_class_option)) { - m = node_next(m); + /*tex We don't have a list so we check for a list now. */ + if (m) { + switch (node_type(m)) { + case glyph_node: + if (tex_math_has_class_option(tex_aux_class_from_glyph(m), short_inline_class_option)) { + m = node_next(m); + break; + } else { + return 0; + } + default: + return 0; + } } else { return 0; } - if (m && node_type(m) == vlist_node && node_subtype(m) == math_scripts_list) { - m = node_next(m); + /*tex We accept optional sub, super or combined scripts. */ + if (m) { + switch (node_type(m)) { + case vlist_node: + case hlist_node: + switch (node_subtype(m)) { + case math_sup_list: /* in hlist */ + case math_sub_list: /* in hlist */ + case math_pre_post_list: /* in vlist */ + case math_scripts_list: /* in vlist */ + m = node_next(m); + break; + } + /* default */ + } } + /*tex We ignore trailing kerns (for now). We could test for size. */ if (m && node_type(m) == kern_node) { m = node_next(m); } diff --git a/source/luametatex/source/tex/texmlist.c b/source/luametatex/source/tex/texmlist.c index 69de1c8c6..1b9201172 100644 --- a/source/luametatex/source/tex/texmlist.c +++ b/source/luametatex/source/tex/texmlist.c @@ -5964,6 +5964,7 @@ static halfword tex_aux_check_nucleus_complexity(halfword target, scaled *italic /*tex We make a math glyph from an ordinary one. */ halfword glyph; quarterword subtype = 0; + /* todo: make this a mapper */ switch (node_subtype(nucleus)) { case ordinary_noad_subtype: subtype = glyph_math_ordinary_subtype; break; case operator_noad_subtype: subtype = glyph_math_operator_subtype; break; diff --git a/source/luametatex/source/tex/texnodes.c b/source/luametatex/source/tex/texnodes.c index 39dedb97f..650e0cee2 100644 --- a/source/luametatex/source/tex/texnodes.c +++ b/source/luametatex/source/tex/texnodes.c @@ -3485,11 +3485,11 @@ halfword tex_kern_dimension_ex(halfword p) scaledwhd tex_pack_dimensions(halfword p) { - scaledwhd whd = { 0, 0, 0, 0 }; - whd.ht = box_height(p); - whd.dp = box_depth(p); - whd.wd = box_width(p); - return whd; + scaledwhd siz = { .wd = 0, .ht = 0, .dp = 0, .ns = 0 }; + siz.ht = box_height(p); + siz.dp = box_depth(p); + siz.wd = box_width(p); + return siz; } /*tex diff --git a/source/luametatex/source/tex/texnodes.h b/source/luametatex/source/tex/texnodes.h index 9e7d3ef13..80ab40f03 100644 --- a/source/luametatex/source/tex/texnodes.h +++ b/source/luametatex/source/tex/texnodes.h @@ -464,10 +464,10 @@ typedef enum glue_subtypes { space_skip_glue, xspace_skip_glue, zero_space_skip_glue, - par_fill_right_skip_glue, par_fill_left_skip_glue, - par_init_right_skip_glue, + par_fill_right_skip_glue, par_init_left_skip_glue, + par_init_right_skip_glue, indent_skip_glue, left_hang_skip_glue, right_hang_skip_glue, diff --git a/source/luametatex/source/tex/texpackaging.c b/source/luametatex/source/tex/texpackaging.c index dbc569246..185b80c1b 100644 --- a/source/luametatex/source/tex/texpackaging.c +++ b/source/luametatex/source/tex/texpackaging.c @@ -1617,7 +1617,7 @@ halfword tex_filtered_hpack(halfword p, halfword qt, scaled w, int m, int grp, h scaledwhd tex_natural_hsizes(halfword p, halfword pp, glueratio g_mult, int g_sign, int g_order) { - scaledwhd siz = { 0, 0, 0, 0 }; + scaledwhd siz = { .wd = 0, .ht = 0, .dp = 0, .ns = 0 }; scaled gp = 0; scaled gm = 0; while (p && p != pp) { @@ -1758,6 +1758,7 @@ scaledwhd tex_natural_hsizes(halfword p, halfword pp, glueratio g_mult, int g_si } p = node_next(p); } + siz.ns = siz.wd; switch (g_sign) { case stretching_glue_sign: siz.wd += glueround((glueratio)(g_mult) * (glueratio)(gp)); @@ -1771,7 +1772,7 @@ scaledwhd tex_natural_hsizes(halfword p, halfword pp, glueratio g_mult, int g_si scaledwhd tex_natural_vsizes(halfword p, halfword pp, glueratio g_mult, int g_sign, int g_order) { - scaledwhd siz = { 0, 0, 0, 0 }; + scaledwhd siz = { .wd = 0, .ht = 0, .dp = 0, .ns = 0 }; scaled gp = 0; scaled gm = 0; while (p && p != pp) { @@ -1851,6 +1852,7 @@ scaledwhd tex_natural_vsizes(halfword p, halfword pp, glueratio g_mult, int g_si } p = node_next(p); } + siz.ns = siz.ht; switch (g_sign) { case stretching_glue_sign: siz.ht += glueround((glueratio)(g_mult) * (glueratio)(gp)); @@ -1988,7 +1990,7 @@ halfword tex_natural_hsize(halfword p, halfword *correction) halfword tex_natural_vsize(halfword p) { - scaledwhd siz = { 0, 0, 0, 0 }; + scaledwhd siz = { .wd = 0, .ht = 0, .dp = 0, .ns = 0 }; while (p) { switch (node_type(p)) { case hlist_node: diff --git a/source/luametatex/source/tex/textypes.h b/source/luametatex/source/tex/textypes.h index 1e83a975f..a3ceea681 100644 --- a/source/luametatex/source/tex/textypes.h +++ b/source/luametatex/source/tex/textypes.h @@ -121,7 +121,10 @@ typedef struct scaledwhd { scaled wd; scaled ht; scaled dp; - scaled ic; /* padding anyway */ + union { + scaled ic; /* padding anyway */ + scaled ns; /* natural size */ + }; } scaledwhd; extern halfword tex_badness( -- cgit v1.2.3