• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "loca.h"
6 
7 #include "head.h"
8 #include "maxp.h"
9 
10 // loca - Index to Location
11 // http://www.microsoft.com/opentype/otspec/loca.htm
12 
13 namespace ots {
14 
ots_loca_parse(OpenTypeFile * file,const uint8_t * data,size_t length)15 bool ots_loca_parse(OpenTypeFile *file, const uint8_t *data, size_t length) {
16   Buffer table(data, length);
17 
18   // We can't do anything useful in validating this data except to ensure that
19   // the values are monotonically increasing.
20 
21   OpenTypeLOCA *loca = new OpenTypeLOCA;
22   file->loca = loca;
23 
24   if (!file->maxp || !file->head) {
25     return OTS_FAILURE();
26   }
27 
28   const unsigned num_glyphs = file->maxp->num_glyphs;
29   unsigned last_offset = 0;
30   loca->offsets.resize(num_glyphs + 1);
31   // maxp->num_glyphs is uint16_t, thus the addition never overflows.
32 
33   if (file->head->index_to_loc_format == 0) {
34     // Note that the <= here (and below) is correct. There is one more offset
35     // than the number of glyphs in order to give the length of the final
36     // glyph.
37     for (unsigned i = 0; i <= num_glyphs; ++i) {
38       uint16_t offset = 0;
39       if (!table.ReadU16(&offset)) {
40         return OTS_FAILURE();
41       }
42       if (offset < last_offset) {
43         return OTS_FAILURE();
44       }
45       last_offset = offset;
46       loca->offsets[i] = offset * 2;
47     }
48   } else {
49     for (unsigned i = 0; i <= num_glyphs; ++i) {
50       uint32_t offset = 0;
51       if (!table.ReadU32(&offset)) {
52         return OTS_FAILURE();
53       }
54       if (offset < last_offset) {
55         return OTS_FAILURE();
56       }
57       last_offset = offset;
58       loca->offsets[i] = offset;
59     }
60   }
61 
62   return true;
63 }
64 
ots_loca_should_serialise(OpenTypeFile * file)65 bool ots_loca_should_serialise(OpenTypeFile *file) {
66   return file->loca != NULL;
67 }
68 
ots_loca_serialise(OTSStream * out,OpenTypeFile * file)69 bool ots_loca_serialise(OTSStream *out, OpenTypeFile *file) {
70   const OpenTypeLOCA *loca = file->loca;
71   const OpenTypeHEAD *head = file->head;
72 
73   if (!head) {
74     return OTS_FAILURE();
75   }
76 
77   if (head->index_to_loc_format == 0) {
78     for (unsigned i = 0; i < loca->offsets.size(); ++i) {
79       if (!out->WriteU16(loca->offsets[i] >> 1)) {
80         return OTS_FAILURE();
81       }
82     }
83   } else {
84     for (unsigned i = 0; i < loca->offsets.size(); ++i) {
85       if (!out->WriteU32(loca->offsets[i])) {
86         return OTS_FAILURE();
87       }
88     }
89   }
90 
91   return true;
92 }
93 
ots_loca_free(OpenTypeFile * file)94 void ots_loca_free(OpenTypeFile *file) {
95   delete file->loca;
96 }
97 
98 }  // namespace ots
99