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