diff options
Diffstat (limited to 'source/luametatex/source/tex')
-rw-r--r-- | source/luametatex/source/tex/texcommands.c | 3 | ||||
-rw-r--r-- | source/luametatex/source/tex/texdumpdata.h | 2 | ||||
-rw-r--r-- | source/luametatex/source/tex/texequivalents.h | 4 | ||||
-rw-r--r-- | source/luametatex/source/tex/texfont.c | 14 | ||||
-rw-r--r-- | source/luametatex/source/tex/texfont.h | 1 | ||||
-rw-r--r-- | source/luametatex/source/tex/texmaincontrol.c | 9 | ||||
-rw-r--r-- | source/luametatex/source/tex/texmath.c | 6 | ||||
-rw-r--r-- | source/luametatex/source/tex/texmlist.c | 117 | ||||
-rw-r--r-- | source/luametatex/source/tex/texnodes.c | 2 | ||||
-rw-r--r-- | source/luametatex/source/tex/texscanning.c | 72 | ||||
-rw-r--r-- | source/luametatex/source/tex/textypes.h | 41 |
11 files changed, 211 insertions, 60 deletions
diff --git a/source/luametatex/source/tex/texcommands.c b/source/luametatex/source/tex/texcommands.c index 76b171789..0eb084296 100644 --- a/source/luametatex/source/tex/texcommands.c +++ b/source/luametatex/source/tex/texcommands.c @@ -277,7 +277,8 @@ void tex_initialize_commands(void) tex_primitive(luatex_command, "alignmentwrapsource", internal_int_cmd, alignment_wrap_source_code, internal_int_base); /* tex_primitive(luatex_command, "pageboundarypenalty", internal_int_cmd, page_boundary_penalty_code, internal_int_base); */ tex_primitive(luatex_command, "linebreakcriterium", internal_int_cmd, line_break_criterium_code, internal_int_base); - + tex_primitive(luatex_command, "eufactor", internal_int_cmd, eu_factor_code, internal_int_base); + /*tex dimensions */ tex_primitive(tex_command, "boxmaxdepth", internal_dimen_cmd, box_max_depth_code, internal_dimen_base); diff --git a/source/luametatex/source/tex/texdumpdata.h b/source/luametatex/source/tex/texdumpdata.h index 847bfa46f..a7b51e924 100644 --- a/source/luametatex/source/tex/texdumpdata.h +++ b/source/luametatex/source/tex/texdumpdata.h @@ -55,7 +55,7 @@ */ -# define luametatex_format_fingerprint 686 +# define luametatex_format_fingerprint 687 /* These end up in the string pool. */ diff --git a/source/luametatex/source/tex/texequivalents.h b/source/luametatex/source/tex/texequivalents.h index cc7f74ffc..c93c1dd04 100644 --- a/source/luametatex/source/tex/texequivalents.h +++ b/source/luametatex/source/tex/texequivalents.h @@ -578,6 +578,7 @@ typedef enum int_codes { compatible anyway. Lesson learned. */ variable_family_code, + eu_factor_code, /* those below these are not interfaced via primitives */ internal_par_state_code, internal_dir_state_code, @@ -607,7 +608,7 @@ typedef enum int_codes { } int_codes; # define first_int_code pre_tolerance_code -# define last_int_code variable_family_code +# define last_int_code eu_factor_code typedef enum dimen_codes { par_indent_code, /*tex indentation of paragraphs */ @@ -1372,6 +1373,7 @@ extern void tex_forced_word_define (int g, halfword p, singleword flag, halfword # define cur_fam_par count_parameter(family_code) # define variable_family_par count_parameter(variable_family_code) +# define eu_factor_par count_parameter(eu_factor_code) # define pre_display_direction_par count_parameter(pre_display_direction_code) # define pre_display_penalty_par count_parameter(pre_display_penalty_code) # define post_display_penalty_par count_parameter(post_display_penalty_code) diff --git a/source/luametatex/source/tex/texfont.c b/source/luametatex/source/tex/texfont.c index 0f1cf6117..b274b3ae9 100644 --- a/source/luametatex/source/tex/texfont.c +++ b/source/luametatex/source/tex/texfont.c @@ -1887,6 +1887,20 @@ extinfo *tex_char_extensible_recipe_from_font(halfword f, halfword c) return ci->math ? ci->math->extensible_recipe : NULL; } +extinfo *tex_char_extensible_recipe_front_last(halfword f, halfword c) +{ + charinfo *ci = tex_aux_char_info(f, c); + while (ci) { + halfword next = ci->math ? ci->math->next : -1; + if (next > 0) { // no zero + ci = tex_aux_char_info(f, c); + } else { + return ci->math ? ci->math->extensible_recipe : NULL; + } + } + return NULL; +} + scaled tex_char_left_margin_from_font(halfword f, halfword c) { charinfo *ci = tex_aux_char_info(f, c); diff --git a/source/luametatex/source/tex/texfont.h b/source/luametatex/source/tex/texfont.h index 0d3fa9fb3..2adadf45d 100644 --- a/source/luametatex/source/tex/texfont.h +++ b/source/luametatex/source/tex/texfont.h @@ -600,6 +600,7 @@ extern scaled tex_char_bottom_margin_from_font (halfword f, halfword c) extern scaled tex_char_top_overshoot_from_font (halfword f, halfword c); extern scaled tex_char_bottom_overshoot_from_font (halfword f, halfword c); extern extinfo *tex_char_extensible_recipe_from_font (halfword f, halfword c); +extern extinfo *tex_char_extensible_recipe_front_last (halfword f, halfword c); extern halfword tex_char_unchecked_top_anchor_from_font (halfword f, halfword c); extern halfword tex_char_unchecked_bottom_anchor_from_font (halfword f, halfword c); diff --git a/source/luametatex/source/tex/texmaincontrol.c b/source/luametatex/source/tex/texmaincontrol.c index 8af8020a7..e901906c4 100644 --- a/source/luametatex/source/tex/texmaincontrol.c +++ b/source/luametatex/source/tex/texmaincontrol.c @@ -5938,6 +5938,14 @@ void tex_assign_internal_int_value(int a, halfword p, int val) } goto DEFINE; */ + case eu_factor_code: + if (val < 1) { + val = 1; + } else if (val > 50) { + val = 50; + } + tex_word_define(a, p, val); + break; default: DEFINE: tex_word_define(a, p, val); @@ -6576,6 +6584,7 @@ void tex_initialize_variables(void) math_font_control_par = assumed_math_control; math_eqno_gap_step_par = default_eqno_gap_step; px_dimen_par = one_bp; + eu_factor_par = 1000; show_node_details_par = 2; /*tex $>1$: |[subtype]| $>2$: |[attributes]| */ ex_hyphen_char_par = '-'; escape_char_par = '\\'; diff --git a/source/luametatex/source/tex/texmath.c b/source/luametatex/source/tex/texmath.c index 0e52f7c70..7ace4f113 100644 --- a/source/luametatex/source/tex/texmath.c +++ b/source/luametatex/source/tex/texmath.c @@ -1763,10 +1763,10 @@ static int tex_aux_scan_active_math_char(mathcodeval *mval, int where) return 0; case active_char_cmd: /*tex - We reset the code so that we don't get a loop, whuich means that the macro that + We reset the code so that we don't get a loop, which means that the macro that gets invoked has to set the amcode again if needed. */ - tex_set_am_code(character, other_char_cmd, 0); + tex_set_am_code(character, other_char_cmd, cur_level); cur_cs = tex_active_to_cs(cur_chr, 1); cur_cmd = eq_type(cur_cs); cur_chr = eq_value(cur_cs); @@ -1783,7 +1783,7 @@ static int tex_aux_scan_active_math_char(mathcodeval *mval, int where) return 1; } } else if (mval->class_value == active_math_class_value) { - /*tex We might eventually drop tthis feature in favor of the amcode. */ + /*tex We might eventually drop this feature in favor of the amcode. */ cur_cs = tex_active_to_cs(cur_chr, 1); cur_cmd = eq_type(cur_cs); cur_chr = eq_value(cur_cs); diff --git a/source/luametatex/source/tex/texmlist.c b/source/luametatex/source/tex/texmlist.c index 3b7734ccf..53a0bd198 100644 --- a/source/luametatex/source/tex/texmlist.c +++ b/source/luametatex/source/tex/texmlist.c @@ -631,6 +631,31 @@ static void tex_aux_fake_delimiter(halfword result) } /*tex + A few helpers: +*/ + +inline static int tex_aux_has_delimiter(halfword delimiter, halfword size) +{ + return ( + delimiter && ( + (tex_fam_fnt(delimiter_small_family(delimiter), size) && delimiter_small_character(delimiter)) || + (tex_fam_fnt(delimiter_large_family(delimiter), size) && delimiter_large_character(delimiter)) + ) + ); +} + +static inline int tex_aux_has_extensible(halfword delimiter, halfword size) +{ + if (delimiter && delimiter_small_character(delimiter)) { + halfword curfnt = tex_fam_fnt(delimiter_small_family(delimiter), size); + if (curfnt != null_font) { + return tex_char_extensible_recipe_front_last(curfnt, delimiter_small_character(delimiter)) ? 1 : 0; + } + } + return 0; +} + +/*tex A variant on a suggestion on the list based on analysis by Ulrik Vieth it in the mean adapted. We keep these 500 and 2 because then we can use similar values. */ @@ -772,7 +797,7 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int 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 = topdelimiter + halfword rule = (topdelimiter && tex_aux_has_extensible(topdelimiter, size)) ? 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: */ @@ -801,9 +826,11 @@ static halfword tex_aux_overbar(halfword box, scaled gap, scaled height, scaled return rule; } -static halfword tex_aux_underbar(halfword box, scaled gap, scaled height, scaled krn, halfword att, quarterword index, halfword size, halfword fam) +static halfword tex_aux_underbar(halfword box, scaled gap, scaled height, scaled krn, halfword att, quarterword index, halfword size, halfword fam, halfword botdelimiter, halfword style) { - halfword rule = tex_aux_fraction_rule(box_width(box), height, att, index, size, fam); + halfword rule = (botdelimiter && tex_aux_has_extensible(botdelimiter, size)) + ? tex_aux_make_delimiter(null, botdelimiter, 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); if (gap) { halfword kern = tex_new_kern_node(gap, vertical_math_kern_subtype); tex_attach_attribute_list_attribute(kern, att); @@ -1403,8 +1430,7 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int extremes->height = 0; extremes->depth = 0; } - if (delimiter && ! delimiter_small_family(delimiter) && ! delimiter_small_character(delimiter) - && ! delimiter_large_family(delimiter) && ! delimiter_large_character(delimiter)) { + if (! tex_aux_has_delimiter(delimiter, size)) { halfword result = tex_new_null_box_node(hlist_node, math_v_delimiter_list); tex_attach_attribute_list_copy(result, delimiter); if (! flat) { @@ -2248,7 +2274,8 @@ static void tex_aux_make_under(halfword target, halfword style, halfword size, h halfword result = tex_aux_underbar( tex_aux_clean_box(noad_nucleus(target), tex_math_style_variant(style, math_parameter_under_line_variant), style, math_nucleus_list, 0, NULL), vgap, thickness, kern, - get_attribute_list(noad_nucleus(target)), math_under_rule_subtype, size, fam + get_attribute_list(noad_nucleus(target)), math_under_rule_subtype, size, fam, + null, style ); node_subtype(result) = math_over_list; kernel_math_list(noad_nucleus(target)) = result; @@ -3566,42 +3593,6 @@ static halfword tex_aux_make_skewed_fraction(halfword target, int style, int siz return fraction; } -static halfword tex_aux_make_stretched_fraction(halfword target, int style, int size, kernset *kerns) -{ - halfword middle = null; - halfword numerator = null; - halfword denominator = null; - scaled shift_up = 0; - scaled shift_down = 0; - scaled delta = 0; - halfword middle_delimiter = fraction_middle_delimiter(target); - halfword thickness = tex_aux_check_fraction_rule(target, style, size, stretched_fraction_subtype, NULL); - halfword fraction = tex_new_null_box_node(vlist_node, math_fraction_list); - (void) kerns; - tex_attach_attribute_list_copy(fraction, target); - tex_aux_wrap_fraction_parts(target, style, size, &numerator, &denominator, 1); - tex_aux_calculate_fraction_shifts_normal(target, style, size, numerator, denominator, &shift_up, &shift_down, &delta); - tex_aux_apply_fraction_shifts(fraction, numerator, denominator, shift_up, shift_down); - middle = tex_aux_make_delimiter(target, middle_delimiter, size, box_width(fraction), 1, style, 0, NULL, NULL, 0, 0, NULL, 0); - 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, "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); - return fraction; -} - static halfword tex_aux_make_ruled_fraction(halfword target, int style, int size, kernset *kerns, int fractiontype) { halfword numerator = null; @@ -3630,6 +3621,46 @@ static halfword tex_aux_make_ruled_fraction(halfword target, int style, int size return fraction; } +static halfword tex_aux_make_stretched_fraction(halfword target, int style, int size, kernset *kerns) +{ + halfword middle_delimiter = fraction_middle_delimiter(target); + if (tex_aux_has_extensible(middle_delimiter, size)) { + halfword middle = null; + halfword numerator = null; + halfword denominator = null; + scaled shift_up = 0; + scaled shift_down = 0; + scaled delta = 0; + halfword thickness = tex_aux_check_fraction_rule(target, style, size, stretched_fraction_subtype, NULL); + halfword fraction = tex_new_null_box_node(vlist_node, math_fraction_list); + (void) kerns; + tex_attach_attribute_list_copy(fraction, target); + tex_aux_wrap_fraction_parts(target, style, size, &numerator, &denominator, 1); + tex_aux_calculate_fraction_shifts_normal(target, style, size, numerator, denominator, &shift_up, &shift_down, &delta); + tex_aux_apply_fraction_shifts(fraction, numerator, denominator, shift_up, shift_down); + middle = tex_aux_make_delimiter(target, middle_delimiter, size, box_width(fraction), 1, style, 0, NULL, NULL, 0, 0, NULL, 0); + 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, "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); + return fraction; + } else { + return tex_aux_make_ruled_fraction(target, style, size, kerns, over_fraction_subtype); + } +} + /*tex We intercept bad nodes created at the \LUA\ end but only partially. The fraction handler is quite complex and uses a lot of parameters. You shouldn't mess with \TEX. @@ -7146,7 +7177,7 @@ static void tex_mlist_to_hlist_finalize_list(mliststate *state) tex_couple_nodes(p, box_list(l)); box_list(l) = null; tex_flush_node(l); - } else if (current_type == simple_noad && (current_subtype == math_end_class) || (current_subtype == math_begin_class)) { + } else if (current_type == simple_noad && (current_subtype == math_end_class || current_subtype == math_begin_class)) { if (noad_new_hlist(current)) { tex_flush_node(noad_new_hlist(current)); noad_new_hlist(current) = null; diff --git a/source/luametatex/source/tex/texnodes.c b/source/luametatex/source/tex/texnodes.c index 09aa74d57..49a5b8fa7 100644 --- a/source/luametatex/source/tex/texnodes.c +++ b/source/luametatex/source/tex/texnodes.c @@ -186,7 +186,7 @@ void lmt_nodelib_initialize(void) { set_value_entry_key(subtypes_kern, italic_kern_subtype, italiccorrection) set_value_entry_key(subtypes_kern, left_margin_kern_subtype, leftmarginkern) set_value_entry_key(subtypes_kern, right_margin_kern_subtype, rightmarginkern) - set_value_entry_key(subtypes_kern, explicit_math_kern_subtype, mathkerns) + set_value_entry_key(subtypes_kern, explicit_math_kern_subtype, mathkern) set_value_entry_key(subtypes_kern, math_shape_kern_subtype, mathshapekern) set_value_entry_key(subtypes_kern, horizontal_math_kern_subtype, horizontalmathkern) set_value_entry_key(subtypes_kern, vertical_math_kern_subtype, verticalmathkern) diff --git a/source/luametatex/source/tex/texscanning.c b/source/luametatex/source/tex/texscanning.c index 23fc29d1c..aae30c6f0 100644 --- a/source/luametatex/source/tex/texscanning.c +++ b/source/luametatex/source/tex/texscanning.c @@ -2339,7 +2339,7 @@ typedef enum scanned_unit { static int tex_aux_scan_unit(halfword *num, halfword *denom, halfword *value, halfword *order) { - AGAIN: /* only for true */ +//AGAIN: /* only for true */ do { tex_get_x_token(); } while (cur_cmd == spacer_cmd); @@ -2436,15 +2436,21 @@ static int tex_aux_scan_unit(halfword *num, halfword *denom, halfword *value, ha } break; case 't': case 'T': - if (order) { - switch (chrtwo) { - case 'r': case 'R': - if (tex_scan_mandate_keyword("true", 2)) { - /*tex This is now a bogus prefix that might get dropped! */ - goto AGAIN; - } - } + switch (chrtwo) { + case 's': case 'S': + *num = 4588; + *denom = 645; + return normal_unit_scanned; } + // if (order) { + // switch (chrtwo) { + // case 'r': case 'R': + // if (tex_scan_mandate_keyword("true", 2)) { + // /*tex This is now a bogus prefix that might get dropped! */ + // goto AGAIN; + // } + // } + // } break; case 'e': case 'E': switch (chrtwo) { @@ -2454,6 +2460,14 @@ static int tex_aux_scan_unit(halfword *num, halfword *denom, halfword *value, ha case 'x': case 'X': *value = tex_get_scaled_ex_height(cur_font_par); return relative_unit_scanned; + case 's': case 'S': + *num = 9176; + *denom = 129; + return normal_unit_scanned; + case 'u': case 'U': + *num = 9176 * eu_factor_par; + *denom = 129 * 10; + return normal_unit_scanned; } break; case 'f': case 'F': @@ -2486,7 +2500,7 @@ static int tex_aux_scan_unit(halfword *num, halfword *denom, halfword *value, ha /*tex When we drop |true| support we can use the next variant which is a bit more efficient - and also handles optional units. LAter we will see a more limited variant that also + and also handles optional units. Later we will see a more limited variant that also includes the scaler. */ @@ -2557,6 +2571,17 @@ static int tex_aux_scan_unit_new(halfword *num, halfword *denom, halfword *value } } break; + case 't': case 'T': + tex_get_x_token(); + if (cur_cmd == letter_cmd || cur_cmd == other_char_cmd) { + switch (cur_chr) { + case 's': case 'S': + *num = 4588; + *denom = 645; + return normal_unit_scanned; + } + } + break; case 'b': case 'B': tex_get_x_token(); if (cur_cmd == letter_cmd || cur_cmd == other_char_cmd) { @@ -2600,6 +2625,14 @@ static int tex_aux_scan_unit_new(halfword *num, halfword *denom, halfword *value case 'x': case 'X': *value = tex_get_scaled_ex_height(cur_font_par); return relative_unit_scanned; + case 's': case 'S': + *num = 9176; + *denom = 129; + return normal_unit_scanned; + case 'u': case 'U': + *num = 9176 * eu_factor_par; + *denom = 129 * 10; + return normal_unit_scanned; } } break; @@ -4801,6 +4834,17 @@ static halfword tex_aux_scan_unit_applied(halfword value, halfword fraction, int } } break; + case 't': case 'T': + tex_get_x_token(); + if (cur_cmd == letter_cmd || cur_cmd == other_char_cmd) { + switch (cur_chr) { + case 's': case 'S': + num = 4588; + denom = 645; + goto NORMALUNIT; + } + } + break; case 'b': case 'B': tex_get_x_token(); if (cur_cmd == letter_cmd || cur_cmd == other_char_cmd) { @@ -4842,6 +4886,14 @@ static halfword tex_aux_scan_unit_applied(halfword value, halfword fraction, int return tex_get_scaled_em_width(cur_font_par); case 'x': case 'X': return tex_get_scaled_ex_height(cur_font_par); + case 's': case 'S': + num = 9176; + denom = 129; + goto NORMALUNIT; + case 'u': case 'U': + num = 9176 * eu_factor_par; + denom = 129 * 10; + goto NORMALUNIT; } } break; diff --git a/source/luametatex/source/tex/textypes.h b/source/luametatex/source/tex/textypes.h index 2ca761e59..399839227 100644 --- a/source/luametatex/source/tex/textypes.h +++ b/source/luametatex/source/tex/textypes.h @@ -576,6 +576,47 @@ typedef union tokenword { # define stp_language_size 250 /*tex + Units. At some point these will be used in texscanning and lmtexlib. +*/ + + +# define bp_numerator 7227 // base point +# define bp_denonimator 7200 + +# define cc_numerator 14856 // cicero +# define cc_denonimator 1157 + +# define cm_numerator 7227 // centimeter +# define cm_denonimator 254 + +# define dd_numerator 1238 // didot +# define dd_denonimator 1157 + +# define dk_numerator 49838 // knuth +# define dk_denonimator 7739 + +# define es_numerator 9176 // edith +# define es_denonimator 129 + +# define in_numerator 7227 // inch +# define in_denonimator 100 + +# define mm_numerator 7227 // millimeter +# define mm_denonimator 2540 + +# define pc_numerator 12 // pica +# define pc_denonimator 1 + +# define pt_numerator 1 // point +# define pt_denonimator 1 + +# define sp_numerator 1 // scaled point +# define sp_denonimator 1 + +# define ts_numerator 4588 // tove +# define ts_denonimator 645 + +/*tex These are used in the code, so when we want them to adapt, which is needed when we make them configurable, we need to change this. |