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, // Remove when MIN_PICTURE_VERSION > 41 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 35// Remove when MIN_PICTURE_VERSION > 41 36static void skip_string(SkStream* stream) { 37 const uint32_t length = SkToU32(stream->readPackedUInt()); 38 if (length > 0) { 39 stream->skip(length); 40 } 41} 42 43static void write_string(SkWStream* stream, const SkString& string, 44 uint32_t id) { 45 if (!string.isEmpty()) { 46 stream->writePackedUInt(id); 47 stream->writePackedUInt(string.size()); 48 stream->write(string.c_str(), string.size()); 49 } 50} 51 52static size_t read_uint(SkStream* stream) { 53 return stream->readPackedUInt(); 54} 55 56static void write_uint(SkWStream* stream, size_t n, uint32_t id) { 57 stream->writePackedUInt(id); 58 stream->writePackedUInt(n); 59} 60 61SkFontDescriptor::SkFontDescriptor(SkStream* stream) : fFontIndex(0) { 62 fStyle = (SkTypeface::Style)stream->readPackedUInt(); 63 64 for (size_t id; (id = stream->readPackedUInt()) != kSentinel;) { 65 switch (id) { 66 case kFontFamilyName: 67 read_string(stream, &fFamilyName); 68 break; 69 case kFullName: 70 read_string(stream, &fFullName); 71 break; 72 case kPostscriptName: 73 read_string(stream, &fPostscriptName); 74 break; 75 case kFontIndex: 76 fFontIndex = read_uint(stream); 77 break; 78 case kFontFileName: // Remove when MIN_PICTURE_VERSION > 41 79 skip_string(stream); 80 break; 81 default: 82 SkDEBUGFAIL("Unknown id used by a font descriptor"); 83 return; 84 } 85 } 86 87 size_t length = stream->readPackedUInt(); 88 if (length > 0) { 89 SkAutoTUnref<SkData> data(SkData::NewUninitialized(length)); 90 if (stream->read(data->writable_data(), length) == length) { 91 fFontData.reset(SkNEW_ARGS(SkMemoryStream, (data))); 92 } 93 } 94} 95 96void SkFontDescriptor::serialize(SkWStream* stream) { 97 stream->writePackedUInt(fStyle); 98 99 write_string(stream, fFamilyName, kFontFamilyName); 100 write_string(stream, fFullName, kFullName); 101 write_string(stream, fPostscriptName, kPostscriptName); 102 if (fFontIndex) { 103 write_uint(stream, fFontIndex, kFontIndex); 104 } 105 106 stream->writePackedUInt(kSentinel); 107 108 if (fFontData) { 109 size_t length = fFontData->getLength(); 110 stream->writePackedUInt(length); 111 stream->writeStream(fFontData, length); 112 } else { 113 stream->writePackedUInt(0); 114 } 115} 116