summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst/src/layout/inline/shaping.rs44
-rw-r--r--crates/typst/src/text/item.rs6
2 files changed, 35 insertions, 15 deletions
diff --git a/crates/typst/src/layout/inline/shaping.rs b/crates/typst/src/layout/inline/shaping.rs
index 80fe476a..b91d0b0b 100644
--- a/crates/typst/src/layout/inline/shaping.rs
+++ b/crates/typst/src/layout/inline/shaping.rs
@@ -240,24 +240,24 @@ impl<'a> ShapedText<'a> {
}
let pos = Point::new(offset, top + shift - y_offset.at(self.size));
- let glyphs = group
+ let glyphs: Vec<Glyph> = group
.iter()
- .map(|glyph| {
+ .map(|shaped: &ShapedGlyph| {
let adjustability_left = if justification_ratio < 0.0 {
- glyph.shrinkability().0
+ shaped.shrinkability().0
} else {
- glyph.stretchability().0
+ shaped.stretchability().0
};
let adjustability_right = if justification_ratio < 0.0 {
- glyph.shrinkability().1
+ shaped.shrinkability().1
} else {
- glyph.stretchability().1
+ shaped.stretchability().1
};
let justification_left = adjustability_left * justification_ratio;
let mut justification_right =
adjustability_right * justification_ratio;
- if glyph.is_justifiable() {
+ if shaped.is_justifiable() {
justification_right +=
Em::from_length(extra_justification, self.size)
}
@@ -265,15 +265,33 @@ impl<'a> ShapedText<'a> {
frame.size_mut().x += justification_left.at(self.size)
+ justification_right.at(self.size);
+ // |<---- a Glyph ---->|
+ // -->|ShapedGlyph|<--
+ // +---+-----------+---+
+ // | | *********| |
+ // | | * | |
+ // | | * ****| |
+ // | | * *| |
+ // | | *********| |
+ // +---+--+--------+---+
+ // A B C D
+ // Note A, B, D could be positive, zero, or negative.
+ // A: justification_left
+ // B: ShapedGlyph's x_offset
+ // (though a small part of the glyph may go inside B)
+ // B+C: ShapedGlyph's x_advance
+ // D: justification_right
+ // A+B: Glyph's x_offset
+ // A+B+C+D: Glyph's x_advance
Glyph {
- id: glyph.glyph_id,
- x_advance: glyph.x_advance
+ id: shaped.glyph_id,
+ x_advance: shaped.x_advance
+ justification_left
+ justification_right,
- x_offset: glyph.x_offset + justification_left,
- range: (glyph.range.start - range.start).saturating_as()
- ..(glyph.range.end - range.start).saturating_as(),
- span: glyph.span,
+ x_offset: shaped.x_offset + justification_left,
+ range: (shaped.range.start - range.start).saturating_as()
+ ..(shaped.range.end - range.start).saturating_as(),
+ span: shaped.span,
}
})
.collect();
diff --git a/crates/typst/src/text/item.rs b/crates/typst/src/text/item.rs
index 081b06d7..49ed7851 100644
--- a/crates/typst/src/text/item.rs
+++ b/crates/typst/src/text/item.rs
@@ -21,7 +21,8 @@ pub struct TextItem {
pub lang: Lang,
/// The item's plain text.
pub text: EcoString,
- /// The glyphs.
+ /// The glyphs. The number of glyphs may be different from the number of
+ /// characters in the plain text due to e.g. ligatures.
pub glyphs: Vec<Glyph>,
}
@@ -49,7 +50,8 @@ pub struct Glyph {
pub x_advance: Em,
/// The horizontal offset of the glyph.
pub x_offset: Em,
- /// The range of the glyph in its item's text.
+ /// The range of the glyph in its item's text. The range's length may
+ /// be more than one due to multi-byte UTF-8 encoding or ligatures.
pub range: Range<u16>,
/// The source code location of the text.
pub span: (Span, u16),