1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 12:07:45 +00:00

LibPDF: Sketch out Type0 font support some more

Type0 fonts can be either CFF-based or TrueType-based.
Create a subclass for each, put in some spec text, and
give each case a dedicated error code, so that `--debugging-stats`
can tell me which branch is more common.
This commit is contained in:
Nico Weber 2023-07-24 14:32:47 -04:00 committed by Andreas Kling
parent 0f21b35d1c
commit 715b6f868f
3 changed files with 73 additions and 2 deletions

View file

@ -27,6 +27,8 @@
A(CF) \ A(CF) \
A(CFM) \ A(CFM) \
A(CalRGB) \ A(CalRGB) \
A(CIDFontType0) \
A(CIDFontType2) \
A(CIDSystemInfo) \ A(CIDSystemInfo) \
A(CIDToGIDMap) \ A(CIDToGIDMap) \
A(Colors) \ A(Colors) \

View file

@ -9,6 +9,57 @@
namespace PDF { namespace PDF {
class CIDFontType {
public:
virtual ~CIDFontType() = default;
virtual PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Color const&, float, float, float, float) = 0;
};
class CIDFontType0 : public CIDFontType {
public:
PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Color const&, float, float, float, float) override;
};
PDFErrorOr<Gfx::FloatPoint> CIDFontType0::draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Color const&, float, float, float, float)
{
// ISO 32000 (PDF 2.0) 9.7.4.2 Glyph selection in CIDFonts
// "When the CIDFont contains an embedded font program that is represented in the Compact Font Format (CFF),
// the FontFile3 entry in the font descriptor (...) shall be either CIDFontType0C or OpenType.
// There are two cases, depending on the contents of the font program:
// * The "CFF" font program has a Top DICT that uses CIDFont operators: The CIDs shall be used to determine
// the GID value for the glyph procedure using the charset table in the CFF program.
// The GID value shall then be used to look up the glyph procedure using the CharStrings INDEX table [...]
// * The "CFF" font program has a Top DICT that does not use CIDFont operators: The CIDs shall be used
// directly as GID values, and the glyph procedure shall be retrieved using the CharStrings INDEX"
return Error::rendering_unsupported_error("Type0 font CIDFontType0 not implemented yet");
}
class CIDFontType2 : public CIDFontType {
public:
PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Color const&, float, float, float, float) override;
};
PDFErrorOr<Gfx::FloatPoint> CIDFontType2::draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Color const&, float, float, float, float)
{
// ISO 32000 (PDF 2.0) 9.7.4.2 Glyph selection in CIDFonts
// "For Type 2, the CIDFont program is actually a TrueType font program, which has no native notion of CIDs.
// In a TrueType font program, glyph descriptions are identified by glyph index values.
// Glyph indices are internal to the font and are not defined consistently from one font to another.
// Instead, a TrueType font program contains a "cmap" table that provides mappings directly from
// character codes to glyph indices for one or more predefined encodings.
// TrueType font programs are integrated with the CID-keyed font architecture in one of two ways,
// depending on whether the font program is embedded in the PDF file:
// * If the TrueType font program is embedded, the Type 2 CIDFont dictionary shall contain a CIDToGIDMap entry
// that maps CIDs to the glyph indices for the appropriate glyph descriptions in that font program.
// * If the TrueType font program is not embedded but is referenced by name, and the Type 2 CIDFont dictionary
// contains a CIDToGIDMap entry, the CIDToGIDMap entry shall be ignored, since it is not meaningful
/// to refer to glyph indices in an external font program."
return Error::rendering_unsupported_error("Type0 font CIDFontType2 not implemented yet");
}
Type0Font::Type0Font() = default;
Type0Font::~Type0Font() = default;
PDFErrorOr<void> Type0Font::initialize(Document* document, NonnullRefPtr<DictObject> const& dict, float font_size) PDFErrorOr<void> Type0Font::initialize(Document* document, NonnullRefPtr<DictObject> const& dict, float font_size)
{ {
TRY(PDFFont::initialize(document, dict, font_size)); TRY(PDFFont::initialize(document, dict, font_size));
@ -27,6 +78,17 @@ PDFErrorOr<void> Type0Font::initialize(Document* document, NonnullRefPtr<DictObj
u8 supplement = system_info_dict->get_value(CommonNames::Supplement).get<int>(); u8 supplement = system_info_dict->get_value(CommonNames::Supplement).get<int>();
CIDSystemInfo system_info { registry, ordering, supplement }; CIDSystemInfo system_info { registry, ordering, supplement };
auto subtype = TRY(descendant_font->get_name(document, CommonNames::Subtype))->name();
if (subtype == CommonNames::CIDFontType0) {
// CFF-based
m_cid_font_type = TRY(try_make<CIDFontType0>());
} else if (subtype == CommonNames::CIDFontType2) {
// TrueType-based
m_cid_font_type = TRY(try_make<CIDFontType2>());
} else {
return Error { Error::Type::MalformedPDF, "invalid /Subtype for Type 0 font" };
}
auto font_descriptor = TRY(descendant_font->get_dict(document, CommonNames::FontDescriptor)); auto font_descriptor = TRY(descendant_font->get_dict(document, CommonNames::FontDescriptor));
u16 default_width = 1000; u16 default_width = 1000;
@ -91,9 +153,9 @@ void Type0Font::set_font_size(float)
{ {
} }
PDFErrorOr<Gfx::FloatPoint> Type0Font::draw_string(Gfx::Painter&, Gfx::FloatPoint, DeprecatedString const&, Color const&, float, float, float, float) PDFErrorOr<Gfx::FloatPoint> Type0Font::draw_string(Gfx::Painter& painter, Gfx::FloatPoint glyph_position, DeprecatedString const& string, Color const& paint_color, float font_size, float character_spacing, float word_spacing, float horizontal_scaling)
{ {
return Error::rendering_unsupported_error("Type0 font not implemented yet"); return m_cid_font_type->draw_string(painter, glyph_position, string, paint_color, font_size, character_spacing, word_spacing, horizontal_scaling);
} }
} }

View file

@ -6,11 +6,14 @@
#pragma once #pragma once
#include <AK/OwnPtr.h>
#include <LibGfx/Point.h> #include <LibGfx/Point.h>
#include <LibPDF/Fonts/PDFFont.h> #include <LibPDF/Fonts/PDFFont.h>
namespace PDF { namespace PDF {
class CIDFontType;
struct CIDSystemInfo { struct CIDSystemInfo {
DeprecatedString registry; DeprecatedString registry;
DeprecatedString ordering; DeprecatedString ordering;
@ -19,6 +22,9 @@ struct CIDSystemInfo {
class Type0Font : public PDFFont { class Type0Font : public PDFFont {
public: public:
Type0Font();
~Type0Font();
void set_font_size(float font_size) override; void set_font_size(float font_size) override;
PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint pos, DeprecatedString const&, Color const&, float, float, float, float) override; PDFErrorOr<Gfx::FloatPoint> draw_string(Gfx::Painter&, Gfx::FloatPoint pos, DeprecatedString const&, Color const&, float, float, float, float) override;
Type type() const override { return PDFFont::Type::Type0; } Type type() const override { return PDFFont::Type::Type0; }
@ -32,6 +38,7 @@ private:
CIDSystemInfo m_system_info; CIDSystemInfo m_system_info;
HashMap<u16, u16> m_widths; HashMap<u16, u16> m_widths;
u16 m_missing_width; u16 m_missing_width;
OwnPtr<CIDFontType> m_cid_font_type;
}; };
} }