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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#![deny(rustdoc::broken_intra_doc_links)]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(any(feature = "std", test))]
#[macro_use]
extern crate std;
#[cfg(all(not(feature = "std"), not(test)))]
#[macro_use]
extern crate core as std;
pub mod array;
mod font_data;
pub mod layout;
mod offset;
mod read;
mod table_provider;
mod table_ref;
pub mod tables;
#[cfg(feature = "traversal")]
pub mod traversal;
#[cfg(any(test, feature = "test_data"))]
pub mod codegen_test;
#[cfg(any(test, feature = "test_data"))]
#[path = "tests/test_data.rs"]
pub mod test_data;
#[cfg(any(test, feature = "test_data"))]
#[path = "tests/test_helpers.rs"]
pub mod test_helpers;
pub use font_data::FontData;
pub use offset::{Offset, ResolveNullableOffset, ResolveOffset};
pub use read::{ComputeSize, FontRead, FontReadWithArgs, ReadArgs, ReadError, VarSize};
pub use table_provider::TableProvider;
pub use table_ref::TableRef;
#[doc(hidden)]
pub(crate) mod codegen_prelude {
pub use crate::array::{ComputedArray, VarLenArray};
pub use crate::font_data::{Cursor, FontData};
pub use crate::offset::{Offset, ResolveNullableOffset, ResolveOffset};
pub use crate::read::{
ComputeSize, FontRead, FontReadWithArgs, Format, ReadArgs, ReadError, VarSize,
};
pub use crate::table_ref::TableRef;
pub use font_types::*;
pub use std::ops::Range;
#[cfg(feature = "traversal")]
pub use crate::traversal::{self, Field, FieldType, RecordResolver, SomeRecord, SomeTable};
#[cfg(feature = "traversal")]
pub(crate) fn better_type_name<T>() -> &'static str {
let raw_name = std::any::type_name::<T>();
let last = raw_name.rsplit("::").next().unwrap_or(raw_name);
last.trim_end_matches("Marker>")
}
pub fn minus_one(val: impl Into<usize>) -> usize {
val.into().saturating_sub(1)
}
}
include!("../generated/font.rs");
pub struct FontRef<'a> {
data: FontData<'a>,
pub table_directory: TableDirectory<'a>,
}
impl<'a> FontRef<'a> {
pub fn new(data: FontData<'a>) -> Result<Self, ReadError> {
let table_directory = TableDirectory::read(data)?;
if [TT_SFNT_VERSION, CFF_SFTN_VERSION].contains(&table_directory.sfnt_version()) {
Ok(FontRef {
data,
table_directory,
})
} else {
Err(ReadError::InvalidSfnt(table_directory.sfnt_version()))
}
}
pub fn table_data(&self, tag: Tag) -> Option<FontData<'a>> {
self.table_directory
.table_records()
.binary_search_by(|rec| rec.tag.get().cmp(&tag))
.ok()
.and_then(|idx| self.table_directory.table_records().get(idx))
.and_then(|record| {
let start = record.offset().non_null()?;
let len = record.length() as usize;
self.data.slice(start..start + len)
})
}
}
impl<'a> TableProvider<'a> for FontRef<'a> {
fn data_for_tag(&self, tag: Tag) -> Option<FontData<'a>> {
self.table_data(tag)
}
}