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 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 73 bool ots_maxp_should_serialise(OpenTypeFile *file) { 74 return file->maxp != NULL; 75 } 76 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 124 void ots_maxp_free(OpenTypeFile *file) { 125 delete file->maxp; 126 } 127 128 } // namespace ots 129