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