diff options
Diffstat (limited to 'source/luametatex/source/tex/texmlist.c')
-rw-r--r-- | source/luametatex/source/tex/texmlist.c | 205 |
1 files changed, 118 insertions, 87 deletions
diff --git a/source/luametatex/source/tex/texmlist.c b/source/luametatex/source/tex/texmlist.c index a3154df62..c5613d90a 100644 --- a/source/luametatex/source/tex/texmlist.c +++ b/source/luametatex/source/tex/texmlist.c @@ -897,7 +897,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, int shrink, int stretch) +static halfword tex_aux_char_box(halfword fnt, int chr, halfword att, scaled *ic, quarterword subtype, scaled target, int style, int shrink, int stretch, int *isscaled) { /*tex The new box and its character node. */ halfword glyph = tex_aux_new_math_glyph(fnt, chr, subtype); @@ -909,6 +909,9 @@ static halfword tex_aux_char_box(halfword fnt, int chr, halfword att, scaled *ic box_height(box) = whd.ht; box_depth(box) = whd.dp; box_list(box) = glyph; + if (isscaled) { + *isscaled = 0; + } if (tex_has_glyph_option(glyph, glyph_option_no_italic_correction)) { whd.ic = 0; } @@ -932,15 +935,21 @@ static halfword tex_aux_char_box(halfword fnt, int chr, halfword att, scaled *ic 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 (isscaled) { + *isscaled = 1; + } } return box; } - if ((shrink && (whd.wd > target)) || (stretch && (whd.wd < target))) { // we need to keep an eye on it - glyph_x_scale(glyph) = lround((double) glyph_x_scale(glyph) * target/whd.wd); - // glyph_x_offset(glyph) = (whd.wd - target)/2; - whd = tex_char_whd_from_glyph(glyph); - box_width(box) = whd.wd; - } + if ((shrink && (whd.wd > target)) || (stretch && (whd.wd < target))) { // we need to keep an eye on it + glyph_x_scale(glyph) = lround((double) glyph_x_scale(glyph) * target/whd.wd); + // glyph_x_offset(glyph) = (whd.wd - target)/2; + whd = tex_char_whd_from_glyph(glyph); + box_width(box) = whd.wd; + if (isscaled) { + *isscaled = 1; + } + } } return box; } @@ -1429,6 +1438,7 @@ 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 isscaled = 0; int shrink = flat && has_noad_option_shrink(target); int stretch = flat && has_noad_option_stretch(target); /*tex to save the current attribute list */ @@ -1581,7 +1591,7 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int added. See (**). */ HERE: - result = tex_aux_char_box(fnt, chr, att, delta, glyph_math_delimiter_subtype, flat ? targetsize : 0, style, shrink, stretch); + result = tex_aux_char_box(fnt, chr, att, delta, glyph_math_delimiter_subtype, flat ? targetsize : 0, style, shrink, stretch, &isscaled); if (flat) { /* This will be done when we have a reasonable example. */ } else { @@ -2393,20 +2403,16 @@ static void tex_aux_set_radical_kerns(delimiterextremes *extremes, kernset *kern { if (kerns && extremes->tfont) { if (tex_math_has_class_option(radical_noad_subtype, carry_over_left_top_kern_class_option)) { -// kerns->topleft = tex_char_top_left_kern_from_font(extremes->tfont, extremes->tchar); -kerns->topleft = tex_aux_math_x_size_scaled(extremes->tfont, tex_char_top_left_kern_from_font(extremes->tfont, extremes->tchar), size); + kerns->topleft = tex_aux_math_x_size_scaled(extremes->tfont, tex_char_top_left_kern_from_font(extremes->tfont, extremes->tchar), size); } if (tex_math_has_class_option(radical_noad_subtype, carry_over_left_bottom_kern_class_option)) { -// kerns->bottomleft = tex_char_bottom_left_kern_from_font(extremes->bfont, extremes->bchar); -kerns->bottomleft = tex_aux_math_x_size_scaled(extremes->bfont, tex_char_bottom_left_kern_from_font(extremes->bfont, extremes->bchar), size); + kerns->bottomleft = tex_aux_math_x_size_scaled(extremes->bfont, tex_char_bottom_left_kern_from_font(extremes->bfont, extremes->bchar), size); } if (tex_math_has_class_option(radical_noad_subtype, carry_over_right_top_kern_class_option)) { -// kerns->topright = tex_char_top_right_kern_from_font(extremes->tfont, extremes->tchar); -kerns->topright = tex_aux_math_x_size_scaled(extremes->tfont, tex_char_top_right_kern_from_font(extremes->tfont, extremes->tchar), size); + kerns->topright = tex_aux_math_x_size_scaled(extremes->tfont, tex_char_top_right_kern_from_font(extremes->tfont, extremes->tchar), size); } if (tex_math_has_class_option(radical_noad_subtype, carry_over_right_bottom_kern_class_option)) { -// kerns->bottomright = tex_char_bottom_right_kern_from_font(extremes->bfont, extremes->bchar); -kerns->bottomright = tex_aux_math_x_size_scaled(extremes->bfont, tex_char_bottom_right_kern_from_font(extremes->bfont, extremes->bchar), size); + kerns->bottomright = tex_aux_math_x_size_scaled(extremes->bfont, tex_char_bottom_right_kern_from_font(extremes->bfont, extremes->bchar), size); } if (tex_math_has_class_option(radical_noad_subtype, prefer_delimiter_dimensions_class_option)) { kerns->height = extremes->height; @@ -2973,10 +2979,14 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal halfword stretch = (flags & stretch_accent_code) == stretch_accent_code; halfword basefnt = null_font; halfword basechr = 0; + halfword accentbasefnt = accentfnt; + halfword accentbasechr = accentchr; int found = 0; + int isscaled = 0; + int keep = 0; /*tex Compute the amount of skew, or set |skew| to an alignment point. This will be true if a - top-accent has been determined. + top-accent has been determined. This concerns the base! */ int absolute = tex_aux_compute_accent_skew(target, flags, &skew, size); { @@ -2995,6 +3005,7 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal // basedepth = box_depth(base); } if (base) { + /*tex We always have a base anyway. */ halfword list = box_list(base); if (list && node_type(list) == glyph_node) { basefnt = glyph_font(list); @@ -3073,25 +3084,36 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal accentchr = next; } } + + } + keep = (accentfnt == accentbasefnt) && (accentchr == accentbasechr) && (has_noad_option_keep_base(target) || tex_char_has_tag_from_font(accentfnt, accentchr, keep_base_tag)); + if (accent) { /*tex - So here we then need to package the offsets. + We have an extensible that already has been boxed */ - } - 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, usedwidth, style, has_noad_option_stretch(target), has_noad_option_shrink(target)); // basewidth + } else { + /*tex + We have a base char or a variant. For traditional fonts the italic correction gets + added to width (not that we have these in \CONTEXT). + */ + accent = tex_aux_char_box(accentfnt, accentchr, attrlist, NULL, glyph_math_accent_subtype, usedwidth, style, keep ? 0 : has_noad_option_shrink(target), keep ? 0 : has_noad_option_stretch(target), &isscaled); // basewidth found = 1; } if (flags & top_accent_code) { scaled b = tex_get_math_y_parameter(style, math_parameter_accent_base_height); - scaled u = found ? tex_get_math_y_parameter(style, stretch ? math_parameter_flattened_accent_top_shift_up : math_parameter_accent_top_shift_up) : undefined_math_parameter; + scaled u = tex_get_math_y_parameter(style, math_parameter_accent_top_shift_up); if (found && ! tex_aux_math_engine_control(accentfnt, math_control_ignore_flat_accents)) { scaled f = tex_get_math_y_parameter(style, math_parameter_flattened_accent_base_height); if (f != undefined_math_parameter && baseheight > f) { + int keep = (accentfnt == accentbasefnt) && (accentchr == accentbasechr) && (has_noad_option_keep_base(target) || tex_char_has_tag_from_font(accentfnt, accentchr, keep_base_tag)); halfword flatchr = tex_char_flat_accent_from_font(accentfnt, accentchr); - if (flatchr != INT_MIN && flatchr != accentchr) { + if (flatchr && flatchr != INT_MIN && flatchr != accentchr) { + scaled uf = tex_get_math_y_parameter(style, math_parameter_flattened_accent_top_shift_up); + if (uf != undefined_math_parameter) { + u = uf; + } tex_flush_node(accent); - accent = tex_aux_char_box(accentfnt, flatchr, attrlist, NULL, glyph_math_accent_subtype, usedwidth, style, 0, 0); + accent = tex_aux_char_box(accentfnt, flatchr, attrlist, NULL, glyph_math_accent_subtype, usedwidth, style, keep ? 0 : has_noad_option_shrink(target), keep ? 0 : has_noad_option_stretch(target), &isscaled); if (tracing_math_par >= 2) { tex_begin_diagnostic(); tex_print_format("[math: flattening accent, old %x, new %x]", accentchr, flatchr); @@ -3155,45 +3177,63 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal /*tex The top accents of both characters are aligned. */ { halfword accentwidth = box_width(accent); - if (absolute) { - scaled anchor = 0; - if (extended) { - /*tex If the accent is extensible just take the center. */ - anchor = tex_half_scaled(accentwidth); - } else { - if (flags & top_accent_code) { - anchor = tex_char_unchecked_top_anchor_from_font(accentfnt, accentchr); /* no bot accent key */ - } else if (flags & bot_accent_code) { - anchor = tex_char_unchecked_bottom_anchor_from_font(accentfnt, accentchr); /* no bot accent key */ - } else { - anchor = INT_MIN; - } - if (anchor == INT_MIN || has_noad_option_center(target)) { - /*tex just take the center */ + if (accentwidth > basewidth && has_noad_option_nooverflow(target)) { + /*tex + This likely only happens with (too wide base) rules so centering is quite okay then and a + bit like scaling. But it could be an accent option (weren't it that we ran out of bits). + In that case a topaccent is also unlikely. + */ + scaled leftkern = tex_half_scaled(accentwidth - basewidth); + if (leftkern > 0) { + halfword kern = tex_new_kern_node(leftkern, horizontal_math_kern_subtype); + tex_attach_attribute_list_copy(kern, target); + tex_try_couple_nodes(kern, base); + base = tex_hpack(kern, 0, packing_additional, direction_unknown, holding_none_option); + basewidth = accentwidth; + box_width(base) = accentwidth; + } + } else { + if (absolute) { + scaled anchor = 0; /* maybe: INT_MIN */ + if (extended || isscaled) { + /*tex If the accent is extensible just take the center. */ anchor = tex_half_scaled(accentwidth); } else { - anchor = tex_aux_math_x_size_scaled(accentfnt, anchor, size); + /*tex When we scale we center. */ + if (flags & top_accent_code) { + anchor = tex_char_unchecked_top_anchor_from_font(accentfnt, accentchr); /* no bot accent key */ + } else if (flags & bot_accent_code) { + anchor = tex_char_unchecked_bottom_anchor_from_font(accentfnt, accentchr); /* no bot accent key */ + } else { + anchor = INT_MIN; + } + 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) { + skew += anchor - accentwidth; + } else { + skew -= anchor; } - } - if (math_direction_par == dir_righttoleft) { - skew += anchor - accentwidth; + } else if (accentwidth == 0) { + skew += basewidth; + } else if (math_direction_par == dir_righttoleft) { + skew += accentwidth; /* ok? */ } else { - skew -= anchor; + skew += tex_half_scaled(basewidth - accentwidth); + } + box_shift_amount(accent) = skew; + box_width(accent) = 0; /* in gyre zero anyway */ + if (accentwidth) { + overshoot = accentwidth + skew - basewidth; + } + if (overshoot < 0) { + overshoot = 0; } - } else if (accentwidth == 0) { - skew += basewidth; - } else if (math_direction_par == dir_righttoleft) { - skew += accentwidth; /* ok? */ - } else { - skew += tex_half_scaled(basewidth - accentwidth); - } - box_shift_amount(accent) = skew; - box_width(accent) = 0; /* in gyre zero anyway */ - if (accentwidth) { - overshoot = accentwidth + skew - basewidth; - } - if (overshoot < 0) { - overshoot = 0; } } if (flags & (top_accent_code)) { @@ -3354,20 +3394,16 @@ static void tex_aux_wrap_fraction_result(halfword target, int style, int size, h right = tex_aux_make_delimiter(target, right_delimiter, size, delta, 0, style, 1, NULL, NULL, 0, has_noad_option_nooverflow(target), &extremes, 0); if (kerns && extremes.tfont) { if (tex_math_has_class_option(fraction_noad_subtype, carry_over_left_top_kern_class_option)) { -// kerns->topleft = tex_char_top_left_kern_from_font(extremes.tfont, extremes.tchar); -kerns->topleft = tex_aux_math_x_size_scaled(extremes.tfont, tex_char_top_left_kern_from_font(extremes.tfont, extremes.tchar), size); + kerns->topleft = tex_aux_math_x_size_scaled(extremes.tfont, tex_char_top_left_kern_from_font(extremes.tfont, extremes.tchar), size); } if (tex_math_has_class_option(fraction_noad_subtype, carry_over_left_bottom_kern_class_option)) { -// kerns->bottomleft = tex_char_bottom_left_kern_from_font(extremes.bfont, extremes.bchar); -kerns->bottomleft = tex_aux_math_x_size_scaled(extremes.bfont, tex_char_bottom_left_kern_from_font(extremes.bfont, extremes.bchar), size); + kerns->bottomleft = tex_aux_math_x_size_scaled(extremes.bfont, tex_char_bottom_left_kern_from_font(extremes.bfont, extremes.bchar), size); } if (tex_math_has_class_option(fraction_noad_subtype, carry_over_right_top_kern_class_option)) { -// kerns->topright = tex_char_top_right_kern_from_font(extremes.tfont, extremes.tchar); -kerns->topright = tex_aux_math_x_size_scaled(extremes.tfont, tex_char_top_right_kern_from_font(extremes.tfont, extremes.tchar), size); + kerns->topright = tex_aux_math_x_size_scaled(extremes.tfont, tex_char_top_right_kern_from_font(extremes.tfont, extremes.tchar), size); } if (tex_math_has_class_option(fraction_noad_subtype, carry_over_right_bottom_kern_class_option)) { -// kerns->bottomright = tex_char_bottom_right_kern_from_font(extremes.bfont, extremes.bchar); -kerns->bottomright = tex_aux_math_x_size_scaled(extremes.bfont, tex_char_bottom_right_kern_from_font(extremes.bfont, extremes.bchar), size); + kerns->bottomright = tex_aux_math_x_size_scaled(extremes.bfont, tex_char_bottom_right_kern_from_font(extremes.bfont, extremes.bchar), size); } if (tex_math_has_class_option(fraction_noad_subtype, prefer_delimiter_dimensions_class_option)) { kerns->height = extremes.height; @@ -3600,14 +3636,15 @@ static halfword tex_aux_make_skewed_fraction(halfword target, int style, int siz box_depth(fraction) = box_depth(middle) > maxdepth ? box_depth(middle) : maxdepth; ngap = hgap; dgap = hgap; - if (tex_math_has_class_option(fraction_noad_subtype, carry_over_left_top_kern_class_option)) { -// ngap += tex_char_top_left_kern_from_font(extremes.tfont, extremes.tchar); -ngap += tex_aux_math_x_size_scaled(extremes.tfont, tex_char_top_left_kern_from_font(extremes.tfont, extremes.tchar), size); - } - if (tex_math_has_class_option(fraction_noad_subtype, carry_over_right_bottom_kern_class_option)) { -// dgap += tex_char_bottom_right_kern_from_font(extremes.bfont, extremes.bchar); -dgap += tex_aux_math_x_size_scaled(extremes.bfont, tex_char_bottom_right_kern_from_font(extremes.bfont, extremes.bchar), size); - } + /*tex Better not do this, as we now have factors to control it and can fix the parameters. */ + /* + if (tex_math_has_class_option(fraction_noad_subtype, carry_over_left_top_kern_class_option)) { + ngap += tex_aux_math_x_size_scaled(extremes.tfont, tex_char_top_left_kern_from_font(extremes.tfont, extremes.tchar), size); + } + if (tex_math_has_class_option(fraction_noad_subtype, carry_over_right_bottom_kern_class_option)) { + dgap += tex_aux_math_x_size_scaled(extremes.bfont, tex_char_bottom_right_kern_from_font(extremes.bfont, extremes.bchar), size); + } + */ if (ngap || dgap) { // todo: only add when non zero halfword nkern = tex_new_kern_node(ngap, horizontal_math_kern_subtype); @@ -5646,12 +5683,10 @@ static halfword tex_aux_make_left_right(halfword target, int style, scaled max_d /* maybe elsewhere as the above case */ if (extremes && extremes->tfont) { if (tex_math_has_class_option(fenced_noad_subtype, carry_over_right_top_kern_class_option)) { -// kerns.topright = tex_char_top_right_kern_from_font(extremes->tfont, extremes->tchar); -kerns.topright = tex_aux_math_x_size_scaled(extremes->tfont, tex_char_top_right_kern_from_font(extremes->tfont, extremes->tchar), size); + kerns.topright = tex_aux_math_x_size_scaled(extremes->tfont, tex_char_top_right_kern_from_font(extremes->tfont, extremes->tchar), size); } if (tex_math_has_class_option(fenced_noad_subtype, carry_over_right_bottom_kern_class_option)) { -// kerns.bottomright = tex_char_bottom_right_kern_from_font(extremes->bfont, extremes->bchar); -kerns.bottomright = tex_aux_math_x_size_scaled(extremes->bfont, tex_char_bottom_right_kern_from_font(extremes->bfont, extremes->bchar), size); + kerns.bottomright = tex_aux_math_x_size_scaled(extremes->bfont, tex_char_bottom_right_kern_from_font(extremes->bfont, extremes->bchar), size); } if (tex_math_has_class_option(fenced_noad_subtype, prefer_delimiter_dimensions_class_option)) { kerns.height = extremes->height; @@ -6217,12 +6252,10 @@ static void tex_aux_finish_fenced(halfword current, halfword main_style, scaled case left_fence_side: case extended_left_fence_side: if (tex_math_has_class_option(fenced_noad_subtype, carry_over_left_top_kern_class_option)) { - // kerns->topleft = tex_char_top_left_kern_from_font(extremes.tfont, extremes.tchar); - kerns->topleft = tex_aux_math_x_size_scaled(extremes.tfont, tex_char_top_left_kern_from_font(extremes.tfont, extremes.tchar), main_style); + kerns->topleft = tex_aux_math_x_size_scaled(extremes.tfont, tex_char_top_left_kern_from_font(extremes.tfont, extremes.tchar), main_style); } if (tex_math_has_class_option(fenced_noad_subtype, carry_over_left_bottom_kern_class_option)) { - // kerns->bottomleft = tex_char_bottom_left_kern_from_font(extremes.bfont, extremes.bchar); - kerns->bottomleft = tex_aux_math_x_size_scaled(extremes.bfont, tex_char_bottom_left_kern_from_font(extremes.bfont, extremes.bchar), main_style); + kerns->bottomleft = tex_aux_math_x_size_scaled(extremes.bfont, tex_char_bottom_left_kern_from_font(extremes.bfont, extremes.bchar), main_style); } if (tex_math_has_class_option(fenced_noad_subtype, prefer_delimiter_dimensions_class_option)) { kerns->height = extremes.height; @@ -6236,12 +6269,10 @@ static void tex_aux_finish_fenced(halfword current, halfword main_style, scaled case left_operator_side: case no_fence_side: if (tex_math_has_class_option(fenced_noad_subtype, carry_over_right_top_kern_class_option)) { -// kerns->topright = tex_char_top_right_kern_from_font(extremes.tfont, extremes.tchar); -kerns->topright = tex_aux_math_x_size_scaled(extremes.tfont, tex_char_top_right_kern_from_font(extremes.tfont, extremes.tchar), main_style); + kerns->topright = tex_aux_math_x_size_scaled(extremes.tfont, tex_char_top_right_kern_from_font(extremes.tfont, extremes.tchar), main_style); } if (tex_math_has_class_option(fenced_noad_subtype, carry_over_right_bottom_kern_class_option)) { -// kerns->bottomright = tex_char_bottom_right_kern_from_font(extremes.bfont, extremes.bchar); -kerns->bottomright = tex_aux_math_x_size_scaled(extremes.bfont, tex_char_bottom_right_kern_from_font(extremes.bfont, extremes.bchar), main_style); + kerns->bottomright = tex_aux_math_x_size_scaled(extremes.bfont, tex_char_bottom_right_kern_from_font(extremes.bfont, extremes.bchar), main_style); } if (tex_math_has_class_option(fenced_noad_subtype, prefer_delimiter_dimensions_class_option)) { kerns->height = extremes.height; |