| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  * Copyright (C) 2007,2008,2009,2010  Red Hat, Inc. |    2  * Copyright © 2007,2008,2009,2010  Red Hat, Inc. | 
|    3  * |    3  * | 
|    4  *  This is part of HarfBuzz, a text shaping library. |    4  *  This is part of HarfBuzz, a text shaping library. | 
|    5  * |    5  * | 
|    6  * Permission is hereby granted, without written agreement and without |    6  * Permission is hereby granted, without written agreement and without | 
|    7  * license or royalty fees, to use, copy, modify, and distribute this |    7  * license or royalty fees, to use, copy, modify, and distribute this | 
|    8  * software and its documentation for any purpose, provided that the |    8  * software and its documentation for any purpose, provided that the | 
|    9  * above copyright notice and the following two paragraphs appear in |    9  * above copyright notice and the following two paragraphs appear in | 
|   10  * all copies of this software. |   10  * all copies of this software. | 
|   11  * |   11  * | 
|   12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |   12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR | 
|   13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |   13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES | 
|   14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |   14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN | 
|   15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |   15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH | 
|   16  * DAMAGE. |   16  * DAMAGE. | 
|   17  * |   17  * | 
|   18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |   18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, | 
|   19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |   19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | 
|   20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS |   20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS | 
|   21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |   21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO | 
|   22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |   22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | 
|   23  * |   23  * | 
|   24  * Red Hat Author(s): Behdad Esfahbod |   24  * Red Hat Author(s): Behdad Esfahbod | 
|   25  */ |   25  */ | 
|   26  |   26  | 
|   27 #ifndef HB_OPEN_TYPE_PRIVATE_HH |   27 #ifndef HB_OPEN_TYPE_PRIVATE_HH | 
|   28 #define HB_OPEN_TYPE_PRIVATE_HH |   28 #define HB_OPEN_TYPE_PRIVATE_HH | 
|   29  |   29  | 
|   30 #include "hb-private.h" |   30 #include "hb-private.hh" | 
|   31  |   31  | 
|   32 #include "hb-blob.h" |   32 #include "hb-blob.h" | 
|   33  |   33  | 
|   34 HB_BEGIN_DECLS |  | 
|   35 HB_END_DECLS |  | 
|   36  |   34  | 
|   37  |   35  | 
|   38 /* |   36 /* | 
|   39  * Casts |   37  * Casts | 
|   40  */ |   38  */ | 
|   41  |   39  | 
|   42 /* Cast to struct T, reference to reference */ |   40 /* Cast to struct T, reference to reference */ | 
|   43 template<typename Type, typename TObject> |   41 template<typename Type, typename TObject> | 
|   44 inline const Type& CastR(const TObject &X) |   42 inline const Type& CastR(const TObject &X) | 
|   45 { return reinterpret_cast<const Type&> (X); } |   43 { return reinterpret_cast<const Type&> (X); } | 
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  137 template <> \ |  135 template <> \ | 
|  138 inline const Type& Null<Type> (void) { \ |  136 inline const Type& Null<Type> (void) { \ | 
|  139   return *CastP<Type> (_Null##Type); \ |  137   return *CastP<Type> (_Null##Type); \ | 
|  140 } /* The following line really exists such that we end in a place needing semico
     lon */ \ |  138 } /* The following line really exists such that we end in a place needing semico
     lon */ \ | 
|  141 ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type)) |  139 ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type)) | 
|  142  |  140  | 
|  143 /* Accessor macro. */ |  141 /* Accessor macro. */ | 
|  144 #define Null(Type) Null<Type>() |  142 #define Null(Type) Null<Type>() | 
|  145  |  143  | 
|  146  |  144  | 
|  147 /* |  | 
|  148  * Trace |  | 
|  149  */ |  | 
|  150  |  | 
|  151  |  | 
|  152 template <int max_depth> |  | 
|  153 struct hb_trace_t { |  | 
|  154   explicit hb_trace_t (unsigned int *pdepth, const char *what, const char *funct
     ion, const void *obj) : pdepth(pdepth) { |  | 
|  155     (void) (*pdepth < max_depth && |  | 
|  156             fprintf (stderr, "%s(%p) %-*d-> %s\n", what, obj, *pdepth, *pdepth, 
     function)); |  | 
|  157     if (max_depth) ++*pdepth; |  | 
|  158   } |  | 
|  159   ~hb_trace_t (void) { if (max_depth) --*pdepth; } |  | 
|  160  |  | 
|  161   private: |  | 
|  162   unsigned int *pdepth; |  | 
|  163 }; |  | 
|  164 template <> /* Optimize when tracing is disabled */ |  | 
|  165 struct hb_trace_t<0> { |  | 
|  166   explicit hb_trace_t (unsigned int *pdepth HB_UNUSED, const char *what HB_UNUSE
     D, const char *function HB_UNUSED, const void *obj HB_UNUSED) {} |  | 
|  167 }; |  | 
|  168  |  | 
|  169  |  | 
|  170  |  145  | 
|  171 /* |  146 /* | 
|  172  * Sanitize |  147  * Sanitize | 
|  173  */ |  148  */ | 
|  174  |  149  | 
|  175 #ifndef HB_DEBUG_SANITIZE |  150 #ifndef HB_DEBUG_SANITIZE | 
|  176 #define HB_DEBUG_SANITIZE (HB_DEBUG+0) |  151 #define HB_DEBUG_SANITIZE (HB_DEBUG+0) | 
|  177 #endif |  152 #endif | 
|  178  |  153  | 
|  179  |  154  | 
|  180 #define TRACE_SANITIZE() \ |  155 #define TRACE_SANITIZE() \ | 
|  181 »       hb_trace_t<HB_DEBUG_SANITIZE> trace (&c->debug_depth, "SANITIZE", HB_FUN
     C, this); \ |  156 »       hb_auto_trace_t<HB_DEBUG_SANITIZE> trace (&c->debug_depth, "SANITIZE", t
     his, NULL, HB_FUNC); | 
