1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/ots/src/maxp.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,130 @@ 1.4 +// Copyright (c) 2009 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "maxp.h" 1.9 + 1.10 +// maxp - Maximum Profile 1.11 +// http://www.microsoft.com/typography/otspec/maxp.htm 1.12 + 1.13 +#define TABLE_NAME "maxp" 1.14 + 1.15 +namespace ots { 1.16 + 1.17 +bool ots_maxp_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { 1.18 + Buffer table(data, length); 1.19 + 1.20 + OpenTypeMAXP *maxp = new OpenTypeMAXP; 1.21 + file->maxp = maxp; 1.22 + 1.23 + uint32_t version = 0; 1.24 + if (!table.ReadU32(&version)) { 1.25 + return OTS_FAILURE_MSG("Failed to read version of maxp table"); 1.26 + } 1.27 + 1.28 + if (version >> 16 > 1) { 1.29 + return OTS_FAILURE_MSG("Bad maxp version %d", version); 1.30 + } 1.31 + 1.32 + if (!table.ReadU16(&maxp->num_glyphs)) { 1.33 + return OTS_FAILURE_MSG("Failed to read number of glyphs from maxp table"); 1.34 + } 1.35 + 1.36 + if (!maxp->num_glyphs) { 1.37 + return OTS_FAILURE_MSG("Bad number of glyphs 0 in maxp table"); 1.38 + } 1.39 + 1.40 + if (version >> 16 == 1) { 1.41 + maxp->version_1 = true; 1.42 + if (!table.ReadU16(&maxp->max_points) || 1.43 + !table.ReadU16(&maxp->max_contours) || 1.44 + !table.ReadU16(&maxp->max_c_points) || 1.45 + !table.ReadU16(&maxp->max_c_contours) || 1.46 + !table.ReadU16(&maxp->max_zones) || 1.47 + !table.ReadU16(&maxp->max_t_points) || 1.48 + !table.ReadU16(&maxp->max_storage) || 1.49 + !table.ReadU16(&maxp->max_fdefs) || 1.50 + !table.ReadU16(&maxp->max_idefs) || 1.51 + !table.ReadU16(&maxp->max_stack) || 1.52 + !table.ReadU16(&maxp->max_size_glyf_instructions) || 1.53 + !table.ReadU16(&maxp->max_c_components) || 1.54 + !table.ReadU16(&maxp->max_c_depth)) { 1.55 + return OTS_FAILURE_MSG("Failed to read maxp table"); 1.56 + } 1.57 + 1.58 + if (maxp->max_zones == 0) { 1.59 + // workaround for ipa*.ttf Japanese fonts. 1.60 + OTS_WARNING("bad max_zones: %u", maxp->max_zones); 1.61 + maxp->max_zones = 1; 1.62 + } else if (maxp->max_zones == 3) { 1.63 + // workaround for Ecolier-*.ttf fonts. 1.64 + OTS_WARNING("bad max_zones: %u", maxp->max_zones); 1.65 + maxp->max_zones = 2; 1.66 + } 1.67 + 1.68 + if ((maxp->max_zones != 1) && (maxp->max_zones != 2)) { 1.69 + return OTS_FAILURE_MSG("Bad max zones %d in maxp", maxp->max_zones); 1.70 + } 1.71 + } else { 1.72 + maxp->version_1 = false; 1.73 + } 1.74 + 1.75 + return true; 1.76 +} 1.77 + 1.78 +bool ots_maxp_should_serialise(OpenTypeFile *file) { 1.79 + return file->maxp != NULL; 1.80 +} 1.81 + 1.82 +bool ots_maxp_serialise(OTSStream *out, OpenTypeFile *file) { 1.83 + const OpenTypeMAXP *maxp = file->maxp; 1.84 + 1.85 + if (!out->WriteU32(maxp->version_1 ? 0x00010000 : 0x00005000) || 1.86 + !out->WriteU16(maxp->num_glyphs)) { 1.87 + return OTS_FAILURE_MSG("Failed to write maxp version or number of glyphs"); 1.88 + } 1.89 + 1.90 + if (!maxp->version_1) return true; 1.91 + 1.92 + if (!out->WriteU16(maxp->max_points) || 1.93 + !out->WriteU16(maxp->max_contours) || 1.94 + !out->WriteU16(maxp->max_c_points) || 1.95 + !out->WriteU16(maxp->max_c_contours)) { 1.96 + return OTS_FAILURE_MSG("Failed to write maxp"); 1.97 + } 1.98 + 1.99 + if (g_transcode_hints) { 1.100 + if (!out->WriteU16(maxp->max_zones) || 1.101 + !out->WriteU16(maxp->max_t_points) || 1.102 + !out->WriteU16(maxp->max_storage) || 1.103 + !out->WriteU16(maxp->max_fdefs) || 1.104 + !out->WriteU16(maxp->max_idefs) || 1.105 + !out->WriteU16(maxp->max_stack) || 1.106 + !out->WriteU16(maxp->max_size_glyf_instructions)) { 1.107 + return OTS_FAILURE_MSG("Failed to write more maxp"); 1.108 + } 1.109 + } else { 1.110 + if (!out->WriteU16(1) || // max zones 1.111 + !out->WriteU16(0) || // max twilight points 1.112 + !out->WriteU16(0) || // max storage 1.113 + !out->WriteU16(0) || // max function defs 1.114 + !out->WriteU16(0) || // max instruction defs 1.115 + !out->WriteU16(0) || // max stack elements 1.116 + !out->WriteU16(0)) { // max instruction byte count 1.117 + return OTS_FAILURE_MSG("Failed to write more maxp"); 1.118 + } 1.119 + } 1.120 + 1.121 + if (!out->WriteU16(maxp->max_c_components) || 1.122 + !out->WriteU16(maxp->max_c_depth)) { 1.123 + return OTS_FAILURE_MSG("Failed to write yet more maxp"); 1.124 + } 1.125 + 1.126 + return true; 1.127 +} 1.128 + 1.129 +void ots_maxp_free(OpenTypeFile *file) { 1.130 + delete file->maxp; 1.131 +} 1.132 + 1.133 +} // namespace ots