tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

maxp.cc (3337B)


      1 // Copyright (c) 2009-2017 The OTS Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "maxp.h"
      6 
      7 // maxp - Maximum Profile
      8 // http://www.microsoft.com/typography/otspec/maxp.htm
      9 
     10 namespace ots {
     11 
     12 bool OpenTypeMAXP::Parse(const uint8_t *data, size_t length) {
     13  Buffer table(data, length);
     14 
     15  uint32_t version = 0;
     16  if (!table.ReadU32(&version)) {
     17    return Error("Failed to read table version");
     18  }
     19 
     20  if (version >> 16 > 1) {
     21    return Error("Unsupported table version 0x%x", version);
     22  }
     23 
     24  if (!table.ReadU16(&this->num_glyphs)) {
     25    return Error("Failed to read numGlyphs");
     26  }
     27 
     28  if (!this->num_glyphs) {
     29    return Error("numGlyphs is 0");
     30  }
     31 
     32  this->version_1 = false;
     33 
     34  // Per https://learn.microsoft.com/en-gb/typography/opentype/spec/maxp,
     35  // the only two 'maxp' version numbers are 0.5 (for CFF/CFF2) and 1.0
     36  // (for TrueType).
     37  // If it's version 0.5, there is nothing more to read.
     38  if (version == 0x00005000) {
     39    return true;
     40  }
     41 
     42  if (version != 0x00010000) {
     43    Warning("Unexpected version 0x%08x; attempting to read as version 1.0",
     44            version);
     45  }
     46 
     47  // Otherwise, try to read the version 1.0 fields:
     48  if (!table.ReadU16(&this->max_points) ||
     49      !table.ReadU16(&this->max_contours) ||
     50      !table.ReadU16(&this->max_c_points) ||
     51      !table.ReadU16(&this->max_c_contours) ||
     52      !table.ReadU16(&this->max_zones) ||
     53      !table.ReadU16(&this->max_t_points) ||
     54      !table.ReadU16(&this->max_storage) ||
     55      !table.ReadU16(&this->max_fdefs) ||
     56      !table.ReadU16(&this->max_idefs) ||
     57      !table.ReadU16(&this->max_stack) ||
     58      !table.ReadU16(&this->max_size_glyf_instructions) ||
     59      !table.ReadU16(&this->max_c_components) ||
     60      !table.ReadU16(&this->max_c_depth)) {
     61    Warning("Failed to read version 1.0 fields, downgrading to version 0.5");
     62    return true;
     63  }
     64 
     65  this->version_1 = true;
     66 
     67  if (this->max_zones < 1) {
     68    // workaround for ipa*.ttf Japanese fonts.
     69    Warning("Bad maxZones: %u", this->max_zones);
     70    this->max_zones = 1;
     71  } else if (this->max_zones > 2) {
     72    // workaround for Ecolier-*.ttf fonts and bad fonts in some PDFs
     73    Warning("Bad maxZones: %u", this->max_zones);
     74    this->max_zones = 2;
     75  }
     76 
     77  return true;
     78 }
     79 
     80 bool OpenTypeMAXP::Serialize(OTSStream *out) {
     81  if (!out->WriteU32(this->version_1 ? 0x00010000 : 0x00005000) ||
     82      !out->WriteU16(this->num_glyphs)) {
     83    return Error("Failed to write version or numGlyphs");
     84  }
     85 
     86  if (!this->version_1) return true;
     87 
     88  if (!out->WriteU16(this->max_points) ||
     89      !out->WriteU16(this->max_contours) ||
     90      !out->WriteU16(this->max_c_points) ||
     91      !out->WriteU16(this->max_c_contours)) {
     92    return Error("Failed to write maxp");
     93  }
     94 
     95  if (!out->WriteU16(this->max_zones) ||
     96      !out->WriteU16(this->max_t_points) ||
     97      !out->WriteU16(this->max_storage) ||
     98      !out->WriteU16(this->max_fdefs) ||
     99      !out->WriteU16(this->max_idefs) ||
    100      !out->WriteU16(this->max_stack) ||
    101      !out->WriteU16(this->max_size_glyf_instructions)) {
    102    return Error("Failed to write more maxp");
    103  }
    104 
    105  if (!out->WriteU16(this->max_c_components) ||
    106      !out->WriteU16(this->max_c_depth)) {
    107    return Error("Failed to write yet more maxp");
    108  }
    109 
    110  return true;
    111 }
    112 
    113 }  // namespace ots