فهرست منبع

LibPDF: Load a few values off a type 3 font dictionary

Nico Weber 1 سال پیش
والد
کامیت
e0c0864ddf

+ 2 - 0
Userland/Libraries/LibPDF/CommonNames.h

@@ -37,6 +37,7 @@
     X(CIDFontType2)               \
     X(CIDSystemInfo)              \
     X(CIDToGIDMap)                \
+    X(CharProcs)                  \
     X(Colors)                     \
     X(ColorSpace)                 \
     X(Columns)                    \
@@ -86,6 +87,7 @@
     X(FontFile)                   \
     X(FontFile2)                  \
     X(FontFile3)                  \
+    X(FontMatrix)                 \
     X(FunctionType)               \
     X(Functions)                  \
     X(Gamma)                      \

+ 44 - 2
Userland/Libraries/LibPDF/Fonts/Type3Font.cpp

@@ -14,7 +14,32 @@ PDFErrorOr<void> Type3Font::initialize(Document* document, NonnullRefPtr<DictObj
 {
     TRY(SimpleFont::initialize(document, dict, font_size));
 
-    // FIXME: /CharProcs, /FontBBox, /FontMatrix, /Resources
+    // "TABLE 5.9 Entries in a Type 3 font dictionary"
+
+    if (!dict->contains(CommonNames::CharProcs))
+        return Error { Error::Type::MalformedPDF, "Type3 font missing /CharProcs" };
+    auto char_procs = TRY(document->resolve_to<DictObject>(dict->get_value(CommonNames::CharProcs)));
+    for (auto const& [name, value] : char_procs->map())
+        m_char_procs.set(name, TRY(document->resolve_to<StreamObject>(value)));
+
+    if (!dict->contains(CommonNames::FontMatrix))
+        return Error { Error::Type::MalformedPDF, "Type3 font missing /FontMatrix" };
+    auto font_matrix_object = TRY(document->resolve_to<ArrayObject>(dict->get_value(CommonNames::FontMatrix)));
+    if (font_matrix_object->size() != 6)
+        return Error { Error::Type::MalformedPDF, "Type3 font /FontMatrix must have 6 elements" };
+    font_matrix() = Gfx::AffineTransform {
+        TRY(document->resolve(font_matrix_object->at(0))).to_float(),
+        TRY(document->resolve(font_matrix_object->at(1))).to_float(),
+        TRY(document->resolve(font_matrix_object->at(2))).to_float(),
+        TRY(document->resolve(font_matrix_object->at(3))).to_float(),
+        TRY(document->resolve(font_matrix_object->at(4))).to_float(),
+        TRY(document->resolve(font_matrix_object->at(5))).to_float(),
+    };
+
+    if (dict->contains(CommonNames::Resources))
+        m_resources = TRY(document->resolve_to<DictObject>(dict->get_value(CommonNames::Resources)));
+
+    // FIXME: /FontBBox
 
     return {};
 }
@@ -28,8 +53,25 @@ void Type3Font::set_font_size(float)
 {
 }
 
-PDFErrorOr<void> Type3Font::draw_glyph(Gfx::Painter&, Gfx::FloatPoint, float, u8, Color)
+PDFErrorOr<void> Type3Font::draw_glyph(Gfx::Painter&, Gfx::FloatPoint, float, u8 char_code, Color)
 {
+    // "For each character code shown by a text-showing operator that uses a Type 3 font,
+    //  the consumer application does the following:""
+
+    // "1. Looks up the character code in the font’s Encoding entry, as described in Sec-
+    //  tion 5.5.5, “Character Encoding,” to obtain a character name."
+    auto char_name = encoding()->get_name(char_code);
+
+    // "2. Looks up the character name in the font’s CharProcs dictionary to obtain a
+    //  stream object containing a glyph description. (If the name is not present as a
+    //  key in CharProcs, no glyph is painted.)"
+    auto char_proc = m_char_procs.get(char_name);
+    if (!char_proc.has_value())
+        return {};
+
+    // "3. Invokes the glyph description, as described below."
+    // FIXME
+
     return Error { Error::Type::RenderingUnsupported, "Type3 fonts not yet implemented" };
 }
 }

+ 5 - 0
Userland/Libraries/LibPDF/Fonts/Type3Font.h

@@ -18,6 +18,11 @@ public:
 
 protected:
     PDFErrorOr<void> initialize(Document*, NonnullRefPtr<DictObject> const&, float font_size) override;
+
+private:
+    HashMap<DeprecatedFlyString, NonnullRefPtr<StreamObject>> m_char_procs;
+    Gfx::AffineTransform m_font_matrix;
+    Optional<NonnullRefPtr<DictObject>> m_resources;
 };
 
 }