makepad_ttf_parser/
lib.rs

1use makepad_font::{Font, Glyph, HorizontalMetrics, Outline, OutlinePoint};
2use makepad_geometry::{
3    AffineTransformation, LinearTransformation, Point, Rectangle, Transform, Vector,
4};
5use makepad_internal_iter::ExtendFromInternalIterator;
6use std::{mem, result};
7
8#[derive(Clone, Debug)]
9pub struct GlyphsParser<'a> {
10    glyphs: Vec<Option<Glyph>>,
11    advance_width_count: usize,
12    hmtx_table_bytes: &'a [u8],
13    index_to_loc_format: IndexToLocFormat,
14    loca_table_bytes: &'a [u8],
15    glyf_table_bytes: &'a [u8],
16}
17
18impl<'a> GlyphsParser<'a> {
19    fn new(
20        glyphs_count: usize,
21        advance_width_count: usize,
22        hmtx_table_bytes: &'a [u8],
23        index_to_loc_format: IndexToLocFormat,
24        loca_table_bytes: &'a [u8],
25        glyf_table_bytes: &'a [u8],
26    ) -> GlyphsParser<'a> {
27        GlyphsParser {
28            glyphs: vec![None; glyphs_count],
29            advance_width_count,
30            hmtx_table_bytes,
31            index_to_loc_format,
32            loca_table_bytes,
33            glyf_table_bytes,
34        }
35    }
36
37    fn parse_glyphs(mut self) -> Result<Vec<Glyph>> {
38        for index in 0..self.glyphs.len() {
39            self.get_or_parse_glyph(index)?;
40        }
41        Ok(self
42            .glyphs
43            .into_iter()
44            .map(|glyph| glyph.unwrap())
45            .collect())
46    }
47
48    fn get_or_parse_glyph(&mut self, index: usize) -> Result<&Glyph> {
49        if !self
50            .glyphs
51            .get(index)
52            .map_or(false, |glyphs| glyphs.is_some())
53        {
54            self.glyphs.resize(index + 1, None);
55            self.glyphs[index] = Some(self.parse_glyph(index)?);
56        }
57        Ok(self.glyphs[index].as_ref().unwrap())
58    }
59
60    fn parse_glyph(&mut self, index: usize) -> Result<Glyph> {
61        let start = self.parse_offset(index)?;
62        let end = self.parse_offset(index + 1)?;
63        let bytes = &self.glyf_table_bytes[start..end];
64        let horizontal_metrics = self.parse_horizontal_metrics(index)?;
65        Ok(if bytes.is_empty() {
66            Glyph {
67                horizontal_metrics,
68                bounds: Rectangle::default(),
69                outline: Outline::new(),
70            }
71        } else {
72            let mut reader = Reader::new(&bytes);
73            let contour_count = reader.read_i16()?;
74            let bounds = Rectangle::new(
75                Point::new(reader.read_i16()? as f32, reader.read_i16()? as f32),
76                Point::new(reader.read_i16()? as f32, reader.read_i16()? as f32),
77            );
78            let bytes = &bytes[10..];
79            if contour_count >= 0 {
80                Self::parse_simple_glyph(bytes, horizontal_metrics, bounds, contour_count as usize)?
81            } else {
82                self.parse_composite_glyph(bytes, horizontal_metrics, bounds)?
83            }
84        })
85    }
86
87    fn parse_offset(&self, index: usize) -> Result<usize> {
88        let mut reader = Reader::new(&self.loca_table_bytes);
89        Ok(match self.index_to_loc_format {
90            IndexToLocFormat::Short => {
91                reader.skip(index * 2)?;
92                reader.read_u16()? as usize * 2
93            }
94            IndexToLocFormat::Long => {
95                reader.skip(index * 4)?;
96                reader.read_u32()? as usize
97            }
98        })
99    }
100
101    fn parse_horizontal_metrics(&self, index: usize) -> Result<HorizontalMetrics> {
102        let mut reader = Reader::new(self.hmtx_table_bytes);
103        if index < self.advance_width_count {
104            reader.skip(index * 4)?;
105            Ok(HorizontalMetrics {
106                advance_width: reader.read_u16()? as f32,
107                left_side_bearing: reader.read_i16()? as f32,
108            })
109        } else {
110            reader.skip((self.advance_width_count - 1) * 4)?;
111            let advance_width = reader.read_u16()? as f32;
112            reader.skip(2)?;
113            reader.skip((index - self.advance_width_count) * 2)?;
114            Ok(HorizontalMetrics {
115                advance_width,
116                left_side_bearing: reader.read_i16()? as f32,
117            })
118        }
119    }
120
121    fn parse_simple_glyph(
122        bytes: &'a [u8],
123        horizontal_metrics: HorizontalMetrics,
124        bounds: Rectangle,
125        contour_count: usize,
126    ) -> Result<Glyph> {
127        let mut reader = Reader::new(bytes);
128        reader.skip((contour_count - 1) * mem::size_of::<u16>())?;
129        let point_count = reader.read_u16()? as usize + 1;
130        let instruction_count = reader.read_u16()? as usize;
131        reader.skip(instruction_count)?;
132        let mut flags_bytes_count = 0;
133        let mut x_coordinates_bytes_count = 0;
134        let mut y_coordinates_bytes_count = 0;
135        let mut flags_count = point_count;
136        while flags_count > 0 {
137            let flags = SimpleGlyphFlags(reader.read_u8()?);
138            let repeat_count = if flags.repeat_flag() {
139                flags_bytes_count += 2;
140                1 + reader.read_u8()? as usize
141            } else {
142                flags_bytes_count += 1;
143                1
144            };
145            if repeat_count > flags_count {
146                return Err(Error);
147            }
148            if flags.x_short_vector() {
149                x_coordinates_bytes_count += repeat_count;
150            } else if !flags.x_is_same_or_positive_x_short_vector() {
151                x_coordinates_bytes_count += repeat_count * mem::size_of::<i16>();
152            }
153            if flags.y_short_vector() {
154                y_coordinates_bytes_count += repeat_count;
155            } else if !flags.y_is_same_or_positive_y_short_vector() {
156                y_coordinates_bytes_count += repeat_count * mem::size_of::<i16>();
157            }
158            flags_count -= repeat_count;
159        }
160        let instructions_bytes_start = (contour_count + 1) * mem::size_of::<u16>();
161        let flags_bytes_start = instructions_bytes_start + instruction_count;
162        let x_coordinates_bytes_start = flags_bytes_start + flags_bytes_count;
163        let y_coordinates_bytes_start = x_coordinates_bytes_start + x_coordinates_bytes_count;
164        if y_coordinates_bytes_count > bytes.len() - y_coordinates_bytes_start {
165            return Err(Error);
166        }
167        let mut end_pts_for_contours_reader = Reader::new(&bytes[..instructions_bytes_start]);
168        let mut point_reader = OutlinePointReader::new(
169            &bytes[flags_bytes_start..x_coordinates_bytes_start],
170            &bytes[x_coordinates_bytes_start..y_coordinates_bytes_start],
171            &bytes[y_coordinates_bytes_start..],
172        );
173        let mut outline = Outline::new();
174        let mut start = 0;
175        for _ in 0..contour_count {
176            let end = end_pts_for_contours_reader.read_u16()? as usize + 1;
177            let mut contour = outline.begin_contour();
178            for _ in 0..(end - start) {
179                contour.push(point_reader.read_outline_point()?);
180            }
181            contour.end();
182            start = end;
183        }
184        Ok(Glyph {
185            horizontal_metrics,
186            bounds,
187            outline,
188        })
189    }
190
191    fn parse_composite_glyph(
192        &mut self,
193        bytes: &'a [u8],
194        mut horizontal_metrics: HorizontalMetrics,
195        bounds: Rectangle,
196    ) -> Result<Glyph> {
197        let mut outline = Outline::new();
198        let mut reader = Reader::new(bytes);
199        let mut flags = CompositeGlyphFlags(reader.read_u16()?);
200        loop {
201            let component_glyph = self.parse_glyph(reader.read_u16()? as usize)?;
202            if flags.use_my_metrics() {
203                horizontal_metrics = component_glyph.horizontal_metrics;
204            }
205            let (argument_1, argument_2) = if flags.arg_1_and_arg_2_are_words() {
206                (reader.read_i16()?, reader.read_i16()?)
207            } else {
208                (reader.read_i8()? as i16, reader.read_i8()? as i16)
209            };
210            let xy = if flags.we_have_a_scale() {
211                LinearTransformation::uniform_scaling(reader.read_f2dot14()?)
212            } else if flags.we_have_an_x_and_y_scale() {
213                LinearTransformation::scaling(Vector::new(
214                    reader.read_f2dot14()?,
215                    reader.read_f2dot14()?,
216                ))
217            } else if flags.we_have_a_two_by_two() {
218                LinearTransformation::new(
219                    Vector::new(reader.read_f2dot14()?, reader.read_f2dot14()?),
220                    Vector::new(reader.read_f2dot14()?, reader.read_f2dot14()?),
221                )
222            } else {
223                LinearTransformation::identity()
224            };
225            let z = if flags.args_are_xy_values() {
226                Vector::new(
227                    xy.x.x.hypot(xy.y.x) * argument_1 as f32,
228                    xy.x.y.hypot(xy.y.y) * argument_2 as f32,
229                )
230            } else {
231                component_glyph
232                    .outline
233                    .points()
234                    .get(argument_2 as usize)
235                    .ok_or(Error)?
236                    .point
237                    .transform(&xy)
238                    - outline
239                        .points()
240                        .get(argument_1 as usize)
241                        .ok_or(Error)?
242                        .point
243            };
244            for component_contour in component_glyph.outline.contours() {
245                let mut contour = outline.begin_contour();
246                contour.extend_from_internal_iter(
247                    component_contour
248                        .points()
249                        .iter()
250                        .cloned()
251                        .map(|point| point.transform(&AffineTransformation::new(xy, z))),
252                );
253                contour.end();
254            }
255            if !flags.more_components() {
256                break;
257            }
258            flags = CompositeGlyphFlags(reader.read_u16()?);
259        }
260        if flags.we_have_instructions() {
261            let instruction_length = reader.read_u16()? as usize;
262            reader.skip(instruction_length)?;
263        }
264        Ok(Glyph {
265            horizontal_metrics,
266            bounds,
267            outline,
268        })
269    }
270}
271
272#[derive(Clone, Copy, Debug, Hash, PartialEq)]
273enum IndexToLocFormat {
274    Short,
275    Long,
276}
277
278impl IndexToLocFormat {
279    fn from_i16(value: i16) -> Option<IndexToLocFormat> {
280        match value {
281            0 => Some(IndexToLocFormat::Short),
282            1 => Some(IndexToLocFormat::Long),
283            _ => None,
284        }
285    }
286}
287
288#[derive(Clone, Debug)]
289struct OutlinePointReader<'a> {
290    flags_reader: SimpleGlyphFlagsReader<'a>,
291    x_coordinates_reader: Reader<'a>,
292    y_coordinates_reader: Reader<'a>,
293    current_point: Point,
294}
295
296impl<'a> OutlinePointReader<'a> {
297    fn new(
298        flags_bytes: &'a [u8],
299        x_coordinates_bytes: &'a [u8],
300        y_coordinates_bytes: &'a [u8],
301    ) -> OutlinePointReader<'a> {
302        OutlinePointReader {
303            flags_reader: SimpleGlyphFlagsReader::new(flags_bytes),
304            x_coordinates_reader: Reader::new(x_coordinates_bytes),
305            y_coordinates_reader: Reader::new(y_coordinates_bytes),
306            current_point: Point::origin(),
307        }
308    }
309
310    fn read_outline_point(&mut self) -> Result<OutlinePoint> {
311        let flags = self.flags_reader.read()?;
312        self.current_point += Vector::new(
313            if flags.x_short_vector() {
314                let x = self.x_coordinates_reader.read_u8()? as f32;
315                if flags.x_is_same_or_positive_x_short_vector() {
316                    x
317                } else {
318                    -x
319                }
320            } else {
321                if flags.x_is_same_or_positive_x_short_vector() {
322                    0.0
323                } else {
324                    self.x_coordinates_reader.read_i16()? as f32
325                }
326            },
327            if flags.y_short_vector() {
328                let y = self.y_coordinates_reader.read_u8()? as f32;
329                if flags.y_is_same_or_positive_y_short_vector() {
330                    y
331                } else {
332                    -y
333                }
334            } else {
335                if flags.y_is_same_or_positive_y_short_vector() {
336                    0.0
337                } else {
338                    self.y_coordinates_reader.read_i16()? as f32
339                }
340            },
341        );
342        Ok(OutlinePoint {
343            is_on_curve: flags.on_curve_point(),
344            point: self.current_point,
345        })
346    }
347}
348
349#[derive(Clone, Debug)]
350struct SimpleGlyphFlagsReader<'a> {
351    reader: Reader<'a>,
352    flags: SimpleGlyphFlags,
353    repeat_count: usize,
354}
355
356impl<'a> SimpleGlyphFlagsReader<'a> {
357    fn new(bytes: &'a [u8]) -> SimpleGlyphFlagsReader<'a> {
358        SimpleGlyphFlagsReader {
359            reader: Reader::new(bytes),
360            flags: SimpleGlyphFlags(0),
361            repeat_count: 0,
362        }
363    }
364
365    fn read(&mut self) -> Result<SimpleGlyphFlags> {
366        if self.repeat_count == 0 {
367            self.flags = SimpleGlyphFlags(self.reader.read_u8()?);
368            self.repeat_count = if self.flags.repeat_flag() {
369                self.reader.read_u8()? as usize
370            } else {
371                0
372            };
373        } else {
374            self.repeat_count -= 1;
375        }
376        Ok(self.flags)
377    }
378}
379
380#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
381struct SimpleGlyphFlags(u8);
382
383impl SimpleGlyphFlags {
384    fn on_curve_point(self) -> bool {
385        self.0 & (1 << 0) != 0
386    }
387
388    fn x_short_vector(self) -> bool {
389        self.0 & (1 << 1) != 0
390    }
391
392    fn y_short_vector(self) -> bool {
393        self.0 & (1 << 2) != 0
394    }
395
396    fn repeat_flag(self) -> bool {
397        self.0 & (1 << 3) != 0
398    }
399
400    fn x_is_same_or_positive_x_short_vector(self) -> bool {
401        self.0 & (1 << 4) != 0
402    }
403
404    fn y_is_same_or_positive_y_short_vector(self) -> bool {
405        self.0 & (1 << 5) != 0
406    }
407}
408
409#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
410struct CompositeGlyphFlags(u16);
411
412impl CompositeGlyphFlags {
413    fn arg_1_and_arg_2_are_words(self) -> bool {
414        self.0 & (1 << 0) != 0
415    }
416
417    fn args_are_xy_values(self) -> bool {
418        self.0 & (1 << 1) != 0
419    }
420
421    fn we_have_a_scale(self) -> bool {
422        self.0 & (1 << 3) != 0
423    }
424
425    fn more_components(self) -> bool {
426        self.0 & (1 << 5) != 0
427    }
428
429    fn we_have_an_x_and_y_scale(self) -> bool {
430        self.0 & (1 << 6) != 0
431    }
432
433    fn we_have_a_two_by_two(self) -> bool {
434        self.0 & (1 << 7) != 0
435    }
436
437    fn we_have_instructions(self) -> bool {
438        self.0 & (1 << 8) != 0
439    }
440
441    fn use_my_metrics(self) -> bool {
442        self.0 & (1 << 9) != 0
443    }
444}
445
446#[derive(Clone, Debug)]
447struct Reader<'a> {
448    bytes: &'a [u8],
449}
450
451impl<'a> Reader<'a> {
452    fn new(bytes: &'a [u8]) -> Reader<'a> {
453        Reader { bytes }
454    }
455
456    fn skip(&mut self, count: usize) -> Result<()> {
457        if count > self.bytes.len() {
458            return Err(Error);
459        }
460        self.bytes = &self.bytes[count..];
461        Ok(())
462    }
463
464    fn read(&mut self, bytes: &mut [u8]) -> Result<()> {
465        if bytes.len() > self.bytes.len() {
466            return Err(Error);
467        }
468        bytes.copy_from_slice(&self.bytes[..bytes.len()]);
469        self.bytes = &self.bytes[bytes.len()..];
470        Ok(())
471    }
472
473    fn read_i8(&mut self) -> Result<i8> {
474        let mut bytes = [0; mem::size_of::<i8>()];
475        self.read(&mut bytes)?;
476        Ok(i8::from_be_bytes(bytes))
477    }
478
479    fn read_i16(&mut self) -> Result<i16> {
480        let mut bytes = [0; mem::size_of::<i16>()];
481        self.read(&mut bytes)?;
482        Ok(i16::from_be_bytes(bytes))
483    }
484
485    fn read_u8(&mut self) -> Result<u8> {
486        let mut bytes = [0; mem::size_of::<u8>()];
487        self.read(&mut bytes)?;
488        Ok(u8::from_be_bytes(bytes))
489    }
490
491    fn read_u16(&mut self) -> Result<u16> {
492        let mut bytes = [0; mem::size_of::<u16>()];
493        self.read(&mut bytes)?;
494        Ok(u16::from_be_bytes(bytes))
495    }
496
497    fn read_u32(&mut self) -> Result<u32> {
498        let mut bytes = [0; mem::size_of::<u32>()];
499        self.read(&mut bytes)?;
500        Ok(u32::from_be_bytes(bytes))
501    }
502
503    fn read_f2dot14(&mut self) -> Result<f32> {
504        Ok(self.read_i16()? as f32 / (1 << 14) as f32)
505    }
506}
507
508pub type Result<T> = result::Result<T, Error>;
509
510#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
511pub struct Error;
512
513pub fn parse_ttf(bytes: &[u8]) -> Result<Font> {
514    let mut reader = Reader::new(&bytes[0..12]);
515    let sfnt_version = reader.read_u32()?;
516    if ![0x00010000, u32::from_be_bytes(*b"true")].contains(&sfnt_version) {
517        return Err(Error);
518    }
519    let table_count = reader.read_u16()? as usize;
520    reader.skip(6)?;
521    let mut cmap_table_bytes = None;
522    let mut glyf_table_bytes = None;
523    let mut head_table_bytes = None;
524    let mut hhea_table_bytes = None;
525    let mut hmtx_table_bytes = None;
526    let mut loca_table_bytes = None;
527    let mut maxp_table_bytes = None;
528    for index in 0..table_count {
529        let mut reader = Reader::new(&bytes[(12 + index * 16)..][..16]);
530        let table_tag = reader.read_u32()?;
531        reader.skip(4)?;
532        let offset = reader.read_u32()? as usize;
533        let length = reader.read_u32()? as usize;
534        let table_bytes = &bytes[offset..][..length];
535        match &table_tag.to_be_bytes() {
536            b"cmap" => cmap_table_bytes = Some(table_bytes),
537            b"glyf" => glyf_table_bytes = Some(table_bytes),
538            b"head" => head_table_bytes = Some(table_bytes),
539            b"hhea" => hhea_table_bytes = Some(table_bytes),
540            b"hmtx" => hmtx_table_bytes = Some(table_bytes),
541            b"loca" => loca_table_bytes = Some(table_bytes),
542            b"maxp" => maxp_table_bytes = Some(table_bytes),
543            _ => {}
544        }
545    }
546    let cmap_table_bytes = cmap_table_bytes.ok_or(Error)?;
547    let glyf_table_bytes = glyf_table_bytes.ok_or(Error)?;
548    let head_table_bytes = head_table_bytes.ok_or(Error)?;
549    let hhea_table_bytes = hhea_table_bytes.ok_or(Error)?;
550    let hmtx_table_bytes = hmtx_table_bytes.ok_or(Error)?;
551    let loca_table_bytes = loca_table_bytes.ok_or(Error)?;
552    let maxp_table_bytes = maxp_table_bytes.ok_or(Error)?;
553    let mut reader = Reader::new(hhea_table_bytes);
554    reader.skip(4)?;
555    let ascender = reader.read_i16()? as f32;
556    let descender = reader.read_i16()? as f32;
557    let line_gap = reader.read_i16()? as f32;
558    reader.skip(24)?;
559    let advance_width_count = reader.read_u16()? as usize;
560    let mut reader = Reader::new(maxp_table_bytes);
561    reader.skip(4)?;
562    let glyph_count = reader.read_u16()? as usize;
563    reader.skip(26)?;
564    let mut reader = Reader::new(head_table_bytes);
565    reader.skip(18)?;
566    let units_per_em = reader.read_u16()? as f32;
567    reader.skip(16)?;
568    let bounds = Rectangle::new(
569        Point::new(reader.read_i16()? as f32, reader.read_i16()? as f32),
570        Point::new(reader.read_i16()? as f32, reader.read_i16()? as f32),
571    );
572    reader.skip(6)?;
573    let index_to_loc_format = IndexToLocFormat::from_i16(reader.read_i16()?).ok_or(Error)?;
574    reader.skip(2)?;
575    Ok(Font {
576        units_per_em,
577        ascender,
578        descender,
579        line_gap,
580        bounds,
581        char_code_to_glyph_index_map: parse_char_code_to_glyph_index_map(cmap_table_bytes)?,
582        glyphs: GlyphsParser::new(
583            glyph_count,
584            advance_width_count,
585            hmtx_table_bytes,
586            index_to_loc_format,
587            loca_table_bytes,
588            glyf_table_bytes,
589        )
590        .parse_glyphs()?,
591    })
592}
593
594fn parse_char_code_to_glyph_index_map(bytes: &[u8]) -> Result<Vec<usize>> {
595    let mut reader = Reader::new(bytes);
596    reader.skip(2)?;
597    let mut subtable_bytes = None;
598    let subtable_count = reader.read_u16()? as usize;
599    for _ in 0..subtable_count {
600        let platform_id = reader.read_u16()?;
601        let encoding_id = reader.read_u16()?;
602        let offset = reader.read_u32()? as usize;
603        if let (0, _) | (3, 1) | (3, 10) = (platform_id, encoding_id) {
604            subtable_bytes = Some(&bytes[offset..]);
605            break;
606        }
607    }
608    let subtable_bytes = subtable_bytes.ok_or(Error)?;
609    let mut reader = Reader::new(subtable_bytes);
610    let format = reader.read_u16()?;
611    let bytes = &subtable_bytes[2..];
612    match format {
613        4 => parse_char_code_to_glyph_index_map_format_4(bytes),
614        _ => Err(Error),
615    }
616}
617
618fn parse_char_code_to_glyph_index_map_format_4(bytes: &[u8]) -> Result<Vec<usize>> {
619    let mut reader = Reader::new(bytes);
620    reader.skip(4)?;
621    let seg_count = reader.read_u16()? as usize / 2;
622    let end_code_bytes_start = 12;
623    let end_code_bytes_end = end_code_bytes_start + seg_count * 2;
624    let start_code_bytes_start = end_code_bytes_end + 2;
625    let id_delta_bytes_start = start_code_bytes_start + seg_count * 2;
626    let id_range_offset_bytes_start = id_delta_bytes_start + seg_count * 2;
627    let end_code_bytes = &bytes[end_code_bytes_start..end_code_bytes_end];
628    let start_code_bytes = &bytes[start_code_bytes_start..id_delta_bytes_start];
629    let id_delta_bytes = &bytes[id_delta_bytes_start..id_range_offset_bytes_start];
630    let id_range_offset_bytes = &bytes[id_range_offset_bytes_start..];
631    let mut end_code_reader = Reader::new(end_code_bytes);
632    let mut start_code_reader = Reader::new(start_code_bytes);
633    let mut id_delta_reader = Reader::new(id_delta_bytes);
634    let mut id_range_offset_reader = Reader::new(id_range_offset_bytes);
635    let mut char_code_to_glyph_index_map = Vec::new();
636    for seg_index in 0..seg_count {
637        let end_code = end_code_reader.read_u16()?;
638        let start_code = start_code_reader.read_u16()?;
639        let id_delta = id_delta_reader.read_u16()? as usize;
640        let id_range_offset = id_range_offset_reader.read_u16()? as usize;
641        for code in start_code..end_code {
642            let mut id = if id_range_offset == 0 {
643                code
644            } else {
645                let id_range_bytes = &id_range_offset_bytes[(seg_index * 2)..];
646                let mut reader = Reader::new(id_range_bytes);
647                reader.skip(id_range_offset + (code - start_code) as usize * 2)?;
648                let id = reader.read_u16()?;
649                id
650            } as usize;
651            if id != 0 {
652                id = (id + id_delta) % 65536;
653            }
654            char_code_to_glyph_index_map.resize(code as usize + 1, 0);
655            char_code_to_glyph_index_map[code as usize] = id;
656        }
657    }
658    Ok(char_code_to_glyph_index_map)
659}