Bug 1785744 [wpt PR 35504] - Recalc style for elements where :toggle() pseudo-class...
[gecko.git] / gfx / ots / src / gvar.cc
blob324a0fc838741ef7e3b290c6ba6a612672fa9cc1
1 // Copyright (c) 2018 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 "gvar.h"
7 #include "fvar.h"
8 #include "maxp.h"
9 #include "variations.h"
11 #define TABLE_NAME "gvar"
13 namespace ots {
15 // -----------------------------------------------------------------------------
16 // OpenTypeGVAR
17 // -----------------------------------------------------------------------------
19 static bool ParseSharedTuples(const Font* font, const uint8_t* data, size_t length,
20 size_t sharedTupleCount, size_t axisCount) {
21 Buffer subtable(data, length);
22 for (unsigned i = 0; i < sharedTupleCount; i++) {
23 for (unsigned j = 0; j < axisCount; j++) {
24 int16_t coordinate;
25 if (!subtable.ReadS16(&coordinate)) {
26 return OTS_FAILURE_MSG("Failed to read shared tuple coordinate");
30 return true;
33 static bool ParseGlyphVariationDataArray(const Font* font, const uint8_t* data, size_t length,
34 uint16_t flags, size_t glyphCount, size_t axisCount,
35 size_t sharedTupleCount,
36 const uint8_t* glyphVariationData,
37 size_t glyphVariationDataLength) {
38 Buffer subtable(data, length);
40 bool glyphVariationDataOffsetsAreLong = (flags & 0x0001u);
41 uint32_t prevOffset = 0;
42 for (size_t i = 0; i < glyphCount + 1; i++) {
43 uint32_t offset;
44 if (glyphVariationDataOffsetsAreLong) {
45 if (!subtable.ReadU32(&offset)) {
46 return OTS_FAILURE_MSG("Failed to read GlyphVariationData offset");
48 } else {
49 uint16_t halfOffset;
50 if (!subtable.ReadU16(&halfOffset)) {
51 return OTS_FAILURE_MSG("Failed to read GlyphVariationData offset");
53 offset = halfOffset * 2;
56 if (i > 0 && offset > prevOffset) {
57 if (prevOffset > glyphVariationDataLength) {
58 return OTS_FAILURE_MSG("Invalid GlyphVariationData offset");
60 if (!ParseVariationData(font, glyphVariationData + prevOffset,
61 glyphVariationDataLength - prevOffset,
62 axisCount, sharedTupleCount)) {
63 return OTS_FAILURE_MSG("Failed to parse GlyphVariationData");
66 prevOffset = offset;
69 return true;
72 bool OpenTypeGVAR::Parse(const uint8_t* data, size_t length) {
73 Buffer table(data, length);
75 uint16_t majorVersion;
76 uint16_t minorVersion;
77 uint16_t axisCount;
78 uint16_t sharedTupleCount;
79 uint32_t sharedTuplesOffset;
80 uint16_t glyphCount;
81 uint16_t flags;
82 uint32_t glyphVariationDataArrayOffset;
84 if (!table.ReadU16(&majorVersion) ||
85 !table.ReadU16(&minorVersion) ||
86 !table.ReadU16(&axisCount) ||
87 !table.ReadU16(&sharedTupleCount) ||
88 !table.ReadU32(&sharedTuplesOffset) ||
89 !table.ReadU16(&glyphCount) ||
90 !table.ReadU16(&flags) ||
91 !table.ReadU32(&glyphVariationDataArrayOffset)) {
92 return DropVariations("Failed to read table header");
94 if (majorVersion != 1) {
95 return DropVariations("Unknown table version");
98 // check axisCount == fvar->axisCount
99 OpenTypeFVAR* fvar = static_cast<OpenTypeFVAR*>(
100 GetFont()->GetTypedTable(OTS_TAG_FVAR));
101 if (!fvar) {
102 return DropVariations("Required fvar table is missing");
104 if (axisCount != fvar->AxisCount()) {
105 return DropVariations("Axis count mismatch");
108 // check glyphCount == maxp->num_glyphs
109 OpenTypeMAXP* maxp = static_cast<OpenTypeMAXP*>(
110 GetFont()->GetTypedTable(OTS_TAG_MAXP));
111 if (!maxp) {
112 return DropVariations("Required maxp table is missing");
114 if (glyphCount != maxp->num_glyphs) {
115 return DropVariations("Glyph count mismatch");
118 if (sharedTupleCount > 0) {
119 if (sharedTuplesOffset < table.offset() || sharedTuplesOffset > length) {
120 return DropVariations("Invalid sharedTuplesOffset");
122 if (!ParseSharedTuples(GetFont(),
123 data + sharedTuplesOffset, length - sharedTuplesOffset,
124 sharedTupleCount, axisCount)) {
125 return DropVariations("Failed to parse shared tuples");
129 if (glyphVariationDataArrayOffset) {
130 if (glyphVariationDataArrayOffset > length) {
131 return DropVariations("Invalid glyphVariationDataArrayOffset");
133 if (!ParseGlyphVariationDataArray(GetFont(),
134 data + table.offset(), length - table.offset(),
135 flags, glyphCount, axisCount, sharedTupleCount,
136 data + glyphVariationDataArrayOffset,
137 length - glyphVariationDataArrayOffset)) {
138 return DropVariations("Failed to read glyph variation data array");
142 this->m_data = data;
143 this->m_length = length;
145 return true;
148 bool OpenTypeGVAR::Serialize(OTSStream* out) {
149 if (!out->Write(this->m_data, this->m_length)) {
150 return Error("Failed to write gvar table");
153 return true;
156 } // namespace ots
158 #undef TABLE_NAME