1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 19:17:44 +00:00

LibPDF: Change how CFF optional width prefix is stored

Per 5177.Type2.pdf 3.1 "Type 2 Charstring Organization",
a glyph's charstring looks like:

    w? {hs* vs* cm* hm* mt subpath}? {mt subpath}* endchar

The `w?` is the width of the glyph, but it's optional. So all
possible commands after it (hstem* vstem* cntrmask hintmask
moveto endchar) check if there's an extra number at the start
and interpret it as a width, for the very first command we read.

This was done by having an `is_first_command` local bool that
got set to false after the first command. That didn't work with
subrs: If the first command was a call to a subr that just pushed
a bunch of numbers, then the second command after it is the actual
first command.

Instead, move that bool into the state. Set it to false the
first time we try to read a width, since that means we just read
a command that could've been prefixed by a width.
This commit is contained in:
Nico Weber 2023-11-13 21:22:56 -05:00 committed by Andreas Kling
parent c0ffff7e88
commit 1c2b0feb7b
2 changed files with 6 additions and 5 deletions

View file

@ -244,15 +244,16 @@ PDFErrorOr<Type1FontProgram::Glyph> Type1FontProgram::parse_glyph(ReadonlyBytes
};
// Potential font width parsing for some commands (type2 only)
bool is_first_command = true;
enum EvenOrOdd {
Even,
Odd
};
auto maybe_read_width = [&](EvenOrOdd required_argument_count) {
if (!is_type2 || !is_first_command || state.sp % 2 != required_argument_count)
if (!is_type2 || !state.is_first_command)
return;
state.glyph.set_width(pop_front());
state.is_first_command = false;
if (state.sp % 2 == required_argument_count)
state.glyph.set_width(pop_front());
};
// Parse the stream of parameters and commands that make up a glyph outline.
@ -717,8 +718,6 @@ PDFErrorOr<Type1FontProgram::Glyph> Type1FontProgram::parse_glyph(ReadonlyBytes
dbgln("Unhandled command: {}", v);
return error("Unhandled command");
}
is_first_command = false;
}
}

View file

@ -79,6 +79,8 @@ protected:
size_t postscript_sp { 0 };
Array<float, 24> postscript_stack;
bool is_first_command { true };
};
static PDFErrorOr<Glyph> parse_glyph(ReadonlyBytes const&, Vector<ByteBuffer> const& local_subroutines, Vector<ByteBuffer> const& global_subroutines, GlyphParserState&, bool is_type2);