tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

hb-ot-shaper.hh (11979B)


      1 /*
      2 * Copyright © 2010,2011,2012  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_SHAPER_HH
     28 #define HB_OT_SHAPER_HH
     29 
     30 #include "hb.hh"
     31 
     32 #include "hb-ot-layout.hh"
     33 #include "hb-ot-shape.hh"
     34 #include "hb-ot-shape-normalize.hh"
     35 
     36 
     37 /* buffer var allocations, used by all OT shapers */
     38 #define ot_shaper_var_u8_category()	var2.u8[2]
     39 #define ot_shaper_var_u8_auxiliary()	var2.u8[3]
     40 
     41 
     42 #define HB_OT_SHAPE_MAX_COMBINING_MARKS 32
     43 
     44 enum hb_ot_shape_zero_width_marks_type_t {
     45  HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
     46  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
     47  HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE
     48 };
     49 
     50 
     51 /* Master OT shaper list */
     52 #define HB_OT_SHAPERS_IMPLEMENT_SHAPERS \
     53  HB_OT_SHAPER_IMPLEMENT (arabic) \
     54  HB_OT_SHAPER_IMPLEMENT (default) \
     55  HB_OT_SHAPER_IMPLEMENT (dumber) \
     56  HB_OT_SHAPER_IMPLEMENT (hangul) \
     57  HB_OT_SHAPER_IMPLEMENT (hebrew) \
     58  HB_OT_SHAPER_IMPLEMENT (indic) \
     59  HB_OT_SHAPER_IMPLEMENT (khmer) \
     60  HB_OT_SHAPER_IMPLEMENT (myanmar) \
     61  HB_OT_SHAPER_IMPLEMENT (myanmar_zawgyi) \
     62  HB_OT_SHAPER_IMPLEMENT (thai) \
     63  HB_OT_SHAPER_IMPLEMENT (use) \
     64  /* ^--- Add new shapers here; keep sorted. */
     65 
     66 
     67 struct hb_ot_shaper_t
     68 {
     69  /* collect_features()
     70   * Called during shape_plan().
     71   * Shapers should use plan->map to add their features and callbacks.
     72   * May be NULL.
     73   */
     74  void (*collect_features) (hb_ot_shape_planner_t *plan);
     75 
     76  /* override_features()
     77   * Called during shape_plan().
     78   * Shapers should use plan->map to override features and add callbacks after
     79   * common features are added.
     80   * May be NULL.
     81   */
     82  void (*override_features) (hb_ot_shape_planner_t *plan);
     83 
     84 
     85  /* data_create()
     86   * Called at the end of shape_plan().
     87   * Whatever shapers return will be accessible through plan->data later.
     88   * If nullptr is returned, means a plan failure.
     89   */
     90  void *(*data_create) (const hb_ot_shape_plan_t *plan);
     91 
     92  /* data_destroy()
     93   * Called when the shape_plan is being destroyed.
     94   * plan->data is passed here for destruction.
     95   * If nullptr is returned, means a plan failure.
     96   * May be NULL.
     97   */
     98  void (*data_destroy) (void *data);
     99 
    100 
    101  /* preprocess_text()
    102   * Called during shape().
    103   * Shapers can use to modify text before shaping starts.
    104   * May be NULL.
    105   */
    106  void (*preprocess_text) (const hb_ot_shape_plan_t *plan,
    107 		   hb_buffer_t              *buffer,
    108 		   hb_font_t                *font);
    109 
    110  /* postprocess_glyphs()
    111   * Called during shape().
    112   * Shapers can use to modify glyphs after shaping ends.
    113   * May be NULL.
    114   */
    115  void (*postprocess_glyphs) (const hb_ot_shape_plan_t *plan,
    116 		      hb_buffer_t              *buffer,
    117 		      hb_font_t                *font);
    118 
    119 
    120  /* decompose()
    121   * Called during shape()'s normalization.
    122   * May be NULL.
    123   */
    124  bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
    125 	     hb_codepoint_t  ab,
    126 	     hb_codepoint_t *a,
    127 	     hb_codepoint_t *b);
    128 
    129  /* compose()
    130   * Called during shape()'s normalization.
    131   * May be NULL.
    132   */
    133  bool (*compose) (const hb_ot_shape_normalize_context_t *c,
    134 	   hb_codepoint_t  a,
    135 	   hb_codepoint_t  b,
    136 	   hb_codepoint_t *ab);
    137 
    138  /* setup_masks()
    139   * Called during shape().
    140   * Shapers should use map to get feature masks and set on buffer.
    141   * Shapers may NOT modify characters.
    142   * May be NULL.
    143   */
    144  void (*setup_masks) (const hb_ot_shape_plan_t *plan,
    145 	       hb_buffer_t              *buffer,
    146 	       hb_font_t                *font);
    147 
    148  /* reorder_marks()
    149   * Called during shape().
    150   * Shapers can use to modify ordering of combining marks.
    151   * May be NULL.
    152   */
    153  void (*reorder_marks) (const hb_ot_shape_plan_t *plan,
    154 		 hb_buffer_t              *buffer,
    155 		 unsigned int              start,
    156 		 unsigned int              end);
    157 
    158  /* gpos_tag()
    159   * If not HB_TAG_NONE, then must match found GPOS script tag for
    160   * GPOS to be applied.  Otherwise, fallback positioning will be used.
    161   */
    162  hb_tag_t gpos_tag;
    163 
    164  hb_ot_shape_normalization_mode_t normalization_preference;
    165 
    166  hb_ot_shape_zero_width_marks_type_t zero_width_marks;
    167 
    168  bool fallback_position;
    169 };
    170 
    171 #define HB_OT_SHAPER_IMPLEMENT(name) extern HB_INTERNAL const hb_ot_shaper_t _hb_ot_shaper_##name;
    172 HB_OT_SHAPERS_IMPLEMENT_SHAPERS
    173 #undef HB_OT_SHAPER_IMPLEMENT
    174 
    175 
    176 static inline const hb_ot_shaper_t *
    177 hb_ot_shaper_categorize (hb_script_t script,
    178 		 hb_direction_t direction,
    179 		 hb_tag_t gsub_script)
    180 {
    181  switch ((hb_tag_t) script)
    182  {
    183    default:
    184      return &_hb_ot_shaper_default;
    185 
    186 
    187    /* Unicode-1.1 additions */
    188    case HB_SCRIPT_ARABIC:
    189 
    190    /* Unicode-3.0 additions */
    191    case HB_SCRIPT_SYRIAC:
    192 
    193      /* For Arabic script, use the Arabic shaper even if no OT script tag was found.
    194       * This is because we do fallback shaping for Arabic script (and not others).
    195       * But note that Arabic shaping is applicable only to horizontal layout; for
    196       * vertical text, just use the generic shaper instead. */
    197      if ((gsub_script != HB_OT_TAG_DEFAULT_SCRIPT || script == HB_SCRIPT_ARABIC) &&
    198   HB_DIRECTION_IS_HORIZONTAL (direction))
    199 return &_hb_ot_shaper_arabic;
    200      else
    201 return &_hb_ot_shaper_default;
    202 
    203 
    204    /* Unicode-1.1 additions */
    205    case HB_SCRIPT_THAI:
    206    case HB_SCRIPT_LAO:
    207 
    208      return &_hb_ot_shaper_thai;
    209 
    210 
    211    /* Unicode-1.1 additions */
    212    case HB_SCRIPT_HANGUL:
    213 
    214      return &_hb_ot_shaper_hangul;
    215 
    216 
    217    /* Unicode-1.1 additions */
    218    case HB_SCRIPT_HEBREW:
    219 
    220      return &_hb_ot_shaper_hebrew;
    221 
    222 
    223    /* Unicode-1.1 additions */
    224    case HB_SCRIPT_BENGALI:
    225    case HB_SCRIPT_DEVANAGARI:
    226    case HB_SCRIPT_GUJARATI:
    227    case HB_SCRIPT_GURMUKHI:
    228    case HB_SCRIPT_KANNADA:
    229    case HB_SCRIPT_MALAYALAM:
    230    case HB_SCRIPT_ORIYA:
    231    case HB_SCRIPT_TAMIL:
    232    case HB_SCRIPT_TELUGU:
    233 
    234      /* If the designer designed the font for the 'DFLT' script,
    235       * (or we ended up arbitrarily pick 'latn'), use the default shaper.
    236       * Otherwise, use the specific shaper.
    237       *
    238       * If it's indy3 tag, send to USE. */
    239      if (gsub_script == HB_TAG ('D','F','L','T') ||
    240   gsub_script == HB_TAG ('l','a','t','n'))
    241 return &_hb_ot_shaper_default;
    242      else if ((gsub_script & 0x000000FF) == '3')
    243 return &_hb_ot_shaper_use;
    244      else
    245 return &_hb_ot_shaper_indic;
    246 
    247    case HB_SCRIPT_KHMER:
    248 return &_hb_ot_shaper_khmer;
    249 
    250    case HB_SCRIPT_MYANMAR:
    251      /* If the designer designed the font for the 'DFLT' script,
    252       * (or we ended up arbitrarily pick 'latn'), use the default shaper.
    253       * Otherwise, use the specific shaper.
    254       *
    255       * If designer designed for 'mymr' tag, also send to default
    256       * shaper.  That's tag used from before Myanmar shaping spec
    257       * was developed.  The shaping spec uses 'mym2' tag. */
    258      if (gsub_script == HB_TAG ('D','F','L','T') ||
    259   gsub_script == HB_TAG ('l','a','t','n') ||
    260   gsub_script == HB_TAG ('m','y','m','r'))
    261 return &_hb_ot_shaper_default;
    262      else
    263 return &_hb_ot_shaper_myanmar;
    264 
    265 
    266 #ifndef HB_NO_OT_SHAPER_MYANMAR_ZAWGYI
    267 #define HB_SCRIPT_MYANMAR_ZAWGYI	((hb_script_t) HB_TAG ('Q','a','a','g'))
    268    case HB_SCRIPT_MYANMAR_ZAWGYI:
    269    /* https://github.com/harfbuzz/harfbuzz/issues/1162 */
    270 
    271      return &_hb_ot_shaper_myanmar_zawgyi;
    272 #endif
    273 
    274 
    275    /* Unicode-2.0 additions */
    276    case HB_SCRIPT_TIBETAN:
    277 
    278    /* Unicode-3.0 additions */
    279    case HB_SCRIPT_MONGOLIAN:
    280    case HB_SCRIPT_SINHALA:
    281 
    282    /* Unicode-3.2 additions */
    283    case HB_SCRIPT_BUHID:
    284    case HB_SCRIPT_HANUNOO:
    285    case HB_SCRIPT_TAGALOG:
    286    case HB_SCRIPT_TAGBANWA:
    287 
    288    /* Unicode-4.0 additions */
    289    case HB_SCRIPT_LIMBU:
    290    case HB_SCRIPT_TAI_LE:
    291 
    292    /* Unicode-4.1 additions */
    293    case HB_SCRIPT_BUGINESE:
    294    case HB_SCRIPT_KHAROSHTHI:
    295    case HB_SCRIPT_SYLOTI_NAGRI:
    296    case HB_SCRIPT_TIFINAGH:
    297 
    298    /* Unicode-5.0 additions */
    299    case HB_SCRIPT_BALINESE:
    300    case HB_SCRIPT_NKO:
    301    case HB_SCRIPT_PHAGS_PA:
    302 
    303    /* Unicode-5.1 additions */
    304    case HB_SCRIPT_CHAM:
    305    case HB_SCRIPT_KAYAH_LI:
    306    case HB_SCRIPT_LEPCHA:
    307    case HB_SCRIPT_REJANG:
    308    case HB_SCRIPT_SAURASHTRA:
    309    case HB_SCRIPT_SUNDANESE:
    310 
    311    /* Unicode-5.2 additions */
    312    case HB_SCRIPT_EGYPTIAN_HIEROGLYPHS:
    313    case HB_SCRIPT_JAVANESE:
    314    case HB_SCRIPT_KAITHI:
    315    case HB_SCRIPT_MEETEI_MAYEK:
    316    case HB_SCRIPT_TAI_THAM:
    317    case HB_SCRIPT_TAI_VIET:
    318 
    319    /* Unicode-6.0 additions */
    320    case HB_SCRIPT_BATAK:
    321    case HB_SCRIPT_BRAHMI:
    322    case HB_SCRIPT_MANDAIC:
    323 
    324    /* Unicode-6.1 additions */
    325    case HB_SCRIPT_CHAKMA:
    326    case HB_SCRIPT_MIAO:
    327    case HB_SCRIPT_SHARADA:
    328    case HB_SCRIPT_TAKRI:
    329 
    330    /* Unicode-7.0 additions */
    331    case HB_SCRIPT_DUPLOYAN:
    332    case HB_SCRIPT_GRANTHA:
    333    case HB_SCRIPT_KHOJKI:
    334    case HB_SCRIPT_KHUDAWADI:
    335    case HB_SCRIPT_MAHAJANI:
    336    case HB_SCRIPT_MANICHAEAN:
    337    case HB_SCRIPT_MODI:
    338    case HB_SCRIPT_PAHAWH_HMONG:
    339    case HB_SCRIPT_PSALTER_PAHLAVI:
    340    case HB_SCRIPT_SIDDHAM:
    341    case HB_SCRIPT_TIRHUTA:
    342 
    343    /* Unicode-8.0 additions */
    344    case HB_SCRIPT_AHOM:
    345    case HB_SCRIPT_MULTANI:
    346 
    347    /* Unicode-9.0 additions */
    348    case HB_SCRIPT_ADLAM:
    349    case HB_SCRIPT_BHAIKSUKI:
    350    case HB_SCRIPT_MARCHEN:
    351    case HB_SCRIPT_NEWA:
    352 
    353    /* Unicode-10.0 additions */
    354    case HB_SCRIPT_MASARAM_GONDI:
    355    case HB_SCRIPT_SOYOMBO:
    356    case HB_SCRIPT_ZANABAZAR_SQUARE:
    357 
    358    /* Unicode-11.0 additions */
    359    case HB_SCRIPT_DOGRA:
    360    case HB_SCRIPT_GUNJALA_GONDI:
    361    case HB_SCRIPT_HANIFI_ROHINGYA:
    362    case HB_SCRIPT_MAKASAR:
    363    case HB_SCRIPT_MEDEFAIDRIN:
    364    case HB_SCRIPT_OLD_SOGDIAN:
    365    case HB_SCRIPT_SOGDIAN:
    366 
    367    /* Unicode-12.0 additions */
    368    case HB_SCRIPT_ELYMAIC:
    369    case HB_SCRIPT_NANDINAGARI:
    370    case HB_SCRIPT_NYIAKENG_PUACHUE_HMONG:
    371    case HB_SCRIPT_WANCHO:
    372 
    373    /* Unicode-13.0 additions */
    374    case HB_SCRIPT_CHORASMIAN:
    375    case HB_SCRIPT_DIVES_AKURU:
    376    case HB_SCRIPT_KHITAN_SMALL_SCRIPT:
    377    case HB_SCRIPT_YEZIDI:
    378 
    379    /* Unicode-14.0 additions */
    380    case HB_SCRIPT_CYPRO_MINOAN:
    381    case HB_SCRIPT_OLD_UYGHUR:
    382    case HB_SCRIPT_TANGSA:
    383    case HB_SCRIPT_TOTO:
    384    case HB_SCRIPT_VITHKUQI:
    385 
    386    /* Unicode-15.0 additions */
    387    case HB_SCRIPT_KAWI:
    388    case HB_SCRIPT_NAG_MUNDARI:
    389 
    390    /* Unicode-16.0 additions */
    391    case HB_SCRIPT_GARAY:
    392    case HB_SCRIPT_GURUNG_KHEMA:
    393    case HB_SCRIPT_KIRAT_RAI:
    394    case HB_SCRIPT_OL_ONAL:
    395    case HB_SCRIPT_SUNUWAR:
    396    case HB_SCRIPT_TODHRI:
    397    case HB_SCRIPT_TULU_TIGALARI:
    398 
    399    /* Unicode-17.0 additions */
    400    case HB_SCRIPT_BERIA_ERFE:
    401    case HB_SCRIPT_SIDETIC:
    402    case HB_SCRIPT_TAI_YO:
    403    case HB_SCRIPT_TOLONG_SIKI:
    404 
    405      /* If the designer designed the font for the 'DFLT' script,
    406       * (or we ended up arbitrarily pick 'latn'), use the default shaper.
    407       * Otherwise, use the specific shaper.
    408       * Note that for some simple scripts, there may not be *any*
    409       * GSUB/GPOS needed, so there may be no scripts found! */
    410      if (gsub_script == HB_TAG ('D','F','L','T') ||
    411   gsub_script == HB_TAG ('l','a','t','n'))
    412 return &_hb_ot_shaper_default;
    413      else
    414 return &_hb_ot_shaper_use;
    415  }
    416 }
    417 
    418 
    419 #endif /* HB_OT_SHAPER_HH */