| // 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::layout::DeltaFormat; |
| |
| /// [Script List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-list-table-and-script-record) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ScriptList { |
| /// Array of ScriptRecords, listed alphabetically by script tag |
| pub script_records: Vec<ScriptRecord>, |
| } |
| |
| impl ScriptList { |
| /// Construct a new `ScriptList` |
| pub fn new(script_records: Vec<ScriptRecord>) -> Self { |
| Self { script_records } |
| } |
| } |
| |
| impl FontWrite for ScriptList { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (u16::try_from(array_len(&self.script_records)).unwrap()).write_into(writer); |
| self.script_records.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ScriptList") |
| } |
| } |
| |
| impl Validate for ScriptList { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ScriptList", |ctx| { |
| ctx.in_field("script_records", |ctx| { |
| if self.script_records.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.script_records.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ScriptList<'a>> for ScriptList { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::ScriptList<'a>, _: FontData) -> Self { |
| let offset_data = obj.offset_data(); |
| ScriptList { |
| script_records: obj.script_records().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ScriptList<'a>> for ScriptList {} |
| |
| impl<'a> FontRead<'a> for ScriptList { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ScriptList as FontRead>::read(data).map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// [Script Record](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-list-table-and-script-record) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ScriptRecord { |
| /// 4-byte script tag identifier |
| pub script_tag: Tag, |
| /// Offset to Script table, from beginning of ScriptList |
| pub script: OffsetMarker<Script>, |
| } |
| |
| impl ScriptRecord { |
| /// Construct a new `ScriptRecord` |
| pub fn new(script_tag: Tag, script: Script) -> Self { |
| Self { |
| script_tag, |
| script: script.into(), |
| } |
| } |
| } |
| |
| impl FontWrite for ScriptRecord { |
| fn write_into(&self, writer: &mut TableWriter) { |
| self.script_tag.write_into(writer); |
| self.script.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ScriptRecord") |
| } |
| } |
| |
| impl Validate for ScriptRecord { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ScriptRecord", |ctx| { |
| ctx.in_field("script", |ctx| { |
| self.script.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl FromObjRef<read_fonts::tables::layout::ScriptRecord> for ScriptRecord { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::ScriptRecord, offset_data: FontData) -> Self { |
| ScriptRecord { |
| script_tag: obj.script_tag(), |
| script: obj.script(offset_data).to_owned_table(), |
| } |
| } |
| } |
| |
| /// [Script Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#script-table-and-language-system-record) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct Script { |
| /// Offset to default LangSys table, from beginning of Script table |
| /// — may be NULL |
| pub default_lang_sys: NullableOffsetMarker<LangSys>, |
| /// Array of LangSysRecords, listed alphabetically by LangSys tag |
| pub lang_sys_records: Vec<LangSysRecord>, |
| } |
| |
| impl Script { |
| /// Construct a new `Script` |
| pub fn new(default_lang_sys: Option<LangSys>, lang_sys_records: Vec<LangSysRecord>) -> Self { |
| Self { |
| default_lang_sys: default_lang_sys.into(), |
| lang_sys_records, |
| } |
| } |
| } |
| |
| impl FontWrite for Script { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| self.default_lang_sys.write_into(writer); |
| (u16::try_from(array_len(&self.lang_sys_records)).unwrap()).write_into(writer); |
| self.lang_sys_records.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("Script") |
| } |
| } |
| |
| impl Validate for Script { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("Script", |ctx| { |
| ctx.in_field("default_lang_sys", |ctx| { |
| self.default_lang_sys.validate_impl(ctx); |
| }); |
| ctx.in_field("lang_sys_records", |ctx| { |
| if self.lang_sys_records.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.lang_sys_records.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::Script<'a>> for Script { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::Script<'a>, _: FontData) -> Self { |
| let offset_data = obj.offset_data(); |
| Script { |
| default_lang_sys: obj.default_lang_sys().to_owned_table(), |
| lang_sys_records: obj.lang_sys_records().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::Script<'a>> for Script {} |
| |
| impl<'a> FontRead<'a> for Script { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::Script as FontRead>::read(data).map(|x| x.to_owned_table()) |
| } |
| } |
| |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct LangSysRecord { |
| /// 4-byte LangSysTag identifier |
| pub lang_sys_tag: Tag, |
| /// Offset to LangSys table, from beginning of Script table |
| pub lang_sys: OffsetMarker<LangSys>, |
| } |
| |
| impl LangSysRecord { |
| /// Construct a new `LangSysRecord` |
| pub fn new(lang_sys_tag: Tag, lang_sys: LangSys) -> Self { |
| Self { |
| lang_sys_tag, |
| lang_sys: lang_sys.into(), |
| } |
| } |
| } |
| |
| impl FontWrite for LangSysRecord { |
| fn write_into(&self, writer: &mut TableWriter) { |
| self.lang_sys_tag.write_into(writer); |
| self.lang_sys.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("LangSysRecord") |
| } |
| } |
| |
| impl Validate for LangSysRecord { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("LangSysRecord", |ctx| { |
| ctx.in_field("lang_sys", |ctx| { |
| self.lang_sys.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl FromObjRef<read_fonts::tables::layout::LangSysRecord> for LangSysRecord { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::LangSysRecord, |
| offset_data: FontData, |
| ) -> Self { |
| LangSysRecord { |
| lang_sys_tag: obj.lang_sys_tag(), |
| lang_sys: obj.lang_sys(offset_data).to_owned_table(), |
| } |
| } |
| } |
| |
| /// [Language System Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#language-system-table) |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct LangSys { |
| /// Index of a feature required for this language system; if no |
| /// required features = 0xFFFF |
| pub required_feature_index: u16, |
| /// Array of indices into the FeatureList, in arbitrary order |
| pub feature_indices: Vec<u16>, |
| } |
| |
| impl Default for LangSys { |
| fn default() -> Self { |
| Self { |
| required_feature_index: 0xFFFF, |
| feature_indices: Default::default(), |
| } |
| } |
| } |
| |
| impl LangSys { |
| /// Construct a new `LangSys` |
| pub fn new(feature_indices: Vec<u16>) -> Self { |
| Self { |
| feature_indices, |
| ..Default::default() |
| } |
| } |
| } |
| |
| impl FontWrite for LangSys { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (0 as u16).write_into(writer); |
| self.required_feature_index.write_into(writer); |
| (u16::try_from(array_len(&self.feature_indices)).unwrap()).write_into(writer); |
| self.feature_indices.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("LangSys") |
| } |
| } |
| |
| impl Validate for LangSys { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("LangSys", |ctx| { |
| ctx.in_field("feature_indices", |ctx| { |
| if self.feature_indices.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::LangSys<'a>> for LangSys { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::LangSys<'a>, _: FontData) -> Self { |
| let offset_data = obj.offset_data(); |
| LangSys { |
| required_feature_index: obj.required_feature_index(), |
| feature_indices: obj.feature_indices().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::LangSys<'a>> for LangSys {} |
| |
| impl<'a> FontRead<'a> for LangSys { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::LangSys as FontRead>::read(data).map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// [Feature List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#feature-list-table) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct FeatureList { |
| /// Array of FeatureRecords — zero-based (first feature has |
| /// FeatureIndex = 0), listed alphabetically by feature tag |
| pub feature_records: Vec<FeatureRecord>, |
| } |
| |
| impl FeatureList { |
| /// Construct a new `FeatureList` |
| pub fn new(feature_records: Vec<FeatureRecord>) -> Self { |
| Self { feature_records } |
| } |
| } |
| |
| impl FontWrite for FeatureList { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (u16::try_from(array_len(&self.feature_records)).unwrap()).write_into(writer); |
| self.feature_records.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("FeatureList") |
| } |
| } |
| |
| impl Validate for FeatureList { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("FeatureList", |ctx| { |
| ctx.in_field("feature_records", |ctx| { |
| if self.feature_records.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.feature_records.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::FeatureList<'a>> for FeatureList { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::FeatureList<'a>, _: FontData) -> Self { |
| let offset_data = obj.offset_data(); |
| FeatureList { |
| feature_records: obj.feature_records().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::FeatureList<'a>> for FeatureList {} |
| |
| impl<'a> FontRead<'a> for FeatureList { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::FeatureList as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// Part of [FeatureList] |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct FeatureRecord { |
| /// 4-byte feature identification tag |
| pub feature_tag: Tag, |
| /// Offset to Feature table, from beginning of FeatureList |
| pub feature: OffsetMarker<Feature>, |
| } |
| |
| impl FeatureRecord { |
| /// Construct a new `FeatureRecord` |
| pub fn new(feature_tag: Tag, feature: Feature) -> Self { |
| Self { |
| feature_tag, |
| feature: feature.into(), |
| } |
| } |
| } |
| |
| impl FontWrite for FeatureRecord { |
| fn write_into(&self, writer: &mut TableWriter) { |
| self.feature_tag.write_into(writer); |
| self.feature.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("FeatureRecord") |
| } |
| } |
| |
| impl Validate for FeatureRecord { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("FeatureRecord", |ctx| { |
| ctx.in_field("feature", |ctx| { |
| self.feature.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl FromObjRef<read_fonts::tables::layout::FeatureRecord> for FeatureRecord { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::FeatureRecord, |
| offset_data: FontData, |
| ) -> Self { |
| FeatureRecord { |
| feature_tag: obj.feature_tag(), |
| feature: obj.feature(offset_data).to_owned_table(), |
| } |
| } |
| } |
| |
| /// [Feature Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#feature-table) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct Feature { |
| /// Offset from start of Feature table to FeatureParams table, if defined for the feature and present, else NULL |
| pub feature_params: NullableOffsetMarker<FeatureParams>, |
| /// Array of indices into the LookupList — zero-based (first |
| /// lookup is LookupListIndex = 0) |
| pub lookup_list_indices: Vec<u16>, |
| } |
| |
| impl Feature { |
| /// Construct a new `Feature` |
| pub fn new(feature_params: Option<FeatureParams>, lookup_list_indices: Vec<u16>) -> Self { |
| Self { |
| feature_params: feature_params.into(), |
| lookup_list_indices, |
| } |
| } |
| } |
| |
| impl FontWrite for Feature { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| self.feature_params.write_into(writer); |
| (u16::try_from(array_len(&self.lookup_list_indices)).unwrap()).write_into(writer); |
| self.lookup_list_indices.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("Feature") |
| } |
| } |
| |
| impl Validate for Feature { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("Feature", |ctx| { |
| ctx.in_field("feature_params", |ctx| { |
| self.feature_params.validate_impl(ctx); |
| }); |
| ctx.in_field("lookup_list_indices", |ctx| { |
| if self.lookup_list_indices.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::Feature<'a>> for Feature { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::Feature<'a>, _: FontData) -> Self { |
| let offset_data = obj.offset_data(); |
| Feature { |
| feature_params: obj.feature_params().to_owned_table(), |
| lookup_list_indices: obj.lookup_list_indices().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::Feature<'a>> for Feature {} |
| |
| /// [Lookup List Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#lookup-list-table) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct LookupList<T> { |
| /// Array of offsets to Lookup tables, from beginning of LookupList |
| /// — zero based (first lookup is Lookup index = 0) |
| pub lookups: Vec<OffsetMarker<T>>, |
| } |
| |
| impl<T: Default> LookupList<T> { |
| /// Construct a new `LookupList` |
| pub fn new(lookups: Vec<T>) -> Self { |
| Self { |
| lookups: lookups.into_iter().map(Into::into).collect(), |
| } |
| } |
| } |
| |
| impl<T: FontWrite> FontWrite for LookupList<T> { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (u16::try_from(array_len(&self.lookups)).unwrap()).write_into(writer); |
| self.lookups.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("LookupList") |
| } |
| } |
| |
| impl<T: Validate> Validate for LookupList<T> { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("LookupList", |ctx| { |
| ctx.in_field("lookups", |ctx| { |
| if self.lookups.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.lookups.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a, T, U> FromObjRef<read_fonts::tables::layout::LookupList<'a, U>> for LookupList<T> |
| where |
| U: FontRead<'a>, |
| T: FromTableRef<U> + Default + 'static, |
| { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::LookupList<'a, U>, _: FontData) -> Self { |
| LookupList { |
| lookups: obj.lookups().to_owned_table(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a, T, U> FromTableRef<read_fonts::tables::layout::LookupList<'a, U>> for LookupList<T> |
| where |
| U: FontRead<'a>, |
| T: FromTableRef<U> + Default + 'static, |
| { |
| } |
| |
| /// [Lookup Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#lookup-table) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct Lookup<T> { |
| /// Lookup qualifiers |
| pub lookup_flag: LookupFlag, |
| /// Array of offsets to lookup subtables, from beginning of Lookup |
| /// table |
| pub subtables: Vec<OffsetMarker<T>>, |
| /// Index (base 0) into GDEF mark glyph sets structure. This field |
| /// is only present if the USE_MARK_FILTERING_SET lookup flag is |
| /// set. |
| pub mark_filtering_set: Option<u16>, |
| } |
| |
| impl<T: Default> Lookup<T> { |
| /// Construct a new `Lookup` |
| pub fn new(lookup_flag: LookupFlag, subtables: Vec<T>) -> Self { |
| Self { |
| lookup_flag, |
| subtables: subtables.into_iter().map(Into::into).collect(), |
| ..Default::default() |
| } |
| } |
| } |
| |
| impl<T: Validate> Validate for Lookup<T> { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("Lookup", |ctx| { |
| let lookup_flag = self.lookup_flag; |
| ctx.in_field("subtables", |ctx| { |
| if self.subtables.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.subtables.validate_impl(ctx); |
| }); |
| ctx.in_field("mark_filtering_set", |ctx| { |
| if !(lookup_flag.contains(LookupFlag::USE_MARK_FILTERING_SET)) |
| && self.mark_filtering_set.is_some() |
| { |
| ctx.report("'mark_filtering_set' is present but USE_MARK_FILTERING_SET not set") |
| } |
| if (lookup_flag.contains(LookupFlag::USE_MARK_FILTERING_SET)) |
| && self.mark_filtering_set.is_none() |
| { |
| ctx.report("USE_MARK_FILTERING_SET is set but 'mark_filtering_set' is None") |
| } |
| }); |
| }) |
| } |
| } |
| |
| impl<'a, T, U> FromObjRef<read_fonts::tables::layout::Lookup<'a, U>> for Lookup<T> |
| where |
| U: FontRead<'a>, |
| T: FromTableRef<U> + Default + 'static, |
| { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::Lookup<'a, U>, _: FontData) -> Self { |
| Lookup { |
| lookup_flag: obj.lookup_flag(), |
| subtables: obj.subtables().to_owned_table(), |
| mark_filtering_set: obj.mark_filtering_set(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a, T, U> FromTableRef<read_fonts::tables::layout::Lookup<'a, U>> for Lookup<T> |
| where |
| U: FontRead<'a>, |
| T: FromTableRef<U> + Default + 'static, |
| { |
| } |
| |
| /// [Coverage Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-1) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct CoverageFormat1 { |
| /// Array of glyph IDs — in numerical order |
| pub glyph_array: Vec<GlyphId16>, |
| } |
| |
| impl CoverageFormat1 { |
| /// Construct a new `CoverageFormat1` |
| pub fn new(glyph_array: Vec<GlyphId16>) -> Self { |
| Self { glyph_array } |
| } |
| } |
| |
| impl FontWrite for CoverageFormat1 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (1 as u16).write_into(writer); |
| (u16::try_from(array_len(&self.glyph_array)).unwrap()).write_into(writer); |
| self.glyph_array.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("CoverageFormat1") |
| } |
| } |
| |
| impl Validate for CoverageFormat1 { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("CoverageFormat1", |ctx| { |
| ctx.in_field("glyph_array", |ctx| { |
| if self.glyph_array.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::CoverageFormat1<'a>> for CoverageFormat1 { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::CoverageFormat1<'a>, _: FontData) -> Self { |
| let offset_data = obj.offset_data(); |
| CoverageFormat1 { |
| glyph_array: obj.glyph_array().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::CoverageFormat1<'a>> for CoverageFormat1 {} |
| |
| impl<'a> FontRead<'a> for CoverageFormat1 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::CoverageFormat1 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// [Coverage Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-2) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct CoverageFormat2 { |
| /// Array of glyph ranges — ordered by startGlyphID. |
| pub range_records: Vec<RangeRecord>, |
| } |
| |
| impl CoverageFormat2 { |
| /// Construct a new `CoverageFormat2` |
| pub fn new(range_records: Vec<RangeRecord>) -> Self { |
| Self { range_records } |
| } |
| } |
| |
| impl FontWrite for CoverageFormat2 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (2 as u16).write_into(writer); |
| (u16::try_from(array_len(&self.range_records)).unwrap()).write_into(writer); |
| self.range_records.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("CoverageFormat2") |
| } |
| } |
| |
| impl Validate for CoverageFormat2 { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("CoverageFormat2", |ctx| { |
| ctx.in_field("range_records", |ctx| { |
| if self.range_records.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.range_records.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::CoverageFormat2<'a>> for CoverageFormat2 { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::CoverageFormat2<'a>, _: FontData) -> Self { |
| let offset_data = obj.offset_data(); |
| CoverageFormat2 { |
| range_records: obj.range_records().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::CoverageFormat2<'a>> for CoverageFormat2 {} |
| |
| impl<'a> FontRead<'a> for CoverageFormat2 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::CoverageFormat2 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// Used in [CoverageFormat2] |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct RangeRecord { |
| /// First glyph ID in the range |
| pub start_glyph_id: GlyphId16, |
| /// Last glyph ID in the range |
| pub end_glyph_id: GlyphId16, |
| /// Coverage Index of first glyph ID in range |
| pub start_coverage_index: u16, |
| } |
| |
| impl RangeRecord { |
| /// Construct a new `RangeRecord` |
| pub fn new( |
| start_glyph_id: GlyphId16, |
| end_glyph_id: GlyphId16, |
| start_coverage_index: u16, |
| ) -> Self { |
| Self { |
| start_glyph_id, |
| end_glyph_id, |
| start_coverage_index, |
| } |
| } |
| } |
| |
| impl FontWrite for RangeRecord { |
| fn write_into(&self, writer: &mut TableWriter) { |
| self.start_glyph_id.write_into(writer); |
| self.end_glyph_id.write_into(writer); |
| self.start_coverage_index.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("RangeRecord") |
| } |
| } |
| |
| impl Validate for RangeRecord { |
| fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
| } |
| |
| impl FromObjRef<read_fonts::tables::layout::RangeRecord> for RangeRecord { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::RangeRecord, _: FontData) -> Self { |
| RangeRecord { |
| start_glyph_id: obj.start_glyph_id(), |
| end_glyph_id: obj.end_glyph_id(), |
| start_coverage_index: obj.start_coverage_index(), |
| } |
| } |
| } |
| |
| /// [Coverage Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-table) |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub enum CoverageTable { |
| Format1(CoverageFormat1), |
| Format2(CoverageFormat2), |
| } |
| |
| impl CoverageTable { |
| /// Construct a new `CoverageFormat1` subtable |
| pub fn format_1(glyph_array: Vec<GlyphId16>) -> Self { |
| Self::Format1(CoverageFormat1::new(glyph_array)) |
| } |
| |
| /// Construct a new `CoverageFormat2` subtable |
| pub fn format_2(range_records: Vec<RangeRecord>) -> Self { |
| Self::Format2(CoverageFormat2::new(range_records)) |
| } |
| } |
| |
| impl Default for CoverageTable { |
| fn default() -> Self { |
| Self::Format1(Default::default()) |
| } |
| } |
| |
| impl FontWrite for CoverageTable { |
| fn write_into(&self, writer: &mut TableWriter) { |
| match self { |
| Self::Format1(item) => item.write_into(writer), |
| Self::Format2(item) => item.write_into(writer), |
| } |
| } |
| fn table_type(&self) -> TableType { |
| match self { |
| Self::Format1(item) => item.table_type(), |
| Self::Format2(item) => item.table_type(), |
| } |
| } |
| } |
| |
| impl Validate for CoverageTable { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| match self { |
| Self::Format1(item) => item.validate_impl(ctx), |
| Self::Format2(item) => item.validate_impl(ctx), |
| } |
| } |
| } |
| |
| impl FromObjRef<read_fonts::tables::layout::CoverageTable<'_>> for CoverageTable { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::CoverageTable, _: FontData) -> Self { |
| use read_fonts::tables::layout::CoverageTable as ObjRefType; |
| match obj { |
| ObjRefType::Format1(item) => CoverageTable::Format1(item.to_owned_table()), |
| ObjRefType::Format2(item) => CoverageTable::Format2(item.to_owned_table()), |
| } |
| } |
| } |
| |
| impl FromTableRef<read_fonts::tables::layout::CoverageTable<'_>> for CoverageTable {} |
| |
| impl<'a> FontRead<'a> for CoverageTable { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::CoverageTable as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| impl From<CoverageFormat1> for CoverageTable { |
| fn from(src: CoverageFormat1) -> CoverageTable { |
| CoverageTable::Format1(src) |
| } |
| } |
| |
| impl From<CoverageFormat2> for CoverageTable { |
| fn from(src: CoverageFormat2) -> CoverageTable { |
| CoverageTable::Format2(src) |
| } |
| } |
| |
| /// [Class Definition Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-1) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ClassDefFormat1 { |
| /// First glyph ID of the classValueArray |
| pub start_glyph_id: GlyphId16, |
| /// Array of Class Values — one per glyph ID |
| pub class_value_array: Vec<u16>, |
| } |
| |
| impl ClassDefFormat1 { |
| /// Construct a new `ClassDefFormat1` |
| pub fn new(start_glyph_id: GlyphId16, class_value_array: Vec<u16>) -> Self { |
| Self { |
| start_glyph_id, |
| class_value_array, |
| } |
| } |
| } |
| |
| impl FontWrite for ClassDefFormat1 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (1 as u16).write_into(writer); |
| self.start_glyph_id.write_into(writer); |
| (u16::try_from(array_len(&self.class_value_array)).unwrap()).write_into(writer); |
| self.class_value_array.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ClassDefFormat1") |
| } |
| } |
| |
| impl Validate for ClassDefFormat1 { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ClassDefFormat1", |ctx| { |
| ctx.in_field("class_value_array", |ctx| { |
| if self.class_value_array.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ClassDefFormat1<'a>> for ClassDefFormat1 { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::ClassDefFormat1<'a>, _: FontData) -> Self { |
| let offset_data = obj.offset_data(); |
| ClassDefFormat1 { |
| start_glyph_id: obj.start_glyph_id(), |
| class_value_array: obj.class_value_array().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ClassDefFormat1<'a>> for ClassDefFormat1 {} |
| |
| impl<'a> FontRead<'a> for ClassDefFormat1 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ClassDefFormat1 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// [Class Definition Table Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table-format-2) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ClassDefFormat2 { |
| /// Array of ClassRangeRecords — ordered by startGlyphID |
| pub class_range_records: Vec<ClassRangeRecord>, |
| } |
| |
| impl ClassDefFormat2 { |
| /// Construct a new `ClassDefFormat2` |
| pub fn new(class_range_records: Vec<ClassRangeRecord>) -> Self { |
| Self { |
| class_range_records, |
| } |
| } |
| } |
| |
| impl FontWrite for ClassDefFormat2 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (2 as u16).write_into(writer); |
| (u16::try_from(array_len(&self.class_range_records)).unwrap()).write_into(writer); |
| self.class_range_records.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ClassDefFormat2") |
| } |
| } |
| |
| impl Validate for ClassDefFormat2 { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ClassDefFormat2", |ctx| { |
| ctx.in_field("class_range_records", |ctx| { |
| if self.class_range_records.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.class_range_records.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ClassDefFormat2<'a>> for ClassDefFormat2 { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::ClassDefFormat2<'a>, _: FontData) -> Self { |
| let offset_data = obj.offset_data(); |
| ClassDefFormat2 { |
| class_range_records: obj.class_range_records().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ClassDefFormat2<'a>> for ClassDefFormat2 {} |
| |
| impl<'a> FontRead<'a> for ClassDefFormat2 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ClassDefFormat2 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// Used in [ClassDefFormat2] |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ClassRangeRecord { |
| /// First glyph ID in the range |
| pub start_glyph_id: GlyphId16, |
| /// Last glyph ID in the range |
| pub end_glyph_id: GlyphId16, |
| /// Applied to all glyphs in the range |
| pub class: u16, |
| } |
| |
| impl ClassRangeRecord { |
| /// Construct a new `ClassRangeRecord` |
| pub fn new(start_glyph_id: GlyphId16, end_glyph_id: GlyphId16, class: u16) -> Self { |
| Self { |
| start_glyph_id, |
| end_glyph_id, |
| class, |
| } |
| } |
| } |
| |
| impl FontWrite for ClassRangeRecord { |
| fn write_into(&self, writer: &mut TableWriter) { |
| self.start_glyph_id.write_into(writer); |
| self.end_glyph_id.write_into(writer); |
| self.class.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ClassRangeRecord") |
| } |
| } |
| |
| impl Validate for ClassRangeRecord { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ClassRangeRecord", |ctx| { |
| ctx.in_field("start_glyph_id", |ctx| { |
| self.validate_glyph_range(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl FromObjRef<read_fonts::tables::layout::ClassRangeRecord> for ClassRangeRecord { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::ClassRangeRecord, _: FontData) -> Self { |
| ClassRangeRecord { |
| start_glyph_id: obj.start_glyph_id(), |
| end_glyph_id: obj.end_glyph_id(), |
| class: obj.class(), |
| } |
| } |
| } |
| |
| /// A [Class Definition Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table) |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub enum ClassDef { |
| Format1(ClassDefFormat1), |
| Format2(ClassDefFormat2), |
| } |
| |
| impl ClassDef { |
| /// Construct a new `ClassDefFormat1` subtable |
| pub fn format_1(start_glyph_id: GlyphId16, class_value_array: Vec<u16>) -> Self { |
| Self::Format1(ClassDefFormat1::new(start_glyph_id, class_value_array)) |
| } |
| |
| /// Construct a new `ClassDefFormat2` subtable |
| pub fn format_2(class_range_records: Vec<ClassRangeRecord>) -> Self { |
| Self::Format2(ClassDefFormat2::new(class_range_records)) |
| } |
| } |
| |
| impl Default for ClassDef { |
| fn default() -> Self { |
| Self::Format1(Default::default()) |
| } |
| } |
| |
| impl FontWrite for ClassDef { |
| fn write_into(&self, writer: &mut TableWriter) { |
| match self { |
| Self::Format1(item) => item.write_into(writer), |
| Self::Format2(item) => item.write_into(writer), |
| } |
| } |
| fn table_type(&self) -> TableType { |
| match self { |
| Self::Format1(item) => item.table_type(), |
| Self::Format2(item) => item.table_type(), |
| } |
| } |
| } |
| |
| impl Validate for ClassDef { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| match self { |
| Self::Format1(item) => item.validate_impl(ctx), |
| Self::Format2(item) => item.validate_impl(ctx), |
| } |
| } |
| } |
| |
| impl FromObjRef<read_fonts::tables::layout::ClassDef<'_>> for ClassDef { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::ClassDef, _: FontData) -> Self { |
| use read_fonts::tables::layout::ClassDef as ObjRefType; |
| match obj { |
| ObjRefType::Format1(item) => ClassDef::Format1(item.to_owned_table()), |
| ObjRefType::Format2(item) => ClassDef::Format2(item.to_owned_table()), |
| } |
| } |
| } |
| |
| impl FromTableRef<read_fonts::tables::layout::ClassDef<'_>> for ClassDef {} |
| |
| impl<'a> FontRead<'a> for ClassDef { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ClassDef as FontRead>::read(data).map(|x| x.to_owned_table()) |
| } |
| } |
| |
| impl From<ClassDefFormat1> for ClassDef { |
| fn from(src: ClassDefFormat1) -> ClassDef { |
| ClassDef::Format1(src) |
| } |
| } |
| |
| impl From<ClassDefFormat2> for ClassDef { |
| fn from(src: ClassDefFormat2) -> ClassDef { |
| ClassDef::Format2(src) |
| } |
| } |
| |
| /// [Sequence Lookup Record](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-lookup-record) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct SequenceLookupRecord { |
| /// Index (zero-based) into the input glyph sequence |
| pub sequence_index: u16, |
| /// Index (zero-based) into the LookupList |
| pub lookup_list_index: u16, |
| } |
| |
| impl SequenceLookupRecord { |
| /// Construct a new `SequenceLookupRecord` |
| pub fn new(sequence_index: u16, lookup_list_index: u16) -> Self { |
| Self { |
| sequence_index, |
| lookup_list_index, |
| } |
| } |
| } |
| |
| impl FontWrite for SequenceLookupRecord { |
| fn write_into(&self, writer: &mut TableWriter) { |
| self.sequence_index.write_into(writer); |
| self.lookup_list_index.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("SequenceLookupRecord") |
| } |
| } |
| |
| impl Validate for SequenceLookupRecord { |
| fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
| } |
| |
| impl FromObjRef<read_fonts::tables::layout::SequenceLookupRecord> for SequenceLookupRecord { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::SequenceLookupRecord, _: FontData) -> Self { |
| SequenceLookupRecord { |
| sequence_index: obj.sequence_index(), |
| lookup_list_index: obj.lookup_list_index(), |
| } |
| } |
| } |
| |
| /// [Sequence Context Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-1-simple-glyph-contexts) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct SequenceContextFormat1 { |
| /// Offset to Coverage table, from beginning of |
| /// SequenceContextFormat1 table |
| pub coverage: OffsetMarker<CoverageTable>, |
| /// Array of offsets to SequenceRuleSet tables, from beginning of |
| /// SequenceContextFormat1 table (offsets may be NULL) |
| pub seq_rule_sets: Vec<NullableOffsetMarker<SequenceRuleSet>>, |
| } |
| |
| impl SequenceContextFormat1 { |
| /// Construct a new `SequenceContextFormat1` |
| pub fn new(coverage: CoverageTable, seq_rule_sets: Vec<Option<SequenceRuleSet>>) -> Self { |
| Self { |
| coverage: coverage.into(), |
| seq_rule_sets: seq_rule_sets.into_iter().map(Into::into).collect(), |
| } |
| } |
| } |
| |
| impl FontWrite for SequenceContextFormat1 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (1 as u16).write_into(writer); |
| self.coverage.write_into(writer); |
| (u16::try_from(array_len(&self.seq_rule_sets)).unwrap()).write_into(writer); |
| self.seq_rule_sets.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("SequenceContextFormat1") |
| } |
| } |
| |
| impl Validate for SequenceContextFormat1 { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("SequenceContextFormat1", |ctx| { |
| ctx.in_field("coverage", |ctx| { |
| self.coverage.validate_impl(ctx); |
| }); |
| ctx.in_field("seq_rule_sets", |ctx| { |
| if self.seq_rule_sets.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.seq_rule_sets.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::SequenceContextFormat1<'a>> |
| for SequenceContextFormat1 |
| { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::SequenceContextFormat1<'a>, |
| _: FontData, |
| ) -> Self { |
| SequenceContextFormat1 { |
| coverage: obj.coverage().to_owned_table(), |
| seq_rule_sets: obj.seq_rule_sets().to_owned_table(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::SequenceContextFormat1<'a>> |
| for SequenceContextFormat1 |
| { |
| } |
| |
| impl<'a> FontRead<'a> for SequenceContextFormat1 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::SequenceContextFormat1 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// Part of [SequenceContextFormat1] |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct SequenceRuleSet { |
| /// Array of offsets to SequenceRule tables, from beginning of the |
| /// SequenceRuleSet table |
| pub seq_rules: Vec<OffsetMarker<SequenceRule>>, |
| } |
| |
| impl SequenceRuleSet { |
| /// Construct a new `SequenceRuleSet` |
| pub fn new(seq_rules: Vec<SequenceRule>) -> Self { |
| Self { |
| seq_rules: seq_rules.into_iter().map(Into::into).collect(), |
| } |
| } |
| } |
| |
| impl FontWrite for SequenceRuleSet { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (u16::try_from(array_len(&self.seq_rules)).unwrap()).write_into(writer); |
| self.seq_rules.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("SequenceRuleSet") |
| } |
| } |
| |
| impl Validate for SequenceRuleSet { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("SequenceRuleSet", |ctx| { |
| ctx.in_field("seq_rules", |ctx| { |
| if self.seq_rules.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.seq_rules.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::SequenceRuleSet<'a>> for SequenceRuleSet { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::SequenceRuleSet<'a>, _: FontData) -> Self { |
| SequenceRuleSet { |
| seq_rules: obj.seq_rules().to_owned_table(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::SequenceRuleSet<'a>> for SequenceRuleSet {} |
| |
| impl<'a> FontRead<'a> for SequenceRuleSet { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::SequenceRuleSet as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// Part of [SequenceContextFormat1] |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct SequenceRule { |
| /// Array of input glyph IDs—starting with the second glyph |
| pub input_sequence: Vec<GlyphId16>, |
| /// Array of Sequence lookup records |
| pub seq_lookup_records: Vec<SequenceLookupRecord>, |
| } |
| |
| impl SequenceRule { |
| /// Construct a new `SequenceRule` |
| pub fn new( |
| input_sequence: Vec<GlyphId16>, |
| seq_lookup_records: Vec<SequenceLookupRecord>, |
| ) -> Self { |
| Self { |
| input_sequence, |
| seq_lookup_records, |
| } |
| } |
| } |
| |
| impl FontWrite for SequenceRule { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (u16::try_from(plus_one(&self.input_sequence.len())).unwrap()).write_into(writer); |
| (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer); |
| self.input_sequence.write_into(writer); |
| self.seq_lookup_records.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("SequenceRule") |
| } |
| } |
| |
| impl Validate for SequenceRule { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("SequenceRule", |ctx| { |
| ctx.in_field("seq_lookup_records", |ctx| { |
| if self.seq_lookup_records.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.seq_lookup_records.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::SequenceRule<'a>> for SequenceRule { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::SequenceRule<'a>, _: FontData) -> Self { |
| let offset_data = obj.offset_data(); |
| SequenceRule { |
| input_sequence: obj.input_sequence().to_owned_obj(offset_data), |
| seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::SequenceRule<'a>> for SequenceRule {} |
| |
| impl<'a> FontRead<'a> for SequenceRule { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::SequenceRule as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// [Sequence Context Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-2-class-based-glyph-contexts) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct SequenceContextFormat2 { |
| /// Offset to Coverage table, from beginning of |
| /// SequenceContextFormat2 table |
| pub coverage: OffsetMarker<CoverageTable>, |
| /// Offset to ClassDef table, from beginning of |
| /// SequenceContextFormat2 table |
| pub class_def: OffsetMarker<ClassDef>, |
| /// Array of offsets to ClassSequenceRuleSet tables, from beginning |
| /// of SequenceContextFormat2 table (may be NULL) |
| pub class_seq_rule_sets: Vec<NullableOffsetMarker<ClassSequenceRuleSet>>, |
| } |
| |
| impl SequenceContextFormat2 { |
| /// Construct a new `SequenceContextFormat2` |
| pub fn new( |
| coverage: CoverageTable, |
| class_def: ClassDef, |
| class_seq_rule_sets: Vec<Option<ClassSequenceRuleSet>>, |
| ) -> Self { |
| Self { |
| coverage: coverage.into(), |
| class_def: class_def.into(), |
| class_seq_rule_sets: class_seq_rule_sets.into_iter().map(Into::into).collect(), |
| } |
| } |
| } |
| |
| impl FontWrite for SequenceContextFormat2 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (2 as u16).write_into(writer); |
| self.coverage.write_into(writer); |
| self.class_def.write_into(writer); |
| (u16::try_from(array_len(&self.class_seq_rule_sets)).unwrap()).write_into(writer); |
| self.class_seq_rule_sets.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("SequenceContextFormat2") |
| } |
| } |
| |
| impl Validate for SequenceContextFormat2 { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("SequenceContextFormat2", |ctx| { |
| ctx.in_field("coverage", |ctx| { |
| self.coverage.validate_impl(ctx); |
| }); |
| ctx.in_field("class_def", |ctx| { |
| self.class_def.validate_impl(ctx); |
| }); |
| ctx.in_field("class_seq_rule_sets", |ctx| { |
| if self.class_seq_rule_sets.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.class_seq_rule_sets.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::SequenceContextFormat2<'a>> |
| for SequenceContextFormat2 |
| { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::SequenceContextFormat2<'a>, |
| _: FontData, |
| ) -> Self { |
| SequenceContextFormat2 { |
| coverage: obj.coverage().to_owned_table(), |
| class_def: obj.class_def().to_owned_table(), |
| class_seq_rule_sets: obj.class_seq_rule_sets().to_owned_table(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::SequenceContextFormat2<'a>> |
| for SequenceContextFormat2 |
| { |
| } |
| |
| impl<'a> FontRead<'a> for SequenceContextFormat2 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::SequenceContextFormat2 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// Part of [SequenceContextFormat2] |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ClassSequenceRuleSet { |
| /// Array of offsets to ClassSequenceRule tables, from beginning of |
| /// ClassSequenceRuleSet table |
| pub class_seq_rules: Vec<OffsetMarker<ClassSequenceRule>>, |
| } |
| |
| impl ClassSequenceRuleSet { |
| /// Construct a new `ClassSequenceRuleSet` |
| pub fn new(class_seq_rules: Vec<ClassSequenceRule>) -> Self { |
| Self { |
| class_seq_rules: class_seq_rules.into_iter().map(Into::into).collect(), |
| } |
| } |
| } |
| |
| impl FontWrite for ClassSequenceRuleSet { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (u16::try_from(array_len(&self.class_seq_rules)).unwrap()).write_into(writer); |
| self.class_seq_rules.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ClassSequenceRuleSet") |
| } |
| } |
| |
| impl Validate for ClassSequenceRuleSet { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ClassSequenceRuleSet", |ctx| { |
| ctx.in_field("class_seq_rules", |ctx| { |
| if self.class_seq_rules.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.class_seq_rules.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ClassSequenceRuleSet<'a>> for ClassSequenceRuleSet { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::ClassSequenceRuleSet<'a>, |
| _: FontData, |
| ) -> Self { |
| ClassSequenceRuleSet { |
| class_seq_rules: obj.class_seq_rules().to_owned_table(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ClassSequenceRuleSet<'a>> |
| for ClassSequenceRuleSet |
| { |
| } |
| |
| impl<'a> FontRead<'a> for ClassSequenceRuleSet { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ClassSequenceRuleSet as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// Part of [SequenceContextFormat2] |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ClassSequenceRule { |
| /// Sequence of classes to be matched to the input glyph sequence, |
| /// beginning with the second glyph position |
| pub input_sequence: Vec<u16>, |
| /// Array of SequenceLookupRecords |
| pub seq_lookup_records: Vec<SequenceLookupRecord>, |
| } |
| |
| impl ClassSequenceRule { |
| /// Construct a new `ClassSequenceRule` |
| pub fn new(input_sequence: Vec<u16>, seq_lookup_records: Vec<SequenceLookupRecord>) -> Self { |
| Self { |
| input_sequence, |
| seq_lookup_records, |
| } |
| } |
| } |
| |
| impl FontWrite for ClassSequenceRule { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (u16::try_from(plus_one(&self.input_sequence.len())).unwrap()).write_into(writer); |
| (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer); |
| self.input_sequence.write_into(writer); |
| self.seq_lookup_records.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ClassSequenceRule") |
| } |
| } |
| |
| impl Validate for ClassSequenceRule { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ClassSequenceRule", |ctx| { |
| ctx.in_field("seq_lookup_records", |ctx| { |
| if self.seq_lookup_records.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.seq_lookup_records.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ClassSequenceRule<'a>> for ClassSequenceRule { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::ClassSequenceRule<'a>, _: FontData) -> Self { |
| let offset_data = obj.offset_data(); |
| ClassSequenceRule { |
| input_sequence: obj.input_sequence().to_owned_obj(offset_data), |
| seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ClassSequenceRule<'a>> for ClassSequenceRule {} |
| |
| impl<'a> FontRead<'a> for ClassSequenceRule { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ClassSequenceRule as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// [Sequence Context Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#sequence-context-format-3-coverage-based-glyph-contexts) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct SequenceContextFormat3 { |
| /// Array of offsets to Coverage tables, from beginning of |
| /// SequenceContextFormat3 subtable |
| pub coverages: Vec<OffsetMarker<CoverageTable>>, |
| /// Array of SequenceLookupRecords |
| pub seq_lookup_records: Vec<SequenceLookupRecord>, |
| } |
| |
| impl SequenceContextFormat3 { |
| /// Construct a new `SequenceContextFormat3` |
| pub fn new( |
| coverages: Vec<CoverageTable>, |
| seq_lookup_records: Vec<SequenceLookupRecord>, |
| ) -> Self { |
| Self { |
| coverages: coverages.into_iter().map(Into::into).collect(), |
| seq_lookup_records, |
| } |
| } |
| } |
| |
| impl FontWrite for SequenceContextFormat3 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (3 as u16).write_into(writer); |
| (u16::try_from(array_len(&self.coverages)).unwrap()).write_into(writer); |
| (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer); |
| self.coverages.write_into(writer); |
| self.seq_lookup_records.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("SequenceContextFormat3") |
| } |
| } |
| |
| impl Validate for SequenceContextFormat3 { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("SequenceContextFormat3", |ctx| { |
| ctx.in_field("coverages", |ctx| { |
| if self.coverages.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.coverages.validate_impl(ctx); |
| }); |
| ctx.in_field("seq_lookup_records", |ctx| { |
| if self.seq_lookup_records.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.seq_lookup_records.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::SequenceContextFormat3<'a>> |
| for SequenceContextFormat3 |
| { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::SequenceContextFormat3<'a>, |
| _: FontData, |
| ) -> Self { |
| let offset_data = obj.offset_data(); |
| SequenceContextFormat3 { |
| coverages: obj.coverages().to_owned_table(), |
| seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::SequenceContextFormat3<'a>> |
| for SequenceContextFormat3 |
| { |
| } |
| |
| impl<'a> FontRead<'a> for SequenceContextFormat3 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::SequenceContextFormat3 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub enum SequenceContext { |
| Format1(SequenceContextFormat1), |
| Format2(SequenceContextFormat2), |
| Format3(SequenceContextFormat3), |
| } |
| |
| impl SequenceContext { |
| /// Construct a new `SequenceContextFormat1` subtable |
| pub fn format_1(coverage: CoverageTable, seq_rule_sets: Vec<Option<SequenceRuleSet>>) -> Self { |
| Self::Format1(SequenceContextFormat1::new(coverage, seq_rule_sets)) |
| } |
| |
| /// Construct a new `SequenceContextFormat2` subtable |
| pub fn format_2( |
| coverage: CoverageTable, |
| class_def: ClassDef, |
| class_seq_rule_sets: Vec<Option<ClassSequenceRuleSet>>, |
| ) -> Self { |
| Self::Format2(SequenceContextFormat2::new( |
| coverage, |
| class_def, |
| class_seq_rule_sets, |
| )) |
| } |
| |
| /// Construct a new `SequenceContextFormat3` subtable |
| pub fn format_3( |
| coverages: Vec<CoverageTable>, |
| seq_lookup_records: Vec<SequenceLookupRecord>, |
| ) -> Self { |
| Self::Format3(SequenceContextFormat3::new(coverages, seq_lookup_records)) |
| } |
| } |
| |
| impl Default for SequenceContext { |
| fn default() -> Self { |
| Self::Format1(Default::default()) |
| } |
| } |
| |
| impl FontWrite for SequenceContext { |
| fn write_into(&self, writer: &mut TableWriter) { |
| match self { |
| Self::Format1(item) => item.write_into(writer), |
| Self::Format2(item) => item.write_into(writer), |
| Self::Format3(item) => item.write_into(writer), |
| } |
| } |
| fn table_type(&self) -> TableType { |
| match self { |
| Self::Format1(item) => item.table_type(), |
| Self::Format2(item) => item.table_type(), |
| Self::Format3(item) => item.table_type(), |
| } |
| } |
| } |
| |
| impl Validate for SequenceContext { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| match self { |
| Self::Format1(item) => item.validate_impl(ctx), |
| Self::Format2(item) => item.validate_impl(ctx), |
| Self::Format3(item) => item.validate_impl(ctx), |
| } |
| } |
| } |
| |
| impl FromObjRef<read_fonts::tables::layout::SequenceContext<'_>> for SequenceContext { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::SequenceContext, _: FontData) -> Self { |
| use read_fonts::tables::layout::SequenceContext as ObjRefType; |
| match obj { |
| ObjRefType::Format1(item) => SequenceContext::Format1(item.to_owned_table()), |
| ObjRefType::Format2(item) => SequenceContext::Format2(item.to_owned_table()), |
| ObjRefType::Format3(item) => SequenceContext::Format3(item.to_owned_table()), |
| } |
| } |
| } |
| |
| impl FromTableRef<read_fonts::tables::layout::SequenceContext<'_>> for SequenceContext {} |
| |
| impl<'a> FontRead<'a> for SequenceContext { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::SequenceContext as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| impl From<SequenceContextFormat1> for SequenceContext { |
| fn from(src: SequenceContextFormat1) -> SequenceContext { |
| SequenceContext::Format1(src) |
| } |
| } |
| |
| impl From<SequenceContextFormat2> for SequenceContext { |
| fn from(src: SequenceContextFormat2) -> SequenceContext { |
| SequenceContext::Format2(src) |
| } |
| } |
| |
| impl From<SequenceContextFormat3> for SequenceContext { |
| fn from(src: SequenceContextFormat3) -> SequenceContext { |
| SequenceContext::Format3(src) |
| } |
| } |
| |
| /// [Chained Sequence Context Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-1-simple-glyph-contexts) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ChainedSequenceContextFormat1 { |
| /// Offset to Coverage table, from beginning of |
| /// ChainSequenceContextFormat1 table |
| pub coverage: OffsetMarker<CoverageTable>, |
| /// Array of offsets to ChainedSeqRuleSet tables, from beginning of |
| /// ChainedSequenceContextFormat1 table (may be NULL) |
| pub chained_seq_rule_sets: Vec<NullableOffsetMarker<ChainedSequenceRuleSet>>, |
| } |
| |
| impl ChainedSequenceContextFormat1 { |
| /// Construct a new `ChainedSequenceContextFormat1` |
| pub fn new( |
| coverage: CoverageTable, |
| chained_seq_rule_sets: Vec<Option<ChainedSequenceRuleSet>>, |
| ) -> Self { |
| Self { |
| coverage: coverage.into(), |
| chained_seq_rule_sets: chained_seq_rule_sets.into_iter().map(Into::into).collect(), |
| } |
| } |
| } |
| |
| impl FontWrite for ChainedSequenceContextFormat1 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (1 as u16).write_into(writer); |
| self.coverage.write_into(writer); |
| (u16::try_from(array_len(&self.chained_seq_rule_sets)).unwrap()).write_into(writer); |
| self.chained_seq_rule_sets.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ChainedSequenceContextFormat1") |
| } |
| } |
| |
| impl Validate for ChainedSequenceContextFormat1 { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ChainedSequenceContextFormat1", |ctx| { |
| ctx.in_field("coverage", |ctx| { |
| self.coverage.validate_impl(ctx); |
| }); |
| ctx.in_field("chained_seq_rule_sets", |ctx| { |
| if self.chained_seq_rule_sets.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.chained_seq_rule_sets.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceContextFormat1<'a>> |
| for ChainedSequenceContextFormat1 |
| { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::ChainedSequenceContextFormat1<'a>, |
| _: FontData, |
| ) -> Self { |
| ChainedSequenceContextFormat1 { |
| coverage: obj.coverage().to_owned_table(), |
| chained_seq_rule_sets: obj.chained_seq_rule_sets().to_owned_table(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceContextFormat1<'a>> |
| for ChainedSequenceContextFormat1 |
| { |
| } |
| |
| impl<'a> FontRead<'a> for ChainedSequenceContextFormat1 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ChainedSequenceContextFormat1 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// Part of [ChainedSequenceContextFormat1] |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ChainedSequenceRuleSet { |
| /// Array of offsets to ChainedSequenceRule tables, from beginning |
| /// of ChainedSequenceRuleSet table |
| pub chained_seq_rules: Vec<OffsetMarker<ChainedSequenceRule>>, |
| } |
| |
| impl ChainedSequenceRuleSet { |
| /// Construct a new `ChainedSequenceRuleSet` |
| pub fn new(chained_seq_rules: Vec<ChainedSequenceRule>) -> Self { |
| Self { |
| chained_seq_rules: chained_seq_rules.into_iter().map(Into::into).collect(), |
| } |
| } |
| } |
| |
| impl FontWrite for ChainedSequenceRuleSet { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (u16::try_from(array_len(&self.chained_seq_rules)).unwrap()).write_into(writer); |
| self.chained_seq_rules.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ChainedSequenceRuleSet") |
| } |
| } |
| |
| impl Validate for ChainedSequenceRuleSet { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ChainedSequenceRuleSet", |ctx| { |
| ctx.in_field("chained_seq_rules", |ctx| { |
| if self.chained_seq_rules.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.chained_seq_rules.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceRuleSet<'a>> |
| for ChainedSequenceRuleSet |
| { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::ChainedSequenceRuleSet<'a>, |
| _: FontData, |
| ) -> Self { |
| ChainedSequenceRuleSet { |
| chained_seq_rules: obj.chained_seq_rules().to_owned_table(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceRuleSet<'a>> |
| for ChainedSequenceRuleSet |
| { |
| } |
| |
| impl<'a> FontRead<'a> for ChainedSequenceRuleSet { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ChainedSequenceRuleSet as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// Part of [ChainedSequenceContextFormat1] |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ChainedSequenceRule { |
| /// Array of backtrack glyph IDs |
| pub backtrack_sequence: Vec<GlyphId16>, |
| /// Array of input glyph IDs—start with second glyph |
| pub input_sequence: Vec<GlyphId16>, |
| /// Array of lookahead glyph IDs |
| pub lookahead_sequence: Vec<GlyphId16>, |
| /// Array of SequenceLookupRecords |
| pub seq_lookup_records: Vec<SequenceLookupRecord>, |
| } |
| |
| impl ChainedSequenceRule { |
| /// Construct a new `ChainedSequenceRule` |
| pub fn new( |
| backtrack_sequence: Vec<GlyphId16>, |
| input_sequence: Vec<GlyphId16>, |
| lookahead_sequence: Vec<GlyphId16>, |
| seq_lookup_records: Vec<SequenceLookupRecord>, |
| ) -> Self { |
| Self { |
| backtrack_sequence, |
| input_sequence, |
| lookahead_sequence, |
| seq_lookup_records, |
| } |
| } |
| } |
| |
| impl FontWrite for ChainedSequenceRule { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (u16::try_from(array_len(&self.backtrack_sequence)).unwrap()).write_into(writer); |
| self.backtrack_sequence.write_into(writer); |
| (u16::try_from(plus_one(&self.input_sequence.len())).unwrap()).write_into(writer); |
| self.input_sequence.write_into(writer); |
| (u16::try_from(array_len(&self.lookahead_sequence)).unwrap()).write_into(writer); |
| self.lookahead_sequence.write_into(writer); |
| (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer); |
| self.seq_lookup_records.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ChainedSequenceRule") |
| } |
| } |
| |
| impl Validate for ChainedSequenceRule { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ChainedSequenceRule", |ctx| { |
| ctx.in_field("backtrack_sequence", |ctx| { |
| if self.backtrack_sequence.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| }); |
| ctx.in_field("lookahead_sequence", |ctx| { |
| if self.lookahead_sequence.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| }); |
| ctx.in_field("seq_lookup_records", |ctx| { |
| if self.seq_lookup_records.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.seq_lookup_records.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceRule<'a>> for ChainedSequenceRule { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::ChainedSequenceRule<'a>, |
| _: FontData, |
| ) -> Self { |
| let offset_data = obj.offset_data(); |
| ChainedSequenceRule { |
| backtrack_sequence: obj.backtrack_sequence().to_owned_obj(offset_data), |
| input_sequence: obj.input_sequence().to_owned_obj(offset_data), |
| lookahead_sequence: obj.lookahead_sequence().to_owned_obj(offset_data), |
| seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceRule<'a>> for ChainedSequenceRule {} |
| |
| impl<'a> FontRead<'a> for ChainedSequenceRule { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ChainedSequenceRule as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// [Chained Sequence Context Format 2](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-2-class-based-glyph-contexts) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ChainedSequenceContextFormat2 { |
| /// Offset to Coverage table, from beginning of |
| /// ChainedSequenceContextFormat2 table |
| pub coverage: OffsetMarker<CoverageTable>, |
| /// Offset to ClassDef table containing backtrack sequence context, |
| /// from beginning of ChainedSequenceContextFormat2 table |
| pub backtrack_class_def: OffsetMarker<ClassDef>, |
| /// Offset to ClassDef table containing input sequence context, |
| /// from beginning of ChainedSequenceContextFormat2 table |
| pub input_class_def: OffsetMarker<ClassDef>, |
| /// Offset to ClassDef table containing lookahead sequence context, |
| /// from beginning of ChainedSequenceContextFormat2 table |
| pub lookahead_class_def: OffsetMarker<ClassDef>, |
| /// Array of offsets to ChainedClassSequenceRuleSet tables, from |
| /// beginning of ChainedSequenceContextFormat2 table (may be NULL) |
| pub chained_class_seq_rule_sets: Vec<NullableOffsetMarker<ChainedClassSequenceRuleSet>>, |
| } |
| |
| impl ChainedSequenceContextFormat2 { |
| /// Construct a new `ChainedSequenceContextFormat2` |
| pub fn new( |
| coverage: CoverageTable, |
| backtrack_class_def: ClassDef, |
| input_class_def: ClassDef, |
| lookahead_class_def: ClassDef, |
| chained_class_seq_rule_sets: Vec<Option<ChainedClassSequenceRuleSet>>, |
| ) -> Self { |
| Self { |
| coverage: coverage.into(), |
| backtrack_class_def: backtrack_class_def.into(), |
| input_class_def: input_class_def.into(), |
| lookahead_class_def: lookahead_class_def.into(), |
| chained_class_seq_rule_sets: chained_class_seq_rule_sets |
| .into_iter() |
| .map(Into::into) |
| .collect(), |
| } |
| } |
| } |
| |
| impl FontWrite for ChainedSequenceContextFormat2 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (2 as u16).write_into(writer); |
| self.coverage.write_into(writer); |
| self.backtrack_class_def.write_into(writer); |
| self.input_class_def.write_into(writer); |
| self.lookahead_class_def.write_into(writer); |
| (u16::try_from(array_len(&self.chained_class_seq_rule_sets)).unwrap()).write_into(writer); |
| self.chained_class_seq_rule_sets.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ChainedSequenceContextFormat2") |
| } |
| } |
| |
| impl Validate for ChainedSequenceContextFormat2 { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ChainedSequenceContextFormat2", |ctx| { |
| ctx.in_field("coverage", |ctx| { |
| self.coverage.validate_impl(ctx); |
| }); |
| ctx.in_field("backtrack_class_def", |ctx| { |
| self.backtrack_class_def.validate_impl(ctx); |
| }); |
| ctx.in_field("input_class_def", |ctx| { |
| self.input_class_def.validate_impl(ctx); |
| }); |
| ctx.in_field("lookahead_class_def", |ctx| { |
| self.lookahead_class_def.validate_impl(ctx); |
| }); |
| ctx.in_field("chained_class_seq_rule_sets", |ctx| { |
| if self.chained_class_seq_rule_sets.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.chained_class_seq_rule_sets.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceContextFormat2<'a>> |
| for ChainedSequenceContextFormat2 |
| { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::ChainedSequenceContextFormat2<'a>, |
| _: FontData, |
| ) -> Self { |
| ChainedSequenceContextFormat2 { |
| coverage: obj.coverage().to_owned_table(), |
| backtrack_class_def: obj.backtrack_class_def().to_owned_table(), |
| input_class_def: obj.input_class_def().to_owned_table(), |
| lookahead_class_def: obj.lookahead_class_def().to_owned_table(), |
| chained_class_seq_rule_sets: obj.chained_class_seq_rule_sets().to_owned_table(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceContextFormat2<'a>> |
| for ChainedSequenceContextFormat2 |
| { |
| } |
| |
| impl<'a> FontRead<'a> for ChainedSequenceContextFormat2 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ChainedSequenceContextFormat2 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// Part of [ChainedSequenceContextFormat2] |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ChainedClassSequenceRuleSet { |
| /// Array of offsets to ChainedClassSequenceRule tables, from |
| /// beginning of ChainedClassSequenceRuleSet |
| pub chained_class_seq_rules: Vec<OffsetMarker<ChainedClassSequenceRule>>, |
| } |
| |
| impl ChainedClassSequenceRuleSet { |
| /// Construct a new `ChainedClassSequenceRuleSet` |
| pub fn new(chained_class_seq_rules: Vec<ChainedClassSequenceRule>) -> Self { |
| Self { |
| chained_class_seq_rules: chained_class_seq_rules |
| .into_iter() |
| .map(Into::into) |
| .collect(), |
| } |
| } |
| } |
| |
| impl FontWrite for ChainedClassSequenceRuleSet { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (u16::try_from(array_len(&self.chained_class_seq_rules)).unwrap()).write_into(writer); |
| self.chained_class_seq_rules.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ChainedClassSequenceRuleSet") |
| } |
| } |
| |
| impl Validate for ChainedClassSequenceRuleSet { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ChainedClassSequenceRuleSet", |ctx| { |
| ctx.in_field("chained_class_seq_rules", |ctx| { |
| if self.chained_class_seq_rules.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.chained_class_seq_rules.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ChainedClassSequenceRuleSet<'a>> |
| for ChainedClassSequenceRuleSet |
| { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::ChainedClassSequenceRuleSet<'a>, |
| _: FontData, |
| ) -> Self { |
| ChainedClassSequenceRuleSet { |
| chained_class_seq_rules: obj.chained_class_seq_rules().to_owned_table(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ChainedClassSequenceRuleSet<'a>> |
| for ChainedClassSequenceRuleSet |
| { |
| } |
| |
| impl<'a> FontRead<'a> for ChainedClassSequenceRuleSet { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ChainedClassSequenceRuleSet as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// Part of [ChainedSequenceContextFormat2] |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ChainedClassSequenceRule { |
| /// Array of backtrack-sequence classes |
| pub backtrack_sequence: Vec<u16>, |
| /// Array of input sequence classes, beginning with the second |
| /// glyph position |
| pub input_sequence: Vec<u16>, |
| /// Array of lookahead-sequence classes |
| pub lookahead_sequence: Vec<u16>, |
| /// Array of SequenceLookupRecords |
| pub seq_lookup_records: Vec<SequenceLookupRecord>, |
| } |
| |
| impl ChainedClassSequenceRule { |
| /// Construct a new `ChainedClassSequenceRule` |
| pub fn new( |
| backtrack_sequence: Vec<u16>, |
| input_sequence: Vec<u16>, |
| lookahead_sequence: Vec<u16>, |
| seq_lookup_records: Vec<SequenceLookupRecord>, |
| ) -> Self { |
| Self { |
| backtrack_sequence, |
| input_sequence, |
| lookahead_sequence, |
| seq_lookup_records, |
| } |
| } |
| } |
| |
| impl FontWrite for ChainedClassSequenceRule { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (u16::try_from(array_len(&self.backtrack_sequence)).unwrap()).write_into(writer); |
| self.backtrack_sequence.write_into(writer); |
| (u16::try_from(plus_one(&self.input_sequence.len())).unwrap()).write_into(writer); |
| self.input_sequence.write_into(writer); |
| (u16::try_from(array_len(&self.lookahead_sequence)).unwrap()).write_into(writer); |
| self.lookahead_sequence.write_into(writer); |
| (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer); |
| self.seq_lookup_records.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ChainedClassSequenceRule") |
| } |
| } |
| |
| impl Validate for ChainedClassSequenceRule { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ChainedClassSequenceRule", |ctx| { |
| ctx.in_field("backtrack_sequence", |ctx| { |
| if self.backtrack_sequence.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| }); |
| ctx.in_field("lookahead_sequence", |ctx| { |
| if self.lookahead_sequence.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| }); |
| ctx.in_field("seq_lookup_records", |ctx| { |
| if self.seq_lookup_records.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.seq_lookup_records.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ChainedClassSequenceRule<'a>> |
| for ChainedClassSequenceRule |
| { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::ChainedClassSequenceRule<'a>, |
| _: FontData, |
| ) -> Self { |
| let offset_data = obj.offset_data(); |
| ChainedClassSequenceRule { |
| backtrack_sequence: obj.backtrack_sequence().to_owned_obj(offset_data), |
| input_sequence: obj.input_sequence().to_owned_obj(offset_data), |
| lookahead_sequence: obj.lookahead_sequence().to_owned_obj(offset_data), |
| seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ChainedClassSequenceRule<'a>> |
| for ChainedClassSequenceRule |
| { |
| } |
| |
| impl<'a> FontRead<'a> for ChainedClassSequenceRule { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ChainedClassSequenceRule as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// [Chained Sequence Context Format 3](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#chained-sequence-context-format-3-coverage-based-glyph-contexts) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ChainedSequenceContextFormat3 { |
| /// Array of offsets to coverage tables for the backtrack sequence |
| pub backtrack_coverages: Vec<OffsetMarker<CoverageTable>>, |
| /// Array of offsets to coverage tables for the input sequence |
| pub input_coverages: Vec<OffsetMarker<CoverageTable>>, |
| /// Array of offsets to coverage tables for the lookahead sequence |
| pub lookahead_coverages: Vec<OffsetMarker<CoverageTable>>, |
| /// Array of SequenceLookupRecords |
| pub seq_lookup_records: Vec<SequenceLookupRecord>, |
| } |
| |
| impl ChainedSequenceContextFormat3 { |
| /// Construct a new `ChainedSequenceContextFormat3` |
| pub fn new( |
| backtrack_coverages: Vec<CoverageTable>, |
| input_coverages: Vec<CoverageTable>, |
| lookahead_coverages: Vec<CoverageTable>, |
| seq_lookup_records: Vec<SequenceLookupRecord>, |
| ) -> Self { |
| Self { |
| backtrack_coverages: backtrack_coverages.into_iter().map(Into::into).collect(), |
| input_coverages: input_coverages.into_iter().map(Into::into).collect(), |
| lookahead_coverages: lookahead_coverages.into_iter().map(Into::into).collect(), |
| seq_lookup_records, |
| } |
| } |
| } |
| |
| impl FontWrite for ChainedSequenceContextFormat3 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (3 as u16).write_into(writer); |
| (u16::try_from(array_len(&self.backtrack_coverages)).unwrap()).write_into(writer); |
| self.backtrack_coverages.write_into(writer); |
| (u16::try_from(array_len(&self.input_coverages)).unwrap()).write_into(writer); |
| self.input_coverages.write_into(writer); |
| (u16::try_from(array_len(&self.lookahead_coverages)).unwrap()).write_into(writer); |
| self.lookahead_coverages.write_into(writer); |
| (u16::try_from(array_len(&self.seq_lookup_records)).unwrap()).write_into(writer); |
| self.seq_lookup_records.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ChainedSequenceContextFormat3") |
| } |
| } |
| |
| impl Validate for ChainedSequenceContextFormat3 { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ChainedSequenceContextFormat3", |ctx| { |
| ctx.in_field("backtrack_coverages", |ctx| { |
| if self.backtrack_coverages.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.backtrack_coverages.validate_impl(ctx); |
| }); |
| ctx.in_field("input_coverages", |ctx| { |
| if self.input_coverages.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.input_coverages.validate_impl(ctx); |
| }); |
| ctx.in_field("lookahead_coverages", |ctx| { |
| if self.lookahead_coverages.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.lookahead_coverages.validate_impl(ctx); |
| }); |
| ctx.in_field("seq_lookup_records", |ctx| { |
| if self.seq_lookup_records.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.seq_lookup_records.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ChainedSequenceContextFormat3<'a>> |
| for ChainedSequenceContextFormat3 |
| { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::ChainedSequenceContextFormat3<'a>, |
| _: FontData, |
| ) -> Self { |
| let offset_data = obj.offset_data(); |
| ChainedSequenceContextFormat3 { |
| backtrack_coverages: obj.backtrack_coverages().to_owned_table(), |
| input_coverages: obj.input_coverages().to_owned_table(), |
| lookahead_coverages: obj.lookahead_coverages().to_owned_table(), |
| seq_lookup_records: obj.seq_lookup_records().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ChainedSequenceContextFormat3<'a>> |
| for ChainedSequenceContextFormat3 |
| { |
| } |
| |
| impl<'a> FontRead<'a> for ChainedSequenceContextFormat3 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ChainedSequenceContextFormat3 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub enum ChainedSequenceContext { |
| Format1(ChainedSequenceContextFormat1), |
| Format2(ChainedSequenceContextFormat2), |
| Format3(ChainedSequenceContextFormat3), |
| } |
| |
| impl ChainedSequenceContext { |
| /// Construct a new `ChainedSequenceContextFormat1` subtable |
| pub fn format_1( |
| coverage: CoverageTable, |
| chained_seq_rule_sets: Vec<Option<ChainedSequenceRuleSet>>, |
| ) -> Self { |
| Self::Format1(ChainedSequenceContextFormat1::new( |
| coverage, |
| chained_seq_rule_sets, |
| )) |
| } |
| |
| /// Construct a new `ChainedSequenceContextFormat2` subtable |
| pub fn format_2( |
| coverage: CoverageTable, |
| backtrack_class_def: ClassDef, |
| input_class_def: ClassDef, |
| lookahead_class_def: ClassDef, |
| chained_class_seq_rule_sets: Vec<Option<ChainedClassSequenceRuleSet>>, |
| ) -> Self { |
| Self::Format2(ChainedSequenceContextFormat2::new( |
| coverage, |
| backtrack_class_def, |
| input_class_def, |
| lookahead_class_def, |
| chained_class_seq_rule_sets, |
| )) |
| } |
| |
| /// Construct a new `ChainedSequenceContextFormat3` subtable |
| pub fn format_3( |
| backtrack_coverages: Vec<CoverageTable>, |
| input_coverages: Vec<CoverageTable>, |
| lookahead_coverages: Vec<CoverageTable>, |
| seq_lookup_records: Vec<SequenceLookupRecord>, |
| ) -> Self { |
| Self::Format3(ChainedSequenceContextFormat3::new( |
| backtrack_coverages, |
| input_coverages, |
| lookahead_coverages, |
| seq_lookup_records, |
| )) |
| } |
| } |
| |
| impl Default for ChainedSequenceContext { |
| fn default() -> Self { |
| Self::Format1(Default::default()) |
| } |
| } |
| |
| impl FontWrite for ChainedSequenceContext { |
| fn write_into(&self, writer: &mut TableWriter) { |
| match self { |
| Self::Format1(item) => item.write_into(writer), |
| Self::Format2(item) => item.write_into(writer), |
| Self::Format3(item) => item.write_into(writer), |
| } |
| } |
| fn table_type(&self) -> TableType { |
| match self { |
| Self::Format1(item) => item.table_type(), |
| Self::Format2(item) => item.table_type(), |
| Self::Format3(item) => item.table_type(), |
| } |
| } |
| } |
| |
| impl Validate for ChainedSequenceContext { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| match self { |
| Self::Format1(item) => item.validate_impl(ctx), |
| Self::Format2(item) => item.validate_impl(ctx), |
| Self::Format3(item) => item.validate_impl(ctx), |
| } |
| } |
| } |
| |
| impl FromObjRef<read_fonts::tables::layout::ChainedSequenceContext<'_>> for ChainedSequenceContext { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::ChainedSequenceContext, _: FontData) -> Self { |
| use read_fonts::tables::layout::ChainedSequenceContext as ObjRefType; |
| match obj { |
| ObjRefType::Format1(item) => ChainedSequenceContext::Format1(item.to_owned_table()), |
| ObjRefType::Format2(item) => ChainedSequenceContext::Format2(item.to_owned_table()), |
| ObjRefType::Format3(item) => ChainedSequenceContext::Format3(item.to_owned_table()), |
| } |
| } |
| } |
| |
| impl FromTableRef<read_fonts::tables::layout::ChainedSequenceContext<'_>> |
| for ChainedSequenceContext |
| { |
| } |
| |
| impl<'a> FontRead<'a> for ChainedSequenceContext { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ChainedSequenceContext as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| impl From<ChainedSequenceContextFormat1> for ChainedSequenceContext { |
| fn from(src: ChainedSequenceContextFormat1) -> ChainedSequenceContext { |
| ChainedSequenceContext::Format1(src) |
| } |
| } |
| |
| impl From<ChainedSequenceContextFormat2> for ChainedSequenceContext { |
| fn from(src: ChainedSequenceContextFormat2) -> ChainedSequenceContext { |
| ChainedSequenceContext::Format2(src) |
| } |
| } |
| |
| impl From<ChainedSequenceContextFormat3> for ChainedSequenceContext { |
| fn from(src: ChainedSequenceContextFormat3) -> ChainedSequenceContext { |
| ChainedSequenceContext::Format3(src) |
| } |
| } |
| |
| impl FontWrite for DeltaFormat { |
| fn write_into(&self, writer: &mut TableWriter) { |
| let val = *self as u16; |
| writer.write_slice(&val.to_be_bytes()) |
| } |
| } |
| |
| /// [Device Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#device-and-variationindex-tables) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct Device { |
| /// Smallest size to correct, in ppem |
| pub start_size: u16, |
| /// Largest size to correct, in ppem |
| pub end_size: u16, |
| /// Format of deltaValue array data: 0x0001, 0x0002, or 0x0003 |
| pub delta_format: DeltaFormat, |
| /// Array of compressed data |
| pub delta_value: Vec<u16>, |
| } |
| |
| impl FontWrite for Device { |
| fn write_into(&self, writer: &mut TableWriter) { |
| self.start_size.write_into(writer); |
| self.end_size.write_into(writer); |
| self.delta_format.write_into(writer); |
| self.delta_value.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("Device") |
| } |
| } |
| |
| impl Validate for Device { |
| fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::Device<'a>> for Device { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::Device<'a>, _: FontData) -> Self { |
| let offset_data = obj.offset_data(); |
| Device { |
| start_size: obj.start_size(), |
| end_size: obj.end_size(), |
| delta_format: obj.delta_format(), |
| delta_value: obj.delta_value().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::Device<'a>> for Device {} |
| |
| impl<'a> FontRead<'a> for Device { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::Device as FontRead>::read(data).map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// Variation index table |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct VariationIndex { |
| /// A delta-set outer index — used to select an item variation |
| /// data subtable within the item variation store. |
| pub delta_set_outer_index: u16, |
| /// A delta-set inner index — used to select a delta-set row |
| /// within an item variation data subtable. |
| pub delta_set_inner_index: u16, |
| } |
| |
| impl VariationIndex { |
| /// Construct a new `VariationIndex` |
| pub fn new(delta_set_outer_index: u16, delta_set_inner_index: u16) -> Self { |
| Self { |
| delta_set_outer_index, |
| delta_set_inner_index, |
| } |
| } |
| } |
| |
| impl FontWrite for VariationIndex { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| self.delta_set_outer_index.write_into(writer); |
| self.delta_set_inner_index.write_into(writer); |
| (DeltaFormat::VariationIndex as DeltaFormat).write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("VariationIndex") |
| } |
| } |
| |
| impl Validate for VariationIndex { |
| fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::VariationIndex<'a>> for VariationIndex { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::VariationIndex<'a>, _: FontData) -> Self { |
| VariationIndex { |
| delta_set_outer_index: obj.delta_set_outer_index(), |
| delta_set_inner_index: obj.delta_set_inner_index(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::VariationIndex<'a>> for VariationIndex {} |
| |
| impl<'a> FontRead<'a> for VariationIndex { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::VariationIndex as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// A type representing a temporary identifier for a set of variation deltas. |
| /// |
| /// The final indices used in the VariationIndex table are not known until |
| /// all deltas have been collected. This variant is used to assign a |
| /// temporary identifier during compilation. |
| /// |
| /// This type is not part of the spec and will never appear in an actual font file. |
| /// It is intended to serve as a sentinel value, and will panic when written, |
| /// ensuring that all VariationIndex tables have been correctly mapped before |
| /// the font is compiled. |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct PendingVariationIndex { |
| /// A unique identifier for a given set of deltas. |
| pub delta_set_id: u32, |
| } |
| |
| impl PendingVariationIndex { |
| /// Construct a new `PendingVariationIndex` |
| pub fn new(delta_set_id: u32) -> Self { |
| Self { delta_set_id } |
| } |
| } |
| |
| impl Validate for PendingVariationIndex { |
| fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
| } |
| |
| /// Either a [Device] table (in a non-variable font) or a [VariationIndex] table (in a variable font) |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub enum DeviceOrVariationIndex { |
| Device(Device), |
| VariationIndex(VariationIndex), |
| PendingVariationIndex(PendingVariationIndex), |
| } |
| |
| impl DeviceOrVariationIndex { |
| /// Construct a new `VariationIndex` subtable |
| pub fn variation_index(delta_set_outer_index: u16, delta_set_inner_index: u16) -> Self { |
| Self::VariationIndex(VariationIndex::new( |
| delta_set_outer_index, |
| delta_set_inner_index, |
| )) |
| } |
| |
| /// Construct a new `PendingVariationIndex` subtable |
| pub fn pending_variation_index(delta_set_id: u32) -> Self { |
| Self::PendingVariationIndex(PendingVariationIndex::new(delta_set_id)) |
| } |
| } |
| |
| impl Default for DeviceOrVariationIndex { |
| fn default() -> Self { |
| Self::Device(Default::default()) |
| } |
| } |
| |
| impl FontWrite for DeviceOrVariationIndex { |
| fn write_into(&self, writer: &mut TableWriter) { |
| match self { |
| Self::Device(item) => item.write_into(writer), |
| Self::VariationIndex(item) => item.write_into(writer), |
| Self::PendingVariationIndex(item) => item.write_into(writer), |
| } |
| } |
| fn table_type(&self) -> TableType { |
| match self { |
| Self::Device(item) => item.table_type(), |
| Self::VariationIndex(item) => item.table_type(), |
| Self::PendingVariationIndex(item) => item.table_type(), |
| } |
| } |
| } |
| |
| impl Validate for DeviceOrVariationIndex { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| match self { |
| Self::Device(item) => item.validate_impl(ctx), |
| Self::VariationIndex(item) => item.validate_impl(ctx), |
| Self::PendingVariationIndex(item) => item.validate_impl(ctx), |
| } |
| } |
| } |
| |
| impl FromObjRef<read_fonts::tables::layout::DeviceOrVariationIndex<'_>> for DeviceOrVariationIndex { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::DeviceOrVariationIndex, _: FontData) -> Self { |
| use read_fonts::tables::layout::DeviceOrVariationIndex as ObjRefType; |
| match obj { |
| ObjRefType::Device(item) => DeviceOrVariationIndex::Device(item.to_owned_table()), |
| ObjRefType::VariationIndex(item) => { |
| DeviceOrVariationIndex::VariationIndex(item.to_owned_table()) |
| } |
| } |
| } |
| } |
| |
| impl FromTableRef<read_fonts::tables::layout::DeviceOrVariationIndex<'_>> |
| for DeviceOrVariationIndex |
| { |
| } |
| |
| impl<'a> FontRead<'a> for DeviceOrVariationIndex { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::DeviceOrVariationIndex as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| impl From<Device> for DeviceOrVariationIndex { |
| fn from(src: Device) -> DeviceOrVariationIndex { |
| DeviceOrVariationIndex::Device(src) |
| } |
| } |
| |
| impl From<VariationIndex> for DeviceOrVariationIndex { |
| fn from(src: VariationIndex) -> DeviceOrVariationIndex { |
| DeviceOrVariationIndex::VariationIndex(src) |
| } |
| } |
| |
| impl From<PendingVariationIndex> for DeviceOrVariationIndex { |
| fn from(src: PendingVariationIndex) -> DeviceOrVariationIndex { |
| DeviceOrVariationIndex::PendingVariationIndex(src) |
| } |
| } |
| |
| /// [FeatureVariations Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#featurevariations-table) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct FeatureVariations { |
| /// Array of feature variation records. |
| pub feature_variation_records: Vec<FeatureVariationRecord>, |
| } |
| |
| impl FeatureVariations { |
| /// Construct a new `FeatureVariations` |
| pub fn new(feature_variation_records: Vec<FeatureVariationRecord>) -> Self { |
| Self { |
| feature_variation_records, |
| } |
| } |
| } |
| |
| impl FontWrite for FeatureVariations { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (MajorMinor::VERSION_1_0 as MajorMinor).write_into(writer); |
| (u32::try_from(array_len(&self.feature_variation_records)).unwrap()).write_into(writer); |
| self.feature_variation_records.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("FeatureVariations") |
| } |
| } |
| |
| impl Validate for FeatureVariations { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("FeatureVariations", |ctx| { |
| ctx.in_field("feature_variation_records", |ctx| { |
| if self.feature_variation_records.len() > (u32::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.feature_variation_records.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::FeatureVariations<'a>> for FeatureVariations { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::FeatureVariations<'a>, _: FontData) -> Self { |
| let offset_data = obj.offset_data(); |
| FeatureVariations { |
| feature_variation_records: obj.feature_variation_records().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::FeatureVariations<'a>> for FeatureVariations {} |
| |
| impl<'a> FontRead<'a> for FeatureVariations { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::FeatureVariations as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// Part of [FeatureVariations] |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct FeatureVariationRecord { |
| /// Offset to a condition set table, from beginning of |
| /// FeatureVariations table. |
| pub condition_set: NullableOffsetMarker<ConditionSet, WIDTH_32>, |
| /// Offset to a feature table substitution table, from beginning of |
| /// the FeatureVariations table. |
| pub feature_table_substitution: NullableOffsetMarker<FeatureTableSubstitution, WIDTH_32>, |
| } |
| |
| impl FeatureVariationRecord { |
| /// Construct a new `FeatureVariationRecord` |
| pub fn new( |
| condition_set: Option<ConditionSet>, |
| feature_table_substitution: Option<FeatureTableSubstitution>, |
| ) -> Self { |
| Self { |
| condition_set: condition_set.into(), |
| feature_table_substitution: feature_table_substitution.into(), |
| } |
| } |
| } |
| |
| impl FontWrite for FeatureVariationRecord { |
| fn write_into(&self, writer: &mut TableWriter) { |
| self.condition_set.write_into(writer); |
| self.feature_table_substitution.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("FeatureVariationRecord") |
| } |
| } |
| |
| impl Validate for FeatureVariationRecord { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("FeatureVariationRecord", |ctx| { |
| ctx.in_field("condition_set", |ctx| { |
| self.condition_set.validate_impl(ctx); |
| }); |
| ctx.in_field("feature_table_substitution", |ctx| { |
| self.feature_table_substitution.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl FromObjRef<read_fonts::tables::layout::FeatureVariationRecord> for FeatureVariationRecord { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::FeatureVariationRecord, |
| offset_data: FontData, |
| ) -> Self { |
| FeatureVariationRecord { |
| condition_set: obj.condition_set(offset_data).to_owned_table(), |
| feature_table_substitution: obj |
| .feature_table_substitution(offset_data) |
| .to_owned_table(), |
| } |
| } |
| } |
| |
| /// [ConditionSet Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#conditionset-table) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ConditionSet { |
| /// Array of offsets to condition tables, from beginning of the |
| /// ConditionSet table. |
| pub conditions: Vec<OffsetMarker<Condition, WIDTH_32>>, |
| } |
| |
| impl ConditionSet { |
| /// Construct a new `ConditionSet` |
| pub fn new(conditions: Vec<Condition>) -> Self { |
| Self { |
| conditions: conditions.into_iter().map(Into::into).collect(), |
| } |
| } |
| } |
| |
| impl FontWrite for ConditionSet { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (u16::try_from(array_len(&self.conditions)).unwrap()).write_into(writer); |
| self.conditions.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ConditionSet") |
| } |
| } |
| |
| impl Validate for ConditionSet { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ConditionSet", |ctx| { |
| ctx.in_field("conditions", |ctx| { |
| if self.conditions.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.conditions.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ConditionSet<'a>> for ConditionSet { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionSet<'a>, _: FontData) -> Self { |
| ConditionSet { |
| conditions: obj.conditions().to_owned_table(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ConditionSet<'a>> for ConditionSet {} |
| |
| impl<'a> FontRead<'a> for ConditionSet { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ConditionSet as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// [Condition Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#condition-table) |
| /// |
| /// Formats 2..5 are implementations of specification changes currently under debate at ISO for an OFF |
| /// update. For the time being the specification is <https://github.com/harfbuzz/boring-expansion-spec/blob/main/ConditionTree.md>. |
| #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub enum Condition { |
| Format1AxisRange(ConditionFormat1), |
| Format2VariableValue(ConditionFormat2), |
| Format3And(ConditionFormat3), |
| Format4Or(ConditionFormat4), |
| Format5Negate(ConditionFormat5), |
| } |
| |
| impl Condition { |
| /// Construct a new `ConditionFormat1` subtable |
| pub fn format_1_axis_range( |
| axis_index: u16, |
| filter_range_min_value: F2Dot14, |
| filter_range_max_value: F2Dot14, |
| ) -> Self { |
| Self::Format1AxisRange(ConditionFormat1::new( |
| axis_index, |
| filter_range_min_value, |
| filter_range_max_value, |
| )) |
| } |
| |
| /// Construct a new `ConditionFormat2` subtable |
| pub fn format_2_variable_value(default_value: i16, var_index: u32) -> Self { |
| Self::Format2VariableValue(ConditionFormat2::new(default_value, var_index)) |
| } |
| |
| /// Construct a new `ConditionFormat3` subtable |
| pub fn format_3_and(condition_count: u8, conditions: Vec<Condition>) -> Self { |
| Self::Format3And(ConditionFormat3::new(condition_count, conditions)) |
| } |
| |
| /// Construct a new `ConditionFormat4` subtable |
| pub fn format_4_or(condition_count: u8, conditions: Vec<Condition>) -> Self { |
| Self::Format4Or(ConditionFormat4::new(condition_count, conditions)) |
| } |
| |
| /// Construct a new `ConditionFormat5` subtable |
| pub fn format_5_negate(condition: Condition) -> Self { |
| Self::Format5Negate(ConditionFormat5::new(condition)) |
| } |
| } |
| |
| impl Default for Condition { |
| fn default() -> Self { |
| Self::Format1AxisRange(Default::default()) |
| } |
| } |
| |
| impl FontWrite for Condition { |
| fn write_into(&self, writer: &mut TableWriter) { |
| match self { |
| Self::Format1AxisRange(item) => item.write_into(writer), |
| Self::Format2VariableValue(item) => item.write_into(writer), |
| Self::Format3And(item) => item.write_into(writer), |
| Self::Format4Or(item) => item.write_into(writer), |
| Self::Format5Negate(item) => item.write_into(writer), |
| } |
| } |
| fn table_type(&self) -> TableType { |
| match self { |
| Self::Format1AxisRange(item) => item.table_type(), |
| Self::Format2VariableValue(item) => item.table_type(), |
| Self::Format3And(item) => item.table_type(), |
| Self::Format4Or(item) => item.table_type(), |
| Self::Format5Negate(item) => item.table_type(), |
| } |
| } |
| } |
| |
| impl Validate for Condition { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| match self { |
| Self::Format1AxisRange(item) => item.validate_impl(ctx), |
| Self::Format2VariableValue(item) => item.validate_impl(ctx), |
| Self::Format3And(item) => item.validate_impl(ctx), |
| Self::Format4Or(item) => item.validate_impl(ctx), |
| Self::Format5Negate(item) => item.validate_impl(ctx), |
| } |
| } |
| } |
| |
| impl FromObjRef<read_fonts::tables::layout::Condition<'_>> for Condition { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::Condition, _: FontData) -> Self { |
| use read_fonts::tables::layout::Condition as ObjRefType; |
| match obj { |
| ObjRefType::Format1AxisRange(item) => { |
| Condition::Format1AxisRange(item.to_owned_table()) |
| } |
| ObjRefType::Format2VariableValue(item) => { |
| Condition::Format2VariableValue(item.to_owned_table()) |
| } |
| ObjRefType::Format3And(item) => Condition::Format3And(item.to_owned_table()), |
| ObjRefType::Format4Or(item) => Condition::Format4Or(item.to_owned_table()), |
| ObjRefType::Format5Negate(item) => Condition::Format5Negate(item.to_owned_table()), |
| } |
| } |
| } |
| |
| impl FromTableRef<read_fonts::tables::layout::Condition<'_>> for Condition {} |
| |
| impl<'a> FontRead<'a> for Condition { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::Condition as FontRead>::read(data).map(|x| x.to_owned_table()) |
| } |
| } |
| |
| impl From<ConditionFormat1> for Condition { |
| fn from(src: ConditionFormat1) -> Condition { |
| Condition::Format1AxisRange(src) |
| } |
| } |
| |
| impl From<ConditionFormat2> for Condition { |
| fn from(src: ConditionFormat2) -> Condition { |
| Condition::Format2VariableValue(src) |
| } |
| } |
| |
| impl From<ConditionFormat3> for Condition { |
| fn from(src: ConditionFormat3) -> Condition { |
| Condition::Format3And(src) |
| } |
| } |
| |
| impl From<ConditionFormat4> for Condition { |
| fn from(src: ConditionFormat4) -> Condition { |
| Condition::Format4Or(src) |
| } |
| } |
| |
| impl From<ConditionFormat5> for Condition { |
| fn from(src: ConditionFormat5) -> Condition { |
| Condition::Format5Negate(src) |
| } |
| } |
| |
| /// [Condition Table Format 1](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#condition-table-format-1-font-variation-axis-range): Font Variation Axis Range |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ConditionFormat1 { |
| /// Index (zero-based) for the variation axis within the 'fvar' |
| /// table. |
| pub axis_index: u16, |
| /// Minimum value of the font variation instances that satisfy this |
| /// condition. |
| pub filter_range_min_value: F2Dot14, |
| /// Maximum value of the font variation instances that satisfy this |
| /// condition. |
| pub filter_range_max_value: F2Dot14, |
| } |
| |
| impl ConditionFormat1 { |
| /// Construct a new `ConditionFormat1` |
| pub fn new( |
| axis_index: u16, |
| filter_range_min_value: F2Dot14, |
| filter_range_max_value: F2Dot14, |
| ) -> Self { |
| Self { |
| axis_index, |
| filter_range_min_value, |
| filter_range_max_value, |
| } |
| } |
| } |
| |
| impl FontWrite for ConditionFormat1 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (1 as u16).write_into(writer); |
| self.axis_index.write_into(writer); |
| self.filter_range_min_value.write_into(writer); |
| self.filter_range_max_value.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ConditionFormat1") |
| } |
| } |
| |
| impl Validate for ConditionFormat1 { |
| fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat1<'a>> for ConditionFormat1 { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat1<'a>, _: FontData) -> Self { |
| ConditionFormat1 { |
| axis_index: obj.axis_index(), |
| filter_range_min_value: obj.filter_range_min_value(), |
| filter_range_max_value: obj.filter_range_max_value(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat1<'a>> for ConditionFormat1 {} |
| |
| impl<'a> FontRead<'a> for ConditionFormat1 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ConditionFormat1 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// [Condition Table Format 2](https://github.com/fonttools/fonttools/blob/5e6b12d12fa08abafbeb7570f47707fbedf69a45/Lib/fontTools/ttLib/tables/otData.py#L3237-L3255): Variation index |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ConditionFormat2 { |
| /// Value at default instance. |
| pub default_value: i16, |
| /// Variation index to vary the value based on current designspace location. |
| pub var_index: u32, |
| } |
| |
| impl ConditionFormat2 { |
| /// Construct a new `ConditionFormat2` |
| pub fn new(default_value: i16, var_index: u32) -> Self { |
| Self { |
| default_value, |
| var_index, |
| } |
| } |
| } |
| |
| impl FontWrite for ConditionFormat2 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (2 as u16).write_into(writer); |
| self.default_value.write_into(writer); |
| self.var_index.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ConditionFormat2") |
| } |
| } |
| |
| impl Validate for ConditionFormat2 { |
| fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat2<'a>> for ConditionFormat2 { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat2<'a>, _: FontData) -> Self { |
| ConditionFormat2 { |
| default_value: obj.default_value(), |
| var_index: obj.var_index(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat2<'a>> for ConditionFormat2 {} |
| |
| impl<'a> FontRead<'a> for ConditionFormat2 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ConditionFormat2 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// [Condition Table Format 3](https://github.com/fonttools/fonttools/blob/5e6b12d12fa08abafbeb7570f47707fbedf69a45/Lib/fontTools/ttLib/tables/otData.py#L3257-L3275): AND |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ConditionFormat3 { |
| /// Number of conditions. |
| pub condition_count: u8, |
| /// Array of condition tables for this conjunction (AND) expression. |
| pub conditions: Vec<OffsetMarker<Condition, WIDTH_24>>, |
| } |
| |
| impl ConditionFormat3 { |
| /// Construct a new `ConditionFormat3` |
| pub fn new(condition_count: u8, conditions: Vec<Condition>) -> Self { |
| Self { |
| condition_count, |
| conditions: conditions.into_iter().map(Into::into).collect(), |
| } |
| } |
| } |
| |
| impl FontWrite for ConditionFormat3 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (3 as u16).write_into(writer); |
| self.condition_count.write_into(writer); |
| self.conditions.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ConditionFormat3") |
| } |
| } |
| |
| impl Validate for ConditionFormat3 { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ConditionFormat3", |ctx| { |
| ctx.in_field("conditions", |ctx| { |
| if self.conditions.len() > (u8::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.conditions.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat3<'a>> for ConditionFormat3 { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat3<'a>, _: FontData) -> Self { |
| ConditionFormat3 { |
| condition_count: obj.condition_count(), |
| conditions: obj.conditions().to_owned_table(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat3<'a>> for ConditionFormat3 {} |
| |
| impl<'a> FontRead<'a> for ConditionFormat3 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ConditionFormat3 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// [Condition Table Format 4](https://github.com/fonttools/fonttools/blob/5e6b12d12fa08abafbeb7570f47707fbedf69a45/Lib/fontTools/ttLib/tables/otData.py#L3276-L3295): OR |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ConditionFormat4 { |
| /// Number of conditions. |
| pub condition_count: u8, |
| /// Array of condition tables for this disjunction (OR) expression. |
| pub conditions: Vec<OffsetMarker<Condition, WIDTH_24>>, |
| } |
| |
| impl ConditionFormat4 { |
| /// Construct a new `ConditionFormat4` |
| pub fn new(condition_count: u8, conditions: Vec<Condition>) -> Self { |
| Self { |
| condition_count, |
| conditions: conditions.into_iter().map(Into::into).collect(), |
| } |
| } |
| } |
| |
| impl FontWrite for ConditionFormat4 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (4 as u16).write_into(writer); |
| self.condition_count.write_into(writer); |
| self.conditions.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ConditionFormat4") |
| } |
| } |
| |
| impl Validate for ConditionFormat4 { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ConditionFormat4", |ctx| { |
| ctx.in_field("conditions", |ctx| { |
| if self.conditions.len() > (u8::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.conditions.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat4<'a>> for ConditionFormat4 { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat4<'a>, _: FontData) -> Self { |
| ConditionFormat4 { |
| condition_count: obj.condition_count(), |
| conditions: obj.conditions().to_owned_table(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat4<'a>> for ConditionFormat4 {} |
| |
| impl<'a> FontRead<'a> for ConditionFormat4 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ConditionFormat4 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// [Condition Table Format 5](https://github.com/fonttools/fonttools/blob/5e6b12d12fa08abafbeb7570f47707fbedf69a45/Lib/fontTools/ttLib/tables/otData.py#L3296-L3308): NOT |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct ConditionFormat5 { |
| /// Condition to negate. |
| pub condition: OffsetMarker<Condition, WIDTH_24>, |
| } |
| |
| impl ConditionFormat5 { |
| /// Construct a new `ConditionFormat5` |
| pub fn new(condition: Condition) -> Self { |
| Self { |
| condition: condition.into(), |
| } |
| } |
| } |
| |
| impl FontWrite for ConditionFormat5 { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (5 as u16).write_into(writer); |
| self.condition.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("ConditionFormat5") |
| } |
| } |
| |
| impl Validate for ConditionFormat5 { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("ConditionFormat5", |ctx| { |
| ctx.in_field("condition", |ctx| { |
| self.condition.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::ConditionFormat5<'a>> for ConditionFormat5 { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::ConditionFormat5<'a>, _: FontData) -> Self { |
| ConditionFormat5 { |
| condition: obj.condition().to_owned_table(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::ConditionFormat5<'a>> for ConditionFormat5 {} |
| |
| impl<'a> FontRead<'a> for ConditionFormat5 { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::ConditionFormat5 as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// [FeatureTableSubstitution Table](https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#featuretablesubstitution-table) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct FeatureTableSubstitution { |
| /// Array of feature table substitution records. |
| pub substitutions: Vec<FeatureTableSubstitutionRecord>, |
| } |
| |
| impl FeatureTableSubstitution { |
| /// Construct a new `FeatureTableSubstitution` |
| pub fn new(substitutions: Vec<FeatureTableSubstitutionRecord>) -> Self { |
| Self { substitutions } |
| } |
| } |
| |
| impl FontWrite for FeatureTableSubstitution { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (MajorMinor::VERSION_1_0 as MajorMinor).write_into(writer); |
| (u16::try_from(array_len(&self.substitutions)).unwrap()).write_into(writer); |
| self.substitutions.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("FeatureTableSubstitution") |
| } |
| } |
| |
| impl Validate for FeatureTableSubstitution { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("FeatureTableSubstitution", |ctx| { |
| ctx.in_field("substitutions", |ctx| { |
| if self.substitutions.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| self.substitutions.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::FeatureTableSubstitution<'a>> |
| for FeatureTableSubstitution |
| { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::FeatureTableSubstitution<'a>, |
| _: FontData, |
| ) -> Self { |
| let offset_data = obj.offset_data(); |
| FeatureTableSubstitution { |
| substitutions: obj.substitutions().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::FeatureTableSubstitution<'a>> |
| for FeatureTableSubstitution |
| { |
| } |
| |
| impl<'a> FontRead<'a> for FeatureTableSubstitution { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::FeatureTableSubstitution as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// Used in [FeatureTableSubstitution] |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct FeatureTableSubstitutionRecord { |
| /// The feature table index to match. |
| pub feature_index: u16, |
| /// Offset to an alternate feature table, from start of the |
| /// FeatureTableSubstitution table. |
| pub alternate_feature: OffsetMarker<Feature, WIDTH_32>, |
| } |
| |
| impl FeatureTableSubstitutionRecord { |
| /// Construct a new `FeatureTableSubstitutionRecord` |
| pub fn new(feature_index: u16, alternate_feature: Feature) -> Self { |
| Self { |
| feature_index, |
| alternate_feature: alternate_feature.into(), |
| } |
| } |
| } |
| |
| impl FontWrite for FeatureTableSubstitutionRecord { |
| fn write_into(&self, writer: &mut TableWriter) { |
| self.feature_index.write_into(writer); |
| self.alternate_feature.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("FeatureTableSubstitutionRecord") |
| } |
| } |
| |
| impl Validate for FeatureTableSubstitutionRecord { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("FeatureTableSubstitutionRecord", |ctx| { |
| ctx.in_field("alternate_feature", |ctx| { |
| self.alternate_feature.validate_impl(ctx); |
| }); |
| }) |
| } |
| } |
| |
| impl FromObjRef<read_fonts::tables::layout::FeatureTableSubstitutionRecord> |
| for FeatureTableSubstitutionRecord |
| { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::FeatureTableSubstitutionRecord, |
| offset_data: FontData, |
| ) -> Self { |
| FeatureTableSubstitutionRecord { |
| feature_index: obj.feature_index(), |
| alternate_feature: obj.alternate_feature(offset_data).to_owned_table(), |
| } |
| } |
| } |
| |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct SizeParams { |
| /// The first value represents the design size in 720/inch units (decipoints). |
| /// |
| /// The design size entry must be non-zero. When there is a design size but |
| /// no recommended size range, the rest of the array will consist of zeros. |
| pub design_size: u16, |
| /// The second value has no independent meaning, but serves as an identifier that associates fonts in a subfamily. |
| /// |
| /// All fonts which share a Typographic or Font Family name and which differ |
| /// only by size range shall have the same subfamily value, and no fonts |
| /// which differ in weight or style shall have the same subfamily value. |
| /// If this value is zero, the remaining fields in the array will be ignored. |
| pub identifier: u16, |
| /// The third value enables applications to use a single name for the subfamily identified by the second value. |
| /// |
| /// If the preceding value is non-zero, this value must be set in the range |
| /// 256 – 32767 (inclusive). It records the value of a field in the 'name' |
| /// table, which must contain English-language strings encoded in Windows |
| /// Unicode and Macintosh Roman, and may contain additional strings localized |
| /// to other scripts and languages. Each of these strings is the name |
| /// an application should use, in combination with the family name, to |
| /// represent the subfamily in a menu. Applications will choose the |
| /// appropriate version based on their selection criteria. |
| pub name_entry: u16, |
| /// The fourth and fifth values represent the small end of the recommended |
| /// usage range (exclusive) and the large end of the recommended usage range |
| /// (inclusive), stored in 720/inch units (decipoints). |
| /// |
| /// Ranges must not overlap, and should generally be contiguous. |
| pub range_start: u16, |
| pub range_end: u16, |
| } |
| |
| impl SizeParams { |
| /// Construct a new `SizeParams` |
| pub fn new( |
| design_size: u16, |
| identifier: u16, |
| name_entry: u16, |
| range_start: u16, |
| range_end: u16, |
| ) -> Self { |
| Self { |
| design_size, |
| identifier, |
| name_entry, |
| range_start, |
| range_end, |
| } |
| } |
| } |
| |
| impl FontWrite for SizeParams { |
| fn write_into(&self, writer: &mut TableWriter) { |
| self.design_size.write_into(writer); |
| self.identifier.write_into(writer); |
| self.name_entry.write_into(writer); |
| self.range_start.write_into(writer); |
| self.range_end.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("SizeParams") |
| } |
| } |
| |
| impl Validate for SizeParams { |
| fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::SizeParams<'a>> for SizeParams { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::SizeParams<'a>, _: FontData) -> Self { |
| SizeParams { |
| design_size: obj.design_size(), |
| identifier: obj.identifier(), |
| name_entry: obj.name_entry(), |
| range_start: obj.range_start(), |
| range_end: obj.range_end(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::SizeParams<'a>> for SizeParams {} |
| |
| impl<'a> FontRead<'a> for SizeParams { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::SizeParams as FontRead>::read(data).map(|x| x.to_owned_table()) |
| } |
| } |
| |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct StylisticSetParams { |
| /// The 'name' table name ID that specifies a string (or strings, for |
| /// multiple languages) for a user-interface label for this feature. |
| /// |
| /// The value of uiLabelNameId is expected to be in the font-specific name |
| /// ID range (256-32767), though that is not a requirement in this Feature |
| /// Parameters specification. The user-interface label for the feature can |
| /// be provided in multiple languages. An English string should be included |
| /// as a fallback. The string should be kept to a minimal length to fit |
| /// comfortably with different application interfaces. |
| pub ui_name_id: NameId, |
| } |
| |
| impl StylisticSetParams { |
| /// Construct a new `StylisticSetParams` |
| pub fn new(ui_name_id: NameId) -> Self { |
| Self { ui_name_id } |
| } |
| } |
| |
| impl FontWrite for StylisticSetParams { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (0 as u16).write_into(writer); |
| self.ui_name_id.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("StylisticSetParams") |
| } |
| } |
| |
| impl Validate for StylisticSetParams { |
| fn validate_impl(&self, _ctx: &mut ValidationCtx) {} |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::StylisticSetParams<'a>> for StylisticSetParams { |
| fn from_obj_ref(obj: &read_fonts::tables::layout::StylisticSetParams<'a>, _: FontData) -> Self { |
| StylisticSetParams { |
| ui_name_id: obj.ui_name_id(), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::StylisticSetParams<'a>> for StylisticSetParams {} |
| |
| impl<'a> FontRead<'a> for StylisticSetParams { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::StylisticSetParams as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |
| |
| /// featureParams for ['cv01'-'cv99'](https://docs.microsoft.com/en-us/typography/opentype/spec/features_ae#cv01-cv99) |
| #[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] |
| #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] |
| pub struct CharacterVariantParams { |
| /// The 'name' table name ID that specifies a string (or strings, |
| /// for multiple languages) for a user-interface label for this |
| /// feature. (May be NULL.) |
| pub feat_ui_label_name_id: NameId, |
| /// The 'name' table name ID that specifies a string (or strings, |
| /// for multiple languages) that an application can use for tooltip |
| /// text for this feature. (May be NULL.) |
| pub feat_ui_tooltip_text_name_id: NameId, |
| /// The 'name' table name ID that specifies sample text that |
| /// illustrates the effect of this feature. (May be NULL.) |
| pub sample_text_name_id: NameId, |
| /// Number of named parameters. (May be zero.) |
| pub num_named_parameters: u16, |
| /// The first 'name' table name ID used to specify strings for |
| /// user-interface labels for the feature parameters. (Must be zero |
| /// if numParameters is zero.) |
| pub first_param_ui_label_name_id: NameId, |
| /// The Unicode Scalar Value of the characters for which this |
| /// feature provides glyph variants. |
| pub character: Vec<Uint24>, |
| } |
| |
| impl CharacterVariantParams { |
| /// Construct a new `CharacterVariantParams` |
| pub fn new( |
| feat_ui_label_name_id: NameId, |
| feat_ui_tooltip_text_name_id: NameId, |
| sample_text_name_id: NameId, |
| num_named_parameters: u16, |
| first_param_ui_label_name_id: NameId, |
| character: Vec<Uint24>, |
| ) -> Self { |
| Self { |
| feat_ui_label_name_id, |
| feat_ui_tooltip_text_name_id, |
| sample_text_name_id, |
| num_named_parameters, |
| first_param_ui_label_name_id, |
| character, |
| } |
| } |
| } |
| |
| impl FontWrite for CharacterVariantParams { |
| #[allow(clippy::unnecessary_cast)] |
| fn write_into(&self, writer: &mut TableWriter) { |
| (0 as u16).write_into(writer); |
| self.feat_ui_label_name_id.write_into(writer); |
| self.feat_ui_tooltip_text_name_id.write_into(writer); |
| self.sample_text_name_id.write_into(writer); |
| self.num_named_parameters.write_into(writer); |
| self.first_param_ui_label_name_id.write_into(writer); |
| (u16::try_from(array_len(&self.character)).unwrap()).write_into(writer); |
| self.character.write_into(writer); |
| } |
| fn table_type(&self) -> TableType { |
| TableType::Named("CharacterVariantParams") |
| } |
| } |
| |
| impl Validate for CharacterVariantParams { |
| fn validate_impl(&self, ctx: &mut ValidationCtx) { |
| ctx.in_table("CharacterVariantParams", |ctx| { |
| ctx.in_field("character", |ctx| { |
| if self.character.len() > (u16::MAX as usize) { |
| ctx.report("array exceeds max length"); |
| } |
| }); |
| }) |
| } |
| } |
| |
| impl<'a> FromObjRef<read_fonts::tables::layout::CharacterVariantParams<'a>> |
| for CharacterVariantParams |
| { |
| fn from_obj_ref( |
| obj: &read_fonts::tables::layout::CharacterVariantParams<'a>, |
| _: FontData, |
| ) -> Self { |
| let offset_data = obj.offset_data(); |
| CharacterVariantParams { |
| feat_ui_label_name_id: obj.feat_ui_label_name_id(), |
| feat_ui_tooltip_text_name_id: obj.feat_ui_tooltip_text_name_id(), |
| sample_text_name_id: obj.sample_text_name_id(), |
| num_named_parameters: obj.num_named_parameters(), |
| first_param_ui_label_name_id: obj.first_param_ui_label_name_id(), |
| character: obj.character().to_owned_obj(offset_data), |
| } |
| } |
| } |
| |
| #[allow(clippy::needless_lifetimes)] |
| impl<'a> FromTableRef<read_fonts::tables::layout::CharacterVariantParams<'a>> |
| for CharacterVariantParams |
| { |
| } |
| |
| impl<'a> FontRead<'a> for CharacterVariantParams { |
| fn read(data: FontData<'a>) -> Result<Self, ReadError> { |
| <read_fonts::tables::layout::CharacterVariantParams as FontRead>::read(data) |
| .map(|x| x.to_owned_table()) |
| } |
| } |