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

Side by Side Diff: trunk/src/core/SkFontStream.cpp

Issue 12485002: start to plumb ttcIndex into fonthost. For now just add to SkFontStream and its callers. (Closed) Base URL: http://skia.googlecode.com/svn/
Patch Set: Created 7 years, 9 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
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkEndian.h" 8 #include "SkEndian.h"
9 #include "SkFontStream.h" 9 #include "SkFontStream.h"
10 #include "SkStream.h" 10 #include "SkStream.h"
(...skipping 25 matching lines...) Expand all
36 uint32_t fLength; 36 uint32_t fLength;
37 }; 37 };
38 38
39 /** Return the number of tables, or if this is a TTC (collection), return the 39 /** Return the number of tables, or if this is a TTC (collection), return the
40 number of tables in the first element of the collection. In either case, 40 number of tables in the first element of the collection. In either case,
41 if offsetToDir is not-null, set it to the offset to the beginning of the 41 if offsetToDir is not-null, set it to the offset to the beginning of the
42 table headers (SkSFNTDirEntry), relative to the start of the stream. 42 table headers (SkSFNTDirEntry), relative to the start of the stream.
43 43
44 On an error, return 0 for number of tables, and ignore offsetToDir 44 On an error, return 0 for number of tables, and ignore offsetToDir
45 */ 45 */
46 static int count_tables(SkStream* stream, size_t* offsetToDir = NULL) { 46 static int count_tables(SkStream* stream, int ttcIndex, size_t* offsetToDir) {
bungeman-skia 2013/03/05 22:07:33 ttcIndex may well be perfectly well served by an i
47 SkASSERT(ttcIndex >= 0);
48
47 SkSharedTTHeader shared; 49 SkSharedTTHeader shared;
48 if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) { 50 if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
49 return 0; 51 return 0;
50 } 52 }
51 53
52 // by default, SkSFNTHeader is at the start of the stream 54 // by default, SkSFNTHeader is at the start of the stream
53 size_t offset = 0; 55 size_t offset = 0;
54 56
55 // if we're really a collection, the first 4-bytes will be 'ttcf' 57 // if we're really a collection, the first 4-bytes will be 'ttcf'
56 uint32_t tag = SkEndian_SwapBE32(shared.fCollection.fTag); 58 uint32_t tag = SkEndian_SwapBE32(shared.fCollection.fTag);
57 if (SkSetFourByteTag('t', 't', 'c', 'f') == tag) { 59 if (SkSetFourByteTag('t', 't', 'c', 'f') == tag) {
58 if (shared.fCollection.fNumOffsets == 0) { 60 unsigned count = SkEndian_SwapBE32(shared.fCollection.fNumOffsets);
61 if ((unsigned)ttcIndex >= count) {
59 return 0; 62 return 0;
60 } 63 }
61 // this is the offset to the first local SkSFNTHeader 64
62 offset = SkEndian_SwapBE32(shared.fCollection.fOffset0); 65 if (ttcIndex > 0) { // need to read more of the shared header
66 stream->rewind();
67 size_t amount = sizeof(shared) + ttcIndex * sizeof(uint32_t);
68 if (stream->read(&shared, amount) != amount) {
69 return 0;
70 }
71 }
72 // this is the offset to the local SkSFNTHeader
73 offset = SkEndian_SwapBE32((&shared.fCollection.fOffset0)[ttcIndex]);
63 stream->rewind(); 74 stream->rewind();
64 if (stream->skip(offset) != offset) { 75 if (stream->skip(offset) != offset) {
65 return 0; 76 return 0;
66 } 77 }
67 if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) { 78 if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
68 return 0; 79 return 0;
69 } 80 }
70 } 81 }
71 82
72 if (offsetToDir) { 83 if (offsetToDir) {
73 // add the size of the header, so we will point to the DirEntries 84 // add the size of the header, so we will point to the DirEntries
74 *offsetToDir = offset + sizeof(SkSFNTHeader); 85 *offsetToDir = offset + sizeof(SkSFNTHeader);
75 } 86 }
76 return SkEndian_SwapBE16(shared.fSingle.fNumTables); 87 return SkEndian_SwapBE16(shared.fSingle.fNumTables);
77 } 88 }
78 89
79 /////////////////////////////////////////////////////////////////////////////// 90 ///////////////////////////////////////////////////////////////////////////////
80 91
81 struct SfntHeader { 92 struct SfntHeader {
82 SfntHeader() : fCount(0), fDir(NULL) {} 93 SfntHeader() : fCount(0), fDir(NULL) {}
83 ~SfntHeader() { sk_free(fDir); } 94 ~SfntHeader() { sk_free(fDir); }
84 95
85 /** If it returns true, then fCount and fDir are properly initialized. 96 /** If it returns true, then fCount and fDir are properly initialized.
86 Note: fDir will point to the raw array of SkSFNTDirEntry values, 97 Note: fDir will point to the raw array of SkSFNTDirEntry values,
87 meaning they will still be in the file's native endianness (BE). 98 meaning they will still be in the file's native endianness (BE).
88 99
89 fDir will be automatically freed when this object is destroyed 100 fDir will be automatically freed when this object is destroyed
90 */ 101 */
91 bool init(SkStream* stream) { 102 bool init(SkStream* stream, int ttcIndex) {
92 stream->rewind(); 103 stream->rewind();
93 104
94 size_t offsetToDir; 105 size_t offsetToDir;
95 fCount = count_tables(stream, &offsetToDir); 106 fCount = count_tables(stream, ttcIndex, &offsetToDir);
96 if (0 == fCount) { 107 if (0 == fCount) {
97 return false; 108 return false;
98 } 109 }
99 110
100 stream->rewind(); 111 stream->rewind();
101 if (stream->skip(offsetToDir) != offsetToDir) { 112 if (stream->skip(offsetToDir) != offsetToDir) {
102 return false; 113 return false;
103 } 114 }
104 115
105 size_t size = fCount * sizeof(SkSFNTDirEntry); 116 size_t size = fCount * sizeof(SkSFNTDirEntry);
106 fDir = reinterpret_cast<SkSFNTDirEntry*>(sk_malloc_throw(size)); 117 fDir = reinterpret_cast<SkSFNTDirEntry*>(sk_malloc_throw(size));
107 return stream->read(fDir, size) == size; 118 return stream->read(fDir, size) == size;
108 } 119 }
109 120
110 int fCount; 121 int fCount;
111 SkSFNTDirEntry* fDir; 122 SkSFNTDirEntry* fDir;
112 }; 123 };
113 124
114 /////////////////////////////////////////////////////////////////////////////// 125 ///////////////////////////////////////////////////////////////////////////////
115 126
116 int SkFontStream::GetTableTags(SkStream* stream, SkFontTableTag tags[]) { 127 int SkFontStream::CountTTCEntries(SkStream* stream) {
128 stream->rewind();
129
130 SkSharedTTHeader shared;
131 if (stream->read(&shared, sizeof(shared)) != sizeof(shared)) {
132 return -1;
133 }
134
135 // if we're really a collection, the first 4-bytes will be 'ttcf'
136 uint32_t tag = SkEndian_SwapBE32(shared.fCollection.fTag);
137 if (SkSetFourByteTag('t', 't', 'c', 'f') == tag) {
138 return SkEndian_SwapBE32(shared.fCollection.fNumOffsets);
139 } else {
140 return 0;
bungeman-skia 2013/03/05 22:07:33 The doc says return 0 for sfnt, but this returns 0
141 }
142 }
143
144 int SkFontStream::GetTableTags(SkStream* stream, int ttcIndex,
145 SkFontTableTag tags[]) {
117 SfntHeader header; 146 SfntHeader header;
118 if (!header.init(stream)) { 147 if (!header.init(stream, ttcIndex)) {
119 return 0; 148 return 0;
120 } 149 }
121 150
122 if (tags) { 151 if (tags) {
123 for (int i = 0; i < header.fCount; i++) { 152 for (int i = 0; i < header.fCount; i++) {
124 tags[i] = SkEndian_SwapBE32(header.fDir[i].fTag); 153 tags[i] = SkEndian_SwapBE32(header.fDir[i].fTag);
125 } 154 }
126 } 155 }
127 return header.fCount; 156 return header.fCount;
128 } 157 }
129 158
130 size_t SkFontStream::GetTableData(SkStream* stream, SkFontTableTag tag, 159 size_t SkFontStream::GetTableData(SkStream* stream, int ttcIndex,
160 SkFontTableTag tag,
131 size_t offset, size_t length, void* data) { 161 size_t offset, size_t length, void* data) {
132 SfntHeader header; 162 SfntHeader header;
133 if (!header.init(stream)) { 163 if (!header.init(stream, ttcIndex)) {
134 return 0; 164 return 0;
135 } 165 }
136 166
137 for (int i = 0; i < header.fCount; i++) { 167 for (int i = 0; i < header.fCount; i++) {
138 if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) { 168 if (SkEndian_SwapBE32(header.fDir[i].fTag) == tag) {
139 size_t realOffset = SkEndian_SwapBE32(header.fDir[i].fOffset); 169 size_t realOffset = SkEndian_SwapBE32(header.fDir[i].fOffset);
140 size_t realLength = SkEndian_SwapBE32(header.fDir[i].fLength); 170 size_t realLength = SkEndian_SwapBE32(header.fDir[i].fLength);
141 // now sanity check the caller's offset/length 171 // now sanity check the caller's offset/length
142 if (offset >= realLength) { 172 if (offset >= realLength) {
143 return 0; 173 return 0;
(...skipping 16 matching lines...) Expand all
160 } 190 }
161 if (stream->read(data, length) != length) { 191 if (stream->read(data, length) != length) {
162 return 0; 192 return 0;
163 } 193 }
164 } 194 }
165 return length; 195 return length;
166 } 196 }
167 } 197 }
168 return 0; 198 return 0;
169 } 199 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698