| Line | Source Code | Coverage | 
|---|
| 1 | /*  | - | 
| 2 |  * Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)  | - | 
| 3 |  *  | - | 
| 4 |  * This is part of HarfBuzz, an OpenType Layout engine 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 |   | - | 
| 25 | #include "harfbuzz-shaper.h"  | - | 
| 26 | #include "harfbuzz-shaper-private.h"  | - | 
| 27 | #include "harfbuzz-external.h"  | - | 
| 28 |   | - | 
| 29 | #include <assert.h>  | - | 
| 30 | #include <stdio.h>  | - | 
| 31 |   | - | 
| 32 | #define LIBTHAI_MAJOR   0  | - | 
| 33 |   | - | 
| 34 | /*  | - | 
| 35 |  * if libthai changed please update these codes too.  | - | 
| 36 |  */  | - | 
| 37 | struct thcell_t {  | - | 
| 38 |     unsigned char base;      /**< base character */  | - | 
| 39 |     unsigned char hilo;      /**< upper/lower vowel/diacritic */  | - | 
| 40 |     unsigned char top;       /**< top-level mark */  | - | 
| 41 | };  | - | 
| 42 | typedef int (*th_brk_def) (const unsigned char*, int*, size_t);  | - | 
| 43 | typedef int (*th_render_cell_tis_def) (struct thcell_t cell, unsigned char res[], size_t res_sz, int is_decomp_am);  | - | 
| 44 | typedef int (*th_render_cell_win_def) (struct thcell_t cell, unsigned char res[], size_t res_sz, int is_decomp_am);  | - | 
| 45 | typedef int (*th_render_cell_mac_def) (struct thcell_t cell, unsigned char res[], size_t res_sz, int is_decomp_am);  | - | 
| 46 | typedef size_t (*th_next_cell_def) (const unsigned char *, size_t, struct thcell_t *, int);  | - | 
| 47 |   | - | 
| 48 | /* libthai releated function handles */  | - | 
| 49 | static th_brk_def th_brk = 0;  | - | 
| 50 | static th_next_cell_def th_next_cell = 0;  | - | 
| 51 | static th_render_cell_tis_def th_render_cell_tis = 0;  | - | 
| 52 | static th_render_cell_win_def th_render_cell_win = 0;  | - | 
| 53 | static th_render_cell_mac_def th_render_cell_mac = 0;  | - | 
| 54 |   | - | 
| 55 | static int init_libthai() {  | - | 
| 56 |     static HB_Bool initialized = false;  | - | 
| 57 |     if (!initialized && (!th_brk || !th_next_cell || !th_render_cell_tis || !th_render_cell_win || !th_render_cell_mac)) { evaluated:  !initialized| yes Evaluation Count:2  | yes Evaluation Count:137  |  
  partially evaluated:  !th_brk| yes Evaluation Count:2  | no Evaluation Count:0  |  
  never evaluated: !th_next_cell never evaluated: !th_render_cell_tis never evaluated: !th_render_cell_win never evaluated: !th_render_cell_mac  | 0-137 | 
| 58 |         th_brk = (th_brk_def) HB_Library_Resolve("thai", (int)LIBTHAI_MAJOR, "th_brk"); executed (the execution status of this line is deduced):  th_brk = (th_brk_def) HB_Library_Resolve("thai", (int)0, "th_brk");  | - | 
| 59 |         th_next_cell = (th_next_cell_def)HB_Library_Resolve("thai", LIBTHAI_MAJOR, "th_next_cell"); executed (the execution status of this line is deduced):  th_next_cell = (th_next_cell_def)HB_Library_Resolve("thai", 0, "th_next_cell");  | - | 
| 60 |         th_render_cell_tis = (th_render_cell_tis_def) HB_Library_Resolve("thai", (int)LIBTHAI_MAJOR, "th_render_cell_tis"); executed (the execution status of this line is deduced):  th_render_cell_tis = (th_render_cell_tis_def) HB_Library_Resolve("thai", (int)0, "th_render_cell_tis");  | - | 
| 61 |         th_render_cell_win = (th_render_cell_win_def) HB_Library_Resolve("thai", (int)LIBTHAI_MAJOR, "th_render_cell_win"); executed (the execution status of this line is deduced):  th_render_cell_win = (th_render_cell_win_def) HB_Library_Resolve("thai", (int)0, "th_render_cell_win");  | - | 
| 62 |         th_render_cell_mac = (th_render_cell_mac_def) HB_Library_Resolve("thai", (int)LIBTHAI_MAJOR, "th_render_cell_mac"); executed (the execution status of this line is deduced):  th_render_cell_mac = (th_render_cell_mac_def) HB_Library_Resolve("thai", (int)0, "th_render_cell_mac");  | - | 
| 63 |         initialized = true; executed (the execution status of this line is deduced):  initialized = true;  | - | 
| 64 |     } executed:  }Execution Count:2   | 2 | 
| 65 |     if (th_brk && th_next_cell && th_render_cell_tis && th_render_cell_win && th_render_cell_mac) partially evaluated:  th_brk| yes Evaluation Count:139  | no Evaluation Count:0  |  
  partially evaluated:  th_next_cell| yes Evaluation Count:139  | no Evaluation Count:0  |  
  partially evaluated:  th_render_cell_tis| yes Evaluation Count:139  | no Evaluation Count:0  |  
  partially evaluated:  th_render_cell_win| yes Evaluation Count:139  | no Evaluation Count:0  |  
  partially evaluated:  th_render_cell_mac| yes Evaluation Count:139  | no Evaluation Count:0  |  
   | 0-139 | 
