|
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 "ltsh.h" |
|
6 |
|
7 #include "maxp.h" |
|
8 |
|
9 // LTSH - Linear Threshold |
|
10 // http://www.microsoft.com/typography/otspec/ltsh.htm |
|
11 |
|
12 #define TABLE_NAME "LTSH" |
|
13 |
|
14 #define DROP_THIS_TABLE \ |
|
15 do { \ |
|
16 delete file->ltsh; \ |
|
17 file->ltsh = 0; \ |
|
18 OTS_FAILURE_MSG("Table discarded"); \ |
|
19 } while (0) |
|
20 |
|
21 namespace ots { |
|
22 |
|
23 bool ots_ltsh_parse(OpenTypeFile *file, const uint8_t *data, size_t length) { |
|
24 Buffer table(data, length); |
|
25 |
|
26 if (!file->maxp) { |
|
27 return OTS_FAILURE_MSG("Missing maxp table from font needed by ltsh"); |
|
28 } |
|
29 |
|
30 OpenTypeLTSH *ltsh = new OpenTypeLTSH; |
|
31 file->ltsh = ltsh; |
|
32 |
|
33 uint16_t num_glyphs = 0; |
|
34 if (!table.ReadU16(<sh->version) || |
|
35 !table.ReadU16(&num_glyphs)) { |
|
36 return OTS_FAILURE_MSG("Failed to read ltsh header"); |
|
37 } |
|
38 |
|
39 if (ltsh->version != 0) { |
|
40 OTS_WARNING("bad version: %u", ltsh->version); |
|
41 DROP_THIS_TABLE; |
|
42 return true; |
|
43 } |
|
44 |
|
45 if (num_glyphs != file->maxp->num_glyphs) { |
|
46 OTS_WARNING("bad num_glyphs: %u", num_glyphs); |
|
47 DROP_THIS_TABLE; |
|
48 return true; |
|
49 } |
|
50 |
|
51 ltsh->ypels.reserve(num_glyphs); |
|
52 for (unsigned i = 0; i < num_glyphs; ++i) { |
|
53 uint8_t pel = 0; |
|
54 if (!table.ReadU8(&pel)) { |
|
55 return OTS_FAILURE_MSG("Failed to read pixels for glyph %d", i); |
|
56 } |
|
57 ltsh->ypels.push_back(pel); |
|
58 } |
|
59 |
|
60 return true; |
|
61 } |
|
62 |
|
63 bool ots_ltsh_should_serialise(OpenTypeFile *file) { |
|
64 if (!file->glyf) return false; // this table is not for CFF fonts. |
|
65 return file->ltsh != NULL; |
|
66 } |
|
67 |
|
68 bool ots_ltsh_serialise(OTSStream *out, OpenTypeFile *file) { |
|
69 const OpenTypeLTSH *ltsh = file->ltsh; |
|
70 |
|
71 if (!out->WriteU16(ltsh->version) || |
|
72 !out->WriteU16(ltsh->ypels.size())) { |
|
73 return OTS_FAILURE_MSG("Failed to write pels size"); |
|
74 } |
|
75 for (unsigned i = 0; i < ltsh->ypels.size(); ++i) { |
|
76 if (!out->Write(&(ltsh->ypels[i]), 1)) { |
|
77 return OTS_FAILURE_MSG("Failed to write pixel size for glyph %d", i); |
|
78 } |
|
79 } |
|
80 |
|
81 return true; |
|
82 } |
|
83 |
|
84 void ots_ltsh_free(OpenTypeFile *file) { |
|
85 delete file->ltsh; |
|
86 } |
|
87 |
|
88 } // namespace ots |