font_map_core/raw/ttf/glyf/
simple.rs1#![allow(clippy::cast_possible_truncation)]
2use crate::error::ParseResult;
3use crate::reader::{BinaryReader, Parse};
4
5#[derive(Debug, Clone)]
7pub struct SimpleGlyf {
8 pub contours: Vec<Contour>,
10
11 pub num_contours: i16,
14
15 pub x: (i16, i16),
17
18 pub y: (i16, i16),
20}
21
22impl Parse for SimpleGlyf {
23 fn parse(_: &mut BinaryReader) -> ParseResult<Self> {
24 unimplemented!("Use parse_with instead")
25 }
26
27 fn parse_with(&mut self, reader: &mut BinaryReader) -> ParseResult<()> {
28 let mut end_pts_of_contours = Vec::with_capacity(self.num_contours as usize);
30 let mut last_pt = 0;
31
32 for _ in 0..self.num_contours {
33 last_pt = reader.read_u16()?;
34 end_pts_of_contours.push(last_pt);
35 }
36
37 let instruction_length = reader.read_u16()?;
38 let _instructions = reader.read(instruction_length as usize)?;
39
40 let num_points = last_pt + 1;
41
42 let mut flags = Vec::with_capacity(num_points as usize);
45 let mut remaining_pts = num_points;
46 while remaining_pts > 0 {
47 let flag = reader.read_u8()?;
48 let mut flag = Flag::from_byte(flag);
49 remaining_pts -= 1;
50
51 if flag.repeats != 0 {
53 let n_times = reader.read_u8()?;
54 flag.repeats = n_times;
55 remaining_pts -= u16::from(n_times);
56 }
57
58 flags.push(flag);
59 flags.reserve(usize::from(flag.repeats));
60 for _ in 0..flag.repeats {
61 flags.push(flag);
62 }
63 }
64
65 let mut x_coordinates = Vec::with_capacity(flags.len());
68 let mut last_x = 0;
69 for flag in &flags {
70 let delta = match flag.x_kind {
71 FlagCoordKind::NegShort => -i16::from(reader.read_u8()?),
72 FlagCoordKind::PosShort => i16::from(reader.read_u8()?),
73 FlagCoordKind::Long => reader.read_i16()?,
74 FlagCoordKind::Same => 0,
75 };
76
77 last_x += delta;
78 x_coordinates.push(last_x);
79 }
80
81 let mut y_coordinates = Vec::with_capacity(flags.len());
84 let mut last_y = 0;
85 for flag in &flags {
86 let delta = match flag.y_kind {
87 FlagCoordKind::NegShort => -i16::from(reader.read_u8()?),
88 FlagCoordKind::PosShort => i16::from(reader.read_u8()?),
89 FlagCoordKind::Long => reader.read_i16()?,
90 FlagCoordKind::Same => 0,
91 };
92
93 last_y += delta;
94 y_coordinates.push(last_y);
95 }
96
97 let mut points = Vec::with_capacity(flags.len());
100 for i in 0..flags.len() {
101 let x = x_coordinates[i];
102 let y = y_coordinates[i];
103 let on_curve = flags[i].on_curve;
104 points.push(Point { x, y, on_curve });
105 }
106
107 let mut start = 0;
110 for end in &end_pts_of_contours {
111 let contour_points = points[start..=*end as usize].to_vec();
112 start = *end as usize + 1;
113 self.contours.push(Contour {
114 points: contour_points,
115 });
116 }
117
118 Ok(())
119 }
120}
121
122#[derive(Debug, Default, Clone, Copy)]
123pub enum FlagCoordKind {
124 NegShort,
125 PosShort,
126 Long,
127
128 #[default]
129 Same,
130}
131
132#[derive(Debug, Default, Clone, Copy)]
134pub struct Flag {
135 pub repeats: u8,
136 pub on_curve: bool,
137 pub x_kind: FlagCoordKind,
138 pub y_kind: FlagCoordKind,
139}
140impl Flag {
141 pub fn from_byte(flag: u8) -> Self {
142 let on_curve = (flag & 0x01) != 0;
145 let x_short_vec = (flag & 0x02) != 0;
146 let y_short_vec = (flag & 0x04) != 0;
147 let repeats = flag & 0x08;
148 let x_same_or_pos = (flag & 0x10) != 0;
149 let y_same_or_pos = (flag & 0x20) != 0;
150
151 let x_kind = match (x_short_vec, x_same_or_pos) {
154 (true, false) => FlagCoordKind::NegShort, (true, true) => FlagCoordKind::PosShort, (false, false) => FlagCoordKind::Long, _ => FlagCoordKind::Same, };
159 let y_kind = match (y_short_vec, y_same_or_pos) {
160 (true, false) => FlagCoordKind::NegShort, (true, true) => FlagCoordKind::PosShort, (false, false) => FlagCoordKind::Long, _ => FlagCoordKind::Same, };
165
166 Self {
167 repeats,
168 on_curve,
169 x_kind,
170 y_kind,
171 }
172 }
173}
174
175#[derive(Debug, Default, Clone, Copy)]
177pub struct Point {
178 pub x: i16,
179 pub y: i16,
180 pub on_curve: bool,
181}
182
183#[derive(Debug, Clone)]
185pub struct Contour {
186 pub points: Vec<Point>,
187}