| 66 |         return 1; executed:  return 1;Execution Count:139   | 139 | 
| 67 |     else  | - | 
| 68 |         return 0; never executed: return 0;  | 0 | 
| 69 | }  | - | 
| 70 |   | - | 
| 71 | static void to_tis620(const HB_UChar16 *string, hb_uint32 len, const char *cstr)  | - | 
| 72 | {  | - | 
| 73 |     hb_uint32 i; executed (the execution status of this line is deduced):  hb_uint32 i;  | - | 
| 74 |     unsigned char *result = (unsigned char *)cstr; executed (the execution status of this line is deduced):  unsigned char *result = (unsigned char *)cstr;  | - | 
| 75 |   | - | 
| 76 |     for (i = 0; i < len; ++i) { evaluated:  i < len| yes Evaluation Count:622666  | yes Evaluation Count:139  |  
   | 139-622666 | 
| 77 |         if (string[i] <= 0xa0) evaluated:  string[i] <= 0xa0| yes Evaluation Count:28  | yes Evaluation Count:622638  |  
   | 28-622638 | 
| 78 |             result[i] = (unsigned char)string[i]; executed:  result[i] = (unsigned char)string[i];Execution Count:28   | 28 | 
| 79 |         else if (string[i] >= 0xe01 && string[i] <= 0xe5b) evaluated:  string[i] >= 0xe01| yes Evaluation Count:622636  | yes Evaluation Count:2  |  
  evaluated:  string[i] <= 0xe5b| yes Evaluation Count:619560  | yes Evaluation Count:3076  |  
   | 2-622636 | 
| 80 |             result[i] = (unsigned char)(string[i] - 0xe00 + 0xa0); executed:  result[i] = (unsigned char)(string[i] - 0xe00 + 0xa0);Execution Count:619560   | 619560 | 
| 81 |         else  | - | 
| 82 |             result[i] = (unsigned char)~0; // Same encoding as libthai uses for invalid chars executed:  result[i] = (unsigned char)~0;Execution Count:3078   | 3078 | 
| 83 |     }  | - | 
| 84 |   | - | 
| 85 |     result[len] = 0; executed (the execution status of this line is deduced):  result[len] = 0;  | - | 
| 86 | } executed:  }Execution Count:139   | 139 | 
| 87 |   | - | 
| 88 | /*  | - | 
| 89 |  * ---------------------------------------------------------------------------  | - | 
| 90 |  * Thai Shaper / Attributes  | - | 
| 91 |  * ---------------------------------------------------------------------------  | - | 
| 92 |  */  | - | 
| 93 |   | - | 
| 94 | /*  | - | 
| 95 |  * USe basic_features prepare for future adding.  | - | 
| 96 |  */  | - | 
| 97 | #ifndef NO_OPENTYPE  | - | 
| 98 | static const HB_OpenTypeFeature thai_features[] = {  | - | 
| 99 |     { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },  | - | 
| 100 |     { HB_MAKE_TAG('l', 'i', 'g', 'a'), CcmpProperty },  | - | 
| 101 |     { HB_MAKE_TAG('c', 'l', 'i', 'g'), CcmpProperty },  | - | 
| 102 |     {0, 0}  | - | 
| 103 | };  | - | 
| 104 | #endif  | - | 
| 105 |   | - | 
| 106 | /* TIS-to-Unicode glyph maps for characters 0x80-0xff */  | - | 
| 107 | static int tis620_0[128] = {  | - | 
| 108 |     /**/ 0,      0,      0,      0,      0,      0,      0,      0,  | - | 
| 109 |     /**/ 0,      0,      0,      0,      0,      0,      0,      0,  | - | 
| 110 |     /**/ 0,      0,      0,      0,      0,      0,      0,      0,  | - | 
| 111 |     /**/ 0,      0,      0,      0,      0,      0,      0,      0,  | - | 
| 112 |     0x0020, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07,  | - | 
| 113 |     0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f,  | - | 
| 114 |     0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17,  | - | 
| 115 |     0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f,  | - | 
| 116 |     0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27,  | - | 
| 117 |     0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f,  | - | 
| 118 |     0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37,  | - | 
| 119 |     0x0e38, 0x0e39, 0x0e3a,      0,      0,      0,      0, 0x0e3f,  | - | 
| 120 |     0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47,  | - | 
| 121 |     0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f,  | - | 
| 122 |     0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57,  | - | 
| 123 |     0x0e58, 0x0e59, 0x0e5a, 0x0e5b,      0,      0,      0,      0  | - | 
| 124 | };  | - | 
| 125 |   | - | 
| 126 | static int tis620_1[128] = {  | - | 
| 127 |     0xf89e,      0,      0, 0xf88c, 0xf88f, 0xf892, 0xf895, 0xf898,  | - | 
| 128 |     0xf88b, 0xf88e, 0xf891, 0xf894, 0xf897,      0,      0, 0xf899,  | - | 
| 129 |     0xf89a,      0, 0xf884, 0xf889, 0xf885, 0xf886, 0xf887, 0xf888,  | - | 
| 130 |     0xf88a, 0xf88d, 0xf890, 0xf893, 0xf896,      0,      0,      0,  | - | 
| 131 |     /**/ 0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07,  | - | 
| 132 |     0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f,  | - | 
| 133 |     0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17,  | - | 
| 134 |     0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f,  | - | 
| 135 |     0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27,  | - | 
| 136 |     0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f,  | - | 
| 137 |     0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37,  | - | 
| 138 |     0x0e38, 0x0e39, 0x0e3a,      0,      0,      0,      0, 0x0e3f,  | - | 
| 139 |     0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47,  | - | 
| 140 |     0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d,      0, 0x0e4f,  | - | 
| 141 |     0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57,  | - | 
| 142 |     0x0e58, 0x0e59,      0,      0, 0xf89b, 0xf89c, 0xf89d,      0  | - | 
| 143 | };  | - | 
| 144 |   | - | 
| 145 | static int tis620_2[128] = {  | - | 
| 146 |     0xf700, 0xf701, 0xf702, 0xf703, 0xf704, 0x2026, 0xf705, 0xf706,  | - | 
| 147 |     0xf707, 0xf708, 0xf709, 0xf70a, 0xf70b, 0xf70c, 0xf70d, 0xf70e,  | - | 
| 148 |     0xf70f, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,  | - | 
| 149 |     0xf710, 0xf711, 0xf712, 0xf713, 0xf714, 0xf715, 0xf716, 0xf717,  | - | 
| 150 |     0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07,  | - | 
| 151 |     0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f,  | - | 
| 152 |     0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17,  | - | 
| 153 |     0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f,  | - | 
| 154 |     0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27,  | - | 
| 155 |     0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f,  | - | 
| 156 |     0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37,  | - | 
| 157 |     0x0e38, 0x0e39, 0x0e3a,      0,      0,      0,      0, 0x0e3f,  | - | 
| 158 |     0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47,  | - | 
| 159 |     0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f,  | - | 
| 160 |     0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57,  | - | 
| 161 |     0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0xf718, 0xf719, 0xf71a,      0  | - | 
| 162 | };  | - | 
| 163 |   | - | 
| 164 | enum ThaiFontType {  | - | 
| 165 |     TIS,  | - | 
| 166 |     WIN,  | - | 
| 167 |     MAC  | - | 
| 168 | };  | - | 
| 169 |   | - | 
| 170 | static int thai_get_glyph_index (ThaiFontType font_type, unsigned char c)  | - | 
| 171 | {  | - | 
| 172 |     switch (font_type){  | - | 
| 173 |         case TIS: return (c & 0x80) ? tis620_0[c & 0x7f] : c; executed:  return (c & 0x80) ? tis620_0[c & 0x7f] : c;Execution Count:412706   | 412706 | 
| 174 |         case WIN: return (c & 0x80) ? tis620_1[c & 0x7f] : c; never executed: return (c & 0x80) ? tis620_1[c & 0x7f] : c;  | 0 | 
| 175 |         case MAC: return (c & 0x80) ? tis620_2[c & 0x7f] : c; never executed: return (c & 0x80) ? tis620_2[c & 0x7f] : c;  | 0 | 
| 176 |         default:  return 0; never executed: return 0;  | 0 | 
| 177 |     }  | - | 
| 178 | }  | 0 | 
| 179 |   | - | 
| 180 | static int thai_contain_glyphs (HB_ShaperItem *shaper_item, const int glyph_map[128])  | - | 
| 181 | {  | - | 
| 182 |     unsigned char c; executed (the execution status of this line is deduced):  unsigned char c;  | - | 
| 183 |   | - | 
| 184 |     for (c = 0; c < 0x80; c++) { partially evaluated:  c < 0x80| yes Evaluation Count:4  | no Evaluation Count:0  |  
   | 0-4 | 
| 185 |         if ( glyph_map[c] ) { partially evaluated:  glyph_map[c]| yes Evaluation Count:4  | no Evaluation Count:0  |  
   | 0-4 | 
| 186 |             if ( !shaper_item->font->klass->canRender (shaper_item->font, (HB_UChar16 *) &glyph_map[c], 1) ) partially evaluated:  !shaper_item->font->klass->canRender (shaper_item->font, (HB_UChar16 *) &glyph_map[c], 1)| yes Evaluation Count:4  | no Evaluation Count:0  |  
   | 0-4 | 
| 187 |                 return 0; executed:  return 0;Execution Count:4   | 4 | 
| 188 |         }  | 0 | 
| 189 |     }  | 0 | 
| 190 |     return 1; never executed: return 1;  | 0 | 
| 191 | }  | - | 
| 192 |   | - | 
| 193 | static ThaiFontType getThaiFontType(HB_ShaperItem *shaper_item)  | - | 
| 194 | {  | - | 
| 195 |     if ( thai_contain_glyphs (shaper_item, tis620_2) ) partially evaluated:  thai_contain_glyphs (shaper_item, tis620_2)| no Evaluation Count:0  | yes Evaluation Count:2  |  
   | 0-2 | 
| 196 |         return MAC; never executed: return MAC;  | 0 | 
| 197 |     else if ( thai_contain_glyphs (shaper_item, tis620_1) ) partially evaluated:  thai_contain_glyphs (shaper_item, tis620_1)| no Evaluation Count:0  | yes Evaluation Count:2  |  
   | 0-2 | 
| 198 |         return WIN; never executed: return WIN;  | 0 | 
| 199 |     else  | - | 
| 200 |         return TIS; executed:  return TIS;Execution Count:2   | 2 | 
| 201 | }  | - | 
| 202 |   | - | 
| 203 | /*  | - | 
| 204 |  * convert to the correct display level of THAI vowels and marks.  | - | 
| 205 |  */  | - | 
| 206 | static HB_Bool HB_ThaiConvertStringToGlyphIndices (HB_ShaperItem *item)  | - | 
| 207 | {  | - | 
| 208 |     char s[128]; executed (the execution status of this line is deduced):  char s[128];  | - | 
| 209 |     char *cstr = s; executed (the execution status of this line is deduced):  char *cstr = s;  | - | 
| 210 |     const HB_UChar16 *string = item->string + item->item.pos; executed (the execution status of this line is deduced):  const HB_UChar16 *string = item->string + item->item.pos;  | - | 
| 211 |     const hb_uint32 len = item->item.length; executed (the execution status of this line is deduced):  const hb_uint32 len = item->item.length;  | - | 
| 212 |     unsigned short *logClusters = item->log_clusters; executed (the execution status of this line is deduced):  unsigned short *logClusters = item->log_clusters;  | - | 
| 213 |     hb_uint32 i = 0, slen = 0; executed (the execution status of this line is deduced):  hb_uint32 i = 0, slen = 0;  | - | 
| 214 |   | - | 
| 215 |     if (!init_libthai()) partially evaluated:  !init_libthai()| no Evaluation Count:0  | yes Evaluation Count:120  |  
   | 0-120 | 
| 216 |         return HB_BasicShape (item); never executed: return HB_BasicShape (item);  | 0 | 
| 217 |   | - | 
| 218 |     if (len >= 128) evaluated:  len >= 128| yes Evaluation Count:106  | yes Evaluation Count:14  |  
   | 14-106 | 
| 219 |         cstr = (char *)malloc(len*sizeof(char) + 1); executed:  cstr = (char *)malloc(len*sizeof(char) + 1);Execution Count:106   | 106 | 
| 220 |   | - | 
| 221 |     if (!cstr) partially evaluated:  !cstr| no Evaluation Count:0  | yes Evaluation Count:120  |  
   | 0-120 | 
| 222 |         return HB_BasicShape (item); never executed: return HB_BasicShape (item);  | 0 | 
| 223 |   | - | 
| 224 |     to_tis620(string, len, cstr); executed (the execution status of this line is deduced):  to_tis620(string, len, cstr);  | - | 
| 225 |   | - | 
| 226 |     /* Get font type */  | - | 
| 227 |     static ThaiFontType font_type;  | - | 
| 228 |     static HB_Font itemFont;  | - | 
| 229 |     if (itemFont != item->font) { evaluated:  itemFont != item->font| yes Evaluation Count:2  | yes Evaluation Count:118  |  
   | 2-118 | 
| 230 |         font_type = getThaiFontType (item); executed (the execution status of this line is deduced):  font_type = getThaiFontType (item);  | - | 
| 231 |         itemFont = item->font; executed (the execution status of this line is deduced):  itemFont = item->font;  | - | 
| 232 |     } executed:  }Execution Count:2   | 2 | 
| 233 |   | - | 
| 234 |     /* allocate temporary glyphs buffers */  | - | 
| 235 |     HB_STACKARRAY (HB_UChar16, glyphString, (item->item.length * 2)); executed:  glyphString = (HB_UChar16 *)malloc(((item->item.length * 2)) * sizeof(HB_UChar16));Execution Count:102  evaluated:  ((item->item.length * 2)) >= 512| yes Evaluation Count:102  | yes Evaluation Count:18  |  
   | 18-102 | 
