gfx/harfbuzz/src/hb-ot-layout-private.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 © 2012,2013  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_PRIVATE_HH
    30 #define HB_OT_LAYOUT_PRIVATE_HH
    32 #include "hb-private.hh"
    34 #include "hb-font-private.hh"
    35 #include "hb-buffer-private.hh"
    36 #include "hb-set-private.hh"
    39 /*
    40  * GDEF
    41  */
    43 typedef enum
    44 {
    45   /* The following three match LookupFlags::Ignore* numbers. */
    46   HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH	= 0x02u,
    47   HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE	= 0x04u,
    48   HB_OT_LAYOUT_GLYPH_PROPS_MARK		= 0x08u,
    50   /* The following are used internally; not derived from GDEF. */
    51   HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED	= 0x10u,
    52   HB_OT_LAYOUT_GLYPH_PROPS_LIGATED	= 0x20u,
    54   HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE     = HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED |
    55 					  HB_OT_LAYOUT_GLYPH_PROPS_LIGATED
    56 } hb_ot_layout_glyph_class_mask_t;
    59 /*
    60  * GSUB/GPOS
    61  */
    63 HB_INTERNAL hb_bool_t
    64 hb_ot_layout_lookup_would_substitute_fast (hb_face_t            *face,
    65 					   unsigned int          lookup_index,
    66 					   const hb_codepoint_t *glyphs,
    67 					   unsigned int          glyphs_length,
    68 					   hb_bool_t             zero_context);
    71 /* Should be called before all the substitute_lookup's are done. */
    72 HB_INTERNAL void
    73 hb_ot_layout_substitute_start (hb_font_t    *font,
    74 			       hb_buffer_t  *buffer);
    77 struct hb_ot_layout_lookup_accelerator_t;
    79 namespace OT {
    80   struct hb_apply_context_t;
    81   struct SubstLookup;
    82 }
    84 HB_INTERNAL void
    85 hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
    86 				const OT::SubstLookup &lookup,
    87 				const hb_ot_layout_lookup_accelerator_t &accel);
    90 /* Should be called after all the substitute_lookup's are done */
    91 HB_INTERNAL void
    92 hb_ot_layout_substitute_finish (hb_font_t    *font,
    93 				hb_buffer_t  *buffer);
    96 /* Should be called before all the position_lookup's are done.  Resets positions to zero. */
    97 HB_INTERNAL void
    98 hb_ot_layout_position_start (hb_font_t    *font,
    99 			     hb_buffer_t  *buffer);
   101 /* Should be called after all the position_lookup's are done */
   102 HB_INTERNAL void
   103 hb_ot_layout_position_finish (hb_font_t    *font,
   104 			      hb_buffer_t  *buffer);
   108 /*
   109  * hb_ot_layout_t
   110  */
   112 namespace OT {
   113   struct GDEF;
   114   struct GSUB;
   115   struct GPOS;
   116 }
   118 struct hb_ot_layout_lookup_accelerator_t
   119 {
   120   template <typename TLookup>
   121   inline void init (const TLookup &lookup)
   122   {
   123     digest.init ();
   124     lookup.add_coverage (&digest);
   125   }
   127   template <typename TLookup>
   128   inline void fini (const TLookup &lookup)
   129   {
   130   }
   132   hb_set_digest_t digest;
   133 };
   135 struct hb_ot_layout_t
   136 {
   137   hb_blob_t *gdef_blob;
   138   hb_blob_t *gsub_blob;
   139   hb_blob_t *gpos_blob;
   141   const struct OT::GDEF *gdef;
   142   const struct OT::GSUB *gsub;
   143   const struct OT::GPOS *gpos;
   145   unsigned int gsub_lookup_count;
   146   unsigned int gpos_lookup_count;
   148   hb_ot_layout_lookup_accelerator_t *gsub_accels;
   149   hb_ot_layout_lookup_accelerator_t *gpos_accels;
   150 };
   153 HB_INTERNAL hb_ot_layout_t *
   154 _hb_ot_layout_create (hb_face_t *face);
   156 HB_INTERNAL void
   157 _hb_ot_layout_destroy (hb_ot_layout_t *layout);
   160 #define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
   163 /*
   164  * Buffer var routines.
   165  */
   167 /* buffer var allocations, used during the entire shaping process */
   168 #define unicode_props0()	var2.u8[0]
   169 #define unicode_props1()	var2.u8[1]
   171 /* buffer var allocations, used during the GSUB/GPOS processing */
   172 #define glyph_props()		var1.u16[0] /* GDEF glyph properties */
   173 #define lig_props()		var1.u8[2] /* GSUB/GPOS ligature tracking */
   174 #define syllable()		var1.u8[3] /* GSUB/GPOS shaping boundaries */
   176 /* unicode_props */
   178 enum {
   179   MASK0_ZWJ       = 0x20u,
   180   MASK0_ZWNJ      = 0x40u,
   181   MASK0_IGNORABLE = 0x80u,
   182   MASK0_GEN_CAT   = 0x1Fu
   183 };
   185 inline void
   186 _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
   187 {
   188   /* XXX This shouldn't be inlined, or at least not while is_default_ignorable() is inline. */
   189   info->unicode_props0() = ((unsigned int) unicode->general_category (info->codepoint)) |
   190 			   (unicode->is_default_ignorable (info->codepoint) ? MASK0_IGNORABLE : 0) |
   191 			   (info->codepoint == 0x200C ? MASK0_ZWNJ : 0) |
   192 			   (info->codepoint == 0x200D ? MASK0_ZWJ : 0);
   193   info->unicode_props1() = unicode->modified_combining_class (info->codepoint);
   194 }
   196 inline void
   197 _hb_glyph_info_set_general_category (hb_glyph_info_t *info,
   198 				     hb_unicode_general_category_t gen_cat)
   199 {
   200   info->unicode_props0() = (unsigned int) gen_cat | ((info->unicode_props0()) & ~MASK0_GEN_CAT);
   201 }
   203 inline hb_unicode_general_category_t
   204 _hb_glyph_info_get_general_category (const hb_glyph_info_t *info)
   205 {
   206   return (hb_unicode_general_category_t) (info->unicode_props0() & MASK0_GEN_CAT);
   207 }
   209 inline void
   210 _hb_glyph_info_set_modified_combining_class (hb_glyph_info_t *info,
   211 					     unsigned int modified_class)
   212 {
   213   info->unicode_props1() = modified_class;
   214 }
   216 inline unsigned int
   217 _hb_glyph_info_get_modified_combining_class (const hb_glyph_info_t *info)
   218 {
   219   return info->unicode_props1();
   220 }
   222 inline hb_bool_t
   223 _hb_glyph_info_is_default_ignorable (const hb_glyph_info_t *info)
   224 {
   225   return !!(info->unicode_props0() & MASK0_IGNORABLE);
   226 }
   228 inline hb_bool_t
   229 _hb_glyph_info_is_zwnj (const hb_glyph_info_t *info)
   230 {
   231   return !!(info->unicode_props0() & MASK0_ZWNJ);
   232 }
   234 inline hb_bool_t
   235 _hb_glyph_info_is_zwj (const hb_glyph_info_t *info)
   236 {
   237   return !!(info->unicode_props0() & MASK0_ZWJ);
   238 }
   240 inline void
   241 _hb_glyph_info_flip_joiners (hb_glyph_info_t *info)
   242 {
   243   info->unicode_props0() ^= MASK0_ZWNJ | MASK0_ZWJ;
   244 }
   246 /* lig_props: aka lig_id / lig_comp
   247  *
   248  * When a ligature is formed:
   249  *
   250  *   - The ligature glyph and any marks in between all the same newly allocated
   251  *     lig_id,
   252  *   - The ligature glyph will get lig_num_comps set to the number of components
   253  *   - The marks get lig_comp > 0, reflecting which component of the ligature
   254  *     they were applied to.
   255  *   - This is used in GPOS to attach marks to the right component of a ligature
   256  *     in MarkLigPos,
   257  *   - Note that when marks are ligated together, much of the above is skipped
   258  *     and the current lig_id reused.
   259  *
   260  * When a multiple-substitution is done:
   261  *
   262  *   - All resulting glyphs will have lig_id = 0,
   263  *   - The resulting glyphs will have lig_comp = 0, 1, 2, ... respectively.
   264  *   - This is used in GPOS to attach marks to the first component of a
   265  *     multiple substitution in MarkBasePos.
   266  *
   267  * The numbers are also used in GPOS to do mark-to-mark positioning only
   268  * to marks that belong to the same component of the same ligature.
   269  */
   271 static inline void
   272 _hb_glyph_info_clear_lig_props (hb_glyph_info_t *info)
   273 {
   274   info->lig_props() = 0;
   275 }
   277 #define IS_LIG_BASE 0x10
   279 static inline void
   280 _hb_glyph_info_set_lig_props_for_ligature (hb_glyph_info_t *info,
   281 					   unsigned int lig_id,
   282 					   unsigned int lig_num_comps)
   283 {
   284   info->lig_props() = (lig_id << 5) | IS_LIG_BASE | (lig_num_comps & 0x0F);
   285 }
   287 static inline void
   288 _hb_glyph_info_set_lig_props_for_mark (hb_glyph_info_t *info,
   289 				       unsigned int lig_id,
   290 				       unsigned int lig_comp)
   291 {
   292   info->lig_props() = (lig_id << 5) | (lig_comp & 0x0F);
   293 }
   295 static inline void
   296 _hb_glyph_info_set_lig_props_for_component (hb_glyph_info_t *info, unsigned int comp)
   297 {
   298   _hb_glyph_info_set_lig_props_for_mark (info, 0, comp);
   299 }
   301 static inline unsigned int
   302 _hb_glyph_info_get_lig_id (const hb_glyph_info_t *info)
   303 {
   304   return info->lig_props() >> 5;
   305 }
   307 static inline bool
   308 _hb_glyph_info_ligated_internal (const hb_glyph_info_t *info)
   309 {
   310   return !!(info->lig_props() & IS_LIG_BASE);
   311 }
   313 static inline unsigned int
   314 _hb_glyph_info_get_lig_comp (const hb_glyph_info_t *info)
   315 {
   316   if (_hb_glyph_info_ligated_internal (info))
   317     return 0;
   318   else
   319     return info->lig_props() & 0x0F;
   320 }
   322 static inline unsigned int
   323 _hb_glyph_info_get_lig_num_comps (const hb_glyph_info_t *info)
   324 {
   325   if ((info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE) &&
   326       _hb_glyph_info_ligated_internal (info))
   327     return info->lig_props() & 0x0F;
   328   else
   329     return 1;
   330 }
   332 static inline uint8_t
   333 _hb_allocate_lig_id (hb_buffer_t *buffer) {
   334   uint8_t lig_id = buffer->next_serial () & 0x07;
   335   if (unlikely (!lig_id))
   336     lig_id = _hb_allocate_lig_id (buffer); /* in case of overflow */
   337   return lig_id;
   338 }
   340 /* glyph_props: */
   342 inline void
   343 _hb_glyph_info_set_glyph_props (hb_glyph_info_t *info, unsigned int props)
   344 {
   345   info->glyph_props() = props;
   346 }
   348 inline unsigned int
   349 _hb_glyph_info_get_glyph_props (const hb_glyph_info_t *info)
   350 {
   351   return info->glyph_props();
   352 }
   354 inline bool
   355 _hb_glyph_info_is_base_glyph (const hb_glyph_info_t *info)
   356 {
   357   return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
   358 }
   360 inline bool
   361 _hb_glyph_info_is_ligature (const hb_glyph_info_t *info)
   362 {
   363   return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE);
   364 }
   366 inline bool
   367 _hb_glyph_info_is_mark (const hb_glyph_info_t *info)
   368 {
   369   return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
   370 }
   372 static inline bool
   373 _hb_glyph_info_substituted (const hb_glyph_info_t *info)
   374 {
   375   return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
   376 }
   378 static inline bool
   379 _hb_glyph_info_ligated (const hb_glyph_info_t *info)
   380 {
   381   return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED);
   382 }
   384 /* Allocation / deallocation. */
   386 inline void
   387 _hb_buffer_allocate_unicode_vars (hb_buffer_t *buffer)
   388 {
   389   HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props0);
   390   HB_BUFFER_ALLOCATE_VAR (buffer, unicode_props1);
   391 }
   393 inline void
   394 _hb_buffer_deallocate_unicode_vars (hb_buffer_t *buffer)
   395 {
   396   HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props0);
   397   HB_BUFFER_DEALLOCATE_VAR (buffer, unicode_props1);
   398 }
   400 inline void
   401 _hb_buffer_allocate_gsubgpos_vars (hb_buffer_t *buffer)
   402 {
   403   HB_BUFFER_ALLOCATE_VAR (buffer, glyph_props);
   404   HB_BUFFER_ALLOCATE_VAR (buffer, lig_props);
   405   HB_BUFFER_ALLOCATE_VAR (buffer, syllable);
   406 }
   408 inline void
   409 _hb_buffer_deallocate_gsubgpos_vars (hb_buffer_t *buffer)
   410 {
   411   HB_BUFFER_DEALLOCATE_VAR (buffer, syllable);
   412   HB_BUFFER_DEALLOCATE_VAR (buffer, lig_props);
   413   HB_BUFFER_DEALLOCATE_VAR (buffer, glyph_props);
   414 }
   416 /* Make sure no one directly touches our props... */
   417 #undef unicode_props0
   418 #undef unicode_props1
   419 #undef lig_props
   420 #undef glyph_props
   423 #endif /* HB_OT_LAYOUT_PRIVATE_HH */

mercurial