LCOV - code coverage report
Current view: directory - gfx/harfbuzz/src - hb-ot-shape-complex-arabic.cc (source / functions) Found Hit Coverage
Test: app.info Lines: 50 0 0.0 %
Date: 2012-06-02 Functions: 4 0 0.0 %

       1                 : /*
       2                 :  * Copyright © 2010  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                 : #include "hb-ot-shape-complex-private.hh"
      28                 : 
      29                 : 
      30                 : 
      31                 : /* buffer var allocations */
      32                 : #define arabic_shaping_action() complex_var_temporary_u16() /* arabic shaping action */
      33                 : 
      34                 : 
      35                 : /*
      36                 :  * Bits used in the joining tables
      37                 :  */
      38                 : enum {
      39                 :   JOINING_TYPE_U                = 0,
      40                 :   JOINING_TYPE_R                = 1,
      41                 :   JOINING_TYPE_D                = 2,
      42                 :   JOINING_TYPE_C                = JOINING_TYPE_D,
      43                 :   JOINING_GROUP_ALAPH           = 3,
      44                 :   JOINING_GROUP_DALATH_RISH     = 4,
      45                 :   NUM_STATE_MACHINE_COLS        = 5,
      46                 : 
      47                 :   /* We deliberately don't have a JOINING_TYPE_L since that's unused in Unicode. */
      48                 : 
      49                 :   JOINING_TYPE_T = 6,
      50                 :   JOINING_TYPE_X = 7  /* means: use general-category to choose between U or T. */
      51                 : };
      52                 : 
      53                 : /*
      54                 :  * Joining types:
      55                 :  */
      56                 : 
      57                 : #include "hb-ot-shape-complex-arabic-table.hh"
      58                 : 
      59               0 : static unsigned int get_joining_type (hb_codepoint_t u, hb_unicode_general_category_t gen_cat)
      60                 : {
      61                 :   /* TODO Macroize the magic bit operations */
      62                 : 
      63               0 :   if (likely (hb_in_range<hb_codepoint_t> (u, JOINING_TABLE_FIRST, JOINING_TABLE_LAST))) {
      64               0 :     unsigned int j_type = joining_table[u - JOINING_TABLE_FIRST];
      65               0 :     if (likely (j_type != JOINING_TYPE_X))
      66               0 :       return j_type;
      67                 :   }
      68                 : 
      69                 :   /* Mongolian joining data is not in ArabicJoining.txt yet */
      70               0 :   if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1800, 0x18AF)))
      71                 :   {
      72                 :     /* All letters, SIBE SYLLABLE BOUNDARY MARKER, and NIRUGU are D */
      73               0 :     if (gen_cat == HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER || u == 0x1807 || u == 0x180A)
      74               0 :       return JOINING_TYPE_D;
      75                 :   }
      76                 : 
      77               0 :   if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x200C, 0x200D))) {
      78               0 :     return u == 0x200C ? JOINING_TYPE_U : JOINING_TYPE_C;
      79                 :   }
      80                 : 
      81                 :   return (FLAG(gen_cat) & (FLAG(HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | FLAG(HB_UNICODE_GENERAL_CATEGORY_FORMAT))) ?
      82               0 :          JOINING_TYPE_T : JOINING_TYPE_U;
      83                 : }
      84                 : 
      85                 : 
      86                 : 
      87                 : static const hb_tag_t arabic_syriac_features[] =
      88                 : {
      89                 :   HB_TAG('i','n','i','t'),
      90                 :   HB_TAG('m','e','d','i'),
      91                 :   HB_TAG('f','i','n','a'),
      92                 :   HB_TAG('i','s','o','l'),
      93                 :   /* Syriac */
      94                 :   HB_TAG('m','e','d','2'),
      95                 :   HB_TAG('f','i','n','2'),
      96                 :   HB_TAG('f','i','n','3'),
      97                 :   HB_TAG_NONE
      98                 : };
      99                 : 
     100                 : 
     101                 : /* Same order as the feature array */
     102                 : enum {
     103                 :   INIT,
     104                 :   MEDI,
     105                 :   FINA,
     106                 :   ISOL,
     107                 : 
     108                 :   /* Syriac */
     109                 :   MED2,
     110                 :   FIN2,
     111                 :   FIN3,
     112                 : 
     113                 :   NONE,
     114                 : 
     115                 :   COMMON_NUM_FEATURES = 4,
     116                 :   SYRIAC_NUM_FEATURES = 7,
     117                 :   TOTAL_NUM_FEATURES = NONE
     118                 : };
     119                 : 
     120                 : static const struct arabic_state_table_entry {
     121                 :         uint8_t prev_action;
     122                 :         uint8_t curr_action;
     123                 :         uint16_t next_state;
     124                 : } arabic_state_table[][NUM_STATE_MACHINE_COLS] =
     125                 : {
     126                 :   /*   jt_U,          jt_R,          jt_D,          jg_ALAPH,      jg_DALATH_RISH */
     127                 : 
     128                 :   /* State 0: prev was U, not willing to join. */
     129                 :   { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,ISOL,1}, {NONE,ISOL,6}, },
     130                 : 
     131                 :   /* State 1: prev was R or ISOL/ALAPH, not willing to join. */
     132                 :   { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN2,5}, {NONE,ISOL,6}, },
     133                 : 
     134                 :   /* State 2: prev was D/ISOL, willing to join. */
     135                 :   { {NONE,NONE,0}, {INIT,FINA,1}, {INIT,FINA,3}, {INIT,FINA,4}, {INIT,FINA,6}, },
     136                 : 
     137                 :   /* State 3: prev was D/FINA, willing to join. */
     138                 :   { {NONE,NONE,0}, {MEDI,FINA,1}, {MEDI,FINA,3}, {MEDI,FINA,4}, {MEDI,FINA,6}, },
     139                 : 
     140                 :   /* State 4: prev was FINA ALAPH, not willing to join. */
     141                 :   { {NONE,NONE,0}, {MED2,ISOL,1}, {MED2,ISOL,2}, {MED2,FIN2,5}, {MED2,ISOL,6}, },
     142                 : 
     143                 :   /* State 5: prev was FIN2/FIN3 ALAPH, not willing to join. */
     144                 :   { {NONE,NONE,0}, {ISOL,ISOL,1}, {ISOL,ISOL,2}, {ISOL,FIN2,5}, {ISOL,ISOL,6}, },
     145                 : 
     146                 :   /* State 6: prev was DALATH/RISH, not willing to join. */
     147                 :   { {NONE,NONE,0}, {NONE,ISOL,1}, {NONE,ISOL,2}, {NONE,FIN3,5}, {NONE,ISOL,6}, }
     148                 : };
     149                 : 
     150                 : 
     151                 : 
     152                 : void
     153               0 : _hb_ot_shape_complex_collect_features_arabic (hb_ot_map_builder_t *map, const hb_segment_properties_t  *props)
     154                 : {
     155                 :   /* For Language forms (in ArabicOT speak), we do the iso/fina/medi/init together,
     156                 :    * then rlig and calt each in their own stage.  This makes IranNastaliq's ALLAH
     157                 :    * ligature work correctly. It's unfortunate though...
     158                 :    *
     159                 :    * This also makes Arial Bold in Windows7 work.  See:
     160                 :    * https://bugzilla.mozilla.org/show_bug.cgi?id=644184
     161                 :    *
     162                 :    * TODO: Add test cases for these two.
     163                 :    */
     164                 : 
     165               0 :   map->add_bool_feature (HB_TAG('c','c','m','p'));
     166               0 :   map->add_bool_feature (HB_TAG('l','o','c','l'));
     167                 : 
     168               0 :   map->add_gsub_pause (NULL, NULL);
     169                 : 
     170               0 :   unsigned int num_features = props->script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
     171               0 :   for (unsigned int i = 0; i < num_features; i++)
     172               0 :     map->add_bool_feature (arabic_syriac_features[i], false);
     173                 : 
     174               0 :   map->add_gsub_pause (NULL, NULL);
     175                 : 
     176               0 :   map->add_bool_feature (HB_TAG('r','l','i','g'));
     177               0 :   map->add_gsub_pause (NULL, NULL);
     178                 : 
     179               0 :   map->add_bool_feature (HB_TAG('c','a','l','t'));
     180               0 :   map->add_gsub_pause (NULL, NULL);
     181                 : 
     182                 :   /* ArabicOT spec enables 'cswh' for Arabic where as for basic shaper it's disabled by default. */
     183               0 :   map->add_bool_feature (HB_TAG('c','s','w','h'));
     184               0 : }
     185                 : 
     186                 : bool
     187               0 : _hb_ot_shape_complex_prefer_decomposed_arabic (void)
     188                 : {
     189               0 :   return FALSE;
     190                 : }
     191                 : 
     192                 : void
     193               0 : _hb_ot_shape_complex_setup_masks_arabic (hb_ot_map_t *map, hb_buffer_t *buffer)
     194                 : {
     195               0 :   unsigned int count = buffer->len;
     196               0 :   unsigned int prev = 0, state = 0;
     197                 : 
     198               0 :   HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action);
     199                 : 
     200               0 :   for (unsigned int i = 0; i < count; i++)
     201                 :   {
     202               0 :     unsigned int this_type = get_joining_type (buffer->info[i].codepoint, (hb_unicode_general_category_t) buffer->info[i].general_category());
     203                 : 
     204               0 :     if (unlikely (this_type == JOINING_TYPE_T)) {
     205               0 :       buffer->info[i].arabic_shaping_action() = NONE;
     206               0 :       continue;
     207                 :     }
     208                 : 
     209               0 :     const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
     210                 : 
     211               0 :     if (entry->prev_action != NONE)
     212               0 :       buffer->info[prev].arabic_shaping_action() = entry->prev_action;
     213                 : 
     214               0 :     buffer->info[i].arabic_shaping_action() = entry->curr_action;
     215                 : 
     216               0 :     prev = i;
     217               0 :     state = entry->next_state;
     218                 :   }
     219                 : 
     220               0 :   hb_mask_t mask_array[TOTAL_NUM_FEATURES + 1] = {0};
     221               0 :   unsigned int num_masks = buffer->props.script == HB_SCRIPT_SYRIAC ? SYRIAC_NUM_FEATURES : COMMON_NUM_FEATURES;
     222               0 :   for (unsigned int i = 0; i < num_masks; i++)
     223               0 :     mask_array[i] = map->get_1_mask (arabic_syriac_features[i]);
     224                 : 
     225               0 :   for (unsigned int i = 0; i < count; i++)
     226               0 :     buffer->info[i].mask |= mask_array[buffer->info[i].arabic_shaping_action()];
     227                 : 
     228               0 :   HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
     229               0 : }
     230                 : 
     231                 : 

Generated by: LCOV version 1.7