Skip to content

Commit bfe7a77

Browse files
committed
[buffer] Expose more glyph flags
Fixes #163
1 parent a2d27a4 commit bfe7a77

File tree

1 file changed

+43
-0
lines changed

1 file changed

+43
-0
lines changed

src/hb/buffer.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,49 @@ impl hb_glyph_info_t {
193193
self.mask & glyph_flag::UNSAFE_TO_BREAK != 0
194194
}
195195

196+
/// Indicates that if input text is changed on one side of the beginning of the cluster
197+
/// this glyph is part of, then the shaping results for the other side might change.
198+
/// Note that the absence of this flag will NOT by itself mean that it IS safe to concat
199+
/// text. Only two pieces of text both of which clear of this flag can be concatenated
200+
/// safely.
201+
///
202+
/// This can be used to optimize paragraph layout, by avoiding re-shaping of each line after
203+
/// line-breaking, by limiting the reshaping to a small piece around the breaking position
204+
/// only, even if the breaking position carries the unsafe-to-break flag or when hyphenation
205+
/// or other text transformation happens at line-break position, in the following way:
206+
/// 1. Iterate back from the line-break position until the first cluster start position
207+
/// that is NOT unsafe-to-concat.
208+
/// 2. Shape the segment from there till the end of line.
209+
/// 3. Check whether the resulting glyph-run also is clear of the unsafe-to-concat at its
210+
/// start-of-text position; if it is, just splice it into place and the line is shaped;
211+
/// If not, move on to a position further back that is clear of unsafe-to-concat and retry
212+
/// from there, and repeat.
213+
///
214+
/// At the start of next line a similar algorithm can be implemented. That is:
215+
/// 1. Iterate forward from the line-break position until the first cluster start position that is
216+
/// NOT unsafe-to-concat.
217+
/// 2. Shape the segment from beginning of the line to that position.
218+
/// 3. Check whether the resulting glyph-run also is clear of the unsafe-to-concat at its end-of-text
219+
/// position; if it is, just splice it into place and the beginning is shaped; If not, move on to a
220+
/// position further forward that is clear of unsafe-to-concat and retry up to there, and repeat. A
221+
/// slight complication will arise in the implementation of the algorithm above, because while our
222+
/// buffer API has a way to return flags for position corresponding to start-of-text, there is currently
223+
/// no position corresponding to end-of-text. This limitation can be alleviated by shaping more text
224+
/// than needed and looking for unsafe-to-concat flag within text clusters. The unsafe-to-break flag will
225+
/// always imply this flag. To use this flag, you must enable the buffer flag [`BufferFlags::PRODUCE_UNSAFE_TO_CONCAT`]
226+
/// during shaping, otherwise the buffer flag will not be reliably produced.
227+
pub fn unsafe_to_concat(&self) -> bool {
228+
self.mask & glyph_flag::UNSAFE_TO_CONCAT != 0
229+
}
230+
231+
/// In scripts that use elongation (Arabic, Mongolian, Syriac, etc.), this flag signifies that it is
232+
/// safe to insert a U+0640 TATWEEL character before this cluster for elongation. This flag does not
233+
/// determine the script-specific elongation places, but only when it is safe to do the elongation
234+
/// without interrupting text shaping.
235+
pub fn safe_to_insert_tatweel(&self) -> bool {
236+
self.mask & glyph_flag::SAFE_TO_INSERT_TATWEEL != 0
237+
}
238+
196239
#[inline]
197240
pub(crate) fn as_char(&self) -> char {
198241
char::try_from(self.glyph_id).unwrap()

0 commit comments

Comments
 (0)