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 "SkFontDescriptor.h" 9#include "SkStream.h" 10#include <SkData.h> 11 12enum { 13 // these must match the sfnt 'name' enums 14 kFontFamilyName = 0x01, 15 kFullName = 0x04, 16 kPostscriptName = 0x06, 17 18 // These count backwards from 0xFF, so as not to collide with the SFNT 19 // defines for names in its 'name' table. 20 kFontIndex = 0xFD, 21 kFontFileName = 0xFE, 22 kSentinel = 0xFF, 23}; 24 25SkFontDescriptor::SkFontDescriptor(SkTypeface::Style style) : fFontIndex(0), fStyle(style) { } 26 27static void read_string(SkStream* stream, SkString* string) { 28 const uint32_t length = SkToU32(stream->readPackedUInt()); 29 if (length > 0) { 30 string->resize(length); 31 stream->read(string->writable_str(), length); 32 } 33} 34 35static void write_string(SkWStream* stream, const SkString& string, 36 uint32_t id) { 37 if (!string.isEmpty()) { 38 stream->writePackedUInt(id); 39 stream->writePackedUInt(string.size()); 40 stream->write(string.c_str(), string.size()); 41 } 42} 43 44static size_t read_uint(SkStream* stream) { 45 return stream->readPackedUInt(); 46} 47 48static void write_uint(SkWStream* stream, size_t n, uint32_t id) { 49 stream->writePackedUInt(id); 50 stream->writePackedUInt(n); 51} 52 53SkFontDescriptor::SkFontDescriptor(SkStream* stream) : fFontIndex(0) { 54 fStyle = (SkTypeface::Style)stream->readPackedUInt(); 55 56 for (size_t id; (id = stream->readPackedUInt()) != kSentinel;) { 57 switch (id) { 58 case kFontFamilyName: 59 read_string(stream, &fFamilyName); 60 break; 61 case kFullName: 62 read_string(stream, &fFullName); 63 break; 64 case kPostscriptName: 65 read_string(stream, &fPostscriptName); 66 break; 67 case kFontIndex: 68 fFontIndex = read_uint(stream); 69 break; 70 case kFontFileName: 71 read_string(stream, &fFontFileName); 72 break; 73 default: 74 SkDEBUGFAIL("Unknown id used by a font descriptor"); 75 return; 76 } 77 } 78 79 size_t length = stream->readPackedUInt(); 80 if (length > 0) { 81 SkAutoTUnref<SkData> data(SkData::NewUninitialized(length)); 82 if (stream->read(data->writable_data(), length) == length) { 83 fFontData.reset(SkNEW_ARGS(SkMemoryStream, (data))); 84 } 85 } 86} 87 88void SkFontDescriptor::serialize(SkWStream* stream) { 89 stream->writePackedUInt(fStyle); 90 91 write_string(stream, fFamilyName, kFontFamilyName); 92 write_string(stream, fFullName, kFullName); 93 write_string(stream, fPostscriptName, kPostscriptName); 94 write_string(stream, fFontFileName, kFontFileName); 95 if (fFontIndex) { 96 write_uint(stream, fFontIndex, kFontIndex); 97 } 98 99 stream->writePackedUInt(kSentinel); 100 101 if (fFontData) { 102 size_t length = fFontData->getLength(); 103 stream->writePackedUInt(length); 104 stream->writeStream(fFontData, length); 105 } else { 106 stream->writePackedUInt(0); 107 } 108} 109