blob: 19a0ad8dbb6a5cb775628c130f98b6bb6193f4e9 [file] [log] [blame] [edit]
// THIS FILE IS AUTOGENERATED.
// Any changes to this file will be overwritten.
// For more information about how codegen works, see font-codegen/README.md
#[allow(unused_imports)]
use crate::codegen_prelude::*;
pub use read_fonts::tables::cmap::PlatformId;
/// [cmap](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#overview)
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Cmap {
pub encoding_records: Vec<EncodingRecord>,
}
impl Cmap {
/// Construct a new `Cmap`
pub fn new(encoding_records: Vec<EncodingRecord>) -> Self {
Self { encoding_records }
}
}
impl FontWrite for Cmap {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(0 as u16).write_into(writer);
(u16::try_from(array_len(&self.encoding_records)).unwrap()).write_into(writer);
self.encoding_records.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::TopLevel(Cmap::TAG)
}
}
impl Validate for Cmap {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("Cmap", |ctx| {
ctx.in_field("encoding_records", |ctx| {
if self.encoding_records.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.encoding_records.validate_impl(ctx);
});
})
}
}
impl TopLevelTable for Cmap {
const TAG: Tag = Tag::new(b"cmap");
}
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap<'a>> for Cmap {
fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
Cmap {
encoding_records: obj.encoding_records().to_owned_obj(offset_data),
}
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap<'a>> for Cmap {}
impl<'a> FontRead<'a> for Cmap {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::cmap::Cmap as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
/// [Encoding Record](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#encoding-records-and-encodings)
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct EncodingRecord {
/// Platform ID.
pub platform_id: PlatformId,
/// Platform-specific encoding ID.
pub encoding_id: u16,
/// Byte offset from beginning of the [`Cmap`] table to the subtable for this
/// encoding.
pub subtable: OffsetMarker<CmapSubtable, WIDTH_32>,
}
impl EncodingRecord {
/// Construct a new `EncodingRecord`
pub fn new(platform_id: PlatformId, encoding_id: u16, subtable: CmapSubtable) -> Self {
Self {
platform_id,
encoding_id,
subtable: subtable.into(),
}
}
}
impl FontWrite for EncodingRecord {
fn write_into(&self, writer: &mut TableWriter) {
self.platform_id.write_into(writer);
self.encoding_id.write_into(writer);
self.subtable.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("EncodingRecord")
}
}
impl Validate for EncodingRecord {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("EncodingRecord", |ctx| {
ctx.in_field("subtable", |ctx| {
self.subtable.validate_impl(ctx);
});
})
}
}
impl FromObjRef<read_fonts::tables::cmap::EncodingRecord> for EncodingRecord {
fn from_obj_ref(obj: &read_fonts::tables::cmap::EncodingRecord, offset_data: FontData) -> Self {
EncodingRecord {
platform_id: obj.platform_id(),
encoding_id: obj.encoding_id(),
subtable: obj.subtable(offset_data).to_owned_table(),
}
}
}
impl FontWrite for PlatformId {
fn write_into(&self, writer: &mut TableWriter) {
let val = *self as u16;
writer.write_slice(&val.to_be_bytes())
}
}
/// The different cmap subtable formats.
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum CmapSubtable {
Format0(Cmap0),
Format2(Cmap2),
Format4(Cmap4),
Format6(Cmap6),
Format8(Cmap8),
Format10(Cmap10),
Format12(Cmap12),
Format13(Cmap13),
Format14(Cmap14),
}
impl CmapSubtable {
/// Construct a new `Cmap0` subtable
pub fn format_0(language: u16, glyph_id_array: Vec<u8>) -> Self {
Self::Format0(Cmap0::new(language, glyph_id_array))
}
/// Construct a new `Cmap2` subtable
pub fn format_2(length: u16, language: u16, sub_header_keys: Vec<u16>) -> Self {
Self::Format2(Cmap2::new(length, language, sub_header_keys))
}
/// Construct a new `Cmap4` subtable
pub fn format_4(
language: u16,
end_code: Vec<u16>,
start_code: Vec<u16>,
id_delta: Vec<i16>,
id_range_offsets: Vec<u16>,
glyph_id_array: Vec<u16>,
) -> Self {
Self::Format4(Cmap4::new(
language,
end_code,
start_code,
id_delta,
id_range_offsets,
glyph_id_array,
))
}
/// Construct a new `Cmap6` subtable
pub fn format_6(
length: u16,
language: u16,
first_code: u16,
entry_count: u16,
glyph_id_array: Vec<u16>,
) -> Self {
Self::Format6(Cmap6::new(
length,
language,
first_code,
entry_count,
glyph_id_array,
))
}
/// Construct a new `Cmap8` subtable
pub fn format_8(
length: u32,
language: u32,
is32: Vec<u8>,
num_groups: u32,
groups: Vec<SequentialMapGroup>,
) -> Self {
Self::Format8(Cmap8::new(length, language, is32, num_groups, groups))
}
/// Construct a new `Cmap10` subtable
pub fn format_10(
length: u32,
language: u32,
start_char_code: u32,
num_chars: u32,
glyph_id_array: Vec<u16>,
) -> Self {
Self::Format10(Cmap10::new(
length,
language,
start_char_code,
num_chars,
glyph_id_array,
))
}
/// Construct a new `Cmap12` subtable
pub fn format_12(language: u32, groups: Vec<SequentialMapGroup>) -> Self {
Self::Format12(Cmap12::new(language, groups))
}
/// Construct a new `Cmap13` subtable
pub fn format_13(
length: u32,
language: u32,
num_groups: u32,
groups: Vec<ConstantMapGroup>,
) -> Self {
Self::Format13(Cmap13::new(length, language, num_groups, groups))
}
/// Construct a new `Cmap14` subtable
pub fn format_14(
length: u32,
num_var_selector_records: u32,
var_selector: Vec<VariationSelector>,
) -> Self {
Self::Format14(Cmap14::new(length, num_var_selector_records, var_selector))
}
}
impl Default for CmapSubtable {
fn default() -> Self {
Self::Format0(Default::default())
}
}
impl FontWrite for CmapSubtable {
fn write_into(&self, writer: &mut TableWriter) {
match self {
Self::Format0(item) => item.write_into(writer),
Self::Format2(item) => item.write_into(writer),
Self::Format4(item) => item.write_into(writer),
Self::Format6(item) => item.write_into(writer),
Self::Format8(item) => item.write_into(writer),
Self::Format10(item) => item.write_into(writer),
Self::Format12(item) => item.write_into(writer),
Self::Format13(item) => item.write_into(writer),
Self::Format14(item) => item.write_into(writer),
}
}
fn table_type(&self) -> TableType {
match self {
Self::Format0(item) => item.table_type(),
Self::Format2(item) => item.table_type(),
Self::Format4(item) => item.table_type(),
Self::Format6(item) => item.table_type(),
Self::Format8(item) => item.table_type(),
Self::Format10(item) => item.table_type(),
Self::Format12(item) => item.table_type(),
Self::Format13(item) => item.table_type(),
Self::Format14(item) => item.table_type(),
}
}
}
impl Validate for CmapSubtable {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
match self {
Self::Format0(item) => item.validate_impl(ctx),
Self::Format2(item) => item.validate_impl(ctx),
Self::Format4(item) => item.validate_impl(ctx),
Self::Format6(item) => item.validate_impl(ctx),
Self::Format8(item) => item.validate_impl(ctx),
Self::Format10(item) => item.validate_impl(ctx),
Self::Format12(item) => item.validate_impl(ctx),
Self::Format13(item) => item.validate_impl(ctx),
Self::Format14(item) => item.validate_impl(ctx),
}
}
}
impl FromObjRef<read_fonts::tables::cmap::CmapSubtable<'_>> for CmapSubtable {
fn from_obj_ref(obj: &read_fonts::tables::cmap::CmapSubtable, _: FontData) -> Self {
use read_fonts::tables::cmap::CmapSubtable as ObjRefType;
match obj {
ObjRefType::Format0(item) => CmapSubtable::Format0(item.to_owned_table()),
ObjRefType::Format2(item) => CmapSubtable::Format2(item.to_owned_table()),
ObjRefType::Format4(item) => CmapSubtable::Format4(item.to_owned_table()),
ObjRefType::Format6(item) => CmapSubtable::Format6(item.to_owned_table()),
ObjRefType::Format8(item) => CmapSubtable::Format8(item.to_owned_table()),
ObjRefType::Format10(item) => CmapSubtable::Format10(item.to_owned_table()),
ObjRefType::Format12(item) => CmapSubtable::Format12(item.to_owned_table()),
ObjRefType::Format13(item) => CmapSubtable::Format13(item.to_owned_table()),
ObjRefType::Format14(item) => CmapSubtable::Format14(item.to_owned_table()),
}
}
}
impl FromTableRef<read_fonts::tables::cmap::CmapSubtable<'_>> for CmapSubtable {}
impl<'a> FontRead<'a> for CmapSubtable {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::cmap::CmapSubtable as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
impl From<Cmap0> for CmapSubtable {
fn from(src: Cmap0) -> CmapSubtable {
CmapSubtable::Format0(src)
}
}
impl From<Cmap2> for CmapSubtable {
fn from(src: Cmap2) -> CmapSubtable {
CmapSubtable::Format2(src)
}
}
impl From<Cmap4> for CmapSubtable {
fn from(src: Cmap4) -> CmapSubtable {
CmapSubtable::Format4(src)
}
}
impl From<Cmap6> for CmapSubtable {
fn from(src: Cmap6) -> CmapSubtable {
CmapSubtable::Format6(src)
}
}
impl From<Cmap8> for CmapSubtable {
fn from(src: Cmap8) -> CmapSubtable {
CmapSubtable::Format8(src)
}
}
impl From<Cmap10> for CmapSubtable {
fn from(src: Cmap10) -> CmapSubtable {
CmapSubtable::Format10(src)
}
}
impl From<Cmap12> for CmapSubtable {
fn from(src: Cmap12) -> CmapSubtable {
CmapSubtable::Format12(src)
}
}
impl From<Cmap13> for CmapSubtable {
fn from(src: Cmap13) -> CmapSubtable {
CmapSubtable::Format13(src)
}
}
impl From<Cmap14> for CmapSubtable {
fn from(src: Cmap14) -> CmapSubtable {
CmapSubtable::Format14(src)
}
}
/// [cmap Format 0](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-0-byte-encoding-table): Byte encoding table
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Cmap0 {
/// For requirements on use of the language field, see “Use of
/// the language field in 'cmap' subtables” in this document.
pub language: u16,
/// An array that maps character codes to glyph index values.
pub glyph_id_array: Vec<u8>,
}
impl Cmap0 {
/// Construct a new `Cmap0`
pub fn new(language: u16, glyph_id_array: Vec<u8>) -> Self {
Self {
language,
glyph_id_array,
}
}
}
impl FontWrite for Cmap0 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(0 as u16).write_into(writer);
(256 + 6 as u16).write_into(writer);
self.language.write_into(writer);
self.glyph_id_array.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("Cmap0")
}
}
impl Validate for Cmap0 {
fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
}
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap0<'a>> for Cmap0 {
fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap0<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
Cmap0 {
language: obj.language(),
glyph_id_array: obj.glyph_id_array().to_owned_obj(offset_data),
}
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap0<'a>> for Cmap0 {}
impl<'a> FontRead<'a> for Cmap0 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::cmap::Cmap0 as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
/// [cmap Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-2-high-byte-mapping-through-table): High-byte mapping through table
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Cmap2 {
/// This is the length in bytes of the subtable.
pub length: u16,
/// For requirements on use of the language field, see “Use of
/// the language field in 'cmap' subtables” in this document.
pub language: u16,
/// Array that maps high bytes to subHeaders: value is subHeader
/// index × 8.
pub sub_header_keys: Vec<u16>,
}
impl Cmap2 {
/// Construct a new `Cmap2`
pub fn new(length: u16, language: u16, sub_header_keys: Vec<u16>) -> Self {
Self {
length,
language,
sub_header_keys,
}
}
}
impl FontWrite for Cmap2 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(2 as u16).write_into(writer);
self.length.write_into(writer);
self.language.write_into(writer);
self.sub_header_keys.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("Cmap2")
}
}
impl Validate for Cmap2 {
fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
}
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap2<'a>> for Cmap2 {
fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap2<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
Cmap2 {
length: obj.length(),
language: obj.language(),
sub_header_keys: obj.sub_header_keys().to_owned_obj(offset_data),
}
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap2<'a>> for Cmap2 {}
impl<'a> FontRead<'a> for Cmap2 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::cmap::Cmap2 as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
/// Part of [Cmap2]
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SubHeader {
/// First valid low byte for this SubHeader.
pub first_code: u16,
/// Number of valid low bytes for this SubHeader.
pub entry_count: u16,
/// See text below.
pub id_delta: i16,
/// See text below.
pub id_range_offset: u16,
}
impl SubHeader {
/// Construct a new `SubHeader`
pub fn new(first_code: u16, entry_count: u16, id_delta: i16, id_range_offset: u16) -> Self {
Self {
first_code,
entry_count,
id_delta,
id_range_offset,
}
}
}
impl FontWrite for SubHeader {
fn write_into(&self, writer: &mut TableWriter) {
self.first_code.write_into(writer);
self.entry_count.write_into(writer);
self.id_delta.write_into(writer);
self.id_range_offset.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("SubHeader")
}
}
impl Validate for SubHeader {
fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
}
impl FromObjRef<read_fonts::tables::cmap::SubHeader> for SubHeader {
fn from_obj_ref(obj: &read_fonts::tables::cmap::SubHeader, _: FontData) -> Self {
SubHeader {
first_code: obj.first_code(),
entry_count: obj.entry_count(),
id_delta: obj.id_delta(),
id_range_offset: obj.id_range_offset(),
}
}
}
/// [cmap Format 4](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-4-segment-mapping-to-delta-values): Segment mapping to delta values
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Cmap4 {
/// For requirements on use of the language field, see “Use of
/// the language field in 'cmap' subtables” in this document.
pub language: u16,
/// End characterCode for each segment, last=0xFFFF.
pub end_code: Vec<u16>,
/// Start character code for each segment.
pub start_code: Vec<u16>,
/// Delta for all character codes in segment.
pub id_delta: Vec<i16>,
/// Offsets into glyphIdArray or 0
pub id_range_offsets: Vec<u16>,
/// Glyph index array (arbitrary length)
pub glyph_id_array: Vec<u16>,
}
impl Cmap4 {
/// Construct a new `Cmap4`
pub fn new(
language: u16,
end_code: Vec<u16>,
start_code: Vec<u16>,
id_delta: Vec<i16>,
id_range_offsets: Vec<u16>,
glyph_id_array: Vec<u16>,
) -> Self {
Self {
language,
end_code,
start_code,
id_delta,
id_range_offsets,
glyph_id_array,
}
}
}
impl FontWrite for Cmap4 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(4 as u16).write_into(writer);
(self.compute_length() as u16).write_into(writer);
self.language.write_into(writer);
(u16::try_from(2 * array_len(&self.end_code)).unwrap()).write_into(writer);
(self.compute_search_range() as u16).write_into(writer);
(self.compute_entry_selector() as u16).write_into(writer);
(self.compute_range_shift() as u16).write_into(writer);
self.end_code.write_into(writer);
(0 as u16).write_into(writer);
self.start_code.write_into(writer);
self.id_delta.write_into(writer);
self.id_range_offsets.write_into(writer);
self.glyph_id_array.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("Cmap4")
}
}
impl Validate for Cmap4 {
fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
}
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap4<'a>> for Cmap4 {
fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap4<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
Cmap4 {
language: obj.language(),
end_code: obj.end_code().to_owned_obj(offset_data),
start_code: obj.start_code().to_owned_obj(offset_data),
id_delta: obj.id_delta().to_owned_obj(offset_data),
id_range_offsets: obj.id_range_offsets().to_owned_obj(offset_data),
glyph_id_array: obj.glyph_id_array().to_owned_obj(offset_data),
}
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap4<'a>> for Cmap4 {}
impl<'a> FontRead<'a> for Cmap4 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::cmap::Cmap4 as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
/// [cmap Format 6](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-6-trimmed-table-mapping): Trimmed table mapping
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Cmap6 {
/// This is the length in bytes of the subtable.
pub length: u16,
/// For requirements on use of the language field, see “Use of
/// the language field in 'cmap' subtables” in this document.
pub language: u16,
/// First character code of subrange.
pub first_code: u16,
/// Number of character codes in subrange.
pub entry_count: u16,
/// Array of glyph index values for character codes in the range.
pub glyph_id_array: Vec<u16>,
}
impl Cmap6 {
/// Construct a new `Cmap6`
pub fn new(
length: u16,
language: u16,
first_code: u16,
entry_count: u16,
glyph_id_array: Vec<u16>,
) -> Self {
Self {
length,
language,
first_code,
entry_count,
glyph_id_array,
}
}
}
impl FontWrite for Cmap6 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(6 as u16).write_into(writer);
self.length.write_into(writer);
self.language.write_into(writer);
self.first_code.write_into(writer);
self.entry_count.write_into(writer);
self.glyph_id_array.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("Cmap6")
}
}
impl Validate for Cmap6 {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("Cmap6", |ctx| {
ctx.in_field("glyph_id_array", |ctx| {
if self.glyph_id_array.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap6<'a>> for Cmap6 {
fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap6<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
Cmap6 {
length: obj.length(),
language: obj.language(),
first_code: obj.first_code(),
entry_count: obj.entry_count(),
glyph_id_array: obj.glyph_id_array().to_owned_obj(offset_data),
}
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap6<'a>> for Cmap6 {}
impl<'a> FontRead<'a> for Cmap6 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::cmap::Cmap6 as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
/// [cmap Format 8](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-8-mixed-16-bit-and-32-bit-coverage): mixed 16-bit and 32-bit coverage
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Cmap8 {
/// Byte length of this subtable (including the header)
pub length: u32,
/// For requirements on use of the language field, see “Use of
/// the language field in 'cmap' subtables” in this document.
pub language: u32,
/// Tightly packed array of bits (8K bytes total) indicating
/// whether the particular 16-bit (index) value is the start of a
/// 32-bit character code
pub is32: Vec<u8>,
/// Number of groupings which follow
pub num_groups: u32,
/// Array of SequentialMapGroup records.
pub groups: Vec<SequentialMapGroup>,
}
impl Cmap8 {
/// Construct a new `Cmap8`
pub fn new(
length: u32,
language: u32,
is32: Vec<u8>,
num_groups: u32,
groups: Vec<SequentialMapGroup>,
) -> Self {
Self {
length,
language,
is32,
num_groups,
groups,
}
}
}
impl FontWrite for Cmap8 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(8 as u16).write_into(writer);
(0 as u16).write_into(writer);
self.length.write_into(writer);
self.language.write_into(writer);
self.is32.write_into(writer);
self.num_groups.write_into(writer);
self.groups.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("Cmap8")
}
}
impl Validate for Cmap8 {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("Cmap8", |ctx| {
ctx.in_field("groups", |ctx| {
if self.groups.len() > (u32::MAX as usize) {
ctx.report("array exceeds max length");
}
self.groups.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap8<'a>> for Cmap8 {
fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap8<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
Cmap8 {
length: obj.length(),
language: obj.language(),
is32: obj.is32().to_owned_obj(offset_data),
num_groups: obj.num_groups(),
groups: obj.groups().to_owned_obj(offset_data),
}
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap8<'a>> for Cmap8 {}
impl<'a> FontRead<'a> for Cmap8 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::cmap::Cmap8 as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
/// Used in [Cmap8] and [Cmap12]
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SequentialMapGroup {
/// First character code in this group; note that if this group is
/// for one or more 16-bit character codes (which is determined
/// from the is32 array), this 32-bit value will have the high
/// 16-bits set to zero
pub start_char_code: u32,
/// Last character code in this group; same condition as listed
/// above for the startCharCode
pub end_char_code: u32,
/// Glyph index corresponding to the starting character code
pub start_glyph_id: u32,
}
impl SequentialMapGroup {
/// Construct a new `SequentialMapGroup`
pub fn new(start_char_code: u32, end_char_code: u32, start_glyph_id: u32) -> Self {
Self {
start_char_code,
end_char_code,
start_glyph_id,
}
}
}
impl FontWrite for SequentialMapGroup {
fn write_into(&self, writer: &mut TableWriter) {
self.start_char_code.write_into(writer);
self.end_char_code.write_into(writer);
self.start_glyph_id.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("SequentialMapGroup")
}
}
impl Validate for SequentialMapGroup {
fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
}
impl FromObjRef<read_fonts::tables::cmap::SequentialMapGroup> for SequentialMapGroup {
fn from_obj_ref(obj: &read_fonts::tables::cmap::SequentialMapGroup, _: FontData) -> Self {
SequentialMapGroup {
start_char_code: obj.start_char_code(),
end_char_code: obj.end_char_code(),
start_glyph_id: obj.start_glyph_id(),
}
}
}
/// [cmap Format 10](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-10-trimmed-array): Tr
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Cmap10 {
/// Byte length of this subtable (including the header)
pub length: u32,
/// For requirements on use of the language field, see “Use of
/// the language field in 'cmap' subtables” in this document.
pub language: u32,
/// First character code covered
pub start_char_code: u32,
/// Number of character codes covered
pub num_chars: u32,
/// Array of glyph indices for the character codes covered
pub glyph_id_array: Vec<u16>,
}
impl Cmap10 {
/// Construct a new `Cmap10`
pub fn new(
length: u32,
language: u32,
start_char_code: u32,
num_chars: u32,
glyph_id_array: Vec<u16>,
) -> Self {
Self {
length,
language,
start_char_code,
num_chars,
glyph_id_array,
}
}
}
impl FontWrite for Cmap10 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(10 as u16).write_into(writer);
(0 as u16).write_into(writer);
self.length.write_into(writer);
self.language.write_into(writer);
self.start_char_code.write_into(writer);
self.num_chars.write_into(writer);
self.glyph_id_array.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("Cmap10")
}
}
impl Validate for Cmap10 {
fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
}
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap10<'a>> for Cmap10 {
fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap10<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
Cmap10 {
length: obj.length(),
language: obj.language(),
start_char_code: obj.start_char_code(),
num_chars: obj.num_chars(),
glyph_id_array: obj.glyph_id_array().to_owned_obj(offset_data),
}
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap10<'a>> for Cmap10 {}
impl<'a> FontRead<'a> for Cmap10 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::cmap::Cmap10 as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
/// [cmap Format 12](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-12-segmented-coverage): Segmented coverage
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Cmap12 {
/// For requirements on use of the language field, see “Use of
/// the language field in 'cmap' subtables” in this document.
pub language: u32,
/// Array of SequentialMapGroup records.
pub groups: Vec<SequentialMapGroup>,
}
impl Cmap12 {
/// Construct a new `Cmap12`
pub fn new(language: u32, groups: Vec<SequentialMapGroup>) -> Self {
Self { language, groups }
}
}
impl FontWrite for Cmap12 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(12 as u16).write_into(writer);
(0 as u16).write_into(writer);
(self.compute_length() as u32).write_into(writer);
self.language.write_into(writer);
(u32::try_from(array_len(&self.groups)).unwrap()).write_into(writer);
self.groups.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("Cmap12")
}
}
impl Validate for Cmap12 {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("Cmap12", |ctx| {
ctx.in_field("groups", |ctx| {
if self.groups.len() > (u32::MAX as usize) {
ctx.report("array exceeds max length");
}
self.groups.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap12<'a>> for Cmap12 {
fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap12<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
Cmap12 {
language: obj.language(),
groups: obj.groups().to_owned_obj(offset_data),
}
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap12<'a>> for Cmap12 {}
impl<'a> FontRead<'a> for Cmap12 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::cmap::Cmap12 as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
/// [cmap Format 13](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-13-many-to-one-range-mappings): Many-to-one range mappings
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Cmap13 {
/// Byte length of this subtable (including the header)
pub length: u32,
/// For requirements on use of the language field, see “Use of
/// the language field in 'cmap' subtables” in this document.
pub language: u32,
/// Number of groupings which follow
pub num_groups: u32,
/// Array of ConstantMapGroup records.
pub groups: Vec<ConstantMapGroup>,
}
impl Cmap13 {
/// Construct a new `Cmap13`
pub fn new(length: u32, language: u32, num_groups: u32, groups: Vec<ConstantMapGroup>) -> Self {
Self {
length,
language,
num_groups,
groups,
}
}
}
impl FontWrite for Cmap13 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(13 as u16).write_into(writer);
(0 as u16).write_into(writer);
self.length.write_into(writer);
self.language.write_into(writer);
self.num_groups.write_into(writer);
self.groups.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("Cmap13")
}
}
impl Validate for Cmap13 {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("Cmap13", |ctx| {
ctx.in_field("groups", |ctx| {
if self.groups.len() > (u32::MAX as usize) {
ctx.report("array exceeds max length");
}
self.groups.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap13<'a>> for Cmap13 {
fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap13<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
Cmap13 {
length: obj.length(),
language: obj.language(),
num_groups: obj.num_groups(),
groups: obj.groups().to_owned_obj(offset_data),
}
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap13<'a>> for Cmap13 {}
impl<'a> FontRead<'a> for Cmap13 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::cmap::Cmap13 as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
/// Part of [Cmap13]
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ConstantMapGroup {
/// First character code in this group
pub start_char_code: u32,
/// Last character code in this group
pub end_char_code: u32,
/// Glyph index to be used for all the characters in the group’s
/// range.
pub glyph_id: u32,
}
impl ConstantMapGroup {
/// Construct a new `ConstantMapGroup`
pub fn new(start_char_code: u32, end_char_code: u32, glyph_id: u32) -> Self {
Self {
start_char_code,
end_char_code,
glyph_id,
}
}
}
impl FontWrite for ConstantMapGroup {
fn write_into(&self, writer: &mut TableWriter) {
self.start_char_code.write_into(writer);
self.end_char_code.write_into(writer);
self.glyph_id.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("ConstantMapGroup")
}
}
impl Validate for ConstantMapGroup {
fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
}
impl FromObjRef<read_fonts::tables::cmap::ConstantMapGroup> for ConstantMapGroup {
fn from_obj_ref(obj: &read_fonts::tables::cmap::ConstantMapGroup, _: FontData) -> Self {
ConstantMapGroup {
start_char_code: obj.start_char_code(),
end_char_code: obj.end_char_code(),
glyph_id: obj.glyph_id(),
}
}
}
/// [cmap Format 14](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#format-14-unicode-variation-sequences): Unicode Variation Sequences
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Cmap14 {
/// Byte length of this subtable (including this header)
pub length: u32,
/// Number of variation Selector Records
pub num_var_selector_records: u32,
/// Array of VariationSelector records.
pub var_selector: Vec<VariationSelector>,
}
impl Cmap14 {
/// Construct a new `Cmap14`
pub fn new(
length: u32,
num_var_selector_records: u32,
var_selector: Vec<VariationSelector>,
) -> Self {
Self {
length,
num_var_selector_records,
var_selector,
}
}
}
impl FontWrite for Cmap14 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(14 as u16).write_into(writer);
self.length.write_into(writer);
self.num_var_selector_records.write_into(writer);
self.var_selector.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("Cmap14")
}
}
impl Validate for Cmap14 {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("Cmap14", |ctx| {
ctx.in_field("var_selector", |ctx| {
if self.var_selector.len() > (u32::MAX as usize) {
ctx.report("array exceeds max length");
}
self.var_selector.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::cmap::Cmap14<'a>> for Cmap14 {
fn from_obj_ref(obj: &read_fonts::tables::cmap::Cmap14<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
Cmap14 {
length: obj.length(),
num_var_selector_records: obj.num_var_selector_records(),
var_selector: obj.var_selector().to_owned_obj(offset_data),
}
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FromTableRef<read_fonts::tables::cmap::Cmap14<'a>> for Cmap14 {}
impl<'a> FontRead<'a> for Cmap14 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::cmap::Cmap14 as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
/// Part of [Cmap14]
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct VariationSelector {
/// Variation selector
pub var_selector: Uint24,
/// Offset from the start of the [`Cmap14`] subtable to Default UVS
/// Table. May be NULL.
pub default_uvs: NullableOffsetMarker<DefaultUvs, WIDTH_32>,
/// Offset from the start of the [`Cmap14`] subtable to Non-Default
/// UVS Table. May be NULL.
pub non_default_uvs: NullableOffsetMarker<NonDefaultUvs, WIDTH_32>,
}
impl VariationSelector {
/// Construct a new `VariationSelector`
pub fn new(
var_selector: Uint24,
default_uvs: Option<DefaultUvs>,
non_default_uvs: Option<NonDefaultUvs>,
) -> Self {
Self {
var_selector,
default_uvs: default_uvs.into(),
non_default_uvs: non_default_uvs.into(),
}
}
}
impl FontWrite for VariationSelector {
fn write_into(&self, writer: &mut TableWriter) {
self.var_selector.write_into(writer);
self.default_uvs.write_into(writer);
self.non_default_uvs.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("VariationSelector")
}
}
impl Validate for VariationSelector {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("VariationSelector", |ctx| {
ctx.in_field("default_uvs", |ctx| {
self.default_uvs.validate_impl(ctx);
});
ctx.in_field("non_default_uvs", |ctx| {
self.non_default_uvs.validate_impl(ctx);
});
})
}
}
impl FromObjRef<read_fonts::tables::cmap::VariationSelector> for VariationSelector {
fn from_obj_ref(
obj: &read_fonts::tables::cmap::VariationSelector,
offset_data: FontData,
) -> Self {
VariationSelector {
var_selector: obj.var_selector(),
default_uvs: obj.default_uvs(offset_data).to_owned_table(),
non_default_uvs: obj.non_default_uvs(offset_data).to_owned_table(),
}
}
}
/// [Default UVS table](https://docs.microsoft.com/en-us/typography/opentype/spec/cmap#default-uvs-table)
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct DefaultUvs {
/// Number of Unicode character ranges.
pub num_unicode_value_ranges: u32,
/// Array of UnicodeRange records.
pub ranges: Vec<UnicodeRange>,
}
impl DefaultUvs {
/// Construct a new `DefaultUvs`
pub fn new(num_unicode_value_ranges: u32, ranges: Vec<UnicodeRange>) -> Self {
Self {
num_unicode_value_ranges,
ranges,
}
}
}
impl FontWrite for DefaultUvs {
fn write_into(&self, writer: &mut TableWriter) {
self.num_unicode_value_ranges.write_into(writer);
self.ranges.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("DefaultUvs")
}
}
impl Validate for DefaultUvs {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("DefaultUvs", |ctx| {
ctx.in_field("ranges", |ctx| {
if self.ranges.len() > (u32::MAX as usize) {
ctx.report("array exceeds max length");
}
self.ranges.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::cmap::DefaultUvs<'a>> for DefaultUvs {
fn from_obj_ref(obj: &read_fonts::tables::cmap::DefaultUvs<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
DefaultUvs {
num_unicode_value_ranges: obj.num_unicode_value_ranges(),
ranges: obj.ranges().to_owned_obj(offset_data),
}
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FromTableRef<read_fonts::tables::cmap::DefaultUvs<'a>> for DefaultUvs {}
impl<'a> FontRead<'a> for DefaultUvs {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::cmap::DefaultUvs as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
/// [Non-Default UVS table](https://learn.microsoft.com/en-us/typography/opentype/spec/cmap#non-default-uvs-table)
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct NonDefaultUvs {
pub num_uvs_mappings: u32,
pub uvs_mapping: Vec<UvsMapping>,
}
impl NonDefaultUvs {
/// Construct a new `NonDefaultUvs`
pub fn new(num_uvs_mappings: u32, uvs_mapping: Vec<UvsMapping>) -> Self {
Self {
num_uvs_mappings,
uvs_mapping,
}
}
}
impl FontWrite for NonDefaultUvs {
fn write_into(&self, writer: &mut TableWriter) {
self.num_uvs_mappings.write_into(writer);
self.uvs_mapping.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("NonDefaultUvs")
}
}
impl Validate for NonDefaultUvs {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("NonDefaultUvs", |ctx| {
ctx.in_field("uvs_mapping", |ctx| {
if self.uvs_mapping.len() > (u32::MAX as usize) {
ctx.report("array exceeds max length");
}
self.uvs_mapping.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::cmap::NonDefaultUvs<'a>> for NonDefaultUvs {
fn from_obj_ref(obj: &read_fonts::tables::cmap::NonDefaultUvs<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
NonDefaultUvs {
num_uvs_mappings: obj.num_uvs_mappings(),
uvs_mapping: obj.uvs_mapping().to_owned_obj(offset_data),
}
}
}
#[allow(clippy::needless_lifetimes)]
impl<'a> FromTableRef<read_fonts::tables::cmap::NonDefaultUvs<'a>> for NonDefaultUvs {}
impl<'a> FontRead<'a> for NonDefaultUvs {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::cmap::NonDefaultUvs as FontRead>::read(data)
.map(|x| x.to_owned_table())
}
}
/// Part of [Cmap14]
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct UvsMapping {
/// Base Unicode value of the UVS
pub unicode_value: Uint24,
/// Glyph ID of the UVS
pub glyph_id: u16,
}
impl UvsMapping {
/// Construct a new `UvsMapping`
pub fn new(unicode_value: Uint24, glyph_id: u16) -> Self {
Self {
unicode_value,
glyph_id,
}
}
}
impl FontWrite for UvsMapping {
fn write_into(&self, writer: &mut TableWriter) {
self.unicode_value.write_into(writer);
self.glyph_id.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("UvsMapping")
}
}
impl Validate for UvsMapping {
fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
}
impl FromObjRef<read_fonts::tables::cmap::UvsMapping> for UvsMapping {
fn from_obj_ref(obj: &read_fonts::tables::cmap::UvsMapping, _: FontData) -> Self {
UvsMapping {
unicode_value: obj.unicode_value(),
glyph_id: obj.glyph_id(),
}
}
}
/// Part of [Cmap14]
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct UnicodeRange {
/// First value in this range
pub start_unicode_value: Uint24,
/// Number of additional values in this range
pub additional_count: u8,
}
impl UnicodeRange {
/// Construct a new `UnicodeRange`
pub fn new(start_unicode_value: Uint24, additional_count: u8) -> Self {
Self {
start_unicode_value,
additional_count,
}
}
}
impl FontWrite for UnicodeRange {
fn write_into(&self, writer: &mut TableWriter) {
self.start_unicode_value.write_into(writer);
self.additional_count.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("UnicodeRange")
}
}
impl Validate for UnicodeRange {
fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
}
impl FromObjRef<read_fonts::tables::cmap::UnicodeRange> for UnicodeRange {
fn from_obj_ref(obj: &read_fonts::tables::cmap::UnicodeRange, _: FontData) -> Self {
UnicodeRange {
start_unicode_value: obj.start_unicode_value(),
additional_count: obj.additional_count(),
}
}
}