LCOV - code coverage report
Current view: directory - gfx/ots/src - metrics.cc (source / functions) Found Hit Coverage
Test: app.info Lines: 85 0 0.0 %
Date: 2012-06-02 Functions: 4 0 0.0 %

       1                 : // Copyright (c) 2011 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 "metrics.h"
       6                 : 
       7                 : #include "head.h"
       8                 : #include "maxp.h"
       9                 : 
      10                 : // OpenType horizontal and vertical common header format
      11                 : // http://www.microsoft.com/opentype/otspec/hhea.htm
      12                 : // http://www.microsoft.com/opentype/otspec/vhea.htm
      13                 : 
      14                 : namespace ots {
      15                 : 
      16               0 : bool ParseMetricsHeader(OpenTypeFile *file, Buffer *table,
      17                 :                         OpenTypeMetricsHeader *header) {
      18               0 :   if (!table->ReadS16(&header->ascent) ||
      19               0 :       !table->ReadS16(&header->descent) ||
      20               0 :       !table->ReadS16(&header->linegap) ||
      21               0 :       !table->ReadU16(&header->adv_width_max) ||
      22               0 :       !table->ReadS16(&header->min_sb1) ||
      23               0 :       !table->ReadS16(&header->min_sb2) ||
      24               0 :       !table->ReadS16(&header->max_extent) ||
      25               0 :       !table->ReadS16(&header->caret_slope_rise) ||
      26               0 :       !table->ReadS16(&header->caret_slope_run) ||
      27               0 :       !table->ReadS16(&header->caret_offset)) {
      28               0 :     return OTS_FAILURE();
      29                 :   }
      30                 : 
      31               0 :   if (header->ascent < 0) {
      32                 :     OTS_WARNING("bad ascent: %d", header->ascent);
      33               0 :     header->ascent = 0;
      34                 :   }
      35               0 :   if (header->linegap < 0) {
      36                 :     OTS_WARNING("bad linegap: %d", header->linegap);
      37               0 :     header->linegap = 0;
      38                 :   }
      39                 : 
      40               0 :   if (!file->head) {
      41               0 :     return OTS_FAILURE();
      42                 :   }
      43                 : 
      44                 :   // if the font is non-slanted, caret_offset should be zero.
      45               0 :   if (!(file->head->mac_style & 2) &&
      46                 :       (header->caret_offset != 0)) {
      47                 :     OTS_WARNING("bad caret offset: %d", header->caret_offset);
      48               0 :     header->caret_offset = 0;
      49                 :   }
      50                 : 
      51                 :   // skip the reserved bytes
      52               0 :   if (!table->Skip(8)) {
      53               0 :     return OTS_FAILURE();
      54                 :   }
      55                 : 
      56                 :   int16_t data_format;
      57               0 :   if (!table->ReadS16(&data_format)) {
      58               0 :     return OTS_FAILURE();
      59                 :   }
      60               0 :   if (data_format) {
      61               0 :     return OTS_FAILURE();
      62                 :   }
      63                 : 
      64               0 :   if (!table->ReadU16(&header->num_metrics)) {
      65               0 :     return OTS_FAILURE();
      66                 :   }
      67                 : 
      68               0 :   if (!file->maxp) {
      69               0 :     return OTS_FAILURE();
      70                 :   }
      71                 : 
      72               0 :   if (header->num_metrics > file->maxp->num_glyphs) {
      73               0 :     return OTS_FAILURE();
      74                 :   }
      75                 : 
      76               0 :   return true;
      77                 : }
      78                 : 
      79               0 : bool SerialiseMetricsHeader(OTSStream *out,
      80                 :                             const OpenTypeMetricsHeader *header) {
      81               0 :   if (!out->WriteU32(header->version) ||
      82               0 :       !out->WriteS16(header->ascent) ||
      83               0 :       !out->WriteS16(header->descent) ||
      84               0 :       !out->WriteS16(header->linegap) ||
      85               0 :       !out->WriteU16(header->adv_width_max) ||
      86               0 :       !out->WriteS16(header->min_sb1) ||
      87               0 :       !out->WriteS16(header->min_sb2) ||
      88               0 :       !out->WriteS16(header->max_extent) ||
      89               0 :       !out->WriteS16(header->caret_slope_rise) ||
      90               0 :       !out->WriteS16(header->caret_slope_run) ||
      91               0 :       !out->WriteS16(header->caret_offset) ||
      92               0 :       !out->WriteR64(0) ||  // reserved
      93               0 :       !out->WriteS16(0) ||  // metric data format
      94               0 :       !out->WriteU16(header->num_metrics)) {
      95               0 :     return OTS_FAILURE();
      96                 :   }
      97                 : 
      98               0 :   return true;
      99                 : }
     100                 : 
     101               0 : bool ParseMetricsTable(Buffer *table,
     102                 :                        const uint16_t num_glyphs,
     103                 :                        const OpenTypeMetricsHeader *header,
     104                 :                        OpenTypeMetricsTable *metrics) {
     105                 :   // |num_metrics| is a uint16_t, so it's bounded < 65536. This limits that
     106                 :   // amount of memory that we'll allocate for this to a sane amount.
     107               0 :   const unsigned num_metrics = header->num_metrics;
     108                 : 
     109               0 :   if (num_metrics > num_glyphs) {
     110               0 :     return OTS_FAILURE();
     111                 :   }
     112               0 :   if (!num_metrics) {
     113               0 :     return OTS_FAILURE();
     114                 :   }
     115               0 :   const unsigned num_sbs = num_glyphs - num_metrics;
     116                 : 
     117               0 :   metrics->entries.reserve(num_metrics);
     118               0 :   for (unsigned i = 0; i < num_metrics; ++i) {
     119               0 :     uint16_t adv = 0;
     120               0 :     int16_t sb = 0;
     121               0 :     if (!table->ReadU16(&adv) || !table->ReadS16(&sb)) {
     122               0 :       return OTS_FAILURE();
     123                 :     }
     124                 : 
     125                 :     // Since so many fonts don't have proper value on |adv| and |sb|,
     126                 :     // we should not call ots_failure() here. For example, about 20% of fonts
     127                 :     // in http://www.princexml.com/fonts/ (200+ fonts) fails these tests.
     128               0 :     if (adv > header->adv_width_max) {
     129                 :       OTS_WARNING("bad adv: %u > %u", adv, header->adv_width_max);
     130               0 :       adv = header->adv_width_max;
     131                 :     }
     132                 : 
     133               0 :     if (sb < header->min_sb1) {
     134                 :       OTS_WARNING("bad sb: %d < %d", sb, header->min_sb1);
     135               0 :       sb = header->min_sb1;
     136                 :     }
     137                 : 
     138               0 :     metrics->entries.push_back(std::make_pair(adv, sb));
     139                 :   }
     140                 : 
     141               0 :   metrics->sbs.reserve(num_sbs);
     142               0 :   for (unsigned i = 0; i < num_sbs; ++i) {
     143                 :     int16_t sb;
     144               0 :     if (!table->ReadS16(&sb)) {
     145                 :       // Some Japanese fonts (e.g., mona.ttf) fail this test.
     146               0 :       return OTS_FAILURE();
     147                 :     }
     148                 : 
     149               0 :     if (sb < header->min_sb1) {
     150                 :       // The same as above. Three fonts in http://www.fontsquirrel.com/fontface
     151                 :       // (e.g., Notice2Std.otf) have weird lsb values.
     152                 :       OTS_WARNING("bad lsb: %d < %d", sb, header->min_sb1);
     153               0 :       sb = header->min_sb1;
     154                 :     }
     155                 : 
     156               0 :     metrics->sbs.push_back(sb);
     157                 :   }
     158                 : 
     159               0 :   return true;
     160                 : }
     161                 : 
     162               0 : bool SerialiseMetricsTable(OTSStream *out,
     163                 :                            const OpenTypeMetricsTable *metrics) {
     164               0 :   for (unsigned i = 0; i < metrics->entries.size(); ++i) {
     165               0 :     if (!out->WriteU16(metrics->entries[i].first) ||
     166               0 :         !out->WriteS16(metrics->entries[i].second)) {
     167               0 :       return OTS_FAILURE();
     168                 :     }
     169                 :   }
     170                 : 
     171               0 :   for (unsigned i = 0; i < metrics->sbs.size(); ++i) {
     172               0 :     if (!out->WriteS16(metrics->sbs[i])) {
     173               0 :       return OTS_FAILURE();
     174                 :     }
     175                 :   }
     176                 : 
     177               0 :   return true;
     178                 : }
     179                 : 
     180                 : }  // namespace ots
     181                 : 

Generated by: LCOV version 1.7