gfx/ots/src/ots.h

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

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

mercurial