1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
//! The lookup flag type.
//!
//! This is kind-of-but-not-quite-exactly a bit enumeration, and so we implement
//! it manually.
/// The [LookupFlag](https://learn.microsoft.com/en-us/typography/opentype/spec/chapter2#lookupFlag) bit enumeration.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct LookupFlag(u16);
impl LookupFlag {
/// Return new, empty flags
pub fn empty() -> Self {
Self(0)
}
/// Construct a LookupFlag from a raw value, discarding invalid bits
pub fn from_bits_truncate(bits: u16) -> Self {
const VALID_BITS: u16 = !0x00E0;
Self(bits & VALID_BITS)
}
/// Raw transmutation to u16.
pub fn to_bits(self) -> u16 {
self.0
}
/// This bit relates only to the correct processing of the cursive attachment
/// lookup type (GPOS lookup type 3).
///
/// When this bit is set, the last glyph in a given sequence to which the
/// cursive attachment lookup is applied, will be positioned on the baseline.
pub fn right_to_left(self) -> bool {
(self.0 & 0x0001) != 0
}
/// This bit relates only to the correct processing of the cursive attachment
/// lookup type (GPOS lookup type 3).
///
/// When this bit is set, the last glyph in a given sequence to which the
/// cursive attachment lookup is applied, will be positioned on the baseline.
pub fn set_right_to_left(&mut self, val: bool) {
if val {
self.0 |= 0x0001
} else {
self.0 &= !0x0001
}
}
/// If set, skips over base glyphs
pub fn ignore_base_glyphs(self) -> bool {
(self.0 & 0x0002) != 0
}
/// If set, skips over base glyphs
pub fn set_ignore_base_glyphs(&mut self, val: bool) {
if val {
self.0 |= 0x0002
} else {
self.0 &= !0x0002
}
}
/// If set, skips over ligatures
pub fn ignore_ligatures(self) -> bool {
(self.0 & 0x0004) != 0
}
/// If set, skips over ligatures
pub fn set_ignore_ligatures(&mut self, val: bool) {
if val {
self.0 |= 0x0004
} else {
self.0 &= !0x0004
}
}
/// If set, skips over all combining marks
pub fn ignore_marks(self) -> bool {
(self.0 & 0x0008) != 0
}
/// If set, skips over all combining marks
pub fn set_ignore_marks(&mut self, val: bool) {
if val {
self.0 |= 0x0008
} else {
self.0 &= !0x0008
}
}
/// If set, indicates that the lookup table structure is followed by a
/// MarkFilteringSet field.
///
/// The layout engine skips over all mark glyphs not in the mark filtering set
/// indicated.
pub fn use_mark_filtering_set(self) -> bool {
(self.0 & 0x0010) != 0
}
/// If set, indicates that the lookup table structure is followed by a
/// MarkFilteringSet field.
///
/// The layout engine skips over all mark glyphs not in the mark filtering set
/// indicated.
pub fn set_use_mark_filtering_set(&mut self, val: bool) {
if val {
self.0 |= 0x0010
} else {
self.0 &= !0x0010
}
}
/// If not zero, skips over all marks of attachment type different from specified.
pub fn mark_attachment_type_mask(self) -> Option<u16> {
let val = self.0 & 0xff00;
if val == 0 {
None
} else {
Some(val >> 8)
}
}
/// If not zero, skips over all marks of attachment type different from specified.
pub fn set_mark_attachment_type(&mut self, val: u16) {
let val = (val & 0xff) << 8;
self.0 = (self.0 & 0xff) | val;
}
}
impl types::Scalar for LookupFlag {
type Raw = <u16 as types::Scalar>::Raw;
fn to_raw(self) -> Self::Raw {
self.0.to_raw()
}
fn from_raw(raw: Self::Raw) -> Self {
let t = <u16>::from_raw(raw);
Self(t)
}
}