diff options
Diffstat (limited to '')
-rw-r--r-- | gfx/ots/src/maxp.cc | 76 |
1 files changed, 43 insertions, 33 deletions
diff --git a/gfx/ots/src/maxp.cc b/gfx/ots/src/maxp.cc index 232e4a9889..90f53b0e39 100644 --- a/gfx/ots/src/maxp.cc +++ b/gfx/ots/src/maxp.cc @@ -29,39 +29,49 @@ bool OpenTypeMAXP::Parse(const uint8_t *data, size_t length) { return Error("numGlyphs is 0"); } - if (version >> 16 == 1) { - this->version_1 = true; - if (!table.ReadU16(&this->max_points) || - !table.ReadU16(&this->max_contours) || - !table.ReadU16(&this->max_c_points) || - !table.ReadU16(&this->max_c_contours) || - !table.ReadU16(&this->max_zones) || - !table.ReadU16(&this->max_t_points) || - !table.ReadU16(&this->max_storage) || - !table.ReadU16(&this->max_fdefs) || - !table.ReadU16(&this->max_idefs) || - !table.ReadU16(&this->max_stack) || - !table.ReadU16(&this->max_size_glyf_instructions) || - !table.ReadU16(&this->max_c_components) || - !table.ReadU16(&this->max_c_depth)) { - return Error("Failed to read version 1 table data"); - } - - if (this->max_zones == 0) { - // workaround for ipa*.ttf Japanese fonts. - Warning("Bad maxZones: %u", this->max_zones); - this->max_zones = 1; - } else if (this->max_zones == 3) { - // workaround for Ecolier-*.ttf fonts. - Warning("Bad maxZones: %u", this->max_zones); - this->max_zones = 2; - } - - if ((this->max_zones != 1) && (this->max_zones != 2)) { - return Error("Bad maxZones: %u", this->max_zones); - } - } else { - this->version_1 = false; + this->version_1 = false; + + // Per https://learn.microsoft.com/en-gb/typography/opentype/spec/maxp, + // the only two 'maxp' version numbers are 0.5 (for CFF/CFF2) and 1.0 + // (for TrueType). + // If it's version 0.5, there is nothing more to read. + if (version == 0x00005000) { + return true; + } + + if (version != 0x00010000) { + Warning("Unexpected version 0x%08x; attempting to read as version 1.0", + version); + } + + // Otherwise, try to read the version 1.0 fields: + if (!table.ReadU16(&this->max_points) || + !table.ReadU16(&this->max_contours) || + !table.ReadU16(&this->max_c_points) || + !table.ReadU16(&this->max_c_contours) || + !table.ReadU16(&this->max_zones) || + !table.ReadU16(&this->max_t_points) || + !table.ReadU16(&this->max_storage) || + !table.ReadU16(&this->max_fdefs) || + !table.ReadU16(&this->max_idefs) || + !table.ReadU16(&this->max_stack) || + !table.ReadU16(&this->max_size_glyf_instructions) || + !table.ReadU16(&this->max_c_components) || + !table.ReadU16(&this->max_c_depth)) { + Warning("Failed to read version 1.0 fields, downgrading to version 0.5"); + return true; + } + + this->version_1 = true; + + if (this->max_zones < 1) { + // workaround for ipa*.ttf Japanese fonts. + Warning("Bad maxZones: %u", this->max_zones); + this->max_zones = 1; + } else if (this->max_zones > 2) { + // workaround for Ecolier-*.ttf fonts and bad fonts in some PDFs + Warning("Bad maxZones: %u", this->max_zones); + this->max_zones = 2; } return true; |