Skip to content

Commit 7b58ee3

Browse files
authored
Change the API of parsing CFF tables to avoid a breaking change (#200)
1 parent 8417ce3 commit 7b58ee3

File tree

3 files changed

+41
-19
lines changed

3 files changed

+41
-19
lines changed

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1337,7 +1337,9 @@ impl<'a> Face<'a> {
13371337

13381338
bdat,
13391339
cbdt,
1340-
cff: raw_tables.cff.and_then(|data| cff::Table::parse(data, head.units_per_em)),
1340+
cff: raw_tables
1341+
.cff
1342+
.and_then(|data| cff::Table::parse_with_upem(data, head.units_per_em)),
13411343
cmap: raw_tables.cmap.and_then(cmap::Table::parse),
13421344
colr,
13431345
ebdt,

src/tables/cff/cff1.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -374,8 +374,13 @@ fn parse_char_string(
374374
local_subrs,
375375
};
376376

377-
let transform = (metadata.units_per_em, metadata.matrix());
378-
let transform = (transform != (1000, Matrix::default())).then_some(transform);
377+
let (upem, transform) = (metadata.units_per_em, metadata.matrix());
378+
let transform = if let Some(upem) = upem {
379+
((upem, transform) != (1000, Matrix::default())).then_some((upem, transform))
380+
} else {
381+
None
382+
};
383+
379384
let mut inner_builder = Builder {
380385
builder,
381386
bbox: RectF::new(),
@@ -802,7 +807,11 @@ fn parse_sid_metadata<'a>(
802807
Some(FontKind::SID(metadata))
803808
}
804809

805-
fn parse_cid_metadata(data: &[u8], top_dict: TopDict, number_of_glyphs: u16) -> Option<FontKind<'_>> {
810+
fn parse_cid_metadata(
811+
data: &[u8],
812+
top_dict: TopDict,
813+
number_of_glyphs: u16,
814+
) -> Option<FontKind<'_>> {
806815
let (charset_offset, fd_array_offset, fd_select_offset) = match (
807816
top_dict.charset_offset,
808817
top_dict.fd_array_offset,
@@ -852,12 +861,23 @@ pub struct Table<'a> {
852861

853862
// Copy of Face::units_per_em().
854863
// Required to do glyph outlining, since coordinates must be scaled up by this before applying the `matrix`.
855-
units_per_em: u16,
864+
units_per_em: Option<u16>,
856865
}
857866

858867
impl<'a> Table<'a> {
859868
/// Parses a table from raw data.
860-
pub fn parse(data: &'a [u8], units_per_em: u16) -> Option<Self> {
869+
pub fn parse(data: &'a [u8]) -> Option<Self> {
870+
Self::parse_inner(data, None)
871+
}
872+
873+
/// The same as [`Table::parse`], with the difference that it allows you to
874+
/// manually pass the units per em of the font, which is needed to properly
875+
/// scale certain fonts with a non-identity matrix.
876+
pub(crate) fn parse_with_upem(data: &'a [u8], units_per_em: u16) -> Option<Self> {
877+
Self::parse_inner(data, Some(units_per_em))
878+
}
879+
880+
fn parse_inner(data: &'a [u8], units_per_em: Option<u16>) -> Option<Self> {
861881
let mut s = Stream::new(data);
862882

863883
// Parse Header.

tests/tables/cff1.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ fn unsupported_version() {
312312
UInt8(0), // absolute offset
313313
]);
314314

315-
assert!(cff::Table::parse(&data, 1000).is_none());
315+
assert!(cff::Table::parse(&data).is_none());
316316
}
317317

318318
#[test]
@@ -360,7 +360,7 @@ fn non_default_header_size() {
360360
UInt8(operator::ENDCHAR),
361361
]);
362362

363-
let table = cff::Table::parse(&data, 1000).unwrap();
363+
let table = cff::Table::parse(&data).unwrap();
364364
let mut builder = Builder(String::new());
365365
let rect = table.outline(GlyphId(0), &mut builder).unwrap();
366366

@@ -377,7 +377,7 @@ macro_rules! test_cs_with_subrs {
377377
#[test]
378378
fn $name() {
379379
let data = gen_cff($glob, $loc, $values);
380-
let table = cff::Table::parse(&data, 1000).unwrap();
380+
let table = cff::Table::parse(&data).unwrap();
381381
let mut builder = Builder(String::new());
382382
let rect = table.outline(GlyphId(0), &mut builder).unwrap();
383383

@@ -398,7 +398,7 @@ macro_rules! test_cs_err {
398398
#[test]
399399
fn $name() {
400400
let data = gen_cff(&[], &[], $values);
401-
let table = cff::Table::parse(&data, 1000).unwrap();
401+
let table = cff::Table::parse(&data).unwrap();
402402
let mut builder = Builder(String::new());
403403
let res = table.outline(GlyphId(0), &mut builder);
404404
assert_eq!(res.unwrap_err(), $err);
@@ -575,7 +575,7 @@ test_cs!(vv_curve_to_with_x, &[
575575
#[test]
576576
fn only_endchar() {
577577
let data = gen_cff(&[], &[], &[UInt8(operator::ENDCHAR)]);
578-
let table = cff::Table::parse(&data, 1000).unwrap();
578+
let table = cff::Table::parse(&data).unwrap();
579579
let mut builder = Builder(String::new());
580580
assert!(table.outline(GlyphId(0), &mut builder).is_err());
581581
}
@@ -800,7 +800,7 @@ fn endchar_in_subr_with_extra_data_1() {
800800
]
801801
);
802802

803-
let table = cff::Table::parse(&data, 1000).unwrap();
803+
let table = cff::Table::parse(&data).unwrap();
804804
let mut builder = Builder(String::new());
805805
let res = table.outline(GlyphId(0), &mut builder);
806806
assert_eq!(res.unwrap_err(), CFFError::DataAfterEndChar);
@@ -827,7 +827,7 @@ fn endchar_in_subr_with_extra_data_2() {
827827
]
828828
);
829829

830-
let table = cff::Table::parse(&data, 1000).unwrap();
830+
let table = cff::Table::parse(&data).unwrap();
831831
let mut builder = Builder(String::new());
832832
let res = table.outline(GlyphId(0), &mut builder);
833833
assert_eq!(res.unwrap_err(), CFFError::DataAfterEndChar);
@@ -854,7 +854,7 @@ fn subr_without_return() {
854854
]
855855
);
856856

857-
let table = cff::Table::parse(&data, 1000).unwrap();
857+
let table = cff::Table::parse(&data).unwrap();
858858
let mut builder = Builder(String::new());
859859
let res = table.outline(GlyphId(0), &mut builder);
860860
assert_eq!(res.unwrap_err(), CFFError::DataAfterEndChar);
@@ -876,7 +876,7 @@ fn recursive_local_subr() {
876876
]
877877
);
878878

879-
let table = cff::Table::parse(&data, 1000).unwrap();
879+
let table = cff::Table::parse(&data).unwrap();
880880
let mut builder = Builder(String::new());
881881
let res = table.outline(GlyphId(0), &mut builder);
882882
assert_eq!(res.unwrap_err(), CFFError::NestingLimitReached);
@@ -898,7 +898,7 @@ fn recursive_global_subr() {
898898
]
899899
);
900900

901-
let table = cff::Table::parse(&data, 1000).unwrap();
901+
let table = cff::Table::parse(&data).unwrap();
902902
let mut builder = Builder(String::new());
903903
let res = table.outline(GlyphId(0), &mut builder);
904904
assert_eq!(res.unwrap_err(), CFFError::NestingLimitReached);
@@ -923,7 +923,7 @@ fn recursive_mixed_subr() {
923923
]
924924
);
925925

926-
let table = cff::Table::parse(&data, 1000).unwrap();
926+
let table = cff::Table::parse(&data).unwrap();
927927
let mut builder = Builder(String::new());
928928
let res = table.outline(GlyphId(0), &mut builder);
929929
assert_eq!(res.unwrap_err(), CFFError::NestingLimitReached);
@@ -952,7 +952,7 @@ fn zero_char_string_offset() {
952952
UInt8(top_dict_operator::CHAR_STRINGS_OFFSET as u8),
953953
]);
954954

955-
assert!(cff::Table::parse(&data, 1000).is_none());
955+
assert!(cff::Table::parse(&data).is_none());
956956
}
957957

958958
#[test]
@@ -978,7 +978,7 @@ fn invalid_char_string_offset() {
978978
UInt8(top_dict_operator::CHAR_STRINGS_OFFSET as u8),
979979
]);
980980

981-
assert!(cff::Table::parse(&data, 1000).is_none());
981+
assert!(cff::Table::parse(&data).is_none());
982982
}
983983

984984
// TODO: return from main

0 commit comments

Comments
 (0)