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