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