ttf_parser/tables/
cbdt.rs1use crate::cblc::{self, BitmapDataFormat, Metrics, MetricsFormat};
5use crate::parser::{NumFrom, Stream};
6use crate::{GlyphId, RasterGlyphImage, RasterImageFormat};
7
8#[derive(Clone, Copy)]
13pub struct Table<'a> {
14    locations: cblc::Table<'a>,
15    data: &'a [u8],
16}
17
18impl<'a> Table<'a> {
19    pub fn parse(locations: cblc::Table<'a>, data: &'a [u8]) -> Option<Self> {
21        Some(Self { locations, data })
22    }
23
24    pub fn get(&self, glyph_id: GlyphId, pixels_per_em: u16) -> Option<RasterGlyphImage<'a>> {
26        let location = self.locations.get(glyph_id, pixels_per_em)?;
27        let mut s = Stream::new_at(self.data, location.offset)?;
28        let metrics = match location.format.metrics {
29            MetricsFormat::Small => {
30                let height = s.read::<u8>()?;
31                let width = s.read::<u8>()?;
32                let bearing_x = s.read::<i8>()?;
33                let bearing_y = s.read::<i8>()?;
34                s.skip::<u8>(); Metrics {
36                    x: bearing_x,
37                    y: bearing_y,
38                    width,
39                    height,
40                }
41            }
42            MetricsFormat::Big => {
43                let height = s.read::<u8>()?;
44                let width = s.read::<u8>()?;
45                let hor_bearing_x = s.read::<i8>()?;
46                let hor_bearing_y = s.read::<i8>()?;
47                s.skip::<u8>(); s.skip::<i8>(); s.skip::<i8>(); s.skip::<u8>(); Metrics {
52                    x: hor_bearing_x,
53                    y: hor_bearing_y,
54                    width,
55                    height,
56                }
57            }
58            MetricsFormat::Shared => location.metrics,
59        };
60        match location.format.data {
61            BitmapDataFormat::ByteAligned { bit_depth } => {
62                let row_len = (u32::from(metrics.width) * u32::from(bit_depth) + 7) / 8;
63                let data_len = row_len * u32::from(metrics.height);
64                let data = s.read_bytes(usize::num_from(data_len))?;
65                Some(RasterGlyphImage {
66                    x: i16::from(metrics.x),
67                    y: i16::from(metrics.y) - i16::from(metrics.height),
69                    width: u16::from(metrics.width),
70                    height: u16::from(metrics.height),
71                    pixels_per_em: location.ppem,
72                    format: match bit_depth {
73                        1 => RasterImageFormat::BitmapMono,
74                        2 => RasterImageFormat::BitmapGray2,
75                        4 => RasterImageFormat::BitmapGray4,
76                        8 => RasterImageFormat::BitmapGray8,
77                        32 => RasterImageFormat::BitmapPremulBgra32,
78                        _ => return None,
79                    },
80                    data,
81                })
82            }
83            BitmapDataFormat::BitAligned { bit_depth } => {
84                let data_len = {
85                    let w = u32::from(metrics.width);
86                    let h = u32::from(metrics.height);
87                    let d = u32::from(bit_depth);
88                    (w * h * d + 7) / 8
89                };
90
91                let data = s.read_bytes(usize::num_from(data_len))?;
92                Some(RasterGlyphImage {
93                    x: i16::from(metrics.x),
94                    y: i16::from(metrics.y) - i16::from(metrics.height),
96                    width: u16::from(metrics.width),
97                    height: u16::from(metrics.height),
98                    pixels_per_em: location.ppem,
99                    format: match bit_depth {
100                        1 => RasterImageFormat::BitmapMonoPacked,
101                        2 => RasterImageFormat::BitmapGray2Packed,
102                        4 => RasterImageFormat::BitmapGray4Packed,
103                        8 => RasterImageFormat::BitmapGray8,
104                        32 => RasterImageFormat::BitmapPremulBgra32,
105                        _ => return None,
106                    },
107                    data,
108                })
109            }
110            BitmapDataFormat::PNG => {
111                let data_len = s.read::<u32>()?;
112                let data = s.read_bytes(usize::num_from(data_len))?;
113                Some(RasterGlyphImage {
114                    x: i16::from(metrics.x),
115                    y: i16::from(metrics.y) - i16::from(metrics.height),
117                    width: u16::from(metrics.width),
118                    height: u16::from(metrics.height),
119                    pixels_per_em: location.ppem,
120                    format: RasterImageFormat::PNG,
121                    data,
122                })
123            }
124        }
125    }
126}
127
128impl core::fmt::Debug for Table<'_> {
129    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
130        write!(f, "Table {{ ... }}")
131    }
132}