From 7f9adfac22fc2b095ef0b859908ea02e39bcdd4b Mon Sep 17 00:00:00 2001 From: diquah <57377930+diquah@users.noreply.github.com> Date: Wed, 9 Apr 2025 23:20:46 -0700 Subject: [PATCH 1/8] Add microjustification --- crates/typst-layout/src/inline/line.rs | 18 +++++++++++++++++- crates/typst-layout/src/inline/mod.rs | 6 ++++++ crates/typst-layout/src/inline/shaping.rs | 21 +++++++++++++++++++++ crates/typst-library/src/model/par.rs | 11 +++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/crates/typst-layout/src/inline/line.rs b/crates/typst-layout/src/inline/line.rs index 659d33f4a..66a1c4d45 100644 --- a/crates/typst-layout/src/inline/line.rs +++ b/crates/typst-layout/src/inline/line.rs @@ -71,6 +71,16 @@ impl Line<'_> { count } + /// How many glyphs are in the text where we can insert micro-amounts + /// of additional space when encountering underfull lines. + fn microjustifiables(&self) -> usize { + let mut count = 0; + for shaped in self.items.iter().filter_map(Item::text) { + count += shaped.microjustifiables(); + } + count + } + /// How much the line can stretch. pub fn stretchability(&self) -> Abs { self.items @@ -472,6 +482,7 @@ pub fn commit( let fr = line.fr(); let mut justification_ratio = 0.0; let mut extra_justification = Abs::zero(); + let mut extra_microjustification = Abs::zero(); let shrinkability = line.shrinkability(); let stretchability = line.stretchability(); @@ -487,9 +498,13 @@ pub fn commit( } let justifiables = line.justifiables(); + let microjustifiables = line.microjustifiables(); + if justifiables > 0 && remaining > Abs::zero() { // Underfull line, distribute the extra space. - extra_justification = remaining / justifiables as f64; + extra_microjustification = (remaining / microjustifiables as f64).min(p.config.microjustification); + + extra_justification = (remaining - extra_microjustification * microjustifiables as f64) / justifiables as f64; remaining = Abs::zero(); } } @@ -531,6 +546,7 @@ pub fn commit( &p.spans, justification_ratio, extra_justification, + extra_microjustification, ); push(&mut offset, frame); } diff --git a/crates/typst-layout/src/inline/mod.rs b/crates/typst-layout/src/inline/mod.rs index 5ef820d07..87e6d3db0 100644 --- a/crates/typst-layout/src/inline/mod.rs +++ b/crates/typst-layout/src/inline/mod.rs @@ -183,11 +183,13 @@ fn configuration( situation: Option, ) -> Config { let justify = base.justify; + let microjustification = ParElem::microjustification_in(shared); let font_size = TextElem::size_in(shared); let dir = TextElem::dir_in(shared); Config { justify, + microjustification, linebreaks: base.linebreaks.unwrap_or_else(|| { if justify { Linebreaks::Optimized @@ -267,6 +269,10 @@ struct ConfigBase { struct Config { /// Whether to justify text. justify: bool, + + /// The maximum allowed kerning adjustment for microjustification. + microjustification: Abs, + /// How to determine line breaks. linebreaks: Linebreaks, /// The indent the first line of a paragraph should have. diff --git a/crates/typst-layout/src/inline/shaping.rs b/crates/typst-layout/src/inline/shaping.rs index 8236d1e36..1f57f1b34 100644 --- a/crates/typst-layout/src/inline/shaping.rs +++ b/crates/typst-layout/src/inline/shaping.rs @@ -83,6 +83,8 @@ pub struct ShapedGlyph { pub c: char, /// Whether this glyph is justifiable for CJK scripts. pub is_justifiable: bool, + /// Whether this glyph is allowed additional kerning for microjustification. + pub is_microjustifiable: bool, /// The script of the glyph. pub script: Script, } @@ -107,6 +109,11 @@ impl ShapedGlyph { self.is_justifiable } + /// Whether the glyph is microjustifiable. + pub fn is_microjustifiable(&self) -> bool { + self.is_microjustifiable + } + /// Whether the glyph is part of Chinese or Japanese script (i.e. CJ, not CJK). pub fn is_cj_script(&self) -> bool { is_cj_script(self.c, self.script) @@ -216,6 +223,7 @@ impl<'a> ShapedText<'a> { spans: &SpanMapper, justification_ratio: f64, extra_justification: Abs, + extra_microjustification: Abs, ) -> Frame { let (top, bottom) = self.measure(engine); let size = Size::new(self.width, top + bottom); @@ -261,6 +269,10 @@ impl<'a> ShapedText<'a> { justification_right += Em::from_length(extra_justification, self.size) } + if shaped.is_microjustifiable() { + justification_right += + Em::from_length(extra_microjustification, self.size) + } frame.size_mut().x += justification_left.at(self.size) + justification_right.at(self.size); @@ -375,6 +387,12 @@ impl<'a> ShapedText<'a> { self.glyphs.iter().filter(|g| g.is_justifiable()).count() } + /// How many glyphs are in the text that are allowed extra kerning for the + /// use of justification when encountering underfull lines. + pub fn microjustifiables(&self) -> usize { + self.glyphs.iter().filter(|g| g.is_microjustifiable()).count() + } + /// Whether the last glyph is a CJK character which should not be justified /// on line end. pub fn cjk_justifiable_at_last(&self) -> bool { @@ -496,6 +514,7 @@ impl<'a> ShapedText<'a> { safe_to_break: true, c: '-', is_justifiable: false, + is_microjustifiable: false, script: Script::Common, }; match side { @@ -881,6 +900,7 @@ fn shape_segment<'a>( x_advance, Adjustability::default().stretchability, ), + is_microjustifiable: true, script, }); } else { @@ -973,6 +993,7 @@ fn shape_tofus(ctx: &mut ShapingContext, base: usize, text: &str, font: Font) { x_advance, Adjustability::default().stretchability, ), + is_microjustifiable: false, script, }); }; diff --git a/crates/typst-library/src/model/par.rs b/crates/typst-library/src/model/par.rs index cf31b5195..a03c335fb 100644 --- a/crates/typst-library/src/model/par.rs +++ b/crates/typst-library/src/model/par.rs @@ -138,6 +138,17 @@ pub struct ParElem { #[default(false)] pub justify: bool, + /// The maximum amount of kerning that is allowed to be used to further + /// justify an existing line. When this value is nonzero, additional + /// justification will be applied to individual glyphs. + /// + /// Note that microjustifications are applied only after a line of text has + /// been constructed. This means that the layout will *not* be affected by + /// microjustifications, but the internal kerning of a line will be. + #[resolve] + #[default(Em::new(0.0).into())] + pub microjustification: Length, + /// How to determine line breaks. /// /// When this property is set to `{auto}`, its default value, optimized line From 422eb36f160bb85053df801f0acc6a9327e9ed90 Mon Sep 17 00:00:00 2001 From: diquah <57377930+diquah@users.noreply.github.com> Date: Thu, 10 Apr 2025 00:15:44 -0700 Subject: [PATCH 2/8] Fix formatting issue --- crates/typst-layout/src/inline/line.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/typst-layout/src/inline/line.rs b/crates/typst-layout/src/inline/line.rs index 66a1c4d45..55b8b8cff 100644 --- a/crates/typst-layout/src/inline/line.rs +++ b/crates/typst-layout/src/inline/line.rs @@ -502,9 +502,13 @@ pub fn commit( if justifiables > 0 && remaining > Abs::zero() { // Underfull line, distribute the extra space. - extra_microjustification = (remaining / microjustifiables as f64).min(p.config.microjustification); + extra_microjustification = + (remaining / microjustifiables as f64).min(p.config.microjustification); + + extra_justification = (remaining + - extra_microjustification * microjustifiables as f64) + / justifiables as f64; - extra_justification = (remaining - extra_microjustification * microjustifiables as f64) / justifiables as f64; remaining = Abs::zero(); } } From 07ba1c1636ad79395f8204b0bdc2b1e5cbb0ff1f Mon Sep 17 00:00:00 2001 From: diquah <57377930+diquah@users.noreply.github.com> Date: Thu, 10 Apr 2025 19:01:02 -0700 Subject: [PATCH 3/8] Add microtype options for par --- crates/typst-layout/src/inline/line.rs | 15 ++++++-- crates/typst-layout/src/inline/mod.rs | 12 +++---- crates/typst-layout/src/inline/shaping.rs | 13 ++++--- crates/typst-library/src/model/par.rs | 42 +++++++++++++++++------ 4 files changed, 58 insertions(+), 24 deletions(-) diff --git a/crates/typst-layout/src/inline/line.rs b/crates/typst-layout/src/inline/line.rs index 55b8b8cff..4d48c9225 100644 --- a/crates/typst-layout/src/inline/line.rs +++ b/crates/typst-layout/src/inline/line.rs @@ -488,7 +488,16 @@ pub fn commit( let stretchability = line.stretchability(); if remaining < Abs::zero() && shrinkability > Abs::zero() { // Attempt to reduce the length of the line, using shrinkability. - justification_ratio = (remaining / shrinkability).max(-1.0); + let microjustifiables = line.microjustifiables(); + + extra_microjustification = (remaining / microjustifiables as f64) + .max(p.config.microtype.max_retract.abs); + + justification_ratio = ((remaining + - extra_microjustification * microjustifiables as f64) + / shrinkability) + .max(-1.0); + remaining = (remaining + shrinkability).min(Abs::zero()); } else if line.justify && fr.is_zero() { // Attempt to increase the length of the line, using stretchability. @@ -502,8 +511,8 @@ pub fn commit( if justifiables > 0 && remaining > Abs::zero() { // Underfull line, distribute the extra space. - extra_microjustification = - (remaining / microjustifiables as f64).min(p.config.microjustification); + extra_microjustification = (remaining / microjustifiables as f64) + .min(p.config.microtype.max_expand.abs); extra_justification = (remaining - extra_microjustification * microjustifiables as f64) diff --git a/crates/typst-layout/src/inline/mod.rs b/crates/typst-layout/src/inline/mod.rs index 87e6d3db0..1ffef5154 100644 --- a/crates/typst-layout/src/inline/mod.rs +++ b/crates/typst-layout/src/inline/mod.rs @@ -17,8 +17,8 @@ use typst_library::foundations::{Packed, Resolve, Smart, StyleChain}; use typst_library::introspection::{Introspector, Locator, LocatorLink, SplitLocator}; use typst_library::layout::{Abs, AlignElem, Dir, FixedAlignment, Fragment, Size}; use typst_library::model::{ - EnumElem, FirstLineIndent, Linebreaks, ListElem, ParElem, ParLine, ParLineMarker, - TermsElem, + EnumElem, FirstLineIndent, Linebreaks, ListElem, Microtype, ParElem, ParLine, + ParLineMarker, TermsElem, }; use typst_library::routines::{Arenas, Pair, RealizationKind, Routines}; use typst_library::text::{Costs, Lang, TextElem}; @@ -183,13 +183,13 @@ fn configuration( situation: Option, ) -> Config { let justify = base.justify; - let microjustification = ParElem::microjustification_in(shared); + let microtype = ParElem::microtype_in(shared); let font_size = TextElem::size_in(shared); let dir = TextElem::dir_in(shared); Config { justify, - microjustification, + microtype, linebreaks: base.linebreaks.unwrap_or_else(|| { if justify { Linebreaks::Optimized @@ -269,10 +269,8 @@ struct ConfigBase { struct Config { /// Whether to justify text. justify: bool, - /// The maximum allowed kerning adjustment for microjustification. - microjustification: Abs, - + microtype: Microtype, /// How to determine line breaks. linebreaks: Linebreaks, /// The indent the first line of a paragraph should have. diff --git a/crates/typst-layout/src/inline/shaping.rs b/crates/typst-layout/src/inline/shaping.rs index 1f57f1b34..037c6ac40 100644 --- a/crates/typst-layout/src/inline/shaping.rs +++ b/crates/typst-layout/src/inline/shaping.rs @@ -10,6 +10,7 @@ use ttf_parser::Tag; use typst_library::engine::Engine; use typst_library::foundations::{Smart, StyleChain}; use typst_library::layout::{Abs, Dir, Em, Frame, FrameItem, Point, Size}; +use typst_library::model::{Microtype, ParElem}; use typst_library::text::{ families, features, is_default_ignorable, variant, Font, FontFamily, FontVariant, Glyph, Lang, Region, TextEdgeBounds, TextElem, TextItem, @@ -152,7 +153,7 @@ impl ShapedGlyph { || self.c.is_ascii_digit() } - pub fn base_adjustability(&self, style: CjkPunctStyle) -> Adjustability { + pub fn base_adjustability(&self, style: CjkPunctStyle, microtype: Microtype) -> Adjustability { let width = self.x_advance; if self.is_space() { Adjustability { @@ -176,7 +177,10 @@ impl ShapedGlyph { shrinkability: (width / 4.0, width / 4.0), } } else { - Adjustability::default() + Adjustability { + stretchability: (Em::zero(), microtype.max_expand.em), + shrinkability: (Em::zero(), microtype.max_retract.em), + } } } @@ -900,7 +904,7 @@ fn shape_segment<'a>( x_advance, Adjustability::default().stretchability, ), - is_microjustifiable: true, + is_microjustifiable: false, script, }); } else { @@ -1034,9 +1038,10 @@ fn track_and_space(ctx: &mut ShapingContext) { /// and CJK punctuation adjustments according to Chinese Layout Requirements. fn calculate_adjustability(ctx: &mut ShapingContext, lang: Lang, region: Option) { let style = cjk_punct_style(lang, region); + let microtype = ParElem::microtype_in(ctx.styles); for glyph in &mut ctx.glyphs { - glyph.adjustability = glyph.base_adjustability(style); + glyph.adjustability = glyph.base_adjustability(style, microtype); } let mut glyphs = ctx.glyphs.iter_mut().peekable(); diff --git a/crates/typst-library/src/model/par.rs b/crates/typst-library/src/model/par.rs index a03c335fb..55e6622f0 100644 --- a/crates/typst-library/src/model/par.rs +++ b/crates/typst-library/src/model/par.rs @@ -138,16 +138,8 @@ pub struct ParElem { #[default(false)] pub justify: bool, - /// The maximum amount of kerning that is allowed to be used to further - /// justify an existing line. When this value is nonzero, additional - /// justification will be applied to individual glyphs. - /// - /// Note that microjustifications are applied only after a line of text has - /// been constructed. This means that the layout will *not* be affected by - /// microjustifications, but the internal kerning of a line will be. - #[resolve] - #[default(Em::new(0.0).into())] - pub microjustification: Length, + /// Microtypographical settings that are used during justification. + pub microtype: Microtype, /// How to determine line breaks. /// @@ -238,6 +230,36 @@ impl ParElem { type ParLine; } +/// Configuration for microtypographical settings to be used during +/// justification. +#[derive(Debug, Default, Copy, Clone, PartialEq, Hash)] +pub struct Microtype { + /// How much a glyph is allowed to translate into its neighbor. + pub max_retract: Length, + /// How much a glyph is allowed to translate away from its neighbor. + pub max_expand: Length, +} + +cast! { + Microtype, + self => Value::Dict(self.into()), + mut dict: Dict => { + let max_retract = dict.take("max_retract")?.cast()?; + let max_expand = dict.take("max_expand")?.cast()?; + dict.finish(&["max_retract", "max_expand"])?; + Self { max_retract, max_expand } + }, +} + +impl From for Dict { + fn from(microtype: Microtype) -> Self { + dict! { + "max_retract" => microtype.max_retract, + "max_expand" => microtype.max_expand, + } + } +} + /// How to determine line breaks in a paragraph. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Cast)] pub enum Linebreaks { From 7d6d46c4d83459a50a09675ef72929f0c9252ebf Mon Sep 17 00:00:00 2001 From: diquah <57377930+diquah@users.noreply.github.com> Date: Thu, 10 Apr 2025 19:05:30 -0700 Subject: [PATCH 4/8] Remove microjustification --- crates/typst-layout/src/inline/line.rs | 31 ++--------------------- crates/typst-layout/src/inline/shaping.rs | 27 ++++---------------- 2 files changed, 7 insertions(+), 51 deletions(-) diff --git a/crates/typst-layout/src/inline/line.rs b/crates/typst-layout/src/inline/line.rs index 4d48c9225..4cedf3451 100644 --- a/crates/typst-layout/src/inline/line.rs +++ b/crates/typst-layout/src/inline/line.rs @@ -71,16 +71,6 @@ impl Line<'_> { count } - /// How many glyphs are in the text where we can insert micro-amounts - /// of additional space when encountering underfull lines. - fn microjustifiables(&self) -> usize { - let mut count = 0; - for shaped in self.items.iter().filter_map(Item::text) { - count += shaped.microjustifiables(); - } - count - } - /// How much the line can stretch. pub fn stretchability(&self) -> Abs { self.items @@ -482,21 +472,12 @@ pub fn commit( let fr = line.fr(); let mut justification_ratio = 0.0; let mut extra_justification = Abs::zero(); - let mut extra_microjustification = Abs::zero(); let shrinkability = line.shrinkability(); let stretchability = line.stretchability(); if remaining < Abs::zero() && shrinkability > Abs::zero() { // Attempt to reduce the length of the line, using shrinkability. - let microjustifiables = line.microjustifiables(); - - extra_microjustification = (remaining / microjustifiables as f64) - .max(p.config.microtype.max_retract.abs); - - justification_ratio = ((remaining - - extra_microjustification * microjustifiables as f64) - / shrinkability) - .max(-1.0); + justification_ratio = (remaining / shrinkability).max(-1.0); remaining = (remaining + shrinkability).min(Abs::zero()); } else if line.justify && fr.is_zero() { @@ -507,17 +488,10 @@ pub fn commit( } let justifiables = line.justifiables(); - let microjustifiables = line.microjustifiables(); if justifiables > 0 && remaining > Abs::zero() { // Underfull line, distribute the extra space. - extra_microjustification = (remaining / microjustifiables as f64) - .min(p.config.microtype.max_expand.abs); - - extra_justification = (remaining - - extra_microjustification * microjustifiables as f64) - / justifiables as f64; - + extra_justification = remaining / justifiables as f64; remaining = Abs::zero(); } } @@ -559,7 +533,6 @@ pub fn commit( &p.spans, justification_ratio, extra_justification, - extra_microjustification, ); push(&mut offset, frame); } diff --git a/crates/typst-layout/src/inline/shaping.rs b/crates/typst-layout/src/inline/shaping.rs index 037c6ac40..55a1db4bc 100644 --- a/crates/typst-layout/src/inline/shaping.rs +++ b/crates/typst-layout/src/inline/shaping.rs @@ -84,8 +84,6 @@ pub struct ShapedGlyph { pub c: char, /// Whether this glyph is justifiable for CJK scripts. pub is_justifiable: bool, - /// Whether this glyph is allowed additional kerning for microjustification. - pub is_microjustifiable: bool, /// The script of the glyph. pub script: Script, } @@ -110,11 +108,6 @@ impl ShapedGlyph { self.is_justifiable } - /// Whether the glyph is microjustifiable. - pub fn is_microjustifiable(&self) -> bool { - self.is_microjustifiable - } - /// Whether the glyph is part of Chinese or Japanese script (i.e. CJ, not CJK). pub fn is_cj_script(&self) -> bool { is_cj_script(self.c, self.script) @@ -153,7 +146,11 @@ impl ShapedGlyph { || self.c.is_ascii_digit() } - pub fn base_adjustability(&self, style: CjkPunctStyle, microtype: Microtype) -> Adjustability { + pub fn base_adjustability( + &self, + style: CjkPunctStyle, + microtype: Microtype, + ) -> Adjustability { let width = self.x_advance; if self.is_space() { Adjustability { @@ -227,7 +224,6 @@ impl<'a> ShapedText<'a> { spans: &SpanMapper, justification_ratio: f64, extra_justification: Abs, - extra_microjustification: Abs, ) -> Frame { let (top, bottom) = self.measure(engine); let size = Size::new(self.width, top + bottom); @@ -273,10 +269,6 @@ impl<'a> ShapedText<'a> { justification_right += Em::from_length(extra_justification, self.size) } - if shaped.is_microjustifiable() { - justification_right += - Em::from_length(extra_microjustification, self.size) - } frame.size_mut().x += justification_left.at(self.size) + justification_right.at(self.size); @@ -391,12 +383,6 @@ impl<'a> ShapedText<'a> { self.glyphs.iter().filter(|g| g.is_justifiable()).count() } - /// How many glyphs are in the text that are allowed extra kerning for the - /// use of justification when encountering underfull lines. - pub fn microjustifiables(&self) -> usize { - self.glyphs.iter().filter(|g| g.is_microjustifiable()).count() - } - /// Whether the last glyph is a CJK character which should not be justified /// on line end. pub fn cjk_justifiable_at_last(&self) -> bool { @@ -518,7 +504,6 @@ impl<'a> ShapedText<'a> { safe_to_break: true, c: '-', is_justifiable: false, - is_microjustifiable: false, script: Script::Common, }; match side { @@ -904,7 +889,6 @@ fn shape_segment<'a>( x_advance, Adjustability::default().stretchability, ), - is_microjustifiable: false, script, }); } else { @@ -997,7 +981,6 @@ fn shape_tofus(ctx: &mut ShapingContext, base: usize, text: &str, font: Font) { x_advance, Adjustability::default().stretchability, ), - is_microjustifiable: false, script, }); }; From 4fa7e5cfd9bdd7368a47ecd6f09012818fac5180 Mon Sep 17 00:00:00 2001 From: diquah <57377930+diquah@users.noreply.github.com> Date: Thu, 10 Apr 2025 19:18:21 -0700 Subject: [PATCH 5/8] Fix warnings --- crates/typst-layout/src/inline/mod.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/crates/typst-layout/src/inline/mod.rs b/crates/typst-layout/src/inline/mod.rs index 1ffef5154..05b957911 100644 --- a/crates/typst-layout/src/inline/mod.rs +++ b/crates/typst-layout/src/inline/mod.rs @@ -17,7 +17,7 @@ use typst_library::foundations::{Packed, Resolve, Smart, StyleChain}; use typst_library::introspection::{Introspector, Locator, LocatorLink, SplitLocator}; use typst_library::layout::{Abs, AlignElem, Dir, FixedAlignment, Fragment, Size}; use typst_library::model::{ - EnumElem, FirstLineIndent, Linebreaks, ListElem, Microtype, ParElem, ParLine, + EnumElem, FirstLineIndent, Linebreaks, ListElem, ParElem, ParLine, ParLineMarker, TermsElem, }; use typst_library::routines::{Arenas, Pair, RealizationKind, Routines}; @@ -183,13 +183,11 @@ fn configuration( situation: Option, ) -> Config { let justify = base.justify; - let microtype = ParElem::microtype_in(shared); let font_size = TextElem::size_in(shared); let dir = TextElem::dir_in(shared); Config { justify, - microtype, linebreaks: base.linebreaks.unwrap_or_else(|| { if justify { Linebreaks::Optimized @@ -269,8 +267,6 @@ struct ConfigBase { struct Config { /// Whether to justify text. justify: bool, - /// The maximum allowed kerning adjustment for microjustification. - microtype: Microtype, /// How to determine line breaks. linebreaks: Linebreaks, /// The indent the first line of a paragraph should have. From 69d0d9e26d38766b94cb80d16866f11730559d88 Mon Sep 17 00:00:00 2001 From: diquah <57377930+diquah@users.noreply.github.com> Date: Thu, 10 Apr 2025 19:23:21 -0700 Subject: [PATCH 6/8] Formatting fix --- crates/typst-layout/src/inline/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/typst-layout/src/inline/mod.rs b/crates/typst-layout/src/inline/mod.rs index 05b957911..5ef820d07 100644 --- a/crates/typst-layout/src/inline/mod.rs +++ b/crates/typst-layout/src/inline/mod.rs @@ -17,8 +17,8 @@ use typst_library::foundations::{Packed, Resolve, Smart, StyleChain}; use typst_library::introspection::{Introspector, Locator, LocatorLink, SplitLocator}; use typst_library::layout::{Abs, AlignElem, Dir, FixedAlignment, Fragment, Size}; use typst_library::model::{ - EnumElem, FirstLineIndent, Linebreaks, ListElem, ParElem, ParLine, - ParLineMarker, TermsElem, + EnumElem, FirstLineIndent, Linebreaks, ListElem, ParElem, ParLine, ParLineMarker, + TermsElem, }; use typst_library::routines::{Arenas, Pair, RealizationKind, Routines}; use typst_library::text::{Costs, Lang, TextElem}; From c8d45148f1e3215e0b6f4c6672950bb6475747a8 Mon Sep 17 00:00:00 2001 From: diquah <57377930+diquah@users.noreply.github.com> Date: Fri, 2 May 2025 16:58:45 -0700 Subject: [PATCH 7/8] Fix naming convention --- crates/typst-layout/src/inline/line.rs | 1 - crates/typst-library/src/model/par.rs | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/crates/typst-layout/src/inline/line.rs b/crates/typst-layout/src/inline/line.rs index 4cedf3451..dffce689a 100644 --- a/crates/typst-layout/src/inline/line.rs +++ b/crates/typst-layout/src/inline/line.rs @@ -478,7 +478,6 @@ pub fn commit( if remaining < Abs::zero() && shrinkability > Abs::zero() { // Attempt to reduce the length of the line, using shrinkability. justification_ratio = (remaining / shrinkability).max(-1.0); - remaining = (remaining + shrinkability).min(Abs::zero()); } else if line.justify && fr.is_zero() { // Attempt to increase the length of the line, using stretchability. diff --git a/crates/typst-library/src/model/par.rs b/crates/typst-library/src/model/par.rs index 55e6622f0..1afa29f1f 100644 --- a/crates/typst-library/src/model/par.rs +++ b/crates/typst-library/src/model/par.rs @@ -244,9 +244,9 @@ cast! { Microtype, self => Value::Dict(self.into()), mut dict: Dict => { - let max_retract = dict.take("max_retract")?.cast()?; - let max_expand = dict.take("max_expand")?.cast()?; - dict.finish(&["max_retract", "max_expand"])?; + let max_retract = dict.take("max-retract")?.cast()?; + let max_expand = dict.take("max-expand")?.cast()?; + dict.finish(&["max-retract", "max-expand"])?; Self { max_retract, max_expand } }, } @@ -254,8 +254,8 @@ cast! { impl From for Dict { fn from(microtype: Microtype) -> Self { dict! { - "max_retract" => microtype.max_retract, - "max_expand" => microtype.max_expand, + "max-retract" => microtype.max_retract, + "max-expand" => microtype.max_expand, } } } From 34e2e4344542b145b1991236571b55e050d5aa7c Mon Sep 17 00:00:00 2001 From: diquah <57377930+diquah@users.noreply.github.com> Date: Fri, 2 May 2025 17:09:18 -0700 Subject: [PATCH 8/8] Minor formatting fix --- crates/typst-layout/src/inline/line.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/typst-layout/src/inline/line.rs b/crates/typst-layout/src/inline/line.rs index dffce689a..659d33f4a 100644 --- a/crates/typst-layout/src/inline/line.rs +++ b/crates/typst-layout/src/inline/line.rs @@ -487,7 +487,6 @@ pub fn commit( } let justifiables = line.justifiables(); - if justifiables > 0 && remaining > Abs::zero() { // Underfull line, distribute the extra space. extra_justification = remaining / justifiables as f64;