1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/ots/src/ots.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,272 @@ 1.4 +// Copyright (c) 2009 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef OTS_H_ 1.9 +#define OTS_H_ 1.10 + 1.11 +#include <stddef.h> 1.12 +#include <cstdarg> 1.13 +#include <cstddef> 1.14 +#include <cstdio> 1.15 +#include <cstdlib> 1.16 +#include <cstring> 1.17 +#include <limits> 1.18 + 1.19 +#include "opentype-sanitiser.h" 1.20 + 1.21 +// arraysize borrowed from base/basictypes.h 1.22 +template <typename T, size_t N> 1.23 +char (&ArraySizeHelper(T (&array)[N]))[N]; 1.24 +#define arraysize(array) (sizeof(ArraySizeHelper(array))) 1.25 + 1.26 +namespace ots { 1.27 + 1.28 +#if defined(_MSC_VER) || !defined(OTS_DEBUG) 1.29 +#define OTS_FAILURE() false 1.30 +#else 1.31 +#define OTS_FAILURE() ots::Failure(__FILE__, __LINE__, __PRETTY_FUNCTION__) 1.32 +bool Failure(const char *f, int l, const char *fn); 1.33 +#endif 1.34 + 1.35 +#if defined(_MSC_VER) 1.36 +// MSVC supports C99 style variadic macros. 1.37 +#define OTS_WARNING(format, ...) 1.38 +#else 1.39 +// GCC 1.40 +#if defined(OTS_DEBUG) 1.41 +#define OTS_WARNING(format, args...) \ 1.42 + ots::Warning(__FILE__, __LINE__, format, ##args) 1.43 +void Warning(const char *f, int l, const char *format, ...) 1.44 + __attribute__((format(printf, 3, 4))); 1.45 +#else 1.46 +#define OTS_WARNING(format, args...) 1.47 +#endif 1.48 +#endif 1.49 + 1.50 +// All OTS_FAILURE_* macros ultimately evaluate to 'false', just like the original 1.51 +// message-less OTS_FAILURE(), so that the current parser will return 'false' as 1.52 +// its result (indicating a failure). 1.53 +// If a message_func pointer has been provided, this will be called before returning 1.54 +// the 'false' status. 1.55 + 1.56 +// Generate a simple message 1.57 +#define OTS_FAILURE_MSG_(otf_,...) \ 1.58 + ((otf_)->message_func && \ 1.59 + (*(otf_)->message_func)((otf_)->user_data, __VA_ARGS__) && \ 1.60 + false) 1.61 + 1.62 +// Generate a message with an associated table tag 1.63 +#define OTS_FAILURE_MSG_TAG_(otf_,msg_,tag_) \ 1.64 + ((otf_)->message_func && \ 1.65 + (*(otf_)->message_func)((otf_)->user_data, "%4.4s: %s", tag_, msg_) && \ 1.66 + false) 1.67 + 1.68 +// Convenience macro for use in files that only handle a single table tag, 1.69 +// defined as TABLE_NAME at the top of the file; the 'file' variable is 1.70 +// expected to be the current OpenTypeFile pointer. 1.71 +#define OTS_FAILURE_MSG(...) OTS_FAILURE_MSG_(file, TABLE_NAME ": " __VA_ARGS__) 1.72 + 1.73 +// Define OTS_NO_TRANSCODE_HINTS (i.e., g++ -DOTS_NO_TRANSCODE_HINTS) if you 1.74 +// want to omit TrueType hinting instructions and variables in glyf, fpgm, prep, 1.75 +// and cvt tables. 1.76 +#if defined(OTS_NO_TRANSCODE_HINTS) 1.77 +const bool g_transcode_hints = false; 1.78 +#else 1.79 +const bool g_transcode_hints = true; 1.80 +#endif 1.81 + 1.82 +// ----------------------------------------------------------------------------- 1.83 +// Buffer helper class 1.84 +// 1.85 +// This class perform some trival buffer operations while checking for 1.86 +// out-of-bounds errors. As a family they return false if anything is amiss, 1.87 +// updating the current offset otherwise. 1.88 +// ----------------------------------------------------------------------------- 1.89 +class Buffer { 1.90 + public: 1.91 + Buffer(const uint8_t *buf, size_t len) 1.92 + : buffer_(buf), 1.93 + length_(len), 1.94 + offset_(0) { } 1.95 + 1.96 + bool Skip(size_t n_bytes) { 1.97 + return Read(NULL, n_bytes); 1.98 + } 1.99 + 1.100 + bool Read(uint8_t *buf, size_t n_bytes) { 1.101 + if (n_bytes > 1024 * 1024 * 1024) { 1.102 + return OTS_FAILURE(); 1.103 + } 1.104 + if ((offset_ + n_bytes > length_) || 1.105 + (offset_ > length_ - n_bytes)) { 1.106 + return OTS_FAILURE(); 1.107 + } 1.108 + if (buf) { 1.109 + std::memcpy(buf, buffer_ + offset_, n_bytes); 1.110 + } 1.111 + offset_ += n_bytes; 1.112 + return true; 1.113 + } 1.114 + 1.115 + inline bool ReadU8(uint8_t *value) { 1.116 + if (offset_ + 1 > length_) { 1.117 + return OTS_FAILURE(); 1.118 + } 1.119 + *value = buffer_[offset_]; 1.120 + ++offset_; 1.121 + return true; 1.122 + } 1.123 + 1.124 + bool ReadU16(uint16_t *value) { 1.125 + if (offset_ + 2 > length_) { 1.126 + return OTS_FAILURE(); 1.127 + } 1.128 + std::memcpy(value, buffer_ + offset_, sizeof(uint16_t)); 1.129 + *value = ntohs(*value); 1.130 + offset_ += 2; 1.131 + return true; 1.132 + } 1.133 + 1.134 + bool ReadS16(int16_t *value) { 1.135 + return ReadU16(reinterpret_cast<uint16_t*>(value)); 1.136 + } 1.137 + 1.138 + bool ReadU24(uint32_t *value) { 1.139 + if (offset_ + 3 > length_) { 1.140 + return OTS_FAILURE(); 1.141 + } 1.142 + *value = static_cast<uint32_t>(buffer_[offset_]) << 16 | 1.143 + static_cast<uint32_t>(buffer_[offset_ + 1]) << 8 | 1.144 + static_cast<uint32_t>(buffer_[offset_ + 2]); 1.145 + offset_ += 3; 1.146 + return true; 1.147 + } 1.148 + 1.149 + bool ReadU32(uint32_t *value) { 1.150 + if (offset_ + 4 > length_) { 1.151 + return OTS_FAILURE(); 1.152 + } 1.153 + std::memcpy(value, buffer_ + offset_, sizeof(uint32_t)); 1.154 + *value = ntohl(*value); 1.155 + offset_ += 4; 1.156 + return true; 1.157 + } 1.158 + 1.159 + bool ReadS32(int32_t *value) { 1.160 + return ReadU32(reinterpret_cast<uint32_t*>(value)); 1.161 + } 1.162 + 1.163 + bool ReadTag(uint32_t *value) { 1.164 + if (offset_ + 4 > length_) { 1.165 + return OTS_FAILURE(); 1.166 + } 1.167 + std::memcpy(value, buffer_ + offset_, sizeof(uint32_t)); 1.168 + offset_ += 4; 1.169 + return true; 1.170 + } 1.171 + 1.172 + bool ReadR64(uint64_t *value) { 1.173 + if (offset_ + 8 > length_) { 1.174 + return OTS_FAILURE(); 1.175 + } 1.176 + std::memcpy(value, buffer_ + offset_, sizeof(uint64_t)); 1.177 + offset_ += 8; 1.178 + return true; 1.179 + } 1.180 + 1.181 + const uint8_t *buffer() const { return buffer_; } 1.182 + size_t offset() const { return offset_; } 1.183 + size_t length() const { return length_; } 1.184 + 1.185 + void set_offset(size_t newoffset) { offset_ = newoffset; } 1.186 + 1.187 + private: 1.188 + const uint8_t * const buffer_; 1.189 + const size_t length_; 1.190 + size_t offset_; 1.191 +}; 1.192 + 1.193 +// Round a value up to the nearest multiple of 4. Don't round the value in the 1.194 +// case that rounding up overflows. 1.195 +template<typename T> T Round4(T value) { 1.196 + if (std::numeric_limits<T>::max() - value < 3) { 1.197 + return value; 1.198 + } 1.199 + return (value + 3) & ~3; 1.200 +} 1.201 + 1.202 +template<typename T> T Round2(T value) { 1.203 + if (value == std::numeric_limits<T>::max()) { 1.204 + return value; 1.205 + } 1.206 + return (value + 1) & ~1; 1.207 +} 1.208 + 1.209 +bool IsValidVersionTag(uint32_t tag); 1.210 + 1.211 +#define FOR_EACH_TABLE_TYPE \ 1.212 + F(cff, CFF) \ 1.213 + F(cmap, CMAP) \ 1.214 + F(cvt, CVT) \ 1.215 + F(fpgm, FPGM) \ 1.216 + F(gasp, GASP) \ 1.217 + F(gdef, GDEF) \ 1.218 + F(glyf, GLYF) \ 1.219 + F(gpos, GPOS) \ 1.220 + F(gsub, GSUB) \ 1.221 + F(hdmx, HDMX) \ 1.222 + F(head, HEAD) \ 1.223 + F(hhea, HHEA) \ 1.224 + F(hmtx, HMTX) \ 1.225 + F(kern, KERN) \ 1.226 + F(loca, LOCA) \ 1.227 + F(ltsh, LTSH) \ 1.228 + F(math, MATH) \ 1.229 + F(maxp, MAXP) \ 1.230 + F(name, NAME) \ 1.231 + F(os2, OS2) \ 1.232 + F(post, POST) \ 1.233 + F(prep, PREP) \ 1.234 + F(vdmx, VDMX) \ 1.235 + F(vorg, VORG) \ 1.236 + F(vhea, VHEA) \ 1.237 + F(vmtx, VMTX) 1.238 + 1.239 +#define F(name, capname) struct OpenType##capname; 1.240 +FOR_EACH_TABLE_TYPE 1.241 +#undef F 1.242 + 1.243 +struct OpenTypeFile { 1.244 + OpenTypeFile() { 1.245 +#define F(name, capname) name = NULL; 1.246 + FOR_EACH_TABLE_TYPE 1.247 +#undef F 1.248 + } 1.249 + 1.250 + uint32_t version; 1.251 + uint16_t num_tables; 1.252 + uint16_t search_range; 1.253 + uint16_t entry_selector; 1.254 + uint16_t range_shift; 1.255 + 1.256 + MessageFunc message_func; 1.257 + void *user_data; 1.258 + 1.259 +#define F(name, capname) OpenType##capname *name; 1.260 +FOR_EACH_TABLE_TYPE 1.261 +#undef F 1.262 +}; 1.263 + 1.264 +#define F(name, capname) \ 1.265 +bool ots_##name##_parse(OpenTypeFile *f, const uint8_t *d, size_t l); \ 1.266 +bool ots_##name##_should_serialise(OpenTypeFile *f); \ 1.267 +bool ots_##name##_serialise(OTSStream *s, OpenTypeFile *f); \ 1.268 +void ots_##name##_free(OpenTypeFile *f); 1.269 +// TODO(yusukes): change these function names to follow Chromium coding rule. 1.270 +FOR_EACH_TABLE_TYPE 1.271 +#undef F 1.272 + 1.273 +} // namespace ots 1.274 + 1.275 +#endif // OTS_H_