|
@@ -13,81 +13,58 @@
|
|
|
|
|
|
namespace PDF {
|
|
|
|
|
|
-PDFErrorOr<Type1Font::Data> Type1Font::parse_data(Document* document, NonnullRefPtr<DictObject> dict, float font_size)
|
|
|
+PDFErrorOr<void> Type1Font::initialize(Document* document, NonnullRefPtr<DictObject> const& dict, float font_size)
|
|
|
{
|
|
|
- Type1Font::Data data;
|
|
|
- TRY(data.load_from_dict(document, dict, font_size));
|
|
|
+ TRY(SimpleFont::initialize(document, dict, font_size));
|
|
|
|
|
|
- if (!data.is_standard_font) {
|
|
|
+ // auto is_standard_font = is_standard_latin_font(font->base_font_name());
|
|
|
+
|
|
|
+ // If there's an embedded font program we use that; otherwise we try to find a replacement font
|
|
|
+ if (dict->contains(CommonNames::FontDescriptor)) {
|
|
|
auto descriptor = TRY(dict->get_dict(document, CommonNames::FontDescriptor));
|
|
|
if (descriptor->contains(CommonNames::FontFile3)) {
|
|
|
auto font_file_stream = TRY(descriptor->get_stream(document, CommonNames::FontFile3));
|
|
|
auto font_file_dict = font_file_stream->dict();
|
|
|
if (font_file_dict->contains(CommonNames::Subtype) && font_file_dict->get_name(CommonNames::Subtype)->name() == CommonNames::Type1C) {
|
|
|
- data.font_program = TRY(CFF::create(font_file_stream->bytes(), data.encoding));
|
|
|
- if (!data.encoding)
|
|
|
- data.encoding = data.font_program->encoding();
|
|
|
- return data;
|
|
|
+ m_font_program = TRY(CFF::create(font_file_stream->bytes(), encoding()));
|
|
|
}
|
|
|
- }
|
|
|
- if (!descriptor->contains(CommonNames::FontFile))
|
|
|
- return data;
|
|
|
-
|
|
|
- auto font_file_stream = TRY(descriptor->get_stream(document, CommonNames::FontFile));
|
|
|
- auto font_file_dict = font_file_stream->dict();
|
|
|
-
|
|
|
- if (!font_file_dict->contains(CommonNames::Length1, CommonNames::Length2))
|
|
|
- return Error { Error::Type::Parse, "Embedded type 1 font is incomplete" };
|
|
|
+ } else if (descriptor->contains(CommonNames::FontFile)) {
|
|
|
+ auto font_file_stream = TRY(descriptor->get_stream(document, CommonNames::FontFile));
|
|
|
+ auto font_file_dict = font_file_stream->dict();
|
|
|
|
|
|
- auto length1 = TRY(document->resolve(font_file_dict->get_value(CommonNames::Length1))).get<int>();
|
|
|
- auto length2 = TRY(document->resolve(font_file_dict->get_value(CommonNames::Length2))).get<int>();
|
|
|
+ if (!font_file_dict->contains(CommonNames::Length1, CommonNames::Length2))
|
|
|
+ return Error::parse_error("Embedded type 1 font is incomplete"sv);
|
|
|
|
|
|
- data.font_program = TRY(PS1FontProgram::create(font_file_stream->bytes(), data.encoding, length1, length2));
|
|
|
+ auto length1 = TRY(document->resolve(font_file_dict->get_value(CommonNames::Length1))).get<int>();
|
|
|
+ auto length2 = TRY(document->resolve(font_file_dict->get_value(CommonNames::Length2))).get<int>();
|
|
|
|
|
|
- if (!data.encoding)
|
|
|
- data.encoding = data.font_program->encoding();
|
|
|
+ m_font_program = TRY(PS1FontProgram::create(font_file_stream->bytes(), encoding(), length1, length2));
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- return data;
|
|
|
-}
|
|
|
-
|
|
|
-PDFErrorOr<NonnullRefPtr<Type1Font>> Type1Font::create(Document* document, NonnullRefPtr<DictObject> dict, float font_size)
|
|
|
-{
|
|
|
- auto data = TRY(Type1Font::parse_data(document, dict, font_size));
|
|
|
- return adopt_ref(*new Type1Font(data));
|
|
|
-}
|
|
|
-
|
|
|
-Type1Font::Type1Font(Data data)
|
|
|
- : m_data(move(data))
|
|
|
-{
|
|
|
- m_is_standard_font = m_data.is_standard_font;
|
|
|
-}
|
|
|
-
|
|
|
-float Type1Font::get_char_width(u16 char_code) const
|
|
|
-{
|
|
|
- u16 width;
|
|
|
- if (auto char_code_width = m_data.widths.get(char_code); char_code_width.has_value()) {
|
|
|
- width = char_code_width.value();
|
|
|
- } else {
|
|
|
- width = m_data.missing_width;
|
|
|
+ if (!m_font_program) {
|
|
|
+ m_font = TRY(replacement_for(base_font_name().to_lowercase(), font_size));
|
|
|
}
|
|
|
|
|
|
- return static_cast<float>(width) / 1000.0f;
|
|
|
+ VERIFY(m_font_program || m_font);
|
|
|
+ return {};
|
|
|
}
|
|
|
|
|
|
-void Type1Font::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float width, u32 char_code, Color color)
|
|
|
+void Type1Font::draw_glyph(Gfx::Painter& painter, Gfx::FloatPoint point, float width, u8 char_code, Color color)
|
|
|
{
|
|
|
- if (!m_data.font_program) {
|
|
|
- if (m_data.font) {
|
|
|
- // Account for the reversed font baseline
|
|
|
- auto position = point.translated(0, -m_data.font->baseline());
|
|
|
- painter.draw_glyph(position, char_code, *m_data.font, color);
|
|
|
- }
|
|
|
+ if (!m_font_program) {
|
|
|
+ // Account for the reversed font baseline
|
|
|
+ auto position = point.translated(0, -m_font->baseline());
|
|
|
+ painter.draw_glyph(position, char_code, *m_font, color);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- auto char_name = m_data.encoding->get_name(char_code);
|
|
|
- auto translation = m_data.font_program->glyph_translation(char_name, width);
|
|
|
+ auto effective_encoding = encoding();
|
|
|
+ if (!effective_encoding)
|
|
|
+ effective_encoding = m_font_program->encoding();
|
|
|
+ if (!effective_encoding)
|
|
|
+ effective_encoding = Encoding::standard_encoding();
|
|
|
+ auto char_name = effective_encoding->get_name(char_code);
|
|
|
+ auto translation = m_font_program->glyph_translation(char_name, width);
|
|
|
point = point.translated(translation);
|
|
|
|
|
|
auto glyph_position = Gfx::GlyphRasterPosition::get_nearest_fit_for(point);
|
|
@@ -98,7 +75,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_name, width, glyph_position.subpixel_offset);
|
|
|
+ bitmap = m_font_program->rasterize_glyph(char_name, width, glyph_position.subpixel_offset);
|
|
|
m_glyph_cache.set(index, bitmap);
|
|
|
}
|
|
|
|