Home | History | Annotate | Download | only in src
      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