summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibPDF
diff options
context:
space:
mode:
authorRodrigo Tobar <rtobarc@gmail.com>2023-02-05 14:04:48 +0800
committerAndreas Kling <kling@serenityos.org>2023-02-08 19:47:15 +0100
commitc0849434574d064f798342f1ee1f0eda53c3dbd4 (patch)
tree342b15ffd53a7ebcc0fc498e8e17d513ccd6ffc3 /Userland/Libraries/LibPDF
parentf99c9dc11a932d302bd07f94370d7cb602076ee6 (diff)
downloadserenity-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/Libraries/LibPDF')
-rw-r--r--Userland/Libraries/LibPDF/Fonts/CFF.cpp20
-rw-r--r--Userland/Libraries/LibPDF/Fonts/PS1FontProgram.cpp3
-rw-r--r--Userland/Libraries/LibPDF/Fonts/Type1Font.cpp5
-rw-r--r--Userland/Libraries/LibPDF/Fonts/Type1FontProgram.cpp12
-rw-r--r--Userland/Libraries/LibPDF/Fonts/Type1FontProgram.h12
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;
};