LibPDF/CFF: Store if a font program is CID-keyed
...and reject CID-keyed font programs for Type1 fonts.
This commit is contained in:
parent
bb7d29d007
commit
7494f24430
Notes:
sideshowbarker
2024-07-17 06:24:08 +09:00
Author: https://github.com/nico Commit: https://github.com/SerenityOS/serenity/commit/7494f24430 Pull-request: https://github.com/SerenityOS/serenity/pull/23194
4 changed files with 26 additions and 0 deletions
|
@ -126,6 +126,11 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
|
|||
return error("CFFs with more than one font not yet implemented");
|
||||
auto const& top_dict = top_dicts[0];
|
||||
|
||||
if (top_dict.is_cid_keyed) {
|
||||
// CFF spec, "18 CID-keyed Fonts"
|
||||
cff->set_kind(CFF::Kind::CIDKeyed);
|
||||
}
|
||||
|
||||
auto strings = TRY(parse_strings(reader));
|
||||
|
||||
// CFF spec "16 Local/Global Subrs INDEXes"
|
||||
|
@ -350,6 +355,12 @@ PDFErrorOr<Vector<CFF::TopDict>> CFF::parse_top_dicts(Reader& reader, ReadonlyBy
|
|||
}));
|
||||
break;
|
||||
}
|
||||
case TopDictOperator::RegistryOrderingSupplement:
|
||||
// CFF Spec, "18 CID-keyed Fonts"
|
||||
// "The Top DICT begins with ROS operator which specifies the Registry-Ordering-Supplement for the font.
|
||||
// This will indicate to a CFF parser that special CID processing should be applied to this font."
|
||||
top_dict.is_cid_keyed = true;
|
||||
break;
|
||||
case TopDictOperator::FDSelect:
|
||||
if (!operands.is_empty())
|
||||
top_dict.fdselect_offset = operands[0].get<int>();
|
||||
|
|
|
@ -126,6 +126,7 @@ public:
|
|||
Vector<ByteBuffer> local_subroutines;
|
||||
float defaultWidthX = 0;
|
||||
float nominalWidthX = 0;
|
||||
bool is_cid_keyed = false;
|
||||
int fdselect_offset = 0;
|
||||
int fdarray_offset = 0;
|
||||
};
|
||||
|
|
|
@ -44,6 +44,10 @@ PDFErrorOr<void> Type1Font::initialize(Document* document, NonnullRefPtr<DictObj
|
|||
m_font_program = TRY(PS1FontProgram::create(font_file_stream->bytes(), encoding(), length1, length2));
|
||||
}
|
||||
}
|
||||
|
||||
if (m_font_program && m_font_program->kind() == Type1FontProgram::Kind::CIDKeyed)
|
||||
return Error::parse_error("Type1 fonts must not be CID-keyed"sv);
|
||||
|
||||
if (!m_font_program) {
|
||||
m_font = TRY(replacement_for(base_font_name().to_lowercase(), font_size));
|
||||
}
|
||||
|
|
|
@ -20,10 +20,17 @@ class Encoding;
|
|||
class Type1FontProgram : public RefCounted<Type1FontProgram> {
|
||||
|
||||
public:
|
||||
enum Kind {
|
||||
NameKeyed,
|
||||
CIDKeyed,
|
||||
};
|
||||
|
||||
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; }
|
||||
|
||||
Kind kind() const { return m_kind; }
|
||||
|
||||
protected:
|
||||
struct AccentedCharacter {
|
||||
AccentedCharacter(u8 base_char_code, u8 accent_char_code, float adx, float ady)
|
||||
|
@ -111,10 +118,13 @@ protected:
|
|||
|
||||
void consolidate_glyphs();
|
||||
|
||||
void set_kind(Kind kind) { m_kind = kind; }
|
||||
|
||||
private:
|
||||
HashMap<DeprecatedFlyString, Glyph> m_glyph_map;
|
||||
Gfx::AffineTransform m_font_matrix;
|
||||
RefPtr<Encoding> m_encoding;
|
||||
Kind m_kind { NameKeyed };
|
||||
|
||||
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;
|
||||
|
|
Loading…
Add table
Reference in a new issue