ReactOS 0.4.17-dev-1133-gc25e4fd
bidi.c
Go to the documentation of this file.
1/*
2 * Uniscribe BiDirectional handling
3 *
4 * Copyright 2003 Shachar Shemesh
5 * Copyright 2007 Maarten Lankhorst
6 * Copyright 2010 CodeWeavers, Aric Stewart
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 *
22 * Code derived from the modified reference implementation
23 * that was found in revision 17 of http://unicode.org/reports/tr9/
24 * "Unicode Standard Annex #9: THE BIDIRECTIONAL ALGORITHM"
25 *
26 * -- Copyright (C) 1999-2005, ASMUS, Inc.
27 *
28 * Permission is hereby granted, free of charge, to any person obtaining a
29 * copy of the Unicode data files and any associated documentation (the
30 * "Data Files") or Unicode software and any associated documentation (the
31 * "Software") to deal in the Data Files or Software without restriction,
32 * including without limitation the rights to use, copy, modify, merge,
33 * publish, distribute, and/or sell copies of the Data Files or Software,
34 * and to permit persons to whom the Data Files or Software are furnished
35 * to do so, provided that (a) the above copyright notice(s) and this
36 * permission notice appear with all copies of the Data Files or Software,
37 * (b) both the above copyright notice(s) and this permission notice appear
38 * in associated documentation, and (c) there is clear notice in each
39 * modified Data File or in the Software as well as in the documentation
40 * associated with the Data File(s) or Software that the data or software
41 * has been modified.
42 */
43
44#include <stdarg.h>
45#include <stdlib.h>
46#include "windef.h"
47#include "winbase.h"
48#include "wingdi.h"
49#include "winnls.h"
50#include "usp10.h"
51#include "wine/debug.h"
52#include "wine/list.h"
53
54#include "usp10_internal.h"
55
56extern const unsigned short bidi_bracket_table[];
57extern const unsigned short bidi_direction_table[];
58
60
61#define ASSERT(x) do { if (!(x)) FIXME("assert failed: %s\n", #x); } while(0)
62#define MAX_DEPTH 125
63
64/* HELPER FUNCTIONS AND DECLARATIONS */
65
66/*------------------------------------------------------------------------
67 Bidirectional Character Types
68
69 as defined by the Unicode Bidirectional Algorithm Table 3-7.
70
71 Note:
72
73 The list of bidirectional character types here is not grouped the
74 same way as the table 3-7, since the numeric values for the types
75 are chosen to keep the state and action tables compact.
76------------------------------------------------------------------------*/
78{
79 /* input types */
80 /* ON MUST be zero, code relies on ON = NI = 0 */
81 ON = 0, /* Other Neutral */
82 L, /* Left Letter */
83 R, /* Right Letter */
84 AN, /* Arabic Number */
85 EN, /* European Number */
86 AL, /* Arabic Letter (Right-to-left) */
87 NSM, /* Non-spacing Mark */
88 CS, /* Common Separator */
89 ES, /* European Separator */
90 ET, /* European Terminator (post/prefix e.g. $ and %) */
91
92 /* resolved types */
93 BN, /* Boundary neutral (type of RLE etc after explicit levels) */
94
95 /* input types, */
96 S, /* Segment Separator (TAB) // used only in L1 */
97 WS, /* White space // used only in L1 */
98 B, /* Paragraph Separator (aka as PS) */
99
100 /* types for explicit controls */
101 RLO, /* these are used only in X1-X9 */
106
107 LRI, /* Isolate formatting characters new with 6.3 */
111
112 /* resolved types, also resolved directions */
113 NI = ON, /* alias, where ON, WS, S and Isolates are treated the same */
114};
115
116static const char debug_type[][4] =
117{
118 "ON", /* Other Neutral */
119 "L", /* Left Letter */
120 "R", /* Right Letter */
121 "AN", /* Arabic Number */
122 "EN", /* European Number */
123 "AL", /* Arabic Letter (Right-to-left) */
124 "NSM", /* Non-spacing Mark */
125 "CS", /* Common Separator */
126 "ES", /* European Separator */
127 "ET", /* European Terminator (post/prefix e.g. $ and %) */
128 "BN", /* Boundary neutral (type of RLE etc after explicit levels) */
129 "S", /* Segment Separator (TAB) // used only in L1 */
130 "WS", /* White space // used only in L1 */
131 "B", /* Paragraph Separator (aka as PS) */
132 "RLO", /* these are used only in X1-X9 */
133 "RLE",
134 "LRO",
135 "LRE",
136 "PDF",
137 "LRI", /* Isolate formatting characters new with 6.3 */
138 "RLI",
139 "FSI",
140 "PDI",
141};
142
143/* HELPER FUNCTIONS */
144
145static inline void dump_types(const char* header, WORD *types, int start, int end)
146{
147 int i, len = 0;
148 TRACE("%s:",header);
149 for (i = start; i < end && len < 200; i++)
150 {
151 TRACE(" %s",debug_type[types[i]]);
152 len += strlen(debug_type[types[i]])+1;
153 }
154 if (i != end)
155 TRACE("...");
156 TRACE("\n");
157}
158
159/* Convert the libwine information to the direction enum */
160static void classify(const WCHAR *string, WORD *chartype, DWORD count, const SCRIPT_CONTROL *c)
161{
162 unsigned i;
163
164 for (i = 0; i < count; ++i)
165 {
166 chartype[i] = get_table_entry_32( bidi_direction_table, string[i] );
167 if (c->fLegacyBidiClass && chartype[i] == ES)
168 {
169 if (string[i] == '+' || string[i] == '-') chartype[i] = NI;
170 }
171 }
172}
173
174/* RESOLVE EXPLICIT */
175
176static WORD GreaterEven(int i)
177{
178 return odd(i) ? i + 1 : i + 2;
179}
180
181static WORD GreaterOdd(int i)
182{
183 return odd(i) ? i + 2 : i + 1;
184}
185
187{
188 return odd(level) ? R : L;
189}
190
191/*------------------------------------------------------------------------
192 Function: resolveExplicit
193
194 Recursively resolves explicit embedding levels and overrides.
195 Implements rules X1-X9, of the Unicode Bidirectional Algorithm.
196
197 Input: Base embedding level and direction
198 Character count
199
200 Output: Array of embedding levels
201
202 In/Out: Array of direction classes
203
204
205 Note: The function uses two simple counters to keep track of
206 matching explicit codes and PDF. Use the default argument for
207 the outermost call. The nesting counter counts the recursion
208 depth and not the embedding level.
209------------------------------------------------------------------------*/
210typedef struct tagStackItem {
211 int level;
212 int override;
215
216#define push_stack(l,o,i) \
217 do { stack_top--; \
218 stack[stack_top].level = l; \
219 stack[stack_top].override = o; \
220 stack[stack_top].isolate = i;} while(0)
221
222#define pop_stack() do { stack_top++; } while(0)
223
224#define valid_level(x) (x <= MAX_DEPTH && overflow_isolate_count == 0 && overflow_embedding_count == 0)
225
226static void resolveExplicit(int level, WORD *pclass, WORD *poutLevel, WORD *poutOverrides, int count, BOOL initialOverride)
227{
228 /* X1 */
229 int overflow_isolate_count = 0;
230 int overflow_embedding_count = 0;
231 int valid_isolate_count = 0;
232 int i;
233
235 int stack_top = MAX_DEPTH+1;
236
237 stack[stack_top].level = level;
238 stack[stack_top].override = NI;
239 stack[stack_top].isolate = FALSE;
240
241 if (initialOverride)
242 {
243 if (odd(level))
245 else
247 }
248
249 for (i = 0; i < count; i++)
250 {
251 poutOverrides[i] = stack[stack_top].override;
252
253 /* X2 */
254 if (pclass[i] == RLE)
255 {
256 int least_odd = GreaterOdd(stack[stack_top].level);
257 poutLevel[i] = stack[stack_top].level;
258 if (valid_level(least_odd))
259 push_stack(least_odd, NI, FALSE);
260 else if (overflow_isolate_count == 0)
261 overflow_embedding_count++;
262 }
263 /* X3 */
264 else if (pclass[i] == LRE)
265 {
266 int least_even = GreaterEven(stack[stack_top].level);
267 poutLevel[i] = stack[stack_top].level;
268 if (valid_level(least_even))
269 push_stack(least_even, NI, FALSE);
270 else if (overflow_isolate_count == 0)
271 overflow_embedding_count++;
272 }
273 /* X4 */
274 else if (pclass[i] == RLO)
275 {
276 int least_odd = GreaterOdd(stack[stack_top].level);
277 poutLevel[i] = stack[stack_top].level;
278 if (valid_level(least_odd))
279 push_stack(least_odd, R, FALSE);
280 else if (overflow_isolate_count == 0)
281 overflow_embedding_count++;
282 }
283 /* X5 */
284 else if (pclass[i] == LRO)
285 {
286 int least_even = GreaterEven(stack[stack_top].level);
287 poutLevel[i] = stack[stack_top].level;
288 if (valid_level(least_even))
289 push_stack(least_even, L, FALSE);
290 else if (overflow_isolate_count == 0)
291 overflow_embedding_count++;
292 }
293 /* X5a */
294 else if (pclass[i] == RLI)
295 {
296 int least_odd = GreaterOdd(stack[stack_top].level);
297 poutLevel[i] = stack[stack_top].level;
298 if (valid_level(least_odd))
299 {
300 valid_isolate_count++;
301 push_stack(least_odd, NI, TRUE);
302 }
303 else
304 overflow_isolate_count++;
305 }
306 /* X5b */
307 else if (pclass[i] == LRI)
308 {
309 int least_even = GreaterEven(stack[stack_top].level);
310 poutLevel[i] = stack[stack_top].level;
311 if (valid_level(least_even))
312 {
313 valid_isolate_count++;
314 push_stack(least_even, NI, TRUE);
315 }
316 else
317 overflow_isolate_count++;
318 }
319 /* X5c */
320 else if (pclass[i] == FSI)
321 {
322 int j;
323 int new_level = 0;
324 int skipping = 0;
325 poutLevel[i] = stack[stack_top].level;
326 for (j = i+1; j < count; j++)
327 {
328 if (pclass[j] == LRI || pclass[j] == RLI || pclass[j] == FSI)
329 {
330 skipping++;
331 continue;
332 }
333 else if (pclass[j] == PDI)
334 {
335 if (skipping)
336 skipping --;
337 else
338 break;
339 continue;
340 }
341
342 if (skipping) continue;
343
344 if (pclass[j] == L)
345 {
346 new_level = 0;
347 break;
348 }
349 else if (pclass[j] == R || pclass[j] == AL)
350 {
351 new_level = 1;
352 break;
353 }
354 }
355 if (odd(new_level))
356 {
357 int least_odd = GreaterOdd(stack[stack_top].level);
358 if (valid_level(least_odd))
359 {
360 valid_isolate_count++;
361 push_stack(least_odd, NI, TRUE);
362 }
363 else
364 overflow_isolate_count++;
365 }
366 else
367 {
368 int least_even = GreaterEven(stack[stack_top].level);
369 if (valid_level(least_even))
370 {
371 valid_isolate_count++;
372 push_stack(least_even, NI, TRUE);
373 }
374 else
375 overflow_isolate_count++;
376 }
377 }
378 /* X6 */
379 else if (pclass[i] != B && pclass[i] != BN && pclass[i] != PDI && pclass[i] != PDF)
380 {
381 poutLevel[i] = stack[stack_top].level;
382 if (stack[stack_top].override != NI)
383 pclass[i] = stack[stack_top].override;
384 }
385 /* X6a */
386 else if (pclass[i] == PDI)
387 {
388 if (overflow_isolate_count) overflow_isolate_count--;
389 else if (!valid_isolate_count) {/* do nothing */}
390 else
391 {
392 overflow_embedding_count = 0;
393 while (!stack[stack_top].isolate) pop_stack();
394 pop_stack();
395 valid_isolate_count --;
396 }
397 poutLevel[i] = stack[stack_top].level;
398 }
399 /* X7 */
400 else if (pclass[i] == PDF)
401 {
402 poutLevel[i] = stack[stack_top].level;
403 if (overflow_isolate_count) {/* do nothing */}
404 else if (overflow_embedding_count) overflow_embedding_count--;
405 else if (!stack[stack_top].isolate && stack_top < (MAX_DEPTH+1))
406 pop_stack();
407 }
408 /* X8: Nothing */
409 }
410 /* X9: Based on 5.2 Retaining Explicit Formatting Characters */
411 for (i = 0; i < count ; i++)
412 if (pclass[i] == RLE || pclass[i] == LRE || pclass[i] == RLO || pclass[i] == LRO || pclass[i] == PDF)
413 pclass[i] = BN;
414}
415
416static inline int previousValidChar(const WORD *pcls, int index, int back_fence)
417{
418 if (index == -1 || index == back_fence) return index;
419 index --;
420 while (index > back_fence && pcls[index] == BN) index --;
421 return index;
422}
423
424static inline int nextValidChar(const WORD *pcls, int index, int front_fence)
425{
426 if (index == front_fence) return index;
427 index ++;
428 while (index < front_fence && pcls[index] == BN) index ++;
429 return index;
430}
431
432typedef struct tagRun
433{
434 int start;
435 int end;
438
439typedef struct tagRunChar
440{
441 WCHAR ch;
444
445typedef struct tagIsolatedRun
446{
447 struct list entry;
448 int length;
452
453 RunChar item[1];
455
456static inline int iso_nextValidChar(IsolatedRun *iso_run, int index)
457{
458 if (index >= (iso_run->length-1)) return -1;
459 index ++;
460 while (index < iso_run->length && *iso_run->item[index].pcls == BN) index++;
461 if (index == iso_run->length) return -1;
462 return index;
463}
464
465static inline int iso_previousValidChar(IsolatedRun *iso_run, int index)
466{
467
468 if (index <= 0) return -1;
469 index --;
470 while (index > -1 && *iso_run->item[index].pcls == BN) index--;
471 return index;
472}
473
474static inline void iso_dump_types(const char* header, IsolatedRun *iso_run)
475{
476 int i, len = 0;
477 TRACE("%s:",header);
478 TRACE("[ ");
479 for (i = 0; i < iso_run->length && len < 200; i++)
480 {
481 TRACE(" %s",debug_type[*iso_run->item[i].pcls]);
482 len += strlen(debug_type[*iso_run->item[i].pcls])+1;
483 }
484 if (i != iso_run->length)
485 TRACE("...");
486 TRACE(" ]\n");
487}
488
489/*------------------------------------------------------------------------
490 Function: resolveWeak
491
492 Resolves the directionality of numeric and other weak character types
493
494 Implements rules X10 and W1-W6 of the Unicode Bidirectional Algorithm.
495
496 Input: Array of embedding levels
497 Character count
498
499 In/Out: Array of directional classes
500
501 Note: On input only these directional classes are expected
502 AL, HL, R, L, ON, BN, NSM, AN, EN, ES, ET, CS,
503------------------------------------------------------------------------*/
504
505static void resolveWeak(IsolatedRun * iso_run)
506{
507 int i;
508
509 /* W1 */
510 for (i=0; i < iso_run->length; i++)
511 {
512 if (*iso_run->item[i].pcls == NSM)
513 {
514 int j = iso_previousValidChar(iso_run, i);
515 if (j == -1)
516 *iso_run->item[i].pcls = iso_run->sos;
517 else if (*iso_run->item[j].pcls >= LRI)
518 *iso_run->item[i].pcls = ON;
519 else
520 *iso_run->item[i].pcls = *iso_run->item[j].pcls;
521 }
522 }
523
524 /* W2 */
525 for (i = 0; i < iso_run->length; i++)
526 {
527 if (*iso_run->item[i].pcls == EN)
528 {
529 int j = iso_previousValidChar(iso_run, i);
530 while (j > -1)
531 {
532 if (*iso_run->item[j].pcls == R || *iso_run->item[j].pcls == L || *iso_run->item[j].pcls == AL)
533 {
534 if (*iso_run->item[j].pcls == AL)
535 *iso_run->item[i].pcls = AN;
536 break;
537 }
538 j = iso_previousValidChar(iso_run, j);
539 }
540 }
541 }
542
543 /* W3 */
544 for (i = 0; i < iso_run->length; i++)
545 {
546 if (*iso_run->item[i].pcls == AL)
547 *iso_run->item[i].pcls = R;
548 }
549
550 /* W4 */
551 for (i = 0; i < iso_run->length; i++)
552 {
553 if (*iso_run->item[i].pcls == ES)
554 {
555 int b = iso_previousValidChar(iso_run, i);
556 int f = iso_nextValidChar(iso_run, i);
557
558 if (b > -1 && f > -1 && *iso_run->item[b].pcls == EN && *iso_run->item[f].pcls == EN)
559 *iso_run->item[i].pcls = EN;
560 }
561 else if (*iso_run->item[i].pcls == CS)
562 {
563 int b = iso_previousValidChar(iso_run, i);
564 int f = iso_nextValidChar(iso_run, i);
565
566 if (b > -1 && f > -1 && *iso_run->item[b].pcls == EN && *iso_run->item[f].pcls == EN)
567 *iso_run->item[i].pcls = EN;
568 else if (b > -1 && f > -1 && *iso_run->item[b].pcls == AN && *iso_run->item[f].pcls == AN)
569 *iso_run->item[i].pcls = AN;
570 }
571 }
572
573 /* W5 */
574 for (i = 0; i < iso_run->length; i++)
575 {
576 if (*iso_run->item[i].pcls == ET)
577 {
578 int j;
579 for (j = i-1 ; j > -1; j--)
580 {
581 if (*iso_run->item[j].pcls == BN) continue;
582 if (*iso_run->item[j].pcls == ET) continue;
583 else if (*iso_run->item[j].pcls == EN) *iso_run->item[i].pcls = EN;
584 else break;
585 }
586 if (*iso_run->item[i].pcls == ET)
587 {
588 for (j = i+1; j < iso_run->length; j++)
589 {
590 if (*iso_run->item[j].pcls == BN) continue;
591 if (*iso_run->item[j].pcls == ET) continue;
592 else if (*iso_run->item[j].pcls == EN) *iso_run->item[i].pcls = EN;
593 else break;
594 }
595 }
596 }
597 }
598
599 /* W6 */
600 for (i = 0; i < iso_run->length; i++)
601 {
602 if (*iso_run->item[i].pcls == ET || *iso_run->item[i].pcls == ES || *iso_run->item[i].pcls == CS || *iso_run->item[i].pcls == ON)
603 {
604 int b = i-1;
605 int f = i+1;
606 if (b > -1 && *iso_run->item[b].pcls == BN)
607 *iso_run->item[b].pcls = ON;
608 if (f < iso_run->length && *iso_run->item[f].pcls == BN)
609 *iso_run->item[f].pcls = ON;
610
611 *iso_run->item[i].pcls = ON;
612 }
613 }
614
615 /* W7 */
616 for (i = 0; i < iso_run->length; i++)
617 {
618 if (*iso_run->item[i].pcls == EN)
619 {
620 int j;
621 for (j = iso_previousValidChar(iso_run, i); j > -1; j = iso_previousValidChar(iso_run, j))
622 if (*iso_run->item[j].pcls == R || *iso_run->item[j].pcls == L)
623 {
624 if (*iso_run->item[j].pcls == L)
625 *iso_run->item[i].pcls = L;
626 break;
627 }
628 if (iso_run->sos == L && j == -1)
629 *iso_run->item[i].pcls = L;
630 }
631 }
632}
633
634typedef struct tagBracketPair
635{
636 int start;
637 int end;
639
640static int __cdecl compr(const void *a, const void* b)
641{
642 return ((BracketPair*)a)->start - ((BracketPair*)b)->start;
643}
644
646{
647 WCHAR *open_stack;
648 int *stack_index;
649 int stack_top = iso_run->length;
650 unsigned int pair_count = 0;
652 SIZE_T out_size = 0;
653 int i;
654
655 open_stack = malloc(iso_run->length * sizeof(*open_stack));
656 stack_index = malloc(iso_run->length * sizeof(*stack_index));
657
658 for (i = 0; i < iso_run->length; i++)
659 {
660 unsigned short ubv = get_table_entry_16(bidi_bracket_table, iso_run->item[i].ch);
661
662 if (!ubv)
663 continue;
664
665 if ((ubv >> 8) == 0)
666 {
667 --stack_top;
668 open_stack[stack_top] = iso_run->item[i].ch + (signed char)(ubv & 0xff);
669 /* Deal with canonical equivalent U+2329/232A and U+3008/3009. */
670 if (open_stack[stack_top] == 0x232a)
671 open_stack[stack_top] = 0x3009;
672 stack_index[stack_top] = i;
673 }
674 else if ((ubv >> 8) == 1)
675 {
676 unsigned int j;
677
678 for (j = stack_top; j < iso_run->length; ++j)
679 {
680 WCHAR c = iso_run->item[i].ch;
681
682 if (c == 0x232a)
683 c = 0x3009;
684
685 if (c != open_stack[j])
686 continue;
687
688 if (!(usp10_array_reserve((void **)&out, &out_size, pair_count + 2, sizeof(*out))))
689 ERR("Failed to grow output array.\n");
690
691 out[pair_count].start = stack_index[j];
692 out[pair_count].end = i;
693 ++pair_count;
694
695 out[pair_count].start = -1;
696 stack_top = j + 1;
697 break;
698 }
699 }
700 }
701
702 free(open_stack);
703 free(stack_index);
704
705 if (!pair_count)
706 return NULL;
707
708 qsort(out, pair_count, sizeof(*out), compr);
709
710 return out;
711}
712
713#define N0_TYPE(a) ((a == AN || a == EN)?R:a)
714
715/*------------------------------------------------------------------------
716 Function: resolveNeutrals
717
718 Resolves the directionality of neutral character types.
719
720 Implements rules N1 and N2 of the Unicode Bidi Algorithm.
721
722 Input: Array of embedding levels
723 Character count
724 Baselevel
725
726 In/Out: Array of directional classes
727
728 Note: On input only these directional classes are expected
729 R, L, NI, AN, EN and BN
730
731 W8 resolves a number of ENs to L
732------------------------------------------------------------------------*/
733static void resolveNeutrals(IsolatedRun *iso_run)
734{
735 int i;
736 BracketPair *pairs = NULL;
737
738 /* Translate isolates into NI */
739 for (i = 0; i < iso_run->length; i++)
740 {
741 if (*iso_run->item[i].pcls >= LRI)
742 *iso_run->item[i].pcls = NI;
743
744 switch(*iso_run->item[i].pcls)
745 {
746 case B:
747 case S:
748 case WS: *iso_run->item[i].pcls = NI;
749 }
750
751 ASSERT(*iso_run->item[i].pcls < 5 || *iso_run->item[i].pcls == BN); /* "Only NI, L, R, AN, EN and BN are allowed" */
752 }
753
754 /* N0: Skipping bracketed pairs for now */
755 pairs = computeBracketPairs(iso_run);
756 if (pairs)
757 {
758 BracketPair *p = &pairs[0];
759 int i = 0;
760 while (p->start >= 0)
761 {
762 int j;
763 int e = EmbeddingDirection(iso_run->e);
764 int o = EmbeddingDirection(iso_run->e+1);
765 BOOL flag_o = FALSE;
766 TRACE("Bracket Pair [%i - %i]\n",p->start, p->end);
767
768 /* N0.b */
769 for (j = p->start+1; j < p->end; j++)
770 {
771 if (N0_TYPE(*iso_run->item[j].pcls) == e)
772 {
773 *iso_run->item[p->start].pcls = e;
774 *iso_run->item[p->end].pcls = e;
775 break;
776 }
777 else if (N0_TYPE(*iso_run->item[j].pcls) == o)
778 flag_o = TRUE;
779 }
780 /* N0.c */
781 if (j == p->end && flag_o)
782 {
783 for (j = p->start; j >= 0; j--)
784 {
785 if (N0_TYPE(*iso_run->item[j].pcls) == o)
786 {
787 *iso_run->item[p->start].pcls = o;
788 *iso_run->item[p->end].pcls = o;
789 break;
790 }
791 else if (N0_TYPE(*iso_run->item[j].pcls) == e)
792 {
793 *iso_run->item[p->start].pcls = e;
794 *iso_run->item[p->end].pcls = e;
795 break;
796 }
797 }
798 if ( j < 0 )
799 {
800 *iso_run->item[p->start].pcls = iso_run->sos;
801 *iso_run->item[p->end].pcls = iso_run->sos;
802 }
803 }
804
805 i++;
806 p = &pairs[i];
807 }
808 free(pairs);
809 }
810
811 /* N1 */
812 for (i = 0; i < iso_run->length; i++)
813 {
814 WORD l,r;
815
816 if (*iso_run->item[i].pcls == NI)
817 {
818 int j;
819 int b = iso_previousValidChar(iso_run, i);
820
821 if (b == -1)
822 {
823 l = iso_run->sos;
824 b = 0;
825 }
826 else
827 {
828 if (*iso_run->item[b].pcls == R || *iso_run->item[b].pcls == AN || *iso_run->item[b].pcls == EN)
829 l = R;
830 else if (*iso_run->item[b].pcls == L)
831 l = L;
832 else /* No string type */
833 continue;
834 }
835 j = iso_nextValidChar(iso_run, i);
836 while (j > -1 && *iso_run->item[j].pcls == NI) j = iso_nextValidChar(iso_run, j);
837
838 if (j == -1)
839 {
840 r = iso_run->eos;
841 j = iso_run->length;
842 }
843 else if (*iso_run->item[j].pcls == R || *iso_run->item[j].pcls == AN || *iso_run->item[j].pcls == EN)
844 r = R;
845 else if (*iso_run->item[j].pcls == L)
846 r = L;
847 else /* No string type */
848 continue;
849
850 if (r == l)
851 {
852 for (b = i; b < j && b < iso_run->length; b++)
853 *iso_run->item[b].pcls = r;
854 }
855 }
856 }
857
858 /* N2 */
859 for (i = 0; i < iso_run->length; i++)
860 {
861 if (*iso_run->item[i].pcls == NI)
862 {
863 int b = i-1;
864 int f = i+1;
865 *iso_run->item[i].pcls = EmbeddingDirection(iso_run->e);
866 if (b > -1 && *iso_run->item[b].pcls == BN)
867 *iso_run->item[b].pcls = EmbeddingDirection(iso_run->e);
868 if (f < iso_run->length && *iso_run->item[f].pcls == BN)
869 *iso_run->item[f].pcls = EmbeddingDirection(iso_run->e);
870 }
871 }
872}
873
874/*------------------------------------------------------------------------
875 Function: resolveImplicit
876
877 Recursively resolves implicit embedding levels.
878 Implements rules I1 and I2 of the Unicode Bidirectional Algorithm.
879
880 Input: Array of direction classes
881 Character count
882 Base level
883
884 In/Out: Array of embedding levels
885
886 Note: levels may exceed 15 on output.
887 Accepted subset of direction classes
888 R, L, AN, EN
889------------------------------------------------------------------------*/
890static void resolveImplicit(const WORD * pcls, WORD *plevel, int sos, int eos)
891{
892 int i;
893
894 /* I1/2 */
895 for (i = sos; i <= eos; i++)
896 {
897 if (pcls[i] == BN)
898 continue;
899
900 ASSERT(pcls[i] > 0); /* "No Neutrals allowed to survive here." */
901 ASSERT(pcls[i] < 5); /* "Out of range." */
902
903 if (odd(plevel[i]) && (pcls[i] == L || pcls[i] == EN || pcls [i] == AN))
904 plevel[i]++;
905 else if (!odd(plevel[i]) && pcls[i] == R)
906 plevel[i]++;
907 else if (!odd(plevel[i]) && (pcls[i] == EN || pcls [i] == AN))
908 plevel[i]+=2;
909 }
910}
911
912static void resolveResolved(unsigned baselevel, const WORD * pcls, WORD *plevel, int sos, int eos)
913{
914 int i;
915
916 /* L1 */
917 for (i = sos; i <= eos; i++)
918 {
919 if (pcls[i] == B || pcls[i] == S)
920 {
921 int j = i -1;
922 while (i > sos && j >= sos &&
923 (pcls[j] == WS || pcls[j] == FSI || pcls[j] == LRI || pcls[j] == RLI ||
924 pcls[j] == PDI || pcls[j] == LRE || pcls[j] == RLE || pcls[j] == LRO ||
925 pcls[j] == RLO || pcls[j] == PDF || pcls[j] == BN))
926 plevel[j--] = baselevel;
927 plevel[i] = baselevel;
928 }
929 else if (pcls[i] == LRE || pcls[i] == RLE || pcls[i] == LRO || pcls[i] == RLO ||
930 pcls[i] == PDF || pcls[i] == BN)
931 {
932 plevel[i] = i ? plevel[i - 1] : baselevel;
933 }
934 if (i == eos &&
935 (pcls[i] == WS || pcls[i] == FSI || pcls[i] == LRI || pcls[i] == RLI ||
936 pcls[i] == PDI || pcls[i] == LRE || pcls[i] == RLE || pcls[i] == LRO ||
937 pcls[i] == RLO || pcls[i] == PDF || pcls[i] == BN ))
938 {
939 int j = i;
940 while (j >= sos && (pcls[j] == WS || pcls[j] == FSI || pcls[j] == LRI || pcls[j] == RLI ||
941 pcls[j] == PDI || pcls[j] == LRE || pcls[j] == RLE || pcls[j] == LRO ||
942 pcls[j] == RLO || pcls[j] == PDF || pcls[j] == BN))
943 plevel[j--] = baselevel;
944 }
945 }
946}
947
948static void computeIsolatingRunsSet(unsigned baselevel, WORD *pcls, const WORD *pLevel,
949 const WCHAR *string, unsigned int uCount, struct list *set)
950{
951 int run_start, run_end, i;
952 int run_count = 0;
953 Run *runs;
954 IsolatedRun *current_isolated;
955
956 if (!(runs = calloc(uCount, sizeof(*runs))))
957 return;
958
959 list_init(set);
960
961 /* Build Runs */
962 run_start = 0;
963 while (run_start < uCount)
964 {
965 run_end = nextValidChar(pcls, run_start, uCount);
966 while (run_end < uCount && pLevel[run_end] == pLevel[run_start]) run_end = nextValidChar(pcls, run_end, uCount);
967 run_end --;
968 runs[run_count].start = run_start;
969 runs[run_count].end = run_end;
970 runs[run_count].e = pLevel[run_start];
971 run_start = nextValidChar(pcls, run_end, uCount);
972 run_count++;
973 }
974
975 /* Build Isolating Runs */
976 i = 0;
977 while (i < run_count)
978 {
979 int k = i;
980 if (runs[k].start >= 0)
981 {
982 int type_fence, real_end;
983 int j;
984
985 if (!(current_isolated = malloc(offsetof(IsolatedRun, item[uCount]))))
986 break;
987
988 run_start = runs[k].start;
989 current_isolated->e = runs[k].e;
990 current_isolated->length = (runs[k].end - runs[k].start)+1;
991
992 for (j = 0; j < current_isolated->length; j++)
993 {
994 current_isolated->item[j].pcls = &pcls[runs[k].start+j];
995 current_isolated->item[j].ch = string[runs[k].start + j];
996 }
997
998 run_end = runs[k].end;
999
1000 TRACE("{ [%i -- %i]",run_start, run_end);
1001
1002 if (pcls[run_end] == BN)
1003 run_end = previousValidChar(pcls, run_end, runs[k].start);
1004
1005 while (run_end < uCount && (pcls[run_end] == RLI || pcls[run_end] == LRI || pcls[run_end] == FSI))
1006 {
1007 j = k+1;
1008search:
1009 while (j < run_count && pcls[runs[j].start] != PDI) j++;
1010 if (j < run_count && runs[i].e != runs[j].e)
1011 {
1012 j++;
1013 goto search;
1014 }
1015
1016 if (j != run_count)
1017 {
1018 int m;
1019 int l = current_isolated->length;
1020
1021 current_isolated->length += (runs[j].end - runs[j].start)+1;
1022 for (m = 0; l < current_isolated->length; l++, m++)
1023 {
1024 current_isolated->item[l].pcls = &pcls[runs[j].start+m];
1025 current_isolated->item[l].ch = string[runs[j].start + m];
1026 }
1027
1028 TRACE("[%i -- %i]",runs[j].start, runs[j].end);
1029
1030 run_end = runs[j].end;
1031 if (pcls[run_end] == BN)
1032 run_end = previousValidChar(pcls, run_end, runs[i].start);
1033 runs[j].start = -1;
1034 k = j;
1035 }
1036 else
1037 {
1038 run_end = uCount;
1039 break;
1040 }
1041 }
1042
1043 type_fence = previousValidChar(pcls, run_start, -1);
1044
1045 if (type_fence == -1)
1046 current_isolated->sos = (baselevel > pLevel[run_start])?baselevel:pLevel[run_start];
1047 else
1048 current_isolated->sos = (pLevel[type_fence] > pLevel[run_start])?pLevel[type_fence]:pLevel[run_start];
1049
1050 current_isolated->sos = EmbeddingDirection(current_isolated->sos);
1051
1052 if (run_end == uCount)
1053 current_isolated->eos = current_isolated->sos;
1054 else
1055 {
1056 /* eos could be an BN */
1057 if ( pcls[run_end] == BN )
1058 {
1059 real_end = previousValidChar(pcls, run_end, run_start-1);
1060 if (real_end < run_start)
1061 real_end = run_start;
1062 }
1063 else
1064 real_end = run_end;
1065
1066 type_fence = nextValidChar(pcls, run_end, uCount);
1067 if (type_fence == uCount)
1068 current_isolated->eos = (baselevel > pLevel[real_end])?baselevel:pLevel[real_end];
1069 else
1070 current_isolated->eos = (pLevel[type_fence] > pLevel[real_end])?pLevel[type_fence]:pLevel[real_end];
1071
1072 current_isolated->eos = EmbeddingDirection(current_isolated->eos);
1073 }
1074
1075 list_add_tail(set, &current_isolated->entry);
1076 TRACE(" } level %i {%s <--> %s}\n",current_isolated->e, debug_type[current_isolated->sos], debug_type[current_isolated->eos]);
1077 }
1078 i++;
1079 }
1080
1081 free(runs);
1082}
1083
1084/*************************************************************
1085 * BIDI_DetermineLevels
1086 */
1088 const WCHAR *lpString, /* [in] The string for which information is to be returned */
1089 unsigned int uCount, /* [in] Number of WCHARs in string. */
1090 const SCRIPT_STATE *s,
1091 const SCRIPT_CONTROL *c,
1092 WORD *lpOutLevels, /* [out] final string levels */
1093 WORD *lpOutOverrides /* [out] final string overrides */
1094 )
1095{
1096 WORD *chartype;
1097 unsigned baselevel = 0;
1098 struct list IsolatingRuns;
1099 IsolatedRun *iso_run, *next;
1100
1101 TRACE("%s, %d\n", debugstr_wn(lpString, uCount), uCount);
1102
1103 if (!(chartype = malloc(uCount * sizeof(*chartype))))
1104 {
1105 WARN("Out of memory\n");
1106 return FALSE;
1107 }
1108
1109 baselevel = s->uBidiLevel;
1110
1111 classify(lpString, chartype, uCount, c);
1112 if (TRACE_ON(bidi)) dump_types("Start ", chartype, 0, uCount);
1113
1114 memset(lpOutOverrides, 0, sizeof(WORD) * uCount);
1115
1116 /* resolve explicit */
1117 resolveExplicit(baselevel, chartype, lpOutLevels, lpOutOverrides, uCount, s->fOverrideDirection);
1118 if (TRACE_ON(bidi)) dump_types("After Explicit", chartype, 0, uCount);
1119
1120 /* X10/BD13: Computer Isolating runs */
1121 computeIsolatingRunsSet(baselevel, chartype, lpOutLevels, lpString, uCount, &IsolatingRuns);
1122
1123 LIST_FOR_EACH_ENTRY_SAFE(iso_run, next, &IsolatingRuns, IsolatedRun, entry)
1124 {
1125 if (TRACE_ON(bidi)) iso_dump_types("Run", iso_run);
1126
1127 /* resolve weak */
1128 resolveWeak(iso_run);
1129 if (TRACE_ON(bidi)) iso_dump_types("After Weak", iso_run);
1130
1131 /* resolve neutrals */
1132 resolveNeutrals(iso_run);
1133 if (TRACE_ON(bidi)) iso_dump_types("After Neutrals", iso_run);
1134
1135 list_remove(&iso_run->entry);
1136 free(iso_run);
1137 }
1138
1139 if (TRACE_ON(bidi)) dump_types("Before Implicit", chartype, 0, uCount);
1140 /* resolveImplicit */
1141 resolveImplicit(chartype, lpOutLevels, 0, uCount-1);
1142
1143 /* resolveResolvedLevels*/
1144 classify(lpString, chartype, uCount, c);
1145 resolveResolved(baselevel, chartype, lpOutLevels, 0, uCount-1);
1146
1147 free(chartype);
1148 return TRUE;
1149}
1150
1151/* reverse cch indices */
1152static void reverse(int *pidx, int cch)
1153{
1154 int temp;
1155 int ich = 0;
1156 for (; ich < --cch; ich++)
1157 {
1158 temp = pidx[ich];
1159 pidx[ich] = pidx[cch];
1160 pidx[cch] = temp;
1161 }
1162}
1163
1164
1165/*------------------------------------------------------------------------
1166 Functions: reorder/reorderLevel
1167
1168 Recursively reorders the display string
1169 "From the highest level down, reverse all characters at that level and
1170 higher, down to the lowest odd level"
1171
1172 Implements rule L2 of the Unicode bidi Algorithm.
1173
1174 Input: Array of embedding levels
1175 Character count
1176 Flag enabling reversal (set to false by initial caller)
1177
1178 In/Out: Text to reorder
1179
1180 Note: levels may exceed 15 resp. 61 on input.
1181
1182 Rule L3 - reorder combining marks is not implemented here
1183 Rule L4 - glyph mirroring is implemented as a display option below
1184
1185 Note: this should be applied a line at a time
1186-------------------------------------------------------------------------*/
1187int BIDI_ReorderV2lLevel(int level, int *pIndices, const BYTE* plevel, int cch, BOOL fReverse)
1188{
1189 int ich = 0;
1190
1191 /* true as soon as first odd level encountered */
1192 fReverse = fReverse || odd(level);
1193
1194 for (; ich < cch; ich++)
1195 {
1196 if (plevel[ich] < level)
1197 {
1198 break;
1199 }
1200 else if (plevel[ich] > level)
1201 {
1202 ich += BIDI_ReorderV2lLevel(level + 1, pIndices + ich, plevel + ich,
1203 cch - ich, fReverse) - 1;
1204 }
1205 }
1206 if (fReverse)
1207 {
1208 reverse(pIndices, ich);
1209 }
1210 return ich;
1211}
1212
1213/* Applies the reorder in reverse. Taking an already reordered string and returning the original */
1214int BIDI_ReorderL2vLevel(int level, int *pIndices, const BYTE* plevel, int cch, BOOL fReverse)
1215{
1216 int ich = 0;
1217 int newlevel = -1;
1218
1219 /* true as soon as first odd level encountered */
1220 fReverse = fReverse || odd(level);
1221
1222 for (; ich < cch; ich++)
1223 {
1224 if (plevel[ich] < level)
1225 break;
1226 else if (plevel[ich] > level)
1227 newlevel = ich;
1228 }
1229 if (fReverse)
1230 {
1231 reverse(pIndices, ich);
1232 }
1233
1234 if (newlevel >= 0)
1235 {
1236 ich = 0;
1237 for (; ich < cch; ich++)
1238 if (plevel[ich] < level)
1239 break;
1240 else if (plevel[ich] > level)
1241 ich += BIDI_ReorderL2vLevel(level + 1, pIndices + ich, plevel + ich,
1242 cch - ich, fReverse) - 1;
1243 }
1244
1245 return ich;
1246}
1247
1248BOOL BIDI_GetStrengths(const WCHAR *string, unsigned int count, const SCRIPT_CONTROL *c, WORD *strength)
1249{
1250 unsigned int i;
1251
1252 classify(string, strength, count, c);
1253 for (i = 0; i < count; i++)
1254 {
1255 switch (strength[i])
1256 {
1257 case L:
1258 case LRE:
1259 case LRO:
1260 case R:
1261 case AL:
1262 case RLE:
1263 case RLO:
1264 strength[i] = BIDI_STRONG;
1265 break;
1266 case PDF:
1267 case EN:
1268 case ES:
1269 case ET:
1270 case AN:
1271 case CS:
1272 case BN:
1273 strength[i] = BIDI_WEAK;
1274 break;
1275 case B:
1276 case S:
1277 case WS:
1278 case ON:
1279 default: /* Neutrals and NSM */
1280 strength[i] = BIDI_NEUTRAL;
1281 }
1282 }
1283 return TRUE;
1284}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_init(struct list_entry *head)
Definition: list.h:51
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
r l[0]
Definition: byte_order.h:168
Definition: ehthrow.cxx:54
Definition: list.h:39
Definition: _set.h:50
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
struct tagBracketPair BracketPair
const unsigned short bidi_direction_table[]
Definition: direction.c:6
struct tagRun Run
static void iso_dump_types(const char *header, IsolatedRun *run)
Definition: bidi.c:475
struct tagIsolatedRun IsolatedRun
#define MAX_DEPTH
Definition: bidi.c:58
#define valid_level(x)
Definition: bidi.c:195
static const char debug_type[][4]
Definition: bidi.c:112
struct tagRunChar RunChar
directions
Definition: bidi.c:74
@ FSI
Definition: bidi.c:105
@ LRO
Definition: bidi.c:99
@ WS
Definition: bidi.c:93
@ EN
Definition: bidi.c:81
@ PDI
Definition: bidi.c:106
@ R
Definition: bidi.c:79
@ LRE
Definition: bidi.c:100
@ NI
Definition: bidi.c:109
@ RLE
Definition: bidi.c:98
@ B
Definition: bidi.c:94
@ ET
Definition: bidi.c:86
@ AN
Definition: bidi.c:80
@ RLI
Definition: bidi.c:104
@ ES
Definition: bidi.c:85
@ PDF
Definition: bidi.c:101
@ RLO
Definition: bidi.c:97
@ CS
Definition: bidi.c:84
@ ON
Definition: bidi.c:77
@ AL
Definition: bidi.c:82
@ LRI
Definition: bidi.c:103
@ BN
Definition: bidi.c:89
@ NSM
Definition: bidi.c:83
@ L
Definition: bidi.c:78
@ S
Definition: bidi.c:92
#define push_stack(l, o, i)
Definition: bidi.c:187
struct tagStackItem StackItem
const unsigned short bidi_bracket_table[]
Definition: bracket.c:7
#define pop_stack()
Definition: bidi.c:193
#define ASSERT(x)
Definition: bidi.c:57
#define odd(x)
Definition: bidi.c:60
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define TRACE_ON(x)
Definition: compat.h:75
#define __cdecl
Definition: corecrt.h:121
_ACRTIMP void __cdecl qsort(void *, size_t, size_t, int(__cdecl *)(const void *, const void *))
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
BOOL usp10_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size)
Definition: usp10.c:655
unsigned char
Definition: typeof.h:29
static const uint32_t k[]
Definition: sha256.c:24
static unsigned short get_table_entry_16(const unsigned short *table, WCHAR ch)
static unsigned short get_table_entry_32(const unsigned short *table, UINT ch)
static jsval_t stack_top(script_ctx_t *ctx)
Definition: engine.c:83
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint start
Definition: gl.h:1545
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
uint32_t entry
Definition: isohybrid.c:63
#define e
Definition: ke_i.h:82
#define f
Definition: ke_i.h:83
#define b
Definition: ke_i.h:79
#define debugstr_wn
Definition: kernel32.h:33
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK ULONG PVOID ULONG PVOID ULONG out_size
Definition: file.c:72
static short search(int val, const short *table, int size)
Definition: msg711.c:255
short WCHAR
Definition: pedump.c:58
#define calloc
Definition: rosglue.h:14
static calc_node_t temp
Definition: rpn_ieee.c:38
#define offsetof(TYPE, MEMBER)
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:242
#define memset(x, y, z)
Definition: compat.h:39
_In_ UINT _In_ UINT cch
Definition: shellapi.h:427
#define TRACE(s)
Definition: solgame.cpp:4
Definition: movable.cpp:9
Definition: format.c:80
int start
Definition: bidi.c:621
int length
Definition: bidi.c:450
RunChar item[1]
Definition: bidi.c:455
UINT8 eos
Definition: bidi.c:452
UINT8 e
Definition: bidi.c:453
UINT8 sos
Definition: bidi.c:451
WORD eos
Definition: bidi.c:450
WORD sos
Definition: bidi.c:449
struct list entry
Definition: bidi.c:449
WORD e
Definition: bidi.c:451
WCHAR ch
Definition: bidi.c:443
WORD * pcls
Definition: bidi.c:442
Definition: bidi.c:435
UINT8 e
Definition: bidi.c:438
int start
Definition: bidi.c:436
int end
Definition: bidi.c:437
WORD e
Definition: bidi.c:436
int level
Definition: bidi.c:211
BOOL isolate
Definition: bidi.c:184
Definition: cmds.c:130
PSYMCRYPT_PARALLEL_HASH_OPERATION next
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define BIDI_NEUTRAL
#define BIDI_STRONG
#define BIDI_WEAK
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
static void classify(LPCWSTR lpString, WORD *chartype, DWORD uCount)
Definition: bidi.c:113
static void reverse(int *pidx, int cch)
Definition: bidi.c:1152
static BracketPair * computeBracketPairs(IsolatedRun *iso_run)
Definition: bidi.c:645
static WORD EmbeddingDirection(int level)
Definition: bidi.c:186
static void resolveImplicit(const WORD *pcls, WORD *plevel, int sos, int eos)
Definition: bidi.c:890
int BIDI_ReorderL2vLevel(int level, int *pIndices, const BYTE *plevel, int cch, BOOL fReverse)
Definition: bidi.c:1214
int BIDI_ReorderV2lLevel(int level, int *pIndices, const BYTE *plevel, int cch, BOOL fReverse)
Definition: bidi.c:1187
static int iso_nextValidChar(IsolatedRun *iso_run, int index)
Definition: bidi.c:456
static int previousValidChar(const WORD *pcls, int index, int back_fence)
Definition: bidi.c:416
static WORD GreaterOdd(int i)
Definition: bidi.c:181
static int nextValidChar(const WORD *pcls, int index, int front_fence)
Definition: bidi.c:424
static int iso_previousValidChar(IsolatedRun *iso_run, int index)
Definition: bidi.c:465
static void resolveWeak(IsolatedRun *iso_run)
Definition: bidi.c:505
static void computeIsolatingRunsSet(unsigned baselevel, WORD *pcls, const WORD *pLevel, const WCHAR *string, unsigned int uCount, struct list *set)
Definition: bidi.c:948
static void resolveResolved(unsigned baselevel, const WORD *pcls, WORD *plevel, int sos, int eos)
Definition: bidi.c:912
#define N0_TYPE(a)
Definition: bidi.c:713
static void dump_types(const char *header, WORD *types, int start, int end)
Definition: bidi.c:145
static WORD GreaterEven(int i)
Definition: bidi.c:176
BOOL BIDI_DetermineLevels(const WCHAR *lpString, unsigned int uCount, const SCRIPT_STATE *s, const SCRIPT_CONTROL *c, WORD *lpOutLevels, WORD *lpOutOverrides)
Definition: bidi.c:1087
static void resolveExplicit(int level, WORD *pclass, WORD *poutLevel, WORD *poutOverrides, int count, BOOL initialOverride)
Definition: bidi.c:226
static int __cdecl compr(const void *a, const void *b)
Definition: bidi.c:640
BOOL BIDI_GetStrengths(const WCHAR *string, unsigned int count, const SCRIPT_CONTROL *c, WORD *strength)
Definition: bidi.c:1248
static void resolveNeutrals(IsolatedRun *iso_run)
Definition: bidi.c:733
unsigned char BYTE
Definition: xxhash.c:193