| 236 |   | - | 
| 237 |     while (i < item->item.length) { evaluated:  i < item->item.length| yes Evaluation Count:412525  | yes Evaluation Count:120  |  
   | 120-412525 | 
| 238 |         struct thcell_t tis_cell; executed (the execution status of this line is deduced):  struct thcell_t tis_cell;  | - | 
| 239 |         unsigned char rglyphs[4]; executed (the execution status of this line is deduced):  unsigned char rglyphs[4];  | - | 
| 240 |         int cell_length; executed (the execution status of this line is deduced):  int cell_length;  | - | 
| 241 |         int lgn = 0; executed (the execution status of this line is deduced):  int lgn = 0;  | - | 
| 242 |         HB_Bool haveSaraAm = false; executed (the execution status of this line is deduced):  HB_Bool haveSaraAm = false;  | - | 
| 243 |   | - | 
| 244 |         cell_length = th_next_cell ((const unsigned char *)cstr + i, len - i, &tis_cell, true); /* !item->fixedPitch); */ executed (the execution status of this line is deduced):  cell_length = th_next_cell ((const unsigned char *)cstr + i, len - i, &tis_cell, true);  | - | 
| 245 |         haveSaraAm  = (cstr[i + cell_length - 1] == (char)0xd3); executed (the execution status of this line is deduced):  haveSaraAm = (cstr[i + cell_length - 1] == (char)0xd3);  | - | 
| 246 |   | - | 
| 247 |         /* set shaper item's log_clusters */  | - | 
| 248 |         logClusters[i] = slen; executed (the execution status of this line is deduced):  logClusters[i] = slen;  | - | 
| 249 |         for (int j = 1; j < cell_length; j++) { evaluated:  j < cell_length| yes Evaluation Count:2232  | yes Evaluation Count:412525  |  
   | 2232-412525 | 
| 250 |             logClusters[i + j] = logClusters[i]; executed (the execution status of this line is deduced):  logClusters[i + j] = logClusters[i];  | - | 
| 251 |         } executed:  }Execution Count:2232   | 2232 | 
| 252 |   | - | 
| 253 |         /* Find Logical Glyphs by font type */  | - | 
| 254 |         switch (font_type) {  | - | 
| 255 |             case TIS: lgn = th_render_cell_tis (tis_cell, rglyphs, sizeof(rglyphs) / sizeof(rglyphs[0]), true); break; executed:  break;Execution Count:412525   | 412525 | 
| 256 |             case WIN: lgn = th_render_cell_mac (tis_cell, rglyphs, sizeof(rglyphs) / sizeof(rglyphs[0]), true); break;  | 0 | 
| 257 |             case MAC: lgn = th_render_cell_win (tis_cell, rglyphs, sizeof(rglyphs) / sizeof(rglyphs[0]), true); break;  | 0 | 
| 258 |         }  | - | 
| 259 |   | - | 
| 260 |         /* Add glyphs to glyphs string and setting some attributes */  | - | 
| 261 |         for (int lgi = 0; lgi < lgn; lgi++) { evaluated:  lgi < lgn| yes Evaluation Count:822309  | yes Evaluation Count:412525  |  
   | 412525-822309 | 
| 262 |             if ( rglyphs[lgi] == 0xdd/*TH_BLANK_BASE_GLYPH*/ ) { evaluated:  rglyphs[lgi] == 0xdd| yes Evaluation Count:407552  | yes Evaluation Count:414757  |  
   | 407552-414757 | 
| 263 |                 glyphString[slen++] = C_DOTTED_CIRCLE; executed (the execution status of this line is deduced):  glyphString[slen++] = C_DOTTED_CIRCLE;  | - | 
| 264 |             } else if (cstr[i] == (signed char)~0) { executed:  }Execution Count:407552  evaluated:  cstr[i] == (signed char)~0| yes Evaluation Count:2051  | yes Evaluation Count:412706  |  
   | 2051-412706 | 
| 265 |                 // The only glyphs that should be passed to this function that cannot be mapped to  | - | 
| 266 |                 // tis620 are the ones of type Inherited class.  Pass these glyphs untouched.  | - | 
| 267 |                 glyphString[slen++] = string[i]; executed (the execution status of this line is deduced):  glyphString[slen++] = string[i];  | - | 
| 268 |                 if (string[i] == 0x200D || string[i] == 0x200C) { evaluated:  string[i] == 0x200D| yes Evaluation Count:2049  | yes Evaluation Count:2  |  
  evaluated:  string[i] == 0x200C| yes Evaluation Count:1  | yes Evaluation Count:1  |  
   | 1-2049 | 
| 269 |                     // Check that we do not run out of bounds when setting item->attributes.  If we do  | - | 
| 270 |                     // run out of bounds then this function will return false, the necessary amount of  | - | 
| 271 |                     // memory is reallocated, and this function will then be called again.  | - | 
| 272 |                     if (slen <= item->num_glyphs) evaluated:  slen <= item->num_glyphs| yes Evaluation Count:1542  | yes Evaluation Count:508  |  
   | 508-1542 | 
| 273 |                         item->attributes[slen-1].dontPrint = true; // Hide ZWJ and ZWNJ characters executed:  item->attributes[slen-1].dontPrint = true;Execution Count:1542   | 1542 | 
| 274 |                 } executed:  }Execution Count:2050   | 2050 | 
| 275 |             } else { executed:  }Execution Count:2051   | 2051 | 
| 276 |                 glyphString[slen++] = (HB_UChar16) thai_get_glyph_index (font_type, rglyphs[lgi]); executed (the execution status of this line is deduced):  glyphString[slen++] = (HB_UChar16) thai_get_glyph_index (font_type, rglyphs[lgi]);  | - | 
| 277 |             } executed:  }Execution Count:412706   | 412706 | 
| 278 |         }  | - | 
| 279 |   | - | 
| 280 |         /* Special case to handle U+0E33 (SARA AM, ำ): SARA AM is normally written at the end of a  | - | 
| 281 |          * word with a base character and an optional top character before it. For example, U+0E0B  | - | 
| 282 |          * (base), U+0E49 (top), U+0E33 (SARA AM). The sequence should be converted to 4 glyphs:  | - | 
| 283 |          * base, hilo (the little circle in the top left part of SARA AM, NIKHAHIT), top, then the  | - | 
| 284 |          * right part of SARA AM (SARA AA).  | - | 
| 285 |          *  | - | 
| 286 |          * The painting process finds out the starting glyph and ending glyph of a character  | - | 
| 287 |          * sequence by checking the logClusters array. In this case, logClusters array should  | - | 
| 288 |          * ideally be [ 0, 1, 3 ] so that glyphsStart = 0 and glyphsEnd = 3 (slen - 1) to paint out  | - | 
| 289 |          * all the glyphs generated.  | - | 
| 290 |          *  | - | 
| 291 |          * A special case in this special case is when we have no base character. When an isolated  | - | 
| 292 |          * SARA AM is processed (cell_length = 1), libthai will produce 3 glyphs: dotted circle  | - | 
| 293 |          * (indicates that the base is empty), NIKHAHIT then SARA AA. If logClusters[0] = 1, it will  | - | 
| 294 |          * paint from the second glyph in the glyphs array. So in this case logClusters[0] should  | - | 
| 295 |          * point to the first glyph it produces, aka. the dotted circle. */  | - | 
| 296 |         if (haveSaraAm) { partially evaluated:  haveSaraAm| no Evaluation Count:0  | yes Evaluation Count:412525  |  
   | 0-412525 | 
| 297 |             logClusters[i + cell_length - 1] = cell_length == 1 ? slen - 3 : slen - 1; never evaluated: cell_length == 1  | 0 | 
| 298 |             if (tis_cell.top != 0) { never evaluated: tis_cell.top != 0  | 0 | 
| 299 |                 if (cell_length > 1) { never evaluated: cell_length > 1  | 0 | 
| 300 |                     /* set the logClusters[top character] to slen - 2 as it points to the second to  | - | 
| 301 |                      * lastglyph (slen - 2) */  | - | 
| 302 |                     logClusters[i + cell_length - 2] = slen - 2; never executed (the execution status of this line is deduced):  logClusters[i + cell_length - 2] = slen - 2;  | - | 
| 303 |                 }  | 0 | 
| 304 |             }  | 0 | 
| 305 |             /* check for overflow */  | - | 
| 306 |             if (logClusters[i + cell_length - 1] > slen) never evaluated: logClusters[i + cell_length - 1] > slen  | 0 | 
| 307 |                 logClusters[i + cell_length - 1] = 0; never executed: logClusters[i + cell_length - 1] = 0;  | 0 | 
| 308 |         }  | 0 | 
| 309 |   | - | 
| 310 |         i += cell_length; executed (the execution status of this line is deduced):  i += cell_length;  | - | 
| 311 |     } executed:  }Execution Count:412525   | 412525 | 
| 312 |     glyphString[slen] = (HB_UChar16) '\0'; executed (the execution status of this line is deduced):  glyphString[slen] = (HB_UChar16) '\0';  | - | 
| 313 |   | - | 
| 314 |     /* for check, should reallocate space or not */  | - | 
| 315 |     HB_Bool spaceOK = (item->num_glyphs >= slen); executed (the execution status of this line is deduced):  HB_Bool spaceOK = (item->num_glyphs >= slen);  | - | 
| 316 |   | - | 
| 317 |     /* Convert to Glyph indices */  | - | 
| 318 |     HB_Bool haveGlyphs = item->font->klass->convertStringToGlyphIndices ( executed (the execution status of this line is deduced):  HB_Bool haveGlyphs = item->font->klass->convertStringToGlyphIndices (  | - | 
| 319 |                                           item->font, executed (the execution status of this line is deduced):  item->font,  | - | 
| 320 |                                           glyphString, slen, executed (the execution status of this line is deduced):  glyphString, slen,  | - | 
| 321 |                                           item->glyphs, &item->num_glyphs, executed (the execution status of this line is deduced):  item->glyphs, &item->num_glyphs,  | - | 
| 322 |                                           item->shaperFlags); executed (the execution status of this line is deduced):  item->shaperFlags);  | - | 
| 323 |   | - | 
| 324 |     HB_FREE_STACKARRAY (glyphString); executed:  free(glyphString);Execution Count:102  evaluated:  stackglyphString != glyphString| yes Evaluation Count:102  | yes Evaluation Count:18  |  
   | 18-102 | 
