summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodrigo Tobar <rtobarc@gmail.com>2023-02-05 14:23:07 +0800
committerAndreas Kling <kling@serenityos.org>2023-02-08 19:47:15 +0100
commit3eaa27f53ad5f6d99e984d693085dce9cf51261b (patch)
treeb7cc4f73787321969a3182222410aaa67b619181
parent11a9bfd4b6b10d27dec54f286b11242db0fd95a1 (diff)
downloadserenity-3eaa27f53ad5f6d99e984d693085dce9cf51261b.zip
LibPDF: Add infrastructure for accented character glyphs
Type1 accented character glyphs are composed of two other glyphs in the same font: a base glyph and an accent glyph, given as char codes in the standard encoding. These two glyphs are then composed together to form the accented character. This commit adds the data structures to hold the information for accented characters, and also the routine that composes the final glyph path out of the two individual components. All glyphs must have been loaded by the time this composition takes place, and thus a new protected consolidate_glyphs() routine has been added to perform this calculation.
-rw-r--r--Userland/Libraries/LibPDF/Fonts/CFF.cpp1
-rw-r--r--Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp1
-rw-r--r--Userland/Libraries/LibPDF/Fonts/Type1FontProgram.cpp18
-rw-r--r--Userland/Libraries/LibPDF/Fonts/Type1FontProgram.h23
4 files changed, 43 insertions, 0 deletions
diff --git a/Userland/Libraries/LibPDF/Fonts/CFF.cpp b/Userland/Libraries/LibPDF/Fonts/CFF.cpp
index eade5fc207..9c8ba8fe9c 100644
--- a/Userland/Libraries/LibPDF/Fonts/CFF.cpp
+++ b/Userland/Libraries/LibPDF/Fonts/CFF.cpp
@@ -116,6 +116,7 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
auto const& name = charset[i - 1];
TRY(cff->add_glyph(name, move(glyphs[i])));
}
+ cff->consolidate_glyphs();
// Encoding given or read
if (encoding) {
diff --git a/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp b/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp
index 38e87a5b55..5676e5ff9e 100644
--- a/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp
+++ b/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp
@@ -98,6 +98,7 @@ PDFErrorOr<void> PS1FontProgram::parse_encrypted_portion(ByteBuffer const& buffe
}
}
+ consolidate_glyphs();
return {};
}
diff --git a/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.cpp b/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.cpp
index 19b6a2075f..649fec3728 100644
--- a/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.cpp
+++ b/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.cpp
@@ -110,6 +110,24 @@ Gfx::AffineTransform Type1FontProgram::glyph_transform_to_device_space(Glyph con
return transform;
}
+void Type1FontProgram::consolidate_glyphs()
+{
+ for (auto& [name, glyph] : m_glyph_map) {
+ if (!glyph.is_accented_character())
+ continue;
+ auto maybe_base_glyph = m_glyph_map.get(glyph.accented_character().base_character);
+ if (!maybe_base_glyph.has_value())
+ continue;
+ auto glyph_path = maybe_base_glyph.value().path();
+ auto maybe_accent_glyph = m_glyph_map.get(glyph.accented_character().accent_character);
+ if (maybe_accent_glyph.has_value()) {
+ auto path = maybe_accent_glyph.value().path();
+ glyph_path.append_path(move(path));
+ }
+ glyph.path() = glyph_path;
+ }
+}
+
PDFErrorOr<Type1FontProgram::Glyph> Type1FontProgram::parse_glyph(ReadonlyBytes const& data, Vector<ByteBuffer> const& subroutines, GlyphParserState& state, bool is_type2)
{
auto push = [&](float value) -> PDFErrorOr<void> {
diff --git a/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.h b/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.h
index 7509f23be6..c06ed5c2c7 100644
--- a/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.h
+++ b/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.h
@@ -25,6 +25,19 @@ public:
RefPtr<Encoding> encoding() const { return m_encoding; }
protected:
+ struct AccentedCharacter {
+ AccentedCharacter(u8 base_char_code, u8 accent_char_code, float adx, float ady)
+ : base_character(Encoding::standard_encoding()->get_name(base_char_code))
+ , accent_character(Encoding::standard_encoding()->get_name(accent_char_code))
+ , accent_origin(adx, ady)
+ {
+ }
+
+ DeprecatedFlyString base_character;
+ DeprecatedFlyString accent_character;
+ Gfx::FloatPoint accent_origin;
+ };
+
class Glyph {
public:
@@ -38,9 +51,17 @@ protected:
Gfx::Path& path() { return m_path; }
Gfx::Path const& path() const { return m_path; }
+ bool is_accented_character() const { return m_accented_character.has_value(); }
+ AccentedCharacter const& accented_character() const { return m_accented_character.value(); }
+ void set_accented_character(AccentedCharacter&& accented_character)
+ {
+ m_accented_character = move(accented_character);
+ }
+
private:
Gfx::Path m_path;
Optional<float> m_width;
+ Optional<AccentedCharacter> m_accented_character;
};
struct GlyphParserState {
@@ -86,6 +107,8 @@ protected:
return {};
}
+ void consolidate_glyphs();
+
private:
HashMap<DeprecatedFlyString, Glyph> m_glyph_map;
Gfx::AffineTransform m_font_matrix;