tor-browser

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

head.cc (3526B)


      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 "head.h"
      6 
      7 #include <cstring>
      8 
      9 // head - Font Header
     10 // http://www.microsoft.com/typography/otspec/head.htm
     11 
     12 namespace ots {
     13 
     14 bool OpenTypeHEAD::Parse(const uint8_t *data, size_t length) {
     15  Buffer table(data, length);
     16 
     17  uint32_t version = 0;
     18  if (!table.ReadU32(&version) ||
     19      !table.ReadU32(&this->revision)) {
     20    return Error("Failed to read table header");
     21  }
     22 
     23  if (version >> 16 != 1) {
     24    return Error("Unsupported majorVersion: %d", version >> 16);
     25  }
     26 
     27  // Skip the checksum adjustment
     28  if (!table.Skip(4)) {
     29    return Error("Failed to read checksum");
     30  }
     31 
     32  uint32_t magic;
     33  if (!table.ReadU32(&magic) || magic != 0x5F0F3CF5) {
     34    return Error("Failed to read or incorrect magicNumber");
     35  }
     36 
     37  if (!table.ReadU16(&this->flags)) {
     38    return Error("Failed to read flags");
     39  }
     40 
     41  // We allow bits 0..4, 11..13
     42  this->flags &= 0x381f;
     43 
     44  if (!table.ReadU16(&this->upem)) {
     45    return Error("Failed to read unitsPerEm");
     46  }
     47 
     48  // upem must be in range
     49  if (this->upem < 16 ||
     50      this->upem > 16384) {
     51    return Error("unitsPerEm on in the range [16, 16384]: %d", this->upem);
     52  }
     53 
     54  if (!table.ReadR64(&this->created) ||
     55      !table.ReadR64(&this->modified)) {
     56    return Error("Can't read font dates");
     57  }
     58 
     59  if (!table.ReadS16(&this->xmin) ||
     60      !table.ReadS16(&this->ymin) ||
     61      !table.ReadS16(&this->xmax) ||
     62      !table.ReadS16(&this->ymax)) {
     63    return Error("Failed to read font bounding box");
     64  }
     65 
     66  if (this->xmin > this->xmax) {
     67    return Error("Bad x dimension in the font bounding box (%d, %d)",
     68                  this->xmin, this->xmax);
     69  }
     70  if (this->ymin > this->ymax) {
     71    return Error("Bad y dimension in the font bounding box (%d, %d)",
     72                  this->ymin, this->ymax);
     73  }
     74 
     75  if (!table.ReadU16(&this->mac_style)) {
     76    return Error("Failed to read macStyle");
     77  }
     78 
     79  // We allow bits 0..6
     80  this->mac_style &= 0x7f;
     81 
     82  if (!table.ReadU16(&this->min_ppem)) {
     83    return Error("Failed to read lowestRecPPEM");
     84  }
     85 
     86  // We don't care about the font direction hint
     87  if (!table.Skip(2)) {
     88    return Error("Failed to read fontDirectionHint");
     89  }
     90 
     91  if (!table.ReadS16(&this->index_to_loc_format)) {
     92    return Error("Failed to read indexToLocFormat");
     93  }
     94  if (this->index_to_loc_format < 0 ||
     95      this->index_to_loc_format > 1) {
     96    return Error("Bad indexToLocFormat %d", this->index_to_loc_format);
     97  }
     98 
     99  int16_t glyph_data_format;
    100  if (!table.ReadS16(&glyph_data_format) ||
    101      glyph_data_format) {
    102    return Error("Failed to read or bad glyphDataFormat");
    103  }
    104 
    105  return true;
    106 }
    107 
    108 bool OpenTypeHEAD::Serialize(OTSStream *out) {
    109  if (!out->WriteU32(0x00010000) ||
    110      !out->WriteU32(this->revision) ||
    111      !out->WriteU32(0) ||  // check sum not filled in yet
    112      !out->WriteU32(0x5F0F3CF5) ||
    113      !out->WriteU16(this->flags) ||
    114      !out->WriteU16(this->upem) ||
    115      !out->WriteR64(this->created) ||
    116      !out->WriteR64(this->modified) ||
    117      !out->WriteS16(this->xmin) ||
    118      !out->WriteS16(this->ymin) ||
    119      !out->WriteS16(this->xmax) ||
    120      !out->WriteS16(this->ymax) ||
    121      !out->WriteU16(this->mac_style) ||
    122      !out->WriteU16(this->min_ppem) ||
    123      !out->WriteS16(2) ||
    124      !out->WriteS16(this->index_to_loc_format) ||
    125      !out->WriteS16(0)) {
    126    return Error("Failed to write table");
    127  }
    128 
    129  return true;
    130 }
    131 
    132 }  // namespace