1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use crate::{GlyphId, RasterGlyphImage, RasterImageFormat};
use crate::parser::{Stream, NumFrom};
use super::cblc::{self, BitmapFormat};
#[derive(Clone, Copy)]
pub struct Table<'a> {
locations: cblc::Table<'a>,
data: &'a [u8],
}
impl<'a> Table<'a> {
pub fn parse(locations: cblc::Table<'a>, data: &'a [u8]) -> Option<Self> {
Some(Self { locations, data })
}
pub fn get(&self, glyph_id: GlyphId, pixels_per_em: u16) -> Option<RasterGlyphImage<'a>> {
let location = self.locations.get(glyph_id, pixels_per_em)?;
let mut s = Stream::new_at(self.data, location.offset)?;
match location.format {
BitmapFormat::Format17 => {
let height = s.read::<u8>()?;
let width = s.read::<u8>()?;
let bearing_x = s.read::<i8>()?;
let bearing_y = s.read::<i8>()?;
s.skip::<u8>();
let data_len = s.read::<u32>()?;
let data = s.read_bytes(usize::num_from(data_len))?;
Some(RasterGlyphImage {
x: i16::from(bearing_x),
y: i16::from(bearing_y) - i16::from(height),
width: u16::from(width),
height: u16::from(height),
pixels_per_em: location.ppem,
format: RasterImageFormat::PNG,
data,
})
}
BitmapFormat::Format18 => {
let height = s.read::<u8>()?;
let width = s.read::<u8>()?;
let hor_bearing_x = s.read::<i8>()?;
let hor_bearing_y = s.read::<i8>()?;
s.skip::<u8>();
s.skip::<i8>();
s.skip::<i8>();
s.skip::<u8>();
let data_len = s.read::<u32>()?;
let data = s.read_bytes(usize::num_from(data_len))?;
Some(RasterGlyphImage {
x: i16::from(hor_bearing_x),
y: i16::from(hor_bearing_y) - i16::from(height),
width: u16::from(width),
height: u16::from(height),
pixels_per_em: location.ppem,
format: RasterImageFormat::PNG,
data,
})
}
BitmapFormat::Format19 => {
let data_len = s.read::<u32>()?;
let data = s.read_bytes(usize::num_from(data_len))?;
Some(RasterGlyphImage {
x: i16::from(location.metrics.x),
y: i16::from(location.metrics.y) - i16::from(location.metrics.height),
width: u16::from(location.metrics.width),
height: u16::from(location.metrics.height),
pixels_per_em: location.ppem,
format: RasterImageFormat::PNG,
data,
})
}
}
}
}
impl core::fmt::Debug for Table<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "Table {{ ... }}")
}
}