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

Side by Side Diff: third_party/ots/src/glyf.cc

Issue 1252363005: Update OTS to revision a7a3b94 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 4 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
« no previous file with comments | « third_party/ots/src/gdef.cc ('k') | third_party/ots/src/gpos.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "glyf.h" 5 #include "glyf.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 9
10 #include "head.h" 10 #include "head.h"
11 #include "loca.h" 11 #include "loca.h"
12 #include "maxp.h" 12 #include "maxp.h"
13 13
14 // glyf - Glyph Data 14 // glyf - Glyph Data
15 // http://www.microsoft.com/typography/otspec/glyf.htm 15 // http://www.microsoft.com/typography/otspec/glyf.htm
16 16
17 #define TABLE_NAME "glyf" 17 #define TABLE_NAME "glyf"
18 18
19 namespace { 19 namespace {
20 20
21 bool ParseFlagsForSimpleGlyph(ots::OpenTypeFile *file, 21 bool ParseFlagsForSimpleGlyph(ots::Font *font,
22 ots::Buffer *table, 22 ots::Buffer *table,
23 uint32_t gly_length, 23 uint32_t gly_length,
24 uint32_t num_flags, 24 uint32_t num_flags,
25 uint32_t *flags_count_logical, 25 uint32_t *flags_count_logical,
26 uint32_t *flags_count_physical, 26 uint32_t *flags_count_physical,
27 uint32_t *xy_coordinates_length) { 27 uint32_t *xy_coordinates_length) {
28 uint8_t flag = 0; 28 uint8_t flag = 0;
29 if (!table->ReadU8(&flag)) { 29 if (!table->ReadU8(&flag)) {
30 return OTS_FAILURE_MSG("Can't read flag"); 30 return OTS_FAILURE_MSG("Can't read flag");
31 } 31 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 } 68 }
69 69
70 *xy_coordinates_length += delta; 70 *xy_coordinates_length += delta;
71 if (gly_length < *xy_coordinates_length) { 71 if (gly_length < *xy_coordinates_length) {
72 return OTS_FAILURE_MSG("Glyph coordinates length too low (%d < %d)", gly_len gth, *xy_coordinates_length); 72 return OTS_FAILURE_MSG("Glyph coordinates length too low (%d < %d)", gly_len gth, *xy_coordinates_length);
73 } 73 }
74 74
75 return true; 75 return true;
76 } 76 }
77 77
78 bool ParseSimpleGlyph(ots::OpenTypeFile *file, const uint8_t *data, 78 bool ParseSimpleGlyph(ots::Font *font, const uint8_t *data,
79 ots::Buffer *table, int16_t num_contours, 79 ots::Buffer *table, int16_t num_contours,
80 uint32_t gly_offset, uint32_t gly_length, 80 uint32_t gly_offset, uint32_t gly_length,
81 uint32_t *new_size) { 81 uint32_t *new_size) {
82 ots::OpenTypeGLYF *glyf = file->glyf; 82 ots::OpenTypeGLYF *glyf = font->glyf;
83 83
84 // read the end-points array 84 // read the end-points array
85 uint16_t num_flags = 0; 85 uint16_t num_flags = 0;
86 for (int i = 0; i < num_contours; ++i) { 86 for (int i = 0; i < num_contours; ++i) {
87 uint16_t tmp_index = 0; 87 uint16_t tmp_index = 0;
88 if (!table->ReadU16(&tmp_index)) { 88 if (!table->ReadU16(&tmp_index)) {
89 return OTS_FAILURE_MSG("Can't read contour index %d", i); 89 return OTS_FAILURE_MSG("Can't read contour index %d", i);
90 } 90 }
91 if (tmp_index == 0xffffu) { 91 if (tmp_index == 0xffffu) {
92 return OTS_FAILURE_MSG("Bad contour index %d", i); 92 return OTS_FAILURE_MSG("Bad contour index %d", i);
93 } 93 }
94 // check if the indices are monotonically increasing 94 // check if the indices are monotonically increasing
95 if (i && (tmp_index + 1 <= num_flags)) { 95 if (i && (tmp_index + 1 <= num_flags)) {
96 return OTS_FAILURE_MSG("Decreasing contour index %d + 1 <= %d", tmp_index, num_flags); 96 return OTS_FAILURE_MSG("Decreasing contour index %d + 1 <= %d", tmp_index, num_flags);
97 } 97 }
98 num_flags = tmp_index + 1; 98 num_flags = tmp_index + 1;
99 } 99 }
100 100
101 uint16_t bytecode_length = 0; 101 uint16_t bytecode_length = 0;
102 if (!table->ReadU16(&bytecode_length)) { 102 if (!table->ReadU16(&bytecode_length)) {
103 return OTS_FAILURE_MSG("Can't read bytecode length"); 103 return OTS_FAILURE_MSG("Can't read bytecode length");
104 } 104 }
105 if ((file->maxp->version_1) && 105 if ((font->maxp->version_1) &&
106 (file->maxp->max_size_glyf_instructions < bytecode_length)) { 106 (font->maxp->max_size_glyf_instructions < bytecode_length)) {
107 return OTS_FAILURE_MSG("Bytecode length too high %d", bytecode_length); 107 return OTS_FAILURE_MSG("Bytecode length too high %d", bytecode_length);
108 } 108 }
109 109
110 const uint32_t gly_header_length = 10 + num_contours * 2 + 2; 110 const uint32_t gly_header_length = 10 + num_contours * 2 + 2;
111 if (gly_length < (gly_header_length + bytecode_length)) { 111 if (gly_length < (gly_header_length + bytecode_length)) {
112 return OTS_FAILURE_MSG("Glyph header length too high %d", gly_header_length) ; 112 return OTS_FAILURE_MSG("Glyph header length too high %d", gly_header_length) ;
113 } 113 }
114 114
115 glyf->iov.push_back(std::make_pair( 115 glyf->iov.push_back(std::make_pair(
116 data + gly_offset, 116 data + gly_offset,
117 static_cast<size_t>(gly_header_length + bytecode_length))); 117 static_cast<size_t>(gly_header_length + bytecode_length)));
118 118
119 if (!table->Skip(bytecode_length)) { 119 if (!table->Skip(bytecode_length)) {
120 return OTS_FAILURE_MSG("Can't skip bytecode of length %d", bytecode_length); 120 return OTS_FAILURE_MSG("Can't skip bytecode of length %d", bytecode_length);
121 } 121 }
122 122
123 uint32_t flags_count_physical = 0; // on memory 123 uint32_t flags_count_physical = 0; // on memory
124 uint32_t xy_coordinates_length = 0; 124 uint32_t xy_coordinates_length = 0;
125 for (uint32_t flags_count_logical = 0; 125 for (uint32_t flags_count_logical = 0;
126 flags_count_logical < num_flags; 126 flags_count_logical < num_flags;
127 ++flags_count_logical, ++flags_count_physical) { 127 ++flags_count_logical, ++flags_count_physical) {
128 if (!ParseFlagsForSimpleGlyph(file, 128 if (!ParseFlagsForSimpleGlyph(font,
129 table, 129 table,
130 gly_length, 130 gly_length,
131 num_flags, 131 num_flags,
132 &flags_count_logical, 132 &flags_count_logical,
133 &flags_count_physical, 133 &flags_count_physical,
134 &xy_coordinates_length)) { 134 &xy_coordinates_length)) {
135 return OTS_FAILURE_MSG("Failed to parse glyph flags %d", flags_count_logic al); 135 return OTS_FAILURE_MSG("Failed to parse glyph flags %d", flags_count_logic al);
136 } 136 }
137 } 137 }
138 138
(...skipping 16 matching lines...) Expand all
155 *new_size 155 *new_size
156 = gly_header_length + flags_count_physical + xy_coordinates_length + bytec ode_length; 156 = gly_header_length + flags_count_physical + xy_coordinates_length + bytec ode_length;
157 157
158 return true; 158 return true;
159 } 159 }
160 160
161 } // namespace 161 } // namespace
162 162
163 namespace ots { 163 namespace ots {
164 164
165 bool ots_glyf_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { 165 bool ots_glyf_parse(Font *font, const uint8_t *data, size_t length) {
166 Buffer table(data, length); 166 Buffer table(data, length);
167 167
168 if (!file->maxp || !file->loca || !file->head) { 168 if (!font->maxp || !font->loca || !font->head) {
169 return OTS_FAILURE_MSG("Missing maxp or loca or head table needed by glyf ta ble"); 169 return OTS_FAILURE_MSG("Missing maxp or loca or head table needed by glyf ta ble");
170 } 170 }
171 171
172 OpenTypeGLYF *glyf = new OpenTypeGLYF; 172 OpenTypeGLYF *glyf = new OpenTypeGLYF;
173 file->glyf = glyf; 173 font->glyf = glyf;
174 174
175 const unsigned num_glyphs = file->maxp->num_glyphs; 175 const unsigned num_glyphs = font->maxp->num_glyphs;
176 std::vector<uint32_t> &offsets = file->loca->offsets; 176 std::vector<uint32_t> &offsets = font->loca->offsets;
177 177
178 if (offsets.size() != num_glyphs + 1) { 178 if (offsets.size() != num_glyphs + 1) {
179 return OTS_FAILURE_MSG("Invalide glyph offsets size %ld != %d", offsets.size (), num_glyphs + 1); 179 return OTS_FAILURE_MSG("Invalide glyph offsets size %ld != %d", offsets.size (), num_glyphs + 1);
180 } 180 }
181 181
182 std::vector<uint32_t> resulting_offsets(num_glyphs + 1); 182 std::vector<uint32_t> resulting_offsets(num_glyphs + 1);
183 uint32_t current_offset = 0; 183 uint32_t current_offset = 0;
184 184
185 for (unsigned i = 0; i < num_glyphs; ++i) { 185 for (unsigned i = 0; i < num_glyphs; ++i) {
186 const unsigned gly_offset = offsets[i]; 186 const unsigned gly_offset = offsets[i];
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 xmin = xmax = ymin = ymax = 0; 228 xmin = xmax = ymin = ymax = 0;
229 } 229 }
230 230
231 if (xmin > xmax || ymin > ymax) { 231 if (xmin > xmax || ymin > ymax) {
232 return OTS_FAILURE_MSG("Bad bounding box values bl=(%d, %d), tr=(%d, %d) i n glyph %d", xmin, ymin, xmax, ymax, i); 232 return OTS_FAILURE_MSG("Bad bounding box values bl=(%d, %d), tr=(%d, %d) i n glyph %d", xmin, ymin, xmax, ymax, i);
233 } 233 }
234 234
235 unsigned new_size = 0; 235 unsigned new_size = 0;
236 if (num_contours >= 0) { 236 if (num_contours >= 0) {
237 // this is a simple glyph and might contain bytecode 237 // this is a simple glyph and might contain bytecode
238 if (!ParseSimpleGlyph(file, data, &table, 238 if (!ParseSimpleGlyph(font, data, &table,
239 num_contours, gly_offset, gly_length, &new_size)) { 239 num_contours, gly_offset, gly_length, &new_size)) {
240 return OTS_FAILURE_MSG("Failed to parse glyph %d", i); 240 return OTS_FAILURE_MSG("Failed to parse glyph %d", i);
241 } 241 }
242 } else { 242 } else {
243 // it's a composite glyph without any bytecode. Enqueue the whole thing 243 // it's a composite glyph without any bytecode. Enqueue the whole thing
244 glyf->iov.push_back(std::make_pair(data + gly_offset, 244 glyf->iov.push_back(std::make_pair(data + gly_offset,
245 static_cast<size_t>(gly_length))); 245 static_cast<size_t>(gly_length)));
246 new_size = gly_length; 246 new_size = gly_length;
247 } 247 }
248 248
249 resulting_offsets[i] = current_offset; 249 resulting_offsets[i] = current_offset;
250 // glyphs must be four byte aligned 250 // glyphs must be four byte aligned
251 // TODO(yusukes): investigate whether this padding is really necessary. 251 // TODO(yusukes): investigate whether this padding is really necessary.
252 // Which part of the spec requires this? 252 // Which part of the spec requires this?
253 const unsigned padding = (4 - (new_size & 3)) % 4; 253 const unsigned padding = (4 - (new_size & 3)) % 4;
254 if (padding) { 254 if (padding) {
255 glyf->iov.push_back(std::make_pair( 255 glyf->iov.push_back(std::make_pair(
256 reinterpret_cast<const uint8_t*>("\x00\x00\x00\x00"), 256 reinterpret_cast<const uint8_t*>("\x00\x00\x00\x00"),
257 static_cast<size_t>(padding))); 257 static_cast<size_t>(padding)));
258 new_size += padding; 258 new_size += padding;
259 } 259 }
260 current_offset += new_size; 260 current_offset += new_size;
261 } 261 }
262 resulting_offsets[num_glyphs] = current_offset; 262 resulting_offsets[num_glyphs] = current_offset;
263 263
264 const uint16_t max16 = std::numeric_limits<uint16_t>::max(); 264 const uint16_t max16 = std::numeric_limits<uint16_t>::max();
265 if ((*std::max_element(resulting_offsets.begin(), 265 if ((*std::max_element(resulting_offsets.begin(),
266 resulting_offsets.end()) >= (max16 * 2u)) && 266 resulting_offsets.end()) >= (max16 * 2u)) &&
267 (file->head->index_to_loc_format != 1)) { 267 (font->head->index_to_loc_format != 1)) {
268 OTS_WARNING("2-bytes indexing is not possible (due to the padding above)"); 268 OTS_WARNING("2-bytes indexing is not possible (due to the padding above)");
269 file->head->index_to_loc_format = 1; 269 font->head->index_to_loc_format = 1;
270 } 270 }
271 271
272 file->loca->offsets = resulting_offsets; 272 font->loca->offsets = resulting_offsets;
273 return true; 273 return true;
274 } 274 }
275 275
276 bool ots_glyf_should_serialise(OpenTypeFile *file) { 276 bool ots_glyf_should_serialise(Font *font) {
277 return file->glyf != NULL; 277 return font->glyf != NULL;
278 } 278 }
279 279
280 bool ots_glyf_serialise(OTSStream *out, OpenTypeFile *file) { 280 bool ots_glyf_serialise(OTSStream *out, Font *font) {
281 const OpenTypeGLYF *glyf = file->glyf; 281 const OpenTypeGLYF *glyf = font->glyf;
282 282
283 for (unsigned i = 0; i < glyf->iov.size(); ++i) { 283 for (unsigned i = 0; i < glyf->iov.size(); ++i) {
284 if (!out->Write(glyf->iov[i].first, glyf->iov[i].second)) { 284 if (!out->Write(glyf->iov[i].first, glyf->iov[i].second)) {
285 return OTS_FAILURE_MSG("Falied to write glyph %d", i); 285 return OTS_FAILURE_MSG("Falied to write glyph %d", i);
286 } 286 }
287 } 287 }
288 288
289 return true; 289 return true;
290 } 290 }
291 291
292 void ots_glyf_free(OpenTypeFile *file) { 292 void ots_glyf_reuse(Font *font, Font *other) {
293 delete file->glyf; 293 font->glyf = other->glyf;
294 font->glyf_reused = true;
295 }
296
297 void ots_glyf_free(Font *font) {
298 delete font->glyf;
294 } 299 }
295 300
296 } // namespace ots 301 } // namespace ots
297 302
298 #undef TABLE_NAME 303 #undef TABLE_NAME
OLDNEW
« no previous file with comments | « third_party/ots/src/gdef.cc ('k') | third_party/ots/src/gpos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698