|  182  |  157  | 
|  183  |  158  | 
|  184 struct hb_sanitize_context_t |  159 struct hb_sanitize_context_t | 
|  185 { |  160 { | 
|  186   inline void init (hb_blob_t *blob) |  161   inline void init (hb_blob_t *b) | 
|  187   { |  162   { | 
|  188     this->blob = hb_blob_reference (blob); |  163     this->blob = hb_blob_reference (b); | 
|  189     this->start = hb_blob_lock (blob); |  164     this->writable = false; | 
|  190     this->end = this->start + hb_blob_get_length (blob); |  165   } | 
|  191     this->writable = hb_blob_is_writable (blob); |  166  | 
 |  167   inline void setup (void) | 
 |  168   { | 
 |  169     this->start = hb_blob_get_data (this->blob, NULL); | 
 |  170     this->end = this->start + hb_blob_get_length (this->blob); | 
|  192     this->edit_count = 0; |  171     this->edit_count = 0; | 
|  193     this->debug_depth = 0; |  172     this->debug_depth = 0; | 
|  194  |  173  | 
|  195     (void) (HB_DEBUG_SANITIZE && |  174     DEBUG_MSG (SANITIZE, this->blob, | 
|  196       fprintf (stderr, "sanitize %p init [%p..%p] (%lu bytes)\n", |  175 »              "init [%p..%p] (%lu bytes)", | 
|  197 »              this->blob, this->start, this->end, |  176 »              this->start, this->end, | 
|  198 »              (unsigned long) (this->end - this->start))); |  177 »              (unsigned long) (this->end - this->start)); | 
|  199   } |  178   } | 
|  200  |  179  | 
|  201   inline void finish (void) |  180   inline void finish (void) | 
|  202   { |  181   { | 
|  203     (void) (HB_DEBUG_SANITIZE && |  182     DEBUG_MSG (SANITIZE, this->blob, | 
|  204       fprintf (stderr, "sanitize %p fini [%p..%p] %u edit requests\n", |  183 »              "fini [%p..%p] %u edit requests", | 
|  205 »              this->blob, this->start, this->end, this->edit_count)); |  184 »              this->start, this->end, this->edit_count); | 
|  206  |  185  | 
|  207     hb_blob_unlock (this->blob); |  | 
|  208     hb_blob_destroy (this->blob); |  186     hb_blob_destroy (this->blob); | 
|  209     this->blob = NULL; |  187     this->blob = NULL; | 
|  210     this->start = this->end = NULL; |  188     this->start = this->end = NULL; | 
|  211   } |  189   } | 
|  212  |  190  | 
|  213   inline bool check_range (const void *base, unsigned int len) const |  191   inline bool check_range (const void *base, unsigned int len) const | 
|  214   { |  192   { | 
|  215     const char *p = (const char *) base; |  193     const char *p = (const char *) base; | 
|  216     bool ret = this->start <= p && |  194     bool ret = this->start <= p && | 
|  217                p <= this->end && |  195                p <= this->end && | 
|  218                (unsigned int) (this->end - p) >= len; |  196                (unsigned int) (this->end - p) >= len; | 
|  219  |  197  | 
|  220     (void) (HB_DEBUG_SANITIZE && (int) this->debug_depth < (int) HB_DEBUG_SANITI
     ZE && |  198     DEBUG_MSG_LEVEL (SANITIZE, this->blob, this->debug_depth, | 
|  221       fprintf (stderr, "SANITIZE(%p) %-*d-> range [%p..%p] (%d bytes) in [%p..%p
     ] -> %s\n", |  199 »       »            "%-*d-> range [%p..%p] (%d bytes) in [%p..%p] -> %s", | 
|  222 »              p, |  200 »       »            this->debug_depth, this->debug_depth, | 
|  223 »              this->debug_depth, this->debug_depth, |  201 »       »            p, p + len, len, | 
|  224 »              p, p + len, len, |  202 »       »            this->start, this->end, | 
|  225 »              this->start, this->end, |  203 »       »            ret ? "pass" : "FAIL"); | 
|  226 »              ret ? "pass" : "FAIL")); |  | 
|  227  |  204  | 
|  228     return likely (ret); |  205     return likely (ret); | 
|  229   } |  206   } | 
|  230  |  207  | 
|  231   inline bool check_array (const void *base, unsigned int record_size, unsigned 
     int len) const |  208   inline bool check_array (const void *base, unsigned int record_size, unsigned 
     int len) const | 
|  232   { |  209   { | 
|  233     const char *p = (const char *) base; |  210     const char *p = (const char *) base; | 
|  234     bool overflows = record_size > 0 && len >= ((unsigned int) -1) / record_size
     ; |  211     bool overflows = _hb_unsigned_int_mul_overflows (len, record_size); | 
|  235  |  212  | 
|  236     (void) (HB_DEBUG_SANITIZE && (int) this->debug_depth < (int) HB_DEBUG_SANITI
     ZE && |  213     DEBUG_MSG_LEVEL (SANITIZE, this->blob, this->debug_depth, | 
|  237       fprintf (stderr, "SANITIZE(%p) %-*d-> array [%p..%p] (%d*%d=%ld bytes) in 
     [%p..%p] -> %s\n", |  214 »       »            "%-*d-> array [%p..%p] (%d*%d=%ld bytes) in [%p..%p] -> %s"
     , | 
|  238 »              p, |  215 »       »            this->debug_depth, this->debug_depth, | 
|  239 »              this->debug_depth, this->debug_depth, |  216 »       »            p, p + (record_size * len), record_size, len, (unsigned lon
     g) record_size * len, | 
|  240 »              p, p + (record_size * len), record_size, len, (unsigned long) rec
     ord_size * len, |  217 »       »            this->start, this->end, | 
|  241 »              this->start, this->end, |  218 »       »            !overflows ? "does not overflow" : "OVERFLOWS FAIL"); | 
|  242 »              !overflows ? "does not overflow" : "OVERFLOWS FAIL")); |  | 
|  243  |  219  | 
|  244     return likely (!overflows && this->check_range (base, record_size * len)); |  220     return likely (!overflows && this->check_range (base, record_size * len)); | 
|  245   } |  221   } | 
|  246  |  222  | 
|  247   template <typename Type> |  223   template <typename Type> | 
|  248   inline bool check_struct (const Type *obj) const |  224   inline bool check_struct (const Type *obj) const | 
|  249   { |  225   { | 
|  250     return likely (this->check_range (obj, obj->min_size)); |  226     return likely (this->check_range (obj, obj->min_size)); | 
|  251   } |  227   } | 
|  252  |  228  | 
|  253   inline bool can_edit (const void *base HB_UNUSED, unsigned int len HB_UNUSED) |  229   inline bool can_edit (const void *base HB_UNUSED, unsigned int len HB_UNUSED) | 
|  254   { |  230   { | 
|  255     const char *p = (const char *) base; |  231     const char *p = (const char *) base; | 
|  256     this->edit_count++; |  232     this->edit_count++; | 
|  257  |  233  | 
|  258     (void) (HB_DEBUG_SANITIZE && (int) this->debug_depth < (int) HB_DEBUG_SANITI
     ZE && |  234     DEBUG_MSG_LEVEL (SANITIZE, this->blob, this->debug_depth, | 
|  259       fprintf (stderr, "SANITIZE(%p) %-*d-> edit(%u) [%p..%p] (%d bytes) in [%p.
     .%p] -> %s\n", |  235 »       »            "%-*d-> edit(%u) [%p..%p] (%d bytes) in [%p..%p] -> %s", | 
|  260 »              p, |  236 »       »            this->debug_depth, this->debug_depth, | 
|  261 »              this->debug_depth, this->debug_depth, |  237 »       »            this->edit_count, | 
|  262 »              this->edit_count, |  238 »       »            p, p + len, len, | 
|  263 »              p, p + len, len, |  239 »       »            this->start, this->end, | 
|  264 »              this->start, this->end, |  240 »       »            this->writable ? "granted" : "REJECTED"); | 
|  265 »              this->writable ? "granted" : "REJECTED")); |  | 
|  266  |  241  | 
|  267     return this->writable; |  242     return this->writable; | 
|  268   } |  243   } | 
|  269  |  244  | 
|  270   unsigned int debug_depth; |  245   unsigned int debug_depth; | 
|  271   const char *start, *end; |  246   const char *start, *end; | 
|  272   bool writable; |  247   bool writable; | 
|  273   unsigned int edit_count; |  248   unsigned int edit_count; | 
|  274   hb_blob_t *blob; |  249   hb_blob_t *blob; | 
|  275 }; |  250 }; | 
|  276  |  251  | 
|  277  |  252  | 
|  278  |  253  | 
|  279 /* Template to sanitize an object. */ |  254 /* Template to sanitize an object. */ | 
|  280 template <typename Type> |  255 template <typename Type> | 
|  281 struct Sanitizer |  256 struct Sanitizer | 
|  282 { |  257 { | 
|  283   static hb_blob_t *sanitize (hb_blob_t *blob) { |  258   static hb_blob_t *sanitize (hb_blob_t *blob) { | 
|  284     hb_sanitize_context_t c[1] = {{0}}; |  259     hb_sanitize_context_t c[1] = {{0}}; | 
|  285     bool sane; |  260     bool sane; | 
|  286  |  261  | 
|  287     /* TODO is_sane() stuff */ |  262     /* TODO is_sane() stuff */ | 
|  288  |  263  | 
|  289     if (!blob) |  264     c->init (blob); | 
|  290       return hb_blob_create_empty (); |  | 
|  291  |  265  | 
|  292   retry: |  266   retry: | 
|  293     (void) (HB_DEBUG_SANITIZE && |  267     DEBUG_MSG_FUNC (SANITIZE, blob, "start"); | 
|  294       fprintf (stderr, "Sanitizer %p start %s\n", blob, HB_FUNC)); |  | 
|  295  |  268  | 
|  296     c->init (blob); |  269     c->setup (); | 
|  297  |  270  | 
|  298     if (unlikely (!c->start)) { |  271     if (unlikely (!c->start)) { | 
|  299       c->finish (); |  272       c->finish (); | 
|  300       return blob; |  273       return blob; | 
|  301     } |  274     } | 
|  302  |  275  | 
|  303     Type *t = CastP<Type> (const_cast<char *> (c->start)); |  276     Type *t = CastP<Type> (const_cast<char *> (c->start)); | 
|  304  |  277  | 
|  305     sane = t->sanitize (c); |  278     sane = t->sanitize (c); | 
|  306     if (sane) { |  279     if (sane) { | 
|  307       if (c->edit_count) { |  280       if (c->edit_count) { | 
|  308 »       (void) (HB_DEBUG_SANITIZE && |  281 »       DEBUG_MSG_FUNC (SANITIZE, blob, "passed first round with %d edits; going
      for second round", c->edit_count); | 
|  309 »         fprintf (stderr, "Sanitizer %p passed first round with %d edits; doing
      a second round %s\n", |  | 
|  310 »       »          blob, c->edit_count, HB_FUNC)); |  | 
|  311  |  282  | 
|  312         /* sanitize again to ensure no toe-stepping */ |  283         /* sanitize again to ensure no toe-stepping */ | 
|  313         c->edit_count = 0; |  284         c->edit_count = 0; | 
|  314         sane = t->sanitize (c); |  285         sane = t->sanitize (c); | 
|  315         if (c->edit_count) { |  286         if (c->edit_count) { | 
|  316 »         (void) (HB_DEBUG_SANITIZE && |  287 »         DEBUG_MSG_FUNC (SANITIZE, blob, "requested %d edits in second round; F
     AILLING", c->edit_count); | 
|  317 »           fprintf (stderr, "Sanitizer %p requested %d edits in second round; F
     AILLING %s\n", |  | 
|  318 »       »            blob, c->edit_count, HB_FUNC)); |  | 
|  319           sane = false; |  288           sane = false; | 
|  320         } |  289         } | 
|  321       } |  290       } | 
|  322       c->finish (); |  | 
|  323     } else { |  291     } else { | 
|  324       unsigned int edit_count = c->edit_count; |  292       unsigned int edit_count = c->edit_count; | 
|  325       c->finish (); |  293       if (edit_count && !c->writable) { | 
|  326       if (edit_count && !hb_blob_is_writable (blob) && hb_blob_try_writable (blo
     b)) { |  294         c->start = hb_blob_get_data_writable (blob, NULL); | 
|  327         /* ok, we made it writable by relocating.  try again */ |  295 »       c->end = c->start + hb_blob_get_length (blob); | 
|  328 »       (void) (HB_DEBUG_SANITIZE && |  296  | 
|  329 »         fprintf (stderr, "Sanitizer %p retry %s\n", blob, HB_FUNC)); |  297 »       if (c->start) { | 
|  330         goto retry; |  298 »         c->writable = true; | 
 |  299 »         /* ok, we made it writable by relocating.  try again */ | 
 |  300 »         DEBUG_MSG_FUNC (SANITIZE, blob, "retry"); | 
 |  301 »         goto retry; | 
 |  302 »       } | 
|  331       } |  303       } | 
|  332     } |  304     } | 
|  333  |  305  | 
|  334     (void) (HB_DEBUG_SANITIZE && |  306     c->finish (); | 
|  335       fprintf (stderr, "Sanitizer %p %s %s\n", blob, sane ? "passed" : "FAILED",
      HB_FUNC)); |  307  | 
 |  308     DEBUG_MSG_FUNC (SANITIZE, blob, sane ? "PASSED" : "FAILED"); | 
|  336     if (sane) |  309     if (sane) | 
|  337       return blob; |  310       return blob; | 
|  338     else { |  311     else { | 
|  339       hb_blob_destroy (blob); |  312       hb_blob_destroy (blob); | 
|  340       return hb_blob_create_empty (); |  313       return hb_blob_get_empty (); | 
|  341     } |  314     } | 
|  342   } |  315   } | 
|  343  |  316  | 
|  344   static const Type* lock_instance (hb_blob_t *blob) { |  317   static const Type* lock_instance (hb_blob_t *blob) { | 
|  345     const char *base = hb_blob_lock (blob); |  318     hb_blob_make_immutable (blob); | 
 |  319     const char *base = hb_blob_get_data (blob, NULL); | 
|  346     return unlikely (!base) ? &Null(Type) : CastP<Type> (base); |  320     return unlikely (!base) ? &Null(Type) : CastP<Type> (base); | 
|  347   } |  321   } | 
|  348 }; |  322 }; | 
|  349  |  323  | 
|  350  |  324  | 
|  351  |  325  | 
|  352  |  326  | 
|  353 /* |  327 /* | 
|  354  * |  328  * | 
|  355  * The OpenType Font File: Data Types |  329  * The OpenType Font File: Data Types | 
|  356  */ |  330  */ | 
|  357  |  331  | 
|  358  |  332  | 
|  359 /* "The following data types are used in the OpenType font file. |  333 /* "The following data types are used in the OpenType font file. | 
|  360  *  All OpenType fonts use Motorola-style byte ordering (Big Endian):" */ |  334  *  All OpenType fonts use Motorola-style byte ordering (Big Endian):" */ | 
|  361  |  335  | 
|  362 /* |  336 /* | 
|  363  * Int types |  337  * Int types | 
|  364  */ |  338  */ | 
|  365  |  339  | 
|  366  |  340  | 
|  367 template <typename Type, int Bytes> class BEInt; |  341 template <typename Type, int Bytes> struct BEInt; | 
|  368  |  342  | 
|  369 /* LONGTERMTODO: On machines allowing unaligned access, we can make the |  343 /* LONGTERMTODO: On machines allowing unaligned access, we can make the | 
|  370  * following tighter by using byteswap instructions on ints directly. */ |  344  * following tighter by using byteswap instructions on ints directly. */ | 
|  371 template <typename Type> |  345 template <typename Type> | 
|  372 class BEInt<Type, 2> |  346 struct BEInt<Type, 2> | 
|  373 { |  347 { | 
|  374   public: |  348   public: | 
|  375   inline void set (Type i) { hb_be_uint16_put (v,i); } |  349   inline void set (Type i) { hb_be_uint16_put (v,i); } | 
|  376   inline operator Type (void) const { return hb_be_uint16_get (v); } |  350   inline operator Type (void) const { return hb_be_uint16_get (v); } | 
|  377   inline bool operator == (const BEInt<Type, 2>& o) const { return hb_be_uint16_
     cmp (v, o.v); } |  351   inline bool operator == (const BEInt<Type, 2>& o) const { return hb_be_uint16_
     eq (v, o.v); } | 
|  378   inline bool operator != (const BEInt<Type, 2>& o) const { return !(*this == o)
     ; } |  352   inline bool operator != (const BEInt<Type, 2>& o) const { return !(*this == o)
     ; } | 
|  379   private: uint8_t v[2]; |  353   private: uint8_t v[2]; | 
|  380 }; |  354 }; | 
|  381 template <typename Type> |  355 template <typename Type> | 
|  382 class BEInt<Type, 4> |  356 struct BEInt<Type, 4> | 
|  383 { |  357 { | 
|  384   public: |  358   public: | 
|  385   inline void set (Type i) { hb_be_uint32_put (v,i); } |  359   inline void set (Type i) { hb_be_uint32_put (v,i); } | 
|  386   inline operator Type (void) const { return hb_be_uint32_get (v); } |  360   inline operator Type (void) const { return hb_be_uint32_get (v); } | 
|  387   inline bool operator == (const BEInt<Type, 4>& o) const { return hb_be_uint32_
     cmp (v, o.v); } |  361   inline bool operator == (const BEInt<Type, 4>& o) const { return hb_be_uint32_
     eq (v, o.v); } | 
|  388   inline bool operator != (const BEInt<Type, 4>& o) const { return !(*this == o)
     ; } |  362   inline bool operator != (const BEInt<Type, 4>& o) const { return !(*this == o)
     ; } | 
|  389   private: uint8_t v[4]; |  363   private: uint8_t v[4]; | 
|  390 }; |  364 }; | 
|  391  |  365  | 
|  392 /* Integer types in big-endian order and no alignment requirement */ |  366 /* Integer types in big-endian order and no alignment requirement */ | 
|  393 template <typename Type> |  367 template <typename Type> | 
|  394 struct IntType |  368 struct IntType | 
|  395 { |  369 { | 
|  396   inline void set (Type i) { v.set (i); } |  370   inline void set (Type i) { v.set (i); } | 
|  397   inline operator Type(void) const { return v; } |  371   inline operator Type(void) const { return v; } | 
|  398   inline bool operator == (const IntType<Type> &o) const { return v == o.v; } |  372   inline bool operator == (const IntType<Type> &o) const { return v == o.v; } | 
|  399   inline bool operator != (const IntType<Type> &o) const { return v != o.v; } |  373   inline bool operator != (const IntType<Type> &o) const { return v != o.v; } | 
|  400   inline int cmp (Type a) const { Type b = v; return a < b ? -1 : a == b ? 0 : +
     1; } |  374   inline int cmp (Type a) const { Type b = v; return a < b ? -1 : a == b ? 0 : +
     1; } | 
|  401   inline bool sanitize (hb_sanitize_context_t *c) { |  375   inline bool sanitize (hb_sanitize_context_t *c) { | 
|  402     TRACE_SANITIZE (); |  376     TRACE_SANITIZE (); | 
|  403     return likely (c->check_struct (this)); |  377     return likely (c->check_struct (this)); | 
|  404   } |  378   } | 
|  405   protected: |  379   protected: | 
|  406   BEInt<Type, sizeof (Type)> v; |  380   BEInt<Type, sizeof (Type)> v; | 
|  407   public: |  381   public: | 
|  408   DEFINE_SIZE_STATIC (sizeof (Type)); |  382   DEFINE_SIZE_STATIC (sizeof (Type)); | 
|  409 }; |  383 }; | 
|  410  |  384  | 
 |  385 /* Typedef these to avoid clash with windows.h */ | 
 |  386 #define USHORT  HB_USHORT | 
 |  387 #define SHORT   HB_SHORT | 
 |  388 #define ULONG   HB_ULONG | 
 |  389 #define LONG    HB_LONG | 
|  411 typedef IntType<uint16_t> USHORT;       /* 16-bit unsigned integer. */ |  390 typedef IntType<uint16_t> USHORT;       /* 16-bit unsigned integer. */ | 
|  412 typedef IntType<int16_t>  SHORT;        /* 16-bit signed integer. */ |  391 typedef IntType<int16_t>  SHORT;        /* 16-bit signed integer. */ | 
|  413 typedef IntType<uint32_t> ULONG;        /* 32-bit unsigned integer. */ |  392 typedef IntType<uint32_t> ULONG;        /* 32-bit unsigned integer. */ | 
|  414 typedef IntType<int32_t>  LONG;         /* 32-bit signed integer. */ |  393 typedef IntType<int32_t>  LONG;         /* 32-bit signed integer. */ | 
|  415  |  394  | 
 |  395 /* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */ | 
 |  396 typedef SHORT FWORD; | 
 |  397  | 
 |  398 /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */ | 
 |  399 typedef USHORT UFWORD; | 
 |  400  | 
|  416 /* Date represented in number of seconds since 12:00 midnight, January 1, |  401 /* Date represented in number of seconds since 12:00 midnight, January 1, | 
|  417  * 1904. The value is represented as a signed 64-bit integer. */ |  402  * 1904. The value is represented as a signed 64-bit integer. */ | 
|  418 struct LONGDATETIME |  403 struct LONGDATETIME | 
|  419 { |  404 { | 
|  420   inline bool sanitize (hb_sanitize_context_t *c) { |  405   inline bool sanitize (hb_sanitize_context_t *c) { | 
|  421     TRACE_SANITIZE (); |  406     TRACE_SANITIZE (); | 
|  422     return likely (c->check_struct (this)); |  407     return likely (c->check_struct (this)); | 
|  423   } |  408   } | 
|  424   private: |  409   private: | 
|  425   LONG major; |  410   LONG major; | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  472   DEFINE_SIZE_STATIC (4); |  457   DEFINE_SIZE_STATIC (4); | 
|  473 }; |  458 }; | 
|  474  |  459  | 
|  475  |  460  | 
|  476 /* |  461 /* | 
|  477  * Version Numbers |  462  * Version Numbers | 
|  478  */ |  463  */ | 
|  479  |  464  | 
|  480 struct FixedVersion |  465 struct FixedVersion | 
|  481 { |  466 { | 
|  482   inline operator uint32_t (void) const { return (major << 16) + minor; } |  467   inline uint32_t to_int (void) const { return (major << 16) + minor; } | 
|  483  |  468  | 
|  484   inline bool sanitize (hb_sanitize_context_t *c) { |  469   inline bool sanitize (hb_sanitize_context_t *c) { | 
|  485     TRACE_SANITIZE (); |  470     TRACE_SANITIZE (); | 
|  486     return c->check_struct (this); |  471     return c->check_struct (this); | 
|  487   } |  472   } | 
|  488  |  473  | 
|  489   USHORT major; |  474   USHORT major; | 
|  490   USHORT minor; |  475   USHORT minor; | 
|  491   public: |  476   public: | 
|  492   DEFINE_SIZE_STATIC (4); |  477   DEFINE_SIZE_STATIC (4); | 
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  705   DEFINE_SIZE_ARRAY (sizeof (USHORT), array); |  690   DEFINE_SIZE_ARRAY (sizeof (USHORT), array); | 
|  706 }; |  691 }; | 
|  707  |  692  | 
|  708  |  693  | 
|  709 /* An array with sorted elements.  Supports binary searching. */ |  694 /* An array with sorted elements.  Supports binary searching. */ | 
|  710 template <typename Type> |  695 template <typename Type> | 
|  711 struct SortedArrayOf : ArrayOf<Type> { |  696 struct SortedArrayOf : ArrayOf<Type> { | 
|  712  |  697  | 
|  713   template <typename SearchType> |  698   template <typename SearchType> | 
|  714   inline int search (const SearchType &x) const { |  699   inline int search (const SearchType &x) const { | 
|  715     class Cmp { |  700     struct Cmp { | 
|  716       public: static int cmp (const SearchType *a, const Type *b) { return b->cm
     p (*a); } |  701       static int cmp (const SearchType *a, const Type *b) { return b->cmp (*a); 
     } | 
|  717     }; |  702     }; | 
|  718     const Type *p = (const Type *) bsearch (&x, this->array, this->len, sizeof (
     this->array[0]), (hb_compare_func_t) Cmp::cmp); |  703     const Type *p = (const Type *) bsearch (&x, this->array, this->len, sizeof (
     this->array[0]), (hb_compare_func_t) Cmp::cmp); | 
|  719     return p ? p - this->array : -1; |  704     return p ? p - this->array : -1; | 
|  720   } |  705   } | 
|  721 }; |  706 }; | 
|  722  |  707  | 
|  723  |  708  | 
|  724 HB_BEGIN_DECLS |  | 
|  725 HB_END_DECLS |  | 
|  726  |  709  | 
|  727 #endif /* HB_OPEN_TYPE_PRIVATE_HH */ |  710 #endif /* HB_OPEN_TYPE_PRIVATE_HH */ | 
| OLD | NEW |