gfx/harfbuzz/src/hb-ot-layout-gdef-table.hh

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

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

mercurial