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

Side by Side Diff: src/ots.cc

Issue 10273021: Revive Tag() function (Closed) Base URL: http://ots.googlecode.com/svn/trunk/
Patch Set: Created 8 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 | « no previous file | no next file » | 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 "ots.h" 5 #include "ots.h"
6 6
7 #include <sys/types.h> 7 #include <sys/types.h>
8 #include <zlib.h> 8 #include <zlib.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 for (unsigned i = 0; i < 4; ++i) { 42 for (unsigned i = 0; i < 4; ++i) {
43 const uint32_t check = tag_value & 0xff; 43 const uint32_t check = tag_value & 0xff;
44 if (check < 32 || check > 126) { 44 if (check < 32 || check > 126) {
45 return false; // non-ASCII character found. 45 return false; // non-ASCII character found.
46 } 46 }
47 tag_value >>= 8; 47 tag_value >>= 8;
48 } 48 }
49 return true; 49 return true;
50 } 50 }
51 51
52 uint32_t Tag(const char *tag_str) {
53 uint32_t ret;
54 std::memcpy(&ret, tag_str, 4);
55 return ret;
56 }
57
52 struct OutputTable { 58 struct OutputTable {
53 uint32_t tag; 59 uint32_t tag;
54 size_t offset; 60 size_t offset;
55 size_t length; 61 size_t length;
56 uint32_t chksum; 62 uint32_t chksum;
57 63
58 static bool SortByTag(const OutputTable& a, const OutputTable& b) { 64 static bool SortByTag(const OutputTable& a, const OutputTable& b) {
59 const uint32_t atag = ntohl(a.tag); 65 const uint32_t atag = ntohl(a.tag);
60 const uint32_t btag = ntohl(b.tag); 66 const uint32_t btag = ntohl(b.tag);
61 return atag < btag; 67 return atag < btag;
(...skipping 12 matching lines...) Expand all
74 uint8_t* Allocate(size_t length) { 80 uint8_t* Allocate(size_t length) {
75 uint8_t* p = new uint8_t[length]; 81 uint8_t* p = new uint8_t[length];
76 hunks_.push_back(p); 82 hunks_.push_back(p);
77 return p; 83 return p;
78 } 84 }
79 85
80 private: 86 private:
81 std::vector<uint8_t*> hunks_; 87 std::vector<uint8_t*> hunks_;
82 }; 88 };
83 89
84 // Use a macro instead of a function because gcc 4.4.3 creates static
85 // initializers in that case.
86 #if defined(__BIG_ENDIAN__) || defined(_BIG_ENDIAN)
87 #define TAG(d, c, b, a) (a | (b << 8) | (c << 16) | (d << 24))
88 #else
89 #define TAG(a, b, c, d) (a | (b << 8) | (c << 16) | (d << 24))
90 #endif
91
92 const struct { 90 const struct {
93 uint32_t tag; 91 const char* tag;
94 bool (*parse)(ots::OpenTypeFile *otf, const uint8_t *data, size_t length); 92 bool (*parse)(ots::OpenTypeFile *otf, const uint8_t *data, size_t length);
95 bool (*serialise)(ots::OTSStream *out, ots::OpenTypeFile *file); 93 bool (*serialise)(ots::OTSStream *out, ots::OpenTypeFile *file);
96 bool (*should_serialise)(ots::OpenTypeFile *file); 94 bool (*should_serialise)(ots::OpenTypeFile *file);
97 void (*free)(ots::OpenTypeFile *file); 95 void (*free)(ots::OpenTypeFile *file);
98 bool required; 96 bool required;
99 } table_parsers[] = { 97 } table_parsers[] = {
100 { TAG('m', 'a', 'x', 'p'), ots::ots_maxp_parse, ots::ots_maxp_serialise, 98 { "maxp", ots::ots_maxp_parse, ots::ots_maxp_serialise,
101 ots::ots_maxp_should_serialise, ots::ots_maxp_free, true }, 99 ots::ots_maxp_should_serialise, ots::ots_maxp_free, true },
102 { TAG('h', 'e', 'a', 'd'), ots::ots_head_parse, ots::ots_head_serialise, 100 { "head", ots::ots_head_parse, ots::ots_head_serialise,
103 ots::ots_head_should_serialise, ots::ots_head_free, true }, 101 ots::ots_head_should_serialise, ots::ots_head_free, true },
104 { TAG('O', 'S', '/', '2'), ots::ots_os2_parse, ots::ots_os2_serialise, 102 { "OS/2", ots::ots_os2_parse, ots::ots_os2_serialise,
105 ots::ots_os2_should_serialise, ots::ots_os2_free, true }, 103 ots::ots_os2_should_serialise, ots::ots_os2_free, true },
106 { TAG('c', 'm', 'a', 'p'), ots::ots_cmap_parse, ots::ots_cmap_serialise, 104 { "cmap", ots::ots_cmap_parse, ots::ots_cmap_serialise,
107 ots::ots_cmap_should_serialise, ots::ots_cmap_free, true }, 105 ots::ots_cmap_should_serialise, ots::ots_cmap_free, true },
108 { TAG('h', 'h', 'e', 'a'), ots::ots_hhea_parse, ots::ots_hhea_serialise, 106 { "hhea", ots::ots_hhea_parse, ots::ots_hhea_serialise,
109 ots::ots_hhea_should_serialise, ots::ots_hhea_free, true }, 107 ots::ots_hhea_should_serialise, ots::ots_hhea_free, true },
110 { TAG('h', 'm', 't', 'x'), ots::ots_hmtx_parse, ots::ots_hmtx_serialise, 108 { "hmtx", ots::ots_hmtx_parse, ots::ots_hmtx_serialise,
111 ots::ots_hmtx_should_serialise, ots::ots_hmtx_free, true }, 109 ots::ots_hmtx_should_serialise, ots::ots_hmtx_free, true },
112 { TAG('n', 'a', 'm', 'e'), ots::ots_name_parse, ots::ots_name_serialise, 110 { "name", ots::ots_name_parse, ots::ots_name_serialise,
113 ots::ots_name_should_serialise, ots::ots_name_free, true }, 111 ots::ots_name_should_serialise, ots::ots_name_free, true },
114 { TAG('p', 'o', 's', 't'), ots::ots_post_parse, ots::ots_post_serialise, 112 { "post", ots::ots_post_parse, ots::ots_post_serialise,
115 ots::ots_post_should_serialise, ots::ots_post_free, true }, 113 ots::ots_post_should_serialise, ots::ots_post_free, true },
116 { TAG('l', 'o', 'c', 'a'), ots::ots_loca_parse, ots::ots_loca_serialise, 114 { "loca", ots::ots_loca_parse, ots::ots_loca_serialise,
117 ots::ots_loca_should_serialise, ots::ots_loca_free, false }, 115 ots::ots_loca_should_serialise, ots::ots_loca_free, false },
118 { TAG('g', 'l', 'y', 'f'), ots::ots_glyf_parse, ots::ots_glyf_serialise, 116 { "glyf", ots::ots_glyf_parse, ots::ots_glyf_serialise,
119 ots::ots_glyf_should_serialise, ots::ots_glyf_free, false }, 117 ots::ots_glyf_should_serialise, ots::ots_glyf_free, false },
120 { TAG('C', 'F', 'F', ' '), ots::ots_cff_parse, ots::ots_cff_serialise, 118 { "CFF ", ots::ots_cff_parse, ots::ots_cff_serialise,
121 ots::ots_cff_should_serialise, ots::ots_cff_free, false }, 119 ots::ots_cff_should_serialise, ots::ots_cff_free, false },
122 { TAG('V', 'D', 'M', 'X'), ots::ots_vdmx_parse, ots::ots_vdmx_serialise, 120 { "VDMX", ots::ots_vdmx_parse, ots::ots_vdmx_serialise,
123 ots::ots_vdmx_should_serialise, ots::ots_vdmx_free, false }, 121 ots::ots_vdmx_should_serialise, ots::ots_vdmx_free, false },
124 { TAG('h', 'd', 'm', 'x'), ots::ots_hdmx_parse, ots::ots_hdmx_serialise, 122 { "hdmx", ots::ots_hdmx_parse, ots::ots_hdmx_serialise,
125 ots::ots_hdmx_should_serialise, ots::ots_hdmx_free, false }, 123 ots::ots_hdmx_should_serialise, ots::ots_hdmx_free, false },
126 { TAG('g', 'a', 's', 'p'), ots::ots_gasp_parse, ots::ots_gasp_serialise, 124 { "gasp", ots::ots_gasp_parse, ots::ots_gasp_serialise,
127 ots::ots_gasp_should_serialise, ots::ots_gasp_free, false }, 125 ots::ots_gasp_should_serialise, ots::ots_gasp_free, false },
128 { TAG('c', 'v', 't', ' '), ots::ots_cvt_parse, ots::ots_cvt_serialise, 126 { "cvt ", ots::ots_cvt_parse, ots::ots_cvt_serialise,
129 ots::ots_cvt_should_serialise, ots::ots_cvt_free, false }, 127 ots::ots_cvt_should_serialise, ots::ots_cvt_free, false },
130 { TAG('f', 'p', 'g', 'm'), ots::ots_fpgm_parse, ots::ots_fpgm_serialise, 128 { "fpgm", ots::ots_fpgm_parse, ots::ots_fpgm_serialise,
131 ots::ots_fpgm_should_serialise, ots::ots_fpgm_free, false }, 129 ots::ots_fpgm_should_serialise, ots::ots_fpgm_free, false },
132 { TAG('p', 'r', 'e', 'p'), ots::ots_prep_parse, ots::ots_prep_serialise, 130 { "prep", ots::ots_prep_parse, ots::ots_prep_serialise,
133 ots::ots_prep_should_serialise, ots::ots_prep_free, false }, 131 ots::ots_prep_should_serialise, ots::ots_prep_free, false },
134 { TAG('L', 'T', 'S', 'H'), ots::ots_ltsh_parse, ots::ots_ltsh_serialise, 132 { "LTSH", ots::ots_ltsh_parse, ots::ots_ltsh_serialise,
135 ots::ots_ltsh_should_serialise, ots::ots_ltsh_free, false }, 133 ots::ots_ltsh_should_serialise, ots::ots_ltsh_free, false },
136 { TAG('V', 'O', 'R', 'G'), ots::ots_vorg_parse, ots::ots_vorg_serialise, 134 { "VORG", ots::ots_vorg_parse, ots::ots_vorg_serialise,
137 ots::ots_vorg_should_serialise, ots::ots_vorg_free, false }, 135 ots::ots_vorg_should_serialise, ots::ots_vorg_free, false },
138 { TAG('k', 'e', 'r', 'n'), ots::ots_kern_parse, ots::ots_kern_serialise, 136 { "kern", ots::ots_kern_parse, ots::ots_kern_serialise,
139 ots::ots_kern_should_serialise, ots::ots_kern_free, false }, 137 ots::ots_kern_should_serialise, ots::ots_kern_free, false },
140 // We need to parse GDEF table in advance of parsing GSUB/GPOS tables 138 // We need to parse GDEF table in advance of parsing GSUB/GPOS tables
141 // because they could refer GDEF table. 139 // because they could refer GDEF table.
142 { TAG('G', 'D', 'E', 'F'), ots::ots_gdef_parse, ots::ots_gdef_serialise, 140 { "GDEF", ots::ots_gdef_parse, ots::ots_gdef_serialise,
143 ots::ots_gdef_should_serialise, ots::ots_gdef_free, false }, 141 ots::ots_gdef_should_serialise, ots::ots_gdef_free, false },
144 { TAG('G', 'P', 'O', 'S'), ots::ots_gpos_parse, ots::ots_gpos_serialise, 142 { "GPOS", ots::ots_gpos_parse, ots::ots_gpos_serialise,
145 ots::ots_gpos_should_serialise, ots::ots_gpos_free, false }, 143 ots::ots_gpos_should_serialise, ots::ots_gpos_free, false },
146 { TAG('G', 'S', 'U', 'B'), ots::ots_gsub_parse, ots::ots_gsub_serialise, 144 { "GSUB", ots::ots_gsub_parse, ots::ots_gsub_serialise,
147 ots::ots_gsub_should_serialise, ots::ots_gsub_free, false }, 145 ots::ots_gsub_should_serialise, ots::ots_gsub_free, false },
148 { TAG('v', 'h', 'e', 'a'), ots::ots_vhea_parse, ots::ots_vhea_serialise, 146 { "vhea", ots::ots_vhea_parse, ots::ots_vhea_serialise,
149 ots::ots_vhea_should_serialise, ots::ots_vhea_free, false }, 147 ots::ots_vhea_should_serialise, ots::ots_vhea_free, false },
150 { TAG('v', 'm', 't', 'x'), ots::ots_vmtx_parse, ots::ots_vmtx_serialise, 148 { "vmtx", ots::ots_vmtx_parse, ots::ots_vmtx_serialise,
151 ots::ots_vmtx_should_serialise, ots::ots_vmtx_free, false }, 149 ots::ots_vmtx_should_serialise, ots::ots_vmtx_free, false },
152 // TODO(bashi): Support mort, base, and jstf tables. 150 // TODO(bashi): Support mort, base, and jstf tables.
153 { 0, NULL, NULL, NULL, NULL, false }, 151 { 0, NULL, NULL, NULL, NULL, false },
154 }; 152 };
155 153
156 bool IsValidVersionTag(uint32_t tag) { 154 bool IsValidVersionTag(uint32_t tag) {
157 return tag == TAG('\x00', '\x01', '\x00', '\x00') || 155 return tag == Tag("\x00\x01\x00\x00") ||
158 // OpenType fonts with CFF data have 'OTTO' tag. 156 // OpenType fonts with CFF data have 'OTTO' tag.
159 tag == TAG('O', 'T', 'T', 'O') || 157 tag == Tag("OTTO") ||
160 // Older Mac fonts might have 'true' or 'typ1' tag. 158 // Older Mac fonts might have 'true' or 'typ1' tag.
161 tag == TAG('t', 'r', 'u', 'e') || 159 tag == Tag("true") ||
162 tag == TAG('t', 'y', 'p', '1'); 160 tag == Tag("typ1");
163 } 161 }
164 162
165 bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output, 163 bool ProcessGeneric(ots::OpenTypeFile *header, ots::OTSStream *output,
166 const uint8_t *data, size_t length, 164 const uint8_t *data, size_t length,
167 const std::vector<OpenTypeTable>& tables, 165 const std::vector<OpenTypeTable>& tables,
168 ots::Buffer& file); 166 ots::Buffer& file);
169 167
170 bool ProcessTTF(ots::OpenTypeFile *header, 168 bool ProcessTTF(ots::OpenTypeFile *header,
171 ots::OTSStream *output, const uint8_t *data, size_t length) { 169 ots::OTSStream *output, const uint8_t *data, size_t length) {
172 ots::Buffer file(data, length); 170 ots::Buffer file(data, length);
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 // we disallow all files > 1GB in size for sanity. 248 // we disallow all files > 1GB in size for sanity.
251 if (length > 1024 * 1024 * 1024) { 249 if (length > 1024 * 1024 * 1024) {
252 return OTS_FAILURE(); 250 return OTS_FAILURE();
253 } 251 }
254 252
255 uint32_t woff_tag; 253 uint32_t woff_tag;
256 if (!file.ReadTag(&woff_tag)) { 254 if (!file.ReadTag(&woff_tag)) {
257 return OTS_FAILURE(); 255 return OTS_FAILURE();
258 } 256 }
259 257
260 if (woff_tag != TAG('w', 'O', 'F', 'F')) { 258 if (woff_tag != Tag("wOFF")) {
261 return OTS_FAILURE(); 259 return OTS_FAILURE();
262 } 260 }
263 261
264 if (!file.ReadTag(&header->version)) { 262 if (!file.ReadTag(&header->version)) {
265 return OTS_FAILURE(); 263 return OTS_FAILURE();
266 } 264 }
267 if (!IsValidVersionTag(header->version)) { 265 if (!IsValidVersionTag(header->version)) {
268 return OTS_FAILURE(); 266 return OTS_FAILURE();
269 } 267 }
270 268
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 return OTS_FAILURE(); 496 return OTS_FAILURE();
499 } 497 }
500 } 498 }
501 499
502 Arena arena; 500 Arena arena;
503 501
504 for (unsigned i = 0; ; ++i) { 502 for (unsigned i = 0; ; ++i) {
505 if (table_parsers[i].parse == NULL) break; 503 if (table_parsers[i].parse == NULL) break;
506 504
507 const std::map<uint32_t, OpenTypeTable>::const_iterator it 505 const std::map<uint32_t, OpenTypeTable>::const_iterator it
508 = table_map.find(table_parsers[i].tag); 506 = table_map.find(Tag(table_parsers[i].tag));
509 507
510 if (it == table_map.end()) { 508 if (it == table_map.end()) {
511 if (table_parsers[i].required) { 509 if (table_parsers[i].required) {
512 return OTS_FAILURE(); 510 return OTS_FAILURE();
513 } 511 }
514 continue; 512 continue;
515 } 513 }
516 514
517 const uint8_t* table_data; 515 const uint8_t* table_data;
518 size_t table_length; 516 size_t table_length;
(...skipping 14 matching lines...) Expand all
533 table_length = it->second.length; 531 table_length = it->second.length;
534 } 532 }
535 533
536 if (!table_parsers[i].parse(header, table_data, table_length)) { 534 if (!table_parsers[i].parse(header, table_data, table_length)) {
537 return OTS_FAILURE(); 535 return OTS_FAILURE();
538 } 536 }
539 } 537 }
540 538
541 if (header->cff) { 539 if (header->cff) {
542 // font with PostScript glyph 540 // font with PostScript glyph
543 if (header->version != TAG('O', 'T', 'T', 'O')) { 541 if (header->version != Tag("OTTO")) {
544 return OTS_FAILURE(); 542 return OTS_FAILURE();
545 } 543 }
546 if (header->glyf || header->loca) { 544 if (header->glyf || header->loca) {
547 // mixing outline formats is not recommended 545 // mixing outline formats is not recommended
548 return OTS_FAILURE(); 546 return OTS_FAILURE();
549 } 547 }
550 } else { 548 } else {
551 if (!header->glyf || !header->loca) { 549 if (!header->glyf || !header->loca) {
552 // No TrueType glyph found. 550 // No TrueType glyph found.
553 // Note: bitmap-only fonts are not supported. 551 // Note: bitmap-only fonts are not supported.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 for (unsigned i = 0; ; ++i) { 591 for (unsigned i = 0; ; ++i) {
594 if (table_parsers[i].parse == NULL) { 592 if (table_parsers[i].parse == NULL) {
595 break; 593 break;
596 } 594 }
597 595
598 if (!table_parsers[i].should_serialise(header)) { 596 if (!table_parsers[i].should_serialise(header)) {
599 continue; 597 continue;
600 } 598 }
601 599
602 OutputTable out; 600 OutputTable out;
603 out.tag = table_parsers[i].tag; 601 uint32_t tag = Tag(table_parsers[i].tag);
602 out.tag = tag;
604 out.offset = output->Tell(); 603 out.offset = output->Tell();
605 604
606 output->ResetChecksum(); 605 output->ResetChecksum();
607 if (table_parsers[i].tag == TAG('h', 'e', 'a', 'd')) { 606 if (tag == Tag("head")) {
608 head_table_offset = out.offset; 607 head_table_offset = out.offset;
609 } 608 }
610 if (!table_parsers[i].serialise(output, header)) { 609 if (!table_parsers[i].serialise(output, header)) {
611 return OTS_FAILURE(); 610 return OTS_FAILURE();
612 } 611 }
613 612
614 const size_t end_offset = output->Tell(); 613 const size_t end_offset = output->Tell();
615 if (end_offset <= out.offset) { 614 if (end_offset <= out.offset) {
616 // paranoid check. |end_offset| is supposed to be greater than the offset, 615 // paranoid check. |end_offset| is supposed to be greater than the offset,
617 // as long as the Tell() interface is implemented correctly. 616 // as long as the Tell() interface is implemented correctly.
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 va_start(va, format); 714 va_start(va, format);
716 std::vfprintf(stderr, format, va); 715 std::vfprintf(stderr, format, va);
717 va_end(va); 716 va_end(va);
718 std::fprintf(stderr, "\n"); 717 std::fprintf(stderr, "\n");
719 std::fflush(stderr); 718 std::fflush(stderr);
720 } 719 }
721 } 720 }
722 #endif 721 #endif
723 722
724 } // namespace ots 723 } // namespace ots
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698