LCOV - code coverage report
Current view: top level - gfx/harfbuzz/src - hb-ot-layout-gdef-table.hh (source / functions) Hit Total Coverage
Test: output.info Lines: 16 112 14.3 %
Date: 2017-07-14 16:53:18 Functions: 6 28 21.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright © 2007,2008,2009  Red Hat, Inc.
       3             :  * Copyright © 2010,2011,2012  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_GDEF_TABLE_HH
      30             : #define HB_OT_LAYOUT_GDEF_TABLE_HH
      31             : 
      32             : #include "hb-ot-layout-common-private.hh"
      33             : 
      34             : #include "hb-font-private.hh"
      35             : 
      36             : 
      37             : namespace OT {
      38             : 
      39             : 
      40             : /*
      41             :  * Attachment List Table
      42             :  */
      43             : 
      44             : typedef ArrayOf<USHORT> AttachPoint;      /* Array of contour point indices--in
      45             :                                          * increasing numerical order */
      46             : 
      47             : struct AttachList
      48             : {
      49           0 :   inline unsigned int get_attach_points (hb_codepoint_t glyph_id,
      50             :                                          unsigned int start_offset,
      51             :                                          unsigned int *point_count /* IN/OUT */,
      52             :                                          unsigned int *point_array /* OUT */) const
      53             :   {
      54           0 :     unsigned int index = (this+coverage).get_coverage (glyph_id);
      55           0 :     if (index == NOT_COVERED)
      56             :     {
      57           0 :       if (point_count)
      58           0 :         *point_count = 0;
      59           0 :       return 0;
      60             :     }
      61             : 
      62           0 :     const AttachPoint &points = this+attachPoint[index];
      63             : 
      64           0 :     if (point_count) {
      65           0 :       const USHORT *array = points.sub_array (start_offset, point_count);
      66           0 :       unsigned int count = *point_count;
      67           0 :       for (unsigned int i = 0; i < count; i++)
      68           0 :         point_array[i] = array[i];
      69             :     }
      70             : 
      71           0 :     return points.len;
      72             :   }
      73             : 
      74           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
      75             :   {
      76           0 :     TRACE_SANITIZE (this);
      77           0 :     return_trace (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
      78             :   }
      79             : 
      80             :   protected:
      81             :   OffsetTo<Coverage>
      82             :                 coverage;               /* Offset to Coverage table -- from
      83             :                                          * beginning of AttachList table */
      84             :   OffsetArrayOf<AttachPoint>
      85             :                 attachPoint;            /* Array of AttachPoint tables
      86             :                                          * in Coverage Index order */
      87             :   public:
      88             :   DEFINE_SIZE_ARRAY (4, attachPoint);
      89             : };
      90             : 
      91             : /*
      92             :  * Ligature Caret Table
      93             :  */
      94             : 
      95             : struct CaretValueFormat1
      96             : {
      97             :   friend struct CaretValue;
      98             : 
      99             :   private:
     100           0 :   inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction) const
     101             :   {
     102           0 :     return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
     103             :   }
     104             : 
     105           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     106             :   {
     107           0 :     TRACE_SANITIZE (this);
     108           0 :     return_trace (c->check_struct (this));
     109             :   }
     110             : 
     111             :   protected:
     112             :   USHORT        caretValueFormat;       /* Format identifier--format = 1 */
     113             :   SHORT         coordinate;             /* X or Y value, in design units */
     114             :   public:
     115             :   DEFINE_SIZE_STATIC (4);
     116             : };
     117             : 
     118             : struct CaretValueFormat2
     119             : {
     120             :   friend struct CaretValue;
     121             : 
     122             :   private:
     123           0 :   inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
     124             :   {
     125             :     hb_position_t x, y;
     126           0 :     if (font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y))
     127           0 :       return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
     128             :     else
     129           0 :       return 0;
     130             :   }
     131             : 
     132           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     133             :   {
     134           0 :     TRACE_SANITIZE (this);
     135           0 :     return_trace (c->check_struct (this));
     136             :   }
     137             : 
     138             :   protected:
     139             :   USHORT        caretValueFormat;       /* Format identifier--format = 2 */
     140             :   USHORT        caretValuePoint;        /* Contour point index on glyph */
     141             :   public:
     142             :   DEFINE_SIZE_STATIC (4);
     143             : };
     144             : 
     145             : struct CaretValueFormat3
     146             : {
     147             :   friend struct CaretValue;
     148             : 
     149           0 :   inline hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, const VariationStore &var_store) const
     150             :   {
     151           0 :     return HB_DIRECTION_IS_HORIZONTAL (direction) ?
     152           0 :            font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) :
     153           0 :            font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store);
     154             :   }
     155             : 
     156           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     157             :   {
     158           0 :     TRACE_SANITIZE (this);
     159           0 :     return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));
     160             :   }
     161             : 
     162             :   protected:
     163             :   USHORT        caretValueFormat;       /* Format identifier--format = 3 */
     164             :   SHORT         coordinate;             /* X or Y value, in design units */
     165             :   OffsetTo<Device>
     166             :                 deviceTable;            /* Offset to Device table for X or Y
     167             :                                          * value--from beginning of CaretValue
     168             :                                          * table */
     169             :   public:
     170             :   DEFINE_SIZE_STATIC (6);
     171             : };
     172             : 
     173             : struct CaretValue
     174             : {
     175           0 :   inline hb_position_t get_caret_value (hb_font_t *font,
     176             :                                         hb_direction_t direction,
     177             :                                         hb_codepoint_t glyph_id,
     178             :                                         const VariationStore &var_store) const
     179             :   {
     180           0 :     switch (u.format) {
     181           0 :     case 1: return u.format1.get_caret_value (font, direction);
     182           0 :     case 2: return u.format2.get_caret_value (font, direction, glyph_id);
     183           0 :     case 3: return u.format3.get_caret_value (font, direction, var_store);
     184           0 :     default:return 0;
     185             :     }
     186             :   }
     187             : 
     188           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     189             :   {
     190           0 :     TRACE_SANITIZE (this);
     191           0 :     if (!u.format.sanitize (c)) return_trace (false);
     192           0 :     switch (u.format) {
     193           0 :     case 1: return_trace (u.format1.sanitize (c));
     194           0 :     case 2: return_trace (u.format2.sanitize (c));
     195           0 :     case 3: return_trace (u.format3.sanitize (c));
     196           0 :     default:return_trace (true);
     197             :     }
     198             :   }
     199             : 
     200             :   protected:
     201             :   union {
     202             :   USHORT                format;         /* Format identifier */
     203             :   CaretValueFormat1     format1;
     204             :   CaretValueFormat2     format2;
     205             :   CaretValueFormat3     format3;
     206             :   } u;
     207             :   public:
     208             :   DEFINE_SIZE_UNION (2, format);
     209             : };
     210             : 
     211             : struct LigGlyph
     212             : {
     213           0 :   inline unsigned int get_lig_carets (hb_font_t *font,
     214             :                                       hb_direction_t direction,
     215             :                                       hb_codepoint_t glyph_id,
     216             :                                       const VariationStore &var_store,
     217             :                                       unsigned int start_offset,
     218             :                                       unsigned int *caret_count /* IN/OUT */,
     219             :                                       hb_position_t *caret_array /* OUT */) const
     220             :   {
     221           0 :     if (caret_count) {
     222           0 :       const OffsetTo<CaretValue> *array = carets.sub_array (start_offset, caret_count);
     223           0 :       unsigned int count = *caret_count;
     224           0 :       for (unsigned int i = 0; i < count; i++)
     225           0 :         caret_array[i] = (this+array[i]).get_caret_value (font, direction, glyph_id, var_store);
     226             :     }
     227             : 
     228           0 :     return carets.len;
     229             :   }
     230             : 
     231           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     232             :   {
     233           0 :     TRACE_SANITIZE (this);
     234           0 :     return_trace (carets.sanitize (c, this));
     235             :   }
     236             : 
     237             :   protected:
     238             :   OffsetArrayOf<CaretValue>
     239             :                 carets;                 /* Offset array of CaretValue tables
     240             :                                          * --from beginning of LigGlyph table
     241             :                                          * --in increasing coordinate order */
     242             :   public:
     243             :   DEFINE_SIZE_ARRAY (2, carets);
     244             : };
     245             : 
     246             : struct LigCaretList
     247             : {
     248           0 :   inline unsigned int get_lig_carets (hb_font_t *font,
     249             :                                       hb_direction_t direction,
     250             :                                       hb_codepoint_t glyph_id,
     251             :                                       const VariationStore &var_store,
     252             :                                       unsigned int start_offset,
     253             :                                       unsigned int *caret_count /* IN/OUT */,
     254             :                                       hb_position_t *caret_array /* OUT */) const
     255             :   {
     256           0 :     unsigned int index = (this+coverage).get_coverage (glyph_id);
     257           0 :     if (index == NOT_COVERED)
     258             :     {
     259           0 :       if (caret_count)
     260           0 :         *caret_count = 0;
     261           0 :       return 0;
     262             :     }
     263           0 :     const LigGlyph &lig_glyph = this+ligGlyph[index];
     264           0 :     return lig_glyph.get_lig_carets (font, direction, glyph_id, var_store, start_offset, caret_count, caret_array);
     265             :   }
     266             : 
     267           2 :   inline bool sanitize (hb_sanitize_context_t *c) const
     268             :   {
     269           2 :     TRACE_SANITIZE (this);
     270           2 :     return_trace (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
     271             :   }
     272             : 
     273             :   protected:
     274             :   OffsetTo<Coverage>
     275             :                 coverage;               /* Offset to Coverage table--from
     276             :                                          * beginning of LigCaretList table */
     277             :   OffsetArrayOf<LigGlyph>
     278             :                 ligGlyph;               /* Array of LigGlyph tables
     279             :                                          * in Coverage Index order */
     280             :   public:
     281             :   DEFINE_SIZE_ARRAY (4, ligGlyph);
     282             : };
     283             : 
     284             : 
     285             : struct MarkGlyphSetsFormat1
     286             : {
     287           0 :   inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
     288           0 :   { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
     289             : 
     290           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     291             :   {
     292           0 :     TRACE_SANITIZE (this);
     293           0 :     return_trace (coverage.sanitize (c, this));
     294             :   }
     295             : 
     296             :   protected:
     297             :   USHORT        format;                 /* Format identifier--format = 1 */
     298             :   ArrayOf<LOffsetTo<Coverage> >
     299             :                 coverage;               /* Array of long offsets to mark set
     300             :                                          * coverage tables */
     301             :   public:
     302             :   DEFINE_SIZE_ARRAY (4, coverage);
     303             : };
     304             : 
     305             : struct MarkGlyphSets
     306             : {
     307           0 :   inline bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
     308             :   {
     309           0 :     switch (u.format) {
     310           0 :     case 1: return u.format1.covers (set_index, glyph_id);
     311           0 :     default:return false;
     312             :     }
     313             :   }
     314             : 
     315           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     316             :   {
     317           0 :     TRACE_SANITIZE (this);
     318           0 :     if (!u.format.sanitize (c)) return_trace (false);
     319           0 :     switch (u.format) {
     320           0 :     case 1: return_trace (u.format1.sanitize (c));
     321           0 :     default:return_trace (true);
     322             :     }
     323             :   }
     324             : 
     325             :   protected:
     326             :   union {
     327             :   USHORT                format;         /* Format identifier */
     328             :   MarkGlyphSetsFormat1  format1;
     329             :   } u;
     330             :   public:
     331             :   DEFINE_SIZE_UNION (2, format);
     332             : };
     333             : 
     334             : 
     335             : /*
     336             :  * GDEF -- The Glyph Definition Table
     337             :  */
     338             : 
     339             : struct GDEF
     340             : {
     341             :   static const hb_tag_t tableTag        = HB_OT_TAG_GDEF;
     342             : 
     343             :   enum GlyphClasses {
     344             :     UnclassifiedGlyph   = 0,
     345             :     BaseGlyph           = 1,
     346             :     LigatureGlyph       = 2,
     347             :     MarkGlyph           = 3,
     348             :     ComponentGlyph      = 4
     349             :   };
     350             : 
     351         136 :   inline bool has_glyph_classes (void) const { return glyphClassDef != 0; }
     352         265 :   inline unsigned int get_glyph_class (hb_codepoint_t glyph) const
     353         265 :   { return (this+glyphClassDef).get_class (glyph); }
     354           0 :   inline void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const
     355           0 :   { (this+glyphClassDef).add_class (glyphs, klass); }
     356             : 
     357             :   inline bool has_mark_attachment_types (void) const { return markAttachClassDef != 0; }
     358           0 :   inline unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
     359           0 :   { return (this+markAttachClassDef).get_class (glyph); }
     360             : 
     361             :   inline bool has_attach_points (void) const { return attachList != 0; }
     362           0 :   inline unsigned int get_attach_points (hb_codepoint_t glyph_id,
     363             :                                          unsigned int start_offset,
     364             :                                          unsigned int *point_count /* IN/OUT */,
     365             :                                          unsigned int *point_array /* OUT */) const
     366           0 :   { return (this+attachList).get_attach_points (glyph_id, start_offset, point_count, point_array); }
     367             : 
     368             :   inline bool has_lig_carets (void) const { return ligCaretList != 0; }
     369           0 :   inline unsigned int get_lig_carets (hb_font_t *font,
     370             :                                       hb_direction_t direction,
     371             :                                       hb_codepoint_t glyph_id,
     372             :                                       unsigned int start_offset,
     373             :                                       unsigned int *caret_count /* IN/OUT */,
     374             :                                       hb_position_t *caret_array /* OUT */) const
     375           0 :   { return (this+ligCaretList).get_lig_carets (font,
     376             :                                                direction, glyph_id, get_var_store(),
     377           0 :                                                start_offset, caret_count, caret_array); }
     378             : 
     379             :   inline bool has_mark_sets (void) const { return version.to_int () >= 0x00010002u && markGlyphSetsDef != 0; }
     380           0 :   inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
     381           0 :   { return version.to_int () >= 0x00010002u && (this+markGlyphSetsDef).covers (set_index, glyph_id); }
     382             : 
     383             :   inline bool has_var_store (void) const { return version.to_int () >= 0x00010003u && varStore != 0; }
     384          68 :   inline const VariationStore &get_var_store (void) const
     385          68 :   { return version.to_int () >= 0x00010003u ? this+varStore : Null(VariationStore); }
     386             : 
     387           2 :   inline bool sanitize (hb_sanitize_context_t *c) const
     388             :   {
     389           2 :     TRACE_SANITIZE (this);
     390           2 :     return_trace (version.sanitize (c) &&
     391             :                   likely (version.major == 1) &&
     392             :                   glyphClassDef.sanitize (c, this) &&
     393             :                   attachList.sanitize (c, this) &&
     394             :                   ligCaretList.sanitize (c, this) &&
     395             :                   markAttachClassDef.sanitize (c, this) &&
     396             :                   (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) &&
     397             :                   (version.to_int () < 0x00010003u || varStore.sanitize (c, this)));
     398             :   }
     399             : 
     400             :   /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
     401             :    * glyph class and other bits, and high 8-bit gthe mark attachment type (if any).
     402             :    * Not to be confused with lookup_props which is very similar. */
     403         265 :   inline unsigned int get_glyph_props (hb_codepoint_t glyph) const
     404             :   {
     405         265 :     unsigned int klass = get_glyph_class (glyph);
     406             : 
     407             :     ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs);
     408             :     ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures);
     409             :     ASSERT_STATIC ((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks);
     410             : 
     411         265 :     switch (klass) {
     412         238 :     default:                    return 0;
     413          27 :     case BaseGlyph:             return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
     414           0 :     case LigatureGlyph:         return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
     415             :     case MarkGlyph:
     416           0 :           klass = get_mark_attachment_type (glyph);
     417           0 :           return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
     418             :     }
     419             :   }
     420             : 
     421             : 
     422             :   protected:
     423             :   FixedVersion<>version;          /* Version of the GDEF table--currently
     424             :                                          * 0x00010003u */
     425             :   OffsetTo<ClassDef>
     426             :                 glyphClassDef;          /* Offset to class definition table
     427             :                                          * for glyph type--from beginning of
     428             :                                          * GDEF header (may be Null) */
     429             :   OffsetTo<AttachList>
     430             :                 attachList;             /* Offset to list of glyphs with
     431             :                                          * attachment points--from beginning
     432             :                                          * of GDEF header (may be Null) */
     433             :   OffsetTo<LigCaretList>
     434             :                 ligCaretList;           /* Offset to list of positioning points
     435             :                                          * for ligature carets--from beginning
     436             :                                          * of GDEF header (may be Null) */
     437             :   OffsetTo<ClassDef>
     438             :                 markAttachClassDef;     /* Offset to class definition table for
     439             :                                          * mark attachment type--from beginning
     440             :                                          * of GDEF header (may be Null) */
     441             :   OffsetTo<MarkGlyphSets>
     442             :                 markGlyphSetsDef;       /* Offset to the table of mark set
     443             :                                          * definitions--from beginning of GDEF
     444             :                                          * header (may be NULL).  Introduced
     445             :                                          * in version 0x00010002. */
     446             :   LOffsetTo<VariationStore>
     447             :                 varStore;               /* Offset to the table of Item Variation
     448             :                                          * Store--from beginning of GDEF
     449             :                                          * header (may be NULL).  Introduced
     450             :                                          * in version 0x00010003. */
     451             :   public:
     452             :   DEFINE_SIZE_MIN (12);
     453             : };
     454             : 
     455             : 
     456             : } /* namespace OT */
     457             : 
     458             : 
     459             : #endif /* HB_OT_LAYOUT_GDEF_TABLE_HH */

Generated by: LCOV version 1.13