Coverage Report

Created: 2025-09-27 07:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fontations/klippa/src/hdmx.rs
Line
Count
Source
1
//! impl subset() for hdmx
2
3
use crate::serialize::{SerializeErrorFlags, Serializer};
4
use crate::{Plan, Subset, SubsetError};
5
use write_fonts::{
6
    read::{
7
        tables::hdmx::{DeviceRecord, Hdmx},
8
        FontRef, TopLevelTable,
9
    },
10
    FontBuilder,
11
};
12
13
0
fn ceil_to_4(v: u32) -> u32 {
14
0
    ((v - 1) | 3) + 1
15
0
}
16
17
// reference: subset() for hmtx/hhea in harfbuzz
18
// <https://github.com/harfbuzz/harfbuzz/blob/e451e91ec3608a2ebfec34d0c4f0b3d880e00e33/src/hb-ot-hdmx-table.hh#L116>
19
impl Subset for Hdmx<'_> {
20
0
    fn subset(
21
0
        &self,
22
0
        plan: &Plan,
23
0
        _font: &FontRef,
24
0
        s: &mut Serializer,
25
0
        _builder: &mut FontBuilder,
26
0
    ) -> Result<(), SubsetError> {
27
0
        s.embed(self.version())
28
0
            .map_err(|_| SubsetError::SubsetTableError(Hdmx::TAG))?;
29
0
        s.embed(self.num_records())
30
0
            .map_err(|_| SubsetError::SubsetTableError(Hdmx::TAG))?;
31
32
0
        let size_device_record = ceil_to_4(2 + plan.num_output_glyphs as u32);
33
0
        s.embed(size_device_record)
34
0
            .map_err(|_| SubsetError::SubsetTableError(Hdmx::TAG))?;
35
36
0
        for record in self.records().iter() {
37
0
            let Ok(r) = record else {
38
0
                return Err(SubsetError::SubsetTableError(Hdmx::TAG));
39
            };
40
0
            serialize_device_record(&r, s, plan, size_device_record as usize)
41
0
                .map_err(|_| SubsetError::SubsetTableError(Hdmx::TAG))?;
42
        }
43
0
        Ok(())
44
0
    }
45
}
46
47
0
fn serialize_device_record(
48
0
    record: &DeviceRecord,
49
0
    s: &mut Serializer,
50
0
    plan: &Plan,
51
0
    size_device_record: usize,
52
0
) -> Result<(), SerializeErrorFlags> {
53
0
    s.embed(record.pixel_size())?;
54
0
    let max_width_pos = s.embed(0_u8)?;
55
0
    let widths_array_pos = s.allocate_size(size_device_record - 2, false)?;
56
0
    let mut max_width = 0;
57
0
    for (new_gid, old_gid) in plan.new_to_old_gid_list.iter() {
58
0
        let old_idx = old_gid.to_u32() as usize;
59
0
        let Some(wdth) = record.widths().get(old_idx) else {
60
0
            return Err(SerializeErrorFlags::SERIALIZE_ERROR_OTHER);
61
        };
62
63
0
        let new_idx = new_gid.to_u32() as usize;
64
0
        s.copy_assign(widths_array_pos + new_idx, *wdth);
65
0
        max_width = max_width.max(*wdth);
66
    }
67
68
0
    s.copy_assign(max_width_pos, max_width);
69
0
    Ok(())
70
0
}