| // 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. |
| |
| #include "vvar.h" |
| |
| #include "variations.h" |
| |
| namespace ots { |
| |
| // ----------------------------------------------------------------------------- |
| // OpenTypeVVAR |
| // ----------------------------------------------------------------------------- |
| |
| bool OpenTypeVVAR::Parse(const uint8_t* data, size_t length) { |
| Buffer table(data, length); |
| |
| uint16_t majorVersion; |
| uint16_t minorVersion; |
| uint32_t itemVariationStoreOffset; |
| uint32_t advanceHeightMappingOffset; |
| uint32_t tsbMappingOffset; |
| uint32_t bsbMappingOffset; |
| uint32_t vOrgMappingOffset; |
| |
| if (!table.ReadU16(&majorVersion) || |
| !table.ReadU16(&minorVersion) || |
| !table.ReadU32(&itemVariationStoreOffset) || |
| !table.ReadU32(&advanceHeightMappingOffset) || |
| !table.ReadU32(&tsbMappingOffset) || |
| !table.ReadU32(&bsbMappingOffset) || |
| !table.ReadU32(&vOrgMappingOffset)) { |
| return DropVariations("Failed to read table header"); |
| } |
| |
| if (majorVersion != 1) { |
| return DropVariations("Unknown table version"); |
| } |
| |
| if (itemVariationStoreOffset > length || |
| advanceHeightMappingOffset > length || |
| tsbMappingOffset > length || |
| bsbMappingOffset > length || |
| vOrgMappingOffset > length) { |
| return DropVariations("Invalid subtable offset"); |
| } |
| |
| if (!ParseItemVariationStore(GetFont(), data + itemVariationStoreOffset, |
| length - itemVariationStoreOffset)) { |
| return DropVariations("Failed to parse item variation store"); |
| } |
| |
| if (advanceHeightMappingOffset) { |
| if (!ParseDeltaSetIndexMap(GetFont(), data + advanceHeightMappingOffset, |
| length - advanceHeightMappingOffset)) { |
| return DropVariations("Failed to parse advance height mappings"); |
| } |
| } |
| |
| if (tsbMappingOffset) { |
| if (!ParseDeltaSetIndexMap(GetFont(), data + tsbMappingOffset, |
| length - tsbMappingOffset)) { |
| return DropVariations("Failed to parse TSB mappings"); |
| } |
| } |
| |
| if (bsbMappingOffset) { |
| if (!ParseDeltaSetIndexMap(GetFont(), data + bsbMappingOffset, |
| length - bsbMappingOffset)) { |
| return DropVariations("Failed to parse BSB mappings"); |
| } |
| } |
| |
| if (vOrgMappingOffset) { |
| if (!ParseDeltaSetIndexMap(GetFont(), data + vOrgMappingOffset, |
| length - vOrgMappingOffset)) { |
| return DropVariations("Failed to parse vOrg mappings"); |
| } |
| } |
| |
| this->m_data = data; |
| this->m_length = length; |
| |
| return true; |
| } |
| |
| bool OpenTypeVVAR::Serialize(OTSStream* out) { |
| if (!out->Write(this->m_data, this->m_length)) { |
| return Error("Failed to write VVAR table"); |
| } |
| |
| return true; |
| } |
| |
| } // namespace ots |