// 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 #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 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 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 axisValues; }; } // namespace ots #endif // OTS_STAT_H_