LibPDF/CFF: Store if a font program is CID-keyed

...and reject CID-keyed font programs for Type1 fonts.
This commit is contained in:
Nico Weber 2024-02-14 09:06:52 -05:00 committed by Andreas Kling
parent bb7d29d007
commit 7494f24430
Notes: sideshowbarker 2024-07-17 06:24:08 +09:00
4 changed files with 26 additions and 0 deletions

View file

@ -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>();

View file

@ -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;
};

View file

@ -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));
}

View file

@ -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;