Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add gasp to write-fonts #1308

Merged
merged 1 commit into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions resources/codegen_plan.toml
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,11 @@ mode = "parse"
source = "resources/codegen_inputs/gasp.rs"
target = "read-fonts/generated/generated_gasp.rs"

[[generate]]
mode = "compile"
source = "resources/codegen_inputs/gasp.rs"
target = "write-fonts/generated/generated_gasp.rs"

[[generate]]
mode = "parse"
source = "resources/codegen_inputs/varc.rs"
Expand Down
127 changes: 127 additions & 0 deletions write-fonts/generated/generated_gasp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
// 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::gasp::GaspRangeBehavior;

/// [gasp](https://learn.microsoft.com/en-us/typography/opentype/spec/gasp#gasp-table-formats)
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Gasp {
/// Version number (set to 1)
pub version: u16,
/// Number of records to follow
pub num_ranges: u16,
/// Sorted by ppem
pub gasp_ranges: Vec<GaspRange>,
}

impl Gasp {
/// Construct a new `Gasp`
pub fn new(version: u16, num_ranges: u16, gasp_ranges: Vec<GaspRange>) -> Self {
Self {
version,
num_ranges,
gasp_ranges: gasp_ranges.into_iter().map(Into::into).collect(),
}
}
}

impl FontWrite for Gasp {
fn write_into(&self, writer: &mut TableWriter) {
self.version.write_into(writer);
self.num_ranges.write_into(writer);
self.gasp_ranges.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::TopLevel(Gasp::TAG)
}
}

impl Validate for Gasp {
fn validate_impl(&self, ctx: &mut ValidationCtx) {
ctx.in_table("Gasp", |ctx| {
ctx.in_field("gasp_ranges", |ctx| {
if self.gasp_ranges.len() > (u16::MAX as usize) {
ctx.report("array exceeds max length");
}
self.gasp_ranges.validate_impl(ctx);
});
})
}
}

impl TopLevelTable for Gasp {
const TAG: Tag = Tag::new(b"gasp");
}

impl<'a> FromObjRef<read_fonts::tables::gasp::Gasp<'a>> for Gasp {
fn from_obj_ref(obj: &read_fonts::tables::gasp::Gasp<'a>, _: FontData) -> Self {
let offset_data = obj.offset_data();
Gasp {
version: obj.version(),
num_ranges: obj.num_ranges(),
gasp_ranges: obj.gasp_ranges().to_owned_obj(offset_data),
}
}
}

#[allow(clippy::needless_lifetimes)]
impl<'a> FromTableRef<read_fonts::tables::gasp::Gasp<'a>> for Gasp {}

impl<'a> FontRead<'a> for Gasp {
fn read(data: FontData<'a>) -> Result<Self, ReadError> {
<read_fonts::tables::gasp::Gasp 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 GaspRange {
/// Upper limit of range, in PPEM
pub range_max_ppem: u16,
/// Flags describing desired rasterizer behavior.
pub range_gasp_behavior: GaspRangeBehavior,
}

impl GaspRange {
/// Construct a new `GaspRange`
pub fn new(range_max_ppem: u16, range_gasp_behavior: GaspRangeBehavior) -> Self {
Self {
range_max_ppem,
range_gasp_behavior,
}
}
}

impl FontWrite for GaspRange {
fn write_into(&self, writer: &mut TableWriter) {
self.range_max_ppem.write_into(writer);
self.range_gasp_behavior.write_into(writer);
}
fn table_type(&self) -> TableType {
TableType::Named("GaspRange")
}
}

impl Validate for GaspRange {
fn validate_impl(&self, _ctx: &mut ValidationCtx) {}
}

impl FromObjRef<read_fonts::tables::gasp::GaspRange> for GaspRange {
fn from_obj_ref(obj: &read_fonts::tables::gasp::GaspRange, _: FontData) -> Self {
GaspRange {
range_max_ppem: obj.range_max_ppem(),
range_gasp_behavior: obj.range_gasp_behavior(),
}
}
}

impl FontWrite for GaspRangeBehavior {
fn write_into(&self, writer: &mut TableWriter) {
writer.write_slice(&self.bits().to_be_bytes())
}
}
2 changes: 2 additions & 0 deletions write-fonts/src/tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod avar;
pub mod base;
pub mod cmap;
pub mod fvar;
pub mod gasp;
pub mod gdef;
pub mod glyf;
pub mod gpos;
Expand Down Expand Up @@ -41,6 +42,7 @@ fn do_we_even_serde() {
base: base::Base,
cmap: cmap::Cmap,
fvar: fvar::Fvar,
gasp: gasp::Gasp,
gdef: gdef::Gdef,
glyf: glyf::Glyf,
gpos: gpos::Gpos,
Expand Down
43 changes: 43 additions & 0 deletions write-fonts/src/tables/gasp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//! The gasp table

include!("../../generated/generated_gasp.rs");

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn gasping() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

let gasp = Gasp {
version: 1,
num_ranges: 2,
gasp_ranges: vec![
GaspRange {
range_max_ppem: 42,
range_gasp_behavior: GaspRangeBehavior::GASP_GRIDFIT,
},
GaspRange {
range_max_ppem: 4242,
range_gasp_behavior: GaspRangeBehavior::GASP_SYMMETRIC_SMOOTHING,
},
],
};

let _dumped = crate::write::dump_table(&gasp).unwrap();
let data = FontData::new(&_dumped);
let loaded = read_fonts::tables::gasp::Gasp::read(data).unwrap();

assert_eq!(1, loaded.version());
assert_eq!(
vec![
(42, GaspRangeBehavior::GASP_GRIDFIT),
(4242, GaspRangeBehavior::GASP_SYMMETRIC_SMOOTHING)
],
loaded
.gasp_ranges()
.iter()
.map(|r| (r.range_max_ppem(), r.range_gasp_behavior()))
.collect::<Vec<_>>()
);
}
}
Loading