OLD | NEW |
| (Empty) |
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 "vorg.h" | |
6 | |
7 #include <vector> | |
8 | |
9 // VORG - Vertical Origin Table | |
10 // http://www.microsoft.com/typography/otspec/vorg.htm | |
11 | |
12 #define TABLE_NAME "VORG" | |
13 | |
14 #define DROP_THIS_TABLE(...) \ | |
15 do { \ | |
16 OTS_FAILURE_MSG_(file, TABLE_NAME ": " __VA_ARGS__); \ | |
17 OTS_FAILURE_MSG("Table discarded"); \ | |
18 delete file->vorg; \ | |
19 file->vorg = 0; \ | |
20 } while (0) | |
21 | |
22 namespace ots { | |
23 | |
24 bool ots_vorg_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { | |
25 Buffer table(data, length); | |
26 file->vorg = new OpenTypeVORG; | |
27 OpenTypeVORG * const vorg = file->vorg; | |
28 | |
29 uint16_t num_recs; | |
30 if (!table.ReadU16(&vorg->major_version) || | |
31 !table.ReadU16(&vorg->minor_version) || | |
32 !table.ReadS16(&vorg->default_vert_origin_y) || | |
33 !table.ReadU16(&num_recs)) { | |
34 return OTS_FAILURE_MSG("Failed to read header"); | |
35 } | |
36 if (vorg->major_version != 1) { | |
37 DROP_THIS_TABLE("bad major version: %u", vorg->major_version); | |
38 return true; | |
39 } | |
40 if (vorg->minor_version != 0) { | |
41 DROP_THIS_TABLE("bad minor version: %u", vorg->minor_version); | |
42 return true; | |
43 } | |
44 | |
45 // num_recs might be zero (e.g., DFHSMinchoPro5-W3-Demo.otf). | |
46 if (!num_recs) { | |
47 return true; | |
48 } | |
49 | |
50 uint16_t last_glyph_index = 0; | |
51 vorg->metrics.reserve(num_recs); | |
52 for (unsigned i = 0; i < num_recs; ++i) { | |
53 OpenTypeVORGMetrics rec; | |
54 | |
55 if (!table.ReadU16(&rec.glyph_index) || | |
56 !table.ReadS16(&rec.vert_origin_y)) { | |
57 return OTS_FAILURE_MSG("Failed to read record %d", i); | |
58 } | |
59 if ((i != 0) && (rec.glyph_index <= last_glyph_index)) { | |
60 DROP_THIS_TABLE("the table is not sorted"); | |
61 return true; | |
62 } | |
63 last_glyph_index = rec.glyph_index; | |
64 | |
65 vorg->metrics.push_back(rec); | |
66 } | |
67 | |
68 return true; | |
69 } | |
70 | |
71 bool ots_vorg_should_serialise(OpenTypeFile *file) { | |
72 if (!file->cff) return false; // this table is not for fonts with TT glyphs. | |
73 return file->vorg != NULL; | |
74 } | |
75 | |
76 bool ots_vorg_serialise(OTSStream *out, OpenTypeFile *file) { | |
77 OpenTypeVORG * const vorg = file->vorg; | |
78 | |
79 const uint16_t num_metrics = static_cast<uint16_t>(vorg->metrics.size()); | |
80 if (num_metrics != vorg->metrics.size() || | |
81 !out->WriteU16(vorg->major_version) || | |
82 !out->WriteU16(vorg->minor_version) || | |
83 !out->WriteS16(vorg->default_vert_origin_y) || | |
84 !out->WriteU16(num_metrics)) { | |
85 return OTS_FAILURE_MSG("Failed to write table header"); | |
86 } | |
87 | |
88 for (uint16_t i = 0; i < num_metrics; ++i) { | |
89 const OpenTypeVORGMetrics& rec = vorg->metrics[i]; | |
90 if (!out->WriteU16(rec.glyph_index) || | |
91 !out->WriteS16(rec.vert_origin_y)) { | |
92 return OTS_FAILURE_MSG("Failed to write record %d", i); | |
93 } | |
94 } | |
95 | |
96 return true; | |
97 } | |
98 | |
99 void ots_vorg_free(OpenTypeFile *file) { | |
100 delete file->vorg; | |
101 } | |
102 | |
103 } // namespace ots | |
104 | |
105 #undef TABLE_NAME | |
106 #undef DROP_THIS_TABLE | |
OLD | NEW |