LCOV - code coverage report
Current view: directory - gfx/harfbuzz/src - hb-ot-layout-common-private.hh (source / functions) Found Hit Coverage
Test: app.info Lines: 178 0 0.0 %
Date: 2012-06-02 Functions: 56 0 0.0 %

       1                 : /*
       2                 :  * Copyright © 2007,2008,2009  Red Hat, Inc.
       3                 :  * Copyright © 2010  Google, Inc.
       4                 :  *
       5                 :  *  This is part of HarfBuzz, a text shaping library.
       6                 :  *
       7                 :  * Permission is hereby granted, without written agreement and without
       8                 :  * license or royalty fees, to use, copy, modify, and distribute this
       9                 :  * software and its documentation for any purpose, provided that the
      10                 :  * above copyright notice and the following two paragraphs appear in
      11                 :  * all copies of this software.
      12                 :  *
      13                 :  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
      14                 :  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
      15                 :  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
      16                 :  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
      17                 :  * DAMAGE.
      18                 :  *
      19                 :  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
      20                 :  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
      21                 :  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
      22                 :  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
      23                 :  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
      24                 :  *
      25                 :  * Red Hat Author(s): Behdad Esfahbod
      26                 :  * Google Author(s): Behdad Esfahbod
      27                 :  */
      28                 : 
      29                 : #ifndef HB_OT_LAYOUT_COMMON_PRIVATE_HH
      30                 : #define HB_OT_LAYOUT_COMMON_PRIVATE_HH
      31                 : 
      32                 : #include "hb-ot-layout-private.hh"
      33                 : 
      34                 : #include "hb-open-type-private.hh"
      35                 : 
      36                 : 
      37                 : #define NO_CONTEXT              ((unsigned int) 0x110000)
      38                 : #define NOT_COVERED             ((unsigned int) 0x110000)
      39                 : #define MAX_NESTING_LEVEL       8
      40                 : 
      41                 : 
      42                 : 
      43                 : /*
      44                 :  *
      45                 :  * OpenType Layout Common Table Formats
      46                 :  *
      47                 :  */
      48                 : 
      49                 : 
      50                 : /*
      51                 :  * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList
      52                 :  */
      53                 : 
      54                 : template <typename Type>
      55                 : struct Record
      56                 : {
      57               0 :   inline int cmp (hb_tag_t a) const {
      58               0 :     return tag.cmp (a);
      59                 :   }
      60                 : 
      61               0 :   inline bool sanitize (hb_sanitize_context_t *c, void *base) {
      62               0 :     TRACE_SANITIZE ();
      63                 :     return c->check_struct (this)
      64               0 :         && offset.sanitize (c, base);
      65                 :   }
      66                 : 
      67                 :   Tag           tag;            /* 4-byte Tag identifier */
      68                 :   OffsetTo<Type>
      69                 :                 offset;         /* Offset from beginning of object holding
      70                 :                                  * the Record */
      71                 :   public:
      72                 :   DEFINE_SIZE_STATIC (6);
      73                 : };
      74                 : 
      75                 : template <typename Type>
      76                 : struct RecordArrayOf : SortedArrayOf<Record<Type> > {
      77               0 :   inline const Tag& get_tag (unsigned int i) const
      78                 :   {
      79                 :     /* We cheat slightly and don't define separate Null objects
      80                 :      * for Record types.  Instead, we return the correct Null(Tag)
      81                 :      * here. */
      82               0 :     if (unlikely (i >= this->len)) return Null(Tag);
      83               0 :     return (*this)[i].tag;
      84                 :   }
      85               0 :   inline unsigned int get_tags (unsigned int start_offset,
      86                 :                                 unsigned int *record_count /* IN/OUT */,
      87                 :                                 hb_tag_t     *record_tags /* OUT */) const
      88                 :   {
      89               0 :     if (record_count) {
      90               0 :       const Record<Type> *arr = this->sub_array (start_offset, record_count);
      91               0 :       unsigned int count = *record_count;
      92               0 :       for (unsigned int i = 0; i < count; i++)
      93               0 :         record_tags[i] = arr[i].tag;
      94                 :     }
      95               0 :     return this->len;
      96                 :   }
      97               0 :   inline bool find_index (hb_tag_t tag, unsigned int *index) const
      98                 :   {
      99               0 :     int i = this->search (tag);
     100               0 :     if (i != -1) {
     101               0 :         if (index) *index = i;
     102               0 :         return true;
     103                 :     } else {
     104               0 :       if (index) *index = Index::NOT_FOUND_INDEX;
     105               0 :       return false;
     106                 :     }
     107                 :   }
     108                 : };
     109                 : 
     110                 : template <typename Type>
     111                 : struct RecordListOf : RecordArrayOf<Type>
     112                 : {
     113               0 :   inline const Type& operator [] (unsigned int i) const
     114               0 :   { return this+RecordArrayOf<Type>::operator [](i).offset; }
     115                 : 
     116               0 :   inline bool sanitize (hb_sanitize_context_t *c) {
     117               0 :     TRACE_SANITIZE ();
     118               0 :     return RecordArrayOf<Type>::sanitize (c, this);
     119                 :   }
     120                 : };
     121                 : 
     122                 : 
     123                 : struct RangeRecord
     124                 : {
     125               0 :   inline int cmp (hb_codepoint_t g) const {
     126               0 :     hb_codepoint_t a = start, b = end;
     127               0 :     return g < a ? -1 : g <= b ? 0 : +1 ;
     128                 :   }
     129                 : 
     130                 :   inline bool sanitize (hb_sanitize_context_t *c) {
     131                 :     TRACE_SANITIZE ();
     132                 :     return c->check_struct (this);
     133                 :   }
     134                 : 
     135                 :   GlyphID       start;          /* First GlyphID in the range */
     136                 :   GlyphID       end;            /* Last GlyphID in the range */
     137                 :   USHORT        value;          /* Value */
     138                 :   public:
     139                 :   DEFINE_SIZE_STATIC (6);
     140                 : };
     141               0 : DEFINE_NULL_DATA (RangeRecord, "\000\001");
     142                 : 
     143                 : 
     144                 : struct IndexArray : ArrayOf<Index>
     145                 : {
     146               0 :   inline unsigned int get_indexes (unsigned int start_offset,
     147                 :                                    unsigned int *_count /* IN/OUT */,
     148                 :                                    unsigned int *_indexes /* OUT */) const
     149                 :   {
     150               0 :     if (_count) {
     151               0 :       const USHORT *arr = this->sub_array (start_offset, _count);
     152               0 :       unsigned int count = *_count;
     153               0 :       for (unsigned int i = 0; i < count; i++)
     154               0 :         _indexes[i] = arr[i];
     155                 :     }
     156               0 :     return this->len;
     157                 :   }
     158                 : };
     159                 : 
     160                 : 
     161                 : struct Script;
     162                 : struct LangSys;
     163                 : struct Feature;
     164                 : 
     165                 : 
     166                 : struct LangSys
     167                 : {
     168               0 :   inline unsigned int get_feature_count (void) const
     169               0 :   { return featureIndex.len; }
     170               0 :   inline hb_tag_t get_feature_index (unsigned int i) const
     171               0 :   { return featureIndex[i]; }
     172               0 :   inline unsigned int get_feature_indexes (unsigned int start_offset,
     173                 :                                            unsigned int *feature_count /* IN/OUT */,
     174                 :                                            unsigned int *feature_indexes /* OUT */) const
     175               0 :   { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); }
     176                 : 
     177               0 :   inline bool has_required_feature (void) const { return reqFeatureIndex != 0xffff; }
     178               0 :   inline unsigned int get_required_feature_index (void) const
     179                 :   {
     180               0 :     if (reqFeatureIndex == 0xffff)
     181               0 :       return Index::NOT_FOUND_INDEX;
     182               0 :    return reqFeatureIndex;;
     183                 :   }
     184                 : 
     185               0 :   inline bool sanitize (hb_sanitize_context_t *c) {
     186               0 :     TRACE_SANITIZE ();
     187               0 :     return c->check_struct (this)
     188               0 :         && featureIndex.sanitize (c);
     189                 :   }
     190                 : 
     191                 :   Offset        lookupOrder;    /* = Null (reserved for an offset to a
     192                 :                                  * reordering table) */
     193                 :   USHORT        reqFeatureIndex;/* Index of a feature required for this
     194                 :                                  * language system--if no required features
     195                 :                                  * = 0xFFFF */
     196                 :   IndexArray    featureIndex;   /* Array of indices into the FeatureList */
     197                 :   public:
     198                 :   DEFINE_SIZE_ARRAY (6, featureIndex);
     199                 : };
     200               0 : DEFINE_NULL_DATA (LangSys, "\0\0\xFF\xFF");
     201                 : 
     202                 : 
     203                 : struct Script
     204                 : {
     205                 :   inline unsigned int get_lang_sys_count (void) const
     206                 :   { return langSys.len; }
     207                 :   inline const Tag& get_lang_sys_tag (unsigned int i) const
     208                 :   { return langSys.get_tag (i); }
     209               0 :   inline unsigned int get_lang_sys_tags (unsigned int start_offset,
     210                 :                                          unsigned int *lang_sys_count /* IN/OUT */,
     211                 :                                          hb_tag_t     *lang_sys_tags /* OUT */) const
     212               0 :   { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); }
     213               0 :   inline const LangSys& get_lang_sys (unsigned int i) const
     214                 :   {
     215               0 :     if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys ();
     216               0 :     return this+langSys[i].offset;
     217                 :   }
     218               0 :   inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
     219               0 :   { return langSys.find_index (tag, index); }
     220                 : 
     221                 :   inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; }
     222               0 :   inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
     223                 : 
     224               0 :   inline bool sanitize (hb_sanitize_context_t *c) {
     225               0 :     TRACE_SANITIZE ();
     226               0 :     return defaultLangSys.sanitize (c, this)
     227               0 :         && langSys.sanitize (c, this);
     228                 :   }
     229                 : 
     230                 :   private:
     231                 :   OffsetTo<LangSys>
     232                 :                 defaultLangSys; /* Offset to DefaultLangSys table--from
     233                 :                                  * beginning of Script table--may be Null */
     234                 :   RecordArrayOf<LangSys>
     235                 :                 langSys;        /* Array of LangSysRecords--listed
     236                 :                                  * alphabetically by LangSysTag */
     237                 :   public:
     238                 :   DEFINE_SIZE_ARRAY (4, langSys);
     239                 : };
     240                 : 
     241                 : typedef RecordListOf<Script> ScriptList;
     242                 : 
     243                 : 
     244                 : struct Feature
     245                 : {
     246                 :   inline unsigned int get_lookup_count (void) const
     247                 :   { return lookupIndex.len; }
     248                 :   inline hb_tag_t get_lookup_index (unsigned int i) const
     249                 :   { return lookupIndex[i]; }
     250               0 :   inline unsigned int get_lookup_indexes (unsigned int start_index,
     251                 :                                           unsigned int *lookup_count /* IN/OUT */,
     252                 :                                           unsigned int *lookup_tags /* OUT */) const
     253               0 :   { return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); }
     254                 : 
     255               0 :   inline bool sanitize (hb_sanitize_context_t *c) {
     256               0 :     TRACE_SANITIZE ();
     257               0 :     return c->check_struct (this)
     258               0 :         && lookupIndex.sanitize (c);
     259                 :   }
     260                 : 
     261                 :   Offset        featureParams;  /* Offset to Feature Parameters table (if one
     262                 :                                  * has been defined for the feature), relative
     263                 :                                  * to the beginning of the Feature Table; = Null
     264                 :                                  * if not required */
     265                 :   IndexArray     lookupIndex;   /* Array of LookupList indices */
     266                 :   public:
     267                 :   DEFINE_SIZE_ARRAY (4, lookupIndex);
     268                 : };
     269                 : 
     270                 : typedef RecordListOf<Feature> FeatureList;
     271                 : 
     272                 : 
     273                 : struct LookupFlag : USHORT
     274                 : {
     275                 :   enum {
     276                 :     RightToLeft         = 0x0001u,
     277                 :     IgnoreBaseGlyphs    = 0x0002u,
     278                 :     IgnoreLigatures     = 0x0004u,
     279                 :     IgnoreMarks         = 0x0008u,
     280                 :     IgnoreFlags         = 0x000Eu,
     281                 :     UseMarkFilteringSet = 0x0010u,
     282                 :     Reserved            = 0x00E0u,
     283                 :     MarkAttachmentType  = 0xFF00u
     284                 :   };
     285                 :   public:
     286                 :   DEFINE_SIZE_STATIC (2);
     287                 : };
     288                 : 
     289                 : struct Lookup
     290                 : {
     291               0 :   inline unsigned int get_subtable_count (void) const { return subTable.len; }
     292                 : 
     293               0 :   inline unsigned int get_type (void) const { return lookupType; }
     294                 : 
     295                 :   /* lookup_props is a 32-bit integer where the lower 16-bit is LookupFlag and
     296                 :    * higher 16-bit is mark-filtering-set if the lookup uses one.
     297                 :    * Not to be confused with glyph_props which is very similar. */
     298               0 :   inline uint32_t get_props (void) const
     299                 :   {
     300               0 :     unsigned int flag = lookupFlag;
     301               0 :     if (unlikely (flag & LookupFlag::UseMarkFilteringSet))
     302                 :     {
     303               0 :       const USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
     304               0 :       flag += (markFilteringSet << 16);
     305                 :     }
     306               0 :     return flag;
     307                 :   }
     308                 : 
     309               0 :   inline bool sanitize (hb_sanitize_context_t *c) {
     310               0 :     TRACE_SANITIZE ();
     311                 :     /* Real sanitize of the subtables is done by GSUB/GPOS/... */
     312               0 :     if (!(c->check_struct (this)
     313               0 :        && subTable.sanitize (c))) return false;
     314               0 :     if (unlikely (lookupFlag & LookupFlag::UseMarkFilteringSet))
     315                 :     {
     316               0 :       USHORT &markFilteringSet = StructAfter<USHORT> (subTable);
     317               0 :       if (!markFilteringSet.sanitize (c)) return false;
     318                 :     }
     319               0 :     return true;
     320                 :   }
     321                 : 
     322                 :   USHORT        lookupType;             /* Different enumerations for GSUB and GPOS */
     323                 :   USHORT        lookupFlag;             /* Lookup qualifiers */
     324                 :   ArrayOf<Offset>
     325                 :                 subTable;               /* Array of SubTables */
     326                 :   USHORT        markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets
     327                 :                                          * structure. This field is only present if bit
     328                 :                                          * UseMarkFilteringSet of lookup flags is set. */
     329                 :   public:
     330                 :   DEFINE_SIZE_ARRAY2 (6, subTable, markFilteringSetX);
     331                 : };
     332                 : 
     333                 : typedef OffsetListOf<Lookup> LookupList;
     334                 : 
     335                 : 
     336                 : /*
     337                 :  * Coverage Table
     338                 :  */
     339                 : 
     340                 : struct CoverageFormat1
     341                 : {
     342                 :   friend struct Coverage;
     343                 : 
     344                 :   private:
     345               0 :   inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
     346                 :   {
     347               0 :     int i = glyphArray.search (glyph_id);
     348               0 :     if (i != -1)
     349               0 :         return i;
     350               0 :     return NOT_COVERED;
     351                 :   }
     352                 : 
     353               0 :   inline bool sanitize (hb_sanitize_context_t *c) {
     354               0 :     TRACE_SANITIZE ();
     355               0 :     return glyphArray.sanitize (c);
     356                 :   }
     357                 : 
     358                 :   private:
     359                 :   USHORT        coverageFormat; /* Format identifier--format = 1 */
     360                 :   SortedArrayOf<GlyphID>
     361                 :                 glyphArray;     /* Array of GlyphIDs--in numerical order */
     362                 :   public:
     363                 :   DEFINE_SIZE_ARRAY (4, glyphArray);
     364                 : };
     365                 : 
     366                 : struct CoverageFormat2
     367                 : {
     368                 :   friend struct Coverage;
     369                 : 
     370                 :   private:
     371               0 :   inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
     372                 :   {
     373               0 :     int i = rangeRecord.search (glyph_id);
     374               0 :     if (i != -1) {
     375               0 :       const RangeRecord &range = rangeRecord[i];
     376               0 :       return (unsigned int) range.value + (glyph_id - range.start);
     377                 :     }
     378               0 :     return NOT_COVERED;
     379                 :   }
     380                 : 
     381               0 :   inline bool sanitize (hb_sanitize_context_t *c) {
     382               0 :     TRACE_SANITIZE ();
     383               0 :     return rangeRecord.sanitize (c);
     384                 :   }
     385                 : 
     386                 :   private:
     387                 :   USHORT        coverageFormat; /* Format identifier--format = 2 */
     388                 :   SortedArrayOf<RangeRecord>
     389                 :                 rangeRecord;    /* Array of glyph ranges--ordered by
     390                 :                                  * Start GlyphID. rangeCount entries
     391                 :                                  * long */
     392                 :   public:
     393                 :   DEFINE_SIZE_ARRAY (4, rangeRecord);
     394                 : };
     395                 : 
     396                 : struct Coverage
     397                 : {
     398               0 :   inline unsigned int operator () (hb_codepoint_t glyph_id) const { return get_coverage (glyph_id); }
     399                 : 
     400               0 :   inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
     401                 :   {
     402               0 :     switch (u.format) {
     403               0 :     case 1: return u.format1.get_coverage(glyph_id);
     404               0 :     case 2: return u.format2.get_coverage(glyph_id);
     405               0 :     default:return NOT_COVERED;
     406                 :     }
     407                 :   }
     408                 : 
     409               0 :   inline bool sanitize (hb_sanitize_context_t *c) {
     410               0 :     TRACE_SANITIZE ();
     411               0 :     if (!u.format.sanitize (c)) return false;
     412               0 :     switch (u.format) {
     413               0 :     case 1: return u.format1.sanitize (c);
     414               0 :     case 2: return u.format2.sanitize (c);
     415               0 :     default:return true;
     416                 :     }
     417                 :   }
     418                 : 
     419                 :   private:
     420                 :   union {
     421                 :   USHORT                format;         /* Format identifier */
     422                 :   CoverageFormat1       format1;
     423                 :   CoverageFormat2       format2;
     424                 :   } u;
     425                 :   public:
     426                 :   DEFINE_SIZE_UNION (2, format);
     427                 : };
     428                 : 
     429                 : 
     430                 : /*
     431                 :  * Class Definition Table
     432                 :  */
     433                 : 
     434                 : struct ClassDefFormat1
     435                 : {
     436                 :   friend struct ClassDef;
     437                 : 
     438                 :   private:
     439               0 :   inline unsigned int get_class (hb_codepoint_t glyph_id) const
     440                 :   {
     441               0 :     if ((unsigned int) (glyph_id - startGlyph) < classValue.len)
     442               0 :       return classValue[glyph_id - startGlyph];
     443               0 :     return 0;
     444                 :   }
     445                 : 
     446               0 :   inline bool sanitize (hb_sanitize_context_t *c) {
     447               0 :     TRACE_SANITIZE ();
     448               0 :     return c->check_struct (this)
     449               0 :         && classValue.sanitize (c);
     450                 :   }
     451                 : 
     452                 :   USHORT        classFormat;            /* Format identifier--format = 1 */
     453                 :   GlyphID       startGlyph;             /* First GlyphID of the classValueArray */
     454                 :   ArrayOf<USHORT>
     455                 :                 classValue;             /* Array of Class Values--one per GlyphID */
     456                 :   public:
     457                 :   DEFINE_SIZE_ARRAY (6, classValue);
     458                 : };
     459                 : 
     460                 : struct ClassDefFormat2
     461                 : {
     462                 :   friend struct ClassDef;
     463                 : 
     464                 :   private:
     465               0 :   inline unsigned int get_class (hb_codepoint_t glyph_id) const
     466                 :   {
     467               0 :     int i = rangeRecord.search (glyph_id);
     468               0 :     if (i != -1)
     469               0 :       return rangeRecord[i].value;
     470               0 :     return 0;
     471                 :   }
     472                 : 
     473               0 :   inline bool sanitize (hb_sanitize_context_t *c) {
     474               0 :     TRACE_SANITIZE ();
     475               0 :     return rangeRecord.sanitize (c);
     476                 :   }
     477                 : 
     478                 :   USHORT        classFormat;    /* Format identifier--format = 2 */
     479                 :   SortedArrayOf<RangeRecord>
     480                 :                 rangeRecord;    /* Array of glyph ranges--ordered by
     481                 :                                  * Start GlyphID */
     482                 :   public:
     483                 :   DEFINE_SIZE_ARRAY (4, rangeRecord);
     484                 : };
     485                 : 
     486                 : struct ClassDef
     487                 : {
     488               0 :   inline unsigned int operator () (hb_codepoint_t glyph_id) const { return get_class (glyph_id); }
     489                 : 
     490               0 :   inline unsigned int get_class (hb_codepoint_t glyph_id) const
     491                 :   {
     492               0 :     switch (u.format) {
     493               0 :     case 1: return u.format1.get_class(glyph_id);
     494               0 :     case 2: return u.format2.get_class(glyph_id);
     495               0 :     default:return 0;
     496                 :     }
     497                 :   }
     498                 : 
     499               0 :   inline bool sanitize (hb_sanitize_context_t *c) {
     500               0 :     TRACE_SANITIZE ();
     501               0 :     if (!u.format.sanitize (c)) return false;
     502               0 :     switch (u.format) {
     503               0 :     case 1: return u.format1.sanitize (c);
     504               0 :     case 2: return u.format2.sanitize (c);
     505               0 :     default:return true;
     506                 :     }
     507                 :   }
     508                 : 
     509                 :   private:
     510                 :   union {
     511                 :   USHORT                format;         /* Format identifier */
     512                 :   ClassDefFormat1       format1;
     513                 :   ClassDefFormat2       format2;
     514                 :   } u;
     515                 :   public:
     516                 :   DEFINE_SIZE_UNION (2, format);
     517                 : };
     518                 : 
     519                 : 
     520                 : /*
     521                 :  * Device Tables
     522                 :  */
     523                 : 
     524                 : struct Device
     525                 : {
     526                 : 
     527               0 :   inline hb_position_t get_x_delta (hb_font_t *font) const
     528               0 :   { return get_delta (font->x_ppem, font->x_scale); }
     529                 : 
     530               0 :   inline hb_position_t get_y_delta (hb_font_t *font) const
     531               0 :   { return get_delta (font->y_ppem, font->y_scale); }
     532                 : 
     533               0 :   inline int get_delta (unsigned int ppem, int scale) const
     534                 :   {
     535               0 :     if (!ppem) return 0;
     536                 : 
     537               0 :     int pixels = get_delta_pixels (ppem);
     538                 : 
     539               0 :     if (!pixels) return 0;
     540                 : 
     541               0 :     return pixels * (int64_t) scale / ppem;
     542                 :   }
     543                 : 
     544                 : 
     545               0 :   inline int get_delta_pixels (unsigned int ppem_size) const
     546                 :   {
     547               0 :     unsigned int f = deltaFormat;
     548               0 :     if (unlikely (f < 1 || f > 3))
     549               0 :       return 0;
     550                 : 
     551               0 :     if (ppem_size < startSize || ppem_size > endSize)
     552               0 :       return 0;
     553                 : 
     554               0 :     unsigned int s = ppem_size - startSize;
     555                 : 
     556               0 :     unsigned int byte = deltaValue[s >> (4 - f)];
     557               0 :     unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f)));
     558               0 :     unsigned int mask = (0xFFFF >> (16 - (1 << f)));
     559                 : 
     560               0 :     int delta = bits & mask;
     561                 : 
     562               0 :     if ((unsigned int) delta >= ((mask + 1) >> 1))
     563               0 :       delta -= mask + 1;
     564                 : 
     565               0 :     return delta;
     566                 :   }
     567                 : 
     568               0 :   inline unsigned int get_size (void) const
     569                 :   {
     570               0 :     unsigned int f = deltaFormat;
     571               0 :     if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * USHORT::static_size;
     572               0 :     return USHORT::static_size * (4 + ((endSize - startSize) >> (4 - f)));
     573                 :   }
     574                 : 
     575               0 :   inline bool sanitize (hb_sanitize_context_t *c) {
     576               0 :     TRACE_SANITIZE ();
     577               0 :     return c->check_struct (this)
     578               0 :         && c->check_range (this, this->get_size ());
     579                 :   }
     580                 : 
     581                 :   private:
     582                 :   USHORT        startSize;              /* Smallest size to correct--in ppem */
     583                 :   USHORT        endSize;                /* Largest size to correct--in ppem */
     584                 :   USHORT        deltaFormat;            /* Format of DeltaValue array data: 1, 2, or 3
     585                 :                                          * 1    Signed 2-bit value, 8 values per uint16
     586                 :                                          * 2    Signed 4-bit value, 4 values per uint16
     587                 :                                          * 3    Signed 8-bit value, 2 values per uint16
     588                 :                                          */
     589                 :   USHORT        deltaValue[VAR];        /* Array of compressed data */
     590                 :   public:
     591                 :   DEFINE_SIZE_ARRAY (6, deltaValue);
     592                 : };
     593                 : 
     594                 : 
     595                 : 
     596                 : #endif /* HB_OT_LAYOUT_COMMON_PRIVATE_HH */

Generated by: LCOV version 1.7