blob: 09f3434190b69908f73d8e36d4e3d6a970bbb081 [file] [log] [blame]
yusukes@chromium.orgd257d182009-11-04 04:56:32 +00001// 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#ifndef OTS_H_
6#define OTS_H_
7
8#include <cstdarg>
bashi@chromium.orgcd35d032011-05-31 07:38:53 +00009#include <cstddef>
yusukes@chromium.orgd257d182009-11-04 04:56:32 +000010#include <cstdio>
11#include <cstdlib>
12#include <cstring>
13
14#include "opentype-sanitiser.h"
15
16namespace ots {
17
18#if defined(_MSC_VER) || !defined(OTS_DEBUG)
19#define OTS_FAILURE() false
20#else
21#define OTS_FAILURE() ots::Failure(__FILE__, __LINE__, __PRETTY_FUNCTION__)
22bool Failure(const char *f, int l, const char *fn);
23#endif
24
25#if defined(_MSC_VER)
26// MSVC supports C99 style variadic macros.
27#define OTS_WARNING(format, ...)
28#else
29// GCC
30#if defined(OTS_DEBUG)
31#define OTS_WARNING(format, args...) \
32 ots::Warning(__FILE__, __LINE__, format, ##args)
33void Warning(const char *f, int l, const char *format, ...)
34 __attribute__((format(printf, 3, 4)));
35#else
36#define OTS_WARNING(format, args...)
37#endif
38#endif
39
40// Define OTS_NO_TRANSCODE_HINTS (i.e., g++ -DOTS_NO_TRANSCODE_HINTS) if you
41// want to omit TrueType hinting instructions and variables in glyf, fpgm, prep,
42// and cvt tables.
43#if defined(OTS_NO_TRANSCODE_HINTS)
44const bool g_transcode_hints = false;
45#else
46const bool g_transcode_hints = true;
47#endif
48
49// -----------------------------------------------------------------------------
50// Buffer helper class
51//
52// This class perform some trival buffer operations while checking for
53// out-of-bounds errors. As a family they return false if anything is amiss,
54// updating the current offset otherwise.
55// -----------------------------------------------------------------------------
56class Buffer {
57 public:
58 Buffer(const uint8_t *buffer, size_t len)
59 : buffer_(buffer),
60 length_(len),
61 offset_(0) { }
62
63 bool Skip(size_t n_bytes) {
64 return Read(NULL, n_bytes);
65 }
66
67 bool Read(uint8_t *buffer, size_t n_bytes) {
68 if (n_bytes > 1024 * 1024 * 1024) {
69 return OTS_FAILURE();
70 }
71 if ((offset_ + n_bytes > length_) ||
72 (offset_ > length_ - n_bytes)) {
73 return OTS_FAILURE();
74 }
75 if (buffer) {
76 std::memcpy(buffer, buffer_ + offset_, n_bytes);
77 }
78 offset_ += n_bytes;
79 return true;
80 }
81
82 inline bool ReadU8(uint8_t *value) {
83 if (offset_ + 1 > length_) {
84 return OTS_FAILURE();
85 }
86 *value = buffer_[offset_];
87 ++offset_;
88 return true;
89 }
90
91 bool ReadU16(uint16_t *value) {
92 if (offset_ + 2 > length_) {
93 return OTS_FAILURE();
94 }
95 std::memcpy(value, buffer_ + offset_, sizeof(uint16_t));
96 *value = ntohs(*value);
97 offset_ += 2;
98 return true;
99 }
100
101 bool ReadS16(int16_t *value) {
102 return ReadU16(reinterpret_cast<uint16_t*>(value));
103 }
104
bashi@google.com93aedf72010-12-24 00:29:23 +0000105 bool ReadU24(uint32_t *value) {
106 if (offset_ + 3 > length_) {
107 return OTS_FAILURE();
108 }
109 *value = static_cast<uint32_t>(buffer_[offset_]) << 16 |
110 static_cast<uint32_t>(buffer_[offset_ + 1]) << 8 |
111 static_cast<uint32_t>(buffer_[offset_ + 2]);
112 offset_ += 3;
113 return true;
114 }
115
yusukes@chromium.orgd257d182009-11-04 04:56:32 +0000116 bool ReadU32(uint32_t *value) {
117 if (offset_ + 4 > length_) {
118 return OTS_FAILURE();
119 }
120 std::memcpy(value, buffer_ + offset_, sizeof(uint32_t));
121 *value = ntohl(*value);
122 offset_ += 4;
123 return true;
124 }
125
126 bool ReadS32(int32_t *value) {
127 return ReadU32(reinterpret_cast<uint32_t*>(value));
128 }
129
130 bool ReadTag(uint32_t *value) {
131 if (offset_ + 4 > length_) {
132 return OTS_FAILURE();
133 }
134 std::memcpy(value, buffer_ + offset_, sizeof(uint32_t));
135 offset_ += 4;
136 return true;
137 }
138
139 bool ReadR64(uint64_t *value) {
140 if (offset_ + 8 > length_) {
141 return OTS_FAILURE();
142 }
143 std::memcpy(value, buffer_ + offset_, sizeof(uint64_t));
144 offset_ += 8;
145 return true;
146 }
147
yusukes@chromium.org6263d062010-08-06 03:27:28 +0000148 const uint8_t *buffer() const { return buffer_; }
yusukes@chromium.orgd257d182009-11-04 04:56:32 +0000149 size_t offset() const { return offset_; }
150 size_t length() const { return length_; }
151
152 void set_offset(size_t newoffset) { offset_ = newoffset; }
153
154 private:
155 const uint8_t * const buffer_;
156 const size_t length_;
157 size_t offset_;
158};
159
160#define FOR_EACH_TABLE_TYPE \
161 F(cff, CFF) \
162 F(cmap, CMAP) \
163 F(cvt, CVT) \
164 F(fpgm, FPGM) \
165 F(gasp, GASP) \
bashi@google.com00b790a2011-01-27 06:35:42 +0000166 F(gdef, GDEF) \
yusukes@chromium.orgd257d182009-11-04 04:56:32 +0000167 F(glyf, GLYF) \
bashi@chromium.orgced71122011-02-17 10:23:47 +0000168 F(gpos, GPOS) \
bashi@chromium.orga5748662011-03-18 17:48:29 +0000169 F(gsub, GSUB) \
yusukes@chromium.orgd257d182009-11-04 04:56:32 +0000170 F(hdmx, HDMX) \
171 F(head, HEAD) \
172 F(hhea, HHEA) \
173 F(hmtx, HMTX) \
yusukes@chromium.orgf12575f2010-02-02 21:26:17 +0000174 F(kern, KERN) \
yusukes@chromium.orgd257d182009-11-04 04:56:32 +0000175 F(loca, LOCA) \
176 F(ltsh, LTSH) \
177 F(maxp, MAXP) \
178 F(name, NAME) \
179 F(os2, OS2) \
180 F(post, POST) \
181 F(prep, PREP) \
182 F(vdmx, VDMX) \
bashi@chromium.org4dcad602011-03-28 20:51:38 +0000183 F(vorg, VORG) \
184 F(vhea, VHEA) \
185 F(vmtx, VMTX)
yusukes@chromium.orgd257d182009-11-04 04:56:32 +0000186
187#define F(name, capname) struct OpenType##capname;
188FOR_EACH_TABLE_TYPE
189#undef F
190
191struct OpenTypeFile {
192 OpenTypeFile() {
193#define F(name, capname) name = NULL;
194 FOR_EACH_TABLE_TYPE
195#undef F
196 }
197
198 uint32_t version;
199 uint16_t num_tables;
200 uint16_t search_range;
201 uint16_t entry_selector;
202 uint16_t range_shift;
203
204#define F(name, capname) OpenType##capname *name;
205FOR_EACH_TABLE_TYPE
206#undef F
207};
208
bashi@chromium.org4dcad602011-03-28 20:51:38 +0000209#define F(name, capname) \
210bool ots_##name##_parse(OpenTypeFile *f, const uint8_t *d, size_t l); \
211bool ots_##name##_should_serialise(OpenTypeFile *f); \
212bool ots_##name##_serialise(OTSStream *s, OpenTypeFile *f); \
213void ots_##name##_free(OpenTypeFile *f);
214// TODO(yusukes): change these function names to follow Chromium coding rule.
215FOR_EACH_TABLE_TYPE
216#undef F
217
yusukes@chromium.orgd257d182009-11-04 04:56:32 +0000218} // namespace ots
219
220#endif // OTS_H_