/src/mozilla-central/gfx/ots/src/avar.cc
Line | Count | Source (jump to first uncovered line) |
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. |
4 | | |
5 | | #include "avar.h" |
6 | | |
7 | | #include "fvar.h" |
8 | | |
9 | | namespace ots { |
10 | | |
11 | | // ----------------------------------------------------------------------------- |
12 | | // OpenTypeAVAR |
13 | | // ----------------------------------------------------------------------------- |
14 | | |
15 | 0 | bool OpenTypeAVAR::Parse(const uint8_t* data, size_t length) { |
16 | 0 | Buffer table(data, length); |
17 | 0 | if (!table.ReadU16(&this->majorVersion) || |
18 | 0 | !table.ReadU16(&this->minorVersion) || |
19 | 0 | !table.ReadU16(&this->reserved) || |
20 | 0 | !table.ReadU16(&this->axisCount)) { |
21 | 0 | return Drop("Failed to read table header"); |
22 | 0 | } |
23 | 0 | if (this->majorVersion != 1) { |
24 | 0 | return Drop("Unknown table version"); |
25 | 0 | } |
26 | 0 | if (this->minorVersion > 0) { |
27 | 0 | // we only know how to serialize version 1.0 |
28 | 0 | Warning("Downgrading minor version to 0"); |
29 | 0 | this->minorVersion = 0; |
30 | 0 | } |
31 | 0 | if (this->reserved != 0) { |
32 | 0 | Warning("Expected reserved=0"); |
33 | 0 | this->reserved = 0; |
34 | 0 | } |
35 | 0 |
|
36 | 0 | OpenTypeFVAR* fvar = static_cast<OpenTypeFVAR*>( |
37 | 0 | GetFont()->GetTypedTable(OTS_TAG_FVAR)); |
38 | 0 | if (!fvar) { |
39 | 0 | return DropVariations("Required fvar table is missing"); |
40 | 0 | } |
41 | 0 | if (axisCount != fvar->AxisCount()) { |
42 | 0 | return Drop("Axis count mismatch"); |
43 | 0 | } |
44 | 0 | |
45 | 0 | for (size_t i = 0; i < this->axisCount; i++) { |
46 | 0 | this->axisSegmentMaps.emplace_back(); |
47 | 0 | uint16_t positionMapCount; |
48 | 0 | if (!table.ReadU16(&positionMapCount)) { |
49 | 0 | return Drop("Failed to read position map count"); |
50 | 0 | } |
51 | 0 | int foundRequiredMappings = 0; |
52 | 0 | for (size_t j = 0; j < positionMapCount; j++) { |
53 | 0 | AxisValueMap map; |
54 | 0 | if (!table.ReadS16(&map.fromCoordinate) || |
55 | 0 | !table.ReadS16(&map.toCoordinate)) { |
56 | 0 | return Drop("Failed to read axis value map"); |
57 | 0 | } |
58 | 0 | if (map.fromCoordinate < -0x4000 || |
59 | 0 | map.fromCoordinate > 0x4000 || |
60 | 0 | map.toCoordinate < -0x4000 || |
61 | 0 | map.toCoordinate > 0x4000) { |
62 | 0 | return Drop("Axis value map coordinate out of range"); |
63 | 0 | } |
64 | 0 | if (j > 0) { |
65 | 0 | if (map.fromCoordinate <= this->axisSegmentMaps[i].back().fromCoordinate || |
66 | 0 | map.toCoordinate < this->axisSegmentMaps[i].back().toCoordinate) { |
67 | 0 | return Drop("Axis value map out of order"); |
68 | 0 | } |
69 | 0 | } |
70 | 0 | if ((map.fromCoordinate == -0x4000 && map.toCoordinate == -0x4000) || |
71 | 0 | (map.fromCoordinate == 0 && map.toCoordinate == 0) || |
72 | 0 | (map.fromCoordinate == 0x4000 && map.toCoordinate == 0x4000)) { |
73 | 0 | ++foundRequiredMappings; |
74 | 0 | } |
75 | 0 | this->axisSegmentMaps[i].push_back(map); |
76 | 0 | } |
77 | 0 | if (positionMapCount > 0 && foundRequiredMappings != 3) { |
78 | 0 | return Drop("A required mapping (for -1, 0 or 1) is missing"); |
79 | 0 | } |
80 | 0 | } |
81 | 0 |
|
82 | 0 | return true; |
83 | 0 | } |
84 | | |
85 | 0 | bool OpenTypeAVAR::Serialize(OTSStream* out) { |
86 | 0 | if (!out->WriteU16(this->majorVersion) || |
87 | 0 | !out->WriteU16(this->minorVersion) || |
88 | 0 | !out->WriteU16(this->reserved) || |
89 | 0 | !out->WriteU16(this->axisCount)) { |
90 | 0 | return Error("Failed to write table"); |
91 | 0 | } |
92 | 0 | |
93 | 0 | for (size_t i = 0; i < this->axisCount; i++) { |
94 | 0 | const auto& axisValueMap = this->axisSegmentMaps[i]; |
95 | 0 | if (!out->WriteU16(axisValueMap.size())) { |
96 | 0 | return Error("Failed to write table"); |
97 | 0 | } |
98 | 0 | for (size_t j = 0; j < axisValueMap.size(); j++) { |
99 | 0 | if (!out->WriteS16(axisValueMap[j].fromCoordinate) || |
100 | 0 | !out->WriteS16(axisValueMap[j].toCoordinate)) { |
101 | 0 | return Error("Failed to write table"); |
102 | 0 | } |
103 | 0 | } |
104 | 0 | } |
105 | 0 |
|
106 | 0 | return true; |
107 | 0 | } |
108 | | |
109 | | } // namespace ots |