OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "loca.h" | 5 #include "loca.h" |
6 | 6 |
7 #include "head.h" | 7 #include "head.h" |
8 #include "maxp.h" | 8 #include "maxp.h" |
9 | 9 |
10 // loca - Index to Location | 10 // loca - Index to Location |
11 // http://www.microsoft.com/opentype/otspec/loca.htm | 11 // http://www.microsoft.com/typography/otspec/loca.htm |
| 12 |
| 13 #define TABLE_NAME "loca" |
12 | 14 |
13 namespace ots { | 15 namespace ots { |
14 | 16 |
15 bool ots_loca_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { | 17 bool ots_loca_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { |
16 Buffer table(data, length); | 18 Buffer table(data, length); |
17 | 19 |
18 // We can't do anything useful in validating this data except to ensure that | 20 // We can't do anything useful in validating this data except to ensure that |
19 // the values are monotonically increasing. | 21 // the values are monotonically increasing. |
20 | 22 |
21 OpenTypeLOCA *loca = new OpenTypeLOCA; | 23 OpenTypeLOCA *loca = new OpenTypeLOCA; |
22 file->loca = loca; | 24 file->loca = loca; |
23 | 25 |
24 if (!file->maxp || !file->head) { | 26 if (!file->maxp || !file->head) { |
25 return OTS_FAILURE(); | 27 return OTS_FAILURE_MSG("maxp or head tables missing from font, needed by loc
a"); |
26 } | 28 } |
27 | 29 |
28 const unsigned num_glyphs = file->maxp->num_glyphs; | 30 const unsigned num_glyphs = file->maxp->num_glyphs; |
29 unsigned last_offset = 0; | 31 unsigned last_offset = 0; |
30 loca->offsets.resize(num_glyphs + 1); | 32 loca->offsets.resize(num_glyphs + 1); |
31 // maxp->num_glyphs is uint16_t, thus the addition never overflows. | 33 // maxp->num_glyphs is uint16_t, thus the addition never overflows. |
32 | 34 |
33 if (file->head->index_to_loc_format == 0) { | 35 if (file->head->index_to_loc_format == 0) { |
34 // Note that the <= here (and below) is correct. There is one more offset | 36 // 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 | 37 // than the number of glyphs in order to give the length of the final |
36 // glyph. | 38 // glyph. |
37 for (unsigned i = 0; i <= num_glyphs; ++i) { | 39 for (unsigned i = 0; i <= num_glyphs; ++i) { |
38 uint16_t offset = 0; | 40 uint16_t offset = 0; |
39 if (!table.ReadU16(&offset)) { | 41 if (!table.ReadU16(&offset)) { |
40 return OTS_FAILURE(); | 42 return OTS_FAILURE_MSG("Failed to read offset for glyph %d", i); |
41 } | 43 } |
42 if (offset < last_offset) { | 44 if (offset < last_offset) { |
43 return OTS_FAILURE(); | 45 return OTS_FAILURE_MSG("Out of order offset %d < %d for glyph %d", offse
t, last_offset, i); |
44 } | 46 } |
45 last_offset = offset; | 47 last_offset = offset; |
46 loca->offsets[i] = offset * 2; | 48 loca->offsets[i] = offset * 2; |
47 } | 49 } |
48 } else { | 50 } else { |
49 for (unsigned i = 0; i <= num_glyphs; ++i) { | 51 for (unsigned i = 0; i <= num_glyphs; ++i) { |
50 uint32_t offset = 0; | 52 uint32_t offset = 0; |
51 if (!table.ReadU32(&offset)) { | 53 if (!table.ReadU32(&offset)) { |
52 return OTS_FAILURE(); | 54 return OTS_FAILURE_MSG("Failed to read offset for glyph %d", i); |
53 } | 55 } |
54 if (offset < last_offset) { | 56 if (offset < last_offset) { |
55 return OTS_FAILURE(); | 57 return OTS_FAILURE_MSG("Out of order offset %d < %d for glyph %d", offse
t, last_offset, i); |
56 } | 58 } |
57 last_offset = offset; | 59 last_offset = offset; |
58 loca->offsets[i] = offset; | 60 loca->offsets[i] = offset; |
59 } | 61 } |
60 } | 62 } |
61 | 63 |
62 return true; | 64 return true; |
63 } | 65 } |
64 | 66 |
65 bool ots_loca_should_serialise(OpenTypeFile *file) { | 67 bool ots_loca_should_serialise(OpenTypeFile *file) { |
66 return file->loca != NULL; | 68 return file->loca != NULL; |
67 } | 69 } |
68 | 70 |
69 bool ots_loca_serialise(OTSStream *out, OpenTypeFile *file) { | 71 bool ots_loca_serialise(OTSStream *out, OpenTypeFile *file) { |
70 const OpenTypeLOCA *loca = file->loca; | 72 const OpenTypeLOCA *loca = file->loca; |
71 const OpenTypeHEAD *head = file->head; | 73 const OpenTypeHEAD *head = file->head; |
72 | 74 |
73 if (!head) { | 75 if (!head) { |
74 return OTS_FAILURE(); | 76 return OTS_FAILURE_MSG("Missing head table in font needed by loca"); |
75 } | 77 } |
76 | 78 |
77 if (head->index_to_loc_format == 0) { | 79 if (head->index_to_loc_format == 0) { |
78 for (unsigned i = 0; i < loca->offsets.size(); ++i) { | 80 for (unsigned i = 0; i < loca->offsets.size(); ++i) { |
79 const uint16_t offset = static_cast<uint16_t>(loca->offsets[i] >> 1); | 81 const uint16_t offset = static_cast<uint16_t>(loca->offsets[i] >> 1); |
80 if ((offset != (loca->offsets[i] >> 1)) || | 82 if ((offset != (loca->offsets[i] >> 1)) || |
81 !out->WriteU16(offset)) { | 83 !out->WriteU16(offset)) { |
82 return OTS_FAILURE(); | 84 return OTS_FAILURE_MSG("Failed to write glyph offset for glyph %d", i); |
83 } | 85 } |
84 } | 86 } |
85 } else { | 87 } else { |
86 for (unsigned i = 0; i < loca->offsets.size(); ++i) { | 88 for (unsigned i = 0; i < loca->offsets.size(); ++i) { |
87 if (!out->WriteU32(loca->offsets[i])) { | 89 if (!out->WriteU32(loca->offsets[i])) { |
88 return OTS_FAILURE(); | 90 return OTS_FAILURE_MSG("Failed to write glyph offset for glyph %d", i); |
89 } | 91 } |
90 } | 92 } |
91 } | 93 } |
92 | 94 |
93 return true; | 95 return true; |
94 } | 96 } |
95 | 97 |
96 void ots_loca_free(OpenTypeFile *file) { | 98 void ots_loca_free(OpenTypeFile *file) { |
97 delete file->loca; | 99 delete file->loca; |
98 } | 100 } |
99 | 101 |
100 } // namespace ots | 102 } // namespace ots |
| 103 |
| 104 #undef TABLE_NAME |
OLD | NEW |