OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "maxp.h" | |
6 | |
7 // maxp - Maximum Profile | |
8 // http://www.microsoft.com/typography/otspec/maxp.htm | |
9 | |
10 #define TABLE_NAME "maxp" | |
11 | |
12 namespace ots { | |
13 | |
14 bool ots_maxp_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { | |
15 Buffer table(data, length); | |
16 | |
17 OpenTypeMAXP *maxp = new OpenTypeMAXP; | |
18 file->maxp = maxp; | |
19 | |
20 uint32_t version = 0; | |
21 if (!table.ReadU32(&version)) { | |
22 return OTS_FAILURE_MSG("Failed to read version of maxp table"); | |
23 } | |
24 | |
25 if (version >> 16 > 1) { | |
26 return OTS_FAILURE_MSG("Bad maxp version %d", version); | |
27 } | |
28 | |
29 if (!table.ReadU16(&maxp->num_glyphs)) { | |
30 return OTS_FAILURE_MSG("Failed to read number of glyphs from maxp table"); | |
31 } | |
32 | |
33 if (!maxp->num_glyphs) { | |
34 return OTS_FAILURE_MSG("Bad number of glyphs 0 in maxp table"); | |
35 } | |
36 | |
37 if (version >> 16 == 1) { | |
38 maxp->version_1 = true; | |
39 if (!table.ReadU16(&maxp->max_points) || | |
40 !table.ReadU16(&maxp->max_contours) || | |
41 !table.ReadU16(&maxp->max_c_points) || | |
42 !table.ReadU16(&maxp->max_c_contours) || | |
43 !table.ReadU16(&maxp->max_zones) || | |
44 !table.ReadU16(&maxp->max_t_points) || | |
45 !table.ReadU16(&maxp->max_storage) || | |
46 !table.ReadU16(&maxp->max_fdefs) || | |
47 !table.ReadU16(&maxp->max_idefs) || | |
48 !table.ReadU16(&maxp->max_stack) || | |
49 !table.ReadU16(&maxp->max_size_glyf_instructions) || | |
50 !table.ReadU16(&maxp->max_c_components) || | |
51 !table.ReadU16(&maxp->max_c_depth)) { | |
52 return OTS_FAILURE_MSG("Failed to read maxp table"); | |
53 } | |
54 | |
55 if (maxp->max_zones == 0) { | |
56 // workaround for ipa*.ttf Japanese fonts. | |
57 OTS_WARNING("bad max_zones: %u", maxp->max_zones); | |
58 maxp->max_zones = 1; | |
59 } else if (maxp->max_zones == 3) { | |
60 // workaround for Ecolier-*.ttf fonts. | |
61 OTS_WARNING("bad max_zones: %u", maxp->max_zones); | |
62 maxp->max_zones = 2; | |
63 } | |
64 | |
65 if ((maxp->max_zones != 1) && (maxp->max_zones != 2)) { | |
66 return OTS_FAILURE_MSG("Bad max zones %d in maxp", maxp->max_zones); | |
67 } | |
68 } else { | |
69 maxp->version_1 = false; | |
70 } | |
71 | |
72 return true; | |
73 } | |
74 | |
75 bool ots_maxp_should_serialise(OpenTypeFile *file) { | |
76 return file->maxp != NULL; | |
77 } | |
78 | |
79 bool ots_maxp_serialise(OTSStream *out, OpenTypeFile *file) { | |
80 const OpenTypeMAXP *maxp = file->maxp; | |
81 | |
82 if (!out->WriteU32(maxp->version_1 ? 0x00010000 : 0x00005000) || | |
83 !out->WriteU16(maxp->num_glyphs)) { | |
84 return OTS_FAILURE_MSG("Failed to write maxp version or number of glyphs"); | |
85 } | |
86 | |
87 if (!maxp->version_1) return true; | |
88 | |
89 if (!out->WriteU16(maxp->max_points) || | |
90 !out->WriteU16(maxp->max_contours) || | |
91 !out->WriteU16(maxp->max_c_points) || | |
92 !out->WriteU16(maxp->max_c_contours)) { | |
93 return OTS_FAILURE_MSG("Failed to write maxp"); | |
94 } | |
95 | |
96 if (!out->WriteU16(maxp->max_zones) || | |
97 !out->WriteU16(maxp->max_t_points) || | |
98 !out->WriteU16(maxp->max_storage) || | |
99 !out->WriteU16(maxp->max_fdefs) || | |
100 !out->WriteU16(maxp->max_idefs) || | |
101 !out->WriteU16(maxp->max_stack) || | |
102 !out->WriteU16(maxp->max_size_glyf_instructions)) { | |
103 return OTS_FAILURE_MSG("Failed to write more maxp"); | |
104 } | |
105 | |
106 if (!out->WriteU16(maxp->max_c_components) || | |
107 !out->WriteU16(maxp->max_c_depth)) { | |
108 return OTS_FAILURE_MSG("Failed to write yet more maxp"); | |
109 } | |
110 | |
111 return true; | |
112 } | |
113 | |
114 void ots_maxp_free(OpenTypeFile *file) { | |
115 delete file->maxp; | |
116 } | |
117 | |
118 } // namespace ots | |
119 | |
120 #undef TABLE_NAME | |
OLD | NEW |