diff options
| author | Peng Guanwen <pg999w@outlook.com> | 2023-10-17 17:14:09 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-10-17 11:14:09 +0200 |
| commit | e4d9db83ea4b7b9a3003c754c80b30b87d6cd119 (patch) | |
| tree | a65e58179aa33adc4bf06732697a22da3dfb643b /crates/typst-library/src/text | |
| parent | a59666369b946c3a8b62db363659cbfca35f0a26 (diff) | |
Automatically add spacing between CJK and Latin characters (#2334)
Diffstat (limited to 'crates/typst-library/src/text')
| -rw-r--r-- | crates/typst-library/src/text/mod.rs | 12 | ||||
| -rw-r--r-- | crates/typst-library/src/text/shaping.rs | 17 |
2 files changed, 26 insertions, 3 deletions
diff --git a/crates/typst-library/src/text/mod.rs b/crates/typst-library/src/text/mod.rs index 748d71ad..4d2f5c63 100644 --- a/crates/typst-library/src/text/mod.rs +++ b/crates/typst-library/src/text/mod.rs @@ -19,6 +19,7 @@ pub use self::shift::*; use rustybuzz::Tag; use ttf_parser::Rect; use typst::diag::{bail, error, SourceResult}; +use typst::eval::Never; use typst::font::{Font, FontStretch, FontStyle, FontWeight, VerticalFontMetric}; use crate::layout::ParElem; @@ -224,6 +225,17 @@ pub struct TextElem { #[default(Rel::one())] pub spacing: Rel<Length>, + /// Whether to automatically insert spacing between CJK and Latin characters. + /// + /// ```example + /// #set text(cjk-latin-spacing: auto) + /// 第4章介绍了基本的API。 + /// + /// #set text(cjk-latin-spacing: none) + /// 第4章介绍了基本的API。 + /// ``` + pub cjk_latin_spacing: Smart<Option<Never>>, + /// An amount to shift the text baseline by. /// /// ```example diff --git a/crates/typst-library/src/text/shaping.rs b/crates/typst-library/src/text/shaping.rs index df30a9c8..1b7d9e09 100644 --- a/crates/typst-library/src/text/shaping.rs +++ b/crates/typst-library/src/text/shaping.rs @@ -100,9 +100,7 @@ impl ShapedGlyph { } pub fn is_cjk_script(&self) -> bool { - use Script::*; - // U+30FC: Katakana-Hiragana Prolonged Sound Mark - matches!(self.c.script(), Hiragana | Katakana | Han) || self.c == '\u{30FC}' + char_is_cjk_script(self.c) } pub fn is_cjk_punctuation(&self) -> bool { @@ -151,6 +149,13 @@ impl ShapedGlyph { matches!(self.c, '\u{30FB}') } + /// Whether the glyph is a western letter or number. + pub fn is_letter_or_number(&self) -> bool { + matches!(self.c.script(), Script::Latin | Script::Greek | Script::Cyrillic) + || matches!(self.c, '#' | '$' | '%' | '&') + || self.c.is_ascii_digit() + } + pub fn base_adjustability(&self, gb_style: bool) -> Adjustability { let width = self.x_advance; if self.is_space() { @@ -958,6 +963,12 @@ fn language(styles: StyleChain) -> rustybuzz::Language { rustybuzz::Language::from_str(&bcp).unwrap() } +pub fn char_is_cjk_script(c: char) -> bool { + use Script::*; + // U+30FC: Katakana-Hiragana Prolonged Sound Mark + matches!(c.script(), Hiragana | Katakana | Han) || c == '\u{30FC}' +} + /// Returns true if all glyphs in `glyphs` have ranges within the range `range`. #[cfg(debug_assertions)] fn assert_all_glyphs_in_range(glyphs: &[ShapedGlyph], text: &str, range: Range<usize>) { |
