../3rdparty/harfbuzz/src/harfbuzz-arabic.c

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
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 -
30static const HB_UChar16 ReplacementCharacter = 0xfffd; -
31 -
32typedef struct { -
33 unsigned char shape; -
34 unsigned char justification; -
35} HB_ArabicProperties; -
36 -
37typedef 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*/ -
54typedef 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 -
132static 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 -
243static ArabicGroup arabicGroup(unsigned short uc) -
244{ -
245 if (uc >= 0x0600 && uc < 0x750)
evaluated: uc >= 0x0600
TRUEFALSE
yes
Evaluation Count:196
yes
Evaluation Count:75
partially evaluated: uc < 0x750
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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 -
289typedef enum { -
290 JNone, -
291 JCausing, -
292 JDual, -
293 JRight, -
294 JTransparent -
295} Joining; -
296 -
297static 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 -
323typedef struct { -
324 ArabicShape form1; -
325 ArabicShape form2; -
326} JoiningPair; -
327 -
328static 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/* -
340According to http://www.microsoft.com/middleeast/Arabicdev/IE6/KBase.asp -
341 -
3421. Find the priority of the connecting opportunities in each word -
3432. Add expansion at the highest priority connection opportunity -
3443. If more than one connection opportunity have the same highest value, -
345 use the opportunity closest to the end of the word. -
346 -
347Following is a chart that provides the priority for connection -
348opportunities and where expansion occurs. The character group names -
349are those in table 6.6 of the UNICODE 2.0 book. -
350 -
351 -
352PrioritY Glyph Condition Kashida Location -
353 -
354Arabic_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 -
358Arabic_Seen Seen, Sad Connecting to the next character. After the character. -
359 (Initial or medial form). -
360 -
361Arabic_HaaDal Teh Marbutah, Haa, Dal Connecting to previous character. Before the final form -
362 of these characters. -
363 -
364Arabic_Alef Alef, Tah, Lam, Connecting to previous character. Before the final form -
365 Kaf and Gaf of these characters. -
366 -
367Arabic_BaRa Reh, Yeh Connected to medial Beh Before preceding medial Baa -
368 -
369Arabic_Waw Waw, Ain, Qaf, Feh Connecting to previous character. Before the final form of -
370 these characters. -
371 -
372Arabic_Normal Other connecting Connecting to previous character. Before the final form -
373 characters of these characters. -
374 -
375 -
376 -
377This seems to imply that we have at most one kashida point per arabic word. -
378 -
379*/ -
380 -
381static 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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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 }
never executed: }
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;
never executed: 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
TRUEFALSE
yes
Evaluation Count:10
yes
Evaluation Count:16
partially evaluated: arabicGroup(chars[lastPos]) == Beh
TRUEFALSE
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 }
never executed: }
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 -
495static 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 -
510static 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) {
never evaluated: i < len
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 }
never executed: }
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}
never executed: }
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*/ -
550static 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 */ -
831static 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*/ -
838static 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 -
847static 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*/ -
860static 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 }
never executed: }
0
871 return ReplacementCharacter;
never executed: return ReplacementCharacter;
0
872} -
873 -
874static 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 }
never executed: }
0
886 return ReplacementCharacter;
never executed: return ReplacementCharacter;
0
887} -
888 -
889static 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;
never executed: 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 }
never executed: }
0
914 if (f + l < stringLength)
never evaluated: f + l < stringLength
0
915 ++l;
never executed: ++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++) {
never evaluated: i < len
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 }
never executed: }
0
932 if (reverse)
never evaluated: 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;
never executed: break;
0
957 } -
958 }
never executed: }
0
959 break;
never executed: 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;
never executed: 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 }
never executed: }
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 {
never executed: }
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 }
never executed: }
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 }
never executed: }
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}
never executed: }
0
999 -
1000#ifndef NO_OPENTYPE -
1001 -
1002static 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 -
1018static 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 -
1034static 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)
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
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
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:57
0-57
1093 -
1094 if (!shaped) {
partially evaluated: !shaped
TRUEFALSE
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 */ -
1104HB_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
TRUEFALSE
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)
TRUEFALSE
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)
TRUEFALSE
yes
Evaluation Count:57
no
Evaluation Count:0
0-57
1118 return TRUE;
executed: return (!0);
Execution Count:57
57
1119 if (ot_ok)
never evaluated: ot_ok
0
1120 return FALSE;
never executed: return 0;
0
1121 /* fall through to the non OT code*/ -
1122 }
never executed: }
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 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial