mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-09-11 13:36:13 +03:00
LibPDF: Fix sign (and fixed point) in glyph decoding opcode 24
Two bugs: 1. We decoded a u32, not an i32 as the spec wants 2. (minor) Our fixed-point divisor was off by one Fixes text rendering in Bakke2010a.pdf in pdffiles, and rendering of other fonts with negative width adjustments from optcode 255. That PDF was produced by "Apple pstopdf" and uses font SFBX1200, which is apparently a variant of Computer Modern. So maybe this helps with lots of PDFs produced from TeX files, but I haven't checked that.
This commit is contained in:
parent
96a4936567
commit
007d7cdd53
Notes:
sideshowbarker
2024-07-16 21:51:02 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/007d7cdd53 Pull-request: https://github.com/SerenityOS/serenity/pull/21453 Reviewed-by: https://github.com/AtkinsSJ Reviewed-by: https://github.com/Hendiadyoin1 Reviewed-by: https://github.com/awesomekling Reviewed-by: https://github.com/gmta
@ -135,6 +135,9 @@ void Type1FontProgram::consolidate_glyphs()
|
||||
|
||||
PDFErrorOr<Type1FontProgram::Glyph> Type1FontProgram::parse_glyph(ReadonlyBytes const& data, Vector<ByteBuffer> const& subroutines, GlyphParserState& state, bool is_type2)
|
||||
{
|
||||
// Type 1 Font Format: https://adobe-type-tools.github.io/font-tech-notes/pdfs/T1_SPEC.pdf (Chapter 6: CharStrings dictionary)
|
||||
// Type 2 Charstring Format: https://adobe-type-tools.github.io/font-tech-notes/pdfs/5177.Type2.pdf
|
||||
|
||||
auto push = [&](float value) -> PDFErrorOr<void> {
|
||||
if (state.sp >= state.stack.size())
|
||||
return error("Operand stack overflow");
|
||||
@ -250,16 +253,17 @@ PDFErrorOr<Type1FontProgram::Glyph> Type1FontProgram::parse_glyph(ReadonlyBytes
|
||||
int v = data[i];
|
||||
if (v == 255) {
|
||||
TRY(require(4));
|
||||
int a = data[++i];
|
||||
int b = data[++i];
|
||||
int c = data[++i];
|
||||
int d = data[++i];
|
||||
// Both Type 1 and Type 2 spec:
|
||||
// "If the charstring byte contains the value 255, the next four bytes indicate a two’s complement signed number.
|
||||
// The first of these four bytes contains the highest order bits [...]"
|
||||
i32 a = static_cast<i32>((data[i + 1] << 24) | (data[i + 2] << 16) | (data[i + 3] << 8) | data[i + 4]);
|
||||
i += 4;
|
||||
if (is_type2) {
|
||||
auto integer = float((a << 8) | b);
|
||||
auto fraction = float((c << 8) | d) / AK::NumericLimits<u16>::max();
|
||||
TRY(push(integer + fraction));
|
||||
} else
|
||||
TRY(push((a << 24) + (b << 16) + (c << 8) + d));
|
||||
// Just in the Type 2 spec: "This number is interpreted as a Fixed; that is, a signed number with 16 bits of fraction."
|
||||
TRY(push(a / (float)0x1'0000));
|
||||
} else {
|
||||
TRY(push(a));
|
||||
}
|
||||
} else if (v >= 251) {
|
||||
TRY(require(1));
|
||||
auto w = data[++i];
|
||||
|
Loading…
Reference in New Issue
Block a user