mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 05:47:35 +00:00
LibPDF: Don't do special subr processing for type 2 CFFs
This is a subset of #21484: Type 2 CFFs never use the special subrs, so stop doing them for type 2 at least for now. Fixes an assert in 0000064.pdf in 0000.zip in the pdfa dataset (a stack underflow because a subr is supposed to push a bunch of stuff, but instead it ran one of the built-in routines instead of the subr from the font file). As discussed in #21484, this isn't right for type 1 CFFs either, but just removing the code there regresses Tests/LibPDF/type1.pdf. A slightly more involved thing is needed there; I added a FIXME for that here.
This commit is contained in:
parent
5c0c55d2c0
commit
e484fae8e1
1 changed files with 39 additions and 29 deletions
|
@ -397,37 +397,47 @@ PDFErrorOr<Type1FontProgram::Glyph> Type1FontProgram::parse_glyph(ReadonlyBytes
|
|||
if (static_cast<size_t>(subr_number) >= subroutines.size())
|
||||
return error("Subroutine index out of range");
|
||||
|
||||
// Subroutines 0-2 handle the flex feature.
|
||||
if (subr_number == 0) {
|
||||
if (state.flex_index != 14)
|
||||
if (!is_type2) {
|
||||
// FIXME: Hardcoding subrs 0-2 here is incorrect, since some fonts don't use the flex feature.
|
||||
// For the ones that do, subrs 0-2 have fixed contents that have callothersubr instructions.
|
||||
// The right thing to do is to implement callothersubr for subrs 0-3 and remove the hardcoding here.
|
||||
|
||||
// Subroutines 0-2 handle the flex feature.
|
||||
if (subr_number == 0) {
|
||||
if (state.flex_index != 14)
|
||||
break;
|
||||
|
||||
auto& flex = state.flex_sequence;
|
||||
|
||||
path.cubic_bezier_curve_to(
|
||||
{ flex[2], flex[3] },
|
||||
{ flex[4], flex[5] },
|
||||
{ flex[6], flex[7] });
|
||||
path.cubic_bezier_curve_to(
|
||||
{ flex[8], flex[9] },
|
||||
{ flex[10], flex[11] },
|
||||
{ flex[12], flex[13] });
|
||||
|
||||
state.flex_feature = false;
|
||||
state.sp = 0;
|
||||
break;
|
||||
|
||||
auto& flex = state.flex_sequence;
|
||||
|
||||
path.cubic_bezier_curve_to(
|
||||
{ flex[2], flex[3] },
|
||||
{ flex[4], flex[5] },
|
||||
{ flex[6], flex[7] });
|
||||
path.cubic_bezier_curve_to(
|
||||
{ flex[8], flex[9] },
|
||||
{ flex[10], flex[11] },
|
||||
{ flex[12], flex[13] });
|
||||
|
||||
state.flex_feature = false;
|
||||
state.sp = 0;
|
||||
} else if (subr_number == 1) {
|
||||
state.flex_feature = true;
|
||||
state.flex_index = 0;
|
||||
state.sp = 0;
|
||||
} else if (subr_number == 2) {
|
||||
state.sp = 0;
|
||||
} else {
|
||||
auto const& subr = subroutines[subr_number];
|
||||
if (subr.is_empty())
|
||||
return error("Empty subroutine");
|
||||
|
||||
TRY(parse_glyph(subr, local_subroutines, global_subroutines, state, is_type2));
|
||||
}
|
||||
if (subr_number == 1) {
|
||||
state.flex_feature = true;
|
||||
state.flex_index = 0;
|
||||
state.sp = 0;
|
||||
break;
|
||||
}
|
||||
if (subr_number == 2) {
|
||||
state.sp = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto const& subr = subroutines[subr_number];
|
||||
if (subr.is_empty())
|
||||
return error("Empty subroutine");
|
||||
|
||||
TRY(parse_glyph(subr, local_subroutines, global_subroutines, state, is_type2));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue