mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 18:37:34 +00:00
LibPDF: Add initial CFF parsing
The Compat Font Format specification (Adobe's Technical Note #5176) is used by PDF's Type1C fonts to store their data. While being similar in spirit to PS1 Type 1 Font Programs, it was designed for a more compact representation and thus space reduction (but an increment on complexity). It also shares most of the charstring encoding logic, which is why the CFF class also inherits from Type1FontProgram. This initial implementation is still lacking many details, e.g.: * It doesn't include all the built-in CFF SIDs * It doesn't support CFF-provided SIDs (defaults those glyphs to the space character) * More checks in general
This commit is contained in:
parent
1ec4ad5eb6
commit
c4b45a82cd
3 changed files with 518 additions and 0 deletions
86
Userland/Libraries/LibPDF/Fonts/CFF.h
Normal file
86
Userland/Libraries/LibPDF/Fonts/CFF.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Rodrigo Tobar <rtobarc@gmail.com>.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Tuple.h>
|
||||
#include <AK/Types.h>
|
||||
#include <LibPDF/Error.h>
|
||||
#include <LibPDF/Fonts/Type1FontProgram.h>
|
||||
|
||||
namespace PDF {
|
||||
|
||||
class Reader;
|
||||
|
||||
class CFF : public Type1FontProgram {
|
||||
|
||||
private:
|
||||
// Table 9: Top DICT Operator Entries
|
||||
enum class TopDictOperator {
|
||||
Version = 0,
|
||||
Notice,
|
||||
FullName,
|
||||
FamilyName,
|
||||
Weight,
|
||||
FontBBox,
|
||||
// UniqueID = 13,
|
||||
// XUID,
|
||||
Charset = 15,
|
||||
Encoding,
|
||||
CharStrings,
|
||||
Private,
|
||||
// IsFixedPitch = (12 << 8 | 1),
|
||||
// ItalicAngle,
|
||||
// UnderlinePosition,
|
||||
// UnderlineThickness,
|
||||
// PaintType,
|
||||
};
|
||||
|
||||
enum class PrivDictOperator {
|
||||
Subrs = 19,
|
||||
DefaultWidthX,
|
||||
NominalWidthX,
|
||||
};
|
||||
|
||||
public:
|
||||
static PDFErrorOr<NonnullRefPtr<CFF>> create(ReadonlyBytes const&, RefPtr<Encoding> encoding);
|
||||
|
||||
// to private
|
||||
using Card8 = u8;
|
||||
using Card16 = u16;
|
||||
using Offset = i32;
|
||||
using OffSize = u8;
|
||||
using SID = u16;
|
||||
using DictOperand = Variant<int, float>;
|
||||
|
||||
static int load_int_dict_operand(u8 b0, Reader&);
|
||||
static float load_float_dict_operand(Reader&);
|
||||
static PDFErrorOr<DictOperand> load_dict_operand(u8, Reader&);
|
||||
|
||||
using IndexDataHandler = Function<PDFErrorOr<void>(ReadonlyBytes const&)>;
|
||||
static PDFErrorOr<void> parse_index(Reader& reader, IndexDataHandler&&);
|
||||
|
||||
template<typename OffsetType>
|
||||
static PDFErrorOr<void> parse_index_data(Card16 count, Reader& reader, IndexDataHandler&);
|
||||
|
||||
template<typename OperatorT>
|
||||
using DictEntryHandler = Function<PDFErrorOr<void>(OperatorT, Vector<DictOperand> const&)>;
|
||||
|
||||
template<typename OperatorT>
|
||||
static PDFErrorOr<void> parse_dict(Reader& reader, DictEntryHandler<OperatorT>&& handler);
|
||||
|
||||
template<typename OperatorT>
|
||||
static PDFErrorOr<OperatorT> parse_dict_operator(u8, Reader&);
|
||||
|
||||
static PDFErrorOr<Vector<CFF::Glyph>> parse_charstrings(Reader&&, Vector<ByteBuffer> const& subroutines);
|
||||
|
||||
static PDFErrorOr<Vector<DeprecatedFlyString>> parse_charset(Reader&&, size_t);
|
||||
static PDFErrorOr<Vector<u8>> parse_encoding(Reader&&);
|
||||
|
||||
static HashMap<SID, DeprecatedFlyString> builtin_names;
|
||||
};
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue