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/opentype/otspec/maxp.htm
9 :
10 : namespace ots {
11 :
12 0 : bool ots_maxp_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
13 0 : Buffer table(data, length);
14 :
15 0 : OpenTypeMAXP *maxp = new OpenTypeMAXP;
16 0 : file->maxp = maxp;
17 :
18 0 : uint32_t version = 0;
19 0 : if (!table.ReadU32(&version)) {
20 0 : return OTS_FAILURE();
21 : }
22 :
23 0 : if (version >> 16 > 1) {
24 0 : return OTS_FAILURE();
25 : }
26 :
27 0 : if (!table.ReadU16(&maxp->num_glyphs)) {
28 0 : return OTS_FAILURE();
29 : }
30 :
31 0 : if (!maxp->num_glyphs) {
32 0 : return OTS_FAILURE();
33 : }
34 :
35 0 : if (version >> 16 == 1) {
36 0 : maxp->version_1 = true;
37 0 : if (!table.ReadU16(&maxp->max_points) ||
38 0 : !table.ReadU16(&maxp->max_contours) ||
39 0 : !table.ReadU16(&maxp->max_c_points) ||
40 0 : !table.ReadU16(&maxp->max_c_contours) ||
41 0 : !table.ReadU16(&maxp->max_zones) ||
42 0 : !table.ReadU16(&maxp->max_t_points) ||
43 0 : !table.ReadU16(&maxp->max_storage) ||
44 0 : !table.ReadU16(&maxp->max_fdefs) ||
45 0 : !table.ReadU16(&maxp->max_idefs) ||
46 0 : !table.ReadU16(&maxp->max_stack) ||
47 0 : !table.ReadU16(&maxp->max_size_glyf_instructions) ||
48 0 : !table.ReadU16(&maxp->max_c_components) ||
49 0 : !table.ReadU16(&maxp->max_c_depth)) {
50 0 : return OTS_FAILURE();
51 : }
52 :
53 0 : if (maxp->max_zones == 0) {
54 : // workaround for ipa*.ttf Japanese fonts.
55 : OTS_WARNING("bad max_zones: %u", maxp->max_zones);
56 0 : maxp->max_zones = 1;
57 0 : } else if (maxp->max_zones == 3) {
58 : // workaround for Ecolier-*.ttf fonts.
59 : OTS_WARNING("bad max_zones: %u", maxp->max_zones);
60 0 : maxp->max_zones = 2;
61 : }
62 :
63 0 : if ((maxp->max_zones != 1) && (maxp->max_zones != 2)) {
64 0 : return OTS_FAILURE();
65 : }
66 : } else {
67 0 : maxp->version_1 = false;
68 : }
69 :
70 0 : return true;
71 : }
72 :
73 0 : bool ots_maxp_should_serialise(OpenTypeFile *file) {
74 0 : return file->maxp != NULL;
75 : }
76 :
77 0 : bool ots_maxp_serialise(OTSStream *out, OpenTypeFile *file) {
78 0 : const OpenTypeMAXP *maxp = file->maxp;
79 :
80 0 : if (!out->WriteU32(maxp->version_1 ? 0x00010000 : 0x00005000) ||
81 0 : !out->WriteU16(maxp->num_glyphs)) {
82 0 : return OTS_FAILURE();
83 : }
84 :
85 0 : if (!maxp->version_1) return true;
86 :
87 0 : if (!out->WriteU16(maxp->max_points) ||
88 0 : !out->WriteU16(maxp->max_contours) ||
89 0 : !out->WriteU16(maxp->max_c_points) ||
90 0 : !out->WriteU16(maxp->max_c_contours)) {
91 0 : return OTS_FAILURE();
92 : }
93 :
94 : if (g_transcode_hints) {
95 0 : if (!out->WriteU16(maxp->max_zones) ||
96 0 : !out->WriteU16(maxp->max_t_points) ||
97 0 : !out->WriteU16(maxp->max_storage) ||
98 0 : !out->WriteU16(maxp->max_fdefs) ||
99 0 : !out->WriteU16(maxp->max_idefs) ||
100 0 : !out->WriteU16(maxp->max_stack) ||
101 0 : !out->WriteU16(maxp->max_size_glyf_instructions)) {
102 0 : return OTS_FAILURE();
103 : }
104 : } else {
105 : if (!out->WriteU16(1) || // max zones
106 : !out->WriteU16(0) || // max twilight points
107 : !out->WriteU16(0) || // max storage
108 : !out->WriteU16(0) || // max function defs
109 : !out->WriteU16(0) || // max instruction defs
110 : !out->WriteU16(0) || // max stack elements
111 : !out->WriteU16(0)) { // max instruction byte count
112 : return OTS_FAILURE();
113 : }
114 : }
115 :
116 0 : if (!out->WriteU16(maxp->max_c_components) ||
117 0 : !out->WriteU16(maxp->max_c_depth)) {
118 0 : return OTS_FAILURE();
119 : }
120 :
121 0 : return true;
122 : }
123 :
124 0 : void ots_maxp_free(OpenTypeFile *file) {
125 0 : delete file->maxp;
126 0 : }
127 :
128 : } // namespace ots
|