1 //! Graphics state for the TrueType interpreter. 2 3 mod projection; 4 mod round; 5 mod zone; 6 7 use core::ops::{Deref, DerefMut}; 8 use read_fonts::types::Point; 9 10 pub use { 11 round::{RoundMode, RoundState}, 12 zone::{Zone, ZonePointer}, 13 }; 14 15 /// Describes the axis to which a measurement or point movement operation 16 /// applies. 17 #[derive(Copy, Clone, PartialEq, Eq, Default, Debug)] 18 pub enum CoordAxis { 19 #[default] 20 Both, 21 X, 22 Y, 23 } 24 25 /// Context in which instructions are executed. 26 /// 27 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html> 28 #[derive(Debug)] 29 pub struct GraphicsState<'a> { 30 /// Fields of the graphics state that persist between calls to the intepreter. 31 pub retained: RetainedGraphicsState, 32 /// A unit vector whose direction establishes an axis along which 33 /// distances are measured. 34 /// 35 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#projection%20vector> 36 pub proj_vector: Point<i32>, 37 /// Current axis for the projection vector. 38 pub proj_axis: CoordAxis, 39 /// A second projection vector set to a line defined by the original 40 /// outline location of two points. The dual projection vector is used 41 /// when it is necessary to measure distances from the scaled outline 42 /// before any instructions were executed. 43 /// 44 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#dual%20projection%20vector> 45 pub dual_proj_vector: Point<i32>, 46 /// Current axis for the dual projection vector. 47 pub dual_proj_axis: CoordAxis, 48 /// A unit vector that establishes an axis along which points can move. 49 /// 50 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#freedom%20vector> 51 pub freedom_vector: Point<i32>, 52 /// Current axis for point movement. 53 pub freedom_axis: CoordAxis, 54 /// Dot product of freedom and projection vectors. 55 pub fdotp: i32, 56 /// Determines the manner in which values are rounded. 57 /// 58 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#round%20state> 59 pub round_state: RoundState, 60 /// First reference point. 61 /// 62 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#rp0> 63 pub rp0: usize, 64 /// Second reference point. 65 /// 66 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#rp1> 67 pub rp1: usize, 68 /// Third reference point. 69 /// 70 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#rp1> 71 pub rp2: usize, 72 /// Makes it possible to repeat certain instructions a designated number of 73 /// times. The default value of one assures that unless the value of loop 74 /// is altered, these instructions will execute one time. 75 /// 76 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#loop> 77 pub loop_counter: u32, 78 /// First zone pointer. 79 /// 80 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#zp0> 81 pub zp0: ZonePointer, 82 /// Second zone pointer. 83 /// 84 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#zp1> 85 pub zp1: ZonePointer, 86 /// Third zone pointer. 87 /// 88 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#zp2> 89 pub zp2: ZonePointer, 90 /// Outline data for each zone. 91 /// 92 /// This array contains the twilight and glyph zones, in that order. 93 pub zones: [Zone<'a>; 2], 94 /// If true, enables a set of backward compabitility heuristics. 95 /// Otherwise, the interpreter operates in "native ClearType mode". 96 /// 97 /// Defaults to true. 98 /// 99 /// See <https://gitlab.freedesktop.org/freetype/freetype/-/blob/57617782464411201ce7bbc93b086c1b4d7d84a5/src/truetype/ttinterp.h#L344> 100 pub backward_compatibility: bool, 101 } 102 103 impl Default for GraphicsState<'_> { default() -> Self104 fn default() -> Self { 105 // For table of default values, see <https://learn.microsoft.com/en-us/typography/opentype/spec/tt_graphics_state> 106 // All vectors are set to the x-axis (normalized in 2.14) 107 let vector = Point::new(0x4000, 0); 108 Self { 109 retained: RetainedGraphicsState::default(), 110 proj_vector: vector, 111 proj_axis: CoordAxis::Both, 112 dual_proj_vector: vector, 113 dual_proj_axis: CoordAxis::Both, 114 freedom_vector: vector, 115 freedom_axis: CoordAxis::Both, 116 fdotp: 0x4000, 117 round_state: RoundState::default(), 118 rp0: 0, 119 rp1: 0, 120 rp2: 0, 121 loop_counter: 1, 122 zp0: ZonePointer::default(), 123 zp1: ZonePointer::default(), 124 zp2: ZonePointer::default(), 125 zones: [Zone::default(), Zone::default()], 126 backward_compatibility: true, 127 } 128 } 129 } 130 131 /// The persistent graphics state. 132 /// 133 /// Some of the graphics state is set by the control value program and 134 /// persists between runs of the interpreter. This struct captures that 135 /// state. 136 /// 137 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html> 138 #[derive(Copy, Clone, Debug)] 139 pub struct RetainedGraphicsState { 140 /// Controls whether the sign of control value table entries will be 141 /// changed to match the sign of the actual distance measurement with 142 /// which it is compared. 143 /// 144 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#auto%20flip> 145 pub auto_flip: bool, 146 /// Limits the regularizing effects of control value table entries to 147 /// cases where the difference between the table value and the measurement 148 /// taken from the original outline is sufficiently small. 149 /// 150 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#control_value_cut-in> 151 pub control_value_cutin: i32, 152 /// Establishes the base value used to calculate the range of point sizes 153 /// to which a given DELTAC[] or DELTAP[] instruction will apply. 154 /// 155 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#delta%20base> 156 pub delta_base: u16, 157 /// Determines the range of movement and smallest magnitude of movement 158 /// (the step) in a DELTAC[] or DELTAP[] instruction. 159 /// 160 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#delta%20shift> 161 pub delta_shift: u16, 162 /// Makes it possible to turn off instructions under some circumstances. 163 /// When set to TRUE, no instructions will be executed 164 /// 165 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#instruct%20control> 166 pub instruct_control: u8, 167 /// Establishes the smallest possible value to which a distance will be 168 /// rounded. 169 /// 170 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#minimum%20distance> 171 pub min_distance: i32, 172 /// Determines whether the interpreter will activate dropout control for 173 /// the current glyph. 174 /// 175 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#scan%20control> 176 pub scan_control: bool, 177 /// Type associated with `scan_control`. 178 pub scan_type: i32, 179 /// The distance difference below which the interpreter will replace a 180 /// CVT distance or an actual distance in favor of the single width value. 181 /// 182 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#single_width_cut_in> 183 pub single_width_cutin: i32, 184 /// The value used in place of the control value table distance or the 185 /// actual distance value when the difference between that distance and 186 /// the single width value is less than the single width cut-in. 187 /// 188 /// See <https://developer.apple.com/fonts/TrueType-Reference-Manual/RM04/Chap4.html#single_width_value> 189 pub single_width: i32, 190 /// The scale factor for the current instance. Conversion from font units 191 /// to 26.6 for current ppem. 192 pub scale: i32, 193 /// The nominal pixels per em value for the current instance. 194 pub ppem: i32, 195 /// True if a rotation is being applied. 196 pub is_rotated: bool, 197 /// True if a non-uniform scale is being applied. 198 pub is_stretched: bool, 199 } 200 201 impl Default for RetainedGraphicsState { default() -> Self202 fn default() -> Self { 203 // For table of default values, see <https://learn.microsoft.com/en-us/typography/opentype/spec/tt_graphics_state> 204 Self { 205 auto_flip: true, 206 // 17/16 pixels in 26.6 207 // (17 * 64 / 16) = 68 208 control_value_cutin: 68, 209 delta_base: 9, 210 delta_shift: 3, 211 instruct_control: 0, 212 // 1 pixel in 26.6 213 min_distance: 64, 214 scan_control: false, 215 scan_type: 0, 216 single_width_cutin: 0, 217 single_width: 0, 218 scale: 0, 219 ppem: 0, 220 is_rotated: false, 221 is_stretched: false, 222 } 223 } 224 } 225 226 impl Deref for GraphicsState<'_> { 227 type Target = RetainedGraphicsState; 228 deref(&self) -> &Self::Target229 fn deref(&self) -> &Self::Target { 230 &self.retained 231 } 232 } 233 234 impl DerefMut for GraphicsState<'_> { deref_mut(&mut self) -> &mut Self::Target235 fn deref_mut(&mut self) -> &mut Self::Target { 236 &mut self.retained 237 } 238 } 239