Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Side by Side Diff: third_party/harfbuzz/src/harfbuzz-arabic.c

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

Powered by Google App Engine
This is Rietveld 408576698