// 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.
bool OpenTypeFVAR::Parse(const uint8_t* data, size_t length) {
Buffer table(data, length); if (!table.ReadU16(&this->majorVersion) ||
!table.ReadU16(&this->minorVersion) ||
!table.ReadU16(&this->axesArrayOffset) ||
!table.ReadU16(&this->reserved) ||
!table.ReadU16(&this->axisCount) ||
!table.ReadU16(&this->axisSize) ||
!table.ReadU16(&this->instanceCount) ||
!table.ReadU16(&this->instanceSize)) { return DropVariations("Failed to read table header");
} if (this->majorVersion != 1) { return DropVariations("Unknown table version");
} if (this->minorVersion > 0) {
Warning("Downgrading minor version to 0");
this->minorVersion = 0;
} if (this->axesArrayOffset > length || this->axesArrayOffset < table.offset()) { return DropVariations("Bad axesArrayOffset");
} if (this->reserved != 2) {
Warning("Expected reserved=2");
this->reserved = 2;
} if (this->axisCount == 0) { return DropVariations("No variation axes");
} if (this->axisSize != 20) { return DropVariations("Invalid axisSize");
} // instanceCount is not validated if (this->instanceSize == this->axisCount * sizeof(Fixed) + 6) {
this->instancesHavePostScriptNameID = true;
} elseif (this->instanceSize == this->axisCount * sizeof(Fixed) + 4) {
this->instancesHavePostScriptNameID = false;
} else { return DropVariations("Invalid instanceSize");
}
// When we serialize, the axes array will go here, even if it was // originally at a different offset. So we update the axesArrayOffset // field for the header.
uint32_t origAxesArrayOffset = this->axesArrayOffset;
this->axesArrayOffset = table.offset();
table.set_offset(origAxesArrayOffset); for (unsigned i = 0; i < this->axisCount; i++) {
this->axes.emplace_back(); auto& axis = this->axes[i]; if (!table.ReadU32(&axis.axisTag) ||
!table.ReadS32(&axis.minValue) ||
!table.ReadS32(&axis.defaultValue) ||
!table.ReadS32(&axis.maxValue) ||
!table.ReadU16(&axis.flags) ||
!table.ReadU16(&axis.axisNameID)) { return DropVariations("Failed to read axis record");
} if (!CheckTag(axis.axisTag)) { return DropVariations("Bad axis tag");
} if (!(axis.minValue <= axis.defaultValue && axis.defaultValue <= axis.maxValue)) { return DropVariations("Bad axis value range");
} if ((axis.flags & 0xFFFEu) != 0) {
Warning("Discarding unknown axis flags");
axis.flags &= ~0xFFFEu;
} if (axis.axisNameID <= 255 || axis.axisNameID >= 32768) {
Warning("Axis nameID out of range"); // We don't check that the name actually exists -- assume the client can handle // a missing name when it tries to read the table.
}
}
for (unsigned i = 0; i < this->instanceCount; i++) {
this->instances.emplace_back(); auto& inst = this->instances[i]; if (!table.ReadU16(&inst.subfamilyNameID) ||
!table.ReadU16(&inst.flags)) { return DropVariations("Failed to read instance record");
}
inst.coordinates.reserve(this->axisCount); for (unsigned j = 0; j < this->axisCount; j++) {
inst.coordinates.emplace_back(); auto& coord = inst.coordinates[j]; if (!table.ReadS32(&coord)) { return DropVariations("Failed to read instance coordinates");
}
} if (this->instancesHavePostScriptNameID) { if (!table.ReadU16(&inst.postScriptNameID)) { return DropVariations("Failed to read instance psname ID");
}
}
}
if (table.remaining()) { return Warning("%zu bytes unparsed", table.remaining());
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.