#[allow(unused_imports)]
use crate::codegen_prelude::*;
pub use read_fonts::tables::gpos::ValueFormat;
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Gpos {
pub script_list: OffsetMarker<ScriptList>,
pub feature_list: OffsetMarker<FeatureList>,
pub lookup_list: OffsetMarker<PositionLookupList>,
pub feature_variations: NullableOffsetMarker<FeatureVariations, WIDTH_32>,
}
impl Gpos {
pub fn new(
script_list: ScriptList,
feature_list: FeatureList,
lookup_list: PositionLookupList,
) -> Self {
Self {
script_list: script_list.into(),
feature_list: feature_list.into(),
lookup_list: lookup_list.into(),
..Default::default()
}
}
}
impl FontWrite for Gpos {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
let version = self.compute_version() as MajorMinor;
version.write_into(writer);
self.script_list.write_into(writer);
self.feature_list.write_into(writer);
self.lookup_list.write_into(writer);
version
.compatible((1, 1))
.then(|| self.feature_variations.write_into(writer));
}
fn table_type(&self) -> TableType {
TableType::TopLevel(Gpos::TAG)
}
}
impl Validate for Gpos {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("Gpos", |ctx| {
ctx.in_field("script_list", |ctx| {
self.script_list.validate_impl(ctx);
});
ctx.in_field("feature_list", |ctx| {
self.feature_list.validate_impl(ctx);
});
ctx.in_field("lookup_list", |ctx| {
self.lookup_list.validate_impl(ctx);
});
ctx.in_field("feature_variations", |ctx| {
self.feature_variations.validate_impl(ctx);
});
})
}
}
impl TopLevelTable for Gpos {
const TAG: Tag = Tag::new(b"GPOS");
}
impl<'a> FromObjRef<read_fonts::tables::gpos::Gpos<'a>> for Gpos {
fn from_obj_ref(obj: &read_fonts::tables::gpos::Gpos<'a>, _: FontData) -> Self {
Gpos {
script_list: obj.script_list().to_owned_table(),
feature_list: obj.feature_list().to_owned_table(),
lookup_list: obj.lookup_list().to_owned_table(),
feature_variations: obj.feature_variations().to_owned_table(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::Gpos<'a>> for Gpos {}
impl<'a> FontRead<'a> for Gpos {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::Gpos 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 PositionLookup {
Single(Lookup<SinglePos>),
Pair(Lookup<PairPos>),
Cursive(Lookup<CursivePosFormat1>),
MarkToBase(Lookup<MarkBasePosFormat1>),
MarkToLig(Lookup<MarkLigPosFormat1>),
MarkToMark(Lookup<MarkMarkPosFormat1>),
Contextual(Lookup<PositionSequenceContext>),
ChainContextual(Lookup<PositionChainContext>),
Extension(Lookup<ExtensionSubtable>),
}
impl Default for PositionLookup {
fn default() -> Self {
Self::Single(Default::default())
}
}
impl FontWrite for PositionLookup {
fn write_into(&self, writer: &mut TableWriter) {
match self {
Self::Single(table) => table.write_into(writer),
Self::Pair(table) => table.write_into(writer),
Self::Cursive(table) => table.write_into(writer),
Self::MarkToBase(table) => table.write_into(writer),
Self::MarkToLig(table) => table.write_into(writer),
Self::MarkToMark(table) => table.write_into(writer),
Self::Contextual(table) => table.write_into(writer),
Self::ChainContextual(table) => table.write_into(writer),
Self::Extension(table) => table.write_into(writer),
}
}
fn table_type(&self) -> TableType {
match self {
Self::Single(table) => table.table_type(),
Self::Pair(table) => table.table_type(),
Self::Cursive(table) => table.table_type(),
Self::MarkToBase(table) => table.table_type(),
Self::MarkToLig(table) => table.table_type(),
Self::MarkToMark(table) => table.table_type(),
Self::Contextual(table) => table.table_type(),
Self::ChainContextual(table) => table.table_type(),
Self::Extension(table) => table.table_type(),
}
}
}
impl Validate for PositionLookup {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
match self {
Self::Single(table) => table.validate_impl(ctx),
Self::Pair(table) => table.validate_impl(ctx),
Self::Cursive(table) => table.validate_impl(ctx),
Self::MarkToBase(table) => table.validate_impl(ctx),
Self::MarkToLig(table) => table.validate_impl(ctx),
Self::MarkToMark(table) => table.validate_impl(ctx),
Self::Contextual(table) => table.validate_impl(ctx),
Self::ChainContextual(table) => table.validate_impl(ctx),
Self::Extension(table) => table.validate_impl(ctx),
}
}
}
impl FromObjRef<read_fonts::tables::gpos::PositionLookup<'_>> for PositionLookup {
fn from_obj_ref(from: &read_fonts::tables::gpos::PositionLookup<'_>, data: FontData) -> Self {
match from {
read_fonts::tables::gpos::PositionLookup::Single(table) => {
Self::Single(table.to_owned_obj(data))
}
read_fonts::tables::gpos::PositionLookup::Pair(table) => {
Self::Pair(table.to_owned_obj(data))
}
read_fonts::tables::gpos::PositionLookup::Cursive(table) => {
Self::Cursive(table.to_owned_obj(data))
}
read_fonts::tables::gpos::PositionLookup::MarkToBase(table) => {
Self::MarkToBase(table.to_owned_obj(data))
}
read_fonts::tables::gpos::PositionLookup::MarkToLig(table) => {
Self::MarkToLig(table.to_owned_obj(data))
}
read_fonts::tables::gpos::PositionLookup::MarkToMark(table) => {
Self::MarkToMark(table.to_owned_obj(data))
}
read_fonts::tables::gpos::PositionLookup::Contextual(table) => {
Self::Contextual(table.to_owned_obj(data))
}
read_fonts::tables::gpos::PositionLookup::ChainContextual(table) => {
Self::ChainContextual(table.to_owned_obj(data))
}
read_fonts::tables::gpos::PositionLookup::Extension(table) => {
Self::Extension(table.to_owned_obj(data))
}
}
}
}
impl FromTableRef<read_fonts::tables::gpos::PositionLookup<'_>> for PositionLookup {}
impl FontWrite for ValueFormat {
fn write_into(&self, writer: &mut TableWriter) {
writer.write_slice(&self.bits().to_be_bytes())
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum AnchorTable {
Format1(AnchorFormat1),
Format2(AnchorFormat2),
Format3(AnchorFormat3),
}
impl AnchorTable {
pub fn format_1(x_coordinate: i16, y_coordinate: i16) -> Self {
Self::Format1(AnchorFormat1::new(x_coordinate, y_coordinate))
}
pub fn format_2(x_coordinate: i16, y_coordinate: i16, anchor_point: u16) -> Self {
Self::Format2(AnchorFormat2::new(x_coordinate, y_coordinate, anchor_point))
}
pub fn format_3(
x_coordinate: i16,
y_coordinate: i16,
x_device: Option<DeviceOrVariationIndex>,
y_device: Option<DeviceOrVariationIndex>,
) -> Self {
Self::Format3(AnchorFormat3::new(
x_coordinate,
y_coordinate,
x_device,
y_device,
))
}
}
impl Default for AnchorTable {
fn default() -> Self {
Self::Format1(Default::default())
}
}
impl FontWrite for AnchorTable {
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 AnchorTable {
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::gpos::AnchorTable<'_>> for AnchorTable {
fn from_obj_ref(obj: &read_fonts::tables::gpos::AnchorTable, _: FontData) -> Self {
use read_fonts::tables::gpos::AnchorTable as ObjRefType;
match obj {
ObjRefType::Format1(item) => AnchorTable::Format1(item.to_owned_table()),
ObjRefType::Format2(item) => AnchorTable::Format2(item.to_owned_table()),
ObjRefType::Format3(item) => AnchorTable::Format3(item.to_owned_table()),
}
}
}
impl FromTableRef<read_fonts::tables::gpos::AnchorTable<'_>> for AnchorTable {}
impl<'a> FontRead<'a> for AnchorTable {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::AnchorTable as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
impl From<AnchorFormat1> for AnchorTable {
fn from(src: AnchorFormat1) -> AnchorTable {
AnchorTable::Format1(src)
}
}
impl From<AnchorFormat2> for AnchorTable {
fn from(src: AnchorFormat2) -> AnchorTable {
AnchorTable::Format2(src)
}
}
impl From<AnchorFormat3> for AnchorTable {
fn from(src: AnchorFormat3) -> AnchorTable {
AnchorTable::Format3(src)
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct AnchorFormat1 {
pub x_coordinate: i16,
pub y_coordinate: i16,
}
impl AnchorFormat1 {
pub fn new(x_coordinate: i16, y_coordinate: i16) -> Self {
Self {
x_coordinate,
y_coordinate,
}
}
}
impl FontWrite for AnchorFormat1 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(1 as u16).write_into(writer);
self.x_coordinate.write_into(writer);
self.y_coordinate.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("AnchorFormat1")
}
}
impl Validate for AnchorFormat1 {
fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::AnchorFormat1<'a>> for AnchorFormat1 {
fn from_obj_ref(obj: &read_fonts::tables::gpos::AnchorFormat1<'a>, _: FontData) -> Self {
AnchorFormat1 {
x_coordinate: obj.x_coordinate(),
y_coordinate: obj.y_coordinate(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::AnchorFormat1<'a>> for AnchorFormat1 {}
impl<'a> FontRead<'a> for AnchorFormat1 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::AnchorFormat1 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 AnchorFormat2 {
pub x_coordinate: i16,
pub y_coordinate: i16,
pub anchor_point: u16,
}
impl AnchorFormat2 {
pub fn new(x_coordinate: i16, y_coordinate: i16, anchor_point: u16) -> Self {
Self {
x_coordinate,
y_coordinate,
anchor_point,
}
}
}
impl FontWrite for AnchorFormat2 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(2 as u16).write_into(writer);
self.x_coordinate.write_into(writer);
self.y_coordinate.write_into(writer);
self.anchor_point.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("AnchorFormat2")
}
}
impl Validate for AnchorFormat2 {
fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::AnchorFormat2<'a>> for AnchorFormat2 {
fn from_obj_ref(obj: &read_fonts::tables::gpos::AnchorFormat2<'a>, _: FontData) -> Self {
AnchorFormat2 {
x_coordinate: obj.x_coordinate(),
y_coordinate: obj.y_coordinate(),
anchor_point: obj.anchor_point(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::AnchorFormat2<'a>> for AnchorFormat2 {}
impl<'a> FontRead<'a> for AnchorFormat2 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::AnchorFormat2 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 AnchorFormat3 {
pub x_coordinate: i16,
pub y_coordinate: i16,
pub x_device: NullableOffsetMarker<DeviceOrVariationIndex>,
pub y_device: NullableOffsetMarker<DeviceOrVariationIndex>,
}
impl AnchorFormat3 {
pub fn new(
x_coordinate: i16,
y_coordinate: i16,
x_device: Option<DeviceOrVariationIndex>,
y_device: Option<DeviceOrVariationIndex>,
) -> Self {
Self {
x_coordinate,
y_coordinate,
x_device: x_device.into(),
y_device: y_device.into(),
}
}
}
impl FontWrite for AnchorFormat3 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(3 as u16).write_into(writer);
self.x_coordinate.write_into(writer);
self.y_coordinate.write_into(writer);
self.x_device.write_into(writer);
self.y_device.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("AnchorFormat3")
}
}
impl Validate for AnchorFormat3 {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("AnchorFormat3", |ctx| {
ctx.in_field("x_device", |ctx| {
self.x_device.validate_impl(ctx);
});
ctx.in_field("y_device", |ctx| {
self.y_device.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::AnchorFormat3<'a>> for AnchorFormat3 {
fn from_obj_ref(obj: &read_fonts::tables::gpos::AnchorFormat3<'a>, _: FontData) -> Self {
AnchorFormat3 {
x_coordinate: obj.x_coordinate(),
y_coordinate: obj.y_coordinate(),
x_device: obj.x_device().to_owned_table(),
y_device: obj.y_device().to_owned_table(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::AnchorFormat3<'a>> for AnchorFormat3 {}
impl<'a> FontRead<'a> for AnchorFormat3 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::AnchorFormat3 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 MarkArray {
pub mark_records: Vec<MarkRecord>,
}
impl MarkArray {
pub fn new(mark_records: Vec<MarkRecord>) -> Self {
Self {
mark_records: mark_records.into_iter().map(Into::into).collect(),
}
}
}
impl FontWrite for MarkArray {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(array_len(&self.mark_records).unwrap() as u16).write_into(writer);
self.mark_records.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("MarkArray")
}
}
impl Validate for MarkArray {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("MarkArray", |ctx| {
ctx.in_field("mark_records", |ctx| {
if self.mark_records.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.mark_records.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::MarkArray<'a>> for MarkArray {
fn from_obj_ref(obj: &read_fonts::tables::gpos::MarkArray<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
MarkArray {
mark_records: obj.mark_records().to_owned_obj(offset_data),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::MarkArray<'a>> for MarkArray {}
impl<'a> FontRead<'a> for MarkArray {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::MarkArray 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 MarkRecord {
pub mark_class: u16,
pub mark_anchor: OffsetMarker<AnchorTable>,
}
impl MarkRecord {
pub fn new(mark_class: u16, mark_anchor: AnchorTable) -> Self {
Self {
mark_class,
mark_anchor: mark_anchor.into(),
}
}
}
impl FontWrite for MarkRecord {
fn write_into(&self, writer: &mut TableWriter) {
self.mark_class.write_into(writer);
self.mark_anchor.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("MarkRecord")
}
}
impl Validate for MarkRecord {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("MarkRecord", |ctx| {
ctx.in_field("mark_anchor", |ctx| {
self.mark_anchor.validate_impl(ctx);
});
})
}
}
impl FromObjRef<read_fonts::tables::gpos::MarkRecord> for MarkRecord {
fn from_obj_ref(obj: &read_fonts::tables::gpos::MarkRecord, offset_data: FontData) -> Self {
MarkRecord {
mark_class: obj.mark_class(),
mark_anchor: obj.mark_anchor(offset_data).to_owned_table(),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum SinglePos {
Format1(SinglePosFormat1),
Format2(SinglePosFormat2),
}
impl SinglePos {
pub fn format_1(coverage: CoverageTable, value_record: ValueRecord) -> Self {
Self::Format1(SinglePosFormat1::new(coverage, value_record))
}
pub fn format_2(coverage: CoverageTable, value_records: Vec<ValueRecord>) -> Self {
Self::Format2(SinglePosFormat2::new(coverage, value_records))
}
}
impl Default for SinglePos {
fn default() -> Self {
Self::Format1(Default::default())
}
}
impl FontWrite for SinglePos {
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 SinglePos {
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::gpos::SinglePos<'_>> for SinglePos {
fn from_obj_ref(obj: &read_fonts::tables::gpos::SinglePos, _: FontData) -> Self {
use read_fonts::tables::gpos::SinglePos as ObjRefType;
match obj {
ObjRefType::Format1(item) => SinglePos::Format1(item.to_owned_table()),
ObjRefType::Format2(item) => SinglePos::Format2(item.to_owned_table()),
}
}
}
impl FromTableRef<read_fonts::tables::gpos::SinglePos<'_>> for SinglePos {}
impl<'a> FontRead<'a> for SinglePos {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::SinglePos as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
impl From<SinglePosFormat1> for SinglePos {
fn from(src: SinglePosFormat1) -> SinglePos {
SinglePos::Format1(src)
}
}
impl From<SinglePosFormat2> for SinglePos {
fn from(src: SinglePosFormat2) -> SinglePos {
SinglePos::Format2(src)
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SinglePosFormat1 {
pub coverage: OffsetMarker<CoverageTable>,
pub value_record: ValueRecord,
}
impl SinglePosFormat1 {
pub fn new(coverage: CoverageTable, value_record: ValueRecord) -> Self {
Self {
coverage: coverage.into(),
value_record,
}
}
}
impl FontWrite for SinglePosFormat1 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(1 as u16).write_into(writer);
self.coverage.write_into(writer);
(self.compute_value_format() as ValueFormat).write_into(writer);
self.value_record.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("SinglePosFormat1")
}
}
impl Validate for SinglePosFormat1 {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("SinglePosFormat1", |ctx| {
ctx.in_field("coverage", |ctx| {
self.coverage.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::SinglePosFormat1<'a>> for SinglePosFormat1 {
fn from_obj_ref(obj: &read_fonts::tables::gpos::SinglePosFormat1<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
SinglePosFormat1 {
coverage: obj.coverage().to_owned_table(),
value_record: obj.value_record().to_owned_obj(offset_data),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::SinglePosFormat1<'a>> for SinglePosFormat1 {}
impl<'a> FontRead<'a> for SinglePosFormat1 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::SinglePosFormat1 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 SinglePosFormat2 {
pub coverage: OffsetMarker<CoverageTable>,
pub value_records: Vec<ValueRecord>,
}
impl SinglePosFormat2 {
pub fn new(coverage: CoverageTable, value_records: Vec<ValueRecord>) -> Self {
Self {
coverage: coverage.into(),
value_records,
}
}
}
impl FontWrite for SinglePosFormat2 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(2 as u16).write_into(writer);
self.coverage.write_into(writer);
(self.compute_value_format() as ValueFormat).write_into(writer);
(array_len(&self.value_records).unwrap() as u16).write_into(writer);
self.value_records.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("SinglePosFormat2")
}
}
impl Validate for SinglePosFormat2 {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("SinglePosFormat2", |ctx| {
ctx.in_field("coverage", |ctx| {
self.coverage.validate_impl(ctx);
});
ctx.in_field("value_records", |ctx| {
if self.value_records.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.value_records.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::SinglePosFormat2<'a>> for SinglePosFormat2 {
fn from_obj_ref(obj: &read_fonts::tables::gpos::SinglePosFormat2<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
SinglePosFormat2 {
coverage: obj.coverage().to_owned_table(),
value_records: obj
.value_records()
.iter()
.filter_map(|x| x.map(|x| FromObjRef::from_obj_ref(&x, offset_data)).ok())
.collect(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::SinglePosFormat2<'a>> for SinglePosFormat2 {}
impl<'a> FontRead<'a> for SinglePosFormat2 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::SinglePosFormat2 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 PairPos {
Format1(PairPosFormat1),
Format2(PairPosFormat2),
}
impl PairPos {
pub fn format_1(coverage: CoverageTable, pair_sets: Vec<PairSet>) -> Self {
Self::Format1(PairPosFormat1::new(coverage, pair_sets))
}
pub fn format_2(
coverage: CoverageTable,
class_def1: ClassDef,
class_def2: ClassDef,
class1_records: Vec<Class1Record>,
) -> Self {
Self::Format2(PairPosFormat2::new(
coverage,
class_def1,
class_def2,
class1_records,
))
}
}
impl Default for PairPos {
fn default() -> Self {
Self::Format1(Default::default())
}
}
impl FontWrite for PairPos {
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 PairPos {
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::gpos::PairPos<'_>> for PairPos {
fn from_obj_ref(obj: &read_fonts::tables::gpos::PairPos, _: FontData) -> Self {
use read_fonts::tables::gpos::PairPos as ObjRefType;
match obj {
ObjRefType::Format1(item) => PairPos::Format1(item.to_owned_table()),
ObjRefType::Format2(item) => PairPos::Format2(item.to_owned_table()),
}
}
}
impl FromTableRef<read_fonts::tables::gpos::PairPos<'_>> for PairPos {}
impl<'a> FontRead<'a> for PairPos {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::PairPos as FontRead>::read(data).map(|x| x.to_owned_table())
}
}
impl From<PairPosFormat1> for PairPos {
fn from(src: PairPosFormat1) -> PairPos {
PairPos::Format1(src)
}
}
impl From<PairPosFormat2> for PairPos {
fn from(src: PairPosFormat2) -> PairPos {
PairPos::Format2(src)
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PairPosFormat1 {
pub coverage: OffsetMarker<CoverageTable>,
pub pair_sets: Vec<OffsetMarker<PairSet>>,
}
impl PairPosFormat1 {
pub fn new(coverage: CoverageTable, pair_sets: Vec<PairSet>) -> Self {
Self {
coverage: coverage.into(),
pair_sets: pair_sets.into_iter().map(Into::into).collect(),
}
}
}
impl FontWrite for PairPosFormat1 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(1 as u16).write_into(writer);
self.coverage.write_into(writer);
(self.compute_value_format1() as ValueFormat).write_into(writer);
(self.compute_value_format2() as ValueFormat).write_into(writer);
(array_len(&self.pair_sets).unwrap() as u16).write_into(writer);
self.pair_sets.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("PairPosFormat1")
}
}
impl Validate for PairPosFormat1 {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("PairPosFormat1", |ctx| {
ctx.in_field("coverage", |ctx| {
self.coverage.validate_impl(ctx);
});
ctx.in_field("pair_sets", |ctx| {
if self.pair_sets.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.check_format_consistency(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::PairPosFormat1<'a>> for PairPosFormat1 {
fn from_obj_ref(obj: &read_fonts::tables::gpos::PairPosFormat1<'a>, _: FontData) -> Self {
PairPosFormat1 {
coverage: obj.coverage().to_owned_table(),
pair_sets: obj.pair_sets().to_owned_table(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::PairPosFormat1<'a>> for PairPosFormat1 {}
impl<'a> FontRead<'a> for PairPosFormat1 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::PairPosFormat1 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 PairSet {
pub pair_value_records: Vec<PairValueRecord>,
}
impl PairSet {
pub fn new(pair_value_records: Vec<PairValueRecord>) -> Self {
Self { pair_value_records }
}
}
impl FontWrite for PairSet {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(array_len(&self.pair_value_records).unwrap() as u16).write_into(writer);
self.pair_value_records.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("PairSet")
}
}
impl Validate for PairSet {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("PairSet", |ctx| {
ctx.in_field("pair_value_records", |ctx| {
if self.pair_value_records.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.pair_value_records.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::PairSet<'a>> for PairSet {
fn from_obj_ref(obj: &read_fonts::tables::gpos::PairSet<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
PairSet {
pair_value_records: obj
.pair_value_records()
.iter()
.filter_map(|x| x.map(|x| FromObjRef::from_obj_ref(&x, offset_data)).ok())
.collect(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::PairSet<'a>> for PairSet {}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PairValueRecord {
pub second_glyph: GlyphId,
pub value_record1: ValueRecord,
pub value_record2: ValueRecord,
}
impl PairValueRecord {
pub fn new(
second_glyph: GlyphId,
value_record1: ValueRecord,
value_record2: ValueRecord,
) -> Self {
Self {
second_glyph,
value_record1,
value_record2,
}
}
}
impl FontWrite for PairValueRecord {
fn write_into(&self, writer: &mut TableWriter) {
self.second_glyph.write_into(writer);
self.value_record1.write_into(writer);
self.value_record2.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("PairValueRecord")
}
}
impl Validate for PairValueRecord {
fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
}
impl FromObjRef<read_fonts::tables::gpos::PairValueRecord> for PairValueRecord {
fn from_obj_ref(
obj: &read_fonts::tables::gpos::PairValueRecord,
offset_data: FontData,
) -> Self {
PairValueRecord {
second_glyph: obj.second_glyph(),
value_record1: obj.value_record1().to_owned_obj(offset_data),
value_record2: obj.value_record2().to_owned_obj(offset_data),
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PairPosFormat2 {
pub coverage: OffsetMarker<CoverageTable>,
pub class_def1: OffsetMarker<ClassDef>,
pub class_def2: OffsetMarker<ClassDef>,
pub class1_records: Vec<Class1Record>,
}
impl PairPosFormat2 {
pub fn new(
coverage: CoverageTable,
class_def1: ClassDef,
class_def2: ClassDef,
class1_records: Vec<Class1Record>,
) -> Self {
Self {
coverage: coverage.into(),
class_def1: class_def1.into(),
class_def2: class_def2.into(),
class1_records,
}
}
}
impl FontWrite for PairPosFormat2 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(2 as u16).write_into(writer);
self.coverage.write_into(writer);
(self.compute_value_format1() as ValueFormat).write_into(writer);
(self.compute_value_format2() as ValueFormat).write_into(writer);
self.class_def1.write_into(writer);
self.class_def2.write_into(writer);
(self.compute_class1_count() as u16).write_into(writer);
(self.compute_class2_count() as u16).write_into(writer);
self.class1_records.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("PairPosFormat2")
}
}
impl Validate for PairPosFormat2 {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("PairPosFormat2", |ctx| {
ctx.in_field("coverage", |ctx| {
self.coverage.validate_impl(ctx);
});
ctx.in_field("class_def1", |ctx| {
self.class_def1.validate_impl(ctx);
});
ctx.in_field("class_def2", |ctx| {
self.class_def2.validate_impl(ctx);
});
ctx.in_field("class1_records", |ctx| {
if self.class1_records.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.class1_records.validate_impl(ctx);
});
self.check_length_and_format_conformance(ctx);
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::PairPosFormat2<'a>> for PairPosFormat2 {
fn from_obj_ref(obj: &read_fonts::tables::gpos::PairPosFormat2<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
PairPosFormat2 {
coverage: obj.coverage().to_owned_table(),
class_def1: obj.class_def1().to_owned_table(),
class_def2: obj.class_def2().to_owned_table(),
class1_records: obj
.class1_records()
.iter()
.filter_map(|x| x.map(|x| FromObjRef::from_obj_ref(&x, offset_data)).ok())
.collect(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::PairPosFormat2<'a>> for PairPosFormat2 {}
impl<'a> FontRead<'a> for PairPosFormat2 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::PairPosFormat2 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 Class1Record {
pub class2_records: Vec<Class2Record>,
}
impl Class1Record {
pub fn new(class2_records: Vec<Class2Record>) -> Self {
Self { class2_records }
}
}
impl FontWrite for Class1Record {
fn write_into(&self, writer: &mut TableWriter) {
self.class2_records.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("Class1Record")
}
}
impl Validate for Class1Record {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("Class1Record", |ctx| {
ctx.in_field("class2_records", |ctx| {
if self.class2_records.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.class2_records.validate_impl(ctx);
});
})
}
}
impl FromObjRef<read_fonts::tables::gpos::Class1Record<'_>> for Class1Record {
fn from_obj_ref(obj: &read_fonts::tables::gpos::Class1Record, offset_data: FontData) -> Self {
Class1Record {
class2_records: obj
.class2_records()
.iter()
.filter_map(|x| x.map(|x| FromObjRef::from_obj_ref(&x, offset_data)).ok())
.collect(),
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Class2Record {
pub value_record1: ValueRecord,
pub value_record2: ValueRecord,
}
impl Class2Record {
pub fn new(value_record1: ValueRecord, value_record2: ValueRecord) -> Self {
Self {
value_record1,
value_record2,
}
}
}
impl FontWrite for Class2Record {
fn write_into(&self, writer: &mut TableWriter) {
self.value_record1.write_into(writer);
self.value_record2.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("Class2Record")
}
}
impl Validate for Class2Record {
fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
}
impl FromObjRef<read_fonts::tables::gpos::Class2Record> for Class2Record {
fn from_obj_ref(obj: &read_fonts::tables::gpos::Class2Record, offset_data: FontData) -> Self {
Class2Record {
value_record1: obj.value_record1().to_owned_obj(offset_data),
value_record2: obj.value_record2().to_owned_obj(offset_data),
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct CursivePosFormat1 {
pub coverage: OffsetMarker<CoverageTable>,
pub entry_exit_record: Vec<EntryExitRecord>,
}
impl CursivePosFormat1 {
pub fn new(coverage: CoverageTable, entry_exit_record: Vec<EntryExitRecord>) -> Self {
Self {
coverage: coverage.into(),
entry_exit_record: entry_exit_record.into_iter().map(Into::into).collect(),
}
}
}
impl FontWrite for CursivePosFormat1 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(1 as u16).write_into(writer);
self.coverage.write_into(writer);
(array_len(&self.entry_exit_record).unwrap() as u16).write_into(writer);
self.entry_exit_record.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("CursivePosFormat1")
}
}
impl Validate for CursivePosFormat1 {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("CursivePosFormat1", |ctx| {
ctx.in_field("coverage", |ctx| {
self.coverage.validate_impl(ctx);
});
ctx.in_field("entry_exit_record", |ctx| {
if self.entry_exit_record.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.entry_exit_record.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::CursivePosFormat1<'a>> for CursivePosFormat1 {
fn from_obj_ref(obj: &read_fonts::tables::gpos::CursivePosFormat1<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
CursivePosFormat1 {
coverage: obj.coverage().to_owned_table(),
entry_exit_record: obj.entry_exit_record().to_owned_obj(offset_data),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::CursivePosFormat1<'a>> for CursivePosFormat1 {}
impl<'a> FontRead<'a> for CursivePosFormat1 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::CursivePosFormat1 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 EntryExitRecord {
pub entry_anchor: NullableOffsetMarker<AnchorTable>,
pub exit_anchor: NullableOffsetMarker<AnchorTable>,
}
impl EntryExitRecord {
pub fn new(entry_anchor: Option<AnchorTable>, exit_anchor: Option<AnchorTable>) -> Self {
Self {
entry_anchor: entry_anchor.into(),
exit_anchor: exit_anchor.into(),
}
}
}
impl FontWrite for EntryExitRecord {
fn write_into(&self, writer: &mut TableWriter) {
self.entry_anchor.write_into(writer);
self.exit_anchor.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("EntryExitRecord")
}
}
impl Validate for EntryExitRecord {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("EntryExitRecord", |ctx| {
ctx.in_field("entry_anchor", |ctx| {
self.entry_anchor.validate_impl(ctx);
});
ctx.in_field("exit_anchor", |ctx| {
self.exit_anchor.validate_impl(ctx);
});
})
}
}
impl FromObjRef<read_fonts::tables::gpos::EntryExitRecord> for EntryExitRecord {
fn from_obj_ref(
obj: &read_fonts::tables::gpos::EntryExitRecord,
offset_data: FontData,
) -> Self {
EntryExitRecord {
entry_anchor: obj.entry_anchor(offset_data).to_owned_table(),
exit_anchor: obj.exit_anchor(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 MarkBasePosFormat1 {
pub mark_coverage: OffsetMarker<CoverageTable>,
pub base_coverage: OffsetMarker<CoverageTable>,
pub mark_array: OffsetMarker<MarkArray>,
pub base_array: OffsetMarker<BaseArray>,
}
impl MarkBasePosFormat1 {
pub fn new(
mark_coverage: CoverageTable,
base_coverage: CoverageTable,
mark_array: MarkArray,
base_array: BaseArray,
) -> Self {
Self {
mark_coverage: mark_coverage.into(),
base_coverage: base_coverage.into(),
mark_array: mark_array.into(),
base_array: base_array.into(),
}
}
}
impl FontWrite for MarkBasePosFormat1 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(1 as u16).write_into(writer);
self.mark_coverage.write_into(writer);
self.base_coverage.write_into(writer);
(self.compute_mark_class_count() as u16).write_into(writer);
self.mark_array.write_into(writer);
self.base_array.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("MarkBasePosFormat1")
}
}
impl Validate for MarkBasePosFormat1 {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("MarkBasePosFormat1", |ctx| {
ctx.in_field("mark_coverage", |ctx| {
self.mark_coverage.validate_impl(ctx);
});
ctx.in_field("base_coverage", |ctx| {
self.base_coverage.validate_impl(ctx);
});
ctx.in_field("mark_array", |ctx| {
self.mark_array.validate_impl(ctx);
});
ctx.in_field("base_array", |ctx| {
self.base_array.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::MarkBasePosFormat1<'a>> for MarkBasePosFormat1 {
fn from_obj_ref(obj: &read_fonts::tables::gpos::MarkBasePosFormat1<'a>, _: FontData) -> Self {
MarkBasePosFormat1 {
mark_coverage: obj.mark_coverage().to_owned_table(),
base_coverage: obj.base_coverage().to_owned_table(),
mark_array: obj.mark_array().to_owned_table(),
base_array: obj.base_array().to_owned_table(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::MarkBasePosFormat1<'a>> for MarkBasePosFormat1 {}
impl<'a> FontRead<'a> for MarkBasePosFormat1 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::MarkBasePosFormat1 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 BaseArray {
pub base_records: Vec<BaseRecord>,
}
impl BaseArray {
pub fn new(base_records: Vec<BaseRecord>) -> Self {
Self { base_records }
}
}
impl FontWrite for BaseArray {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(array_len(&self.base_records).unwrap() as u16).write_into(writer);
self.base_records.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("BaseArray")
}
}
impl Validate for BaseArray {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("BaseArray", |ctx| {
ctx.in_field("base_records", |ctx| {
if self.base_records.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.base_records.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::BaseArray<'a>> for BaseArray {
fn from_obj_ref(obj: &read_fonts::tables::gpos::BaseArray<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
BaseArray {
base_records: obj
.base_records()
.iter()
.filter_map(|x| x.map(|x| FromObjRef::from_obj_ref(&x, offset_data)).ok())
.collect(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::BaseArray<'a>> for BaseArray {}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BaseRecord {
pub base_anchors: Vec<NullableOffsetMarker<AnchorTable>>,
}
impl BaseRecord {
pub fn new(base_anchors: Vec<Option<AnchorTable>>) -> Self {
Self {
base_anchors: base_anchors.into_iter().map(Into::into).collect(),
}
}
}
impl FontWrite for BaseRecord {
fn write_into(&self, writer: &mut TableWriter) {
self.base_anchors.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("BaseRecord")
}
}
impl Validate for BaseRecord {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("BaseRecord", |ctx| {
ctx.in_field("base_anchors", |ctx| {
if self.base_anchors.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.base_anchors.validate_impl(ctx);
});
})
}
}
impl FromObjRef<read_fonts::tables::gpos::BaseRecord<'_>> for BaseRecord {
fn from_obj_ref(obj: &read_fonts::tables::gpos::BaseRecord, offset_data: FontData) -> Self {
BaseRecord {
base_anchors: obj.base_anchors(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 MarkLigPosFormat1 {
pub mark_coverage: OffsetMarker<CoverageTable>,
pub ligature_coverage: OffsetMarker<CoverageTable>,
pub mark_array: OffsetMarker<MarkArray>,
pub ligature_array: OffsetMarker<LigatureArray>,
}
impl MarkLigPosFormat1 {
pub fn new(
mark_coverage: CoverageTable,
ligature_coverage: CoverageTable,
mark_array: MarkArray,
ligature_array: LigatureArray,
) -> Self {
Self {
mark_coverage: mark_coverage.into(),
ligature_coverage: ligature_coverage.into(),
mark_array: mark_array.into(),
ligature_array: ligature_array.into(),
}
}
}
impl FontWrite for MarkLigPosFormat1 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(1 as u16).write_into(writer);
self.mark_coverage.write_into(writer);
self.ligature_coverage.write_into(writer);
(self.compute_mark_class_count() as u16).write_into(writer);
self.mark_array.write_into(writer);
self.ligature_array.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("MarkLigPosFormat1")
}
}
impl Validate for MarkLigPosFormat1 {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("MarkLigPosFormat1", |ctx| {
ctx.in_field("mark_coverage", |ctx| {
self.mark_coverage.validate_impl(ctx);
});
ctx.in_field("ligature_coverage", |ctx| {
self.ligature_coverage.validate_impl(ctx);
});
ctx.in_field("mark_array", |ctx| {
self.mark_array.validate_impl(ctx);
});
ctx.in_field("ligature_array", |ctx| {
self.ligature_array.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::MarkLigPosFormat1<'a>> for MarkLigPosFormat1 {
fn from_obj_ref(obj: &read_fonts::tables::gpos::MarkLigPosFormat1<'a>, _: FontData) -> Self {
MarkLigPosFormat1 {
mark_coverage: obj.mark_coverage().to_owned_table(),
ligature_coverage: obj.ligature_coverage().to_owned_table(),
mark_array: obj.mark_array().to_owned_table(),
ligature_array: obj.ligature_array().to_owned_table(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::MarkLigPosFormat1<'a>> for MarkLigPosFormat1 {}
impl<'a> FontRead<'a> for MarkLigPosFormat1 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::MarkLigPosFormat1 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 LigatureArray {
pub ligature_attaches: Vec<OffsetMarker<LigatureAttach>>,
}
impl LigatureArray {
pub fn new(ligature_attaches: Vec<LigatureAttach>) -> Self {
Self {
ligature_attaches: ligature_attaches.into_iter().map(Into::into).collect(),
}
}
}
impl FontWrite for LigatureArray {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(array_len(&self.ligature_attaches).unwrap() as u16).write_into(writer);
self.ligature_attaches.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("LigatureArray")
}
}
impl Validate for LigatureArray {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("LigatureArray", |ctx| {
ctx.in_field("ligature_attaches", |ctx| {
if self.ligature_attaches.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.ligature_attaches.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::LigatureArray<'a>> for LigatureArray {
fn from_obj_ref(obj: &read_fonts::tables::gpos::LigatureArray<'a>, _: FontData) -> Self {
LigatureArray {
ligature_attaches: obj.ligature_attaches().to_owned_table(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::LigatureArray<'a>> for LigatureArray {}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct LigatureAttach {
pub component_records: Vec<ComponentRecord>,
}
impl LigatureAttach {
pub fn new(component_records: Vec<ComponentRecord>) -> Self {
Self { component_records }
}
}
impl FontWrite for LigatureAttach {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(array_len(&self.component_records).unwrap() as u16).write_into(writer);
self.component_records.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("LigatureAttach")
}
}
impl Validate for LigatureAttach {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("LigatureAttach", |ctx| {
ctx.in_field("component_records", |ctx| {
if self.component_records.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.component_records.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::LigatureAttach<'a>> for LigatureAttach {
fn from_obj_ref(obj: &read_fonts::tables::gpos::LigatureAttach<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
LigatureAttach {
component_records: obj
.component_records()
.iter()
.filter_map(|x| x.map(|x| FromObjRef::from_obj_ref(&x, offset_data)).ok())
.collect(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::LigatureAttach<'a>> for LigatureAttach {}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ComponentRecord {
pub ligature_anchors: Vec<NullableOffsetMarker<AnchorTable>>,
}
impl ComponentRecord {
pub fn new(ligature_anchors: Vec<Option<AnchorTable>>) -> Self {
Self {
ligature_anchors: ligature_anchors.into_iter().map(Into::into).collect(),
}
}
}
impl FontWrite for ComponentRecord {
fn write_into(&self, writer: &mut TableWriter) {
self.ligature_anchors.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("ComponentRecord")
}
}
impl Validate for ComponentRecord {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("ComponentRecord", |ctx| {
ctx.in_field("ligature_anchors", |ctx| {
if self.ligature_anchors.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.ligature_anchors.validate_impl(ctx);
});
})
}
}
impl FromObjRef<read_fonts::tables::gpos::ComponentRecord<'_>> for ComponentRecord {
fn from_obj_ref(
obj: &read_fonts::tables::gpos::ComponentRecord,
offset_data: FontData,
) -> Self {
ComponentRecord {
ligature_anchors: obj.ligature_anchors(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 MarkMarkPosFormat1 {
pub mark1_coverage: OffsetMarker<CoverageTable>,
pub mark2_coverage: OffsetMarker<CoverageTable>,
pub mark1_array: OffsetMarker<MarkArray>,
pub mark2_array: OffsetMarker<Mark2Array>,
}
impl MarkMarkPosFormat1 {
pub fn new(
mark1_coverage: CoverageTable,
mark2_coverage: CoverageTable,
mark1_array: MarkArray,
mark2_array: Mark2Array,
) -> Self {
Self {
mark1_coverage: mark1_coverage.into(),
mark2_coverage: mark2_coverage.into(),
mark1_array: mark1_array.into(),
mark2_array: mark2_array.into(),
}
}
}
impl FontWrite for MarkMarkPosFormat1 {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(1 as u16).write_into(writer);
self.mark1_coverage.write_into(writer);
self.mark2_coverage.write_into(writer);
(self.compute_mark_class_count() as u16).write_into(writer);
self.mark1_array.write_into(writer);
self.mark2_array.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("MarkMarkPosFormat1")
}
}
impl Validate for MarkMarkPosFormat1 {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("MarkMarkPosFormat1", |ctx| {
ctx.in_field("mark1_coverage", |ctx| {
self.mark1_coverage.validate_impl(ctx);
});
ctx.in_field("mark2_coverage", |ctx| {
self.mark2_coverage.validate_impl(ctx);
});
ctx.in_field("mark1_array", |ctx| {
self.mark1_array.validate_impl(ctx);
});
ctx.in_field("mark2_array", |ctx| {
self.mark2_array.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::MarkMarkPosFormat1<'a>> for MarkMarkPosFormat1 {
fn from_obj_ref(obj: &read_fonts::tables::gpos::MarkMarkPosFormat1<'a>, _: FontData) -> Self {
MarkMarkPosFormat1 {
mark1_coverage: obj.mark1_coverage().to_owned_table(),
mark2_coverage: obj.mark2_coverage().to_owned_table(),
mark1_array: obj.mark1_array().to_owned_table(),
mark2_array: obj.mark2_array().to_owned_table(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::MarkMarkPosFormat1<'a>> for MarkMarkPosFormat1 {}
impl<'a> FontRead<'a> for MarkMarkPosFormat1 {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gpos::MarkMarkPosFormat1 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 Mark2Array {
pub mark2_records: Vec<Mark2Record>,
}
impl Mark2Array {
pub fn new(mark2_records: Vec<Mark2Record>) -> Self {
Self { mark2_records }
}
}
impl FontWrite for Mark2Array {
#[allow(clippy::unnecessary_cast)]
fn write_into(&self, writer: &mut TableWriter) {
(array_len(&self.mark2_records).unwrap() as u16).write_into(writer);
self.mark2_records.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("Mark2Array")
}
}
impl Validate for Mark2Array {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("Mark2Array", |ctx| {
ctx.in_field("mark2_records", |ctx| {
if self.mark2_records.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.mark2_records.validate_impl(ctx);
});
})
}
}
impl<'a> FromObjRef<read_fonts::tables::gpos::Mark2Array<'a>> for Mark2Array {
fn from_obj_ref(obj: &read_fonts::tables::gpos::Mark2Array<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
Mark2Array {
mark2_records: obj
.mark2_records()
.iter()
.filter_map(|x| x.map(|x| FromObjRef::from_obj_ref(&x, offset_data)).ok())
.collect(),
}
}
}
impl<'a> FromTableRef<read_fonts::tables::gpos::Mark2Array<'a>> for Mark2Array {}
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Mark2Record {
pub mark2_anchors: Vec<NullableOffsetMarker<AnchorTable>>,
}
impl Mark2Record {
pub fn new(mark2_anchors: Vec<Option<AnchorTable>>) -> Self {
Self {
mark2_anchors: mark2_anchors.into_iter().map(Into::into).collect(),
}
}
}
impl FontWrite for Mark2Record {
fn write_into(&self, writer: &mut TableWriter) {
self.mark2_anchors.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("Mark2Record")
}
}
impl Validate for Mark2Record {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("Mark2Record", |ctx| {
ctx.in_field("mark2_anchors", |ctx| {
if self.mark2_anchors.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.mark2_anchors.validate_impl(ctx);
});
})
}
}
impl FromObjRef<read_fonts::tables::gpos::Mark2Record<'_>> for Mark2Record {
fn from_obj_ref(obj: &read_fonts::tables::gpos::Mark2Record, offset_data: FontData) -> Self {
Mark2Record {
mark2_anchors: obj.mark2_anchors(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 ExtensionPosFormat1<T> {
pub extension_lookup_type: u16,
pub extension: OffsetMarker<T, WIDTH_32>,
}
impl<T> ExtensionPosFormat1<T> {
pub fn new(extension_lookup_type: u16, extension: T) -> Self {
Self {
extension_lookup_type,
extension: extension.into(),
}
}
}
impl<T: Validate> Validate for ExtensionPosFormat1<T> {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("ExtensionPosFormat1", |ctx| {
ctx.in_field("extension", |ctx| {
self.extension.validate_impl(ctx);
});
})
}
}
impl<'a, T, U> FromObjRef<read_fonts::tables::gpos::ExtensionPosFormat1<'a, U>>
for ExtensionPosFormat1<T>
where
U: FontRead<'a>,
T: FromTableRef<U> + Default + 'static,
{
fn from_obj_ref(
obj: &read_fonts::tables::gpos::ExtensionPosFormat1<'a, U>,
_: FontData,
) -> Self {
ExtensionPosFormat1 {
extension_lookup_type: obj.extension_lookup_type(),
extension: obj.extension().to_owned_table(),
}
}
}
impl<'a, T, U> FromTableRef<read_fonts::tables::gpos::ExtensionPosFormat1<'a, U>>
for ExtensionPosFormat1<T>
where
U: FontRead<'a>,
T: FromTableRef<U> + Default + 'static,
{
}
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ExtensionSubtable {
Single(ExtensionPosFormat1<SinglePos>),
Pair(ExtensionPosFormat1<PairPos>),
Cursive(ExtensionPosFormat1<CursivePosFormat1>),
MarkToBase(ExtensionPosFormat1<MarkBasePosFormat1>),
MarkToLig(ExtensionPosFormat1<MarkLigPosFormat1>),
MarkToMark(ExtensionPosFormat1<MarkMarkPosFormat1>),
Contextual(ExtensionPosFormat1<PositionSequenceContext>),
ChainContextual(ExtensionPosFormat1<PositionChainContext>),
}
impl Default for ExtensionSubtable {
fn default() -> Self {
Self::Single(Default::default())
}
}
impl FontWrite for ExtensionSubtable {
fn write_into(&self, writer: &mut TableWriter) {
match self {
Self::Single(table) => table.write_into(writer),
Self::Pair(table) => table.write_into(writer),
Self::Cursive(table) => table.write_into(writer),
Self::MarkToBase(table) => table.write_into(writer),
Self::MarkToLig(table) => table.write_into(writer),
Self::MarkToMark(table) => table.write_into(writer),
Self::Contextual(table) => table.write_into(writer),
Self::ChainContextual(table) => table.write_into(writer),
}
}
fn table_type(&self) -> TableType {
match self {
Self::Single(table) => table.table_type(),
Self::Pair(table) => table.table_type(),
Self::Cursive(table) => table.table_type(),
Self::MarkToBase(table) => table.table_type(),
Self::MarkToLig(table) => table.table_type(),
Self::MarkToMark(table) => table.table_type(),
Self::Contextual(table) => table.table_type(),
Self::ChainContextual(table) => table.table_type(),
}
}
}
impl Validate for ExtensionSubtable {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
match self {
Self::Single(table) => table.validate_impl(ctx),
Self::Pair(table) => table.validate_impl(ctx),
Self::Cursive(table) => table.validate_impl(ctx),
Self::MarkToBase(table) => table.validate_impl(ctx),
Self::MarkToLig(table) => table.validate_impl(ctx),
Self::MarkToMark(table) => table.validate_impl(ctx),
Self::Contextual(table) => table.validate_impl(ctx),
Self::ChainContextual(table) => table.validate_impl(ctx),
}
}
}
impl FromObjRef<read_fonts::tables::gpos::ExtensionSubtable<'_>> for ExtensionSubtable {
fn from_obj_ref(
from: &read_fonts::tables::gpos::ExtensionSubtable<'_>,
data: FontData,
) -> Self {
match from {
read_fonts::tables::gpos::ExtensionSubtable::Single(table) => {
Self::Single(table.to_owned_obj(data))
}
read_fonts::tables::gpos::ExtensionSubtable::Pair(table) => {
Self::Pair(table.to_owned_obj(data))
}
read_fonts::tables::gpos::ExtensionSubtable::Cursive(table) => {
Self::Cursive(table.to_owned_obj(data))
}
read_fonts::tables::gpos::ExtensionSubtable::MarkToBase(table) => {
Self::MarkToBase(table.to_owned_obj(data))
}
read_fonts::tables::gpos::ExtensionSubtable::MarkToLig(table) => {
Self::MarkToLig(table.to_owned_obj(data))
}
read_fonts::tables::gpos::ExtensionSubtable::MarkToMark(table) => {
Self::MarkToMark(table.to_owned_obj(data))
}
read_fonts::tables::gpos::ExtensionSubtable::Contextual(table) => {
Self::Contextual(table.to_owned_obj(data))
}
read_fonts::tables::gpos::ExtensionSubtable::ChainContextual(table) => {
Self::ChainContextual(table.to_owned_obj(data))
}
}
}
}
impl FromTableRef<read_fonts::tables::gpos::ExtensionSubtable<'_>> for ExtensionSubtable {}