diff options
Diffstat (limited to 'gfx/ots/src/stat.h')
-rw-r--r-- | gfx/ots/src/stat.h | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/gfx/ots/src/stat.h b/gfx/ots/src/stat.h new file mode 100644 index 000000000..873d08edc --- /dev/null +++ b/gfx/ots/src/stat.h @@ -0,0 +1,155 @@ +// Copyright (c) 2018 The OTS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef OTS_STAT_H_ +#define OTS_STAT_H_ + +#include <vector> + +#include "ots.h" + +namespace ots { + +// ----------------------------------------------------------------------------- +// OpenTypeSTAT Interface +// ----------------------------------------------------------------------------- + +class OpenTypeSTAT : public Table { + public: + explicit OpenTypeSTAT(Font* font, uint32_t tag) + : Table(font, tag, tag) { } + + bool Parse(const uint8_t* data, size_t length); + bool Serialize(OTSStream* out); + + private: + bool ValidateNameId(uint16_t nameid, bool allowPredefined = true); + + uint16_t majorVersion; + uint16_t minorVersion; + uint16_t designAxisSize; + uint16_t designAxisCount; + uint32_t designAxesOffset; + uint16_t axisValueCount; + uint32_t offsetToAxisValueOffsets; + uint16_t elidedFallbackNameID; + + struct AxisRecord { + uint32_t axisTag; + uint16_t axisNameID; + uint16_t axisOrdering; + }; + std::vector<AxisRecord> designAxes; + + typedef int32_t Fixed; /* 16.16 fixed-point value */ + + struct AxisValueFormat1 { + uint16_t axisIndex; + uint16_t flags; + uint16_t valueNameID; + Fixed value; + static size_t Length() { + return 3 * sizeof(uint16_t) + sizeof(Fixed); + } + }; + + struct AxisValueFormat2 { + uint16_t axisIndex; + uint16_t flags; + uint16_t valueNameID; + Fixed nominalValue; + Fixed rangeMinValue; + Fixed rangeMaxValue; + static size_t Length() { + return 3 * sizeof(uint16_t) + 3 * sizeof(Fixed); + } + }; + + struct AxisValueFormat3 { + uint16_t axisIndex; + uint16_t flags; + uint16_t valueNameID; + Fixed value; + Fixed linkedValue; + static size_t Length() { + return 3 * sizeof(uint16_t) + 2 * sizeof(Fixed); + } + }; + + struct AxisValueFormat4 { + uint16_t axisCount; + uint16_t flags; + uint16_t valueNameID; + struct AxisValue { + uint16_t axisIndex; + Fixed value; + }; + std::vector<AxisValue> axisValues; + size_t Length() const { + return 3 * sizeof(uint16_t) + axisValues.size() * (sizeof(uint16_t) + sizeof(Fixed)); + } + }; + + struct AxisValueRecord { + uint16_t format; + union { + AxisValueFormat1 format1; + AxisValueFormat2 format2; + AxisValueFormat3 format3; + AxisValueFormat4 format4; + }; + explicit AxisValueRecord(uint16_t format_) + : format(format_) + { + if (format == 4) { + new (&this->format4) AxisValueFormat4(); + } + } + AxisValueRecord(const AxisValueRecord& other_) + : format(other_.format) + { + switch (format) { + case 1: + format1 = other_.format1; + break; + case 2: + format2 = other_.format2; + break; + case 3: + format3 = other_.format3; + break; + case 4: + new (&this->format4) AxisValueFormat4(); + format4 = other_.format4; + break; + } + } + ~AxisValueRecord() { + if (format == 4) { + this->format4.~AxisValueFormat4(); + } + } + uint32_t Length() const { + switch (format) { + case 1: + return sizeof(uint16_t) + format1.Length(); + case 2: + return sizeof(uint16_t) + format2.Length(); + case 3: + return sizeof(uint16_t) + format3.Length(); + case 4: + return sizeof(uint16_t) + format4.Length(); + default: + // can't happen + return 0; + } + } + }; + + std::vector<AxisValueRecord> axisValues; +}; + +} // namespace ots + +#endif // OTS_STAT_H_ |