gfx/ots/src/ots.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
michael@0 2 // Use of this source code is governed by a BSD-style license that can be
michael@0 3 // found in the LICENSE file.
michael@0 4
michael@0 5 #ifndef OTS_H_
michael@0 6 #define OTS_H_
michael@0 7
michael@0 8 #include <stddef.h>
michael@0 9 #include <cstdarg>
michael@0 10 #include <cstddef>
michael@0 11 #include <cstdio>
michael@0 12 #include <cstdlib>
michael@0 13 #include <cstring>
michael@0 14 #include <limits>
michael@0 15
michael@0 16 #include "opentype-sanitiser.h"
michael@0 17
michael@0 18 // arraysize borrowed from base/basictypes.h
michael@0 19 template <typename T, size_t N>
michael@0 20 char (&ArraySizeHelper(T (&array)[N]))[N];
michael@0 21 #define arraysize(array) (sizeof(ArraySizeHelper(array)))
michael@0 22
michael@0 23 namespace ots {
michael@0 24
michael@0 25 #if defined(_MSC_VER) || !defined(OTS_DEBUG)
michael@0 26 #define OTS_FAILURE() false
michael@0 27 #else
michael@0 28 #define OTS_FAILURE() ots::Failure(__FILE__, __LINE__, __PRETTY_FUNCTION__)
michael@0 29 bool Failure(const char *f, int l, const char *fn);
michael@0 30 #endif
michael@0 31
michael@0 32 #if defined(_MSC_VER)
michael@0 33 // MSVC supports C99 style variadic macros.
michael@0 34 #define OTS_WARNING(format, ...)
michael@0 35 #else
michael@0 36 // GCC
michael@0 37 #if defined(OTS_DEBUG)
michael@0 38 #define OTS_WARNING(format, args...) \
michael@0 39 ots::Warning(__FILE__, __LINE__, format, ##args)
michael@0 40 void Warning(const char *f, int l, const char *format, ...)
michael@0 41 __attribute__((format(printf, 3, 4)));
michael@0 42 #else
michael@0 43 #define OTS_WARNING(format, args...)
michael@0 44 #endif
michael@0 45 #endif
michael@0 46
michael@0 47 // All OTS_FAILURE_* macros ultimately evaluate to 'false', just like the original
michael@0 48 // message-less OTS_FAILURE(), so that the current parser will return 'false' as
michael@0 49 // its result (indicating a failure).
michael@0 50 // If a message_func pointer has been provided, this will be called before returning
michael@0 51 // the 'false' status.
michael@0 52
michael@0 53 // Generate a simple message
michael@0 54 #define OTS_FAILURE_MSG_(otf_,...) \
michael@0 55 ((otf_)->message_func && \
michael@0 56 (*(otf_)->message_func)((otf_)->user_data, __VA_ARGS__) && \
michael@0 57 false)
michael@0 58
michael@0 59 // Generate a message with an associated table tag
michael@0 60 #define OTS_FAILURE_MSG_TAG_(otf_,msg_,tag_) \
michael@0 61 ((otf_)->message_func && \
michael@0 62 (*(otf_)->message_func)((otf_)->user_data, "%4.4s: %s", tag_, msg_) && \
michael@0 63 false)
michael@0 64
michael@0 65 // Convenience macro for use in files that only handle a single table tag,
michael@0 66 // defined as TABLE_NAME at the top of the file; the 'file' variable is
michael@0 67 // expected to be the current OpenTypeFile pointer.
michael@0 68 #define OTS_FAILURE_MSG(...) OTS_FAILURE_MSG_(file, TABLE_NAME ": " __VA_ARGS__)
michael@0 69
michael@0 70 // Define OTS_NO_TRANSCODE_HINTS (i.e., g++ -DOTS_NO_TRANSCODE_HINTS) if you
michael@0 71 // want to omit TrueType hinting instructions and variables in glyf, fpgm, prep,
michael@0 72 // and cvt tables.
michael@0 73 #if defined(OTS_NO_TRANSCODE_HINTS)
michael@0 74 const bool g_transcode_hints = false;
michael@0 75 #else
michael@0 76 const bool g_transcode_hints = true;
michael@0 77 #endif
michael@0 78
michael@0 79 // -----------------------------------------------------------------------------
michael@0 80 // Buffer helper class
michael@0 81 //
michael@0 82 // This class perform some trival buffer operations while checking for
michael@0 83 // out-of-bounds errors. As a family they return false if anything is amiss,
michael@0 84 // updating the current offset otherwise.
michael@0 85 // -----------------------------------------------------------------------------
michael@0 86 class Buffer {
michael@0 87 public:
michael@0 88 Buffer(const uint8_t *buf, size_t len)
michael@0 89 : buffer_(buf),
michael@0 90 length_(len),
michael@0 91 offset_(0) { }
michael@0 92
michael@0 93 bool Skip(size_t n_bytes) {
michael@0 94 return Read(NULL, n_bytes);
michael@0 95 }
michael@0 96
michael@0 97 bool Read(uint8_t *buf, size_t n_bytes) {
michael@0 98 if (n_bytes > 1024 * 1024 * 1024) {
michael@0 99 return OTS_FAILURE();
michael@0 100 }
michael@0 101 if ((offset_ + n_bytes > length_) ||
michael@0 102 (offset_ > length_ - n_bytes)) {
michael@0 103 return OTS_FAILURE();
michael@0 104 }
michael@0 105 if (buf) {
michael@0 106 std::memcpy(buf, buffer_ + offset_, n_bytes);
michael@0 107 }
michael@0 108 offset_ += n_bytes;
michael@0 109 return true;
michael@0 110 }
michael@0 111
michael@0 112 inline bool ReadU8(uint8_t *value) {
michael@0 113 if (offset_ + 1 > length_) {
michael@0 114 return OTS_FAILURE();
michael@0 115 }
michael@0 116 *value = buffer_[offset_];
michael@0 117 ++offset_;
michael@0 118 return true;
michael@0 119 }
michael@0 120
michael@0 121 bool ReadU16(uint16_t *value) {
michael@0 122 if (offset_ + 2 > length_) {
michael@0 123 return OTS_FAILURE();
michael@0 124 }
michael@0 125 std::memcpy(value, buffer_ + offset_, sizeof(uint16_t));
michael@0 126 *value = ntohs(*value);
michael@0 127 offset_ += 2;
michael@0 128 return true;
michael@0 129 }
michael@0 130
michael@0 131 bool ReadS16(int16_t *value) {
michael@0 132 return ReadU16(reinterpret_cast<uint16_t*>(value));
michael@0 133 }
michael@0 134
michael@0 135 bool ReadU24(uint32_t *value) {
michael@0 136 if (offset_ + 3 > length_) {
michael@0 137 return OTS_FAILURE();
michael@0 138 }
michael@0 139 *value = static_cast<uint32_t>(buffer_[offset_]) << 16 |
michael@0 140 static_cast<uint32_t>(buffer_[offset_ + 1]) << 8 |
michael@0 141 static_cast<uint32_t>(buffer_[offset_ + 2]);
michael@0 142 offset_ += 3;
michael@0 143 return true;
michael@0 144 }
michael@0 145
michael@0 146 bool ReadU32(uint32_t *value) {
michael@0 147 if (offset_ + 4 > length_) {
michael@0 148 return OTS_FAILURE();
michael@0 149 }
michael@0 150 std::memcpy(value, buffer_ + offset_, sizeof(uint32_t));
michael@0 151 *value = ntohl(*value);
michael@0 152 offset_ += 4;
michael@0 153 return true;
michael@0 154 }
michael@0 155
michael@0 156 bool ReadS32(int32_t *value) {
michael@0 157 return ReadU32(reinterpret_cast<uint32_t*>(value));
michael@0 158 }
michael@0 159
michael@0 160 bool ReadTag(uint32_t *value) {
michael@0 161 if (offset_ + 4 > length_) {
michael@0 162 return OTS_FAILURE();
michael@0 163 }
michael@0 164 std::memcpy(value, buffer_ + offset_, sizeof(uint32_t));
michael@0 165 offset_ += 4;
michael@0 166 return true;
michael@0 167 }
michael@0 168
michael@0 169 bool ReadR64(uint64_t *value) {
michael@0 170 if (offset_ + 8 > length_) {
michael@0 171 return OTS_FAILURE();
michael@0 172 }
michael@0 173 std::memcpy(value, buffer_ + offset_, sizeof(uint64_t));
michael@0 174 offset_ += 8;
michael@0 175 return true;
michael@0 176 }
michael@0 177
michael@0 178 const uint8_t *buffer() const { return buffer_; }
michael@0 179 size_t offset() const { return offset_; }
michael@0 180 size_t length() const { return length_; }
michael@0 181
michael@0 182 void set_offset(size_t newoffset) { offset_ = newoffset; }
michael@0 183
michael@0 184 private:
michael@0 185 const uint8_t * const buffer_;
michael@0 186 const size_t length_;
michael@0 187 size_t offset_;
michael@0 188 };
michael@0 189
michael@0 190 // Round a value up to the nearest multiple of 4. Don't round the value in the
michael@0 191 // case that rounding up overflows.
michael@0 192 template<typename T> T Round4(T value) {
michael@0 193 if (std::numeric_limits<T>::max() - value < 3) {
michael@0 194 return value;
michael@0 195 }
michael@0 196 return (value + 3) & ~3;
michael@0 197 }
michael@0 198
michael@0 199 template<typename T> T Round2(T value) {
michael@0 200 if (value == std::numeric_limits<T>::max()) {
michael@0 201 return value;
michael@0 202 }
michael@0 203 return (value + 1) & ~1;
michael@0 204 }
michael@0 205
michael@0 206 bool IsValidVersionTag(uint32_t tag);
michael@0 207
michael@0 208 #define FOR_EACH_TABLE_TYPE \
michael@0 209 F(cff, CFF) \
michael@0 210 F(cmap, CMAP) \
michael@0 211 F(cvt, CVT) \
michael@0 212 F(fpgm, FPGM) \
michael@0 213 F(gasp, GASP) \
michael@0 214 F(gdef, GDEF) \
michael@0 215 F(glyf, GLYF) \
michael@0 216 F(gpos, GPOS) \
michael@0 217 F(gsub, GSUB) \
michael@0 218 F(hdmx, HDMX) \
michael@0 219 F(head, HEAD) \
michael@0 220 F(hhea, HHEA) \
michael@0 221 F(hmtx, HMTX) \
michael@0 222 F(kern, KERN) \
michael@0 223 F(loca, LOCA) \
michael@0 224 F(ltsh, LTSH) \
michael@0 225 F(math, MATH) \
michael@0 226 F(maxp, MAXP) \
michael@0 227 F(name, NAME) \
michael@0 228 F(os2, OS2) \
michael@0 229 F(post, POST) \
michael@0 230 F(prep, PREP) \
michael@0 231 F(vdmx, VDMX) \
michael@0 232 F(vorg, VORG) \
michael@0 233 F(vhea, VHEA) \
michael@0 234 F(vmtx, VMTX)
michael@0 235
michael@0 236 #define F(name, capname) struct OpenType##capname;
michael@0 237 FOR_EACH_TABLE_TYPE
michael@0 238 #undef F
michael@0 239
michael@0 240 struct OpenTypeFile {
michael@0 241 OpenTypeFile() {
michael@0 242 #define F(name, capname) name = NULL;
michael@0 243 FOR_EACH_TABLE_TYPE
michael@0 244 #undef F
michael@0 245 }
michael@0 246
michael@0 247 uint32_t version;
michael@0 248 uint16_t num_tables;
michael@0 249 uint16_t search_range;
michael@0 250 uint16_t entry_selector;
michael@0 251 uint16_t range_shift;
michael@0 252
michael@0 253 MessageFunc message_func;
michael@0 254 void *user_data;
michael@0 255
michael@0 256 #define F(name, capname) OpenType##capname *name;
michael@0 257 FOR_EACH_TABLE_TYPE
michael@0 258 #undef F
michael@0 259 };
michael@0 260
michael@0 261 #define F(name, capname) \
michael@0 262 bool ots_##name##_parse(OpenTypeFile *f, const uint8_t *d, size_t l); \
michael@0 263 bool ots_##name##_should_serialise(OpenTypeFile *f); \
michael@0 264 bool ots_##name##_serialise(OTSStream *s, OpenTypeFile *f); \
michael@0 265 void ots_##name##_free(OpenTypeFile *f);
michael@0 266 // TODO(yusukes): change these function names to follow Chromium coding rule.
michael@0 267 FOR_EACH_TABLE_TYPE
michael@0 268 #undef F
michael@0 269
michael@0 270 } // namespace ots
michael@0 271
michael@0 272 #endif // OTS_H_

mercurial