Ignore weak HElem at the beginning and end of an LR group (#2950)

This commit is contained in:
Leedehai 2024-01-05 13:08:27 -05:00 committed by GitHub
parent d52ae4bd48
commit a124694f08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 9 deletions

View File

@ -18,7 +18,7 @@ pub enum MathFragment {
Glyph(GlyphFragment),
Variant(VariantFragment),
Frame(FrameFragment),
Spacing(Abs),
Spacing(SpacingFragment),
Space(Abs),
Linebreak,
Align,
@ -34,7 +34,7 @@ impl MathFragment {
Self::Glyph(glyph) => glyph.width,
Self::Variant(variant) => variant.frame.width(),
Self::Frame(fragment) => fragment.frame.width(),
Self::Spacing(amount) => *amount,
Self::Spacing(spacing) => spacing.width,
Self::Space(amount) => *amount,
_ => Abs::zero(),
}
@ -205,6 +205,12 @@ impl From<FrameFragment> for MathFragment {
}
}
impl From<SpacingFragment> for MathFragment {
fn from(fragment: SpacingFragment) -> Self {
Self::Spacing(fragment)
}
}
#[derive(Clone)]
pub struct GlyphFragment {
pub id: GlyphId,
@ -467,6 +473,12 @@ impl FrameFragment {
}
}
#[derive(Debug, Clone)]
pub struct SpacingFragment {
pub width: Abs,
pub weak: bool,
}
/// Look up the italics correction for a glyph.
fn italics_correction(ctx: &MathContext, id: GlyphId) -> Option<Abs> {
Some(ctx.table.glyph_info?.italic_corrections?.get(id)?.scaled(ctx))

View File

@ -3,7 +3,9 @@ use unicode_math_class::MathClass;
use crate::diag::SourceResult;
use crate::foundations::{elem, func, Content, NativeElement, Resolve, Smart};
use crate::layout::{Abs, Em, Length, Rel};
use crate::math::{GlyphFragment, LayoutMath, MathContext, MathFragment, Scaled};
use crate::math::{
GlyphFragment, LayoutMath, MathContext, MathFragment, Scaled, SpacingFragment,
};
use crate::text::TextElem;
/// How much less high scaled delimiters can be than what they wrap.
@ -77,6 +79,19 @@ impl LayoutMath for LrElem {
}
}
// Remove weak SpacingFragment immediately after the opening or immediately
// before the closing.
let original_len = fragments.len();
let mut index = 0;
fragments.retain(|fragment| {
index += 1;
(index != 2 && index + 1 != original_len)
|| !matches!(
fragment,
MathFragment::Spacing(SpacingFragment { weak: true, .. })
)
});
ctx.extend(fragments);
Ok(())

View File

@ -279,7 +279,10 @@ impl LayoutMath for Content {
if let Some(elem) = self.to::<HElem>() {
if let Spacing::Rel(rel) = elem.amount() {
if rel.rel.is_zero() {
ctx.push(MathFragment::Spacing(rel.abs.resolve(ctx.styles())));
ctx.push(SpacingFragment {
width: rel.abs.resolve(ctx.styles()),
weak: elem.weak(ctx.styles()),
});
}
}
return Ok(());

View File

@ -10,6 +10,8 @@ use crate::math::{
};
use crate::model::ParElem;
use super::fragment::SpacingFragment;
pub const TIGHT_LEADING: Em = Em::new(0.25);
#[derive(Debug, Default, Clone)]
@ -279,8 +281,9 @@ impl MathRow {
while let Some(fragment) = iter.next() {
if space_is_visible {
match fragment {
MathFragment::Space(s) | MathFragment::Spacing(s) => {
items.push(MathParItem::Space(s));
MathFragment::Space(width)
| MathFragment::Spacing(SpacingFragment { width, .. }) => {
items.push(MathParItem::Space(width));
continue;
}
_ => {}

View File

@ -2,7 +2,7 @@ use unicode_math_class::MathClass;
use crate::foundations::{NativeElement, Scope};
use crate::layout::{Abs, Em, HElem};
use crate::math::{MathFragment, MathSize};
use crate::math::{MathFragment, MathSize, SpacingFragment};
pub(super) const THIN: Em = Em::new(1.0 / 6.0);
pub(super) const MEDIUM: Em = Em::new(2.0 / 9.0);
@ -28,8 +28,9 @@ pub(super) fn spacing(
use MathClass::*;
let class = |f: &MathFragment| f.class().unwrap_or(Special);
let resolve = |v: Em, f: &MathFragment| {
Some(MathFragment::Spacing(f.font_size().map_or(Abs::zero(), |size| v.at(size))))
let resolve = |v: Em, size_ref: &MathFragment| -> Option<MathFragment> {
let width = size_ref.font_size().map_or(Abs::zero(), |size| v.at(size));
Some(SpacingFragment { width, weak: false }.into())
};
let script =
|f: &MathFragment| f.style().map_or(false, |s| s.size <= MathSize::Script);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 99 KiB

View File

@ -51,3 +51,9 @@ $ { x mid(|) sum_(i=1)^oo phi_i (x) < 1 } \
{ integral |x| dif x
mid(bar.v.double)
floor(hat(A) mid(|) { x mid(|) y } mid(|) A) } $
---
// Test ignoring weak spacing immediately after the opening
// and immediately before the closing.
$ [#h(1em, weak: true)A(dif x, f(x) dif x)sum#h(1em, weak: true)] $