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