Handle non-breaking spaces during justification
This commit is contained in:
parent
0d12f2ab23
commit
b98004330b
@ -58,12 +58,12 @@ pub struct ShapedGlyph {
|
||||
impl ShapedGlyph {
|
||||
/// Whether the glyph is a space.
|
||||
pub fn is_space(&self) -> bool {
|
||||
self.c == ' '
|
||||
matches!(self.c, ' ' | '\u{00A0}' | ' ')
|
||||
}
|
||||
|
||||
/// Whether the glyph is justifiable.
|
||||
pub fn is_justifiable(&self) -> bool {
|
||||
matches!(self.c, ' ' | ',' | ' ' | '。' | '、')
|
||||
self.is_space() || matches!(self.c, ',' | '。' | '、')
|
||||
}
|
||||
}
|
||||
|
||||
@ -508,12 +508,14 @@ fn track_and_space(ctx: &mut ShapingContext) {
|
||||
.get(TextNode::SPACING)
|
||||
.map(|abs| Em::from_length(abs, ctx.size));
|
||||
|
||||
if tracking.is_zero() && spacing.is_one() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut glyphs = ctx.glyphs.iter_mut().peekable();
|
||||
while let Some(glyph) = glyphs.next() {
|
||||
// Make non-breaking space same width as normal space.
|
||||
if glyph.c == '\u{00A0}' {
|
||||
let face = ctx.fonts.get(glyph.face_id);
|
||||
glyph.x_advance -= nbsp_delta(face).unwrap_or_default();
|
||||
}
|
||||
|
||||
if glyph.is_space() {
|
||||
glyph.x_advance = spacing.relative_to(glyph.x_advance);
|
||||
}
|
||||
@ -524,6 +526,13 @@ fn track_and_space(ctx: &mut ShapingContext) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Difference between non-breaking and normal space.
|
||||
fn nbsp_delta(face: &Face) -> Option<Em> {
|
||||
let space = face.ttf().glyph_index(' ')?.0;
|
||||
let nbsp = face.ttf().glyph_index('\u{00A0}')?.0;
|
||||
Some(face.advance(nbsp)? - face.advance(space)?)
|
||||
}
|
||||
|
||||
/// Resolve the font variant with `BOLD` and `ITALIC` factored in.
|
||||
pub fn variant(styles: StyleChain) -> FontVariant {
|
||||
let mut variant = FontVariant::new(
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.7 KiB |
@ -3,6 +3,14 @@
|
||||
---
|
||||
The non-breaking~space does work.
|
||||
|
||||
---
|
||||
// Make sure non-breaking and normal space always
|
||||
// have the same width. Even if the font decided
|
||||
// differently.
|
||||
#set text("Latin Modern Roman")
|
||||
a b \
|
||||
a~b
|
||||
|
||||
---
|
||||
- En dash: --
|
||||
- Em dash: ---
|
||||
|
@ -128,7 +128,7 @@
|
||||
"captures": { "1": { "name": "punctuation.definition.label.typst" } }
|
||||
},
|
||||
{
|
||||
"begin": "(#)(pub|let|set|show|wrap)\\b",
|
||||
"begin": "(#)(pub|let|set|rule|select|show|wrap)\\b",
|
||||
"end": "\n|(;)|(?=])",
|
||||
"beginCaptures": {
|
||||
"0": { "name": "keyword.other.typst" },
|
||||
@ -239,7 +239,7 @@
|
||||
},
|
||||
{
|
||||
"name": "keyword.other.typst",
|
||||
"match": "\\b(pub|let|set|show|wrap|as|in|from)\\b"
|
||||
"match": "\\b(pub|let|set|rule|select|show|wrap|as|in|from)\\b"
|
||||
},
|
||||
{
|
||||
"name": "keyword.control.conditional.typst",
|
||||
|
Loading…
Reference in New Issue
Block a user