gfx/ots/src/gasp.cc

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/ots/src/gasp.cc	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,112 @@
     1.4 +// Copyright (c) 2009 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +#include "gasp.h"
     1.9 +
    1.10 +// gasp - Grid-fitting And Scan-conversion Procedure
    1.11 +// http://www.microsoft.com/typography/otspec/gasp.htm
    1.12 +
    1.13 +#define TABLE_NAME "gasp"
    1.14 +
    1.15 +#define DROP_THIS_TABLE \
    1.16 +  do { \
    1.17 +    delete file->gasp; \
    1.18 +    file->gasp = 0; \
    1.19 +    OTS_FAILURE_MSG("Table discarded"); \
    1.20 +  } while (0)
    1.21 +
    1.22 +namespace ots {
    1.23 +
    1.24 +bool ots_gasp_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
    1.25 +  Buffer table(data, length);
    1.26 +
    1.27 +  OpenTypeGASP *gasp = new OpenTypeGASP;
    1.28 +  file->gasp = gasp;
    1.29 +
    1.30 +  uint16_t num_ranges = 0;
    1.31 +  if (!table.ReadU16(&gasp->version) ||
    1.32 +      !table.ReadU16(&num_ranges)) {
    1.33 +    return OTS_FAILURE_MSG("Failed to read table header");
    1.34 +  }
    1.35 +
    1.36 +  if (gasp->version > 1) {
    1.37 +    // Lots of Linux fonts have bad version numbers...
    1.38 +    OTS_WARNING("bad version: %u", gasp->version);
    1.39 +    DROP_THIS_TABLE;
    1.40 +    return true;
    1.41 +  }
    1.42 +
    1.43 +  if (num_ranges == 0) {
    1.44 +    OTS_WARNING("num_ranges is zero");
    1.45 +    DROP_THIS_TABLE;
    1.46 +    return true;
    1.47 +  }
    1.48 +
    1.49 +  gasp->gasp_ranges.reserve(num_ranges);
    1.50 +  for (unsigned i = 0; i < num_ranges; ++i) {
    1.51 +    uint16_t max_ppem = 0;
    1.52 +    uint16_t behavior = 0;
    1.53 +    if (!table.ReadU16(&max_ppem) ||
    1.54 +        !table.ReadU16(&behavior)) {
    1.55 +      return OTS_FAILURE_MSG("Failed to read subrange %d", i);
    1.56 +    }
    1.57 +    if ((i > 0) && (gasp->gasp_ranges[i - 1].first >= max_ppem)) {
    1.58 +      // The records in the gaspRange[] array must be sorted in order of
    1.59 +      // increasing rangeMaxPPEM value.
    1.60 +      OTS_WARNING("ranges are not sorted");
    1.61 +      DROP_THIS_TABLE;
    1.62 +      return true;
    1.63 +    }
    1.64 +    if ((i == num_ranges - 1u) &&  // never underflow.
    1.65 +        (max_ppem != 0xffffu)) {
    1.66 +      OTS_WARNING("The last record should be 0xFFFF as a sentinel value "
    1.67 +                  "for rangeMaxPPEM");
    1.68 +      DROP_THIS_TABLE;
    1.69 +      return true;
    1.70 +    }
    1.71 +
    1.72 +    if (behavior >> 8) {
    1.73 +      OTS_WARNING("undefined bits are used: %x", behavior);
    1.74 +      // mask undefined bits.
    1.75 +      behavior &= 0x000fu;
    1.76 +    }
    1.77 +
    1.78 +    if (gasp->version == 0 && (behavior >> 2) != 0) {
    1.79 +      OTS_WARNING("changed the version number to 1");
    1.80 +      gasp->version = 1;
    1.81 +    }
    1.82 +
    1.83 +    gasp->gasp_ranges.push_back(std::make_pair(max_ppem, behavior));
    1.84 +  }
    1.85 +
    1.86 +  return true;
    1.87 +}
    1.88 +
    1.89 +bool ots_gasp_should_serialise(OpenTypeFile *file) {
    1.90 +  return file->gasp != NULL;
    1.91 +}
    1.92 +
    1.93 +bool ots_gasp_serialise(OTSStream *out, OpenTypeFile *file) {
    1.94 +  const OpenTypeGASP *gasp = file->gasp;
    1.95 +
    1.96 +  if (!out->WriteU16(gasp->version) ||
    1.97 +      !out->WriteU16(gasp->gasp_ranges.size())) {
    1.98 +    return OTS_FAILURE_MSG("failed to write gasp header");
    1.99 +  }
   1.100 +
   1.101 +  for (unsigned i = 0; i < gasp->gasp_ranges.size(); ++i) {
   1.102 +    if (!out->WriteU16(gasp->gasp_ranges[i].first) ||
   1.103 +        !out->WriteU16(gasp->gasp_ranges[i].second)) {
   1.104 +      return OTS_FAILURE_MSG("Failed to write gasp subtable %d", i);
   1.105 +    }
   1.106 +  }
   1.107 +
   1.108 +  return true;
   1.109 +}
   1.110 +
   1.111 +void ots_gasp_free(OpenTypeFile *file) {
   1.112 +  delete file->gasp;
   1.113 +}
   1.114 +
   1.115 +}  // namespace ots

mercurial