diff --git a/library/src/math/fragment.rs b/library/src/math/fragment.rs index 40dca3479..027ab7da1 100644 --- a/library/src/math/fragment.rs +++ b/library/src/math/fragment.rs @@ -164,6 +164,32 @@ impl GlyphFragment { } pub fn with_id(ctx: &MathContext, c: char, id: GlyphId, span: Span) -> Self { + let mut fragment = Self { + id, + c, + font: ctx.font.clone(), + lang: TextElem::lang_in(ctx.styles()), + fill: TextElem::fill_in(ctx.styles()), + style: ctx.style, + font_size: ctx.size, + width: Abs::zero(), + ascent: Abs::zero(), + descent: Abs::zero(), + italics_correction: Abs::zero(), + class: match c { + ':' => Some(MathClass::Relation), + _ => unicode_math_class::class(c), + }, + span, + meta: MetaElem::data_in(ctx.styles()), + }; + fragment.set_id(ctx, id); + fragment + } + + /// Sets element id and boxes in appropriate way without changing other + /// styles. This is used to replace the glyph with a stretch variant. + pub fn set_id(&mut self, ctx: &MathContext, id: GlyphId) { let advance = ctx.ttf.glyph_hor_advance(id).unwrap_or_default(); let italics = italics_correction(ctx, id).unwrap_or_default(); let bbox = ctx.ttf.glyph_bounding_box(id).unwrap_or(Rect { @@ -178,25 +204,11 @@ impl GlyphFragment { width += italics; } - Self { - id, - c, - font: ctx.font.clone(), - lang: TextElem::lang_in(ctx.styles()), - fill: TextElem::fill_in(ctx.styles()), - style: ctx.style, - font_size: ctx.size, - width, - ascent: bbox.y_max.scaled(ctx), - descent: -bbox.y_min.scaled(ctx), - italics_correction: italics, - class: match c { - ':' => Some(MathClass::Relation), - _ => unicode_math_class::class(c), - }, - span, - meta: MetaElem::data_in(ctx.styles()), - } + self.id = id; + self.width = width; + self.ascent = bbox.y_max.scaled(ctx); + self.descent = -bbox.y_min.scaled(ctx); + self.italics_correction = italics; } pub fn height(&self) -> Abs { diff --git a/library/src/math/stretch.rs b/library/src/math/stretch.rs index bb454022b..bbb0c9c44 100644 --- a/library/src/math/stretch.rs +++ b/library/src/math/stretch.rs @@ -33,7 +33,7 @@ impl GlyphFragment { /// The resulting frame may not have the exact desired width. fn stretch_glyph( ctx: &MathContext, - base: GlyphFragment, + mut base: GlyphFragment, target: Abs, short_fall: Abs, horizontal: bool, @@ -73,7 +73,8 @@ fn stretch_glyph( // This is either good or the best we've got. if short_target <= best_advance || construction.assembly.is_none() { - return GlyphFragment::with_id(ctx, base.c, best_id, base.span).into_variant(); + base.set_id(ctx, best_id); + return base.into_variant(); } // Assemble from parts. @@ -142,7 +143,8 @@ fn assemble( advance += ratio * (max_overlap - min_overlap); } - let fragment = GlyphFragment::with_id(ctx, base.c, part.glyph_id, base.span); + let mut fragment = base.clone(); + fragment.set_id(ctx, part.glyph_id); selected.push((fragment, advance)); } diff --git a/tests/ref/math/delimited.png b/tests/ref/math/delimited.png index 0670337fe..e9f6e2c14 100644 Binary files a/tests/ref/math/delimited.png and b/tests/ref/math/delimited.png differ diff --git a/tests/ref/math/underover.png b/tests/ref/math/underover.png index d090057d6..7c92c9825 100644 Binary files a/tests/ref/math/underover.png and b/tests/ref/math/underover.png differ diff --git a/tests/typ/math/delimited.typ b/tests/typ/math/delimited.typ index d22b76c0c..24374b8c2 100644 --- a/tests/typ/math/delimited.typ +++ b/tests/typ/math/delimited.typ @@ -36,3 +36,10 @@ $ lr(]sum_(x=1)^n x], size: #70%) --- // Test predefined delimiter pairings. $floor(x/2), ceil(x/2), abs(x), norm(x)$ + +--- +// Test colored delimiters +$ lr( + text("(", fill: #green) a/b + text(")", fill: #blue) + ) $