Skip to content
Open
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
1 change: 1 addition & 0 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ The SIL OPEN FONT LICENSE Version 1.1 applies to the following fonts:
- fonts/NotoSansCJKsc-Bold-subset1.otf
- fonts/NotoSansCJKsc-Regular.otf
- fonts/Syne-Regular_subset.oft (Copyright 2017 The Syne Project Authors (https://gitlab.com/bonjour-monde/fonderie/syne-typeface))
- fonts/Astrolabe_subset.ttf (Copyright 2024 The Astrolabe Project Authors (github.com/aliftype/astrolabe))

-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
Expand Down
Binary file added fonts/Astrolabe_subset.ttf
Binary file not shown.
9 changes: 9 additions & 0 deletions src/glyf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ pub(crate) fn subset_with<'a>(
glyph_data_fn: impl FnMut(u16, &Context<'a>) -> Result<Cow<'a, [u8]>>,
) -> Result<()> {
let subsetted_entries = subset_glyf_entries(ctx, glyph_data_fn)?;
ctx.font_bbox = subsetted_entries
.iter()
.filter_map(|entry| glyph_bbox(entry))
.reduce(|a, b| [a[0].min(b[0]), a[1].min(b[1]), a[2].max(b[2]), a[3].max(b[3])]);

let mut sub_glyf = Writer::new();
let mut sub_loca = Writer::new();
Expand Down Expand Up @@ -187,6 +191,11 @@ fn subset_glyf_entries<'a>(
Ok(glyf_entries)
}

fn glyph_bbox(glyph_data: &[u8]) -> Option<[i16; 4]> {
let mut r = Reader::new_at(glyph_data, 2);
Some([r.read()?, r.read()?, r.read()?, r.read()?])
}

fn remap_component_glyph(mapper: &GlyphRemapper, data: &[u8]) -> Result<Vec<u8>> {
let mut r = Reader::new(data);
let mut w = Writer::with_capacity(data.len());
Expand Down
14 changes: 13 additions & 1 deletion src/head.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! The `head` table mostly contains information that can be reused from the
//! old table, except for the `loca` format, which depends on the size of the
//! glyph data. The checksum will be recalculated in the very end.
//! glyph data, and the bounds which can change when instancing. The checksum
//! will be recalculated in the very end.

use super::*;

Expand All @@ -9,6 +10,17 @@ pub fn subset(ctx: &mut Context) -> Result<()> {
let index_to_loc = head.get_mut(50..52).ok_or(MalformedFont)?;
index_to_loc[0] = 0;
index_to_loc[1] = ctx.long_loca as u8;

// We are (potentially) instancing a variable font, recalculate the font bounds.
if ctx.interjector.is_skrifa() {
let [x_min, y_min, x_max, y_max] = ctx.font_bbox.unwrap_or_default();
let bbox = head.get_mut(36..44).ok_or(MalformedFont)?;
bbox[0..2].copy_from_slice(&x_min.to_be_bytes());
bbox[2..4].copy_from_slice(&y_min.to_be_bytes());
bbox[4..6].copy_from_slice(&x_max.to_be_bytes());
bbox[6..8].copy_from_slice(&y_max.to_be_bytes());
}

ctx.push(Tag::HEAD, head);
Ok(())
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ fn prepare_context<'a>(
flavor,
tables: vec![],
long_loca: false,
font_bbox: None,
})
}

Expand Down Expand Up @@ -390,6 +391,9 @@ struct Context<'a> {
pub(crate) custom_hmtx_data: Option<Vec<(u16, i16)>>,
/// Whether the long loca format was chosen.
long_loca: bool,
/// The font bounding box (xMin, yMin, xMax, yMax), or `None` if there are
/// no glyphs with outlines.
font_bbox: Option<[i16; 4]>,
}

