diff options
Diffstat (limited to 'source/luametatex/source/tex/texmlist.c')
-rw-r--r-- | source/luametatex/source/tex/texmlist.c | 83 |
1 files changed, 61 insertions, 22 deletions
diff --git a/source/luametatex/source/tex/texmlist.c b/source/luametatex/source/tex/texmlist.c index 56b780506..3b7734ccf 100644 --- a/source/luametatex/source/tex/texmlist.c +++ b/source/luametatex/source/tex/texmlist.c @@ -861,7 +861,7 @@ static halfword tex_aux_underbar(halfword box, scaled gap, scaled height, scaled */ -static halfword tex_aux_char_box(halfword fnt, int chr, halfword att, scaled *ic, quarterword subtype, scaled target, int style) +static halfword tex_aux_char_box(halfword fnt, int chr, halfword att, scaled *ic, quarterword subtype, scaled target, int style, int shrink, int stretch) { /*tex The new box and its character node. */ halfword glyph = tex_aux_new_math_glyph(fnt, chr, subtype); @@ -876,7 +876,7 @@ static halfword tex_aux_char_box(halfword fnt, int chr, halfword att, scaled *ic if (tex_has_glyph_option(glyph, glyph_option_no_italic_correction)) { whd.ic = 0; } - if (whd.ic) { + if (! (stretch || shrink) && whd.ic) { if (ic) { *ic = whd.ic; /* also in open type? needs checking */ } @@ -889,12 +889,19 @@ static halfword tex_aux_char_box(halfword fnt, int chr, halfword att, scaled *ic } else if (ic) { *ic = 0; } - if (target && whd.wd > 0 && whd.wd < target && tex_aux_math_engine_control(fnt, math_control_extend_accents) && tex_char_has_tag_from_font(fnt, chr, extend_last_tag)) { - scaled margin = tex_get_math_x_parameter_default(style, math_parameter_accent_extend_margin, 0); - scaled amount = target - 2 * margin; - if (amount > 0) { - glyph_x_scale(glyph) = lround((double) glyph_x_scale(glyph) * amount/whd.wd); - glyph_x_offset(glyph) = (whd.wd - amount)/2; + if (target && whd.wd > 0) { + if (whd.wd < target && tex_aux_math_engine_control(fnt, math_control_extend_accents) && tex_char_has_tag_from_font(fnt, chr, extend_last_tag)) { + scaled margin = tex_get_math_x_parameter_default(style, math_parameter_accent_extend_margin, 0); + scaled amount = target - 2 * margin; + if (amount > 0) { + glyph_x_scale(glyph) = lround((double) glyph_x_scale(glyph) * amount/whd.wd); + glyph_x_offset(glyph) = (whd.wd - amount)/2; + } + return box; + } + if ((shrink && (whd.wd > target)) || (stretch && (whd.wd < target))) { + glyph_x_scale(glyph) = lround((double) glyph_x_scale(glyph) * target/whd.wd); + glyph_x_offset(glyph) = (whd.wd - target)/2; } } return box; @@ -1384,6 +1391,8 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int /*tex are we trying the large variant? */ int large_attempt = 0; int do_parts = 0; + int shrink = flat && tex_has_noad_option(target, noad_option_shrink); + int stretch = flat && tex_has_noad_option(target, noad_option_stretch); /*tex to save the current attribute list */ halfword att = null; if (extremes) { @@ -1448,7 +1457,7 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int if (total >= (targetsize - tolerance)) { goto FOUND; } - } + } if (tex_char_has_tag_from_font(curfnt, curchr, extensible_tag)) { if (tex_char_has_tag_from_font(curfnt, curchr, horizontal_tag) || tex_char_has_tag_from_font(curfnt, curchr, vertical_tag)) { /*tex We only check when we are explicit. */ @@ -1498,8 +1507,13 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int */ extinfo *ext = do_parts ? tex_char_extensible_recipe_from_font(fnt, chr) : NULL; if (ext) { - scaled minoverlap = flat ? tex_get_math_x_parameter_default(style, math_parameter_connector_overlap_min, 0) : tex_get_math_y_parameter_default(style, math_parameter_connector_overlap_min, 0);; + scaled minoverlap = flat ? tex_get_math_x_parameter_default(style, math_parameter_connector_overlap_min, 0) : tex_get_math_y_parameter_default(style, math_parameter_connector_overlap_min, 0); result = tex_aux_get_delimiter_box(fnt, chr, targetsize, minoverlap, flat, att); + if (stretch && flat && (box_width(result) > targetsize)) { // threshold nooverflow + tex_flush_node_list(result); + do_parts = 0; + goto HERE; + } if (delta) { /*tex Not yet done: horizontal italics. */ if (tex_aux_math_engine_control(fnt, math_control_apply_vertical_italic_kern)) { @@ -1529,7 +1543,8 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int the traditional width (which is fake width + italic) becomes less and the delta is added. See (**). */ - result = tex_aux_char_box(fnt, chr, att, delta, glyph_math_delimiter_subtype, flat ? targetsize : 0, style); + HERE: + result = tex_aux_char_box(fnt, chr, att, delta, glyph_math_delimiter_subtype, flat ? targetsize : 0, style, shrink, stretch); if (flat) { /* This will be done when we have a reasonable example. */ } else { @@ -2395,12 +2410,20 @@ static void tex_aux_make_root_radical(halfword target, int style, int size, kern } delimiter = tex_aux_make_delimiter(target, delimiter, size, box_total(nucleus) + clearance + theta, 0, style, 1, NULL, NULL, 0, has_noad_option_nooverflow(target), &extremes, 0); if (radical_degree(target)) { + halfword innerf = 0; + halfword innerc = 0; if (tex_char_has_tag_from_font(extremes.bfont, extremes.bchar, inner_left_tag)) { - innerx = tex_char_inner_x_offset_from_font(extremes.bfont, extremes.bchar); - innery = tex_char_inner_y_offset_from_font(extremes.bfont, extremes.bchar); + innerf = extremes.bfont; + innerc = extremes.bchar; } else if (tex_char_has_tag_from_font(extremes.tfont, extremes.tchar, inner_left_tag)) { - innerx = tex_char_inner_x_offset_from_font(extremes.tfont, extremes.tchar); - innery = tex_char_inner_y_offset_from_font(extremes.tfont, extremes.tchar); + innerf = extremes.tfont; + innerc = extremes.tchar; + } + if (innerc) { + innerx = tex_char_inner_x_offset_from_font(innerf, innerc); + innery = tex_char_inner_y_offset_from_font(innerf, innerc); + innerx = innerx == INT_MIN ? 0 : tex_aux_math_y_size_scaled(innerf, innerx, size); + innery = innery == INT_MIN ? 0 : tex_aux_math_y_size_scaled(innerf, innery, size); } } if (companion) { @@ -2790,7 +2813,7 @@ static void tex_aux_preroll_radical(halfword target, int style, int size) typedef enum math_accent_location_codes { top_accent_code = 1, - bot_accent_code = 2, + bot_accent_code = 2, // todo : bottom_accent_code overlay_accent_code = 4, stretch_accent_code = 8, /* reserved, not yet set */ } math_accent_location_codes; @@ -2896,6 +2919,7 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal scaled fraction = accent_fraction(target) > 0 ? accent_fraction(target) : 1000; scaled skew = 0; scaled offset = 0; + scaled innery = 0; halfword accent = null; halfword base = null; halfword result = null; @@ -3008,7 +3032,7 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal } if (! accent) { /*tex Italic gets added to width for traditional fonts (no italic anyway): */ - accent = tex_aux_char_box(accentfnt, accentchr, attrlist, NULL, glyph_math_accent_subtype, basewidth, style); // usedwidth + accent = tex_aux_char_box(accentfnt, accentchr, attrlist, NULL, glyph_math_accent_subtype, basewidth, style, 0, 0); // usedwidth } if (flags & top_accent_code) { scaled b = tex_get_math_y_parameter(style, math_parameter_accent_base_height); @@ -3019,7 +3043,7 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal halfword flatchr = tex_char_flat_accent_from_font(accentfnt, accentchr); if (flatchr != INT_MIN && flatchr != accentchr) { tex_flush_node(accent); - accent = tex_aux_char_box(accentfnt, flatchr, attrlist, NULL, glyph_math_accent_subtype, usedwidth, style); + accent = tex_aux_char_box(accentfnt, flatchr, attrlist, NULL, glyph_math_accent_subtype, usedwidth, style, 0, 0); if (tracing_math_par >= 2) { tex_begin_diagnostic(); tex_print_format("[math: flattening accent, old %x, new %x]", accentchr, flatchr); @@ -3039,6 +3063,10 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal if (u != undefined_math_parameter) { delta -= u; } + if (tex_char_has_tag_from_font(accentfnt, accentchr, inner_top_tag)) { + innery = tex_char_inner_y_offset_from_font(accentfnt, accentchr); + innery = innery == INT_MIN ? 0 : tex_aux_math_y_size_scaled(accentfnt, innery, size); + } } else if (flags & bot_accent_code) { // scaled b = tex_get_math_y_parameter(style, math_parameter_accent_base_depth, 0); // scaled f = tex_get_math_y_parameter(style, math_parameter_flattened_accent_base_depth, 0); @@ -3050,6 +3078,10 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal if (l != undefined_math_parameter) { delta += l; } + if (tex_char_has_tag_from_font(accentfnt, accentchr, inner_bottom_tag)) { + innery = tex_char_inner_y_offset_from_font(accentfnt, accentchr); + innery = innery == INT_MIN ? 0 : tex_aux_math_y_size_scaled(accentfnt, innery, size); + } } else { /* if (flags & overlay_accent_code) { */ /*tex Center the accent vertically around base: */ delta = tex_half_scaled(box_total(accent) + box_total(base)); @@ -3082,11 +3114,11 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal anchor = tex_half_scaled(accentwidth); } else { anchor = tex_char_unchecked_top_anchor_from_font(accentfnt, accentchr); /* no bot accent key */ - if (anchor != INT_MIN) { - anchor = tex_aux_math_y_size_scaled(accentfnt, anchor, size); /* why y and not x */ - } else { + if (anchor == INT_MIN || has_noad_option_center(target)) { /*tex just take the center */ anchor = tex_half_scaled(accentwidth); + } else { + anchor = tex_aux_math_x_size_scaled(accentfnt, anchor, size); } } if (math_direction_par == dir_righttoleft) { @@ -3117,6 +3149,7 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal accent_bot_overshoot(target) = overshoot; } if (flags & (top_accent_code | overlay_accent_code)) { + delta += innery; if (delta) { halfword kern = tex_new_kern_node(-delta, vertical_math_kern_subtype); tex_attach_attribute_list_copy(kern, target); @@ -3126,6 +3159,12 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal tex_couple_nodes(accent, base); } result = accent; + } else if ((flags & bot_accent_code) && innery) { + halfword kern = tex_new_kern_node(innery, vertical_math_kern_subtype); + tex_attach_attribute_list_copy(kern, target); + tex_couple_nodes(base, kern); + tex_couple_nodes(kern, accent); + result = base; } else { tex_couple_nodes(base, accent); result = base; @@ -7107,7 +7146,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) { + } 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; |