|
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 delete file->vorg; \ |
|
17 file->vorg = 0; \ |
|
18 OTS_FAILURE_MSG("Table discarded"); \ |
|
19 } while (0) |
|
20 |
|
21 namespace ots { |
|
22 |
|
23 bool ots_vorg_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { |
|
24 Buffer table(data, length); |
|
25 file->vorg = new OpenTypeVORG; |
|
26 OpenTypeVORG * const vorg = file->vorg; |
|
27 |
|
28 uint16_t num_recs; |
|
29 if (!table.ReadU16(&vorg->major_version) || |
|
30 !table.ReadU16(&vorg->minor_version) || |
|
31 !table.ReadS16(&vorg->default_vert_origin_y) || |
|
32 !table.ReadU16(&num_recs)) { |
|
33 return OTS_FAILURE_MSG("Failed to read header"); |
|
34 } |
|
35 if (vorg->major_version != 1) { |
|
36 OTS_WARNING("bad major version: %u", vorg->major_version); |
|
37 DROP_THIS_TABLE; |
|
38 return true; |
|
39 } |
|
40 if (vorg->minor_version != 0) { |
|
41 OTS_WARNING("bad minor version: %u", vorg->minor_version); |
|
42 DROP_THIS_TABLE; |
|
43 return true; |
|
44 } |
|
45 |
|
46 // num_recs might be zero (e.g., DFHSMinchoPro5-W3-Demo.otf). |
|
47 if (!num_recs) { |
|
48 return true; |
|
49 } |
|
50 |
|
51 uint16_t last_glyph_index = 0; |
|
52 vorg->metrics.reserve(num_recs); |
|
53 for (unsigned i = 0; i < num_recs; ++i) { |
|
54 OpenTypeVORGMetrics rec; |
|
55 |
|
56 if (!table.ReadU16(&rec.glyph_index) || |
|
57 !table.ReadS16(&rec.vert_origin_y)) { |
|
58 return OTS_FAILURE_MSG("Failed to read record %d", i); |
|
59 } |
|
60 if ((i != 0) && (rec.glyph_index <= last_glyph_index)) { |
|
61 OTS_WARNING("the table is not sorted"); |
|
62 DROP_THIS_TABLE; |
|
63 return true; |
|
64 } |
|
65 last_glyph_index = rec.glyph_index; |
|
66 |
|
67 vorg->metrics.push_back(rec); |
|
68 } |
|
69 |
|
70 return true; |
|
71 } |
|
72 |
|
73 bool ots_vorg_should_serialise(OpenTypeFile *file) { |
|
74 if (!file->cff) return false; // this table is not for fonts with TT glyphs. |
|
75 return file->vorg != NULL; |
|
76 } |
|
77 |
|
78 bool ots_vorg_serialise(OTSStream *out, OpenTypeFile *file) { |
|
79 OpenTypeVORG * const vorg = file->vorg; |
|
80 |
|
81 if (!out->WriteU16(vorg->major_version) || |
|
82 !out->WriteU16(vorg->minor_version) || |
|
83 !out->WriteS16(vorg->default_vert_origin_y) || |
|
84 !out->WriteU16(vorg->metrics.size())) { |
|
85 return OTS_FAILURE_MSG("Failed to write table header"); |
|
86 } |
|
87 |
|
88 for (unsigned i = 0; i < vorg->metrics.size(); ++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 |