ReactOS  0.4.13-dev-73-gcfe54aa
bidi.c
Go to the documentation of this file.
1 /*
2  * GDI BiDirectional handling
3  *
4  * Copyright 2003 Shachar Shemesh
5  * Copyright 2007 Maarten Lankhorst
6  * Copyright 2010 CodeWeavers, Aric Stewart
7  *
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  *
23  * Code derived from the modified reference implementation
24  * that was found in revision 17 of http://unicode.org/reports/tr9/
25  * "Unicode Standard Annex #9: THE BIDIRECTIONAL ALGORITHM"
26  *
27  * -- Copyright (C) 1999-2005, ASMUS, Inc.
28  *
29  * Permission is hereby granted, free of charge, to any person obtaining a
30  * copy of the Unicode data files and any associated documentation (the
31  * "Data Files") or Unicode software and any associated documentation (the
32  * "Software") to deal in the Data Files or Software without restriction,
33  * including without limitation the rights to use, copy, modify, merge,
34  * publish, distribute, and/or sell copies of the Data Files or Software,
35  * and to permit persons to whom the Data Files or Software are furnished
36  * to do so, provided that (a) the above copyright notice(s) and this
37  * permission notice appear with all copies of the Data Files or Software,
38  * (b) both the above copyright notice(s) and this permission notice appear
39  * in associated documentation, and (c) there is clear notice in each
40  * modified Data File or in the Software as well as in the documentation
41  * associated with the Data File(s) or Software that the data or software
42  * has been modified.
43  */
44 
45 #include "ros_lpk.h"
46 //#include "config.h"
47 //#include "gdi_private.h"
48 
50 
51 /* HELPER FUNCTIONS AND DECLARATIONS */
52 
53 #define odd(x) ((x) & 1)
54 
55 /*------------------------------------------------------------------------
56  Bidirectional Character Types
57 
58  as defined by the Unicode Bidirectional Algorithm Table 3-7.
59 
60  Note:
61 
62  The list of bidirectional character types here is not grouped the
63  same way as the table 3-7, since the numberic values for the types
64  are chosen to keep the state and action tables compact.
65 ------------------------------------------------------------------------*/
67 {
68  /* input types */
69  /* ON MUST be zero, code relies on ON = N = 0 */
70  ON = 0, /* Other Neutral */
71  L, /* Left Letter */
72  R, /* Right Letter */
73  AN, /* Arabic Number */
74  EN, /* European Number */
75  AL, /* Arabic Letter (Right-to-left) */
76  NSM, /* Non-spacing Mark */
77  CS, /* Common Separator */
78  ES, /* European Separator */
79  ET, /* European Terminator (post/prefix e.g. $ and %) */
80 
81  /* resolved types */
82  BN, /* Boundary neutral (type of RLE etc after explicit levels) */
83 
84  /* input types, */
85  S, /* Segment Separator (TAB) // used only in L1 */
86  WS, /* White space // used only in L1 */
87  B, /* Paragraph Separator (aka as PS) */
88 
89  /* types for explicit controls */
90  RLO, /* these are used only in X1-X9 */
91  RLE,
92  LRO,
93  LRE,
94  PDF,
95 
96  /* resolved types, also resolved directions */
97  N = ON, /* alias, where ON, WS and S are treated the same */
98 };
99 
100 /* HELPER FUNCTIONS */
101 
102 /* Convert the libwine information to the direction enum */
103 static void classify(LPCWSTR lpString, WORD *chartype, DWORD uCount)
104 {
105  static const enum directions dir_map[16] =
106  {
107  L, /* unassigned defaults to L */
108  L,
109  R,
110  EN,
111  ES,
112  ET,
113  AN,
114  CS,
115  B,
116  S,
117  WS,
118  ON,
119  AL,
120  NSM,
121  BN,
122  PDF /* also LRE, LRO, RLE, RLO */
123  };
124 
125  unsigned i;
126 
127  for (i = 0; i < uCount; ++i)
128  {
129  chartype[i] = dir_map[get_char_typeW(lpString[i]) >> 12];
130  if (chartype[i] == PDF)
131  {
132  switch (lpString[i])
133  {
134  case 0x202A: chartype[i] = LRE; break;
135  case 0x202B: chartype[i] = RLE; break;
136  case 0x202C: chartype[i] = PDF; break;
137  case 0x202D: chartype[i] = LRO; break;
138  case 0x202E: chartype[i] = RLO; break;
139  }
140  }
141  }
142 }
143 
144 /* Set a run of cval values at locations all prior to, but not including */
145 /* iStart, to the new value nval. */
146 static void SetDeferredRun(BYTE *pval, int cval, int iStart, int nval)
147 {
148  int i = iStart - 1;
149  for (; i >= iStart - cval; i--)
150  {
151  pval[i] = nval;
152  }
153 }
154 
155 /* THE PARAGRAPH LEVEL */
156 
157 /*------------------------------------------------------------------------
158  Function: resolveParagraphs
159 
160  Resolves the input strings into blocks over which the algorithm
161  is then applied.
162 
163  Implements Rule P1 of the Unicode Bidi Algorithm
164 
165  Input: Text string
166  Character count
167 
168  Output: revised character count
169 
170  Note: This is a very simplistic function. In effect it restricts
171  the action of the algorithm to the first paragraph in the input
172  where a paragraph ends at the end of the first block separator
173  or at the end of the input text.
174 
175 ------------------------------------------------------------------------*/
176 
177 static int resolveParagraphs(WORD *types, int cch)
178 {
179  /* skip characters not of type B */
180  int ich = 0;
181  for(; ich < cch && types[ich] != B; ich++);
182  /* stop after first B, make it a BN for use in the next steps */
183  if (ich < cch && types[ich] == B)
184  types[ich++] = BN;
185  return ich;
186 }
187 
188 /* REORDER */
189 /*------------------------------------------------------------------------
190  Function: resolveLines
191 
192  Breaks a paragraph into lines
193 
194  Input: Array of line break flags
195  Character count
196  In/Out: Array of characters
197 
198  Returns the count of characters on the first line
199 
200  Note: This function only breaks lines at hard line breaks. Other
201  line breaks can be passed in. If pbrk[n] is TRUE, then a break
202  occurs after the character in pszInput[n]. Breaks before the first
203  character are not allowed.
204 ------------------------------------------------------------------------*/
205 static int resolveLines(LPCWSTR pszInput, const BOOL * pbrk, int cch)
206 {
207  /* skip characters not of type LS */
208  int ich = 0;
209  for(; ich < cch; ich++)
210  {
211  if (pszInput[ich] == (WCHAR)'\n' || (pbrk && pbrk[ich]))
212  {
213  ich++;
214  break;
215  }
216  }
217 
218  return ich;
219 }
220 
221 /*------------------------------------------------------------------------
222  Function: resolveWhiteSpace
223 
224  Resolves levels for WS and S
225  Implements rule L1 of the Unicode bidi Algorithm.
226 
227  Input: Base embedding level
228  Character count
229  Array of direction classes (for one line of text)
230 
231  In/Out: Array of embedding levels (for one line of text)
232 
233  Note: this should be applied a line at a time. The default driver
234  code supplied in this file assumes a single line of text; for
235  a real implementation, cch and the initial pointer values
236  would have to be adjusted.
237 ------------------------------------------------------------------------*/
238 static void resolveWhitespace(int baselevel, const WORD *pcls, BYTE *plevel, int cch)
239 {
240  int cchrun = 0;
241  BYTE oldlevel = baselevel;
242 
243  int ich = 0;
244  for (; ich < cch; ich++)
245  {
246  switch(pcls[ich])
247  {
248  default:
249  cchrun = 0; /* any other character breaks the run */
250  break;
251  case WS:
252  cchrun++;
253  break;
254 
255  case RLE:
256  case LRE:
257  case LRO:
258  case RLO:
259  case PDF:
260  case BN:
261  plevel[ich] = oldlevel;
262  cchrun++;
263  break;
264 
265  case S:
266  case B:
267  /* reset levels for WS before eot */
268  SetDeferredRun(plevel, cchrun, ich, baselevel);
269  cchrun = 0;
270  plevel[ich] = baselevel;
271  break;
272  }
273  oldlevel = plevel[ich];
274  }
275  /* reset level before eot */
276  SetDeferredRun(plevel, cchrun, ich, baselevel);
277 }
278 
279 /*------------------------------------------------------------------------
280  Function: BidiLines
281 
282  Implements the Line-by-Line phases of the Unicode Bidi Algorithm
283 
284  Input: Count of characters
285  Array of character directions
286 
287  Inp/Out: Input text
288  Array of levels
289 
290 ------------------------------------------------------------------------*/
291 static void BidiLines(int baselevel, LPWSTR pszOutLine, LPCWSTR pszLine, const WORD * pclsLine,
292  BYTE * plevelLine, int cchPara, const BOOL * pbrk)
293 {
294  int cchLine = 0;
295  int done = 0;
296  int *run;
297 
298  run = HeapAlloc(GetProcessHeap(), 0, cchPara * sizeof(int));
299  if (!run)
300  {
301  WARN("Out of memory\n");
302  return;
303  }
304 
305  do
306  {
307  /* break lines at LS */
308  cchLine = resolveLines(pszLine, pbrk, cchPara);
309 
310  /* resolve whitespace */
311  resolveWhitespace(baselevel, pclsLine, plevelLine, cchLine);
312 
313  if (pszOutLine)
314  {
315  int i;
316  /* reorder each line in place */
317  ScriptLayout(cchLine, plevelLine, NULL, run);
318  for (i = 0; i < cchLine; i++)
319  pszOutLine[done+run[i]] = pszLine[i];
320  }
321 
322  pszLine += cchLine;
323  plevelLine += cchLine;
324  pbrk += pbrk ? cchLine : 0;
325  pclsLine += cchLine;
326  cchPara -= cchLine;
327  done += cchLine;
328 
329  } while (cchPara);
330 
331  HeapFree(GetProcessHeap(), 0, run);
332 }
333 
334 /*************************************************************
335  * BIDI_Reorder
336  *
337  * Returns TRUE if reordering was required and done.
338  */
340  HDC hDC, /*[in] Display DC */
341  LPCWSTR lpString, /* [in] The string for which information is to be returned */
342  INT uCount, /* [in] Number of WCHARs in string. */
343  DWORD dwFlags, /* [in] GetCharacterPlacement compatible flags specifying how to process the string */
344  DWORD dwWineGCP_Flags, /* [in] Wine internal flags - Force paragraph direction */
345  LPWSTR lpOutString, /* [out] Reordered string */
346  INT uCountOut, /* [in] Size of output buffer */
347  UINT *lpOrder, /* [out] Logical -> Visual order map */
348  WORD **lpGlyphs, /* [out] reordered, mirrored, shaped glyphs to display */
349  INT *cGlyphs /* [out] number of glyphs generated */
350  )
351 {
352  WORD *chartype;
353  BYTE *levels;
354  INT i, done;
355  unsigned glyph_i;
356  BOOL is_complex;
357 
358  int maxItems;
359  int nItems;
363  HRESULT res;
365  WORD *run_glyphs = NULL;
366  WORD *pwLogClust = NULL;
367  SCRIPT_VISATTR *psva = NULL;
368  DWORD cMaxGlyphs = 0;
369  BOOL doGlyphs = TRUE;
370 
371  TRACE("%s, %d, 0x%08x lpOutString=%p, lpOrder=%p\n",
372  debugstr_wn(lpString, uCount), uCount, dwFlags,
373  lpOutString, lpOrder);
374 
375  memset(&Control, 0, sizeof(Control));
376  memset(&State, 0, sizeof(State));
377  if (lpGlyphs)
378  *lpGlyphs = NULL;
379 
380  if (!(dwFlags & GCP_REORDER))
381  {
382  FIXME("Asked to reorder without reorder flag set\n");
383  return FALSE;
384  }
385 
386  if (lpOutString && uCountOut < uCount)
387  {
388  FIXME("lpOutString too small\n");
389  return FALSE;
390  }
391 
392  chartype = HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD));
393  if (!chartype)
394  {
395  WARN("Out of memory\n");
396  return FALSE;
397  }
398 
399  if (lpOutString)
400  memcpy(lpOutString, lpString, uCount * sizeof(WCHAR));
401 
402  is_complex = FALSE;
403  for (i = 0; i < uCount && !is_complex; i++)
404  {
405  if ((lpString[i] >= 0x900 && lpString[i] <= 0xfff) ||
406  (lpString[i] >= 0x1cd0 && lpString[i] <= 0x1cff) ||
407  (lpString[i] >= 0xa840 && lpString[i] <= 0xa8ff))
408  is_complex = TRUE;
409  }
410 
411  /* Verify reordering will be required */
412  if ((WINE_GCPW_FORCE_RTL == (dwWineGCP_Flags&WINE_GCPW_DIR_MASK)) ||
413  ((dwWineGCP_Flags&WINE_GCPW_DIR_MASK) == WINE_GCPW_LOOSE_RTL))
414  State.uBidiLevel = 1;
415  else if (!is_complex)
416  {
417  done = 1;
418  classify(lpString, chartype, uCount);
419  for (i = 0; i < uCount; i++)
420  switch (chartype[i])
421  {
422  case R:
423  case AL:
424  case RLE:
425  case RLO:
426  done = 0;
427  break;
428  }
429  if (done)
430  {
431  HeapFree(GetProcessHeap(), 0, chartype);
432  if (lpOrder)
433  {
434  for (i = 0; i < uCount; i++)
435  lpOrder[i] = i;
436  }
437  return TRUE;
438  }
439  }
440 
441  levels = HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(BYTE));
442  if (!levels)
443  {
444  WARN("Out of memory\n");
445  HeapFree(GetProcessHeap(), 0, chartype);
446  return FALSE;
447  }
448 
449  maxItems = 5;
450  pItems = HeapAlloc(GetProcessHeap(),0, maxItems * sizeof(SCRIPT_ITEM));
451  if (!pItems)
452  {
453  WARN("Out of memory\n");
454  HeapFree(GetProcessHeap(), 0, chartype);
456  return FALSE;
457  }
458 
459  if (lpGlyphs)
460  {
461 #ifdef __REACTOS__
462  /* ReactOS r57677 and r57679 */
463  cMaxGlyphs = 3 * uCount / 2 + 16;
464 #else
465  cMaxGlyphs = 1.5 * uCount + 16;
466 #endif
467  run_glyphs = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * cMaxGlyphs);
468  if (!run_glyphs)
469  {
470  WARN("Out of memory\n");
471  HeapFree(GetProcessHeap(), 0, chartype);
474  return FALSE;
475  }
476  pwLogClust = HeapAlloc(GetProcessHeap(),0,sizeof(WORD) * uCount);
477  if (!pwLogClust)
478  {
479  WARN("Out of memory\n");
480  HeapFree(GetProcessHeap(), 0, chartype);
483  HeapFree(GetProcessHeap(), 0, run_glyphs);
484  return FALSE;
485  }
486  psva = HeapAlloc(GetProcessHeap(),0,sizeof(SCRIPT_VISATTR) * uCount);
487  if (!psva)
488  {
489  WARN("Out of memory\n");
490  HeapFree(GetProcessHeap(), 0, chartype);
493  HeapFree(GetProcessHeap(), 0, run_glyphs);
495  return FALSE;
496  }
497  }
498 
499  done = 0;
500  glyph_i = 0;
501  while (done < uCount)
502  {
503  INT j;
504  classify(lpString + done, chartype, uCount - done);
505  /* limit text to first block */
506  i = resolveParagraphs(chartype, uCount - done);
507  for (j = 0; j < i; ++j)
508  switch(chartype[j])
509  {
510  case B:
511  case S:
512  case WS:
513  case ON: chartype[j] = N;
514  default: continue;
515  }
516 
517  if ((dwWineGCP_Flags&WINE_GCPW_DIR_MASK) == WINE_GCPW_LOOSE_RTL)
518  State.uBidiLevel = 1;
519  else if ((dwWineGCP_Flags&WINE_GCPW_DIR_MASK) == WINE_GCPW_LOOSE_LTR)
520  State.uBidiLevel = 0;
521 
522  if (dwWineGCP_Flags & WINE_GCPW_LOOSE_MASK)
523  {
524  for (j = 0; j < i; ++j)
525  if (chartype[j] == L)
526  {
527  State.uBidiLevel = 0;
528  break;
529  }
530  else if (chartype[j] == R || chartype[j] == AL)
531  {
532  State.uBidiLevel = 1;
533  break;
534  }
535  }
536 
537  res = ScriptItemize(lpString + done, i, maxItems, &Control, &State, pItems, &nItems);
538  while (res == E_OUTOFMEMORY)
539  {
540  maxItems = maxItems * 2;
541  pItems = HeapReAlloc(GetProcessHeap(), 0, pItems, sizeof(SCRIPT_ITEM) * maxItems);
542  if (!pItems)
543  {
544  WARN("Out of memory\n");
545  HeapFree(GetProcessHeap(), 0, chartype);
547  HeapFree(GetProcessHeap(), 0, run_glyphs);
549  HeapFree(GetProcessHeap(), 0, psva);
550  return FALSE;
551  }
552  res = ScriptItemize(lpString + done, i, maxItems, &Control, &State, pItems, &nItems);
553  }
554 
555  if (lpOutString || lpOrder)
556  for (j = 0; j < nItems; j++)
557  {
558  int k;
559  for (k = pItems[j].iCharPos; k < pItems[j+1].iCharPos; k++)
560  levels[k] = pItems[j].a.s.uBidiLevel;
561  }
562 
563  if (lpOutString)
564  {
565  /* assign directional types again, but for WS, S this time */
566  classify(lpString + done, chartype, i);
567 
568  BidiLines(State.uBidiLevel, lpOutString + done, lpString + done,
569  chartype, levels, i, 0);
570  }
571 
572  if (lpOrder)
573  {
574  int k, lastgood;
575  for (j = lastgood = 0; j < i; ++j)
576  if (levels[j] != levels[lastgood])
577  {
578  --j;
579  if (odd(levels[lastgood]))
580  for (k = j; k >= lastgood; --k)
581  lpOrder[done + k] = done + j - k;
582  else
583  for (k = lastgood; k <= j; ++k)
584  lpOrder[done + k] = done + k;
585  lastgood = ++j;
586  }
587  if (odd(levels[lastgood]))
588  for (k = j - 1; k >= lastgood; --k)
589  lpOrder[done + k] = done + j - 1 - k;
590  else
591  for (k = lastgood; k < j; ++k)
592  lpOrder[done + k] = done + k;
593  }
594 
595  if (lpGlyphs && doGlyphs)
596  {
597  BYTE *runOrder;
598  int *visOrder;
599  SCRIPT_ITEM *curItem;
600 
601  runOrder = HeapAlloc(GetProcessHeap(), 0, maxItems * sizeof(*runOrder));
602  visOrder = HeapAlloc(GetProcessHeap(), 0, maxItems * sizeof(*visOrder));
603  if (!runOrder || !visOrder)
604  {
605  WARN("Out of memory\n");
606  HeapFree(GetProcessHeap(), 0, runOrder);
607  HeapFree(GetProcessHeap(), 0, visOrder);
608  HeapFree(GetProcessHeap(), 0, chartype);
611  HeapFree(GetProcessHeap(), 0, psva);
613  return FALSE;
614  }
615 
616  for (j = 0; j < nItems; j++)
617  runOrder[j] = pItems[j].a.s.uBidiLevel;
618 
619  ScriptLayout(nItems, runOrder, visOrder, NULL);
620 
621  for (j = 0; j < nItems; j++)
622  {
623  int k;
624  int cChars,cOutGlyphs;
625  curItem = &pItems[visOrder[j]];
626 
627  cChars = pItems[visOrder[j]+1].iCharPos - curItem->iCharPos;
628 
629  res = ScriptShape(hDC, &psc, lpString + done + curItem->iCharPos, cChars, cMaxGlyphs, &curItem->a, run_glyphs, pwLogClust, psva, &cOutGlyphs);
630  while (res == E_OUTOFMEMORY)
631  {
632  cMaxGlyphs *= 2;
633  run_glyphs = HeapReAlloc(GetProcessHeap(), 0, run_glyphs, sizeof(WORD) * cMaxGlyphs);
634  if (!run_glyphs)
635  {
636  WARN("Out of memory\n");
637  HeapFree(GetProcessHeap(), 0, runOrder);
638  HeapFree(GetProcessHeap(), 0, visOrder);
639  HeapFree(GetProcessHeap(), 0, chartype);
642  HeapFree(GetProcessHeap(), 0, psva);
644  HeapFree(GetProcessHeap(), 0, *lpGlyphs);
646  *lpGlyphs = NULL;
647  return FALSE;
648  }
649  res = ScriptShape(hDC, &psc, lpString + done + curItem->iCharPos, cChars, cMaxGlyphs, &curItem->a, run_glyphs, pwLogClust, psva, &cOutGlyphs);
650  }
651  if (res)
652  {
654  TRACE("Unable to shape with currently selected font\n");
655  else
656  FIXME("Unable to shape string (%x)\n",res);
657  j = nItems;
658  doGlyphs = FALSE;
659  HeapFree(GetProcessHeap(), 0, *lpGlyphs);
660  *lpGlyphs = NULL;
661  }
662  else
663  {
664  if (*lpGlyphs)
665  *lpGlyphs = HeapReAlloc(GetProcessHeap(), 0, *lpGlyphs, sizeof(WORD) * (glyph_i + cOutGlyphs));
666  else
667  *lpGlyphs = HeapAlloc(GetProcessHeap(), 0, sizeof(WORD) * (glyph_i + cOutGlyphs));
668  for (k = 0; k < cOutGlyphs; k++)
669  (*lpGlyphs)[glyph_i+k] = run_glyphs[k];
670  glyph_i += cOutGlyphs;
671  }
672  }
673  HeapFree(GetProcessHeap(), 0, runOrder);
674  HeapFree(GetProcessHeap(), 0, visOrder);
675  }
676 
677  done += i;
678  }
679  if (cGlyphs)
680  *cGlyphs = glyph_i;
681 
682  HeapFree(GetProcessHeap(), 0, chartype);
685  HeapFree(GetProcessHeap(), 0, run_glyphs);
687  HeapFree(GetProcessHeap(), 0, psva);
689  return TRUE;
690 }
Definition: bidi.c:85
Definition: bidi.c:86
#define TRUE
Definition: types.h:120
#define USP_E_SCRIPT_NOT_IN_FONT
Definition: usp10.h:71
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int TEXTRANGE_PROPERTIES int const WCHAR int int WORD * pwLogClust
Definition: usp10.c:64
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
GLsizei levels
Definition: glext.h:7884
directions
Definition: bidi.c:66
#define cval
Definition: fillbytes.c:26
Definition: bidi.c:71
#define WINE_GCPW_DIR_MASK
Definition: ros_lpk.h:93
_In_ FONTOBJ _In_ ULONG _In_ ULONG cGlyphs
Definition: winddi.h:3799
#define WARN(fmt,...)
Definition: debug.h:111
static HDC
Definition: imagelist.c:92
int iCharPos
Definition: usp10.h:150
HRESULT WINAPI ScriptLayout(int runs, const BYTE *level, int *vistolog, int *logtovis)
Definition: usp10.c:3747
_In_ UINT iStart
Definition: wingdi.h:3598
#define WINE_GCPW_FORCE_RTL
Definition: ros_lpk.h:90
Definition: bidi.c:90
Definition: bidi.c:78
Definition: bidi.c:79
int32_t INT
Definition: typedefs.h:56
#define WINE_GCPW_LOOSE_MASK
Definition: ros_lpk.h:94
SCRIPT_ANALYSIS a
Definition: usp10.h:151
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
Definition: bidi.c:77
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned int BOOL
Definition: ntddk_ex.h:94
Definition: bidi.c:97
#define FIXME(fmt,...)
Definition: debug.h:110
Definition: bidi.c:91
Definition: bidi.c:72
int nItems
Definition: appswitch.c:56
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:201
smooth NULL
Definition: ftsmooth.c:416
Definition: bidi.c:94
static int resolveLines(LPCWSTR pszInput, const BOOL *pbrk, int cch)
Definition: bidi.c:205
#define WINE_GCPW_LOOSE_LTR
Definition: ros_lpk.h:91
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
WINE_DEFAULT_DEBUG_CHANNEL(bidi)
static int int const SCRIPT_CONTROL const SCRIPT_STATE SCRIPT_ITEM * pItems
Definition: usp10.c:62
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int TEXTRANGE_PROPERTIES int const WCHAR int cChars
Definition: usp10.c:64
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
Definition: cmds.c:130
BOOL BIDI_Reorder(HDC hDC, LPCWSTR lpString, INT uCount, DWORD dwFlags, DWORD dwWineGCP_Flags, LPWSTR lpOutString, INT uCountOut, UINT *lpOrder, WORD **lpGlyphs, INT *cGlyphs)
Definition: bidi.c:339
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
static SCRIPT_CACHE SCRIPT_ANALYSIS OPENTYPE_TAG OPENTYPE_TAG int TEXTRANGE_PROPERTIES int const WCHAR int int cMaxGlyphs
Definition: usp10.c:64
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WINE_GCPW_LOOSE_RTL
Definition: ros_lpk.h:92
WINE_UNICODE_INLINE unsigned short get_char_typeW(WCHAR ch)
Definition: unicode.h:149
Definition: bidi.c:87
HRESULT WINAPI ScriptItemize(const WCHAR *pwcInChars, int cInChars, int cMaxItems, const SCRIPT_CONTROL *psControl, const SCRIPT_STATE *psState, SCRIPT_ITEM *pItems, int *pcItems)
Definition: usp10.c:1851
Definition: bidi.c:70
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
Definition: bidi.c:73
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: mem.h:68
#define debugstr_wn
Definition: kernel32.h:33
static const WCHAR Control[]
Definition: interface.c:27
static HDC hDC
Definition: 3dtext.c:33
enum State_ State
Definition: pofuncs.h:54
static SCRIPT_CACHE * psc
Definition: usp10.c:64
#define HeapReAlloc
Definition: compat.h:393
static void BidiLines(int baselevel, LPWSTR pszOutLine, LPCWSTR pszLine, const WORD *pclsLine, BYTE *plevelLine, int cchPara, const BOOL *pbrk)
Definition: bidi.c:291
HRESULT WINAPI ScriptShape(HDC hdc, SCRIPT_CACHE *psc, const WCHAR *pwcChars, int cChars, int cMaxGlyphs, SCRIPT_ANALYSIS *psa, WORD *pwOutGlyphs, WORD *pwLogClust, SCRIPT_VISATTR *psva, int *pcGlyphs)
Definition: usp10.c:3319
unsigned int UINT
Definition: ndis.h:50
Definition: bidi.c:76
Definition: bidi.c:92
#define GCP_REORDER
Definition: wingdi.h:842
GLuint res
Definition: glext.h:9613
HRESULT WINAPI ScriptFreeCache(SCRIPT_CACHE *psc)
Definition: usp10.c:1078
Definition: bidi.c:74
Definition: bidi.c:82
static void classify(LPCWSTR lpString, WORD *chartype, DWORD uCount)
Definition: bidi.c:103
static int resolveParagraphs(WORD *types, int cch)
Definition: bidi.c:177
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
static void resolveWhitespace(int baselevel, const WORD *pcls, BYTE *plevel, int cch)
Definition: bidi.c:238
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define memset(x, y, z)
Definition: compat.h:39
Definition: bidi.c:75
#define odd(x)
Definition: bidi.c:53
int k
Definition: mpi.c:3369
Definition: bidi.c:93
#define HeapFree(x, y, z)
Definition: compat.h:394
static void SetDeferredRun(BYTE *pval, int cval, int iStart, int nval)
Definition: bidi.c:146