Handle non-breaking spaces during justification

This commit is contained in:
Laurenz 2022-09-19 10:28:06 +02:00
parent 0d12f2ab23
commit b98004330b
5 changed files with 25 additions and 8 deletions

View File

@ -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

View File

@ -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: ---

View File

@ -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",