gfx/ots/src/ots.h

changeset 0
6474c204b198
     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_

mercurial