Skip to content
Merged

Fixes #164

Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions src/hb/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,49 @@ impl hb_glyph_info_t {
self.mask & glyph_flag::UNSAFE_TO_BREAK != 0
}

/// Indicates that if input text is changed on one side of the beginning of the cluster
/// this glyph is part of, then the shaping results for the other side might change.
/// Note that the absence of this flag will NOT by itself mean that it IS safe to concat
/// text. Only two pieces of text both of which clear of this flag can be concatenated
/// safely.
///
/// This can be used to optimize paragraph layout, by avoiding re-shaping of each line after
/// line-breaking, by limiting the reshaping to a small piece around the breaking position
/// only, even if the breaking position carries the unsafe-to-break flag or when hyphenation
/// or other text transformation happens at line-break position, in the following way:
/// 1. Iterate back from the line-break position until the first cluster start position
/// that is NOT unsafe-to-concat.
/// 2. Shape the segment from there till the end of line.
/// 3. Check whether the resulting glyph-run also is clear of the unsafe-to-concat at its
/// start-of-text position; if it is, just splice it into place and the line is shaped;
/// If not, move on to a position further back that is clear of unsafe-to-concat and retry
/// from there, and repeat.
///
/// At the start of next line a similar algorithm can be implemented. That is:
/// 1. Iterate forward from the line-break position until the first cluster start position that is
/// NOT unsafe-to-concat.
/// 2. Shape the segment from beginning of the line to that position.
/// 3. Check whether the resulting glyph-run also is clear of the unsafe-to-concat at its end-of-text
/// position; if it is, just splice it into place and the beginning is shaped; If not, move on to a
/// position further forward that is clear of unsafe-to-concat and retry up to there, and repeat. A
/// slight complication will arise in the implementation of the algorithm above, because while our
/// buffer API has a way to return flags for position corresponding to start-of-text, there is currently
/// no position corresponding to end-of-text. This limitation can be alleviated by shaping more text
/// than needed and looking for unsafe-to-concat flag within text clusters. The unsafe-to-break flag will
/// always imply this flag. To use this flag, you must enable the buffer flag [`BufferFlags::PRODUCE_UNSAFE_TO_CONCAT`]
/// during shaping, otherwise the buffer flag will not be reliably produced.
pub fn unsafe_to_concat(&self) -> bool {
self.mask & glyph_flag::UNSAFE_TO_CONCAT != 0
}

/// In scripts that use elongation (Arabic, Mongolian, Syriac, etc.), this flag signifies that it is
/// safe to insert a U+0640 TATWEEL character before this cluster for elongation. This flag does not
/// determine the script-specific elongation places, but only when it is safe to do the elongation
/// without interrupting text shaping.
pub fn safe_to_insert_tatweel(&self) -> bool {
self.mask & glyph_flag::SAFE_TO_INSERT_TATWEEL != 0
}

#[inline]
pub(crate) fn as_char(&self) -> char {
char::try_from(self.glyph_id).unwrap()
Expand Down