mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 12:17:44 +00:00
LibPDF/CFF: Compute per-glyph glyph width in CID-keyed fonts
Make TopDict's defaultWidthX and nominalWidthX Optional<>s so that we can check if they're set per fdselect-selected font dict, and if so use the value from there in CID-keyed fonts. Otherwise, keep using the value in the top dict.
This commit is contained in:
parent
4348b484c6
commit
5c8778a161
2 changed files with 19 additions and 9 deletions
|
@ -214,24 +214,34 @@ PDFErrorOr<NonnullRefPtr<CFF>> CFF::create(ReadonlyBytes const& cff_bytes, RefPt
|
||||||
}
|
}
|
||||||
|
|
||||||
// CFF spec, "18 CID-keyed Fonts"
|
// CFF spec, "18 CID-keyed Fonts"
|
||||||
|
Vector<TopDict> font_dicts;
|
||||||
if (top_dict.fdarray_offset != 0) {
|
if (top_dict.fdarray_offset != 0) {
|
||||||
Reader fdarray_reader { cff_bytes.slice(top_dict.fdarray_offset) };
|
Reader fdarray_reader { cff_bytes.slice(top_dict.fdarray_offset) };
|
||||||
auto font_dicts = TRY(parse_top_dicts(fdarray_reader, cff_bytes));
|
font_dicts = TRY(parse_top_dicts(fdarray_reader, cff_bytes));
|
||||||
dbgln_if(CFF_DEBUG, "CFF has {} FDArray entries", font_dicts.size());
|
dbgln_if(CFF_DEBUG, "CFF has {} FDArray entries", font_dicts.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// CFF spec, "19 FDSelect"
|
// CFF spec, "19 FDSelect"
|
||||||
|
Vector<u8> fdselect;
|
||||||
if (top_dict.fdselect_offset != 0) {
|
if (top_dict.fdselect_offset != 0) {
|
||||||
auto fdselect = TRY(parse_fdselect(Reader { cff_bytes.slice(top_dict.fdselect_offset) }, glyphs.size()));
|
fdselect = TRY(parse_fdselect(Reader { cff_bytes.slice(top_dict.fdselect_offset) }, glyphs.size()));
|
||||||
dbgln_if(CFF_DEBUG, "CFF has {} FDSelect entries", fdselect.size());
|
dbgln_if(CFF_DEBUG, "CFF has {} FDSelect entries", fdselect.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust glyphs' widths as they are deltas from nominalWidthX
|
// Adjust glyphs' widths as they are deltas from nominalWidthX
|
||||||
for (auto& glyph : glyphs) {
|
for (size_t glyph_id = 0; glyph_id < glyphs.size(); glyph_id++) {
|
||||||
if (!glyph.has_width())
|
auto& glyph = glyphs[glyph_id];
|
||||||
glyph.set_width(top_dict.defaultWidthX);
|
if (!glyph.has_width()) {
|
||||||
else
|
auto default_width = top_dict.defaultWidthX.value_or(0.0f);
|
||||||
glyph.set_width(glyph.width() + top_dict.nominalWidthX);
|
if (top_dict.is_cid_keyed)
|
||||||
|
default_width = font_dicts[fdselect[glyph_id]].defaultWidthX.value_or(default_width);
|
||||||
|
glyph.set_width(default_width);
|
||||||
|
} else {
|
||||||
|
auto nominal_width = top_dict.nominalWidthX.value_or(0.0f);
|
||||||
|
if (top_dict.is_cid_keyed)
|
||||||
|
nominal_width = font_dicts[fdselect[glyph_id]].nominalWidthX.value_or(nominal_width);
|
||||||
|
glyph.set_width(glyph.width() + nominal_width);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < glyphs.size(); i++) {
|
for (size_t i = 0; i < glyphs.size(); i++) {
|
||||||
|
|
|
@ -124,8 +124,8 @@ public:
|
||||||
int encoding_offset = 0;
|
int encoding_offset = 0;
|
||||||
int charstrings_offset = 0;
|
int charstrings_offset = 0;
|
||||||
Vector<ByteBuffer> local_subroutines;
|
Vector<ByteBuffer> local_subroutines;
|
||||||
float defaultWidthX = 0;
|
Optional<float> defaultWidthX;
|
||||||
float nominalWidthX = 0;
|
Optional<float> nominalWidthX;
|
||||||
bool is_cid_keyed = false;
|
bool is_cid_keyed = false;
|
||||||
int fdselect_offset = 0;
|
int fdselect_offset = 0;
|
||||||
int fdarray_offset = 0;
|
int fdarray_offset = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue