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

       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 "post.h"
       6                 : 
       7                 : #include "maxp.h"
       8                 : 
       9                 : // post - PostScript
      10                 : // http://www.microsoft.com/opentype/otspec/post.htm
      11                 : 
      12                 : namespace ots {
      13                 : 
      14               0 : bool ots_post_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
      15               0 :   Buffer table(data, length);
      16                 : 
      17               0 :   OpenTypePOST *post = new OpenTypePOST;
      18               0 :   file->post = post;
      19                 : 
      20               0 :   if (!table.ReadU32(&post->version) ||
      21               0 :       !table.ReadU32(&post->italic_angle) ||
      22               0 :       !table.ReadS16(&post->underline) ||
      23               0 :       !table.ReadS16(&post->underline_thickness) ||
      24               0 :       !table.ReadU32(&post->is_fixed_pitch)) {
      25               0 :     return OTS_FAILURE();
      26                 :   }
      27                 : 
      28               0 :   if (post->underline_thickness < 0) {
      29               0 :     post->underline_thickness = 1;
      30                 :   }
      31                 : 
      32               0 :   if (post->version == 0x00010000) {
      33               0 :     return true;
      34               0 :   } else if (post->version == 0x00030000) {
      35               0 :     return true;
      36               0 :   } else if (post->version != 0x00020000) {
      37                 :     // 0x00025000 is deprecated. We don't accept it.
      38               0 :     return OTS_FAILURE();
      39                 :   }
      40                 : 
      41                 :   // We have a version 2 table with a list of Pascal strings at the end
      42                 : 
      43                 :   // We don't care about the memory usage fields. We'll set all these to zero
      44                 :   // when serialising
      45               0 :   if (!table.Skip(16)) {
      46               0 :     return OTS_FAILURE();
      47                 :   }
      48                 : 
      49               0 :   uint16_t num_glyphs = 0;
      50               0 :   if (!table.ReadU16(&num_glyphs)) {
      51               0 :     return OTS_FAILURE();
      52                 :   }
      53                 : 
      54               0 :   if (!file->maxp) {
      55               0 :     return OTS_FAILURE();
      56                 :   }
      57                 : 
      58               0 :   if (num_glyphs == 0) {
      59               0 :     if (file->maxp->num_glyphs > 258) {
      60               0 :       return OTS_FAILURE();
      61                 :     }
      62                 :     OTS_WARNING("table version is 1, but no glyf names are found");
      63                 :     // workaround for fonts in http://www.fontsquirrel.com/fontface
      64                 :     // (e.g., yataghan.ttf).
      65               0 :     post->version = 0x00010000;
      66               0 :     return true;
      67                 :   }
      68                 : 
      69               0 :   if (num_glyphs != file->maxp->num_glyphs) {
      70                 :     // Note: Fixedsys500c.ttf seems to have inconsistent num_glyphs values.
      71               0 :     return OTS_FAILURE();
      72                 :   }
      73                 : 
      74               0 :   post->glyph_name_index.resize(num_glyphs);
      75               0 :   for (unsigned i = 0; i < num_glyphs; ++i) {
      76               0 :     if (!table.ReadU16(&post->glyph_name_index[i])) {
      77               0 :       return OTS_FAILURE();
      78                 :     }
      79               0 :     if (post->glyph_name_index[i] >= 32768) {
      80                 :       // Note: droid_arialuni.ttf fails this test.
      81               0 :       return OTS_FAILURE();  // reserved area.
      82                 :     }
      83                 :   }
      84                 : 
      85                 :   // Now we have an array of Pascal strings. We have to check that they are all
      86                 :   // valid and read them in.
      87               0 :   const size_t strings_offset = table.offset();
      88               0 :   const uint8_t *strings = data + strings_offset;
      89               0 :   const uint8_t *strings_end = data + length;
      90                 : 
      91               0 :   for (;;) {
      92               0 :     if (strings == strings_end) break;
      93               0 :     const unsigned string_length = *strings;
      94               0 :     if (strings + 1 + string_length > strings_end) {
      95               0 :       return OTS_FAILURE();
      96                 :     }
      97               0 :     if (std::memchr(strings + 1, '\0', string_length)) {
      98               0 :       return OTS_FAILURE();
      99                 :     }
     100                 :     post->names.push_back(
     101               0 :         std::string(reinterpret_cast<const char*>(strings + 1), string_length));
     102               0 :     strings += 1 + string_length;
     103                 :   }
     104               0 :   const unsigned num_strings = post->names.size();
     105                 : 
     106                 :   // check that all the references are within bounds
     107               0 :   for (unsigned i = 0; i < num_glyphs; ++i) {
     108               0 :     unsigned offset = post->glyph_name_index[i];
     109               0 :     if (offset < 258) {
     110               0 :       continue;
     111                 :     }
     112                 : 
     113               0 :     offset -= 258;
     114               0 :     if (offset >= num_strings) {
     115               0 :       return OTS_FAILURE();
     116                 :     }
     117                 :   }
     118                 : 
     119               0 :   return true;
     120                 : }
     121                 : 
     122               0 : bool ots_post_should_serialise(OpenTypeFile *file) {
     123               0 :   return file->post != NULL;
     124                 : }
     125                 : 
     126               0 : bool ots_post_serialise(OTSStream *out, OpenTypeFile *file) {
     127               0 :   const OpenTypePOST *post = file->post;
     128                 : 
     129                 :   // OpenType with CFF glyphs must have v3 post table.
     130               0 :   if (file->post && file->cff && file->post->version != 0x00030000) {
     131               0 :     return OTS_FAILURE();
     132                 :   }
     133                 : 
     134               0 :   if (!out->WriteU32(post->version) ||
     135               0 :       !out->WriteU32(post->italic_angle) ||
     136               0 :       !out->WriteS16(post->underline) ||
     137               0 :       !out->WriteS16(post->underline_thickness) ||
     138               0 :       !out->WriteU32(post->is_fixed_pitch) ||
     139               0 :       !out->WriteU32(0) ||
     140               0 :       !out->WriteU32(0) ||
     141               0 :       !out->WriteU32(0) ||
     142               0 :       !out->WriteU32(0)) {
     143               0 :     return OTS_FAILURE();
     144                 :   }
     145                 : 
     146               0 :   if (post->version != 0x00020000) {
     147               0 :     return true;  // v1.0 and v3.0 does not have glyph names.
     148                 :   }
     149                 : 
     150               0 :   if (!out->WriteU16(post->glyph_name_index.size())) {
     151               0 :     return OTS_FAILURE();
     152                 :   }
     153                 : 
     154               0 :   for (unsigned i = 0; i < post->glyph_name_index.size(); ++i) {
     155               0 :     if (!out->WriteU16(post->glyph_name_index[i])) {
     156               0 :       return OTS_FAILURE();
     157                 :     }
     158                 :   }
     159                 : 
     160                 :   // Now we just have to write out the strings in the correct order
     161               0 :   for (unsigned i = 0; i < post->names.size(); ++i) {
     162               0 :     const std::string& s = post->names[i];
     163               0 :     const uint8_t string_length = s.size();
     164               0 :     if (!out->Write(&string_length, 1)) {
     165               0 :       return OTS_FAILURE();
     166                 :     }
     167                 :     // Some ttf fonts (e.g., frank.ttf on Windows Vista) have zero-length name.
     168                 :     // We allow them.
     169               0 :     if (string_length > 0 && !out->Write(s.data(), string_length)) {
     170               0 :       return OTS_FAILURE();
     171                 :     }
     172                 :   }
     173                 : 
     174               0 :   return true;
     175                 : }
     176                 : 
     177               0 : void ots_post_free(OpenTypeFile *file) {
     178               0 :   delete file->post;
     179               0 : }
     180                 : 
     181                 : }  // namespace ots

Generated by: LCOV version 1.7