|
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 (g_transcode_hints) { |
|
97 if (!out->WriteU16(maxp->max_zones) || |
|
98 !out->WriteU16(maxp->max_t_points) || |
|
99 !out->WriteU16(maxp->max_storage) || |
|
100 !out->WriteU16(maxp->max_fdefs) || |
|
101 !out->WriteU16(maxp->max_idefs) || |
|
102 !out->WriteU16(maxp->max_stack) || |
|
103 !out->WriteU16(maxp->max_size_glyf_instructions)) { |
|
104 return OTS_FAILURE_MSG("Failed to write more maxp"); |
|
105 } |
|
106 } else { |
|
107 if (!out->WriteU16(1) || // max zones |
|
108 !out->WriteU16(0) || // max twilight points |
|
109 !out->WriteU16(0) || // max storage |
|
110 !out->WriteU16(0) || // max function defs |
|
111 !out->WriteU16(0) || // max instruction defs |
|
112 !out->WriteU16(0) || // max stack elements |
|
113 !out->WriteU16(0)) { // max instruction byte count |
|
114 return OTS_FAILURE_MSG("Failed to write more maxp"); |
|
115 } |
|
116 } |
|
117 |
|
118 if (!out->WriteU16(maxp->max_c_components) || |
|
119 !out->WriteU16(maxp->max_c_depth)) { |
|
120 return OTS_FAILURE_MSG("Failed to write yet more maxp"); |
|
121 } |
|
122 |
|
123 return true; |
|
124 } |
|
125 |
|
126 void ots_maxp_free(OpenTypeFile *file) { |
|
127 delete file->maxp; |
|
128 } |
|
129 |
|
130 } // namespace ots |