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), Glyph(GlyphFragment),
Variant(VariantFragment), Variant(VariantFragment),
Frame(FrameFragment), Frame(FrameFragment),
Spacing(Abs), Spacing(SpacingFragment),
Space(Abs), Space(Abs),
Linebreak, Linebreak,
Align, Align,
@ -34,7 +34,7 @@ impl MathFragment {
Self::Glyph(glyph) => glyph.width, Self::Glyph(glyph) => glyph.width,
Self::Variant(variant) => variant.frame.width(), Self::Variant(variant) => variant.frame.width(),
Self::Frame(fragment) => fragment.frame.width(), Self::Frame(fragment) => fragment.frame.width(),
Self::Spacing(amount) => *amount, Self::Spacing(spacing) => spacing.width,
Self::Space(amount) => *amount, Self::Space(amount) => *amount,
_ => Abs::zero(), _ => 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)] #[derive(Clone)]
pub struct GlyphFragment { pub struct GlyphFragment {
pub id: GlyphId, 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. /// Look up the italics correction for a glyph.
fn italics_correction(ctx: &MathContext, id: GlyphId) -> Option<Abs> { fn italics_correction(ctx: &MathContext, id: GlyphId) -> Option<Abs> {
Some(ctx.table.glyph_info?.italic_corrections?.get(id)?.scaled(ctx)) 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::diag::SourceResult;
use crate::foundations::{elem, func, Content, NativeElement, Resolve, Smart}; use crate::foundations::{elem, func, Content, NativeElement, Resolve, Smart};
use crate::layout::{Abs, Em, Length, Rel}; 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; use crate::text::TextElem;
/// How much less high scaled delimiters can be than what they wrap. /// 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); ctx.extend(fragments);
Ok(()) Ok(())

View File

@ -279,7 +279,10 @@ impl LayoutMath for Content {
if let Some(elem) = self.to::<HElem>() { if let Some(elem) = self.to::<HElem>() {
if let Spacing::Rel(rel) = elem.amount() { if let Spacing::Rel(rel) = elem.amount() {
if rel.rel.is_zero() { 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(()); return Ok(());

View File

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

View File

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