diff --git a/library/src/layout/container.rs b/library/src/layout/container.rs index 0f81a1df2..166d6c09c 100644 --- a/library/src/layout/container.rs +++ b/library/src/layout/container.rs @@ -84,6 +84,7 @@ pub struct BoxElem { /// outset: (y: 3pt), /// radius: 2pt, /// )[rectangle]. + /// ``` #[resolve] #[fold] pub outset: Sides>>, diff --git a/library/src/text/shaping.rs b/library/src/text/shaping.rs index b895b6f9a..2dd0cd6d6 100644 --- a/library/src/text/shaping.rs +++ b/library/src/text/shaping.rs @@ -4,6 +4,7 @@ use std::str::FromStr; use rustybuzz::{Feature, Tag, UnicodeBuffer}; use typst::font::{Font, FontVariant}; use typst::util::SliceExt; +use unicode_script::{Script, UnicodeScript}; use super::*; use crate::layout::SpanMapper; @@ -69,11 +70,24 @@ impl ShapedGlyph { } /// Whether the glyph is justifiable. + /// + /// Typst's basic justification strategy is to stretch all the spaces + /// in a line until the line fills the available width. However, some + /// scripts (notably Chinese and Japanese) don't use spaces. + /// + /// In Japanese typography, the convention is to insert space evenly + /// between all glyphs. I assume it's the same in Chinese. pub fn is_justifiable(&self) -> bool { - self.is_space() || matches!(self.c, ',' | '。' | '、') + self.is_space() || is_spaceless(self.c.script()) } } +/// Does this script separate its words using spaces? +fn is_spaceless(script: Script) -> bool { + use Script::*; + matches!(script, Hiragana | Katakana | Han) +} + /// A side you can go toward. enum Side { /// To the left-hand side. diff --git a/tests/ref/layout/par-justify.png b/tests/ref/layout/par-justify.png index 1ef783326..8a1578fea 100644 Binary files a/tests/ref/layout/par-justify.png and b/tests/ref/layout/par-justify.png differ