diff --git a/NOTICE b/NOTICE index 8d921d26..80a9cdc0 100644 --- a/NOTICE +++ b/NOTICE @@ -264,6 +264,7 @@ from Tavmjong Bah. For further information, contact: tavmjong @ free The GUST font license applies to the following fonts: - fonts/LatinModernRoman-Regular.otf +- fonts/EndcharInSubroutine_1.otf (derived from LatinModernRoman-Regular.otf) - fonts/NewCMMath-Regular.otf % This is version 1.0, dated 22 June 2009, of the GUST Font License. diff --git a/fonts/EndcharInSubroutine.otf b/fonts/EndcharInSubroutine.otf new file mode 100644 index 00000000..ec679fc5 Binary files /dev/null and b/fonts/EndcharInSubroutine.otf differ diff --git a/src/cff/charstring.rs b/src/cff/charstring.rs index bd478843..6da1c3f1 100644 --- a/src/cff/charstring.rs +++ b/src/cff/charstring.rs @@ -21,6 +21,11 @@ pub struct Decompiler<'a> { hint_mask_bytes: u16, } +enum CharStringEnd { + Return, + EndChar, +} + impl<'a> Decompiler<'a> { /// Create a new charstring decompiler. pub fn new( @@ -48,7 +53,7 @@ impl<'a> Decompiler<'a> { charstring: CharString<'a>, program: &mut Program<'a>, depth: u8, - ) -> Result<()> { + ) -> Result { if depth > 64 { return Err(CFFError); } @@ -94,9 +99,7 @@ impl<'a> Decompiler<'a> { self.stack.pop_all(); program.push(Instruction::Operator(operator)); } - RETURN => { - // Don't do anything for return, since we desubroutinize. - } + RETURN => return Ok(CharStringEnd::Return), CALL_GLOBAL_SUBROUTINE => { // Pop the subroutine index from the program. program.0.pop(); @@ -107,7 +110,12 @@ impl<'a> Decompiler<'a> { .gsubr_handler .get_with_biased(biased_index) .ok_or(CFFError)?; - self.decompile_inner(gsubr, program, depth + 1)?; + if matches!( + self.decompile_inner(gsubr, program, depth + 1)?, + CharStringEnd::EndChar + ) { + return Ok(CharStringEnd::EndChar); + } } CALL_LOCAL_SUBROUTINE => { // Pop the subroutine index from the program. @@ -119,7 +127,12 @@ impl<'a> Decompiler<'a> { .lsubr_handler .get_with_biased(biased_index) .ok_or(CFFError)?; - self.decompile_inner(lsubr, program, depth + 1)?; + if matches!( + self.decompile_inner(lsubr, program, depth + 1)?, + CharStringEnd::EndChar + ) { + return Ok(CharStringEnd::EndChar); + } } HINT_MASK | COUNTER_MASK => { program.push(Instruction::Operator(operator)); @@ -141,6 +154,8 @@ impl<'a> Decompiler<'a> { } program.push(Instruction::Operator(operator)); + + return Ok(CharStringEnd::EndChar); } _ => { return Err(CFFError); @@ -148,7 +163,7 @@ impl<'a> Decompiler<'a> { } } - Ok(()) + Ok(CharStringEnd::Return) } fn count_hints(&mut self) { diff --git a/tests/data/fonttools.tests b/tests/data/fonttools.tests index 8b797370..7dba3823 100644 --- a/tests/data/fonttools.tests +++ b/tests/data/fonttools.tests @@ -10,6 +10,7 @@ NotoSans-Regular.ttf;567-570,2345-2350 Roboto-Regular.ttf;456,460-463 NewCMMath-Regular.otf;803-806,950-952,5600-5602 NotoSansCJKsc-Bold-subset1.otf;1 +EndcharInSubroutine.otf;1 NotoSans-Regular_var.ttf;10,40,58,201-205;wght=400 NotoSans-Regular_var.ttf;10,40,58,201-205;wght=900 NotoSans-Regular_var.ttf;10,40,58,201-205;wght=800,wdth=70.0 diff --git a/tests/src/font_tools.rs b/tests/src/font_tools.rs index 2c6c2ab2..d71d1ac0 100644 --- a/tests/src/font_tools.rs +++ b/tests/src/font_tools.rs @@ -13,6 +13,7 @@ use crate::*; #[test] fn roboto_regular_1() {test_font_tools("Roboto-Regular.ttf", "456,460-463", "", 1)} #[test] fn new_c_m_math_regular_1() {test_font_tools("NewCMMath-Regular.otf", "803-806,950-952,5600-5602", "", 1)} #[test] fn noto_sans_c_j_ksc_boldsubset1_1() {test_font_tools("NotoSansCJKsc-Bold-subset1.otf", "1", "", 1)} +#[test] fn endchar_in_subroutine_1() {test_font_tools("EndcharInSubroutine.otf", "1", "", 1)} #[test] #[cfg(feature = "variable-fonts")] fn noto_sans_regular_var_1() {test_font_tools("NotoSans-Regular_var.ttf", "10,40,58,201-205", "wght=400", 1)} #[test] #[cfg(feature = "variable-fonts")] fn noto_sans_regular_var_2() {test_font_tools("NotoSans-Regular_var.ttf", "10,40,58,201-205", "wght=900", 2)} #[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)} diff --git a/tests/ttx/EndcharInSubroutine_1.ttx b/tests/ttx/EndcharInSubroutine_1.ttx new file mode 100644 index 00000000..231e2490 --- /dev/null +++ b/tests/ttx/EndcharInSubroutine_1.ttx @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Copyright 2003, 2009 B. Jackowski and J. M. Nowacki (on behalf of TeX users groups). This work is released under the GUST Font License -- see http://tug.org/fonts/licenses/GUST-FONT-LICENSE.txt for details. + + + LM Roman 10 + + + Regular + + + 2.004;UKWN;LMRoman10-Regular + + + LMRoman10-Regular + + + Version 2.004;PS 2.004;hotconv 1.0.49;makeotf.lib2.0.14853 + + + LMRoman10-Regular + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 280 endchar + + + 333 endchar + + + + + + + + + + + + + + +