1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2012 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkData.h" 9cb93a386Sopenharmony_ci#include "include/core/SkStream.h" 10cb93a386Sopenharmony_ci#include "src/core/SkFontDescriptor.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_cienum { 13cb93a386Sopenharmony_ci kInvalid = 0x00, 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_ci // these must match the sfnt 'name' enums 16cb93a386Sopenharmony_ci kFontFamilyName = 0x01, 17cb93a386Sopenharmony_ci kFullName = 0x04, 18cb93a386Sopenharmony_ci kPostscriptName = 0x06, 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_ci // These count backwards from 0xFF, so as not to collide with the SFNT 21cb93a386Sopenharmony_ci // defines for names in its 'name' table. 22cb93a386Sopenharmony_ci kFontVariation = 0xFA, 23cb93a386Sopenharmony_ci kFontIndex = 0xFD, 24cb93a386Sopenharmony_ci kSentinel = 0xFF, 25cb93a386Sopenharmony_ci}; 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ciSkFontDescriptor::SkFontDescriptor() { } 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_cistatic bool SK_WARN_UNUSED_RESULT read_string(SkStream* stream, SkString* string) { 30cb93a386Sopenharmony_ci size_t length; 31cb93a386Sopenharmony_ci if (!stream->readPackedUInt(&length)) { return false; } 32cb93a386Sopenharmony_ci if (length > 0) { 33cb93a386Sopenharmony_ci string->resize(length); 34cb93a386Sopenharmony_ci if (stream->read(string->writable_str(), length) != length) { return false; } 35cb93a386Sopenharmony_ci } 36cb93a386Sopenharmony_ci return true; 37cb93a386Sopenharmony_ci} 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_cistatic bool write_string(SkWStream* stream, const SkString& string, uint32_t id) { 40cb93a386Sopenharmony_ci if (string.isEmpty()) { return true; } 41cb93a386Sopenharmony_ci return stream->writePackedUInt(id) && 42cb93a386Sopenharmony_ci stream->writePackedUInt(string.size()) && 43cb93a386Sopenharmony_ci stream->write(string.c_str(), string.size()); 44cb93a386Sopenharmony_ci} 45cb93a386Sopenharmony_ci 46cb93a386Sopenharmony_cistatic bool write_uint(SkWStream* stream, size_t n, uint32_t id) { 47cb93a386Sopenharmony_ci return stream->writePackedUInt(id) && 48cb93a386Sopenharmony_ci stream->writePackedUInt(n); 49cb93a386Sopenharmony_ci} 50cb93a386Sopenharmony_ci 51cb93a386Sopenharmony_cistatic size_t SK_WARN_UNUSED_RESULT read_id(SkStream* stream) { 52cb93a386Sopenharmony_ci size_t i; 53cb93a386Sopenharmony_ci if (!stream->readPackedUInt(&i)) { return kInvalid; } 54cb93a386Sopenharmony_ci return i; 55cb93a386Sopenharmony_ci} 56cb93a386Sopenharmony_ci 57cb93a386Sopenharmony_cibool SkFontDescriptor::Deserialize(SkStream* stream, SkFontDescriptor* result) { 58cb93a386Sopenharmony_ci size_t styleBits; 59cb93a386Sopenharmony_ci if (!stream->readPackedUInt(&styleBits)) { return false; } 60cb93a386Sopenharmony_ci result->fStyle = SkFontStyle((styleBits >> 16) & 0xFFFF, 61cb93a386Sopenharmony_ci (styleBits >> 8 ) & 0xFF, 62cb93a386Sopenharmony_ci static_cast<SkFontStyle::Slant>(styleBits & 0xFF)); 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ci size_t coordinateCount; 65cb93a386Sopenharmony_ci using CoordinateCountType = decltype(result->fCoordinateCount); 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_ci size_t index; 68cb93a386Sopenharmony_ci using CollectionIndexType = decltype(result->fCollectionIndex); 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci for (size_t id; (id = read_id(stream)) != kSentinel;) { 71cb93a386Sopenharmony_ci switch (id) { 72cb93a386Sopenharmony_ci case kFontFamilyName: 73cb93a386Sopenharmony_ci if (!read_string(stream, &result->fFamilyName)) { return false; } 74cb93a386Sopenharmony_ci break; 75cb93a386Sopenharmony_ci case kFullName: 76cb93a386Sopenharmony_ci if (!read_string(stream, &result->fFullName)) { return false; } 77cb93a386Sopenharmony_ci break; 78cb93a386Sopenharmony_ci case kPostscriptName: 79cb93a386Sopenharmony_ci if (!read_string(stream, &result->fPostscriptName)) { return false; } 80cb93a386Sopenharmony_ci break; 81cb93a386Sopenharmony_ci case kFontVariation: 82cb93a386Sopenharmony_ci if (!stream->readPackedUInt(&coordinateCount)) { return false; } 83cb93a386Sopenharmony_ci if (!SkTFitsIn<CoordinateCountType>(coordinateCount)) { return false; } 84cb93a386Sopenharmony_ci result->fCoordinateCount = SkTo<CoordinateCountType>(coordinateCount); 85cb93a386Sopenharmony_ci 86cb93a386Sopenharmony_ci result->fVariation.reset(coordinateCount); 87cb93a386Sopenharmony_ci for (size_t i = 0; i < coordinateCount; ++i) { 88cb93a386Sopenharmony_ci if (!stream->readU32(&result->fVariation[i].axis)) { return false; } 89cb93a386Sopenharmony_ci if (!stream->readScalar(&result->fVariation[i].value)) { return false; } 90cb93a386Sopenharmony_ci } 91cb93a386Sopenharmony_ci break; 92cb93a386Sopenharmony_ci case kFontIndex: 93cb93a386Sopenharmony_ci if (!stream->readPackedUInt(&index)) { return false; } 94cb93a386Sopenharmony_ci if (!SkTFitsIn<CollectionIndexType>(index)) { return false; } 95cb93a386Sopenharmony_ci result->fCollectionIndex = SkTo<CollectionIndexType>(index); 96cb93a386Sopenharmony_ci break; 97cb93a386Sopenharmony_ci default: 98cb93a386Sopenharmony_ci SkDEBUGFAIL("Unknown id used by a font descriptor"); 99cb93a386Sopenharmony_ci return false; 100cb93a386Sopenharmony_ci } 101cb93a386Sopenharmony_ci } 102cb93a386Sopenharmony_ci 103cb93a386Sopenharmony_ci size_t length; 104cb93a386Sopenharmony_ci if (!stream->readPackedUInt(&length)) { return false; } 105cb93a386Sopenharmony_ci if (length > 0) { 106cb93a386Sopenharmony_ci sk_sp<SkData> data(SkData::MakeUninitialized(length)); 107cb93a386Sopenharmony_ci if (stream->read(data->writable_data(), length) != length) { 108cb93a386Sopenharmony_ci SkDEBUGFAIL("Could not read font data"); 109cb93a386Sopenharmony_ci return false; 110cb93a386Sopenharmony_ci } 111cb93a386Sopenharmony_ci result->fStream = SkMemoryStream::Make(std::move(data)); 112cb93a386Sopenharmony_ci } 113cb93a386Sopenharmony_ci return true; 114cb93a386Sopenharmony_ci} 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_civoid SkFontDescriptor::serialize(SkWStream* stream) const { 117cb93a386Sopenharmony_ci uint32_t styleBits = (fStyle.weight() << 16) | (fStyle.width() << 8) | (fStyle.slant()); 118cb93a386Sopenharmony_ci stream->writePackedUInt(styleBits); 119cb93a386Sopenharmony_ci 120cb93a386Sopenharmony_ci write_string(stream, fFamilyName, kFontFamilyName); 121cb93a386Sopenharmony_ci write_string(stream, fFullName, kFullName); 122cb93a386Sopenharmony_ci write_string(stream, fPostscriptName, kPostscriptName); 123cb93a386Sopenharmony_ci 124cb93a386Sopenharmony_ci if (fCollectionIndex) { 125cb93a386Sopenharmony_ci write_uint(stream, fCollectionIndex, kFontIndex); 126cb93a386Sopenharmony_ci } 127cb93a386Sopenharmony_ci if (fCoordinateCount) { 128cb93a386Sopenharmony_ci write_uint(stream, fCoordinateCount, kFontVariation); 129cb93a386Sopenharmony_ci for (int i = 0; i < fCoordinateCount; ++i) { 130cb93a386Sopenharmony_ci stream->write32(fVariation[i].axis); 131cb93a386Sopenharmony_ci stream->writeScalar(fVariation[i].value); 132cb93a386Sopenharmony_ci } 133cb93a386Sopenharmony_ci } 134cb93a386Sopenharmony_ci 135cb93a386Sopenharmony_ci stream->writePackedUInt(kSentinel); 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci if (fStream) { 138cb93a386Sopenharmony_ci std::unique_ptr<SkStreamAsset> fontStream = fStream->duplicate(); 139cb93a386Sopenharmony_ci size_t length = fontStream->getLength(); 140cb93a386Sopenharmony_ci stream->writePackedUInt(length); 141cb93a386Sopenharmony_ci stream->writeStream(fontStream.get(), length); 142cb93a386Sopenharmony_ci } else { 143cb93a386Sopenharmony_ci stream->writePackedUInt(0); 144cb93a386Sopenharmony_ci } 145cb93a386Sopenharmony_ci} 146