From 2b905cc4826677a30a2b36f58ae35c078f7f03a7 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Sat, 13 Apr 2024 22:05:28 -0400 Subject: [PATCH] LibPDF: Move rest of CFF from Reader to Stream parse_index_data() wants to take ReadonlyByte views of the stream data, so we need FixedMemoryStream::read_in_place(size_t). All other remaining code indirectly calls parse_index_data(), so that all operates on FixedMemoryStreams too. No behavior change. --- Userland/Libraries/LibPDF/Fonts/CFF.cpp | 45 ++++++++++++------------- Userland/Libraries/LibPDF/Fonts/CFF.h | 12 +++---- 2 files changed, 27 insertions(+), 30 deletions(-) diff --git a/Userland/Libraries/LibPDF/Fonts/CFF.cpp b/Userland/Libraries/LibPDF/Fonts/CFF.cpp index b4ef20bdc94..5768186da42 100644 --- a/Userland/Libraries/LibPDF/Fonts/CFF.cpp +++ b/Userland/Libraries/LibPDF/Fonts/CFF.cpp @@ -13,7 +13,6 @@ #include #include #include -#include namespace PDF { @@ -97,15 +96,15 @@ static constexpr auto s_predefined_charset_expert_subset = to_array({ PDFErrorOr> CFF::create(ReadonlyBytes const& cff_bytes, RefPtr encoding) { - Reader reader(cff_bytes); + FixedMemoryStream reader(cff_bytes); // CFF spec, "6 Header" // skip major, minor version - reader.consume(2); - auto header_size = TRY(reader.try_read()); + TRY(reader.discard(2)); + auto header_size = TRY(reader.read_value()); // skip offset size - reader.consume(1); - reader.move_to(header_size); + TRY(reader.discard(1)); + TRY(reader.seek(header_size)); // CFF spec, "7 Name INDEX" Vector font_names; @@ -157,7 +156,7 @@ PDFErrorOr> CFF::create(ReadonlyBytes const& cff_bytes, RefPt dbgln_if(CFF_DEBUG, "CFF has {} gsubr entries", global_subroutines.size()); // Create glyphs (now that we have the subroutines) and associate missing information to store them and their encoding - auto glyphs = TRY(parse_charstrings(Reader(cff_bytes.slice(top_dict.charstrings_offset)), top_dict.local_subroutines, global_subroutines)); + auto glyphs = TRY(parse_charstrings(FixedMemoryStream(cff_bytes.slice(top_dict.charstrings_offset)), top_dict.local_subroutines, global_subroutines)); // CFF spec, "Table 16 Encoding ID" // FIXME: Only read this if the built-in encoding is actually needed? (ie. `if (!encoding)`) @@ -216,7 +215,7 @@ PDFErrorOr> CFF::create(ReadonlyBytes const& cff_bytes, RefPt // CFF spec, "18 CID-keyed Fonts" Vector font_dicts; if (top_dict.fdarray_offset != 0) { - Reader fdarray_reader { cff_bytes.slice(top_dict.fdarray_offset) }; + FixedMemoryStream fdarray_reader { cff_bytes.slice(top_dict.fdarray_offset) }; font_dicts = TRY(parse_top_dicts(fdarray_reader, cff_bytes)); dbgln_if(CFF_DEBUG, "CFF has {} FDArray entries", font_dicts.size()); } @@ -294,7 +293,7 @@ PDFErrorOr> CFF::create(ReadonlyBytes const& cff_bytes, RefPt return cff; } -PDFErrorOr> CFF::parse_top_dicts(Reader& reader, ReadonlyBytes const& cff_bytes) +PDFErrorOr> CFF::parse_top_dicts(FixedMemoryStream& reader, ReadonlyBytes const& cff_bytes) { Vector top_dicts; @@ -379,7 +378,7 @@ PDFErrorOr> CFF::parse_top_dicts(Reader& reader, ReadonlyBy // CFF spec, "16 Local/Global Subrs INDEXes" // "Local subrs are stored in an INDEX structure which is located via the offset operand of the Subrs operator in the Private DICT." auto subrs_offset = operands[0].get(); - Reader subrs_reader { cff_bytes.slice(private_dict_offset + subrs_offset) }; + FixedMemoryStream subrs_reader { cff_bytes.slice(private_dict_offset + subrs_offset) }; TRY(parse_index(subrs_reader, [&](ReadonlyBytes const& subroutine_bytes) -> PDFErrorOr { return TRY(top_dict.local_subroutines.try_append(TRY(ByteBuffer::copy(subroutine_bytes)))); })); @@ -831,7 +830,7 @@ static constexpr Array s_cff_builtin_names { "Semibold"sv, }; -PDFErrorOr> CFF::parse_strings(Reader& reader) +PDFErrorOr> CFF::parse_strings(FixedMemoryStream& reader) { // CFF spec "10 String Index" Vector strings; @@ -940,7 +939,7 @@ PDFErrorOr> CFF::parse_fdselect(Stream&& reader, size_t glyph_count) return fd_selector_array; } -PDFErrorOr> CFF::parse_charstrings(Reader&& reader, Vector const& local_subroutines, Vector const& global_subroutines) +PDFErrorOr> CFF::parse_charstrings(FixedMemoryStream&& reader, Vector const& local_subroutines, Vector const& global_subroutines) { // CFF spec, "14 CharStrings INDEX" Vector glyphs; @@ -1034,19 +1033,19 @@ PDFErrorOr CFF::parse_dict_operator(u8 b0, Stream& reader) template PDFErrorOr CFF::parse_dict_operator(u8, Stream&); -PDFErrorOr CFF::parse_index(Reader& reader, IndexDataHandler&& data_handler) +PDFErrorOr CFF::parse_index(FixedMemoryStream& reader, IndexDataHandler&& data_handler) { // CFF spec, "5 INDEX Data" - Card16 count = TRY(reader.try_read>()); + Card16 count = TRY(reader.read_value>()); if (count == 0) return {}; - auto offset_size = TRY(reader.try_read()); + auto offset_size = TRY(reader.read_value()); if (offset_size > 4) return error("CFF INDEX Data offset_size > 4 not supported"); return parse_index_data(offset_size, count, reader, data_handler); } -PDFErrorOr CFF::parse_index_data(OffSize offset_size, Card16 count, Reader& reader, IndexDataHandler& handler) +PDFErrorOr CFF::parse_index_data(OffSize offset_size, Card16 count, FixedMemoryStream& reader, IndexDataHandler& handler) { // CFF spec, "5 INDEX Data" u32 last_data_end = 1; @@ -1054,24 +1053,24 @@ PDFErrorOr CFF::parse_index_data(OffSize offset_size, Card16 count, Reader auto read_offset = [&]() -> PDFErrorOr { u32 offset = 0; for (OffSize i = 0; i < offset_size; ++i) - offset = (offset << 8) | TRY(reader.try_read()); + offset = (offset << 8) | TRY(reader.read_value()); return offset; }; auto offset_refpoint = reader.offset() + offset_size * (count + 1) - 1; for (u16 i = 0; i < count; i++) { - reader.save(); + auto saved_offset = TRY(reader.tell()); - reader.move_by(offset_size * i); + TRY(reader.seek(offset_size * i, SeekMode::FromCurrentPosition)); u32 data_start = TRY(read_offset()); last_data_end = TRY(read_offset()); auto data_size = last_data_end - data_start; - reader.move_to(offset_refpoint + data_start); - TRY(handler(reader.bytes().slice(reader.offset(), data_size))); - reader.load(); + TRY(reader.seek(offset_refpoint + data_start)); + TRY(handler(TRY(reader.read_in_place(data_size)))); + TRY(reader.seek(saved_offset)); } - reader.move_to(offset_refpoint + last_data_end); + TRY(reader.seek(offset_refpoint + last_data_end)); return {}; } diff --git a/Userland/Libraries/LibPDF/Fonts/CFF.h b/Userland/Libraries/LibPDF/Fonts/CFF.h index e9a627eb1ca..0a3decbcf3c 100644 --- a/Userland/Libraries/LibPDF/Fonts/CFF.h +++ b/Userland/Libraries/LibPDF/Fonts/CFF.h @@ -12,8 +12,6 @@ namespace PDF { -class Reader; - // CFF spec: https://adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf class CFF : public Type1FontProgram { @@ -104,9 +102,9 @@ public: static PDFErrorOr load_dict_operand(u8, Stream&); using IndexDataHandler = Function(ReadonlyBytes const&)>; - static PDFErrorOr parse_index(Reader& reader, IndexDataHandler&&); + static PDFErrorOr parse_index(FixedMemoryStream&, IndexDataHandler&&); - static PDFErrorOr parse_index_data(OffSize offset_size, Card16 count, Reader& reader, IndexDataHandler&); + static PDFErrorOr parse_index_data(OffSize offset_size, Card16 count, FixedMemoryStream&, IndexDataHandler&); template using DictEntryHandler = Function(OperatorT, Vector const&)>; @@ -129,11 +127,11 @@ public: int fdselect_offset = 0; int fdarray_offset = 0; }; - static PDFErrorOr> parse_top_dicts(Reader&, ReadonlyBytes const& cff_bytes); + static PDFErrorOr> parse_top_dicts(FixedMemoryStream&, ReadonlyBytes const& cff_bytes); - static PDFErrorOr> parse_strings(Reader&); + static PDFErrorOr> parse_strings(FixedMemoryStream&); - static PDFErrorOr> parse_charstrings(Reader&&, Vector const& local_subroutines, Vector const& global_subroutines); + static PDFErrorOr> parse_charstrings(FixedMemoryStream&&, Vector const& local_subroutines, Vector const& global_subroutines); static DeprecatedFlyString resolve_sid(SID, Vector const&); static PDFErrorOr> parse_charset(Stream&&, size_t);