LCOV - app.info - gfx/ots/src/post.cc

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-04-21 | 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