From 23b5ef45e7939a00addff726d02d6c29243177af Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Thu, 23 Feb 2023 21:40:04 +0100 Subject: 2023-02-23 21:26:00 --- source/luametatex/source/lua/lmtinterface.c | 2 + source/luametatex/source/lua/lmtinterface.h | 5 ++ source/luametatex/source/lua/lmtnodelib.c | 8 +++ source/luametatex/source/lua/lmttexlib.c | 42 +++++++------ source/luametatex/source/luametatex.h | 2 +- source/luametatex/source/tex/texcommands.c | 2 + source/luametatex/source/tex/texcommands.h | 1 + source/luametatex/source/tex/texdumpdata.h | 2 +- source/luametatex/source/tex/texequivalents.h | 28 ++------- source/luametatex/source/tex/texmath.c | 33 ++++++++-- source/luametatex/source/tex/texmath.h | 3 + source/luametatex/source/tex/texmlist.c | 79 ++++++++++++++++++++---- source/luametatex/source/tex/texnodes.c | 6 ++ source/luametatex/source/tex/texnodes.h | 86 ++++++++++++++------------- 14 files changed, 197 insertions(+), 102 deletions(-) (limited to 'source') diff --git a/source/luametatex/source/lua/lmtinterface.c b/source/luametatex/source/lua/lmtinterface.c index 9156f0aaf..2c94feb6f 100644 --- a/source/luametatex/source/lua/lmtinterface.c +++ b/source/luametatex/source/lua/lmtinterface.c @@ -435,6 +435,7 @@ void lmt_initialize_interface(void) set_math_parameter_value(math_parameter_delimiter_percent, math_int_parameter, delimiterpercent); set_math_parameter_value(math_parameter_delimiter_shortfall, math_dimen_parameter, delimitershortfall); + set_math_parameter_value(math_parameter_delimiter_extend_margin, math_dimen_parameter, delimiterextendmargin); set_math_parameter_value(math_parameter_over_line_variant, math_style_parameter, overlinevariant); set_math_parameter_value(math_parameter_under_line_variant, math_style_parameter, underlinevariant); @@ -548,4 +549,5 @@ void lmt_initialize_interface(void) set_math_font_parameter(FlattenedAccentBottomShiftDown, math_dimen_parameter); set_math_font_parameter(DelimiterPercent, math_int_parameter); set_math_font_parameter(DelimiterShortfall, math_dimen_parameter); + set_math_font_parameter(DelimiterExtendMargin, math_dimen_parameter); } diff --git a/source/luametatex/source/lua/lmtinterface.h b/source/luametatex/source/lua/lmtinterface.h index 59ef808c8..26481d075 100644 --- a/source/luametatex/source/lua/lmtinterface.h +++ b/source/luametatex/source/lua/lmtinterface.h @@ -560,6 +560,7 @@ make_lua_key(L, data);\ make_lua_key(L, deep_frozen_cs_dont_expand);\ make_lua_key(L, deep_frozen_cs_end_template);\ make_lua_key(L, def);\ +make_lua_key(L, deferred);\ make_lua_key(L, define_char_code);\ make_lua_key(L, define_family);\ make_lua_key(L, define_font);\ @@ -572,6 +573,8 @@ make_lua_key(L, delimiter);\ make_lua_key(L, delimiter_number);\ make_lua_key(L, delimiterover);\ make_lua_key(L, delimiterovervariant);\ +make_lua_key(L, DelimiterExtendMargin);\ +make_lua_key(L, delimiterextendmargin);\ make_lua_key(L, DelimiterPercent);\ make_lua_key(L, delimiterpercent);\ make_lua_key(L, DelimiterShortfall);\ @@ -749,6 +752,7 @@ make_lua_key(L, indentskip);\ make_lua_key(L, index);\ make_lua_key(L, info);\ make_lua_key(L, Info);\ +make_lua_key(L, inherited);\ make_lua_key(L, inner);\ make_lua_key(L, innerlocation);\ make_lua_key(L, innerxoffset);\ @@ -1126,6 +1130,7 @@ make_lua_key(L, ScriptScriptPercentScaleDown);\ make_lua_key(L, scriptscriptscale);\ make_lua_key(L, second);\ make_lua_key(L, semisimple);\ +make_lua_key(L, semiprotected);\ make_lua_key(L, set);\ make_lua_key(L, set_auxiliary);\ make_lua_key(L, set_box);\ diff --git a/source/luametatex/source/lua/lmtnodelib.c b/source/luametatex/source/lua/lmtnodelib.c index 72b9918e4..997115267 100644 --- a/source/luametatex/source/lua/lmtnodelib.c +++ b/source/luametatex/source/lua/lmtnodelib.c @@ -6763,6 +6763,10 @@ static int nodelib_common_getfield(lua_State *L, int direct, halfword n) nodelib_push_direct_or_node(L, direct, radical_left_delimiter(n)); } else if (lua_key_eq(s, right)) { nodelib_push_direct_or_node(L, direct, radical_right_delimiter(n)); + } else if (lua_key_eq(s, top)) { + nodelib_push_direct_or_node(L, direct, radical_top_delimiter(n)); + } else if (lua_key_eq(s, bottom)) { + nodelib_push_direct_or_node(L, direct, radical_bottom_delimiter(n)); } else if (lua_key_eq(s, degree)) { nodelib_push_direct_or_node(L, direct, radical_degree(n)); } else if (lua_key_eq(s, width)) { @@ -7436,6 +7440,10 @@ static int nodelib_common_setfield(lua_State *L, int direct, halfword n) radical_left_delimiter(n) = nodelib_direct_or_node_from_index(L, direct, 3); } else if (lua_key_eq(s, right)) { radical_right_delimiter(n) = nodelib_direct_or_node_from_index(L, direct, 3); + } else if (lua_key_eq(s, top)) { + radical_top_delimiter(n) = nodelib_direct_or_node_from_index(L, direct, 3); + } else if (lua_key_eq(s, bottom)) { + radical_bottom_delimiter(n) = nodelib_direct_or_node_from_index(L, direct, 3); } else if (lua_key_eq(s, degree)) { radical_degree(n) = nodelib_direct_or_node_from_index(L, direct, 3); } else if (lua_key_eq(s, width)) { diff --git a/source/luametatex/source/lua/lmttexlib.c b/source/luametatex/source/lua/lmttexlib.c index 0afd6cdf6..38c8e3fa8 100644 --- a/source/luametatex/source/lua/lmttexlib.c +++ b/source/luametatex/source/lua/lmttexlib.c @@ -4928,23 +4928,28 @@ static int texlib_getautomigrationvalues(lua_State *L) static int texlib_getflagvalues(lua_State *L) { - lua_createtable(L, 2, 15); - lua_push_key_at_index(L, frozen, frozen_flag_bit); - lua_push_key_at_index(L, permanent, permanent_flag_bit); - lua_push_key_at_index(L, immutable, immutable_flag_bit); - lua_push_key_at_index(L, primitive, primitive_flag_bit); - lua_push_key_at_index(L, mutable, mutable_flag_bit); - lua_push_key_at_index(L, noaligned, noaligned_flag_bit); - lua_push_key_at_index(L, instance, instance_flag_bit); - lua_push_key_at_index(L, untraced, untraced_flag_bit); - lua_push_key_at_index(L, global, global_flag_bit); - lua_push_key_at_index(L, tolerant, tolerant_flag_bit); - lua_push_key_at_index(L, protected, protected_flag_bit); - lua_push_key_at_index(L, overloaded, overloaded_flag_bit); - lua_push_key_at_index(L, aliased, aliased_flag_bit); - lua_push_key_at_index(L, immediate, immediate_flag_bit); - lua_push_key_at_index(L, conditional, conditional_flag_bit); - lua_push_key_at_index(L, value, value_flag_bit); + lua_createtable(L, 2, 18); + /* what about the rest */ + lua_push_key_at_index(L, frozen, frozen_flag_bit); + lua_push_key_at_index(L, permanent, permanent_flag_bit); + lua_push_key_at_index(L, immutable, immutable_flag_bit); + lua_push_key_at_index(L, primitive, primitive_flag_bit); + lua_push_key_at_index(L, mutable, mutable_flag_bit); + lua_push_key_at_index(L, noaligned, noaligned_flag_bit); + lua_push_key_at_index(L, instance, instance_flag_bit); + lua_push_key_at_index(L, untraced, untraced_flag_bit); + lua_push_key_at_index(L, global, global_flag_bit); + lua_push_key_at_index(L, tolerant, tolerant_flag_bit); + lua_push_key_at_index(L, protected, protected_flag_bit); + lua_push_key_at_index(L, overloaded, overloaded_flag_bit); + lua_push_key_at_index(L, aliased, aliased_flag_bit); + lua_push_key_at_index(L, immediate, immediate_flag_bit); + lua_push_key_at_index(L, conditional, conditional_flag_bit); + lua_push_key_at_index(L, value, value_flag_bit); + lua_push_key_at_index(L, semiprotected, semiprotected_flag_bit); + lua_push_key_at_index(L, inherited, inherited_flag_bit); + lua_push_key_at_index(L, constant, constant_flag_bit); + lua_push_key_at_index(L, deferred, deferred_flag_bit); return 1; } @@ -5240,7 +5245,7 @@ static int texlib_getdiscstatevalues(lua_State *L) static int texlib_getmathcontrolvalues(lua_State *L) { - lua_createtable(L, 2, 23); + lua_createtable(L, 2, 24); lua_set_string_by_index(L, math_control_use_font_control, "usefontcontrol"); lua_set_string_by_index(L, math_control_over_rule, "overrule"); lua_set_string_by_index(L, math_control_under_rule, "underrule"); @@ -5266,6 +5271,7 @@ static int texlib_getmathcontrolvalues(lua_State *L) lua_set_string_by_index(L, math_control_ignore_kern_dimensions, "ignorekerndimensions"); lua_set_string_by_index(L, math_control_ignore_flat_accents, "ignoreflataccents"); lua_set_string_by_index(L, math_control_extend_accents, "extendaccents"); + lua_set_string_by_index(L, math_control_extend_delimiters, "extenddelimiters"); return 1; } diff --git a/source/luametatex/source/luametatex.h b/source/luametatex/source/luametatex.h index 19175a487..410d4dd68 100644 --- a/source/luametatex/source/luametatex.h +++ b/source/luametatex/source/luametatex.h @@ -92,7 +92,7 @@ # define luametatex_version 210 # define luametatex_revision 06 # define luametatex_version_string "2.10.06" -# define luametatex_development_id 20230209 +# define luametatex_development_id 20230224 # 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 e52825b33..76b171789 100644 --- a/source/luametatex/source/tex/texcommands.c +++ b/source/luametatex/source/tex/texcommands.c @@ -990,6 +990,7 @@ void tex_initialize_commands(void) tex_primitive(luatex_command, "overloaded", prefix_cmd, overloaded_code, 0); tex_primitive(luatex_command, "aliased", prefix_cmd, aliased_code, 0); tex_primitive(luatex_command, "immediate", prefix_cmd, immediate_code, 0); + tex_primitive(luatex_command, "deferred", prefix_cmd, deferred_code, 0); tex_primitive(luatex_command, "semiprotected", prefix_cmd, semiprotected_code, 0); tex_primitive(luatex_command, "enforced", prefix_cmd, enforced_code, 0); tex_primitive(luatex_command, "inherited", prefix_cmd, inherited_code, 0); @@ -1216,6 +1217,7 @@ void tex_initialize_commands(void) /* */ tex_primitive(luatex_command, "Umathdelimiterpercent", set_math_parameter_cmd, math_parameter_delimiter_percent, 0); tex_primitive(luatex_command, "Umathdelimitershortfall", set_math_parameter_cmd, math_parameter_delimiter_shortfall, 0); + tex_primitive(luatex_command, "Umathdelimiterextendmargin", set_math_parameter_cmd, math_parameter_delimiter_extend_margin, 0); /* */ tex_primitive(luatex_command, "Umathoverlinevariant", set_math_parameter_cmd, math_parameter_over_line_variant, 0); tex_primitive(luatex_command, "Umathunderlinevariant", set_math_parameter_cmd, math_parameter_under_line_variant, 0); diff --git a/source/luametatex/source/tex/texcommands.h b/source/luametatex/source/tex/texcommands.h index 57dc30f4f..faeb38247 100644 --- a/source/luametatex/source/tex/texcommands.h +++ b/source/luametatex/source/tex/texcommands.h @@ -831,6 +831,7 @@ typedef enum prefix_codes { overloaded_code, aliased_code, immediate_code, + deferred_code, /* conditional_code */ /* value_code */ semiprotected_code, diff --git a/source/luametatex/source/tex/texdumpdata.h b/source/luametatex/source/tex/texdumpdata.h index 87d987421..847bfa46f 100644 --- a/source/luametatex/source/tex/texdumpdata.h +++ b/source/luametatex/source/tex/texdumpdata.h @@ -55,7 +55,7 @@ */ -# define luametatex_format_fingerprint 684 +# define luametatex_format_fingerprint 686 /* These end up in the string pool. */ diff --git a/source/luametatex/source/tex/texequivalents.h b/source/luametatex/source/tex/texequivalents.h index d64c78807..cc7f74ffc 100644 --- a/source/luametatex/source/tex/texequivalents.h +++ b/source/luametatex/source/tex/texequivalents.h @@ -1163,6 +1163,7 @@ typedef enum flag_bit { semiprotected_flag_bit = 0x10000, inherited_flag_bit = 0x20000, constant_flag_bit = 0x40000, + deferred_flag_bit = 0x80000, /* this might move up */ } flag_bits; /*tex Flags: */ @@ -1185,6 +1186,7 @@ typedef enum flag_bit { # define add_overloaded_flag(a) ((a) | overloaded_flag_bit) # define add_aliased_flag(a) ((a) | aliased_flag_bit) # define add_immediate_flag(a) ((a) | immediate_flag_bit) +# define add_deferred_flag(a) ((a) | deferred_flag_bit) # define add_conditional_flag(a) ((a) | conditional_flag_bit) # define add_value_flag(a) ((a) | value_flag_bit) # define add_inherited_flag(a) ((a) | inherited_flag_bit) @@ -1207,32 +1209,10 @@ typedef enum flag_bit { # define remove_overloaded_flag(a) ((a) & ~overloaded_flag_bit) # define remove_aliased_flag(a) ((a) & ~aliased_flag_bit) # define remove_immediate_flag(a) ((a) & ~immediate_flag_bit) +# define remove_deferred_flag(a) ((a) & ~deferred_flag_bit) # define remove_conditional_flag(a) ((a) & ~conditional_flag_bit) # define remove_value_flag(a) ((a) & ~value_flag_bit) -// do we really need the == here - -// # define is_frozen(a) (((a) & frozen_flag_bit) == frozen_flag_bit) -// # define is_permanent(a) (((a) & permanent_flag_bit) == permanent_flag_bit) -// # define is_immutable(a) (((a) & immutable_flag_bit) == immutable_flag_bit) -// # define is_primitive(a) (((a) & primitive_flag_bit) == primitive_flag_bit) -// # define is_mutable(a) (((a) & mutable_flag_bit) == mutable_flag_bit) -// # define is_noaligned(a) (((a) & noaligned_flag_bit) == noaligned_flag_bit) -// # define is_instance(a) (((a) & instance_flag_bit) == instance_flag_bit) -// # define is_untraced(a) (((a) & untraced_flag_bit) == untraced_flag_bit) -// -// # define is_global(a) (((a) & global_flag_bit) == global_flag_bit) -// # define is_tolerant(a) (((a) & tolerant_flag_bit) == tolerant_flag_bit) -// # define is_protected(a) (((a) & protected_flag_bit) == protected_flag_bit) -// # define is_semiprotected(a) (((a) & semiprotected_flag_bit) == semiprotected_flag_bit) -// # define is_overloaded(a) (((a) & overloaded_flag_bit) == overloaded_flag_bit) -// # define is_aliased(a) (((a) & aliased_flag_bit) == aliased_flag_bit) -// # define is_immediate(a) (((a) & immediate_flag_bit) == immediate_flag_bit) -// # define is_conditional(a) (((a) & conditional_flag_bit) == conditional_flag_bit) -// # define is_value(a) (((a) & value_flag_bit) == value_flag_bit) -// # define is_inherited(a) (((a) & inherited_flag_bit) == inherited_flag_bit) -// # define is_constant(a) (((a) & constant_flag_bit) == constant_flag_bit) - # define is_frozen(a) (((a) & frozen_flag_bit)) # define is_permanent(a) (((a) & permanent_flag_bit)) # define is_immutable(a) (((a) & immutable_flag_bit)) @@ -1249,12 +1229,12 @@ typedef enum flag_bit { # define is_overloaded(a) (((a) & overloaded_flag_bit)) # define is_aliased(a) (((a) & aliased_flag_bit)) # define is_immediate(a) (((a) & immediate_flag_bit)) +# define is_deferred(a) (((a) & deferred_flag_bit)) # define is_conditional(a) (((a) & conditional_flag_bit)) # define is_value(a) (((a) & value_flag_bit)) # define is_inherited(a) (((a) & inherited_flag_bit)) # define is_constant(a) (((a) & constant_flag_bit)) - # define is_expandable(cmd) (cmd > max_command_cmd) # define global_or_local(a) (is_global(a) ? level_one : cur_level) diff --git a/source/luametatex/source/tex/texmath.c b/source/luametatex/source/tex/texmath.c index 0820b2405..1b62a389c 100644 --- a/source/luametatex/source/tex/texmath.c +++ b/source/luametatex/source/tex/texmath.c @@ -1037,7 +1037,7 @@ static void tex_aux_display_simple_noad(halfword n, int threshold, int max) tex_aux_display_common_noad(n, threshold, max); } -static void tex_aux_display_radical_noad(halfword n, int threshold, int max) +static void tex_aux_display_radical_noad(halfword n, int threshold, int max) /* todo: more fields */ { if (noad_width(n)) { tex_print_format(", width %D", noad_width(n), pt_unit); @@ -1071,7 +1071,7 @@ static void tex_aux_display_radical_noad(halfword n, int threshold, int max) tex_aux_display_common_noad(n, threshold, max); } -static void tex_aux_display_accent_noad(halfword n, int threshold, int max) +static void tex_aux_display_accent_noad(halfword n, int threshold, int max) /* todo: more fields */ { halfword top_char = accent_top_character(n); halfword bottom_char = accent_bottom_character(n); @@ -1129,7 +1129,7 @@ static void tex_aux_display_accent_noad(halfword n, int threshold, int max) tex_aux_display_common_noad(n, threshold, max); } -static void tex_aux_display_fence_noad(halfword n, int threshold, int max) +static void tex_aux_display_fence_noad(halfword n, int threshold, int max) /* todo: more fields */ { if (noad_height(n)) { tex_print_format(", height %D", noad_height(n), pt_unit); @@ -1163,7 +1163,7 @@ static void tex_aux_display_fence_noad(halfword n, int threshold, int max) tex_print_node_list(fence_delimiter_bottom(n), "bottom", threshold, max); } -static void tex_aux_display_fraction_noad(halfword n, int threshold, int max) +static void tex_aux_display_fraction_noad(halfword n, int threshold, int max) /* todo: more fields */ { halfword leftdelimiter = tex_aux_valid_delimiter(fraction_left_delimiter(n)); halfword rightdelimiter = tex_aux_valid_delimiter(fraction_right_delimiter(n)); @@ -2660,9 +2660,11 @@ void tex_run_math_radical(void) halfword variant = 0; /* quad, harmless */ halfword attrlist = null; tex_tail_append(radical); + halfword top = null; + halfword bottom = null; /* only kewords to UI ones? */ while (1) { - switch (tex_scan_character("abeswlmrhndABESWLMRHDN", 0, 1, 0)) { + switch (tex_scan_character("abeswlmrhndtABESWLMRHDNT", 0, 1, 0)) { case 0: goto DONE; case 'a': case 'A': @@ -2675,6 +2677,16 @@ void tex_run_math_radical(void) options = options | noad_option_exact; } break; + case 'b': case 'B': + if (tex_scan_mandate_keyword("bottom", 1)) { + bottom = 1; + } + break; + case 't': case 'T': + if (tex_scan_mandate_keyword("top", 1)) { + top = 1; + } + break; case 's': case 'S': switch (tex_scan_character("itoITO", 0, 0, 0)) { case 't': case 'T': @@ -2824,6 +2836,16 @@ void tex_run_math_radical(void) tex_confusion("scan math radical"); break; } + if (top) { + top = tex_new_node(delimiter_node, 0); + radical_top_delimiter(radical) = top; + tex_aux_scan_delimiter(top, umath_mathcode, unset_noad_class); + } + if (bottom) { + bottom = tex_new_node(delimiter_node, 0); + radical_bottom_delimiter(radical) = bottom; + tex_aux_scan_delimiter(bottom, umath_mathcode, unset_noad_class); + } } switch (code) { case h_extensible_radical_subtype: @@ -5199,6 +5221,7 @@ void tex_fixup_math_parameters(int fam, int size, int f, int level) tex_aux_define_all_math_parameters(size, math_parameter_flattened_accent_bottom_shift_down, math_parameter(f, FlattenedAccentBottomShiftDown), level); /* engine, undefined */ tex_aux_define_all_math_parameters(size, math_parameter_delimiter_percent, math_parameter(f, DelimiterPercent), level); /* engine, undefined */ tex_aux_define_all_math_parameters(size, math_parameter_delimiter_shortfall, math_parameter(f, DelimiterShortfall), level); /* engine, undefined */ + tex_aux_define_all_math_parameters(size, math_parameter_delimiter_extend_margin, math_parameter(f, DelimiterExtendMargin), level); /* engine, undefined */ tex_aux_define_all_math_parameters(size, math_parameter_radical_extensible_after, math_parameter(f, RadicalKernAfterExtensible), level); /* engine, undefined */ tex_aux_define_all_math_parameters(size, math_parameter_radical_extensible_before, math_parameter(f, RadicalKernBeforeExtensible), level); /* engine, undefined */ diff --git a/source/luametatex/source/tex/texmath.h b/source/luametatex/source/tex/texmath.h index 79f40c13b..ba02e8373 100644 --- a/source/luametatex/source/tex/texmath.h +++ b/source/luametatex/source/tex/texmath.h @@ -169,6 +169,7 @@ typedef enum math_parameters { /* */ math_parameter_delimiter_percent, math_parameter_delimiter_shortfall, + math_parameter_delimiter_extend_margin, /* */ math_parameter_over_line_variant, math_parameter_under_line_variant, @@ -514,6 +515,7 @@ typedef enum math_parameter_codes { FlattenedAccentBottomShiftDown, DelimiterPercent, DelimiterShortfall, + DelimiterExtendMargin, /* done */ math_parameter_last_code, } math_parameter_codes; @@ -682,6 +684,7 @@ typedef enum math_control_codes { math_control_ignore_kern_dimensions = 0x0400000, /* for bad fonts (like xits fence depths) */ math_control_ignore_flat_accents = 0x0800000, math_control_extend_accents = 0x1000000, + math_control_extend_delimiters = 0x2000000, } math_control_codes; /*tex This is what we use for \OPENTYPE\ in \CONTEXT: */ diff --git a/source/luametatex/source/tex/texmlist.c b/source/luametatex/source/tex/texmlist.c index 8409f8df3..56b780506 100644 --- a/source/luametatex/source/tex/texmlist.c +++ b/source/luametatex/source/tex/texmlist.c @@ -309,6 +309,21 @@ inline static void tex_aux_make_style(halfword current, halfword *current_style, } } +/*tex + There is no need to be more subtle, if needed we can always do some extensive checking for the + combined styles. Basically this is just a catch for |\allmathstyles|. Also keep in mind that + there no grouping inside a formula: we can cook up something but in the end one always has some + synchronization problem because the next atom is likely outside the group anyway. +*/ + +inline static void tex_aux_set_parameter(halfword current, halfword style) +{ + if (is_valid_math_style(node_subtype(current))) { + style = node_subtype(current); + } + tex_def_math_parameter(style, parameter_name(current), parameter_value(current), cur_level + lmt_math_state.level, indirect_math_regular); +} + void tex_set_math_text_font(halfword style, int usetextfont) { halfword size = tex_aux_set_style_to_size(style); @@ -753,9 +768,20 @@ static halfword tex_aux_fraction_rule(scaled width, scaled height, halfword att, */ -static halfword tex_aux_overbar(halfword box, scaled gap, scaled height, scaled krn, halfword att, quarterword index, halfword size, halfword fam) +static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int size, scaled targetsize, int flat, int style, int shift, int *stack, scaled *delta, scaled tolerance, int nooverflow, delimiterextremes *extremes, scaled move); + +static halfword tex_aux_overbar(halfword box, scaled gap, scaled height, scaled krn, halfword att, quarterword index, halfword size, halfword fam, halfword topdelimiter, halfword style) { - halfword rule = tex_aux_fraction_rule(box_width(box), height, att, index, size, fam); + halfword rule = topdelimiter + ? tex_aux_make_delimiter(null, topdelimiter, size, box_width(box), 1, style, 0, NULL, NULL, 0, 0, NULL, 0) + : tex_aux_fraction_rule(box_width(box), height, att, index, size, fam); + /*tex Safeguard: */ + if (topdelimiter && box_width(rule) > box_width(box)) { + halfword delta = (box_width(rule) - box_width(box)) / 2; + tex_aux_prepend_hkern_to_box_list(box, delta, horizontal_math_kern_subtype, "narrow delimiter"); + tex_aux_append_hkern_to_box_list(box, delta, horizontal_math_kern_subtype, "narrow delimiter"); + box_width(box) = box_width(rule); + } if (gap) { halfword kern = tex_new_kern_node(gap, vertical_math_kern_subtype); tex_attach_attribute_list_attribute(kern, att); @@ -1504,6 +1530,24 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int added. See (**). */ result = tex_aux_char_box(fnt, chr, att, delta, glyph_math_delimiter_subtype, flat ? targetsize : 0, style); + if (flat) { + /* This will be done when we have a reasonable example. */ + } else { + if (box_total(result) < targetsize && tex_aux_math_engine_control(fnt, math_control_extend_delimiters) && tex_char_has_tag_from_font(fnt, chr, extend_last_tag)) { + halfword glyph = box_list(result); + if (glyph && node_type(glyph) == glyph_node) { + scaled margin = tex_get_math_y_parameter_default(style, math_parameter_delimiter_extend_margin, 0); + scaled amount = targetsize - 2 * margin; + if (amount > 0) { + double ratio = (double) amount/box_total(result); + glyph_y_scale(glyph) = lround((double) glyph_y_scale(glyph) * ratio); + glyph_y_offset(glyph) = lround((double) box_total(glyph) * ratio); + box_height(result) = lround((double) box_height(result) * ratio); + box_depth(result) = lround((double) box_depth(result) * ratio); + } + } + } + } if (stack) { *stack = 0 ; } @@ -1532,7 +1576,7 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int } } if (do_parts) { - if (has_noad_option_phantom(target) || has_noad_option_void(target)) { + if (target && (has_noad_option_phantom(target) || has_noad_option_void(target))) { result = tex_aux_make_list_phantom(result, has_noad_option_void(target), att); } else { result = register_extensible(fnt, chr, size, result, att); @@ -2158,7 +2202,8 @@ static void tex_aux_make_over(halfword target, halfword style, halfword size, ha halfword result = tex_aux_overbar( tex_aux_clean_box(noad_nucleus(target), tex_math_style_variant(style, math_parameter_over_line_variant), style, math_nucleus_list, 0, NULL), vgap, thickness, kern, - get_attribute_list(noad_nucleus(target)), math_over_rule_subtype, size, fam + get_attribute_list(noad_nucleus(target)), math_over_rule_subtype, size, fam, + null, style ); node_subtype(result) = math_over_list; kernel_math_list(noad_nucleus(target)) = result; @@ -2324,6 +2369,7 @@ static void tex_aux_make_root_radical(halfword target, int style, int size, kern scaled fam = delimiter_small_family(radical_left_delimiter(target)); halfword leftdelimiter = radical_left_delimiter(target); halfword rightdelimiter = radical_right_delimiter(target); + halfword topdelimiter = radical_top_delimiter(target); halfword delimiter = leftdelimiter ? leftdelimiter : rightdelimiter; halfword companion = leftdelimiter ? rightdelimiter : null; halfword radical = null; @@ -2411,7 +2457,7 @@ static void tex_aux_make_root_radical(halfword target, int style, int size, kern } { halfword total = box_total(delimiter); - halfword list = tex_aux_overbar(nucleus, clearance, theta, kern, get_attribute_list(delimiter), math_radical_rule_subtype, size, fam); + halfword list = tex_aux_overbar(nucleus, clearance, theta, kern, get_attribute_list(delimiter), math_radical_rule_subtype, size, fam, topdelimiter, style); radical = tex_aux_link_radical(list, delimiter, companion, rightdelimiter); if (radical_degree(target)) { halfword degree = tex_aux_clean_box(radical_degree(target), script_script_style, style, math_degree_list, 0, NULL); @@ -3501,9 +3547,16 @@ static halfword tex_aux_make_stretched_fraction(halfword target, int style, int if (box_width(middle) < box_width(fraction)) { /*tex It's always in the details: */ scaled delta = (box_width(fraction) - box_width(middle)) / 2; - tex_aux_prepend_hkern_to_box_list(middle, delta, horizontal_math_kern_subtype, "bad delimiter"); - tex_aux_append_hkern_to_box_list(middle, delta, horizontal_math_kern_subtype, "bad delimiter"); + tex_aux_prepend_hkern_to_box_list(middle, delta, horizontal_math_kern_subtype, "narrow delimiter"); + tex_aux_append_hkern_to_box_list(middle, delta, horizontal_math_kern_subtype, "narrow delimiter"); box_width(middle) = box_width(fraction); + } else if (box_width(middle) > box_width(fraction)) { + scaled delta = (box_width(middle) - box_width(fraction)) / 2; + tex_aux_prepend_hkern_to_box_list(numerator, delta, horizontal_math_kern_subtype, "wide delimiter"); + tex_aux_append_hkern_to_box_list(numerator, delta, horizontal_math_kern_subtype, "wide delimiter"); + tex_aux_prepend_hkern_to_box_list(denominator, delta, horizontal_math_kern_subtype, "wide delimiter"); + tex_aux_append_hkern_to_box_list(denominator, delta, horizontal_math_kern_subtype, "wide delimiter"); + box_width(fraction) = box_width(middle); } tex_aux_compensate_fraction_rule(target, fraction, middle, thickness); box_list(fraction) = tex_aux_assemble_fraction(target, style, size, numerator, denominator, middle, delta, shift_up, shift_down); @@ -4950,7 +5003,7 @@ static void tex_aux_make_scripts(halfword target, halfword kernel, scaled italic } } /*tex - Each of the scripts gets treated. Traditionally a super and subscript are looked and and + Each of the scripts gets treated. Traditionally a super and subscript are looked at and vercially spaced out together which in turn results in the staricase kerns needing that information. Prescripts we handle differently: they are always aligned, so there the maximum kern wins. @@ -6337,7 +6390,7 @@ static void tex_mlist_to_hlist_preroll_radicals(mliststate *state) tex_aux_make_style(current, ¤t_style, NULL); break; case parameter_node: - tex_def_math_parameter(node_subtype(current), parameter_name(current), parameter_value(current), cur_level + lmt_math_state.level, indirect_math_regular); + tex_aux_set_parameter(current, current_style); break; } current = node_next(current); @@ -6530,7 +6583,7 @@ static void tex_mlist_to_hlist_preroll_dimensions(mliststate *state) goto DONE_WITH_NODE; case parameter_node: /* maybe not needed as we do a first pass */ - tex_def_math_parameter(node_subtype(current), parameter_name(current), parameter_value(current), cur_level + lmt_math_state.level, indirect_math_regular); + tex_aux_set_parameter(current, current_style); goto DONE_WITH_NODE; case insert_node: case mark_node: @@ -6612,7 +6665,7 @@ static void tex_mlist_to_hlist_size_fences(mliststate *state) break; case parameter_node: /* tricky as this is sort of persistent, we need to reset it at the start */ - tex_def_math_parameter(node_subtype(current), parameter_name(current), parameter_value(current), cur_level + lmt_math_state.level, indirect_math_regular); + tex_aux_set_parameter(current, current_style); break; } current = node_next(current); @@ -6788,7 +6841,7 @@ static void tex_mlist_to_hlist_finalize_list(mliststate *state) tex_aux_wipe_noad(recent); goto RESTART; case parameter_node: - tex_def_math_parameter(node_subtype(current), parameter_name(current), parameter_value(current), cur_level + lmt_math_state.level, indirect_math_regular); + tex_aux_set_parameter(current, current_style); recent = current; current = node_next(current); tex_aux_wipe_noad(recent); @@ -6910,7 +6963,7 @@ static void tex_mlist_to_hlist_finalize_list(mliststate *state) } if (current_type == simple_noad) { pre_penalty = tex_aux_math_penalty(state->main_style, 1, current_subtype); - post_penalty = tex_aux_math_penalty(state->main_style,0, current_subtype); + post_penalty = tex_aux_math_penalty(state->main_style, 0, current_subtype); } /*tex Dirty trick: */ /* todo: use kerns info */ current_plus_glyph = tex_aux_get_plus_glyph(current); diff --git a/source/luametatex/source/tex/texnodes.c b/source/luametatex/source/tex/texnodes.c index 625a4346b..09aa74d57 100644 --- a/source/luametatex/source/tex/texnodes.c +++ b/source/luametatex/source/tex/texnodes.c @@ -1205,6 +1205,8 @@ halfword tex_copy_node(halfword p) /* how about null */ case radical_noad: copy_sub_node(radical_left_delimiter(r), radical_left_delimiter(p)) ; copy_sub_node(radical_right_delimiter(r), radical_right_delimiter(p)) ; + copy_sub_node(radical_top_delimiter(r), radical_top_delimiter(p)) ; + copy_sub_node(radical_bottom_delimiter(r), radical_bottom_delimiter(p)) ; copy_sub_list(radical_degree(r), radical_degree(p)) ; break; case fraction_noad: @@ -1394,6 +1396,8 @@ void tex_flush_node(halfword p) case radical_noad: tex_aux_free_sub_node(radical_left_delimiter(p)); tex_aux_free_sub_node(radical_right_delimiter(p)); + tex_aux_free_sub_node(radical_top_delimiter(p)); + tex_aux_free_sub_node(radical_bottom_delimiter(p)); tex_aux_free_sub_node_list(radical_degree(p)); break; case accent_noad: @@ -1510,6 +1514,8 @@ static void tex_aux_check_node(halfword p) tex_aux_node_range_test(p, radical_degree(p)); tex_aux_node_range_test(p, radical_left_delimiter(p)); tex_aux_node_range_test(p, radical_right_delimiter(p)); + tex_aux_node_range_test(p, radical_top_delimiter(p)); + tex_aux_node_range_test(p, radical_bottom_delimiter(p)); break; case fraction_noad: // tex_aux_node_range_test(p, fraction_numerator(p)); diff --git a/source/luametatex/source/tex/texnodes.h b/source/luametatex/source/tex/texnodes.h index e19ff933d..f3f9276a6 100644 --- a/source/luametatex/source/tex/texnodes.h +++ b/source/luametatex/source/tex/texnodes.h @@ -1576,36 +1576,38 @@ typedef enum simple_choice_subtypes { \starttabulate[|l|l|l|l|l|l|] \FL - \BC \BC noad \BC accent \BC fraction \BC radical \NC fence \NC \NR - \ML \NC - \NC vlink 2 \NC new_hlist \NC \NC \NC \NC \NC \NR - \ML \NC - \NC vinfo 2 \NC nucleus \NC \NC \NC \NC \NC \NR - \NC vlink 3 \NC supscr \NC \NC numerator \NC \NC \NC \NR - \NC vinfo 3 \NC subscr \NC \NC denominator \NC \NC \NC \NR - \NC vlink 4 \NC supprescr \NC \NC \NC \NC \NC \NR - \NC vinfo 4 \NC subprescr \NC \NC \NC \NC \NC \NR - \ML \NC - \NC vlink 5 \NC italic \NC \NC \NC \NC \NC \NR - \NC vinfo 5 \NC width \NC \NC \NC \NC \NC \NR - \NC vlink 6 \NC height \NC \NC \NC \NC \NC \NR - \NC vinfo 6 \NC depth \NC \NC \NC \NC \NC \NR - \ML \NC - \NC vlink 7 \NC options \NC \NC \NC \NC \NC \NR - \NC vinfo 7 \NC style \NC \NC \NC \NC \NC \NR - \NC vlink 8 \NC family \NC \NC \NC \NC \NC \NR - \NC vinfo 8 \NC class \NC \NC \NC \NC \NC \NR - \NC vlink 9 \NC source \NC \NC \NC \NC \NC \NR - \NC vinfo 9 \NC prime \NC \NC \NC \NC \NC \NR - \NC vlink 10 \NC leftslack \NC \NC \NC \NC \NC \NR - \NC vinfo 10 \NC rightslack \NC \NC \NC \NC \NC \NR - \ML \NC - \NC vlink 11 \NC extra_1 \NC top_character \NC rule_thickness \NC degree \NC list \NC \NR - \NC vinfo 11 \NC extra_2 \NC bot_character \NC left_delimiter \NC left_delimiter \NC source \NC \NR - \NC vlink 12 \NC extra_3 \NC overlay_character \NC right_delimiter \NC right_delimiter \NC top \NC \NR - \NC vinfo 12 \NC extra_4 \NC fraction \NC middle_delimiter \NC \NC bottom \NC \NR - \NC vlink 13 \NC extra_5 \NC topovershoot \NC \NC height \NC topovershoot \NC \NR - \NC vinfo 13 \NC extra_6 \NC botovershoot \NC \NC depth \NC botovershoot \NC \NR + \BC \BC noad \BC accent \BC fraction \BC radical \NC fence \NC \NR + \ML + \NC vlink 2 \NC new_hlist \NC \NC \NC \NC \NC \NR + \ML + \NC vinfo 2 \NC nucleus \NC \NC \NC \NC \NC \NR + \NC vlink 3 \NC supscr \NC \NC \NC \NC \NC \NR + \NC vinfo 3 \NC subscr \NC \NC \NC \NC \NC \NR + \NC vlink 4 \NC supprescr \NC \NC \NC \NC \NC \NR + \NC vinfo 4 \NC subprescr \NC \NC \NC \NC \NC \NR + \ML + \NC vlink 5 \NC italic \NC \NC \NC \NC \NC \NR + \NC vinfo 5 \NC width \NC \NC \NC \NC \NC \NR + \NC vlink 6 \NC height \NC \NC \NC \NC \NC \NR + \NC vinfo 6 \NC depth \NC \NC \NC \NC \NC \NR + \ML + \NC vlink 7 \NC options \NC \NC \NC \NC \NC \NR + \NC vinfo 7 \NC style \NC \NC \NC \NC \NC \NR + \NC vlink 8 \NC family \NC \NC \NC \NC \NC \NR + \NC vinfo 8 \NC class \NC \NC \NC \NC \NC \NR + \NC vlink 9 \NC source \NC \NC \NC \NC \NC \NR + \NC vinfo 9 \NC prime \NC \NC \NC \NC \NC \NR + \NC vlink 10 \NC leftslack \NC \NC \NC \NC \NC \NR + \NC vinfo 10 \NC rightslack \NC \NC \NC \NC \NC \NR + \ML + \NC vlink 11 \NC extra_1 \NC top_character \NC rule_thickness \NC degree \NC list \NC \NR + \NC vinfo 11 \NC extra_2 \NC bot_character \NC left_delimiter \NC left_delimiter \NC source \NC \NR + \NC vlink 12 \NC extra_3 \NC overlay_character \NC right_delimiter \NC right_delimiter \NC top \NC \NR + \NC vinfo 12 \NC extra_4 \NC fraction \NC middle_delimiter \NC size \NC bottom \NC \NR + \NC vlink 13 \NC extra_5 \NC topovershoot \NC h_factor \NC height \NC topovershoot \NC \NR + \NC vinfo 13 \NC extra_6 \NC botovershoot \NC v_factor \NC depth \NC botovershoot \NC \NR + \NC vlink 14 \NC extra_7 \NC \NC numerator \NC top_delimiter \NC \NC \NR + \NC vinfo 14 \NC extra_8 \NC \NC denominator \NC bottom_delimiter \NC \NC \NR \LL \stoptabulate @@ -1627,7 +1629,7 @@ typedef enum simple_choice_subtypes { //define noad_state_toptotal(a) vlink(a,5) //define noad_state_bottomtotal(a) vinfo(a,5) -# define noad_size 14 +# define noad_size 15 # define noad_new_hlist(a) vlink(a,2) /*tex the translation of an mlist; a bit confusing name */ # define noad_nucleus(a) vinfo(a,2) # define noad_supscr(a) vlink(a,3) @@ -1663,6 +1665,8 @@ typedef enum simple_choice_subtypes { # define noad_extra_4(a) vinfo(a,12) # define noad_extra_5(a) vlink(a,13) # define noad_extra_6(a) vinfo(a,13) +# define noad_extra_7(a) vlink(a,14) +# define noad_extra_8(a) vinfo(a,14) # define noad_total(a) (noad_height(a) + noad_depth(a)) @@ -1980,14 +1984,14 @@ typedef enum fence_subtypes { */ # define fraction_noad_size noad_size -# define fraction_numerator noad_supprescr /* ! */ -# define fraction_denominator noad_subprescr /* ! */ # define fraction_rule_thickness noad_extra_1 # define fraction_left_delimiter noad_extra_2 # define fraction_right_delimiter noad_extra_3 # define fraction_middle_delimiter noad_extra_4 # define fraction_h_factor noad_extra_5 # define fraction_v_factor noad_extra_6 +# define fraction_numerator noad_extra_7 +# define fraction_denominator noad_extra_8 typedef enum fraction_subtypes { over_fraction_subtype, @@ -2004,13 +2008,15 @@ typedef enum fraction_subtypes { used for extensibles (over, under, etc) so the name is is somewhat confusing. */ -# define radical_noad_size noad_size -# define radical_degree noad_extra_1 -# define radical_left_delimiter noad_extra_2 -# define radical_right_delimiter noad_extra_3 -# define radical_size noad_extra_4 -# define radical_height noad_extra_5 -# define radical_depth noad_extra_6 +# define radical_noad_size noad_size +# define radical_degree noad_extra_1 +# define radical_left_delimiter noad_extra_2 +# define radical_right_delimiter noad_extra_3 +# define radical_size noad_extra_4 +# define radical_height noad_extra_5 +# define radical_depth noad_extra_6 +# define radical_top_delimiter noad_extra_7 +# define radical_bottom_delimiter noad_extra_8 typedef enum radical_subtypes { normal_radical_subtype, -- cgit v1.2.3