| 325 |   | - | 
| 326 |     if (len >= 128) evaluated:  len >= 128| yes Evaluation Count:106  | yes Evaluation Count:14  |  
   | 14-106 | 
| 327 |         free(cstr); executed:  free(cstr);Execution Count:106   | 106 | 
| 328 |   | - | 
| 329 |     return (haveGlyphs && spaceOK); executed:  return (haveGlyphs && spaceOK);Execution Count:120   | 120 | 
| 330 | }  | - | 
| 331 |   | - | 
| 332 | /*  | - | 
| 333 |  * set the glyph attributes heuristically.  | - | 
| 334 |  */  | - | 
| 335 | static void HB_ThaiHeuristicSetGlyphAttributes (HB_ShaperItem *item)  | - | 
| 336 | {  | - | 
| 337 |     /* Set Glyph Attributes */  | - | 
| 338 |     hb_uint32 iCluster = 0; executed (the execution status of this line is deduced):  hb_uint32 iCluster = 0;  | - | 
| 339 |     hb_uint32 length = item->item.length; executed (the execution status of this line is deduced):  hb_uint32 length = item->item.length;  | - | 
| 340 |     while (iCluster < length) { evaluated:  iCluster < length| yes Evaluation Count:206701  | yes Evaluation Count:69  |  
   | 69-206701 | 
| 341 |         int cluster_start = item->log_clusters[iCluster]; executed (the execution status of this line is deduced):  int cluster_start = item->log_clusters[iCluster];  | - | 
| 342 |         ++iCluster; executed (the execution status of this line is deduced):  ++iCluster;  | - | 
| 343 |         while (iCluster < length && item->log_clusters[iCluster] == cluster_start) { evaluated:  iCluster < length| yes Evaluation Count:207840  | yes Evaluation Count:69  |  
  evaluated:  item->log_clusters[iCluster] == cluster_start| yes Evaluation Count:1208  | yes Evaluation Count:206632  |  
   | 69-207840 | 
| 344 |             ++iCluster; executed (the execution status of this line is deduced):  ++iCluster;  | - | 
| 345 |         } executed:  }Execution Count:1208   | 1208 | 
| 346 |         int cluster_end = (iCluster < length) ? item->log_clusters[iCluster] : item->num_glyphs; evaluated:  (iCluster < length)| yes Evaluation Count:206632  | yes Evaluation Count:69  |  
   | 69-206632 | 
| 347 |         item->attributes[cluster_start].clusterStart = true; executed (the execution status of this line is deduced):  item->attributes[cluster_start].clusterStart = true;  | - | 
| 348 |         for (int i = cluster_start + 1; i < cluster_end; i++) { evaluated:  i < cluster_end| yes Evaluation Count:204984  | yes Evaluation Count:206701  |  
   | 204984-206701 | 
| 349 |             item->attributes[i].clusterStart = false; executed (the execution status of this line is deduced):  item->attributes[i].clusterStart = false;  | - | 
| 350 |         } executed:  }Execution Count:204984   | 204984 | 
| 351 |     } executed:  }Execution Count:206701   | 206701 | 
| 352 | } executed:  }Execution Count:69   | 69 | 
| 353 |   | - | 
| 354 | /*  | - | 
| 355 |  * THAI Shaping.  | - | 
| 356 |  */  | - | 
| 357 | HB_Bool HB_ThaiShape (HB_ShaperItem *shaper_item)  | - | 
| 358 | {  | - | 
| 359 |     if ( !HB_ThaiConvertStringToGlyphIndices (shaper_item) ) evaluated:  !HB_ThaiConvertStringToGlyphIndices (shaper_item)| yes Evaluation Count:51  | yes Evaluation Count:69  |  
   | 51-69 | 
| 360 |         return false; executed:  return false;Execution Count:51   | 51 | 
| 361 |   | - | 
| 362 |     HB_ThaiHeuristicSetGlyphAttributes (shaper_item); executed (the execution status of this line is deduced):  HB_ThaiHeuristicSetGlyphAttributes (shaper_item);  | - | 
| 363 |   | - | 
| 364 | #ifndef NO_OPENTYPE  | - | 
| 365 |     const int availableGlyphs = shaper_item->num_glyphs; executed (the execution status of this line is deduced):  const int availableGlyphs = shaper_item->num_glyphs;  | - | 
| 366 |     if ( HB_SelectScript (shaper_item, thai_features) ) { partially evaluated:  HB_SelectScript (shaper_item, thai_features)| yes Evaluation Count:69  | no Evaluation Count:0  |  
   | 0-69 | 
| 367 |         HB_OpenTypeShape (shaper_item, /*properties*/0); executed (the execution status of this line is deduced):  HB_OpenTypeShape (shaper_item, 0);  | - | 
| 368 |         return HB_OpenTypePosition (shaper_item, availableGlyphs, /*doLogClusters*/true); executed:  return HB_OpenTypePosition (shaper_item, availableGlyphs, true);Execution Count:69   | 69 | 
| 369 |     }  | - | 
| 370 | #endif  | - | 
| 371 |   | - | 
| 372 |     HB_HeuristicPosition (shaper_item); never executed (the execution status of this line is deduced):  HB_HeuristicPosition (shaper_item);  | - | 
| 373 |     return true; never executed: return true;  | 0 | 
| 374 | }  | - | 
| 375 |   | - | 
| 376 | /*  | - | 
| 377 |  * Thai Attributes: computes Word Break, Word Boundary and Char stop for THAI.  | - | 
| 378 |  */  | - | 
| 379 | static void HB_ThaiAssignAttributes(const HB_UChar16 *string, hb_uint32 len, HB_CharAttributes *attributes)  | - | 
| 380 | {  | - | 
| 381 |     char s[128]; executed (the execution status of this line is deduced):  char s[128];  | - | 
| 382 |     char *cstr = s; executed (the execution status of this line is deduced):  char *cstr = s;  | - | 
| 383 |     int *break_positions = 0; executed (the execution status of this line is deduced):  int *break_positions = 0;  | - | 
| 384 |     int brp[128]; executed (the execution status of this line is deduced):  int brp[128];  | - | 
| 385 |     int brp_size = 0; executed (the execution status of this line is deduced):  int brp_size = 0;  | - | 
| 386 |     hb_uint32 numbreaks, i, j, cell_length; executed (the execution status of this line is deduced):  hb_uint32 numbreaks, i, j, cell_length;  | - | 
| 387 |     struct thcell_t tis_cell; executed (the execution status of this line is deduced):  struct thcell_t tis_cell;  | - | 
| 388 |   | - | 
| 389 |     if (!init_libthai()) partially evaluated:  !init_libthai()| no Evaluation Count:0  | yes Evaluation Count:19  |  
   | 0-19 | 
| 390 |         return ;  | 0 | 
| 391 |   | - | 
| 392 |     if (len >= 128) evaluated:  len >= 128| yes Evaluation Count:5  | yes Evaluation Count:14  |  
   | 5-14 | 
| 393 |         cstr = (char *)malloc(len*sizeof(char) + 1); executed:  cstr = (char *)malloc(len*sizeof(char) + 1);Execution Count:5   | 5 | 
| 394 |   | - | 
| 395 |     to_tis620(string, len, cstr); executed (the execution status of this line is deduced):  to_tis620(string, len, cstr);  | - | 
| 396 |   | - | 
| 397 |     for (i = 0; i < len; ++i) { evaluated:  i < len| yes Evaluation Count:207909  | yes Evaluation Count:19  |  
   | 19-207909 | 
| 398 |         attributes[i].wordBreak = FALSE; executed (the execution status of this line is deduced):  attributes[i].wordBreak = 0;  | - | 
| 399 |         attributes[i].wordStart = FALSE; executed (the execution status of this line is deduced):  attributes[i].wordStart = 0;  | - | 
| 400 |         attributes[i].wordEnd = FALSE; executed (the execution status of this line is deduced):  attributes[i].wordEnd = 0;  | - | 
| 401 |         attributes[i].lineBreak = FALSE; executed (the execution status of this line is deduced):  attributes[i].lineBreak = 0;  | - | 
| 402 |     } executed:  }Execution Count:207909   | 207909 | 
| 403 |   | - | 
| 404 |     if (len > 128) { evaluated:  len > 128| yes Evaluation Count:5  | yes Evaluation Count:14  |  
   | 5-14 | 
| 405 |         break_positions = (int*) malloc (sizeof(int) * len); executed (the execution status of this line is deduced):  break_positions = (int*) malloc (sizeof(int) * len);  | - | 
| 406 |         memset (break_positions, 0, sizeof(int) * len); executed (the execution status of this line is deduced):  memset (break_positions, 0, sizeof(int) * len);  | - | 
| 407 |         brp_size = len; executed (the execution status of this line is deduced):  brp_size = len;  | - | 
| 408 |     } executed:  }Execution Count:5   | 5 | 
| 409 |     else {  | - | 
| 410 |         break_positions = brp; executed (the execution status of this line is deduced):  break_positions = brp;  | - | 
| 411 |         brp_size = 128; executed (the execution status of this line is deduced):  brp_size = 128;  | - | 
| 412 |     } executed:  }Execution Count:14   | 14 | 
| 413 |   | - | 
| 414 |     if (break_positions) { partially evaluated:  break_positions| yes Evaluation Count:19  | no Evaluation Count:0  |  
   | 0-19 | 
| 415 |         attributes[0].wordBreak = TRUE; executed (the execution status of this line is deduced):  attributes[0].wordBreak = (!0);  | - | 
| 416 |         attributes[0].wordStart = TRUE; executed (the execution status of this line is deduced):  attributes[0].wordStart = (!0);  | - | 
| 417 |         attributes[0].wordEnd = FALSE; executed (the execution status of this line is deduced):  attributes[0].wordEnd = 0;  | - | 
| 418 |         numbreaks = th_brk((const unsigned char *)cstr, break_positions, brp_size); executed (the execution status of this line is deduced):  numbreaks = th_brk((const unsigned char *)cstr, break_positions, brp_size);  | - | 
| 419 |         for (i = 0; i < numbreaks; ++i) { evaluated:  i < numbreaks| yes Evaluation Count:1314  | yes Evaluation Count:19  |  
   | 19-1314 | 
| 420 |             attributes[break_positions[i]].wordBreak = TRUE; executed (the execution status of this line is deduced):  attributes[break_positions[i]].wordBreak = (!0);  | - | 
| 421 |             attributes[break_positions[i]].wordStart = TRUE; executed (the execution status of this line is deduced):  attributes[break_positions[i]].wordStart = (!0);  | - | 
| 422 |             attributes[break_positions[i]].wordEnd = TRUE; executed (the execution status of this line is deduced):  attributes[break_positions[i]].wordEnd = (!0);  | - | 
| 423 |             attributes[break_positions[i]].lineBreak = TRUE; executed (the execution status of this line is deduced):  attributes[break_positions[i]].lineBreak = (!0);  | - | 
| 424 |         } executed:  }Execution Count:1314   | 1314 | 
| 425 |         if (numbreaks > 0) evaluated:  numbreaks > 0| yes Evaluation Count:14  | yes Evaluation Count:5  |  
   | 5-14 | 
