* has been modified.
*/
-#include <windef.h>
-
-#include <wine/list.h>
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winnls.h"
+#include "usp10.h"
+#include "wine/unicode.h"
+#include "wine/debug.h"
+#include "wine/heap.h"
+#include "wine/list.h"
#include "usp10_internal.h"
-extern const unsigned short bidi_bracket_table[];
+extern const unsigned short bidi_bracket_table[] DECLSPEC_HIDDEN;
WINE_DEFAULT_DEBUG_CHANNEL(bidi);
}
/* Convert the libwine information to the direction enum */
-static void classify(LPCWSTR lpString, WORD *chartype, DWORD uCount, const SCRIPT_CONTROL *c)
+static void classify(const WCHAR *string, WORD *chartype, DWORD count, const SCRIPT_CONTROL *c)
{
static const enum directions dir_map[16] =
{
unsigned i;
- for (i = 0; i < uCount; ++i)
+ for (i = 0; i < count; ++i)
{
- chartype[i] = dir_map[get_char_typeW(lpString[i]) >> 12];
+ chartype[i] = dir_map[get_char_typeW(string[i]) >> 12];
switch (chartype[i])
{
case ES:
if (!c->fLegacyBidiClass) break;
- switch (lpString[i])
+ switch (string[i])
{
case '-':
case '+': chartype[i] = NI; break;
}
break;
case PDF:
- switch (lpString[i])
+ switch (string[i])
{
case 0x202A: chartype[i] = LRE; break;
case 0x202B: chartype[i] = RLE; break;
#define valid_level(x) (x <= MAX_DEPTH && overflow_isolate_count == 0 && overflow_embedding_count == 0)
-static void resolveExplicit(int level, WORD *pclass, WORD *poutLevel, int count)
+static void resolveExplicit(int level, WORD *pclass, WORD *poutLevel, WORD *poutOverrides, int count, BOOL initialOverride)
{
/* X1 */
int overflow_isolate_count = 0;
stack[stack_top].override = NI;
stack[stack_top].isolate = FALSE;
+ if (initialOverride)
+ {
+ if (odd(level))
+ push_stack(level, R, FALSE);
+ else
+ push_stack(level, L, FALSE);
+ }
+
for (i = 0; i < count; i++)
{
+ poutOverrides[i] = stack[stack_top].override;
+
/* X2 */
if (pclass[i] == RLE)
{
return index;
}
-static inline int iso_previousChar(IsolatedRun *iso_run, int index)
-{
- if (index <= 0) return -1;
- return index --;
-}
-
static inline void iso_dump_types(const char* header, IsolatedRun *iso_run)
{
int i, len = 0;
WCHAR *open_stack;
int *stack_index;
int stack_top = iso_run->length;
+ unsigned int pair_count = 0;
BracketPair *out = NULL;
- int pair_count = 0;
+ SIZE_T out_size = 0;
int i;
- open_stack = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * iso_run->length);
- stack_index = HeapAlloc(GetProcessHeap(), 0, sizeof(int) * iso_run->length);
+ open_stack = heap_alloc(iso_run->length * sizeof(*open_stack));
+ stack_index = heap_alloc(iso_run->length * sizeof(*stack_index));
for (i = 0; i < iso_run->length; i++)
{
unsigned short ubv = get_table_entry(bidi_bracket_table, iso_run->item[i].ch);
- if (ubv)
+
+ if (!ubv)
+ continue;
+
+ if ((ubv >> 8) == 0)
{
- if (!out)
- {
- out = HeapAlloc(GetProcessHeap(),0,sizeof(BracketPair));
- out[0].start = -1;
- }
+ --stack_top;
+ open_stack[stack_top] = iso_run->item[i].ch + (signed char)(ubv & 0xff);
+ /* Deal with canonical equivalent U+2329/232A and U+3008/3009. */
+ if (open_stack[stack_top] == 0x232a)
+ open_stack[stack_top] = 0x3009;
+ stack_index[stack_top] = i;
+ }
+ else if ((ubv >> 8) == 1)
+ {
+ unsigned int j;
- if ((ubv >> 8) == 0)
+ for (j = stack_top; j < iso_run->length; ++j)
{
- stack_top --;
- open_stack[stack_top] = iso_run->item[i].ch + (signed char)(ubv & 0xff);
- /* deal with canonical equivalent U+2329/232A and U+3008/3009 */
- if (open_stack[stack_top] == 0x232A)
- open_stack[stack_top] = 0x3009;
- stack_index[stack_top] = i;
- }
- else if ((ubv >> 8) == 1)
- {
- int j;
- if (stack_top == iso_run->length) continue;
- for (j = stack_top; j < iso_run->length; j++)
- {
- WCHAR c = iso_run->item[i].ch;
- if (c == 0x232A) c = 0x3009;
- if (c == open_stack[j])
- {
- out[pair_count].start = stack_index[j];
- out[pair_count].end = i;
- pair_count++;
- out = HeapReAlloc(GetProcessHeap(), 0, out, sizeof(BracketPair) * (pair_count+1));
- out[pair_count].start = -1;
- stack_top = j+1;
- break;
- }
- }
+ WCHAR c = iso_run->item[i].ch;
+
+ if (c == 0x232a)
+ c = 0x3009;
+
+ if (c != open_stack[j])
+ continue;
+
+ if (!(usp10_array_reserve((void **)&out, &out_size, pair_count + 2, sizeof(*out))))
+ ERR("Failed to grow output array.\n");
+
+ out[pair_count].start = stack_index[j];
+ out[pair_count].end = i;
+ ++pair_count;
+
+ out[pair_count].start = -1;
+ stack_top = j + 1;
+ break;
}
}
}
- if (pair_count == 0)
- {
- HeapFree(GetProcessHeap(),0,out);
- out = NULL;
- }
- else if (pair_count > 1)
- qsort(out, pair_count, sizeof(BracketPair), compr);
- HeapFree(GetProcessHeap(), 0, open_stack);
- HeapFree(GetProcessHeap(), 0, stack_index);
+ heap_free(open_stack);
+ heap_free(stack_index);
+
+ if (!pair_count)
+ return NULL;
+
+ qsort(out, pair_count, sizeof(*out), compr);
+
return out;
}
i++;
p = &pairs[i];
}
- HeapFree(GetProcessHeap(),0,pairs);
+ heap_free(pairs);
}
/* N1 */
plevel[j--] = baselevel;
plevel[i] = baselevel;
}
+ else if (pcls[i] == LRE || pcls[i] == RLE || pcls[i] == LRO || pcls[i] == RLO ||
+ pcls[i] == PDF || pcls[i] == BN)
+ {
+ plevel[i] = i ? plevel[i - 1] : baselevel;
+ }
if (i == eos &&
(pcls[i] == WS || pcls[i] == FSI || pcls[i] == LRI || pcls[i] == RLI ||
pcls[i] == PDI || pcls[i] == LRE || pcls[i] == RLE || pcls[i] == LRO ||
}
}
-static void computeIsolatingRunsSet(unsigned baselevel, WORD *pcls, WORD *pLevel, LPCWSTR lpString, int uCount, struct list *set)
+static void computeIsolatingRunsSet(unsigned baselevel, WORD *pcls, const WORD *pLevel,
+ const WCHAR *string, unsigned int uCount, struct list *set)
{
int run_start, run_end, i;
int run_count = 0;
Run *runs;
IsolatedRun *current_isolated;
- runs = HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(Run));
- if (!runs) return;
+ if (!(runs = heap_alloc(uCount * sizeof(*runs))))
+ return;
list_init(set);
{
int type_fence, real_end;
int j;
- current_isolated = HeapAlloc(GetProcessHeap(), 0, sizeof(IsolatedRun) + sizeof(RunChar)*uCount);
- if (!current_isolated) break;
+
+ if (!(current_isolated = heap_alloc(FIELD_OFFSET(IsolatedRun, item[uCount]))))
+ break;
run_start = runs[k].start;
current_isolated->e = runs[k].e;
for (j = 0; j < current_isolated->length; j++)
{
current_isolated->item[j].pcls = &pcls[runs[k].start+j];
- current_isolated->item[j].ch = lpString[runs[k].start+j];
+ current_isolated->item[j].ch = string[runs[k].start + j];
}
run_end = runs[k].end;
for (m = 0; l < current_isolated->length; l++, m++)
{
current_isolated->item[l].pcls = &pcls[runs[j].start+m];
- current_isolated->item[l].ch = lpString[runs[j].start+m];
+ current_isolated->item[l].ch = string[runs[j].start + m];
}
TRACE("[%i -- %i]",runs[j].start, runs[j].end);
i++;
}
- HeapFree(GetProcessHeap(), 0, runs);
+ heap_free(runs);
}
/*************************************************************
* BIDI_DeterminLevels
*/
BOOL BIDI_DetermineLevels(
- LPCWSTR lpString, /* [in] The string for which information is to be returned */
- INT uCount, /* [in] Number of WCHARs in string. */
+ const WCHAR *lpString, /* [in] The string for which information is to be returned */
+ unsigned int uCount, /* [in] Number of WCHARs in string. */
const SCRIPT_STATE *s,
const SCRIPT_CONTROL *c,
- WORD *lpOutLevels /* [out] final string levels */
+ WORD *lpOutLevels, /* [out] final string levels */
+ WORD *lpOutOverrides /* [out] final string overrides */
)
{
WORD *chartype;
TRACE("%s, %d\n", debugstr_wn(lpString, uCount), uCount);
- chartype = HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WORD));
- if (!chartype)
+ if (!(chartype = heap_alloc(uCount * sizeof(*chartype))))
{
WARN("Out of memory\n");
return FALSE;
classify(lpString, chartype, uCount, c);
if (TRACE_ON(bidi)) dump_types("Start ", chartype, 0, uCount);
+ memset(lpOutOverrides, 0, sizeof(WORD) * uCount);
+
/* resolve explicit */
- resolveExplicit(baselevel, chartype, lpOutLevels, uCount);
+ resolveExplicit(baselevel, chartype, lpOutLevels, lpOutOverrides, uCount, s->fOverrideDirection);
if (TRACE_ON(bidi)) dump_types("After Explicit", chartype, 0, uCount);
/* X10/BD13: Computer Isolating runs */
if (TRACE_ON(bidi)) iso_dump_types("After Neutrals", iso_run);
list_remove(&iso_run->entry);
- HeapFree(GetProcessHeap(),0,iso_run);
+ heap_free(iso_run);
}
if (TRACE_ON(bidi)) dump_types("Before Implicit", chartype, 0, uCount);
classify(lpString, chartype, uCount, c);
resolveResolved(baselevel, chartype, lpOutLevels, 0, uCount-1);
- HeapFree(GetProcessHeap(), 0, chartype);
+ heap_free(chartype);
return TRUE;
}
return ich;
}
-BOOL BIDI_GetStrengths(LPCWSTR lpString, INT uCount, const SCRIPT_CONTROL *c,
- WORD* lpStrength)
+BOOL BIDI_GetStrengths(const WCHAR *string, unsigned int count, const SCRIPT_CONTROL *c, WORD *strength)
{
- int i;
- classify(lpString, lpStrength, uCount, c);
+ unsigned int i;
- for ( i = 0; i < uCount; i++)
+ classify(string, strength, count, c);
+ for (i = 0; i < count; i++)
{
- switch(lpStrength[i])
+ switch (strength[i])
{
case L:
case LRE:
case AL:
case RLE:
case RLO:
- lpStrength[i] = BIDI_STRONG;
+ strength[i] = BIDI_STRONG;
break;
case PDF:
case EN:
case AN:
case CS:
case BN:
- lpStrength[i] = BIDI_WEAK;
+ strength[i] = BIDI_WEAK;
break;
case B:
case S:
case WS:
case ON:
default: /* Neutrals and NSM */
- lpStrength[i] = BIDI_NEUTRAL;
+ strength[i] = BIDI_NEUTRAL;
}
}
return TRUE;