Coverage Report

Created: 2025-11-16 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fontations/write-fonts/generated/generated_font.rs
Line
Count
Source
1
// THIS FILE IS AUTOGENERATED.
2
// Any changes to this file will be overwritten.
3
// For more information about how codegen works, see font-codegen/README.md
4
5
#[allow(unused_imports)]
6
use crate::codegen_prelude::*;
7
8
/// The OpenType [Table Directory](https://docs.microsoft.com/en-us/typography/opentype/spec/otff#table-directory)
9
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
10
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11
pub struct TableDirectory {
12
    /// 0x00010000 or 0x4F54544F
13
    pub sfnt_version: u32,
14
    pub search_range: u16,
15
    pub entry_selector: u16,
16
    pub range_shift: u16,
17
    /// Table records array—one for each top-level table in the font
18
    pub table_records: Vec<TableRecord>,
19
}
20
21
impl TableDirectory {
22
    /// Construct a new `TableDirectory`
23
9.74k
    pub fn new(
24
9.74k
        sfnt_version: u32,
25
9.74k
        search_range: u16,
26
9.74k
        entry_selector: u16,
27
9.74k
        range_shift: u16,
28
9.74k
        table_records: Vec<TableRecord>,
29
9.74k
    ) -> Self {
30
9.74k
        Self {
31
9.74k
            sfnt_version,
32
9.74k
            search_range,
33
9.74k
            entry_selector,
34
9.74k
            range_shift,
35
9.74k
            table_records,
36
9.74k
        }
37
9.74k
    }
38
}
39
40
impl FontWrite for TableDirectory {
41
    #[allow(clippy::unnecessary_cast)]
42
9.74k
    fn write_into(&self, writer: &mut TableWriter) {
43
9.74k
        self.sfnt_version.write_into(writer);
44
9.74k
        (u16::try_from(array_len(&self.table_records)).unwrap()).write_into(writer);
45
9.74k
        self.search_range.write_into(writer);
46
9.74k
        self.entry_selector.write_into(writer);
47
9.74k
        self.range_shift.write_into(writer);
48
9.74k
        self.table_records.write_into(writer);
49
9.74k
    }
50
0
    fn table_type(&self) -> TableType {
51
0
        TableType::Named("TableDirectory")
52
0
    }
53
}
54
55
impl Validate for TableDirectory {
56
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
57
0
        ctx.in_table("TableDirectory", |ctx| {
58
0
            ctx.in_field("table_records", |ctx| {
59
0
                if self.table_records.len() > (u16::MAX as usize) {
60
0
                    ctx.report("array exceeds max length");
61
0
                }
62
0
                self.table_records.validate_impl(ctx);
63
0
            });
64
0
        })
65
0
    }
66
}
67
68
/// Record for a table in a font.
69
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
70
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
71
pub struct TableRecord {
72
    /// Table identifier.
73
    pub tag: Tag,
74
    /// Checksum for the table.
75
    pub checksum: u32,
76
    /// Offset from the beginning of the font data.
77
    pub offset: u32,
78
    /// Length of the table.
79
    pub length: u32,
80
}
81
82
impl TableRecord {
83
    /// Construct a new `TableRecord`
84
262k
    pub fn new(tag: Tag, checksum: u32, offset: u32, length: u32) -> Self {
85
262k
        Self {
86
262k
            tag,
87
262k
            checksum,
88
262k
            offset,
89
262k
            length,
90
262k
        }
91
262k
    }
92
}
93
94
impl FontWrite for TableRecord {
95
262k
    fn write_into(&self, writer: &mut TableWriter) {
96
262k
        self.tag.write_into(writer);
97
262k
        self.checksum.write_into(writer);
98
262k
        self.offset.write_into(writer);
99
262k
        self.length.write_into(writer);
100
262k
    }
101
0
    fn table_type(&self) -> TableType {
102
0
        TableType::Named("TableRecord")
103
0
    }
104
}
105
106
impl Validate for TableRecord {
107
0
    fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
108
}
109
110
/// [TTC Header](https://learn.microsoft.com/en-us/typography/opentype/spec/otff#ttc-header)
111
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
112
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
113
pub struct TTCHeader {
114
    /// Font Collection ID string: \"ttcf\"
115
    pub ttc_tag: Tag,
116
    /// Number of fonts in TTC
117
    pub num_fonts: u32,
118
    /// Array of offsets to the TableDirectory for each font from the beginning of the file
119
    pub table_directory_offsets: Vec<u32>,
120
    /// Tag indicating that a DSIG table exists, 0x44534947 ('DSIG') (null if no signature)
121
    pub dsig_tag: Option<u32>,
122
    /// The length (in bytes) of the DSIG table (null if no signature)
123
    pub dsig_length: Option<u32>,
124
    /// The offset (in bytes) of the DSIG table from the beginning of the TTC file (null if no signature)
125
    pub dsig_offset: Option<u32>,
126
}
127
128
impl Validate for TTCHeader {
129
0
    fn validate_impl(&self, ctx: &mut ValidationCtx) {
130
0
        ctx.in_table("TTCHeader", |ctx| {
131
0
            let version: MajorMinor = self.compute_version();
132
0
            ctx.in_field("table_directory_offsets", |ctx| {
133
0
                if self.table_directory_offsets.len() > (u32::MAX as usize) {
134
0
                    ctx.report("array exceeds max length");
135
0
                }
136
0
            });
137
0
            ctx.in_field("dsig_tag", |ctx| {
138
0
                if version.compatible((2u16, 0u16)) && self.dsig_tag.is_none() {
139
0
                    ctx.report(format!("field must be present for version {version}"));
140
0
                }
141
0
            });
142
0
            ctx.in_field("dsig_length", |ctx| {
143
0
                if version.compatible((2u16, 0u16)) && self.dsig_length.is_none() {
144
0
                    ctx.report(format!("field must be present for version {version}"));
145
0
                }
146
0
            });
147
0
            ctx.in_field("dsig_offset", |ctx| {
148
0
                if version.compatible((2u16, 0u16)) && self.dsig_offset.is_none() {
149
0
                    ctx.report(format!("field must be present for version {version}"));
150
0
                }
151
0
            });
152
0
        })
153
0
    }
154
}