• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
12 enum {
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     kFontAxes       = 0xFC,
21     kFontIndex      = 0xFD,
22     kFontFileName   = 0xFE,  // Remove when MIN_PICTURE_VERSION > 41
23     kSentinel       = 0xFF,
24 };
25 
SkFontDescriptor(SkTypeface::Style style)26 SkFontDescriptor::SkFontDescriptor(SkTypeface::Style style) : fStyle(style) { }
27 
read_string(SkStream * stream,SkString * string)28 static void read_string(SkStream* stream, SkString* string) {
29     const uint32_t length = SkToU32(stream->readPackedUInt());
30     if (length > 0) {
31         string->resize(length);
32         stream->read(string->writable_str(), length);
33     }
34 }
35 
36 // Remove when MIN_PICTURE_VERSION > 41
skip_string(SkStream * stream)37 static void skip_string(SkStream* stream) {
38     const uint32_t length = SkToU32(stream->readPackedUInt());
39     if (length > 0) {
40         stream->skip(length);
41     }
42 }
43 
write_string(SkWStream * stream,const SkString & string,uint32_t id)44 static void write_string(SkWStream* stream, const SkString& string, 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 
read_uint(SkStream * stream)52 static size_t read_uint(SkStream* stream) {
53     return stream->readPackedUInt();
54 }
55 
write_uint(SkWStream * stream,size_t n,uint32_t id)56 static void write_uint(SkWStream* stream, size_t n, uint32_t id) {
57     stream->writePackedUInt(id);
58     stream->writePackedUInt(n);
59 }
60 
Deserialize(SkStream * stream,SkFontDescriptor * result)61 bool SkFontDescriptor::Deserialize(SkStream* stream, SkFontDescriptor* result) {
62     result->fStyle = (SkTypeface::Style)stream->readPackedUInt();
63 
64     SkAutoSTMalloc<4, SkFixed> axis;
65     size_t axisCount = 0;
66     size_t index = 0;
67     for (size_t id; (id = stream->readPackedUInt()) != kSentinel;) {
68         switch (id) {
69             case kFontFamilyName:
70                 read_string(stream, &result->fFamilyName);
71                 break;
72             case kFullName:
73                 read_string(stream, &result->fFullName);
74                 break;
75             case kPostscriptName:
76                 read_string(stream, &result->fPostscriptName);
77                 break;
78             case kFontAxes:
79                 axisCount = read_uint(stream);
80                 axis.reset(axisCount);
81                 for (size_t i = 0; i < axisCount; ++i) {
82                     axis[i] = read_uint(stream);
83                 }
84                 break;
85             case kFontIndex:
86                 index = read_uint(stream);
87                 break;
88             case kFontFileName:  // Remove when MIN_PICTURE_VERSION > 41
89                 skip_string(stream);
90                 break;
91             default:
92                 SkDEBUGFAIL("Unknown id used by a font descriptor");
93                 return false;
94         }
95     }
96 
97     size_t length = stream->readPackedUInt();
98     if (length > 0) {
99         SkAutoTUnref<SkData> data(SkData::NewUninitialized(length));
100         if (stream->read(data->writable_data(), length) == length) {
101             result->fFontData.reset(new SkFontData(new SkMemoryStream(data),
102                                                    index, axis, axisCount));
103         } else {
104             SkDEBUGFAIL("Could not read font data");
105             return false;
106         }
107     }
108     return true;
109 }
110 
serialize(SkWStream * stream)111 void SkFontDescriptor::serialize(SkWStream* stream) {
112     stream->writePackedUInt(fStyle);
113 
114     write_string(stream, fFamilyName, kFontFamilyName);
115     write_string(stream, fFullName, kFullName);
116     write_string(stream, fPostscriptName, kPostscriptName);
117     if (fFontData.get()) {
118         if (fFontData->getIndex()) {
119             write_uint(stream, fFontData->getIndex(), kFontIndex);
120         }
121         if (fFontData->getAxisCount()) {
122             write_uint(stream, fFontData->getAxisCount(), kFontAxes);
123             for (int i = 0; i < fFontData->getAxisCount(); ++i) {
124                 stream->writePackedUInt(fFontData->getAxis()[i]);
125             }
126         }
127     }
128 
129     stream->writePackedUInt(kSentinel);
130 
131     if (fFontData.get() && fFontData->hasStream()) {
132         SkAutoTDelete<SkStreamAsset> fontData(fFontData->detachStream());
133         size_t length = fontData->getLength();
134         stream->writePackedUInt(length);
135         stream->writeStream(fontData, length);
136     } else {
137         stream->writePackedUInt(0);
138     }
139 }
140