gfx/ots/src/gasp.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
michael@0 2 // Use of this source code is governed by a BSD-style license that can be
michael@0 3 // found in the LICENSE file.
michael@0 4
michael@0 5 #include "gasp.h"
michael@0 6
michael@0 7 // gasp - Grid-fitting And Scan-conversion Procedure
michael@0 8 // http://www.microsoft.com/typography/otspec/gasp.htm
michael@0 9
michael@0 10 #define TABLE_NAME "gasp"
michael@0 11
michael@0 12 #define DROP_THIS_TABLE \
michael@0 13 do { \
michael@0 14 delete file->gasp; \
michael@0 15 file->gasp = 0; \
michael@0 16 OTS_FAILURE_MSG("Table discarded"); \
michael@0 17 } while (0)
michael@0 18
michael@0 19 namespace ots {
michael@0 20
michael@0 21 bool ots_gasp_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
michael@0 22 Buffer table(data, length);
michael@0 23
michael@0 24 OpenTypeGASP *gasp = new OpenTypeGASP;
michael@0 25 file->gasp = gasp;
michael@0 26
michael@0 27 uint16_t num_ranges = 0;
michael@0 28 if (!table.ReadU16(&gasp->version) ||
michael@0 29 !table.ReadU16(&num_ranges)) {
michael@0 30 return OTS_FAILURE_MSG("Failed to read table header");
michael@0 31 }
michael@0 32
michael@0 33 if (gasp->version > 1) {
michael@0 34 // Lots of Linux fonts have bad version numbers...
michael@0 35 OTS_WARNING("bad version: %u", gasp->version);
michael@0 36 DROP_THIS_TABLE;
michael@0 37 return true;
michael@0 38 }
michael@0 39
michael@0 40 if (num_ranges == 0) {
michael@0 41 OTS_WARNING("num_ranges is zero");
michael@0 42 DROP_THIS_TABLE;
michael@0 43 return true;
michael@0 44 }
michael@0 45
michael@0 46 gasp->gasp_ranges.reserve(num_ranges);
michael@0 47 for (unsigned i = 0; i < num_ranges; ++i) {
michael@0 48 uint16_t max_ppem = 0;
michael@0 49 uint16_t behavior = 0;
michael@0 50 if (!table.ReadU16(&max_ppem) ||
michael@0 51 !table.ReadU16(&behavior)) {
michael@0 52 return OTS_FAILURE_MSG("Failed to read subrange %d", i);
michael@0 53 }
michael@0 54 if ((i > 0) && (gasp->gasp_ranges[i - 1].first >= max_ppem)) {
michael@0 55 // The records in the gaspRange[] array must be sorted in order of
michael@0 56 // increasing rangeMaxPPEM value.
michael@0 57 OTS_WARNING("ranges are not sorted");
michael@0 58 DROP_THIS_TABLE;
michael@0 59 return true;
michael@0 60 }
michael@0 61 if ((i == num_ranges - 1u) && // never underflow.
michael@0 62 (max_ppem != 0xffffu)) {
michael@0 63 OTS_WARNING("The last record should be 0xFFFF as a sentinel value "
michael@0 64 "for rangeMaxPPEM");
michael@0 65 DROP_THIS_TABLE;
michael@0 66 return true;
michael@0 67 }
michael@0 68
michael@0 69 if (behavior >> 8) {
michael@0 70 OTS_WARNING("undefined bits are used: %x", behavior);
michael@0 71 // mask undefined bits.
michael@0 72 behavior &= 0x000fu;
michael@0 73 }
michael@0 74
michael@0 75 if (gasp->version == 0 && (behavior >> 2) != 0) {
michael@0 76 OTS_WARNING("changed the version number to 1");
michael@0 77 gasp->version = 1;
michael@0 78 }
michael@0 79
michael@0 80 gasp->gasp_ranges.push_back(std::make_pair(max_ppem, behavior));
michael@0 81 }
michael@0 82
michael@0 83 return true;
michael@0 84 }
michael@0 85
michael@0 86 bool ots_gasp_should_serialise(OpenTypeFile *file) {
michael@0 87 return file->gasp != NULL;
michael@0 88 }
michael@0 89
michael@0 90 bool ots_gasp_serialise(OTSStream *out, OpenTypeFile *file) {
michael@0 91 const OpenTypeGASP *gasp = file->gasp;
michael@0 92
michael@0 93 if (!out->WriteU16(gasp->version) ||
michael@0 94 !out->WriteU16(gasp->gasp_ranges.size())) {
michael@0 95 return OTS_FAILURE_MSG("failed to write gasp header");
michael@0 96 }
michael@0 97
michael@0 98 for (unsigned i = 0; i < gasp->gasp_ranges.size(); ++i) {
michael@0 99 if (!out->WriteU16(gasp->gasp_ranges[i].first) ||
michael@0 100 !out->WriteU16(gasp->gasp_ranges[i].second)) {
michael@0 101 return OTS_FAILURE_MSG("Failed to write gasp subtable %d", i);
michael@0 102 }
michael@0 103 }
michael@0 104
michael@0 105 return true;
michael@0 106 }
michael@0 107
michael@0 108 void ots_gasp_free(OpenTypeFile *file) {
michael@0 109 delete file->gasp;
michael@0 110 }
michael@0 111
michael@0 112 } // namespace ots

mercurial