| 426 |             attributes[break_positions[numbreaks - 1]].wordStart = FALSE; executed:  attributes[break_positions[numbreaks - 1]].wordStart = 0;Execution Count:14   | 14 | 
| 427 |   | - | 
| 428 |         if (break_positions != brp) evaluated:  break_positions != brp| yes Evaluation Count:5  | yes Evaluation Count:14  |  
   | 5-14 | 
| 429 |             free(break_positions); executed:  free(break_positions);Execution Count:5   | 5 | 
| 430 |     } executed:  }Execution Count:19   | 19 | 
| 431 |   | - | 
| 432 |     /* manage grapheme boundaries */  | - | 
| 433 |     i = 0; executed (the execution status of this line is deduced):  i = 0;  | - | 
| 434 |     while (i < len) { evaluated:  i < len| yes Evaluation Count:206701  | yes Evaluation Count:19  |  
   | 19-206701 | 
| 435 |         cell_length = th_next_cell((const unsigned char *)cstr + i, len - i, &tis_cell, true); executed (the execution status of this line is deduced):  cell_length = th_next_cell((const unsigned char *)cstr + i, len - i, &tis_cell, true);  | - | 
| 436 |   | - | 
| 437 |         attributes[i].graphemeBoundary = true; executed (the execution status of this line is deduced):  attributes[i].graphemeBoundary = true;  | - | 
| 438 |         for (j = 1; j < cell_length; j++) evaluated:  j < cell_length| yes Evaluation Count:1208  | yes Evaluation Count:206701  |  
   | 1208-206701 | 
| 439 |             attributes[i + j].graphemeBoundary = false; executed:  attributes[i + j].graphemeBoundary = false;Execution Count:1208   | 1208 | 
| 440 |   | - | 
| 441 |         /* Set graphemeBoundary for SARA AM */  | - | 
| 442 |         if (cstr[i + cell_length - 1] == (char)0xd3) partially evaluated:  cstr[i + cell_length - 1] == (char)0xd3| no Evaluation Count:0  | yes Evaluation Count:206701  |  
   | 0-206701 | 
| 443 |             attributes[i + cell_length - 1].graphemeBoundary = true; never executed: attributes[i + cell_length - 1].graphemeBoundary = true;  | 0 | 
| 444 |   | - | 
| 445 |         i += cell_length; executed (the execution status of this line is deduced):  i += cell_length;  | - | 
| 446 |     } executed:  }Execution Count:206701   | 206701 | 
| 447 |   | - | 
| 448 |     if (len >= 128) evaluated:  len >= 128| yes Evaluation Count:5  | yes Evaluation Count:14  |  
   | 5-14 | 
