Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: skia/ports/SkFontHost_tables.cpp

Issue 113827: Remove the remainder of the skia source code from the Chromium repo.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « skia/ports/SkFontHost_none.cpp ('k') | skia/ports/SkFontHost_win.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #include "SkEndian.h"
2 #include "SkFontHost.h"
3 #include "SkStream.h"
4
5 struct SkSFNTHeader {
6 uint32_t fVersion;
7 uint16_t fNumTables;
8 uint16_t fSearchRange;
9 uint16_t fEntrySelector;
10 uint16_t fRangeShift;
11 };
12
13 struct SkTTCFHeader {
14 uint32_t fTag;
15 uint32_t fVersion;
16 uint32_t fNumOffsets;
17 uint32_t fOffset0; // the first of N (fNumOffsets)
18 };
19
20 union SkSharedTTHeader {
21 SkSFNTHeader fSingle;
22 SkTTCFHeader fCollection;
23 };
24
25 struct SkSFNTDirEntry {
26 uint32_t fTag;
27 uint32_t fChecksum;
28 uint32_t fOffset;
29 uint32_t fLength;
30 };
31
32 static int count_tables(SkStream* stream, size_t* offsetToDir = NULL) {
33 SkSharedTTHeader shared;
34 if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
35 return 0;
36 }
37
38 uint32_t tag = SkEndian_SwapBE32(shared.fCollection.fTag);
39 if (SkSetFourByteTag('t', 't', 'c', 'f') == tag) {
40 if (shared.fCollection.fNumOffsets == 0) {
41 return 0;
42 }
43 size_t offset = SkEndian_SwapBE32(shared.fCollection.fOffset0);
44 stream->rewind();
45 if (stream->skip(offset) != offset) {
46 return 0;
47 }
48 if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
49 return 0;
50 }
51 if (offsetToDir) {
52 *offsetToDir = offset;
53 }
54 } else {
55 *offsetToDir = 0;
56 }
57
58 return SkEndian_SwapBE16(shared.fSingle.fNumTables);
59 }
60
61 ///////////////////////////////////////////////////////////////////////////////
62
63 struct SfntHeader {
64 SfntHeader() : fCount(0), fDir(NULL) {}
65 ~SfntHeader() { sk_free(fDir); }
66
67 bool init(SkStream* stream) {
68 size_t offsetToDir;
69 fCount = count_tables(stream, &offsetToDir);
70 if (0 == fCount) {
71 return false;
72 }
73
74 stream->rewind();
75 const size_t tableRecordOffset = offsetToDir + sizeof(SkSFNTHeader);
76 if (stream->skip(tableRecordOffset) != tableRecordOffset) {
77 return false;
78 }
79
80 size_t size = fCount * sizeof(SkSFNTDirEntry);
81 fDir = reinterpret_cast<SkSFNTDirEntry*>(sk_malloc_throw(size));
82 return stream->read(fDir, size) == size;
83 }
84
85 int fCount;
86 SkSFNTDirEntry* fDir;
87 };
88
89 ///////////////////////////////////////////////////////////////////////////////
90
91 int SkFontHost::CountTables(SkFontID fontID) {
92 SkStream* stream = SkFontHost::OpenStream(fontID);
93 if (NULL == stream) {
94 return 0;
95 }
96
97 SkAutoUnref au(stream);
98 return count_tables(stream);
99 }
100
101 int SkFontHost::GetTableTags(SkFontID fontID, SkFontTableTag tags[]) {
102 SkStream* stream = SkFontHost::OpenStream(fontID);
103 if (NULL == stream) {
104 return 0;
105 }
106
107 SkAutoUnref au(stream);
108 SfntHeader header;
109 if (!header.init(stream)) {
110 return 0;
111 }
112
113 for (int i = 0; i < header.fCount; i++) {
114 tags[i] = SkEndian_SwapBE32(header.fDir[i].fTag);
115 }
116 return header.fCount;
117 }
118
119 size_t SkFontHost::GetTableSize(SkFontID fontID, SkFontTableTag tag) {
120 SkStream* stream = SkFontHost::OpenStream(fontID);
121 if (NULL == stream) {
122 return 0;
123 }
124
125 SkAutoUnref au(stream);
126 SfntHeader header;
127 if (!header.init(stream)) {
128 return 0;
129 }
130
131 for (int i = 0; i < header.fCount; i++) {
132 if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) {
133 return SkEndian_SwapBE32(header.fDir[i].fLength);
134 }
135 }
136 return 0;
137 }
138
139 size_t SkFontHost::GetTableData(SkFontID fontID, SkFontTableTag tag,
140 size_t offset, size_t length, void* data) {
141 SkStream* stream = SkFontHost::OpenStream(fontID);
142 if (NULL == stream) {
143 return 0;
144 }
145
146 SkAutoUnref au(stream);
147 SfntHeader header;
148 if (!header.init(stream)) {
149 return 0;
150 }
151
152 for (int i = 0; i < header.fCount; i++) {
153 if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) {
154 size_t realOffset = SkEndian_SwapBE32(header.fDir[i].fOffset);
155 size_t realLength = SkEndian_SwapBE32(header.fDir[i].fLength);
156 // now sanity check the caller's offset/length
157 if (offset >= realLength) {
158 return 0;
159 }
160 // if the caller is trusting the length from the file, then a
161 // hostile file might choose a value which would overflow offset +
162 // length.
163 if (offset + length < offset) {
164 return 0;
165 }
166 if (offset + length > realLength) {
167 length = realLength - offset;
168 }
169 // skip the stream to the part of the table we want to copy from
170 stream->rewind();
171 size_t bytesToSkip = realOffset + offset;
172 if (stream->skip(bytesToSkip) != bytesToSkip) {
173 return 0;
174 }
175 if (stream->read(data, length) != length) {
176 return 0;
177 }
178 return length;
179 }
180 }
181 return 0;
182 }
183
OLDNEW
« no previous file with comments | « skia/ports/SkFontHost_none.cpp ('k') | skia/ports/SkFontHost_win.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698