swash/shape/cluster.rs
1/*!
2Glyph cluster modeling-- output from the shaper.
3*/
4
5use super::buffer::MARK_ATTACH;
6use crate::text::cluster::{ClusterInfo, SourceRange, UserData};
7use crate::GlyphId;
8
9/// Information for a glyph.
10#[derive(Copy, Clone, Default, Debug)]
11pub struct GlyphInfo(pub u16);
12
13impl GlyphInfo {
14 /// Returns true if the glyph is an attached mark.
15 pub fn is_mark(self) -> bool {
16 self.0 & MARK_ATTACH != 0
17 }
18}
19
20/// Glyph identifier and positioning information as a result of shaping.
21#[derive(Copy, Clone, Default, Debug)]
22pub struct Glyph {
23 /// Glyph identifier.
24 pub id: GlyphId,
25 /// Glyph flags.
26 pub info: GlyphInfo,
27 /// Horizontal offset.
28 pub x: f32,
29 /// Vertical offset.
30 pub y: f32,
31 /// Advance width or height.
32 pub advance: f32,
33 /// Arbitrary user data.
34 pub data: UserData,
35}
36
37/// Collection of glyphs and associated metadata corresponding to one or
38/// more source clusters.
39#[derive(Copy, Clone, Debug)]
40pub struct GlyphCluster<'a> {
41 /// Full source range of the cluster in original units supplied to the
42 /// shaper.
43 pub source: SourceRange,
44 /// Information about the textual content of the cluster.
45 pub info: ClusterInfo,
46 /// Sequence of glyphs for the cluster. May be empty for clusters whose
47 /// source consisted entirely of control characters.
48 pub glyphs: &'a [Glyph],
49 /// If the cluster is a ligature, this contains the source range
50 /// of each ligature component. Empty otherwise.
51 pub components: &'a [SourceRange],
52 /// Arbitrary user data-- taken from the initial character of the cluster.
53 pub data: UserData,
54}
55
56impl<'a> GlyphCluster<'a> {
57 /// Returns true if the cluster is empty. Empty clusters still represent
58 /// characters in the source text, but contain no glyphs. This will be
59 /// true, for example, with newline sequences (\n or \r\n) as well as other
60 /// control characters.
61 pub fn is_empty(&self) -> bool {
62 self.glyphs.is_empty()
63 }
64
65 /// Returns true if the cluster contains a single glyph. Note that a simple
66 /// cluster can also be a ligature.
67 pub fn is_simple(&self) -> bool {
68 self.glyphs.len() == 1
69 }
70
71 /// Returns true if the cluster corresponds to multiple source clusters.
72 /// Note that a ligature cluster can also be complex.
73 pub fn is_ligature(&self) -> bool {
74 !self.components.is_empty()
75 }
76
77 /// Returns true if the cluster is complex-- that is if it contains more
78 /// than one glyph. This will be true for clusters containing marks and is
79 /// also commonly true for syllabic languages such as those in the Indic
80 /// family.
81 pub fn is_complex(&self) -> bool {
82 self.glyphs.len() > 1
83 }
84
85 /// Computes the full advance width or height of the cluster.
86 pub fn advance(&self) -> f32 {
87 let mut advance = 0.;
88 for g in self.glyphs {
89 advance += g.advance;
90 }
91 advance
92 }
93}