diff options
author | Rodrigo Tobar <rtobarc@gmail.com> | 2023-02-05 14:04:48 +0800 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-02-08 19:47:15 +0100 |
commit | c0849434574d064f798342f1ee1f0eda53c3dbd4 (patch) | |
tree | 342b15ffd53a7ebcc0fc498e8e17d513ccd6ffc3 /Userland | |
parent | f99c9dc11a932d302bd07f94370d7cb602076ee6 (diff) | |
download | serenity-c0849434574d064f798342f1ee1f0eda53c3dbd4.zip |
LibPDF: Index Type1 glyphs by name, not char code
Storing glyphs indexed by char code in a Type1 Font Program binds a Font
Program instance to the particular Encoding that was used at Font
Program construction time. This makes it difficult to reuse Font Program
instances against different Encodings, which would be otherwise
possible.
This commit changes how we store the glyphs on Type1 Font Programs.
Instead of storing them on a map indexed by char code, the map is now
indexed by glyph name. In turn, when rendering a glyph we use the
Encoding object to turn the char code into a glyph name, which in turn
is used to index into the map of glyphs.
This is the first step towards reusability of Type1 Font Programs. It
also unlocks the ability to render glyphs that are described via the
"seac" command (standard encoding accented character), which requires
accessing the base and accent glyphs by name.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibPDF/Fonts/CFF.cpp | 20 | ||||
-rw-r--r-- | Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp | 3 | ||||
-rw-r--r-- | Userland/Libraries/LibPDF/Fonts/Type1Font.cpp | 5 | ||||
-rw-r--r-- | Userland/Libraries/LibPDF/Fonts/Type1FontProgram.cpp | 12 | ||||
-rw-r--r-- | Userland/Libraries/LibPDF/Fonts/Type1FontProgram.h | 12 |
5 files changed, 25 insertions, 27 deletions
diff --git a/Userland/Libraries/LibPDF/Fonts/CFF.cpp b/Userland/Libraries/LibPDF/Fonts/CFF.cpp index 2aad6a1b07..63e856c13e 100644 --- a/Userland/Libraries/LibPDF/Fonts/CFF.cpp +++ b/Userland/Libraries/LibPDF/Fonts/CFF.cpp @@ -108,29 +108,27 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt glyph.width += float(nominalWidthX); } + for (size_t i = 0; i < glyphs.size(); i++) { + if (i == 0) { + TRY(cff->add_glyph(0, move(glyphs[0]))); + continue; + } + auto const& name = charset[i - 1]; + TRY(cff->add_glyph(name, move(glyphs[i]))); + } + // Encoding given or read if (encoding) { - for (size_t i = 0; i < glyphs.size(); i++) { - if (i == 0) { - TRY(cff->add_glyph(0, move(glyphs[0]))); - continue; - } - auto const& name = charset[i - 1]; - u16 code = encoding->get_char_code(name); - TRY(cff->add_glyph(code, move(glyphs[i]))); - } cff->set_encoding(move(encoding)); } else { auto encoding = Encoding::create(); for (size_t i = 0; i < glyphs.size(); i++) { if (i == 0) { - TRY(cff->add_glyph(0, move(glyphs[0]))); encoding->set(0, ".notdef"); continue; } auto code = encoding_codes[i - 1]; auto char_name = charset[i - 1]; - TRY(cff->add_glyph(code, move(glyphs[i]))); encoding->set(code, char_name); } cff->set_encoding(move(encoding)); diff --git a/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp b/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp index b7a813a8a3..38e87a5b55 100644 --- a/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp +++ b/Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp @@ -92,9 +92,8 @@ PDFErrorOr<void> PS1FontProgram::parse_encrypted_portion(ByteBuffer const& buffe auto line = TRY(decrypt(reader.bytes().slice(reader.offset(), encrypted_size), m_encryption_key, m_lenIV)); reader.move_by(encrypted_size); auto glyph_name = word.substring_view(1); - auto char_code = encoding()->get_char_code(glyph_name); GlyphParserState state; - TRY(add_glyph(char_code, TRY(parse_glyph(line, subroutines, state, false)))); + TRY(add_glyph(glyph_name, TRY(parse_glyph(line, subroutines, state, false)))); } } } diff --git a/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp b/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp index 334c5ce991..4c97c98701 100644 --- a/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp +++ b/Userland/Libraries/LibPDF/Fonts/Type1Font.cpp @@ -86,7 +86,8 @@ void Type1Font::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float w return; } - auto translation = m_data.font_program->glyph_translation(char_code, width); + auto char_name = m_data.encoding->get_name(char_code); + auto translation = m_data.font_program->glyph_translation(char_name, width); point = point.translated(translation); auto glyph_position = Gfx::GlyphRasterPosition::get_nearest_fit_for(point); @@ -97,7 +98,7 @@ void Type1Font::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float w if (maybe_bitmap.has_value()) { bitmap = maybe_bitmap.value(); } else { - bitmap = m_data.font_program->rasterize_glyph(char_code, width, glyph_position.subpixel_offset); + bitmap = m_data.font_program->rasterize_glyph(char_name, width, glyph_position.subpixel_offset); m_glyph_cache.set(index, bitmap); } diff --git a/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.cpp b/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.cpp index 920e344927..060fad86de 100644 --- a/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.cpp +++ b/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.cpp @@ -52,9 +52,9 @@ enum ExtendedCommand { Flex1, }; -RefPtr<Gfx::Bitmap> Type1FontProgram::rasterize_glyph(u32 char_code, float width, Gfx::GlyphSubpixelOffset subpixel_offset) +RefPtr<Gfx::Bitmap> Type1FontProgram::rasterize_glyph(DeprecatedFlyString const& char_name, float width, Gfx::GlyphSubpixelOffset subpixel_offset) { - auto path = build_char(char_code, width, subpixel_offset); + auto path = build_char(char_name, width, subpixel_offset); auto bounding_box = path.bounding_box().size(); u32 w = (u32)ceilf(bounding_box.width()) + 2; @@ -65,9 +65,9 @@ RefPtr<Gfx::Bitmap> Type1FontProgram::rasterize_glyph(u32 char_code, float width return rasterizer.accumulate(); } -Gfx::Path Type1FontProgram::build_char(u32 char_code, float width, Gfx::GlyphSubpixelOffset subpixel_offset) +Gfx::Path Type1FontProgram::build_char(DeprecatedFlyString const& char_name, float width, Gfx::GlyphSubpixelOffset subpixel_offset) { - auto maybe_glyph = m_glyph_map.get(char_code); + auto maybe_glyph = m_glyph_map.get(char_name); if (!maybe_glyph.has_value()) return {}; @@ -84,9 +84,9 @@ Gfx::Path Type1FontProgram::build_char(u32 char_code, float width, Gfx::GlyphSub return glyph.path.copy_transformed(transform); } -Gfx::FloatPoint Type1FontProgram::glyph_translation(u32 char_code, float width) const +Gfx::FloatPoint Type1FontProgram::glyph_translation(DeprecatedFlyString const& char_name, float width) const { - auto maybe_glyph = m_glyph_map.get(char_code); + auto maybe_glyph = m_glyph_map.get(char_name); if (!maybe_glyph.has_value()) return {}; diff --git a/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.h b/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.h index c4240a7cf3..a6e2140f7e 100644 --- a/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.h +++ b/Userland/Libraries/LibPDF/Fonts/Type1FontProgram.h @@ -20,8 +20,8 @@ class Encoding; class Type1FontProgram : public RefCounted<Type1FontProgram> { public: - RefPtr<Gfx::Bitmap> rasterize_glyph(u32 char_code, float width, Gfx::GlyphSubpixelOffset subpixel_offset); - Gfx::FloatPoint glyph_translation(u32 char_code, float width) const; + RefPtr<Gfx::Bitmap> rasterize_glyph(DeprecatedFlyString const& char_name, float width, Gfx::GlyphSubpixelOffset subpixel_offset); + Gfx::FloatPoint glyph_translation(DeprecatedFlyString const& char_name, float width) const; RefPtr<Encoding> encoding() const { return m_encoding; } protected: @@ -68,18 +68,18 @@ protected: m_font_matrix = move(font_matrix); } - PDFErrorOr<void> add_glyph(u16 char_code, Glyph&& glyph) + PDFErrorOr<void> add_glyph(DeprecatedFlyString name, Glyph&& glyph) { - TRY(m_glyph_map.try_set(char_code, glyph)); + TRY(m_glyph_map.try_set(move(name), move(glyph))); return {}; } private: - HashMap<u16, Glyph> m_glyph_map; + HashMap<DeprecatedFlyString, Glyph> m_glyph_map; Gfx::AffineTransform m_font_matrix; RefPtr<Encoding> m_encoding; - Gfx::Path build_char(u32 char_code, float width, Gfx::GlyphSubpixelOffset subpixel_offset); + Gfx::Path build_char(DeprecatedFlyString const& char_name, float width, Gfx::GlyphSubpixelOffset subpixel_offset); Gfx::AffineTransform glyph_transform_to_device_space(Glyph const& glyph, float width) const; }; |