impl<'a> Context<'a> {
Expand Down
2 changes: 2 additions & 0 deletions tests/data/fonttools.tests
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ NotoSans-Regular_var.ttf;10,40,58,201-205;wght=800,wdth=70.0
// Note that the lsb values currently doesn't match fonttools
Cantarell-VF.otf;1,15,30-35,40,103-105;wght=400
Cantarell-VF.otf;1,15,30-35,40,103-105;wght=800
// Glyph 1 at MSHQ=200 is outside the head bounds of the font.
Astrolabe_subset.ttf;1;MSHQ=200

1 change: 1 addition & 0 deletions tests/src/font_tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ use crate::*;
#[test] #[cfg(feature = "variable-fonts")] fn noto_sans_regular_var_3() {test_font_tools("NotoSans-Regular_var.ttf", "10,40,58,201-205", "wght=800,wdth=70.0", 3)}
#[test] #[cfg(feature = "variable-fonts")] fn cantarell_v_f_1() {test_font_tools("Cantarell-VF.otf", "1,15,30-35,40,103-105", "wght=400", 1)}
#[test] #[cfg(feature = "variable-fonts")] fn cantarell_v_f_2() {test_font_tools("Cantarell-VF.otf", "1,15,30-35,40,103-105", "wght=800", 2)}
#[test] #[cfg(feature = "variable-fonts")] fn astrolabe_subset_1() {test_font_tools("Astrolabe_subset.ttf", "1", "MSHQ=200", 1)}
187 changes: 187 additions & 0 deletions tests/ttx/Astrolabe_subset_1.ttx
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
<?xml version="1.0" encoding="UTF-8"?>
<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.62">

<GlyphOrder>
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
<GlyphID id="0" name=".notdef"/>
<GlyphID id="1" name="dal-ar.isol"/>
</GlyphOrder>

<head>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="1.0"/>
<fontRevision value="1.0"/>
<checkSumAdjustment value="0xf943b2c3"/>
<magicNumber value="0x5f0f3cf5"/>
<flags value="00000000 00000011"/>
<unitsPerEm value="750"/>
<created value="Thu Mar 21 17:45:22 2024"/>
<modified value="Sat Nov 22 12:26:50 2025"/>
<xMin value="0"/>
<yMin value="0"/>
<xMax value="4657"/>
<yMax value="314"/>
<macStyle value="00000000 00000000"/>
<lowestRecPPEM value="6"/>
<fontDirectionHint value="2"/>
<indexToLocFormat value="0"/>
<glyphDataFormat value="0"/>
</head>

<hhea>
<tableVersion value="0x00010000"/>
<ascent value="800"/>
<descent value="-350"/>
<lineGap value="0"/>
<advanceWidthMax value="600"/>
<minLeftSideBearing value="0"/>
<minRightSideBearing value="43"/>
<xMaxExtent value="557"/>
<caretSlopeRise value="750"/>
<caretSlopeRun value="0"/>
<caretOffset value="0"/>
<reserved0 value="0"/>
<reserved1 value="0"/>
<reserved2 value="0"/>
<reserved3 value="0"/>
<metricDataFormat value="0"/>
<numberOfHMetrics value="2"/>
</hhea>

<maxp>
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="0x10000"/>
<numGlyphs value="2"/>
<maxPoints value="36"/>
<maxContours value="5"/>
<maxCompositePoints value="0"/>
<maxCompositeContours value="0"/>
<maxZones value="1"/>
<maxTwilightPoints value="0"/>
<maxStorage value="0"/>
<maxFunctionDefs value="0"/>
<maxInstructionDefs value="0"/>
<maxStackElements value="0"/>
<maxSizeOfInstructions value="0"/>
<maxComponentElements value="0"/>
<maxComponentDepth value="1"/>
</maxp>

<hmtx>
<mtx name=".notdef" width="375" lsb="0"/>
<mtx name="dal-ar.isol" width="4700" lsb="0"/>
</hmtx>

<loca>
<!-- The 'loca' table will be calculated by the compiler -->
</loca>

<glyf>

<!-- The xMin, yMin, xMax and yMax values
will be recalculated by the compiler. -->

<TTGlyph name=".notdef"/><!-- contains no outline data -->

<TTGlyph name="dal-ar.isol" xMin="0" yMin="0" xMax="4657" yMax="314">
<contour>
<pt x="4600" y="0" on="1"/>
<pt x="4600" y="50" on="1"/>
<pt x="4608" y="50" on="1"/>
<pt x="4657" y="0" on="1"/>
</contour>
<contour>
<pt x="110" y="100" on="1"/>
<pt x="135" y="314" on="1"/>
<pt x="144" y="313" on="1"/>
<pt x="158" y="286" on="0"/>
<pt x="194" y="261" on="0"/>
<pt x="228" y="252" on="1"/>
<pt x="228" y="244" on="1"/>
<pt x="206" y="239" on="0"/>
<pt x="180" y="206" on="0"/>
<pt x="168" y="170" on="0"/>
<pt x="166" y="159" on="1"/>
<pt x="161" y="108" on="1"/>
</contour>
<contour>
<pt x="110" y="100" on="1"/>
<pt x="140" y="150" on="1"/>
<pt x="4637" y="150" on="1"/>
<pt x="4608" y="100" on="1"/>
</contour>
<contour>
<pt x="4657" y="0" on="1"/>
<pt x="4599" y="50" on="1"/>
<pt x="4592" y="100" on="1"/>
<pt x="4637" y="150" on="1"/>
</contour>
<contour>
<pt x="0" y="0" on="1"/>
<pt x="0" y="8" on="1"/>
<pt x="25" y="25" on="0"/>
<pt x="46" y="64" on="0"/>
<pt x="50" y="100" on="1"/>
<pt x="58" y="100" on="1"/>
<pt x="66" y="80" on="0"/>
<pt x="102" y="58" on="0"/>
<pt x="139" y="50" on="0"/>
<pt x="150" y="50" on="1"/>
<pt x="4600" y="50" on="1"/>
<pt x="4650" y="0" on="1"/>
</contour>
<instructions/>
</TTGlyph>

</glyf>

<name>
<namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
Copyright 2024 The Astrolabe Project Authors (github.com/aliftype/astrolabe)
</namerecord>
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
Astrolabe
</namerecord>
<namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
Regular
</namerecord>
<namerecord nameID="3" platformID="3" platEncID="1" langID="0x409">
1.000;ALIF;Astrolabe-Regular
</namerecord>
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
Astrolabe Regular
</namerecord>
<namerecord nameID="5" platformID="3" platEncID="1" langID="0x409">
Version 1.000
</namerecord>
<namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
Astrolabe-Regular
</namerecord>
</name>

<post>
<formatType value="2.0"/>
<italicAngle value="0.0"/>
<underlinePosition value="-100"/>
<underlineThickness value="50"/>
<isFixedPitch value="0"/>
<minMemType42 value="0"/>
<maxMemType42 value="0"/>
<minMemType1 value="0"/>
<maxMemType1 value="0"/>
<psNames>
<!-- This file uses unique glyph names based on the information
found in the 'post' table. Since these names might not be unique,
we have to invent artificial names in case of clashes. In order to
be able to retain the original information, we need a name to
ps name mapping for those cases where they differ. That's what
you see below.
-->
</psNames>
<extraNames>
<!-- following are the name that are not taken from the standard Mac glyph order -->
<psName name="dal-ar.isol"/>
</extraNames>
</post>

</ttFont>
8 changes: 4 additions & 4 deletions tests/ttx/Cantarell-VF_1.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="1.0"/>
<fontRevision value="0.303"/>
<checkSumAdjustment value="0xae97bddf"/>
<checkSumAdjustment value="0xaf9fbe5d"/>
<magicNumber value="0x5f0f3cf5"/>
<flags value="00000000 00000011"/>
<unitsPerEm value="1000"/>
<created value="Fri Mar 13 21:44:13 2009"/>
<modified value="Thu Jan 6 10:43:08 2022"/>
<xMin value="-346"/>
<xMin value="7"/>
<yMin value="-256"/>
<xMax value="1309"/>
<yMax value="1099"/>
<xMax value="824"/>
<yMax value="1036"/>
<macStyle value="00000000 00000000"/>
<lowestRecPPEM value="6"/>
<fontDirectionHint value="2"/>
Expand Down
10 changes: 5 additions & 5 deletions tests/ttx/Cantarell-VF_2.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="1.0"/>
<fontRevision value="0.303"/>
<checkSumAdjustment value="0xa3d206f7"/>
<checkSumAdjustment value="0xa3f406f1"/>
<magicNumber value="0x5f0f3cf5"/>
<flags value="00000000 00000011"/>
<unitsPerEm value="1000"/>
<created value="Fri Mar 13 21:44:13 2009"/>
<modified value="Thu Jan 6 10:43:08 2022"/>
<xMin value="-346"/>
<yMin value="-256"/>
<xMax value="1309"/>
<yMax value="1099"/>
<xMin value="-7"/>
<yMin value="-258"/>
<xMax value="953"/>
<yMax value="1104"/>
<macStyle value="00000000 00000000"/>
<lowestRecPPEM value="6"/>
<fontDirectionHint value="2"/>
Expand Down
10 changes: 5 additions & 5 deletions tests/ttx/NotoSans-Regular_var_2.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="1.0"/>
<fontRevision value="2.013"/>
<checkSumAdjustment value="0xe2047929"/>
<checkSumAdjustment value="0xeaec772d"/>
<magicNumber value="0x5f0f3cf5"/>
<flags value="00000000 00000011"/>
<unitsPerEm value="1000"/>
<created value="Mon Oct 4 15:53:11 2021"/>
<modified value="Sat Sep 30 09:29:49 2023"/>
<xMin value="-621"/>
<yMin value="-394"/>
<xMax value="2800"/>
<yMax value="1067"/>
<xMin value="15"/>
<yMin value="-10"/>
<xMax value="1024"/>
<yMax value="937"/>
<macStyle value="00000000 00000000"/>
<lowestRecPPEM value="6"/>
<fontDirectionHint value="2"/>
Expand Down
10 changes: 5 additions & 5 deletions tests/ttx/NotoSans-Regular_var_3.ttx
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@
<!-- Most of this table will be recalculated by the compiler -->
<tableVersion value="1.0"/>
<fontRevision value="2.013"/>
<checkSumAdjustment value="0xec59e4fb"/>
<checkSumAdjustment value="0xf6e5e309"/>
<magicNumber value="0x5f0f3cf5"/>
<flags value="00000000 00000011"/>
<unitsPerEm value="1000"/>
<created value="Mon Oct 4 15:53:11 2021"/>
<modified value="Sat Sep 30 09:29:49 2023"/>
<xMin value="-621"/>
<yMin value="-394"/>
<xMax value="2800"/>
<yMax value="1067"/>
<xMin value="2"/>
<yMin value="-10"/>
<xMax value="827"/>
<yMax value="932"/>
<macStyle value="00000000 00000000"/>
<lowestRecPPEM value="6"/>
<fontDirectionHint value="2"/>
Expand Down
Loading