| 449 |         free(cstr); executed:  free(cstr);Execution Count:5   | 5 | 
| 450 | } executed:  }Execution Count:19   | 19 | 
| 451 |   | - | 
| 452 | void HB_ThaiAttributes(HB_Script script, const HB_UChar16 *text, hb_uint32 from, hb_uint32 len, HB_CharAttributes *attributes)  | - | 
| 453 | {  | - | 
| 454 |     assert(script == HB_Script_Thai); executed (the execution status of this line is deduced):  ((script == HB_Script_Thai) ? static_cast<void> (0) : __assert_fail ("script == HB_Script_Thai", "../3rdparty/harfbuzz/src/harfbuzz-thai.c", 454, __PRETTY_FUNCTION__));  | - | 
| 455 |     const HB_UChar16 *uc = text + from; executed (the execution status of this line is deduced):  const HB_UChar16 *uc = text + from;  | - | 
| 456 |     attributes += from; executed (the execution status of this line is deduced):  attributes += from;  | - | 
| 457 |     HB_UNUSED(script); executed (the execution status of this line is deduced):  ((script) = (script));  | - | 
| 458 |     HB_ThaiAssignAttributes(uc, len, attributes); executed (the execution status of this line is deduced):  HB_ThaiAssignAttributes(uc, len, attributes);  | - | 
| 459 | } executed:  }Execution Count:19   | 19 | 
| 460 |   | - | 
| 461 |   | - | 
 |  |  |