ttf_parser/tables/
cbdt.rs

1// https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt
2
3use crate::{RasterGlyphImage, RasterImageFormat};
4use crate::parser::{Stream, NumFrom};
5use super::cblc::{BitmapFormat, Location};
6
7pub fn parse(
8    data: &[u8],
9    location: Location,
10) -> Option<RasterGlyphImage> {
11    let mut s = Stream::new_at(data, location.offset)?;
12    match location.format {
13        BitmapFormat::Format17 => {
14            let height: u8 = s.read()?;
15            let width: u8 = s.read()?;
16            let bearing_x: i8 = s.read()?;
17            let bearing_y: i8 = s.read()?;
18            s.skip::<u8>(); // advance
19            let data_len: u32 = s.read()?;
20            let data = s.read_bytes(usize::num_from(data_len))?;
21            Some(RasterGlyphImage {
22                x: i16::from(bearing_x),
23                // `y` in CBDT is a bottom bound, not top one.
24                y: i16::from(bearing_y) - i16::from(height),
25                width: u16::from(width),
26                height: u16::from(height),
27                pixels_per_em: location.ppem,
28                format: RasterImageFormat::PNG,
29                data,
30            })
31        }
32        BitmapFormat::Format18 => {
33            let height: u8 = s.read()?;
34            let width: u8 = s.read()?;
35            let hor_bearing_x: i8 = s.read()?;
36            let hor_bearing_y: i8 = s.read()?;
37            s.skip::<u8>(); // hor_advance
38            s.skip::<i8>(); // ver_bearing_x
39            s.skip::<i8>(); // ver_bearing_y
40            s.skip::<u8>(); // ver_advance
41            let data_len: u32 = s.read()?;
42            let data = s.read_bytes(usize::num_from(data_len))?;
43            Some(RasterGlyphImage {
44                x: i16::from(hor_bearing_x),
45                // `y` in CBDT is a bottom bound, not top one.
46                y: i16::from(hor_bearing_y) - i16::from(height),
47                width: u16::from(width),
48                height: u16::from(height),
49                pixels_per_em: location.ppem,
50                format: RasterImageFormat::PNG,
51                data,
52            })
53        }
54        BitmapFormat::Format19 => {
55            let data_len: u32 = s.read()?;
56            let data = s.read_bytes(usize::num_from(data_len))?;
57            Some(RasterGlyphImage {
58                x: i16::from(location.metrics.x),
59                // `y` in CBDT is a bottom bound, not top one.
60                y: i16::from(location.metrics.y) - i16::from(location.metrics.height),
61                width: u16::from(location.metrics.width),
62                height: u16::from(location.metrics.height),
63                pixels_per_em: location.ppem,
64                format: RasterImageFormat::PNG,
65                data,
66            })
67        }
68    }
69}