blob: 4c088f456b3feec730ba64954563c3b491fd1eee [file] [log] [blame] [edit]
//! Handling offsets
use crate::serialize::{OffsetWhence, SerializeErrorFlags, Serializer};
use crate::{Plan, Serialize, SubsetTable};
use write_fonts::{
read::{MinByteRange, TableRef},
types::{FixedSize, Scalar},
};
pub(crate) trait SerializeSubset {
fn serialize_subset<'a, T: SubsetTable<'a>>(
t: &T,
s: &mut Serializer,
plan: &Plan,
args: T::ArgsForSubset,
pos: usize,
) -> Result<T::Output, SerializeErrorFlags>;
}
impl<O: Scalar> SerializeSubset for O {
fn serialize_subset<'a, T: SubsetTable<'a>>(
t: &T,
s: &mut Serializer,
plan: &Plan,
args: T::ArgsForSubset,
pos: usize,
) -> Result<T::Output, SerializeErrorFlags> {
s.push()?;
match t.subset(plan, s, args) {
Ok(ret) => {
let Some(obj_idx) = s.pop_pack(true) else {
return Err(s.error());
};
s.add_link(
pos..pos + O::RAW_BYTE_LEN,
obj_idx,
OffsetWhence::Head,
0,
false,
)?;
Ok(ret)
}
Err(e) => {
s.pop_discard();
Err(e)
}
}
}
}
// this is trait is used to copy simple tables only which implemented MinByteRange trait
pub(crate) trait SerializeCopy {
fn serialize_copy<T: MinByteRange, F>(
t: &TableRef<T, F>,
s: &mut Serializer,
pos: usize,
) -> Result<(), SerializeErrorFlags>;
fn serialize_copy_from_bytes(
src_bytes: &[u8],
s: &mut Serializer,
pos: usize,
) -> Result<(), SerializeErrorFlags>;
}
impl<O: Scalar> SerializeCopy for O {
fn serialize_copy<T: MinByteRange, F>(
t: &TableRef<T, F>,
s: &mut Serializer,
pos: usize,
) -> Result<(), SerializeErrorFlags> {
s.push()?;
s.embed_bytes(t.min_table_bytes())?;
let Some(obj_idx) = s.pop_pack(true) else {
return Err(s.error());
};
s.add_link(
pos..pos + O::RAW_BYTE_LEN,
obj_idx,
OffsetWhence::Head,
0,
false,
)
}
fn serialize_copy_from_bytes(
src_bytes: &[u8],
s: &mut Serializer,
pos: usize,
) -> Result<(), SerializeErrorFlags> {
s.push()?;
s.embed_bytes(src_bytes)?;
let Some(obj_idx) = s.pop_pack(true) else {
return Err(s.error());
};
s.add_link(
pos..pos + O::RAW_BYTE_LEN,
obj_idx,
OffsetWhence::Head,
0,
false,
)
}
}
/// this is trait is used to serialize a table that an offset at pos points to
pub(crate) trait SerializeSerialize {
fn serialize_serialize<'a, T: Serialize<'a>>(
s: &mut Serializer,
args: T::Args,
pos: usize,
) -> Result<(), SerializeErrorFlags>;
}
impl<O: Scalar> SerializeSerialize for O {
fn serialize_serialize<'a, T: Serialize<'a>>(
s: &mut Serializer,
args: T::Args,
pos: usize,
) -> Result<(), SerializeErrorFlags> {
s.push()?;
match T::serialize(s, args) {
Ok(()) => {
let Some(obj_idx) = s.pop_pack(true) else {
return Err(s.error());
};
s.add_link(
pos..pos + O::RAW_BYTE_LEN,
obj_idx,
OffsetWhence::Head,
0,
false,
)?;
Ok(())
}
Err(e) => {
s.pop_discard();
Err(e)
}
}
}
}