gfx/ots/src/head.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 "head.h"
michael@0 6
michael@0 7 #include <cstring>
michael@0 8
michael@0 9 // head - Font Header
michael@0 10 // http://www.microsoft.com/typography/otspec/head.htm
michael@0 11
michael@0 12 #define TABLE_NAME "head"
michael@0 13
michael@0 14 namespace ots {
michael@0 15
michael@0 16 bool ots_head_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
michael@0 17 Buffer table(data, length);
michael@0 18 file->head = new OpenTypeHEAD;
michael@0 19
michael@0 20 uint32_t version = 0;
michael@0 21 if (!table.ReadU32(&version) ||
michael@0 22 !table.ReadU32(&file->head->revision)) {
michael@0 23 return OTS_FAILURE_MSG("Failed to read head header");
michael@0 24 }
michael@0 25
michael@0 26 if (version >> 16 != 1) {
michael@0 27 return OTS_FAILURE_MSG("Bad head table version of %d", version);
michael@0 28 }
michael@0 29
michael@0 30 // Skip the checksum adjustment
michael@0 31 if (!table.Skip(4)) {
michael@0 32 return OTS_FAILURE_MSG("Failed to read checksum");
michael@0 33 }
michael@0 34
michael@0 35 uint32_t magic;
michael@0 36 if (!table.ReadTag(&magic) ||
michael@0 37 std::memcmp(&magic, "\x5F\x0F\x3C\xF5", 4)) {
michael@0 38 return OTS_FAILURE_MSG("Failed to read font magic number");
michael@0 39 }
michael@0 40
michael@0 41 if (!table.ReadU16(&file->head->flags)) {
michael@0 42 return OTS_FAILURE_MSG("Failed to read head flags");
michael@0 43 }
michael@0 44
michael@0 45 // We allow bits 0..4, 11..13
michael@0 46 file->head->flags &= 0x381f;
michael@0 47
michael@0 48 if (!table.ReadU16(&file->head->ppem)) {
michael@0 49 return OTS_FAILURE_MSG("Failed to read pixels per em");
michael@0 50 }
michael@0 51
michael@0 52 // ppem must be in range
michael@0 53 if (file->head->ppem < 16 ||
michael@0 54 file->head->ppem > 16384) {
michael@0 55 return OTS_FAILURE_MSG("Bad ppm of %d", file->head->ppem);
michael@0 56 }
michael@0 57
michael@0 58 // ppem must be a power of two
michael@0 59 #if 0
michael@0 60 // We don't call ots_failure() for now since lots of TrueType fonts are
michael@0 61 // not following this rule. Putting OTS_WARNING here is too noisy.
michael@0 62 if ((file->head->ppem - 1) & file->head->ppem) {
michael@0 63 return OTS_FAILURE_MSG("ppm not a power of two: %d", file->head->ppem);
michael@0 64 }
michael@0 65 #endif
michael@0 66
michael@0 67 if (!table.ReadR64(&file->head->created) ||
michael@0 68 !table.ReadR64(&file->head->modified)) {
michael@0 69 return OTS_FAILURE_MSG("Can't read font dates");
michael@0 70 }
michael@0 71
michael@0 72 if (!table.ReadS16(&file->head->xmin) ||
michael@0 73 !table.ReadS16(&file->head->ymin) ||
michael@0 74 !table.ReadS16(&file->head->xmax) ||
michael@0 75 !table.ReadS16(&file->head->ymax)) {
michael@0 76 return OTS_FAILURE_MSG("Failed to read font bounding box");
michael@0 77 }
michael@0 78
michael@0 79 if (file->head->xmin > file->head->xmax) {
michael@0 80 return OTS_FAILURE_MSG("Bad x dimension in the font bounding box (%d, %d)", file->head->xmin, file->head->xmax);
michael@0 81 }
michael@0 82 if (file->head->ymin > file->head->ymax) {
michael@0 83 return OTS_FAILURE_MSG("Bad y dimension in the font bounding box (%d, %d)", file->head->ymin, file->head->ymax);
michael@0 84 }
michael@0 85
michael@0 86 if (!table.ReadU16(&file->head->mac_style)) {
michael@0 87 return OTS_FAILURE_MSG("Failed to read font style");
michael@0 88 }
michael@0 89
michael@0 90 // We allow bits 0..6
michael@0 91 file->head->mac_style &= 0x7f;
michael@0 92
michael@0 93 if (!table.ReadU16(&file->head->min_ppem)) {
michael@0 94 return OTS_FAILURE_MSG("Failed to read font minimum ppm");
michael@0 95 }
michael@0 96
michael@0 97 // We don't care about the font direction hint
michael@0 98 if (!table.Skip(2)) {
michael@0 99 return OTS_FAILURE_MSG("Failed to skip font direction hint");
michael@0 100 }
michael@0 101
michael@0 102 if (!table.ReadS16(&file->head->index_to_loc_format)) {
michael@0 103 return OTS_FAILURE_MSG("Failed to read index to loc format");
michael@0 104 }
michael@0 105 if (file->head->index_to_loc_format < 0 ||
michael@0 106 file->head->index_to_loc_format > 1) {
michael@0 107 return OTS_FAILURE_MSG("Bad index to loc format %d", file->head->index_to_loc_format);
michael@0 108 }
michael@0 109
michael@0 110 int16_t glyph_data_format;
michael@0 111 if (!table.ReadS16(&glyph_data_format) ||
michael@0 112 glyph_data_format) {
michael@0 113 return OTS_FAILURE_MSG("Failed to read glyph data format");
michael@0 114 }
michael@0 115
michael@0 116 return true;
michael@0 117 }
michael@0 118
michael@0 119 bool ots_head_should_serialise(OpenTypeFile *file) {
michael@0 120 return file->head != NULL;
michael@0 121 }
michael@0 122
michael@0 123 bool ots_head_serialise(OTSStream *out, OpenTypeFile *file) {
michael@0 124 if (!out->WriteU32(0x00010000) ||
michael@0 125 !out->WriteU32(file->head->revision) ||
michael@0 126 !out->WriteU32(0) || // check sum not filled in yet
michael@0 127 !out->WriteU32(0x5F0F3CF5) ||
michael@0 128 !out->WriteU16(file->head->flags) ||
michael@0 129 !out->WriteU16(file->head->ppem) ||
michael@0 130 !out->WriteR64(file->head->created) ||
michael@0 131 !out->WriteR64(file->head->modified) ||
michael@0 132 !out->WriteS16(file->head->xmin) ||
michael@0 133 !out->WriteS16(file->head->ymin) ||
michael@0 134 !out->WriteS16(file->head->xmax) ||
michael@0 135 !out->WriteS16(file->head->ymax) ||
michael@0 136 !out->WriteU16(file->head->mac_style) ||
michael@0 137 !out->WriteU16(file->head->min_ppem) ||
michael@0 138 !out->WriteS16(2) ||
michael@0 139 !out->WriteS16(file->head->index_to_loc_format) ||
michael@0 140 !out->WriteS16(0)) {
michael@0 141 return OTS_FAILURE_MSG("Failed to write head table");
michael@0 142 }
michael@0 143
michael@0 144 return true;
michael@0 145 }
michael@0 146
michael@0 147 void ots_head_free(OpenTypeFile *file) {
michael@0 148 delete file->head;
michael@0 149 }
michael@0 150
michael@0 151 } // namespace

mercurial