Backed out 3 changesets (bug 1918178) for causing reftest failures. a=backout
[gecko.git] / gfx / ots / src / head.cc
blob6088504c8b1834f39907af33aa81ee7ad78dc826
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.
5 #include "head.h"
7 #include <cstring>
9 // head - Font Header
10 // http://www.microsoft.com/typography/otspec/head.htm
12 namespace ots {
14 bool OpenTypeHEAD::Parse(const uint8_t *data, size_t length) {
15 Buffer table(data, length);
17 uint32_t version = 0;
18 if (!table.ReadU32(&version) ||
19 !table.ReadU32(&this->revision)) {
20 return Error("Failed to read table header");
23 if (version >> 16 != 1) {
24 return Error("Unsupported majorVersion: %d", version >> 16);
27 // Skip the checksum adjustment
28 if (!table.Skip(4)) {
29 return Error("Failed to read checksum");
32 uint32_t magic;
33 if (!table.ReadU32(&magic) || magic != 0x5F0F3CF5) {
34 return Error("Failed to read or incorrect magicNumber");
37 if (!table.ReadU16(&this->flags)) {
38 return Error("Failed to read flags");
41 // We allow bits 0..4, 11..13
42 this->flags &= 0x381f;
44 if (!table.ReadU16(&this->upem)) {
45 return Error("Failed to read unitsPerEm");
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);
54 if (!table.ReadR64(&this->created) ||
55 !table.ReadR64(&this->modified)) {
56 return Error("Can't read font dates");
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");
66 if (this->xmin > this->xmax) {
67 return Error("Bad x dimension in the font bounding box (%d, %d)",
68 this->xmin, this->xmax);
70 if (this->ymin > this->ymax) {
71 return Error("Bad y dimension in the font bounding box (%d, %d)",
72 this->ymin, this->ymax);
75 if (!table.ReadU16(&this->mac_style)) {
76 return Error("Failed to read macStyle");
79 // We allow bits 0..6
80 this->mac_style &= 0x7f;
82 if (!table.ReadU16(&this->min_ppem)) {
83 return Error("Failed to read lowestRecPPEM");
86 // We don't care about the font direction hint
87 if (!table.Skip(2)) {
88 return Error("Failed to read fontDirectionHint");
91 if (!table.ReadS16(&this->index_to_loc_format)) {
92 return Error("Failed to read indexToLocFormat");
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);
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");
105 return true;
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");
129 return true;
132 } // namespace