1 /*
   2  * Copyright © 2018  Google, Inc.
   3  *
   4  *  This is part of HarfBuzz, a text shaping library.
   5  *
   6  * Permission is hereby granted, without written agreement and without
   7  * license or royalty fees, to use, copy, modify, and distribute this
   8  * software and its documentation for any purpose, provided that the
   9  * above copyright notice and the following two paragraphs appear in
  10  * all copies of this software.
  11  *
  12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
  13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
  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
  16  * DAMAGE.
  17  *
  18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
  19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  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
  22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  23  *
  24  * Google Author(s): Behdad Esfahbod
  25  */
  26 
  27 #ifndef HB_OT_SHAPE_COMPLEX_KHMER_HH
  28 #define HB_OT_SHAPE_COMPLEX_KHMER_HH
  29 
  30 #include "hb.hh"
  31 
  32 #include "hb-ot-shape-complex-indic.hh"
  33 
  34 
  35 /* buffer var allocations */
  36 #define khmer_category() indic_category() /* khmer_category_t */
  37 
  38 
  39 /* Note: This enum is duplicated in the -machine.rl source file.
  40  * Not sure how to avoid duplication. */
  41 enum khmer_category_t
  42 {
  43   OT_Robatic = 20,
  44   OT_Xgroup  = 21,
  45   OT_Ygroup  = 22,
  46 
  47   OT_VAbv    = 26,
  48   OT_VBlw    = 27,
  49   OT_VPre    = 28,
  50   OT_VPst    = 29,
  51 };
  52 
  53 static inline void
  54 set_khmer_properties (hb_glyph_info_t &info)
  55 {
  56   hb_codepoint_t u = info.codepoint;
  57   unsigned int type = hb_indic_get_categories (u);
  58   khmer_category_t cat = (khmer_category_t) (type & 0x7Fu);
  59   indic_position_t pos = (indic_position_t) (type >> 8);
  60 
  61 
  62   /*
  63    * Re-assign category
  64    *
  65    * These categories are experimentally extracted from what Uniscribe allows.
  66    */
  67   switch (u)
  68   {
  69     case 0x179Au:
  70       cat = (khmer_category_t) OT_Ra;
  71       break;
  72 
  73     case 0x17CCu:
  74     case 0x17C9u:
  75     case 0x17CAu:
  76       cat = OT_Robatic;
  77       break;
  78 
  79     case 0x17C6u:
  80     case 0x17CBu:
  81     case 0x17CDu:
  82     case 0x17CEu:
  83     case 0x17CFu:
  84     case 0x17D0u:
  85     case 0x17D1u:
  86       cat = OT_Xgroup;
  87       break;
  88 
  89     case 0x17C7u:
  90     case 0x17C8u:
  91     case 0x17DDu:
  92     case 0x17D3u: /* Just guessing. Uniscribe doesn't categorize it. */
  93       cat = OT_Ygroup;
  94       break;
  95   }
  96 
  97   /*
  98    * Re-assign position.
  99    */
 100   if (cat == (khmer_category_t) OT_M)
 101     switch ((int) pos)
 102     {
 103       case POS_PRE_C:   cat = OT_VPre; break;
 104       case POS_BELOW_C: cat = OT_VBlw; break;
 105       case POS_ABOVE_C: cat = OT_VAbv; break;
 106       case POS_POST_C:  cat = OT_VPst; break;
 107       default: assert (0);
 108     };
 109 
 110   info.khmer_category() = cat;
 111 }
 112 
 113 
 114 #endif /* HB_OT_SHAPE_COMPLEX_KHMER_HH */