| 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 | | - |
| 28 | #include <assert.h> | - |
| 29 | | - |
| 30 | static const HB_UChar16 ReplacementCharacter = 0xfffd; | - |
| 31 | | - |
| 32 | typedef struct { | - |
| 33 | unsigned char shape; | - |
| 34 | unsigned char justification; | - |
| 35 | } HB_ArabicProperties; | - |
| 36 | | - |
| 37 | typedef enum { | - |
| 38 | XIsolated, | - |
| 39 | XFinal, | - |
| 40 | XInitial, | - |
| 41 | XMedial, | - |
| 42 | /* intermediate state */ | - |
| 43 | XCausing | - |
| 44 | } ArabicShape; | - |
| 45 | | - |
| 46 | /* | - |
| 47 | // these groups correspond to the groups defined in the Unicode standard. | - |
| 48 | // Some of these groups are equal with regards to both joining and line breaking behaviour, | - |
| 49 | // and thus have the same enum value | - |
| 50 | // | - |
| 51 | // I'm not sure the mapping of syriac to arabic enums is correct with regards to justification, but as | - |
| 52 | // I couldn't find any better document I'll hope for the best. | - |
| 53 | */ | - |
| 54 | typedef enum { | - |
| 55 | /* NonJoining */ | - |
| 56 | ArabicNone, | - |
| 57 | ArabicSpace, | - |
| 58 | /* Transparent */ | - |
| 59 | Transparent, | - |
| 60 | /* Causing */ | - |
| 61 | Center, | - |
| 62 | Kashida, | - |
| 63 | | - |
| 64 | /* Arabic */ | - |
| 65 | /* Dual */ | - |
| 66 | Beh, | - |
| 67 | Noon, | - |
| 68 | Nya = Noon, | - |
| 69 | Meem = Noon, | - |
| 70 | Heh = Noon, | - |
| 71 | KnottedHeh = Noon, | - |
| 72 | HehGoal = Noon, | - |
| 73 | SwashKaf = Noon, | - |
| 74 | Yeh, | - |
| 75 | FarsiYeh = Yeh, | - |
| 76 | Hah, | - |
| 77 | Seen, | - |
| 78 | Sad = Seen, | - |
| 79 | Tah, | - |
| 80 | Kaf = Tah, | - |
| 81 | Gaf = Tah, | - |
| 82 | Lam = Tah, | - |
| 83 | Ain, | - |
| 84 | Feh = Ain, | - |
| 85 | Qaf = Ain, | - |
| 86 | /* Right */ | - |
| 87 | Alef, | - |
| 88 | Waw, | - |
| 89 | Dal, | - |
| 90 | TehMarbuta = Dal, | - |
| 91 | Reh, | - |
| 92 | TehMarbutaGoal, | - |
| 93 | HamzaOnHehGoal = TehMarbutaGoal, /* has been retained as a property value alias */ | - |
| 94 | YehWithTail = TehMarbutaGoal, | - |
| 95 | YehBarree = TehMarbutaGoal, | - |
| 96 | | - |
| 97 | /* Syriac */ | - |
| 98 | /* Dual */ | - |
| 99 | Beth = Beh, | - |
| 100 | Gamal = Ain, | - |
| 101 | Heth = Noon, | - |
| 102 | Teth = Hah, | - |
| 103 | Yudh = Noon, | - |
| 104 | Khaph = Noon, | - |
| 105 | Lamadh = Lam, | - |
| 106 | Mim = Noon, | - |
| 107 | Nun = Noon, | - |
| 108 | Semkath = Noon, | - |
| 109 | FinalSemkath = Noon, | - |
| 110 | SyriacE = Ain, | - |
| 111 | Pe = Ain, | - |
| 112 | ReversedPe = Hah, | - |
| 113 | Qaph = Noon, | - |
| 114 | Shin = Noon, | - |
| 115 | Fe = Ain, | - |
| 116 | | - |
| 117 | /* Right */ | - |
| 118 | Alaph = Alef, | - |
| 119 | DalathRish = Dal, | - |
| 120 | He = Dal, | - |
| 121 | SyriacWaw = Waw, | - |
| 122 | Zhain = Alef, | - |
| 123 | YudhHe = Waw, | - |
| 124 | Sadhe = TehMarbutaGoal, | - |
| 125 | Taw = Dal, | - |
| 126 | | - |
| 127 | /* Compiler bug? Otherwise ArabicGroupsEnd would be equal to Dal + 1. */ | - |
| 128 | Dummy = TehMarbutaGoal, | - |
| 129 | ArabicGroupsEnd | - |
| 130 | } ArabicGroup; | - |
| 131 | | - |
| 132 | static const unsigned char arabic_group[0x150] = { | - |
| 133 | ArabicNone, ArabicNone, ArabicNone, ArabicNone, | - |
| 134 | ArabicNone, ArabicNone, ArabicNone, ArabicNone, | - |
| 135 | ArabicNone, ArabicNone, ArabicNone, ArabicNone, | - |
| 136 | ArabicNone, ArabicNone, ArabicNone, ArabicNone, | - |
| 137 | | - |
| 138 | Transparent, Transparent, Transparent, Transparent, | - |
| 139 | Transparent, Transparent, Transparent, Transparent, | - |
| 140 | Transparent, Transparent, Transparent, ArabicNone, | - |
| 141 | ArabicNone, ArabicNone, ArabicNone, ArabicNone, | - |
| 142 | | - |
| 143 | Yeh, ArabicNone, Alef, Alef, | - |
| 144 | Waw, Alef, Yeh, Alef, | - |
| 145 | Beh, TehMarbuta, Beh, Beh, | - |
| 146 | Hah, Hah, Hah, Dal, | - |
| 147 | | - |
| 148 | Dal, Reh, Reh, Seen, | - |
| 149 | Seen, Sad, Sad, Tah, | - |
| 150 | Tah, Ain, Ain, Gaf, | - |
| 151 | Gaf, FarsiYeh, FarsiYeh, FarsiYeh, | - |
| 152 | | - |
| 153 | /* 0x640 */ | - |
| 154 | Kashida, Feh, Qaf, Kaf, | - |
| 155 | Lam, Meem, Noon, Heh, | - |
| 156 | Waw, Yeh, Yeh, Transparent, | - |
| 157 | Transparent, Transparent, Transparent, Transparent, | - |
| 158 | | - |
| 159 | Transparent, Transparent, Transparent, Transparent, | - |
| 160 | Transparent, Transparent, Transparent, Transparent, | - |
| 161 | Transparent, Transparent, Transparent, Transparent, | - |
| 162 | Transparent, Transparent, Transparent, Transparent, | - |
| 163 | | - |
| 164 | ArabicNone, ArabicNone, ArabicNone, ArabicNone, | - |
| 165 | ArabicNone, ArabicNone, ArabicNone, ArabicNone, | - |
| 166 | ArabicNone, ArabicNone, ArabicNone, ArabicNone, | - |
| 167 | ArabicNone, ArabicNone, Beh, Qaf, | - |
| 168 | | - |
| 169 | Transparent, Alef, Alef, Alef, | - |
| 170 | ArabicNone, Alef, Waw, Waw, | - |
| 171 | Yeh, Beh, Beh, Beh, | - |
| 172 | Beh, Beh, Beh, Beh, | - |
| 173 | | - |
| 174 | /* 0x680 */ | - |
| 175 | Beh, Hah, Hah, Hah, | - |
| 176 | Hah, Hah, Hah, Hah, | - |
| 177 | Dal, Dal, Dal, Dal, | - |
| 178 | Dal, Dal, Dal, Dal, | - |
| 179 | | - |
| 180 | Dal, Reh, Reh, Reh, | - |
| 181 | Reh, Reh, Reh, Reh, | - |
| 182 | Reh, Reh, Seen, Seen, | - |
| 183 | Seen, Sad, Sad, Tah, | - |
| 184 | | - |
| 185 | Ain, Feh, Feh, Feh, | - |
| 186 | Feh, Feh, Feh, Qaf, | - |
| 187 | Qaf, Gaf, SwashKaf, Gaf, | - |
| 188 | Kaf, Kaf, Kaf, Gaf, | - |
| 189 | | - |
| 190 | Gaf, Gaf, Gaf, Gaf, | - |
| 191 | Gaf, Lam, Lam, Lam, | - |
| 192 | Lam, Noon, Noon, Noon, | - |
| 193 | Noon, Nya, KnottedHeh, Hah, | - |
| 194 | | - |
| 195 | /* 0x6c0 */ | - |
| 196 | TehMarbuta, HehGoal, HehGoal, TehMarbutaGoal, | - |
| 197 | Waw, Waw, Waw, Waw, | - |
| 198 | Waw, Waw, Waw, Waw, | - |
| 199 | FarsiYeh, YehWithTail, FarsiYeh, Waw, | - |
| 200 | | - |
| 201 | Yeh, Yeh, YehBarree, YehBarree, | - |
| 202 | ArabicNone, TehMarbuta, Transparent, Transparent, | - |
| 203 | Transparent, Transparent, Transparent, Transparent, | - |
| 204 | Transparent, ArabicNone, ArabicNone, Transparent, | - |
| 205 | | - |
| 206 | Transparent, Transparent, Transparent, Transparent, | - |
| 207 | Transparent, ArabicNone, ArabicNone, Transparent, | - |
| 208 | Transparent, ArabicNone, Transparent, Transparent, | - |
| 209 | Transparent, Transparent, Dal, Reh, | - |
| 210 | | - |
| 211 | ArabicNone, ArabicNone, ArabicNone, ArabicNone, | - |
| 212 | ArabicNone, ArabicNone, ArabicNone, ArabicNone, | - |
| 213 | ArabicNone, ArabicNone, Seen, Sad, | - |
| 214 | Ain, ArabicNone, ArabicNone, KnottedHeh, | - |
| 215 | | - |
| 216 | /* 0x700 */ | - |
| 217 | ArabicNone, ArabicNone, ArabicNone, ArabicNone, | - |
| 218 | ArabicNone, ArabicNone, ArabicNone, ArabicNone, | - |
| 219 | ArabicNone, ArabicNone, ArabicNone, ArabicNone, | - |
| 220 | ArabicNone, ArabicNone, ArabicNone, Transparent, | - |
| 221 | | - |
| 222 | Alaph, Transparent, Beth, Gamal, | - |
| 223 | Gamal, DalathRish, DalathRish, He, | - |
| 224 | SyriacWaw, Zhain, Heth, Teth, | - |
| 225 | Teth, Yudh, YudhHe, Khaph, | - |
| 226 | | - |
| 227 | Lamadh, Mim, Nun, Semkath, | - |
| 228 | FinalSemkath, SyriacE, Pe, ReversedPe, | - |
| 229 | Sadhe, Qaph, DalathRish, Shin, | - |
| 230 | Taw, Beth, Gamal, DalathRish, | - |
| 231 | | - |
| 232 | Transparent, Transparent, Transparent, Transparent, | - |
| 233 | Transparent, Transparent, Transparent, Transparent, | - |
| 234 | Transparent, Transparent, Transparent, Transparent, | - |
| 235 | Transparent, Transparent, Transparent, Transparent, | - |
| 236 | | - |
| 237 | Transparent, Transparent, Transparent, Transparent, | - |
| 238 | Transparent, Transparent, Transparent, Transparent, | - |
| 239 | Transparent, Transparent, Transparent, ArabicNone, | - |
| 240 | ArabicNone, Zhain, Khaph, Fe, | - |
| 241 | }; | - |
| 242 | | - |
| 243 | static ArabicGroup arabicGroup(unsigned short uc) | - |
| 244 | { | - |
| 245 | if (uc >= 0x0600 && uc < 0x750) evaluated: uc >= 0x0600| yes Evaluation Count:196 | yes Evaluation Count:75 |
partially evaluated: uc < 0x750| yes Evaluation Count:196 | no Evaluation Count:0 |
| 0-196 |
| 246 | return (ArabicGroup) arabic_group[uc-0x600]; executed: return (ArabicGroup) arabic_group[uc-0x600];Execution Count:196 | 196 |
| 247 | else if (uc == 0x200d) partially evaluated: uc == 0x200d| no Evaluation Count:0 | yes Evaluation Count:75 |
| 0-75 |
| 248 | return Center; never executed: return Center; | 0 |
| 249 | else if (HB_GetUnicodeCharCategory(uc) == HB_Separator_Space) evaluated: HB_GetUnicodeCharCategory(uc) == HB_Separator_Space| yes Evaluation Count:65 | yes Evaluation Count:10 |
| 10-65 |
| 250 | return ArabicSpace; executed: return ArabicSpace;Execution Count:65 | 65 |
| 251 | else | - |
| 252 | return ArabicNone; executed: return ArabicNone;Execution Count:10 | 10 |
| 253 | } | - |
| 254 | | - |
| 255 | | - |
| 256 | /* | - |
| 257 | Arabic shaping obeys a number of rules according to the joining classes (see Unicode book, section on | - |
| 258 | arabic). | - |
| 259 | | - |
| 260 | Each unicode char has a joining class (right, dual (left&right), center (joincausing) or transparent). | - |
| 261 | transparent joining is not encoded in HB_UChar16::joining(), but applies to all combining marks and format marks. | - |
| 262 | | - |
| 263 | Right join-causing: dual + center | - |
| 264 | Left join-causing: dual + right + center | - |
| 265 | | - |
| 266 | Rules are as follows (for a string already in visual order, as we have it here): | - |
| 267 | | - |
| 268 | R1 Transparent characters do not affect joining behaviour. | - |
| 269 | R2 A right joining character, that has a right join-causing char on the right will get form XRight | - |
| 270 | (R3 A left joining character, that has a left join-causing char on the left will get form XLeft) | - |
| 271 | Note: the above rule is meaningless, as there are no pure left joining characters defined in Unicode | - |
| 272 | R4 A dual joining character, that has a left join-causing char on the left and a right join-causing char on | - |
| 273 | the right will get form XMedial | - |
| 274 | R5 A dual joining character, that has a right join causing char on the right, and no left join causing char on the left | - |
| 275 | will get form XRight | - |
| 276 | R6 A dual joining character, that has a left join causing char on the left, and no right join causing char on the right | - |
| 277 | will get form XLeft | - |
| 278 | R7 Otherwise the character will get form XIsolated | - |
| 279 | | - |
| 280 | Additionally we have to do the minimal ligature support for lam-alef ligatures: | - |
| 281 | | - |
| 282 | L1 Transparent characters do not affect ligature behaviour. | - |
| 283 | L2 Any sequence of Alef(XRight) + Lam(XMedial) will form the ligature Alef.Lam(XLeft) | - |
| 284 | L3 Any sequence of Alef(XRight) + Lam(XLeft) will form the ligature Alef.Lam(XIsolated) | - |
| 285 | | - |
| 286 | The state table below handles rules R1-R7. | - |
| 287 | */ | - |
| 288 | | - |
| 289 | typedef enum { | - |
| 290 | JNone, | - |
| 291 | JCausing, | - |
| 292 | JDual, | - |
| 293 | JRight, | - |
| 294 | JTransparent | - |
| 295 | } Joining; | - |
| 296 | | - |
| 297 | static const Joining joining_for_group[ArabicGroupsEnd] = { | - |
| 298 | /* NonJoining */ | - |
| 299 | JNone, /* ArabicNone */ | - |
| 300 | JNone, /* ArabicSpace */ | - |
| 301 | /* Transparent */ | - |
| 302 | JTransparent, /* Transparent */ | - |
| 303 | /* Causing */ | - |
| 304 | JCausing, /* Center */ | - |
| 305 | JCausing, /* Kashida */ | - |
| 306 | /* Dual */ | - |
| 307 | JDual, /* Beh */ | - |
| 308 | JDual, /* Noon */ | - |
| 309 | JDual, /* Yeh */ | - |
| 310 | JDual, /* Hah */ | - |
| 311 | JDual, /* Seen */ | - |
| 312 | JDual, /* Tah */ | - |
| 313 | JDual, /* Ain */ | - |
| 314 | /* Right */ | - |
| 315 | JRight, /* Alef */ | - |
| 316 | JRight, /* Waw */ | - |
| 317 | JRight, /* Dal */ | - |
| 318 | JRight, /* Reh */ | - |
| 319 | JRight /* TehMarbutaGoal */ | - |
| 320 | }; | - |
| 321 | | - |
| 322 | | - |
| 323 | typedef struct { | - |
| 324 | ArabicShape form1; | - |
| 325 | ArabicShape form2; | - |
| 326 | } JoiningPair; | - |
| 327 | | - |
| 328 | static const JoiningPair joining_table[5][4] = | - |
| 329 | /* None, Causing, Dual, Right */ | - |
| 330 | { | - |
| 331 | { { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XInitial }, { XIsolated, XIsolated } }, /* XIsolated */ | - |
| 332 | { { XFinal, XIsolated }, { XFinal, XCausing }, { XFinal, XInitial }, { XFinal, XIsolated } }, /* XFinal */ | - |
| 333 | { { XIsolated, XIsolated }, { XInitial, XCausing }, { XInitial, XMedial }, { XInitial, XFinal } }, /* XInitial */ | - |
| 334 | { { XFinal, XIsolated }, { XMedial, XCausing }, { XMedial, XMedial }, { XMedial, XFinal } }, /* XMedial */ | - |
| 335 | { { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XMedial }, { XIsolated, XFinal } }, /* XCausing */ | - |
| 336 | }; | - |
| 337 | | - |
| 338 | | - |
| 339 | /* | - |
| 340 | According to http://www.microsoft.com/middleeast/Arabicdev/IE6/KBase.asp | - |
| 341 | | - |
| 342 | 1. Find the priority of the connecting opportunities in each word | - |
| 343 | 2. Add expansion at the highest priority connection opportunity | - |
| 344 | 3. If more than one connection opportunity have the same highest value, | - |
| 345 | use the opportunity closest to the end of the word. | - |
| 346 | | - |
| 347 | Following is a chart that provides the priority for connection | - |
| 348 | opportunities and where expansion occurs. The character group names | - |
| 349 | are those in table 6.6 of the UNICODE 2.0 book. | - |
| 350 | | - |
| 351 | | - |
| 352 | PrioritY Glyph Condition Kashida Location | - |
| 353 | | - |
| 354 | Arabic_Kashida User inserted Kashida The user entered a Kashida in a position. After the user | - |
| 355 | (Shift+j or Shift+[E with hat]) Thus, it is the highest priority to insert an inserted kashida | - |
| 356 | automatic kashida. | - |
| 357 | | - |
| 358 | Arabic_Seen Seen, Sad Connecting to the next character. After the character. | - |
| 359 | (Initial or medial form). | - |
| 360 | | - |
| 361 | Arabic_HaaDal Teh Marbutah, Haa, Dal Connecting to previous character. Before the final form | - |
| 362 | of these characters. | - |
| 363 | | - |
| 364 | Arabic_Alef Alef, Tah, Lam, Connecting to previous character. Before the final form | - |
| 365 | Kaf and Gaf of these characters. | - |
| 366 | | - |
| 367 | Arabic_BaRa Reh, Yeh Connected to medial Beh Before preceding medial Baa | - |
| 368 | | - |
| 369 | Arabic_Waw Waw, Ain, Qaf, Feh Connecting to previous character. Before the final form of | - |
| 370 | these characters. | - |
| 371 | | - |
| 372 | Arabic_Normal Other connecting Connecting to previous character. Before the final form | - |
| 373 | characters of these characters. | - |
| 374 | | - |
| 375 | | - |
| 376 | | - |
| 377 | This seems to imply that we have at most one kashida point per arabic word. | - |
| 378 | | - |
| 379 | */ | - |
| 380 | | - |
| 381 | static void getArabicProperties(const unsigned short *chars, int len, HB_ArabicProperties *properties) | - |
| 382 | { | - |
| 383 | /* qDebug("arabicSyriacOpenTypeShape: properties:"); */ | - |
| 384 | int lastPos = 0; executed (the execution status of this line is deduced): int lastPos = 0; | - |
| 385 | int lastGroup = ArabicNone; executed (the execution status of this line is deduced): int lastGroup = ArabicNone; | - |
| 386 | int i = 0; executed (the execution status of this line is deduced): int i = 0; | - |
| 387 | | - |
| 388 | ArabicGroup group = arabicGroup(chars[0]); executed (the execution status of this line is deduced): ArabicGroup group = arabicGroup(chars[0]); | - |
| 389 | Joining j = joining_for_group[group]; executed (the execution status of this line is deduced): Joining j = joining_for_group[group]; | - |
| 390 | ArabicShape shape = joining_table[XIsolated][j].form2; executed (the execution status of this line is deduced): ArabicShape shape = joining_table[XIsolated][j].form2; | - |
| 391 | properties[0].justification = HB_NoJustification; executed (the execution status of this line is deduced): properties[0].justification = HB_NoJustification; | - |
| 392 | | - |
| 393 | for (i = 1; i < len; ++i) { evaluated: i < len| yes Evaluation Count:204 | yes Evaluation Count:57 |
| 57-204 |
| 394 | /* #### fix handling for spaces and punktuation */ | - |
| 395 | properties[i].justification = HB_NoJustification; executed (the execution status of this line is deduced): properties[i].justification = HB_NoJustification; | - |
| 396 | | - |
| 397 | group = arabicGroup(chars[i]); executed (the execution status of this line is deduced): group = arabicGroup(chars[i]); | - |
| 398 | j = joining_for_group[group]; executed (the execution status of this line is deduced): j = joining_for_group[group]; | - |
| 399 | | - |
| 400 | if (j == JTransparent) { partially evaluated: j == JTransparent| no Evaluation Count:0 | yes Evaluation Count:204 |
| 0-204 |
| 401 | properties[i].shape = XIsolated; never executed (the execution status of this line is deduced): properties[i].shape = XIsolated; | - |
| 402 | continue; never executed: continue; | 0 |
| 403 | } | - |
| 404 | | - |
| 405 | properties[lastPos].shape = joining_table[shape][j].form1; executed (the execution status of this line is deduced): properties[lastPos].shape = joining_table[shape][j].form1; | - |
| 406 | shape = joining_table[shape][j].form2; executed (the execution status of this line is deduced): shape = joining_table[shape][j].form2; | - |
| 407 | | - |
| 408 | switch(lastGroup) { | - |
| 409 | case Seen: | - |
| 410 | if (properties[lastPos].shape == XInitial || properties[lastPos].shape == XMedial) partially evaluated: properties[lastPos].shape == XInitial| yes Evaluation Count:4 | no Evaluation Count:0 |
never evaluated: properties[lastPos].shape == XMedial | 0-4 |
| 411 | properties[i-1].justification = HB_Arabic_Seen; executed: properties[i-1].justification = HB_Arabic_Seen;Execution Count:4 | 4 |
| 412 | break; executed: break;Execution Count:4 | 4 |
| 413 | case Hah: | - |
| 414 | if (properties[lastPos].shape == XFinal) evaluated: properties[lastPos].shape == XFinal| yes Evaluation Count:4 | yes Evaluation Count:16 |
| 4-16 |
| 415 | properties[lastPos-1].justification = HB_Arabic_HaaDal; executed: properties[lastPos-1].justification = HB_Arabic_HaaDal;Execution Count:4 | 4 |
| 416 | break; executed: break;Execution Count:20 | 20 |
| 417 | case Alef: | - |
| 418 | if (properties[lastPos].shape == XFinal) evaluated: properties[lastPos].shape == XFinal| yes Evaluation Count:12 | yes Evaluation Count:31 |
| 12-31 |
| 419 | properties[lastPos-1].justification = HB_Arabic_Alef; executed: properties[lastPos-1].justification = HB_Arabic_Alef;Execution Count:12 | 12 |
| 420 | break; executed: break;Execution Count:43 | 43 |
| 421 | case Ain: | - |
| 422 | if (properties[lastPos].shape == XFinal) evaluated: properties[lastPos].shape == XFinal| yes Evaluation Count:8 | yes Evaluation Count:9 |
| 8-9 |
| 423 | properties[lastPos-1].justification = HB_Arabic_Waw; executed: properties[lastPos-1].justification = HB_Arabic_Waw;Execution Count:8 | 8 |
| 424 | break; executed: break;Execution Count:17 | 17 |
| 425 | case Noon: | - |
| 426 | if (properties[lastPos].shape == XFinal) evaluated: properties[lastPos].shape == XFinal| yes Evaluation Count:10 | yes Evaluation Count:18 |
| 10-18 |
| 427 | properties[lastPos-1].justification = HB_Arabic_Normal; executed: properties[lastPos-1].justification = HB_Arabic_Normal;Execution Count:10 | 10 |
| 428 | break; executed: break;Execution Count:28 | 28 |
| 429 | case ArabicNone: | - |
| 430 | break; executed: break;Execution Count:92 | 92 |
| 431 | | - |
| 432 | default: | - |
| 433 | assert(FALSE); never executed (the execution status of this line is deduced): ((0) ? static_cast<void> (0) : __assert_fail ("0", "../3rdparty/harfbuzz/src/harfbuzz-arabic.c", 433, __PRETTY_FUNCTION__)); | - |
| 434 | } | 0 |
| 435 | | - |
| 436 | lastGroup = ArabicNone; executed (the execution status of this line is deduced): lastGroup = ArabicNone; | - |
| 437 | | - |
| 438 | switch(group) { | - |
| 439 | case ArabicNone: | - |
| 440 | case Transparent: | - |
| 441 | /* ### Center should probably be treated as transparent when it comes to justification. */ | - |
| 442 | case Center: | - |
| 443 | break; executed: break;Execution Count:19 | 19 |
| 444 | case ArabicSpace: | - |
| 445 | properties[i].justification = HB_Arabic_Space; executed (the execution status of this line is deduced): properties[i].justification = HB_Arabic_Space; | - |
| 446 | break; executed: break;Execution Count:34 | 34 |
| 447 | case Kashida: | - |
| 448 | properties[i].justification = HB_Arabic_Kashida; never executed (the execution status of this line is deduced): properties[i].justification = HB_Arabic_Kashida; | - |
| 449 | break; | 0 |
| 450 | case Seen: | - |
| 451 | lastGroup = Seen; executed (the execution status of this line is deduced): lastGroup = Seen; | - |
| 452 | break; executed: break;Execution Count:4 | 4 |
| 453 | | - |
| 454 | case Hah: | - |
| 455 | case Dal: | - |
| 456 | lastGroup = Hah; executed (the execution status of this line is deduced): lastGroup = Hah; | - |
| 457 | break; executed: break;Execution Count:20 | 20 |
| 458 | | - |
| 459 | case Alef: | - |
| 460 | case Tah: | - |
| 461 | lastGroup = Alef; executed (the execution status of this line is deduced): lastGroup = Alef; | - |
| 462 | break; executed: break;Execution Count:43 | 43 |
| 463 | | - |
| 464 | case Yeh: | - |
| 465 | case Reh: | - |
| 466 | if (properties[lastPos].shape == XMedial && arabicGroup(chars[lastPos]) == Beh) evaluated: properties[lastPos].shape == XMedial| yes Evaluation Count:10 | yes Evaluation Count:16 |
partially evaluated: arabicGroup(chars[lastPos]) == Beh| no Evaluation Count:0 | yes Evaluation Count:10 |
| 0-16 |
| 467 | properties[lastPos-1].justification = HB_Arabic_BaRa; never executed: properties[lastPos-1].justification = HB_Arabic_BaRa; | 0 |
| 468 | break; executed: break;Execution Count:26 | 26 |
| 469 | | - |
| 470 | case Ain: | - |
| 471 | case Waw: | - |
| 472 | lastGroup = Ain; executed (the execution status of this line is deduced): lastGroup = Ain; | - |
| 473 | break; executed: break;Execution Count:21 | 21 |
| 474 | | - |
| 475 | case Noon: | - |
| 476 | case Beh: | - |
| 477 | case TehMarbutaGoal: | - |
| 478 | lastGroup = Noon; executed (the execution status of this line is deduced): lastGroup = Noon; | - |
| 479 | break; executed: break;Execution Count:37 | 37 |
| 480 | case ArabicGroupsEnd: | - |
| 481 | assert(FALSE); never executed (the execution status of this line is deduced): ((0) ? static_cast<void> (0) : __assert_fail ("0", "../3rdparty/harfbuzz/src/harfbuzz-arabic.c", 481, __PRETTY_FUNCTION__)); | - |
| 482 | } | 0 |
| 483 | | - |
| 484 | lastPos = i; executed (the execution status of this line is deduced): lastPos = i; | - |
| 485 | } executed: }Execution Count:204 | 204 |
| 486 | properties[lastPos].shape = joining_table[shape][JNone].form1; executed (the execution status of this line is deduced): properties[lastPos].shape = joining_table[shape][JNone].form1; | - |
| 487 | | - |
| 488 | | - |
| 489 | /* | - |
| 490 | for (int i = 0; i < len; ++i) | - |
| 491 | qDebug("arabic properties(%d): uc=%x shape=%d, justification=%d", i, chars[i], properties[i].shape, properties[i].justification); | - |
| 492 | */ | - |
| 493 | } executed: }Execution Count:57 | 57 |
| 494 | | - |
| 495 | static Joining getNkoJoining(unsigned short uc) | - |
| 496 | { | - |
| 497 | if (uc < 0x7ca) never evaluated: uc < 0x7ca | 0 |
| 498 | return JNone; never executed: return JNone; | 0 |
| 499 | if (uc <= 0x7ea) never evaluated: uc <= 0x7ea | 0 |
| 500 | return JDual; never executed: return JDual; | 0 |
| 501 | if (uc <= 0x7f3) never evaluated: uc <= 0x7f3 | 0 |
| 502 | return JTransparent; never executed: return JTransparent; | 0 |
| 503 | if (uc <= 0x7f9) never evaluated: uc <= 0x7f9 | 0 |
| 504 | return JNone; never executed: return JNone; | 0 |
| 505 | if (uc == 0x7fa) never evaluated: uc == 0x7fa | 0 |
| 506 | return JCausing; never executed: return JCausing; | 0 |
| 507 | return JNone; never executed: return JNone; | 0 |
| 508 | } | - |
| 509 | | - |
| 510 | static void getNkoProperties(const unsigned short *chars, int len, HB_ArabicProperties *properties) | - |
| 511 | { | - |
| 512 | int lastPos = 0; never executed (the execution status of this line is deduced): int lastPos = 0; | - |
| 513 | int i = 0; never executed (the execution status of this line is deduced): int i = 0; | - |
| 514 | | - |
| 515 | Joining j = getNkoJoining(chars[0]); never executed (the execution status of this line is deduced): Joining j = getNkoJoining(chars[0]); | - |
| 516 | ArabicShape shape = joining_table[XIsolated][j].form2; never executed (the execution status of this line is deduced): ArabicShape shape = joining_table[XIsolated][j].form2; | - |
| 517 | properties[0].justification = HB_NoJustification; never executed (the execution status of this line is deduced): properties[0].justification = HB_NoJustification; | - |
| 518 | | - |
| 519 | for (i = 1; i < len; ++i) { | 0 |
| 520 | properties[i].justification = (HB_GetUnicodeCharCategory(chars[i]) == HB_Separator_Space) ? never evaluated: (HB_GetUnicodeCharCategory(chars[i]) == HB_Separator_Space) | 0 |
| 521 | ArabicSpace : ArabicNone; never executed (the execution status of this line is deduced): ArabicSpace : ArabicNone; | - |
| 522 | | - |
| 523 | j = getNkoJoining(chars[i]); never executed (the execution status of this line is deduced): j = getNkoJoining(chars[i]); | - |
| 524 | | - |
| 525 | if (j == JTransparent) { never evaluated: j == JTransparent | 0 |
| 526 | properties[i].shape = XIsolated; never executed (the execution status of this line is deduced): properties[i].shape = XIsolated; | - |
| 527 | continue; never executed: continue; | 0 |
| 528 | } | - |
| 529 | | - |
| 530 | properties[lastPos].shape = joining_table[shape][j].form1; never executed (the execution status of this line is deduced): properties[lastPos].shape = joining_table[shape][j].form1; | - |
| 531 | shape = joining_table[shape][j].form2; never executed (the execution status of this line is deduced): shape = joining_table[shape][j].form2; | - |
| 532 | | - |
| 533 | | - |
| 534 | lastPos = i; never executed (the execution status of this line is deduced): lastPos = i; | - |
| 535 | } | 0 |
| 536 | properties[lastPos].shape = joining_table[shape][JNone].form1; never executed (the execution status of this line is deduced): properties[lastPos].shape = joining_table[shape][JNone].form1; | - |
| 537 | | - |
| 538 | | - |
| 539 | /* | - |
| 540 | for (int i = 0; i < len; ++i) | - |
| 541 | qDebug("nko properties(%d): uc=%x shape=%d, justification=%d", i, chars[i], properties[i].shape, properties[i].justification); | - |
| 542 | */ | - |
| 543 | } | 0 |
| 544 | | - |
| 545 | /* | - |
| 546 | // The unicode to unicode shaping codec. | - |
| 547 | // does only presentation forms B at the moment, but that should be enough for | - |
| 548 | // simple display | - |
| 549 | */ | - |
| 550 | static const hb_uint16 arabicUnicodeMapping[256][2] = { | - |
| 551 | /* base of shaped forms, and number-1 of them (0 for non shaping, | - |
| 552 | 1 for right binding and 3 for dual binding */ | - |
| 553 | | - |
| 554 | /* These are just the glyphs available in Unicode, | - |
| 555 | some characters are in R class, but have no glyphs in Unicode. */ | - |
| 556 | | - |
| 557 | { 0x0600, 0 }, /* 0x0600 */ | - |
| 558 | { 0x0601, 0 }, /* 0x0601 */ | - |
| 559 | { 0x0602, 0 }, /* 0x0602 */ | - |
| 560 | { 0x0603, 0 }, /* 0x0603 */ | - |
| 561 | { 0x0604, 0 }, /* 0x0604 */ | - |
| 562 | { 0x0605, 0 }, /* 0x0605 */ | - |
| 563 | { 0x0606, 0 }, /* 0x0606 */ | - |
| 564 | { 0x0607, 0 }, /* 0x0607 */ | - |
| 565 | { 0x0608, 0 }, /* 0x0608 */ | - |
| 566 | { 0x0609, 0 }, /* 0x0609 */ | - |
| 567 | { 0x060A, 0 }, /* 0x060A */ | - |
| 568 | { 0x060B, 0 }, /* 0x060B */ | - |
| 569 | { 0x060C, 0 }, /* 0x060C */ | - |
| 570 | { 0x060D, 0 }, /* 0x060D */ | - |
| 571 | { 0x060E, 0 }, /* 0x060E */ | - |
| 572 | { 0x060F, 0 }, /* 0x060F */ | - |
| 573 | | - |
| 574 | { 0x0610, 0 }, /* 0x0610 */ | - |
| 575 | { 0x0611, 0 }, /* 0x0611 */ | - |
| 576 | { 0x0612, 0 }, /* 0x0612 */ | - |
| 577 | { 0x0613, 0 }, /* 0x0613 */ | - |
| 578 | { 0x0614, 0 }, /* 0x0614 */ | - |
| 579 | { 0x0615, 0 }, /* 0x0615 */ | - |
| 580 | { 0x0616, 0 }, /* 0x0616 */ | - |
| 581 | { 0x0617, 0 }, /* 0x0617 */ | - |
| 582 | { 0x0618, 0 }, /* 0x0618 */ | - |
| 583 | { 0x0619, 0 }, /* 0x0619 */ | - |
| 584 | { 0x061A, 0 }, /* 0x061A */ | - |
| 585 | { 0x061B, 0 }, /* 0x061B */ | - |
| 586 | { 0x061C, 0 }, /* 0x061C */ | - |
| 587 | { 0x061D, 0 }, /* 0x061D */ | - |
| 588 | { 0x061E, 0 }, /* 0x061E */ | - |
| 589 | { 0x061F, 0 }, /* 0x061F */ | - |
| 590 | | - |
| 591 | { 0x0620, 0 }, /* 0x0620 */ | - |
| 592 | { 0xFE80, 0 }, /* 0x0621 HAMZA */ | - |
| 593 | { 0xFE81, 1 }, /* 0x0622 R ALEF WITH MADDA ABOVE */ | - |
| 594 | { 0xFE83, 1 }, /* 0x0623 R ALEF WITH HAMZA ABOVE */ | - |
| 595 | { 0xFE85, 1 }, /* 0x0624 R WAW WITH HAMZA ABOVE */ | - |
| 596 | { 0xFE87, 1 }, /* 0x0625 R ALEF WITH HAMZA BELOW */ | - |
| 597 | { 0xFE89, 3 }, /* 0x0626 D YEH WITH HAMZA ABOVE */ | - |
| 598 | { 0xFE8D, 1 }, /* 0x0627 R ALEF */ | - |
| 599 | { 0xFE8F, 3 }, /* 0x0628 D BEH */ | - |
| 600 | { 0xFE93, 1 }, /* 0x0629 R TEH MARBUTA */ | - |
| 601 | { 0xFE95, 3 }, /* 0x062A D TEH */ | - |
| 602 | { 0xFE99, 3 }, /* 0x062B D THEH */ | - |
| 603 | { 0xFE9D, 3 }, /* 0x062C D JEEM */ | - |
| 604 | { 0xFEA1, 3 }, /* 0x062D D HAH */ | - |
| 605 | { 0xFEA5, 3 }, /* 0x062E D KHAH */ | - |
| 606 | { 0xFEA9, 1 }, /* 0x062F R DAL */ | - |
| 607 | | - |
| 608 | { 0xFEAB, 1 }, /* 0x0630 R THAL */ | - |
| 609 | { 0xFEAD, 1 }, /* 0x0631 R REH */ | - |
| 610 | { 0xFEAF, 1 }, /* 0x0632 R ZHAIN */ | - |
| 611 | { 0xFEB1, 3 }, /* 0x0633 D SEEN */ | - |
| 612 | { 0xFEB5, 3 }, /* 0x0634 D SHEEN */ | - |
| 613 | { 0xFEB9, 3 }, /* 0x0635 D SAD */ | - |
| 614 | { 0xFEBD, 3 }, /* 0x0636 D DAD */ | - |
| 615 | { 0xFEC1, 3 }, /* 0x0637 D TAH */ | - |
| 616 | { 0xFEC5, 3 }, /* 0x0638 D ZAH */ | - |
| 617 | { 0xFEC9, 3 }, /* 0x0639 D AIN */ | - |
| 618 | { 0xFECD, 3 }, /* 0x063A D GHAIN */ | - |
| 619 | { 0x063B, 0 }, /* 0x063B */ | - |
| 620 | { 0x063C, 0 }, /* 0x063C */ | - |
| 621 | { 0x063D, 0 }, /* 0x063D */ | - |
| 622 | { 0x063E, 0 }, /* 0x063E */ | - |
| 623 | { 0x063F, 0 }, /* 0x063F */ | - |
| 624 | | - |
| 625 | { 0x0640, 0 }, /* 0x0640 C TATWEEL // ### Join Causing, only one glyph */ | - |
| 626 | { 0xFED1, 3 }, /* 0x0641 D FEH */ | - |
| 627 | { 0xFED5, 3 }, /* 0x0642 D QAF */ | - |
| 628 | { 0xFED9, 3 }, /* 0x0643 D KAF */ | - |
| 629 | { 0xFEDD, 3 }, /* 0x0644 D LAM */ | - |
| 630 | { 0xFEE1, 3 }, /* 0x0645 D MEEM */ | - |
| 631 | { 0xFEE5, 3 }, /* 0x0646 D NOON */ | - |
| 632 | { 0xFEE9, 3 }, /* 0x0647 D HEH */ | - |
| 633 | { 0xFEED, 1 }, /* 0x0648 R WAW */ | - |
| 634 | { 0x0649, 3 }, /* 0x0649 ALEF MAKSURA // ### Dual, glyphs not consecutive, handle in code. */ | - |
| 635 | { 0xFEF1, 3 }, /* 0x064A D YEH */ | - |
| 636 | { 0x064B, 0 }, /* 0x064B */ | - |
| 637 | { 0x064C, 0 }, /* 0x064C */ | - |
| 638 | { 0x064D, 0 }, /* 0x064D */ | - |
| 639 | { 0x064E, 0 }, /* 0x064E */ | - |
| 640 | { 0x064F, 0 }, /* 0x064F */ | - |
| 641 | | - |
| 642 | { 0x0650, 0 }, /* 0x0650 */ | - |
| 643 | { 0x0651, 0 }, /* 0x0651 */ | - |
| 644 | { 0x0652, 0 }, /* 0x0652 */ | - |
| 645 | { 0x0653, 0 }, /* 0x0653 */ | - |
| 646 | { 0x0654, 0 }, /* 0x0654 */ | - |
| 647 | { 0x0655, 0 }, /* 0x0655 */ | - |
| 648 | { 0x0656, 0 }, /* 0x0656 */ | - |
| 649 | { 0x0657, 0 }, /* 0x0657 */ | - |
| 650 | { 0x0658, 0 }, /* 0x0658 */ | - |
| 651 | { 0x0659, 0 }, /* 0x0659 */ | - |
| 652 | { 0x065A, 0 }, /* 0x065A */ | - |
| 653 | { 0x065B, 0 }, /* 0x065B */ | - |
| 654 | { 0x065C, 0 }, /* 0x065C */ | - |
| 655 | { 0x065D, 0 }, /* 0x065D */ | - |
| 656 | { 0x065E, 0 }, /* 0x065E */ | - |
| 657 | { 0x065F, 0 }, /* 0x065F */ | - |
| 658 | | - |
| 659 | { 0x0660, 0 }, /* 0x0660 */ | - |
| 660 | { 0x0661, 0 }, /* 0x0661 */ | - |
| 661 | { 0x0662, 0 }, /* 0x0662 */ | - |
| 662 | { 0x0663, 0 }, /* 0x0663 */ | - |
| 663 | { 0x0664, 0 }, /* 0x0664 */ | - |
| 664 | { 0x0665, 0 }, /* 0x0665 */ | - |
| 665 | { 0x0666, 0 }, /* 0x0666 */ | - |
| 666 | { 0x0667, 0 }, /* 0x0667 */ | - |
| 667 | { 0x0668, 0 }, /* 0x0668 */ | - |
| 668 | { 0x0669, 0 }, /* 0x0669 */ | - |
| 669 | { 0x066A, 0 }, /* 0x066A */ | - |
| 670 | { 0x066B, 0 }, /* 0x066B */ | - |
| 671 | { 0x066C, 0 }, /* 0x066C */ | - |
| 672 | { 0x066D, 0 }, /* 0x066D */ | - |
| 673 | { 0x066E, 0 }, /* 0x066E */ | - |
| 674 | { 0x066F, 0 }, /* 0x066F */ | - |
| 675 | | - |
| 676 | { 0x0670, 0 }, /* 0x0670 */ | - |
| 677 | { 0xFB50, 1 }, /* 0x0671 R ALEF WASLA */ | - |
| 678 | { 0x0672, 0 }, /* 0x0672 */ | - |
| 679 | { 0x0673, 0 }, /* 0x0673 */ | - |
| 680 | { 0x0674, 0 }, /* 0x0674 */ | - |
| 681 | { 0x0675, 0 }, /* 0x0675 */ | - |
| 682 | { 0x0676, 0 }, /* 0x0676 */ | - |
| 683 | { 0x0677, 0 }, /* 0x0677 */ | - |
| 684 | { 0x0678, 0 }, /* 0x0678 */ | - |
| 685 | { 0xFB66, 3 }, /* 0x0679 D TTEH */ | - |
| 686 | { 0xFB5E, 3 }, /* 0x067A D TTEHEH */ | - |
| 687 | { 0xFB52, 3 }, /* 0x067B D BEEH */ | - |
| 688 | { 0x067C, 0 }, /* 0x067C */ | - |
| 689 | { 0x067D, 0 }, /* 0x067D */ | - |
| 690 | { 0xFB56, 3 }, /* 0x067E D PEH */ | - |
| 691 | { 0xFB62, 3 }, /* 0x067F D TEHEH */ | - |
| 692 | | - |
| 693 | { 0xFB5A, 3 }, /* 0x0680 D BEHEH */ | - |
| 694 | { 0x0681, 0 }, /* 0x0681 */ | - |
| 695 | { 0x0682, 0 }, /* 0x0682 */ | - |
| 696 | { 0xFB76, 3 }, /* 0x0683 D NYEH */ | - |
| 697 | { 0xFB72, 3 }, /* 0x0684 D DYEH */ | - |
| 698 | { 0x0685, 0 }, /* 0x0685 */ | - |
| 699 | { 0xFB7A, 3 }, /* 0x0686 D TCHEH */ | - |
| 700 | { 0xFB7E, 3 }, /* 0x0687 D TCHEHEH */ | - |
| 701 | { 0xFB88, 1 }, /* 0x0688 R DDAL */ | - |
| 702 | { 0x0689, 0 }, /* 0x0689 */ | - |
| 703 | { 0x068A, 0 }, /* 0x068A */ | - |
| 704 | { 0x068B, 0 }, /* 0x068B */ | - |
| 705 | { 0xFB84, 1 }, /* 0x068C R DAHAL */ | - |
| 706 | { 0xFB82, 1 }, /* 0x068D R DDAHAL */ | - |
| 707 | { 0xFB86, 1 }, /* 0x068E R DUL */ | - |
| 708 | { 0x068F, 0 }, /* 0x068F */ | - |
| 709 | | - |
| 710 | { 0x0690, 0 }, /* 0x0690 */ | - |
| 711 | { 0xFB8C, 1 }, /* 0x0691 R RREH */ | - |
| 712 | { 0x0692, 0 }, /* 0x0692 */ | - |
| 713 | { 0x0693, 0 }, /* 0x0693 */ | - |
| 714 | { 0x0694, 0 }, /* 0x0694 */ | - |
| 715 | { 0x0695, 0 }, /* 0x0695 */ | - |
| 716 | { 0x0696, 0 }, /* 0x0696 */ | - |
| 717 | { 0x0697, 0 }, /* 0x0697 */ | - |
| 718 | { 0xFB8A, 1 }, /* 0x0698 R JEH */ | - |
| 719 | { 0x0699, 0 }, /* 0x0699 */ | - |
| 720 | { 0x069A, 0 }, /* 0x069A */ | - |
| 721 | { 0x069B, 0 }, /* 0x069B */ | - |
| 722 | { 0x069C, 0 }, /* 0x069C */ | - |
| 723 | { 0x069D, 0 }, /* 0x069D */ | - |
| 724 | { 0x069E, 0 }, /* 0x069E */ | - |
| 725 | { 0x069F, 0 }, /* 0x069F */ | - |
| 726 | | - |
| 727 | { 0x06A0, 0 }, /* 0x06A0 */ | - |
| 728 | { 0x06A1, 0 }, /* 0x06A1 */ | - |
| 729 | { 0x06A2, 0 }, /* 0x06A2 */ | - |
| 730 | { 0x06A3, 0 }, /* 0x06A3 */ | - |
| 731 | { 0xFB6A, 3 }, /* 0x06A4 D VEH */ | - |
| 732 | { 0x06A5, 0 }, /* 0x06A5 */ | - |
| 733 | { 0xFB6E, 3 }, /* 0x06A6 D PEHEH */ | - |
| 734 | { 0x06A7, 0 }, /* 0x06A7 */ | - |
| 735 | { 0x06A8, 0 }, /* 0x06A8 */ | - |
| 736 | { 0xFB8E, 3 }, /* 0x06A9 D KEHEH */ | - |
| 737 | { 0x06AA, 0 }, /* 0x06AA */ | - |
| 738 | { 0x06AB, 0 }, /* 0x06AB */ | - |
| 739 | { 0x06AC, 0 }, /* 0x06AC */ | - |
| 740 | { 0xFBD3, 3 }, /* 0x06AD D NG */ | - |
| 741 | { 0x06AE, 0 }, /* 0x06AE */ | - |
| 742 | { 0xFB92, 3 }, /* 0x06AF D GAF */ | - |
| 743 | | - |
| 744 | { 0x06B0, 0 }, /* 0x06B0 */ | - |
| 745 | { 0xFB9A, 3 }, /* 0x06B1 D NGOEH */ | - |
| 746 | { 0x06B2, 0 }, /* 0x06B2 */ | - |
| 747 | { 0xFB96, 3 }, /* 0x06B3 D GUEH */ | - |
| 748 | { 0x06B4, 0 }, /* 0x06B4 */ | - |
| 749 | { 0x06B5, 0 }, /* 0x06B5 */ | - |
| 750 | { 0x06B6, 0 }, /* 0x06B6 */ | - |
| 751 | { 0x06B7, 0 }, /* 0x06B7 */ | - |
| 752 | { 0x06B8, 0 }, /* 0x06B8 */ | - |
| 753 | { 0x06B9, 0 }, /* 0x06B9 */ | - |
| 754 | { 0xFB9E, 1 }, /* 0x06BA R NOON GHUNNA */ | - |
| 755 | { 0xFBA0, 3 }, /* 0x06BB D RNOON */ | - |
| 756 | { 0x06BC, 0 }, /* 0x06BC */ | - |
| 757 | { 0x06BD, 0 }, /* 0x06BD */ | - |
| 758 | { 0xFBAA, 3 }, /* 0x06BE D HEH DOACHASHMEE */ | - |
| 759 | { 0x06BF, 0 }, /* 0x06BF */ | - |
| 760 | | - |
| 761 | { 0xFBA4, 1 }, /* 0x06C0 R HEH WITH YEH ABOVE */ | - |
| 762 | { 0xFBA6, 3 }, /* 0x06C1 D HEH GOAL */ | - |
| 763 | { 0x06C2, 0 }, /* 0x06C2 */ | - |
| 764 | { 0x06C3, 0 }, /* 0x06C3 */ | - |
| 765 | { 0x06C4, 0 }, /* 0x06C4 */ | - |
| 766 | { 0xFBE0, 1 }, /* 0x06C5 R KIRGHIZ OE */ | - |
| 767 | { 0xFBD9, 1 }, /* 0x06C6 R OE */ | - |
| 768 | { 0xFBD7, 1 }, /* 0x06C7 R U */ | - |
| 769 | { 0xFBDB, 1 }, /* 0x06C8 R YU */ | - |
| 770 | { 0xFBE2, 1 }, /* 0x06C9 R KIRGHIZ YU */ | - |
| 771 | { 0x06CA, 0 }, /* 0x06CA */ | - |
| 772 | { 0xFBDE, 1 }, /* 0x06CB R VE */ | - |
| 773 | { 0xFBFC, 3 }, /* 0x06CC D FARSI YEH */ | - |
| 774 | { 0x06CD, 0 }, /* 0x06CD */ | - |
| 775 | { 0x06CE, 0 }, /* 0x06CE */ | - |
| 776 | { 0x06CF, 0 }, /* 0x06CF */ | - |
| 777 | | - |
| 778 | { 0xFBE4, 3 }, /* 0x06D0 D E */ | - |
| 779 | { 0x06D1, 0 }, /* 0x06D1 */ | - |
| 780 | { 0xFBAE, 1 }, /* 0x06D2 R YEH BARREE */ | - |
| 781 | { 0xFBB0, 1 }, /* 0x06D3 R YEH BARREE WITH HAMZA ABOVE */ | - |
| 782 | { 0x06D4, 0 }, /* 0x06D4 */ | - |
| 783 | { 0x06D5, 0 }, /* 0x06D5 */ | - |
| 784 | { 0x06D6, 0 }, /* 0x06D6 */ | - |
| 785 | { 0x06D7, 0 }, /* 0x06D7 */ | - |
| 786 | { 0x06D8, 0 }, /* 0x06D8 */ | - |
| 787 | { 0x06D9, 0 }, /* 0x06D9 */ | - |
| 788 | { 0x06DA, 0 }, /* 0x06DA */ | - |
| 789 | { 0x06DB, 0 }, /* 0x06DB */ | - |
| 790 | { 0x06DC, 0 }, /* 0x06DC */ | - |
| 791 | { 0x06DD, 0 }, /* 0x06DD */ | - |
| 792 | { 0x06DE, 0 }, /* 0x06DE */ | - |
| 793 | { 0x06DF, 0 }, /* 0x06DF */ | - |
| 794 | | - |
| 795 | { 0x06E0, 0 }, /* 0x06E0 */ | - |
| 796 | { 0x06E1, 0 }, /* 0x06E1 */ | - |
| 797 | { 0x06E2, 0 }, /* 0x06E2 */ | - |
| 798 | { 0x06E3, 0 }, /* 0x06E3 */ | - |
| 799 | { 0x06E4, 0 }, /* 0x06E4 */ | - |
| 800 | { 0x06E5, 0 }, /* 0x06E5 */ | - |
| 801 | { 0x06E6, 0 }, /* 0x06E6 */ | - |
| 802 | { 0x06E7, 0 }, /* 0x06E7 */ | - |
| 803 | { 0x06E8, 0 }, /* 0x06E8 */ | - |
| 804 | { 0x06E9, 0 }, /* 0x06E9 */ | - |
| 805 | { 0x06EA, 0 }, /* 0x06EA */ | - |
| 806 | { 0x06EB, 0 }, /* 0x06EB */ | - |
| 807 | { 0x06EC, 0 }, /* 0x06EC */ | - |
| 808 | { 0x06ED, 0 }, /* 0x06ED */ | - |
| 809 | { 0x06EE, 0 }, /* 0x06EE */ | - |
| 810 | { 0x06EF, 0 }, /* 0x06EF */ | - |
| 811 | | - |
| 812 | { 0x06F0, 0 }, /* 0x06F0 */ | - |
| 813 | { 0x06F1, 0 }, /* 0x06F1 */ | - |
| 814 | { 0x06F2, 0 }, /* 0x06F2 */ | - |
| 815 | { 0x06F3, 0 }, /* 0x06F3 */ | - |
| 816 | { 0x06F4, 0 }, /* 0x06F4 */ | - |
| 817 | { 0x06F5, 0 }, /* 0x06F5 */ | - |
| 818 | { 0x06F6, 0 }, /* 0x06F6 */ | - |
| 819 | { 0x06F7, 0 }, /* 0x06F7 */ | - |
| 820 | { 0x06F8, 0 }, /* 0x06F8 */ | - |
| 821 | { 0x06F9, 0 }, /* 0x06F9 */ | - |
| 822 | { 0x06FA, 0 }, /* 0x06FA */ | - |
| 823 | { 0x06FB, 0 }, /* 0x06FB */ | - |
| 824 | { 0x06FC, 0 }, /* 0x06FC */ | - |
| 825 | { 0x06FD, 0 }, /* 0x06FD */ | - |
| 826 | { 0x06FE, 0 }, /* 0x06FE */ | - |
| 827 | { 0x06FF, 0 } /* 0x06FF */ | - |
| 828 | }; | - |
| 829 | | - |
| 830 | /* the arabicUnicodeMapping does not work for U+0649 ALEF MAKSURA, this table does */ | - |
| 831 | static const hb_uint16 alefMaksura[4] = {0xFEEF, 0xFEF0, 0xFBE8, 0xFBE9}; | - |
| 832 | | - |
| 833 | /* | - |
| 834 | // this is a bit tricky. Alef always binds to the right, so the second parameter descibing the shape | - |
| 835 | // of the lam can be either initial of medial. So initial maps to the isolated form of the ligature, | - |
| 836 | // medial to the final form | - |
| 837 | */ | - |
| 838 | static const hb_uint16 arabicUnicodeLamAlefMapping[6][4] = { | - |
| 839 | { 0xfffd, 0xfffd, 0xfef5, 0xfef6 }, /* 0x622 R Alef with Madda above */ | - |
| 840 | { 0xfffd, 0xfffd, 0xfef7, 0xfef8 }, /* 0x623 R Alef with Hamza above */ | - |
| 841 | { 0xfffd, 0xfffd, 0xfffd, 0xfffd }, /* 0x624 // Just to fill the table ;-) */ | - |
| 842 | { 0xfffd, 0xfffd, 0xfef9, 0xfefa }, /* 0x625 R Alef with Hamza below */ | - |
| 843 | { 0xfffd, 0xfffd, 0xfffd, 0xfffd }, /* 0x626 // Just to fill the table ;-) */ | - |
| 844 | { 0xfffd, 0xfffd, 0xfefb, 0xfefc } /* 0x627 R Alef */ | - |
| 845 | }; | - |
| 846 | | - |
| 847 | static int getShape(hb_uint8 cell, int shape) | - |
| 848 | { | - |
| 849 | /* the arabicUnicodeMapping does not work for U+0649 ALEF MAKSURA, handle this here */ | - |
| 850 | int ch = (cell != 0x49) never evaluated: (cell != 0x49) | 0 |
| 851 | ? (shape ? arabicUnicodeMapping[cell][0] + shape : 0x600+cell) never executed (the execution status of this line is deduced): ? (shape ? arabicUnicodeMapping[cell][0] + shape : 0x600+cell) | - |
| 852 | : alefMaksura[shape] ; never executed (the execution status of this line is deduced): : alefMaksura[shape] ; | - |
| 853 | return ch; never executed: return ch; | 0 |
| 854 | } | - |
| 855 | | - |
| 856 | | - |
| 857 | /* | - |
| 858 | Two small helper functions for arabic shaping. | - |
| 859 | */ | - |
| 860 | static HB_UChar16 prevChar(const HB_UChar16 *str, int pos) | - |
| 861 | { | - |
| 862 | /*qDebug("leftChar: pos=%d", pos); */ | - |
| 863 | const HB_UChar16 *ch = str + pos - 1; never executed (the execution status of this line is deduced): const HB_UChar16 *ch = str + pos - 1; | - |
| 864 | pos--; never executed (the execution status of this line is deduced): pos--; | - |
| 865 | while(pos > -1) { never evaluated: pos > -1 | 0 |
| 866 | if(HB_GetUnicodeCharCategory(*ch) != HB_Mark_NonSpacing) never evaluated: HB_GetUnicodeCharCategory(*ch) != HB_Mark_NonSpacing | 0 |
| 867 | return *ch; never executed: return *ch; | 0 |
| 868 | pos--; never executed (the execution status of this line is deduced): pos--; | - |
| 869 | ch--; never executed (the execution status of this line is deduced): ch--; | - |
| 870 | } | 0 |
| 871 | return ReplacementCharacter; never executed: return ReplacementCharacter; | 0 |
| 872 | } | - |
| 873 | | - |
| 874 | static HB_UChar16 nextChar(const HB_UChar16 *str, hb_uint32 len, hb_uint32 pos) | - |
| 875 | { | - |
| 876 | const HB_UChar16 *ch = str + pos + 1; never executed (the execution status of this line is deduced): const HB_UChar16 *ch = str + pos + 1; | - |
| 877 | pos++; never executed (the execution status of this line is deduced): pos++; | - |
| 878 | while(pos < len) { never evaluated: pos < len | 0 |
| 879 | /*qDebug("rightChar: %d isLetter=%d, joining=%d", pos, ch.isLetter(), ch.joining()); */ | - |
| 880 | if(HB_GetUnicodeCharCategory(*ch) != HB_Mark_NonSpacing) never evaluated: HB_GetUnicodeCharCategory(*ch) != HB_Mark_NonSpacing | 0 |
| 881 | return *ch; never executed: return *ch; | 0 |
| 882 | /* assume it's a transparent char, this might not be 100% correct */ | - |
| 883 | pos++; never executed (the execution status of this line is deduced): pos++; | - |
| 884 | ch++; never executed (the execution status of this line is deduced): ch++; | - |
| 885 | } | 0 |
| 886 | return ReplacementCharacter; never executed: return ReplacementCharacter; | 0 |
| 887 | } | - |
| 888 | | - |
| 889 | static void shapedString(const HB_UChar16 *uc, hb_uint32 stringLength, hb_uint32 from, hb_uint32 len, HB_UChar16 *shapeBuffer, int *shapedLength, | - |
| 890 | HB_Bool reverse, HB_GlyphAttributes *attributes, unsigned short *logClusters) | - |
| 891 | { | - |
| 892 | HB_ArabicProperties *properties; never executed (the execution status of this line is deduced): HB_ArabicProperties *properties; | - |
| 893 | hb_int32 f = from; never executed (the execution status of this line is deduced): hb_int32 f = from; | - |
| 894 | hb_uint32 l = len; never executed (the execution status of this line is deduced): hb_uint32 l = len; | - |
| 895 | const HB_UChar16 *ch; never executed (the execution status of this line is deduced): const HB_UChar16 *ch; | - |
| 896 | HB_UChar16 *data; never executed (the execution status of this line is deduced): HB_UChar16 *data; | - |
| 897 | int clusterStart; never executed (the execution status of this line is deduced): int clusterStart; | - |
| 898 | hb_uint32 i; never executed (the execution status of this line is deduced): hb_uint32 i; | - |
| 899 | HB_STACKARRAY(HB_ArabicProperties, props, len + 2); never executed: props = (HB_ArabicProperties *)malloc((len + 2) * sizeof(HB_ArabicProperties)); never evaluated: (len + 2) >= 512 | 0 |
| 900 | properties = props; never executed (the execution status of this line is deduced): properties = props; | - |
| 901 | | - |
| 902 | assert(stringLength >= from + len); never executed (the execution status of this line is deduced): ((stringLength >= from + len) ? static_cast<void> (0) : __assert_fail ("stringLength >= from + len", "../3rdparty/harfbuzz/src/harfbuzz-arabic.c", 902, __PRETTY_FUNCTION__)); | - |
| 903 | | - |
| 904 | if(len == 0) { never evaluated: len == 0 | 0 |
| 905 | *shapedLength = 0; never executed (the execution status of this line is deduced): *shapedLength = 0; | - |
| 906 | return; | 0 |
| 907 | } | - |
| 908 | | - |
| 909 | if (from > 0) { never evaluated: from > 0 | 0 |
| 910 | --f; never executed (the execution status of this line is deduced): --f; | - |
| 911 | ++l; never executed (the execution status of this line is deduced): ++l; | - |
| 912 | ++properties; never executed (the execution status of this line is deduced): ++properties; | - |
| 913 | } | 0 |
| 914 | if (f + l < stringLength) never evaluated: f + l < stringLength | 0 |
| 915 | ++l; | 0 |
| 916 | getArabicProperties(uc+f, l, props); never executed (the execution status of this line is deduced): getArabicProperties(uc+f, l, props); | - |
| 917 | | - |
| 918 | ch = uc + from; never executed (the execution status of this line is deduced): ch = uc + from; | - |
| 919 | data = shapeBuffer; never executed (the execution status of this line is deduced): data = shapeBuffer; | - |
| 920 | clusterStart = 0; never executed (the execution status of this line is deduced): clusterStart = 0; | - |
| 921 | | - |
| 922 | for (i = 0; i < len; i++) { | 0 |
| 923 | hb_uint8 r = *ch >> 8; never executed (the execution status of this line is deduced): hb_uint8 r = *ch >> 8; | - |
| 924 | int gpos = data - shapeBuffer; never executed (the execution status of this line is deduced): int gpos = data - shapeBuffer; | - |
| 925 | | - |
| 926 | if (r != 0x06) { never evaluated: r != 0x06 | 0 |
| 927 | if (r == 0x20) { never evaluated: r == 0x20 | 0 |
| 928 | if (*ch == 0x200c || *ch == 0x200d) never evaluated: *ch == 0x200c never evaluated: *ch == 0x200d | 0 |
| 929 | /* remove ZWJ and ZWNJ */ | - |
| 930 | goto skip; never executed: goto skip; | 0 |
| 931 | } | 0 |
| 932 | if (reverse) | 0 |
| 933 | *data = HB_GetMirroredChar(*ch); never executed: *data = HB_GetMirroredChar(*ch); | 0 |
| 934 | else | - |
| 935 | *data = *ch; never executed: *data = *ch; | 0 |
| 936 | } else { | - |
| 937 | hb_uint8 c = *ch & 0xff; never executed (the execution status of this line is deduced): hb_uint8 c = *ch & 0xff; | - |
| 938 | int pos = i + from; never executed (the execution status of this line is deduced): int pos = i + from; | - |
| 939 | int shape = properties[i].shape; never executed (the execution status of this line is deduced): int shape = properties[i].shape; | - |
| 940 | /* qDebug("mapping U+%x to shape %d glyph=0x%x", ch->unicode(), shape, getShape(c, shape)); */ | - |
| 941 | /* take care of lam-alef ligatures (lam right of alef) */ | - |
| 942 | hb_uint16 map; never executed (the execution status of this line is deduced): hb_uint16 map; | - |
| 943 | switch (c) { | - |
| 944 | case 0x44: { /* lam */ | - |
| 945 | const HB_UChar16 pch = nextChar(uc, stringLength, pos); never executed (the execution status of this line is deduced): const HB_UChar16 pch = nextChar(uc, stringLength, pos); | - |
| 946 | if ((pch >> 8) == 0x06) { never evaluated: (pch >> 8) == 0x06 | 0 |
| 947 | switch (pch & 0xff) { | - |
| 948 | case 0x22: | - |
| 949 | case 0x23: | - |
| 950 | case 0x25: | - |
| 951 | case 0x27: | - |
| 952 | /* qDebug(" lam of lam-alef ligature"); */ | - |
| 953 | map = arabicUnicodeLamAlefMapping[(pch & 0xff) - 0x22][shape]; never executed (the execution status of this line is deduced): map = arabicUnicodeLamAlefMapping[(pch & 0xff) - 0x22][shape]; | - |
| 954 | goto next; never executed: goto next; | 0 |
| 955 | default: | - |
| 956 | break; | 0 |
| 957 | } | - |
| 958 | } | 0 |
| 959 | break; | 0 |
| 960 | } | - |
| 961 | case 0x22: /* alef with madda */ | - |
| 962 | case 0x23: /* alef with hamza above */ | - |
| 963 | case 0x25: /* alef with hamza below */ | - |
| 964 | case 0x27: /* alef */ | - |
| 965 | if (prevChar(uc, pos) == 0x0644) { never evaluated: prevChar(uc, pos) == 0x0644 | 0 |
| 966 | /* have a lam alef ligature */ | - |
| 967 | /*qDebug(" alef of lam-alef ligature"); */ | - |
| 968 | goto skip; never executed: goto skip; | 0 |
| 969 | } | - |
| 970 | default: | - |
| 971 | break; | 0 |
| 972 | } | - |
| 973 | map = getShape(c, shape); never executed (the execution status of this line is deduced): map = getShape(c, shape); | - |
| 974 | next: code before this statement never executed: next: | 0 |
| 975 | *data = map; never executed (the execution status of this line is deduced): *data = map; | - |
| 976 | } | 0 |
| 977 | /* ##### Fixme */ | - |
| 978 | /*glyphs[gpos].attributes.zeroWidth = zeroWidth; */ | - |
| 979 | if (HB_GetUnicodeCharCategory(*ch) == HB_Mark_NonSpacing) { never evaluated: HB_GetUnicodeCharCategory(*ch) == HB_Mark_NonSpacing | 0 |
| 980 | attributes[gpos].mark = TRUE; never executed (the execution status of this line is deduced): attributes[gpos].mark = (!0); | - |
| 981 | /* qDebug("glyph %d (char %d) is mark!", gpos, i); */ | - |
| 982 | } else { | 0 |
| 983 | attributes[gpos].mark = FALSE; never executed (the execution status of this line is deduced): attributes[gpos].mark = 0; | - |
| 984 | clusterStart = data - shapeBuffer; never executed (the execution status of this line is deduced): clusterStart = data - shapeBuffer; | - |
| 985 | } | 0 |
| 986 | attributes[gpos].clusterStart = !attributes[gpos].mark; never executed (the execution status of this line is deduced): attributes[gpos].clusterStart = !attributes[gpos].mark; | - |
| 987 | attributes[gpos].combiningClass = HB_GetUnicodeCharCombiningClass(*ch); never executed (the execution status of this line is deduced): attributes[gpos].combiningClass = HB_GetUnicodeCharCombiningClass(*ch); | - |
| 988 | attributes[gpos].justification = properties[i].justification; never executed (the execution status of this line is deduced): attributes[gpos].justification = properties[i].justification; | - |
| 989 | /* qDebug("data[%d] = %x (from %x)", gpos, (uint)data->unicode(), ch->unicode());*/ | - |
| 990 | data++; never executed (the execution status of this line is deduced): data++; | - |
| 991 | skip: code before this statement never executed: skip: | 0 |
| 992 | ch++; never executed (the execution status of this line is deduced): ch++; | - |
| 993 | logClusters[i] = clusterStart; never executed (the execution status of this line is deduced): logClusters[i] = clusterStart; | - |
| 994 | } | 0 |
| 995 | *shapedLength = data - shapeBuffer; never executed (the execution status of this line is deduced): *shapedLength = data - shapeBuffer; | - |
| 996 | | - |
| 997 | HB_FREE_STACKARRAY(props); never executed: free(props); never evaluated: stackprops != props | 0 |
| 998 | } | 0 |
| 999 | | - |
| 1000 | #ifndef NO_OPENTYPE | - |
| 1001 | | - |
| 1002 | static const HB_OpenTypeFeature arabic_features[] = { | - |
| 1003 | { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, | - |
| 1004 | { HB_MAKE_TAG('i', 's', 'o', 'l'), IsolProperty }, | - |
| 1005 | { HB_MAKE_TAG('f', 'i', 'n', 'a'), FinaProperty }, | - |
| 1006 | { HB_MAKE_TAG('m', 'e', 'd', 'i'), MediProperty }, | - |
| 1007 | { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty }, | - |
| 1008 | { HB_MAKE_TAG('r', 'l', 'i', 'g'), RligProperty }, | - |
| 1009 | { HB_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty }, | - |
| 1010 | { HB_MAKE_TAG('l', 'i', 'g', 'a'), LigaProperty }, | - |
| 1011 | { HB_MAKE_TAG('d', 'l', 'i', 'g'), DligProperty }, | - |
| 1012 | { HB_MAKE_TAG('c', 's', 'w', 'h'), CswhProperty }, | - |
| 1013 | /* mset is used in old Win95 fonts that don't have a 'mark' positioning table. */ | - |
| 1014 | { HB_MAKE_TAG('m', 's', 'e', 't'), MsetProperty }, | - |
| 1015 | {0, 0} | - |
| 1016 | }; | - |
| 1017 | | - |
| 1018 | static const HB_OpenTypeFeature syriac_features[] = { | - |
| 1019 | { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, | - |
| 1020 | { HB_MAKE_TAG('i', 's', 'o', 'l'), IsolProperty }, | - |
| 1021 | { HB_MAKE_TAG('f', 'i', 'n', 'a'), FinaProperty }, | - |
| 1022 | { HB_MAKE_TAG('f', 'i', 'n', '2'), FinaProperty }, | - |
| 1023 | { HB_MAKE_TAG('f', 'i', 'n', '3'), FinaProperty }, | - |
| 1024 | { HB_MAKE_TAG('m', 'e', 'd', 'i'), MediProperty }, | - |
| 1025 | { HB_MAKE_TAG('m', 'e', 'd', '2'), MediProperty }, | - |
| 1026 | { HB_MAKE_TAG('i', 'n', 'i', 't'), InitProperty }, | - |
| 1027 | { HB_MAKE_TAG('r', 'l', 'i', 'g'), RligProperty }, | - |
| 1028 | { HB_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty }, | - |
| 1029 | { HB_MAKE_TAG('l', 'i', 'g', 'a'), LigaProperty }, | - |
| 1030 | { HB_MAKE_TAG('d', 'l', 'i', 'g'), DligProperty }, | - |
| 1031 | {0, 0} | - |
| 1032 | }; | - |
| 1033 | | - |
| 1034 | static HB_Bool arabicSyriacOpenTypeShape(HB_ShaperItem *item, HB_Bool *ot_ok) | - |
| 1035 | { | - |
| 1036 | const HB_UChar16 *uc; executed (the execution status of this line is deduced): const HB_UChar16 *uc; | - |
| 1037 | const int nglyphs = item->num_glyphs; executed (the execution status of this line is deduced): const int nglyphs = item->num_glyphs; | - |
| 1038 | hb_int32 f; executed (the execution status of this line is deduced): hb_int32 f; | - |
| 1039 | hb_uint32 l; executed (the execution status of this line is deduced): hb_uint32 l; | - |
| 1040 | HB_ArabicProperties *properties; executed (the execution status of this line is deduced): HB_ArabicProperties *properties; | - |
| 1041 | HB_DECLARE_STACKARRAY(HB_ArabicProperties, props) executed (the execution status of this line is deduced): HB_ArabicProperties stackprops[512]; HB_ArabicProperties *props = stackprops; | - |
| 1042 | HB_DECLARE_STACKARRAY(hb_uint32, apply) executed (the execution status of this line is deduced): hb_uint32 stackapply[512]; hb_uint32 *apply = stackapply; | - |
| 1043 | HB_Bool shaped; executed (the execution status of this line is deduced): HB_Bool shaped; | - |
| 1044 | int i = 0; executed (the execution status of this line is deduced): int i = 0; | - |
| 1045 | | - |
| 1046 | *ot_ok = TRUE; executed (the execution status of this line is deduced): *ot_ok = (!0); | - |
| 1047 | | - |
| 1048 | if (!HB_ConvertStringToGlyphIndices(item)) partially evaluated: !HB_ConvertStringToGlyphIndices(item)| no Evaluation Count:0 | yes Evaluation Count:57 |
| 0-57 |
| 1049 | return FALSE; never executed: return 0; | 0 |
| 1050 | HB_HeuristicSetGlyphAttributes(item); executed (the execution status of this line is deduced): HB_HeuristicSetGlyphAttributes(item); | - |
| 1051 | | - |
| 1052 | HB_INIT_STACKARRAY(HB_ArabicProperties, props, item->item.length + 2); never executed: props = (HB_ArabicProperties *)malloc((item->item.length + 2) * sizeof(HB_ArabicProperties)); partially evaluated: (item->item.length + 2) >= 512| no Evaluation Count:0 | yes Evaluation Count:57 |
| 0-57 |
| 1053 | HB_INIT_STACKARRAY(hb_uint32, apply, item->num_glyphs); never executed: apply = (hb_uint32 *)malloc((item->num_glyphs) * sizeof(hb_uint32)); partially evaluated: (item->num_glyphs) >= 512| no Evaluation Count:0 | yes Evaluation Count:57 |
| 0-57 |
| 1054 | | - |
| 1055 | uc = item->string + item->item.pos; executed (the execution status of this line is deduced): uc = item->string + item->item.pos; | - |
| 1056 | | - |
| 1057 | properties = props; executed (the execution status of this line is deduced): properties = props; | - |
| 1058 | f = 0; executed (the execution status of this line is deduced): f = 0; | - |
| 1059 | l = item->item.length; executed (the execution status of this line is deduced): l = item->item.length; | - |
| 1060 | if (item->item.pos > 0) { evaluated: item->item.pos > 0| yes Evaluation Count:33 | yes Evaluation Count:24 |
| 24-33 |
| 1061 | --f; executed (the execution status of this line is deduced): --f; | - |
| 1062 | ++l; executed (the execution status of this line is deduced): ++l; | - |
| 1063 | ++properties; executed (the execution status of this line is deduced): ++properties; | - |
| 1064 | } executed: }Execution Count:33 | 33 |
| 1065 | if (f + l + item->item.pos < item->stringLength) { evaluated: f + l + item->item.pos < item->stringLength| yes Evaluation Count:37 | yes Evaluation Count:20 |
| 20-37 |
| 1066 | ++l; executed (the execution status of this line is deduced): ++l; | - |
| 1067 | } executed: }Execution Count:37 | 37 |
| 1068 | if (item->item.script == HB_Script_Nko) partially evaluated: item->item.script == HB_Script_Nko| no Evaluation Count:0 | yes Evaluation Count:57 |
| 0-57 |
| 1069 | getNkoProperties(uc+f, l, props); never executed: getNkoProperties(uc+f, l, props); | 0 |
| 1070 | else | - |
| 1071 | getArabicProperties(uc+f, l, props); executed: getArabicProperties(uc+f, l, props);Execution Count:57 | 57 |
| 1072 | | - |
| 1073 | for (i = 0; i < (int)item->num_glyphs; i++) { evaluated: i < (int)item->num_glyphs| yes Evaluation Count:191 | yes Evaluation Count:57 |
| 57-191 |
| 1074 | apply[i] = 0; executed (the execution status of this line is deduced): apply[i] = 0; | - |
| 1075 | | - |
| 1076 | if (properties[i].shape == XIsolated) evaluated: properties[i].shape == XIsolated| yes Evaluation Count:61 | yes Evaluation Count:130 |
| 61-130 |
| 1077 | apply[i] |= MediProperty|FinaProperty|InitProperty; executed: apply[i] |= MediProperty|FinaProperty|InitProperty;Execution Count:61 | 61 |
| 1078 | else if (properties[i].shape == XMedial) evaluated: properties[i].shape == XMedial| yes Evaluation Count:18 | yes Evaluation Count:112 |
| 18-112 |
| 1079 | apply[i] |= IsolProperty|FinaProperty|InitProperty; executed: apply[i] |= IsolProperty|FinaProperty|InitProperty;Execution Count:18 | 18 |
| 1080 | else if (properties[i].shape == XFinal) evaluated: properties[i].shape == XFinal| yes Evaluation Count:56 | yes Evaluation Count:56 |
| 56 |
| 1081 | apply[i] |= IsolProperty|MediProperty|InitProperty; executed: apply[i] |= IsolProperty|MediProperty|InitProperty;Execution Count:56 | 56 |
| 1082 | else if (properties[i].shape == XInitial) partially evaluated: properties[i].shape == XInitial| yes Evaluation Count:56 | no Evaluation Count:0 |
| 0-56 |
| 1083 | apply[i] |= IsolProperty|MediProperty|FinaProperty; executed: apply[i] |= IsolProperty|MediProperty|FinaProperty;Execution Count:56 | 56 |
| 1084 | | - |
| 1085 | item->attributes[i].justification = properties[i].justification; executed (the execution status of this line is deduced): item->attributes[i].justification = properties[i].justification; | - |
| 1086 | } executed: }Execution Count:191 | 191 |
| 1087 | | - |
| 1088 | HB_FREE_STACKARRAY(props); never executed: free(props); partially evaluated: stackprops != props| no Evaluation Count:0 | yes Evaluation Count:57 |
| 0-57 |
| 1089 | | - |
| 1090 | shaped = HB_OpenTypeShape(item, apply); executed (the execution status of this line is deduced): shaped = HB_OpenTypeShape(item, apply); | - |
| 1091 | | - |
| 1092 | HB_FREE_STACKARRAY(apply); never executed: free(apply); partially evaluated: stackapply != apply| no Evaluation Count:0 | yes Evaluation Count:57 |
| 0-57 |
| 1093 | | - |
| 1094 | if (!shaped) { partially evaluated: !shaped| no Evaluation Count:0 | yes Evaluation Count:57 |
| 0-57 |
| 1095 | *ot_ok = FALSE; never executed (the execution status of this line is deduced): *ot_ok = 0; | - |
| 1096 | return FALSE; never executed: return 0; | 0 |
| 1097 | } | - |
| 1098 | return HB_OpenTypePosition(item, nglyphs, /*doLogClusters*/TRUE); executed: return HB_OpenTypePosition(item, nglyphs, (!0));Execution Count:57 | 57 |
| 1099 | } | - |
| 1100 | | - |
| 1101 | #endif | - |
| 1102 | | - |
| 1103 | /* #### stil missing: identify invalid character combinations */ | - |
| 1104 | HB_Bool HB_ArabicShape(HB_ShaperItem *item) | - |
| 1105 | { | - |
| 1106 | int slen; executed (the execution status of this line is deduced): int slen; | - |
| 1107 | HB_Bool haveGlyphs; executed (the execution status of this line is deduced): HB_Bool haveGlyphs; | - |
| 1108 | HB_STACKARRAY(HB_UChar16, shapedChars, item->item.length); never executed: shapedChars = (HB_UChar16 *)malloc((item->item.length) * sizeof(HB_UChar16)); partially evaluated: (item->item.length) >= 512| no Evaluation Count:0 | yes Evaluation Count:57 |
| 0-57 |
| 1109 | | - |
| 1110 | assert(item->item.script == HB_Script_Arabic || item->item.script == HB_Script_Syriac executed (the execution status of this line is deduced): ((item->item.script == HB_Script_Arabic || item->item.script == HB_Script_Syriac || item->item.script == HB_Script_Nko) ? static_cast<void> (0) : __assert_fail ("item->item.script == HB_Script_Arabic || item->item.script == HB_Script_Syriac || item->item.script == HB_Script_Nko", "../3rdparty/harfbuzz/src/harfbuzz-arabic.c", 1111, __PRETTY_FUNCTION__)); | - |
| 1111 | || item->item.script == HB_Script_Nko); | - |
| 1112 | | - |
| 1113 | #ifndef NO_OPENTYPE | - |
| 1114 | | - |
| 1115 | if (HB_SelectScript(item, item->item.script == HB_Script_Arabic ? arabic_features : syriac_features)) { partially evaluated: HB_SelectScript(item, item->item.script == HB_Script_Arabic ? arabic_features : syriac_features)| yes Evaluation Count:57 | no Evaluation Count:0 |
| 0-57 |
| 1116 | HB_Bool ot_ok; executed (the execution status of this line is deduced): HB_Bool ot_ok; | - |
| 1117 | if (arabicSyriacOpenTypeShape(item, &ot_ok)) partially evaluated: arabicSyriacOpenTypeShape(item, &ot_ok)| yes Evaluation Count:57 | no Evaluation Count:0 |
| 0-57 |
| 1118 | return TRUE; executed: return (!0);Execution Count:57 | 57 |
| 1119 | if (ot_ok) | 0 |
| 1120 | return FALSE; never executed: return 0; | 0 |
| 1121 | /* fall through to the non OT code*/ | - |
| 1122 | } | 0 |
| 1123 | #endif | - |
| 1124 | | - |
| 1125 | if (item->item.script != HB_Script_Arabic) never evaluated: item->item.script != HB_Script_Arabic | 0 |
| 1126 | return HB_BasicShape(item); never executed: return HB_BasicShape(item); | 0 |
| 1127 | | - |
| 1128 | shapedString(item->string, item->stringLength, item->item.pos, item->item.length, shapedChars, &slen, never executed (the execution status of this line is deduced): shapedString(item->string, item->stringLength, item->item.pos, item->item.length, shapedChars, &slen, | - |
| 1129 | item->item.bidiLevel % 2, never executed (the execution status of this line is deduced): item->item.bidiLevel % 2, | - |
| 1130 | item->attributes, item->log_clusters); never executed (the execution status of this line is deduced): item->attributes, item->log_clusters); | - |
| 1131 | | - |
| 1132 | haveGlyphs = item->font->klass never executed (the execution status of this line is deduced): haveGlyphs = item->font->klass | - |
| 1133 | ->convertStringToGlyphIndices(item->font, never executed (the execution status of this line is deduced): ->convertStringToGlyphIndices(item->font, | - |
| 1134 | shapedChars, slen, never executed (the execution status of this line is deduced): shapedChars, slen, | - |
| 1135 | item->glyphs, &item->num_glyphs, never executed (the execution status of this line is deduced): item->glyphs, &item->num_glyphs, | - |
| 1136 | item->item.bidiLevel % 2); never executed (the execution status of this line is deduced): item->item.bidiLevel % 2); | - |
| 1137 | | - |
| 1138 | HB_FREE_STACKARRAY(shapedChars); never executed: free(shapedChars); never evaluated: stackshapedChars != shapedChars | 0 |
| 1139 | | - |
| 1140 | if (!haveGlyphs) never evaluated: !haveGlyphs | 0 |
| 1141 | return FALSE; never executed: return 0; | 0 |
| 1142 | | - |
| 1143 | HB_HeuristicPosition(item); never executed (the execution status of this line is deduced): HB_HeuristicPosition(item); | - |
| 1144 | return TRUE; never executed: return (!0); | 0 |
| 1145 | } | - |
| 1146 | | - |
| 1147 | | - |
| 1148 | | - |
| | |