agg_rust/
glyph_raster_bin.rs1use crate::basics::CoverType;
7
8#[derive(Debug, Clone, Copy, Default)]
14pub struct GlyphRect {
15 pub x1: i32,
16 pub y1: i32,
17 pub x2: i32,
18 pub y2: i32,
19 pub dx: f64,
20 pub dy: f64,
21}
22
23pub struct GlyphRasterBin<'a> {
40 font: &'a [u8],
41 span: Vec<CoverType>,
42 bits: &'a [u8],
43 glyph_width: u32,
44 glyph_byte_width: u32,
45}
46
47impl<'a> GlyphRasterBin<'a> {
48 pub fn new(font: &'a [u8]) -> Self {
49 Self {
50 font,
51 span: vec![0; 32],
52 bits: &[],
53 glyph_width: 0,
54 glyph_byte_width: 0,
55 }
56 }
57
58 pub fn font(&self) -> &'a [u8] {
59 self.font
60 }
61
62 pub fn set_font(&mut self, font: &'a [u8]) {
63 self.font = font;
64 }
65
66 pub fn height(&self) -> f64 {
68 self.font[0] as f64
69 }
70
71 pub fn base_line(&self) -> f64 {
73 self.font[1] as f64
74 }
75
76 pub fn width(&self, s: &str) -> f64 {
78 let start_char = self.font[2] as u32;
79 let num_chars = self.font[3] as u32;
80 let mut w = 0u32;
81 for ch in s.bytes() {
82 let glyph = ch as u32;
83 if glyph >= start_char && glyph < start_char + num_chars {
84 let offset = self.value(4 + (glyph - start_char) as usize * 2);
85 let bits_start = 4 + num_chars as usize * 2 + offset as usize;
86 w += self.font[bits_start] as u32;
87 }
88 }
89 w as f64
90 }
91
92 pub fn prepare(&mut self, r: &mut GlyphRect, x: f64, y: f64, glyph: u32, flip: bool) {
97 let start_char = self.font[2] as u32;
98 let num_chars = self.font[3] as u32;
99
100 if glyph < start_char || glyph >= start_char + num_chars {
102 r.x1 = 1;
103 r.x2 = 0; r.dx = 0.0;
105 r.dy = 0.0;
106 self.glyph_width = 0;
107 self.glyph_byte_width = 0;
108 self.bits = &[];
109 return;
110 }
111
112 let offset = self.value(4 + (glyph - start_char) as usize * 2);
113 let bits_start = 4 + num_chars as usize * 2 + offset as usize;
114
115 self.glyph_width = self.font[bits_start] as u32;
116 self.glyph_byte_width = (self.glyph_width + 7) >> 3;
117 self.bits = &self.font[bits_start + 1..];
118
119 if self.span.len() < self.glyph_width as usize {
121 self.span.resize(self.glyph_width as usize, 0);
122 }
123
124 r.x1 = x as i32;
125 r.x2 = r.x1 + self.glyph_width as i32 - 1;
126 if flip {
127 r.y1 = y as i32 - self.font[0] as i32 + self.font[1] as i32;
128 r.y2 = r.y1 + self.font[0] as i32 - 1;
129 } else {
130 r.y1 = y as i32 - self.font[1] as i32 + 1;
131 r.y2 = r.y1 + self.font[0] as i32 - 1;
132 }
133 r.dx = self.glyph_width as f64;
134 r.dy = 0.0;
135 }
136
137 pub fn span(&mut self, i: u32) -> &[CoverType] {
141 if self.glyph_width == 0 || self.bits.is_empty() {
142 return &self.span[..0];
143 }
144 let row = self.font[0] as u32 - i - 1;
146 let row_start = (row * self.glyph_byte_width) as usize;
147 if row_start >= self.bits.len() {
148 for j in 0..self.glyph_width as usize {
150 self.span[j] = 0;
151 }
152 return &self.span[..self.glyph_width as usize];
153 }
154 let bits = &self.bits[row_start..];
155 let mut val = bits[0];
156 let mut nb = 0u32;
157 let mut bit_idx = 0usize;
158 for j in 0..self.glyph_width as usize {
159 self.span[j] = if (val & 0x80) != 0 { 255 } else { 0 };
160 val <<= 1;
161 nb += 1;
162 if nb >= 8 {
163 bit_idx += 1;
164 if bit_idx < bits.len() {
165 val = bits[bit_idx];
166 }
167 nb = 0;
168 }
169 }
170 &self.span[..self.glyph_width as usize]
171 }
172
173 fn value(&self, offset: usize) -> u16 {
175 u16::from_le_bytes([self.font[offset], self.font[offset + 1]])
176 }
177}
178
179#[cfg(test)]
180mod tests {
181 use super::*;
182
183 fn make_test_font() -> Vec<u8> {
189 let mut font = Vec::new();
190 font.push(2); font.push(0); font.push(65); font.push(1); font.push(0);
198 font.push(0);
199
200 font.push(2); font.push(0b1100_0000); font.push(0b0100_0000); font
206 }
207
208 #[test]
209 fn test_font_properties() {
210 let font = make_test_font();
211 let glyph = GlyphRasterBin::new(&font);
212 assert_eq!(glyph.height(), 2.0);
213 assert_eq!(glyph.base_line(), 0.0);
214 }
215
216 #[test]
217 fn test_prepare_glyph() {
218 let font = make_test_font();
219 let mut glyph = GlyphRasterBin::new(&font);
220 let mut r = GlyphRect::default();
221 glyph.prepare(&mut r, 10.0, 5.0, 65, false);
222 assert_eq!(r.x1, 10);
223 assert_eq!(r.x2, 11); assert_eq!(r.dx, 2.0);
225 }
226
227 #[test]
228 fn test_span() {
229 let font = make_test_font();
230 let mut glyph = GlyphRasterBin::new(&font);
231 let mut r = GlyphRect::default();
232 glyph.prepare(&mut r, 0.0, 0.0, 65, false);
233
234 let s0 = glyph.span(0);
236 assert_eq!(s0.len(), 2);
237 assert_eq!(s0[0], 0); assert_eq!(s0[1], 255); let s1 = glyph.span(1);
242 assert_eq!(s1[0], 255); assert_eq!(s1[1], 255);
244 }
245
246 #[test]
247 fn test_width_calculation() {
248 let font = make_test_font();
249 let glyph = GlyphRasterBin::new(&font);
250 assert_eq!(glyph.width("A"), 2.0);
251 }
252}