[USP10] Sync with Wine Staging 1.9.4. CORE-10912

svn path=/trunk/; revision=70939
This commit is contained in:
Amine Khaldi 2016-03-05 10:30:03 +00:00
parent bf460ff671
commit 5182944828
6 changed files with 537 additions and 249 deletions

View file

@ -258,7 +258,7 @@ typedef struct tagStackItem {
#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;
@ -273,8 +273,18 @@ static void resolveExplicit(int level, WORD *pclass, WORD *poutLevel, int count)
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)
{
@ -1106,7 +1116,8 @@ BOOL BIDI_DetermineLevels(
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;
@ -1128,8 +1139,10 @@ BOOL BIDI_DetermineLevels(
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 */

View file

@ -3,7 +3,7 @@
/* and from http://www.unicode.org/Public/8.0.0/ucd/IndicPositionalCategory.txt */
/* DO NOT EDIT!! */
const unsigned short indic_syllabic_table[3088] =
const unsigned short indic_syllabic_table[3264] =
{
/* level 1 offsets */
0x0100, 0x0110, 0x0110, 0x0110, 0x0110, 0x0110, 0x0110, 0x0110,
@ -62,25 +62,25 @@ const unsigned short indic_syllabic_table[3088] =
0x0810, 0x0820, 0x0830, 0x0820, 0x0830, 0x0840, 0x0810, 0x0850,
0x02e0, 0x02e0, 0x0860, 0x0870, 0x0880, 0x0890, 0x0280, 0x0260,
0x08a0, 0x0650, 0x08b0, 0x08c0, 0x03f0, 0x02e0, 0x08d0, 0x08e0,
0x0260, 0x0260, 0x0260, 0x08f0, 0x0900, 0x0260, 0x0260, 0x0260,
0x0260, 0x0910, 0x0260, 0x0260, 0x0260, 0x0920, 0x0930, 0x0940,
0x02e0, 0x02e0, 0x08f0, 0x0900, 0x0910, 0x0280, 0x0260, 0x0260,
0x02e0, 0x0920, 0x02e0, 0x02e0, 0x0930, 0x0940, 0x0950, 0x0960,
0x0280, 0x0280, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260,
0x0970, 0x0830, 0x02e0, 0x0980, 0x0990, 0x0280, 0x09a0, 0x09b0,
0x09c0, 0x02e0, 0x09d0, 0x09e0, 0x02e0, 0x02e0, 0x09f0, 0x0a00,
0x02e0, 0x02e0, 0x0a10, 0x0a20, 0x0a30, 0x0260, 0x0260, 0x0260,
0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0a40, 0x0a50, 0x0a60,
0x0a70, 0x0a80, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0a90,
0x0aa0, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260,
0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260,
0x0950, 0x0260, 0x0260, 0x0960, 0x0970, 0x0260, 0x0980, 0x0990,
0x09a0, 0x0260, 0x09b0, 0x09c0, 0x0260, 0x0260, 0x09d0, 0x09e0,
0x0260, 0x0260, 0x09f0, 0x0a00, 0x0260, 0x0260, 0x0260, 0x0260,
0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0a10, 0x0a20, 0x0a30,
0x0a40, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0a50,
0x0260, 0x0260, 0x0260, 0x0260, 0x0ab0, 0x0260, 0x0260, 0x0260,
0x0ac0, 0x02e0, 0x0ad0, 0x0260, 0x02e0, 0x0ae0, 0x0af0, 0x0b00,
0x0b10, 0x0b20, 0x02e0, 0x0b30, 0x0b40, 0x0280, 0x0b50, 0x0b60,
0x0b70, 0x02e0, 0x0b80, 0x02e0, 0x0b90, 0x0ba0, 0x0260, 0x0260,
0x0bb0, 0x02e0, 0x02e0, 0x0bc0, 0x0bd0, 0x0280, 0x0be0, 0x0bf0,
0x0c00, 0x02e0, 0x0c10, 0x0c20, 0x0c30, 0x0280, 0x02e0, 0x0c40,
0x02e0, 0x02e0, 0x02e0, 0x0c50, 0x0c60, 0x0260, 0x0c70, 0x0c80,
0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260,
0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260,
0x0260, 0x0260, 0x0260, 0x0260, 0x0a60, 0x0260, 0x0260, 0x0260,
0x0a70, 0x0260, 0x0a80, 0x0260, 0x0260, 0x0260, 0x0a90, 0x0aa0,
0x0ab0, 0x0260, 0x0260, 0x0ac0, 0x0ad0, 0x0260, 0x0ae0, 0x0af0,
0x0260, 0x0260, 0x0b00, 0x0260, 0x0b10, 0x0b20, 0x0260, 0x0260,
0x0b30, 0x0260, 0x0260, 0x0b40, 0x0b50, 0x0260, 0x0b60, 0x0260,
0x0260, 0x0260, 0x0b70, 0x0b80, 0x0b90, 0x0260, 0x0260, 0x0ba0,
0x0260, 0x0260, 0x0260, 0x0bb0, 0x0bc0, 0x0260, 0x0bd0, 0x0be0,
0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0260,
0x0260, 0x0260, 0x0260, 0x0260, 0x0260, 0x0bf0, 0x0c00, 0x0260,
0x0260, 0x0260, 0x0260, 0x0260, 0x0c90, 0x0ca0, 0x0cb0, 0x0280,
/* values */
0x5f00, 0x9c00, 0x9500, 0x9500, 0x8600, 0x8600, 0x8600, 0x8600,
0x7e00, 0x6e00, 0x5d00, 0x5100, 0x4200, 0x2d00, 0x1700, 0x0a00,
@ -294,104 +294,126 @@ const unsigned short indic_syllabic_table[3088] =
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0000, 0x0000,
0x0012, 0x0012, 0x0012, 0x0012, 0x0012, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0300, 0x0300, 0x0300,
0x0100, 0x0100, 0x0000, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0100, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0500,
0x0600, 0x0200, 0x0100, 0x0507, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x020e, 0x060e, 0x010f,
0x0500, 0x0500, 0x0500, 0x0600, 0x0600, 0x0600, 0x0600, 0x0000,
0x0017, 0x0107, 0x0507, 0x0100, 0x0100, 0x0500, 0x0500, 0x0500,
0x0500, 0x0600, 0x0600, 0x0500, 0x0600, 0x0100, 0x0200, 0x0200,
0x0200, 0x0200, 0x0200, 0x0500, 0x0500, 0x0500, 0x0500, 0x0500,
0x0500, 0x0500, 0x0500, 0x0500, 0x0500, 0x0000, 0x0000, 0x0621,
0x0500, 0x0500, 0x0500, 0x050c, 0x0102, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0504, 0x0107, 0x0500, 0x0500,
0x0600, 0x0600, 0x0600, 0x0007, 0x0007, 0x0000, 0x0200, 0x0200,
0x0400, 0x0400, 0x0507, 0x0007, 0x0105, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
0x000a, 0x000a, 0x000a, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000,
0x0107, 0x0107, 0x0107, 0x0107, 0x0107, 0x0307, 0x0307, 0x0307,
0x0107, 0x0107, 0x0007, 0x0107, 0x0107, 0x0107, 0x0107, 0x0107,
0x0107, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f,
0x0113, 0x0113, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0507,
0x0607, 0x0207, 0x0107, 0x0507, 0x0000, 0x0000, 0x0000, 0x0000,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0006, 0x0006, 0x0006,
0x0006, 0x0006, 0x0006, 0x000a, 0x000a, 0x020e, 0x060e, 0x010f,
0x050f, 0x050f, 0x050f, 0x060f, 0x060f, 0x060f, 0x060f, 0x0000,
0x0017, 0x0107, 0x0507, 0x0107, 0x0107, 0x0507, 0x0507, 0x0507,
0x0507, 0x0607, 0x0607, 0x0507, 0x0607, 0x0107, 0x0207, 0x0207,
0x0207, 0x0207, 0x0207, 0x0507, 0x0507, 0x0513, 0x0513, 0x0513,
0x0513, 0x0513, 0x0521, 0x0521, 0x0521, 0x0000, 0x0000, 0x0621,
0x0501, 0x0501, 0x0501, 0x050c, 0x0102, 0x0006, 0x0006, 0x0006,
0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006,
0x000a, 0x000a, 0x000a, 0x000a, 0x0504, 0x0107, 0x0507, 0x0507,
0x0607, 0x0607, 0x0607, 0x0007, 0x0007, 0x0007, 0x0207, 0x0207,
0x0407, 0x0407, 0x0507, 0x0007, 0x0105, 0x000a, 0x000a, 0x000a,
0x000a, 0x000a, 0x000a, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0500, 0x0600, 0x0500, 0x0500, 0x0500,
0x0500, 0x0500, 0x0500, 0x0500, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0501, 0x050c, 0x0102, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0501, 0x050c, 0x0102, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006,
0x0006, 0x0006, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
0x000a, 0x010d, 0x060d, 0x060d, 0x0507, 0x0607, 0x0207, 0x0107,
0x0507, 0x0507, 0x0116, 0x0017, 0x060d, 0x060d, 0x000a, 0x000a,
0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d,
0x001d, 0x001d, 0x0003, 0x000a, 0x000a, 0x000a, 0x000f, 0x000f,
0x000a, 0x000a, 0x000a, 0x000a, 0x0006, 0x0006, 0x0504, 0x0107,
0x0507, 0x0507, 0x0107, 0x0107, 0x0107, 0x0507, 0x0107, 0x0507,
0x050f, 0x050f, 0x0116, 0x0116, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x010d, 0x0600, 0x0600, 0x0500, 0x0600, 0x0200, 0x0100,
0x0500, 0x0500, 0x0116, 0x0017, 0x0600, 0x0600, 0x0000, 0x0000,
0x000a, 0x000a, 0x000a, 0x000a, 0x010d, 0x010d, 0x0107, 0x0207,
0x0207, 0x0007, 0x0107, 0x0107, 0x0607, 0x050f, 0x050f, 0x050f,
0x050f, 0x050f, 0x050f, 0x050f, 0x0201, 0x0201, 0x0521, 0x0604,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0003, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0504, 0x0107,
0x0500, 0x0500, 0x0100, 0x0100, 0x0100, 0x0507, 0x0107, 0x0507,
0x0500, 0x0500, 0x0100, 0x0100, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0100, 0x0100, 0x0100, 0x0200,
0x0200, 0x0000, 0x0100, 0x0100, 0x0607, 0x0500, 0x0500, 0x0500,
0x0500, 0x0500, 0x0500, 0x0500, 0x0200, 0x0200, 0x0521, 0x0604,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0500, 0x0500, 0x0500, 0x0000, 0x0d00, 0x0600, 0x0600, 0x0600,
0x0600, 0x0600, 0x0500, 0x0500, 0x0600, 0x0600, 0x0600, 0x0600,
0x0500, 0x0119, 0x0d00, 0x0d00, 0x0d00, 0x0d00, 0x0d00, 0x0d00,
0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d,
0x001d, 0x001d, 0x0000, 0x0000, 0x0000, 0x000a, 0x000a, 0x000a,
0x0519, 0x0519, 0x0519, 0x0000, 0x0d19, 0x0619, 0x0619, 0x0619,
0x0619, 0x0619, 0x0519, 0x0519, 0x0619, 0x0619, 0x0619, 0x0619,
0x0519, 0x0119, 0x0d00, 0x0d00, 0x0d00, 0x0d00, 0x0d00, 0x0d00,
0x0d00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0600, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0519, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0002, 0x0002, 0x0519, 0x0000, 0x0000, 0x0000,
0x0019, 0x0019, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x001a, 0x001b, 0x0000, 0x0000,
0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0021, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0021, 0x0021, 0x0021, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0009, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0516, 0x0000,
0x0000, 0x0000, 0x0000, 0x0501, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0100, 0x0100, 0x0600, 0x0500, 0x0107,
0x0006, 0x0006, 0x0000, 0x0006, 0x0006, 0x0006, 0x0516, 0x000a,
0x000a, 0x000a, 0x000a, 0x0501, 0x000a, 0x000a, 0x000a, 0x000a,
0x000a, 0x000a, 0x000a, 0x0107, 0x0107, 0x0607, 0x0507, 0x0107,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0008, 0x0000,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0008, 0x0008,
0x0008, 0x0008, 0x000a, 0x000a, 0x000a, 0x000a, 0x0008, 0x000d,
0x000d, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
0x000a, 0x000d, 0x000a, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x000d, 0x000a, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000,
0x0101, 0x0102, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006,
0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006,
0x0006, 0x0006, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
0x000a, 0x000a, 0x000a, 0x000a, 0x010f, 0x0107, 0x0107, 0x0107,
0x0107, 0x0107, 0x0107, 0x0107, 0x0107, 0x0107, 0x0107, 0x0107,
0x0107, 0x0107, 0x0107, 0x0107, 0x0605, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0101, 0x0102, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0519, 0x0519, 0x0519, 0x0519, 0x0519, 0x0519, 0x0519, 0x0519,
0x0519, 0x0519, 0x0519, 0x0519, 0x0519, 0x0519, 0x0519, 0x0519,
0x0519, 0x0519, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x010f, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0605, 0x0000, 0x0000, 0x0000,
0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d,
0x001d, 0x001d, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
0x000a, 0x000a, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0613, 0x0613, 0x0613, 0x0000, 0x0000,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0607,
0x0607, 0x0607, 0x0507, 0x0607, 0x0607, 0x0607, 0x0607, 0x050f,
0x050f, 0x050f, 0x010f, 0x0116, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0500, 0x0500, 0x0500, 0x0500, 0x0500, 0x0500, 0x0500, 0x0500,
0x0500, 0x0500, 0x0500, 0x0500, 0x0500, 0x0500, 0x0500, 0x0500,
0x0500, 0x0500, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0600, 0x0600, 0x0600, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0600,
0x0600, 0x0600, 0x0500, 0x0600, 0x0600, 0x0600, 0x0600, 0x0500,
0x0500, 0x0500, 0x010f, 0x0116, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0500, 0x0500, 0x050c, 0x0102, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0504, 0x0100, 0x0100, 0x0500, 0x0500,
0x0600, 0x0600, 0x0200, 0x0200, 0x0507, 0x010d, 0x0100, 0x0100,
0x0501, 0x0501, 0x050c, 0x0102, 0x0006, 0x0006, 0x0006, 0x0006,
0x0006, 0x000a, 0x000a, 0x000a, 0x0006, 0x0006, 0x0006, 0x000a,
0x000a, 0x000a, 0x000a, 0x0504, 0x0107, 0x0107, 0x0507, 0x0507,
0x0607, 0x0607, 0x0207, 0x0207, 0x0507, 0x010d, 0x010e, 0x010e,
0x0005, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0507, 0x0000, 0x0000,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0507, 0x0000, 0x000a,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d, 0x001d,
0x001d, 0x001d, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0000,
0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x000a, 0x000a,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
0x000a, 0x0507, 0x0507, 0x0507, 0x0507, 0x0607, 0x0507, 0x0207,
0x0207, 0x0507, 0x0607, 0x010e, 0x020e, 0x060e, 0x060e, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0500, 0x0500, 0x0500, 0x0500, 0x0600, 0x0500, 0x0200,
0x0200, 0x0500, 0x0600, 0x0100, 0x0200, 0x0600, 0x0600, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x050f, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x050f, 0x010f, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x000a, 0x0113, 0x0513, 0x0113, 0x0000, 0x0000,
0x0507, 0x0107, 0x0500, 0x0500, 0x0600, 0x0300, 0x0300, 0x0500,
0x0500, 0x0000, 0x0100, 0x0300, 0x0300, 0x0100, 0x0507, 0x0513,
0x000f, 0x000f, 0x000f, 0x050f, 0x000f, 0x000f, 0x000f, 0x000f,
0x000f, 0x000f, 0x000f, 0x000f, 0x050f, 0x010f, 0x0000, 0x0000,
0x0000, 0x000a, 0x000a, 0x000a, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x000a, 0x0113, 0x0513, 0x0113, 0x000a, 0x000a,
0x0507, 0x0107, 0x0507, 0x0507, 0x0607, 0x0307, 0x0307, 0x0507,
0x0507, 0x0007, 0x0107, 0x0307, 0x0307, 0x0107, 0x0507, 0x0513,
0x0012, 0x0513, 0x0012, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0207, 0x0600, 0x0500, 0x0200, 0x0100,
0x0006, 0x0006, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
0x000a, 0x000a, 0x000a, 0x0207, 0x0607, 0x0507, 0x0207, 0x0107,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0102, 0x0017, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x000a, 0x0006, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0100, 0x0100, 0x0507, 0x0100, 0x0100,
0x0607, 0x0100, 0x0100, 0x0000, 0x0113, 0x0616, 0x0000, 0x0000
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0006, 0x0006,
0x000a, 0x0006, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x000a,
0x000a, 0x000a, 0x000a, 0x000f, 0x000f, 0x000f, 0x000f, 0x000f,
0x000f, 0x000f, 0x000f, 0x0107, 0x0107, 0x0507, 0x0107, 0x0107,
0x0607, 0x0107, 0x0107, 0x0000, 0x0113, 0x0616, 0x0000, 0x0000
};

View file

@ -267,6 +267,12 @@ typedef struct{
WORD Alternate[1];
} GSUB_AlternateSet;
typedef struct {
WORD SubstFormat;
WORD ExtensionLookupType;
DWORD ExtensionOffset;
} GSUB_ExtensionPosFormat1;
/* These are all structures needed for the GPOS table */
typedef struct {
@ -715,6 +721,25 @@ static INT GSUB_is_glyph_covered(LPCVOID table , UINT glyph)
return -1;
}
static const BYTE *GSUB_get_subtable(const OT_LookupTable *look, int index)
{
int offset = GET_BE_WORD(look->SubTable[index]);
if (GET_BE_WORD(look->LookupType) == 7)
{
const GSUB_ExtensionPosFormat1 *ext = (const GSUB_ExtensionPosFormat1 *)((const BYTE *)look + offset);
if (GET_BE_WORD(ext->SubstFormat) == 1)
{
offset += GET_BE_DWORD(ext->ExtensionOffset);
}
else
{
FIXME("Unhandled Extension Substitution Format %i\n",GET_BE_WORD(ext->SubstFormat));
}
}
return (const BYTE *)look + offset;
}
static INT GSUB_apply_SingleSubst(const OT_LookupTable *look, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
{
int j;
@ -722,10 +747,7 @@ static INT GSUB_apply_SingleSubst(const OT_LookupTable *look, WORD *glyphs, INT
for (j = 0; j < GET_BE_WORD(look->SubTableCount); j++)
{
int offset;
const GSUB_SingleSubstFormat1 *ssf1;
offset = GET_BE_WORD(look->SubTable[j]);
ssf1 = (const GSUB_SingleSubstFormat1*)((const BYTE*)look+offset);
const GSUB_SingleSubstFormat1 *ssf1 = (const GSUB_SingleSubstFormat1*)GSUB_get_subtable(look, j);
if (GET_BE_WORD(ssf1->SubstFormat) == 1)
{
int offset = GET_BE_WORD(ssf1->Coverage);
@ -773,8 +795,7 @@ static INT GSUB_apply_MultipleSubst(const OT_LookupTable *look, WORD *glyphs, IN
{
int offset, index;
const GSUB_MultipleSubstFormat1 *msf1;
offset = GET_BE_WORD(look->SubTable[j]);
msf1 = (const GSUB_MultipleSubstFormat1*)((const BYTE*)look+offset);
msf1 = (const GSUB_MultipleSubstFormat1*)GSUB_get_subtable(look, j);
offset = GET_BE_WORD(msf1->Coverage);
index = GSUB_is_glyph_covered((const BYTE*)msf1+offset, glyphs[glyph_index]);
@ -823,8 +844,7 @@ static INT GSUB_apply_AlternateSubst(const OT_LookupTable *look, WORD *glyphs, I
const GSUB_AlternateSubstFormat1 *asf1;
INT index;
offset = GET_BE_WORD(look->SubTable[j]);
asf1 = (const GSUB_AlternateSubstFormat1*)((const BYTE*)look+offset);
asf1 = (const GSUB_AlternateSubstFormat1*)GSUB_get_subtable(look, j);
offset = GET_BE_WORD(asf1->Coverage);
index = GSUB_is_glyph_covered((const BYTE*)asf1+offset, glyphs[glyph_index]);
@ -856,8 +876,7 @@ static INT GSUB_apply_LigatureSubst(const OT_LookupTable *look, WORD *glyphs, IN
const GSUB_LigatureSubstFormat1 *lsf1;
int offset,index;
offset = GET_BE_WORD(look->SubTable[j]);
lsf1 = (const GSUB_LigatureSubstFormat1*)((const BYTE*)look+offset);
lsf1 = (const GSUB_LigatureSubstFormat1*)GSUB_get_subtable(look, j);
offset = GET_BE_WORD(lsf1->Coverage);
index = GSUB_is_glyph_covered((const BYTE*)lsf1+offset, glyphs[glyph_index]);
TRACE(" Coverage index %i\n",index);
@ -923,8 +942,7 @@ static INT GSUB_apply_ChainContextSubst(const OT_LookupList* lookup, const OT_Lo
int dirLookahead = write_dir;
int dirBacktrack = -1 * write_dir;
offset = GET_BE_WORD(look->SubTable[j]);
ccsf1 = (const GSUB_ChainContextSubstFormat1*)((const BYTE*)look+offset);
ccsf1 = (const GSUB_ChainContextSubstFormat1*)GSUB_get_subtable(look, j);
if (GET_BE_WORD(ccsf1->SubstFormat) == 1)
{
static int once;
@ -1019,12 +1037,34 @@ static INT GSUB_apply_ChainContextSubst(const OT_LookupList* lookup, const OT_Lo
static INT GSUB_apply_lookup(const OT_LookupList* lookup, INT lookup_index, WORD *glyphs, INT glyph_index, INT write_dir, INT *glyph_count)
{
int offset;
int type;
const OT_LookupTable *look;
offset = GET_BE_WORD(lookup->Lookup[lookup_index]);
look = (const OT_LookupTable*)((const BYTE*)lookup + offset);
TRACE("type %i, flag %x, subtables %i\n",GET_BE_WORD(look->LookupType),GET_BE_WORD(look->LookupFlag),GET_BE_WORD(look->SubTableCount));
switch(GET_BE_WORD(look->LookupType))
type = GET_BE_WORD(look->LookupType);
TRACE("type %i, flag %x, subtables %i\n",type,GET_BE_WORD(look->LookupFlag),GET_BE_WORD(look->SubTableCount));
if (type == 7)
{
if (GET_BE_WORD(look->SubTableCount))
{
const GSUB_ExtensionPosFormat1 *ext = (const GSUB_ExtensionPosFormat1 *)((const BYTE *)look + GET_BE_WORD(look->SubTable[0]));
if (GET_BE_WORD(ext->SubstFormat) == 1)
{
type = GET_BE_WORD(ext->ExtensionLookupType);
TRACE("extension type %i\n",type);
}
else
{
FIXME("Unhandled Extension Substitution Format %i\n",GET_BE_WORD(ext->SubstFormat));
}
}
else
{
WARN("lookup type is Extension Substitution but no extension subtable exists\n");
}
}
switch(type)
{
case 1:
return GSUB_apply_SingleSubst(look, glyphs, glyph_index, write_dir, glyph_count);
@ -1036,8 +1076,11 @@ static INT GSUB_apply_lookup(const OT_LookupList* lookup, INT lookup_index, WORD
return GSUB_apply_LigatureSubst(look, glyphs, glyph_index, write_dir, glyph_count);
case 6:
return GSUB_apply_ChainContextSubst(lookup, look, glyphs, glyph_index, write_dir, glyph_count);
case 7:
FIXME("Extension Substitution types not valid here\n");
break;
default:
FIXME("We do not handle SubType %i\n",GET_BE_WORD(look->LookupType));
FIXME("We do not handle SubType %i\n",type);
}
return GSUB_E_NOGLYPH;
}

View file

@ -26,6 +26,7 @@
#include "usp10_internal.h"
#include <math.h>
#include <winuser.h>
#include <winreg.h>
@ -708,11 +709,6 @@ static inline void *heap_alloc_zero(SIZE_T size)
return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
}
static inline void *heap_realloc_zero(LPVOID mem, SIZE_T size)
{
return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, size);
}
static inline BOOL heap_free(LPVOID mem)
{
return HeapFree(GetProcessHeap(), 0, mem);
@ -1261,9 +1257,12 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
int New_Script = -1;
int i;
WORD *levels = NULL;
WORD *layout_levels = NULL;
WORD *overrides = NULL;
WORD *strength = NULL;
WORD *scripts = NULL;
WORD baselevel = 0;
WORD baselayout = 0;
BOOL new_run;
WORD last_indic = -1;
WORD layoutRTL = 0;
@ -1300,9 +1299,15 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
else if (is_indic(scripts[i]))
last_indic = base_indic(scripts[i]);
/* Some unicode points (Zero Width Space U+200B -
Right-to-Left Mark U+200F) will force us into bidi mode */
if (!forceLevels && pwcInChars[i] >= 0x200B && pwcInChars[i] <= 0x200F)
/* Some unicode points :
(Zero Width Space U+200B - Right-to-Left Mark U+200F)
(Left Right Embed U+202A - Left Right Override U+202D)
(Left Right Isolate U+2066 - Pop Directional Isolate U+2069)
will force us into bidi mode */
if (!forceLevels && ((pwcInChars[i] >= 0x200B && pwcInChars[i] <= 0x200F) ||
(pwcInChars[i] >= 0x202A && pwcInChars[i] <= 0x202E) ||
(pwcInChars[i] >= 0x2066 && pwcInChars[i] <= 0x2069)))
forceLevels = TRUE;
/* Diacritical marks merge with other scripts */
@ -1366,20 +1371,56 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
if (!levels)
goto nomemory;
BIDI_DetermineLevels(pwcInChars, cInChars, psState, psControl, levels);
overrides = heap_alloc_zero(cInChars * sizeof(WORD));
if (!overrides)
goto nomemory;
layout_levels = heap_alloc_zero(cInChars * sizeof(WORD));
if (!layout_levels)
goto nomemory;
if (psState->fOverrideDirection)
{
if (!forceLevels)
{
SCRIPT_STATE s = *psState;
s.fOverrideDirection = FALSE;
BIDI_DetermineLevels(pwcInChars, cInChars, &s, psControl, layout_levels, overrides);
if (odd(layout_levels[0]))
forceLevels = TRUE;
else for (i = 0; i < cInChars; i++)
if (layout_levels[i]!=layout_levels[0])
{
forceLevels = TRUE;
break;
}
}
BIDI_DetermineLevels(pwcInChars, cInChars, psState, psControl, levels, overrides);
}
else
{
BIDI_DetermineLevels(pwcInChars, cInChars, psState, psControl, levels, overrides);
memcpy(layout_levels, levels, cInChars * sizeof(WORD));
}
baselevel = levels[0];
baselayout = layout_levels[0];
for (i = 0; i < cInChars; i++)
if (levels[i]!=levels[0])
break;
if (i >= cInChars && !odd(baselevel) && !odd(psState->uBidiLevel) && !forceLevels)
{
heap_free(levels);
heap_free(overrides);
heap_free(layout_levels);
overrides = NULL;
levels = NULL;
layout_levels = NULL;
}
else
{
BOOL inNumber = FALSE;
static const WCHAR math_punc[] = {'#','$','%','+',',','-','.','/',':',0x2212, 0x2044, 0x00a0,0};
static const WCHAR repeatable_math_punc[] = {'#','$','%','+','-','/',0x2212, 0x2044,0};
strength = heap_alloc_zero(cInChars * sizeof(WORD));
if (!strength)
@ -1394,21 +1435,48 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
strength[i] = BIDI_STRONG;
}
/* Math punctuation bordered on both sides by numbers can be
merged into the number */
for (i = 0; i < cInChars; i++)
{
/* Script_Numeric and select puncuation at level 0 get bumped to level 2 */
if ((levels[i] == 0 || (odd(psState->uBidiLevel) && levels[i] == psState->uBidiLevel+1)) && inNumber && strchrW(math_punc,pwcInChars[i]))
if (i > 0 && i < cInChars-1 &&
scripts[i-1] == Script_Numeric &&
strchrW(math_punc, pwcInChars[i]))
{
scripts[i] = Script_Numeric;
levels[i] = 2;
if (scripts[i+1] == Script_Numeric)
{
scripts[i] = Script_Numeric;
levels[i] = levels[i-1];
strength[i] = strength[i-1];
i++;
}
else if (strchrW(repeatable_math_punc, pwcInChars[i]))
{
int j;
for (j = i+1; j < cInChars; j++)
{
if (scripts[j] == Script_Numeric)
{
for(;i<j; i++)
{
scripts[i] = Script_Numeric;
levels[i] = levels[i-1];
strength[i] = strength[i-1];
}
}
else if (pwcInChars[i] != pwcInChars[j]) break;
}
}
}
else if ((levels[i] == 0 || (odd(psState->uBidiLevel) && levels[i] == psState->uBidiLevel+1)) && scripts[i] == Script_Numeric)
}
for (i = 0; i < cInChars; i++)
{
/* Script_Numeric at level 0 get bumped to level 2 */
if (!overrides[i] && (levels[i] == 0 || (odd(psState->uBidiLevel) && levels[i] == psState->uBidiLevel+1)) && scripts[i] == Script_Numeric)
{
levels[i] = 2;
inNumber = TRUE;
}
else
inNumber = FALSE;
/* Joiners get merged preferencially right */
if (i > 0 && (pwcInChars[i] == ZWJ || pwcInChars[i] == ZWNJ))
@ -1491,19 +1559,31 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
if (levels)
{
if (strength[cnt] == BIDI_STRONG)
layoutRTL = (odd(levels[cnt]))?1:0;
layoutRTL = odd(layout_levels[cnt]);
else
layoutRTL = (psState->uBidiLevel || odd(levels[cnt]))?1:0;
layoutRTL = (psState->uBidiLevel || odd(layout_levels[cnt]));
if (overrides)
pItems[index].a.s.fOverrideDirection = (overrides[cnt] != 0);
pItems[index].a.fRTL = odd(levels[cnt]);
pItems[index].a.fLayoutRTL = layoutRTL;
if (pItems[index].a.eScript == Script_Numeric ||
pItems[index].a.eScript == Script_Numeric2)
pItems[index].a.fLayoutRTL = layoutRTL;
else
pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
pItems[index].a.s.uBidiLevel = levels[cnt];
}
else if (!pItems[index].a.s.uBidiLevel)
else if (!pItems[index].a.s.uBidiLevel || (overrides && overrides[cnt]))
{
layoutRTL = (odd(baselevel))?1:0;
if (pItems[index].a.s.uBidiLevel != baselevel)
pItems[index].a.s.fOverrideDirection = TRUE;
layoutRTL = odd(baselayout);
pItems[index].a.s.uBidiLevel = baselevel;
pItems[index].a.fLayoutRTL = odd(baselevel);
pItems[index].a.fRTL = odd(baselevel);
if (pItems[index].a.eScript == Script_Numeric ||
pItems[index].a.eScript == Script_Numeric2)
pItems[index].a.fLayoutRTL = odd(baselayout);
else
pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
}
TRACE("New_Level=%i New_Strength=%i New_Script=%d, eScript=%d index=%d cnt=%d iCharPos=%d\n",
@ -1554,8 +1634,10 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
if (!new_run && strength && str == BIDI_STRONG)
{
layoutRTL = odd(levels[cnt])?1:0;
pItems[index].a.fLayoutRTL = layoutRTL;
layoutRTL = odd(layout_levels[cnt]);
if (pItems[index].a.eScript == Script_Numeric ||
pItems[index].a.eScript == Script_Numeric2)
pItems[index].a.fLayoutRTL = layoutRTL;
}
if (new_run)
@ -1577,19 +1659,31 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
pScriptTags[index] = scriptInformation[New_Script].scriptTag;
if (levels)
{
if (levels[cnt] == 0)
if (overrides)
pItems[index].a.s.fOverrideDirection = (overrides[cnt] != 0);
if (layout_levels[cnt] == 0)
layoutRTL = 0;
else
layoutRTL = (layoutRTL || odd(levels[cnt]))?1:0;
layoutRTL = (layoutRTL || odd(layout_levels[cnt]));
pItems[index].a.fRTL = odd(levels[cnt]);
pItems[index].a.fLayoutRTL = layoutRTL;
if (pItems[index].a.eScript == Script_Numeric ||
pItems[index].a.eScript == Script_Numeric2)
pItems[index].a.fLayoutRTL = layoutRTL;
else
pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
pItems[index].a.s.uBidiLevel = levels[cnt];
}
else if (!pItems[index].a.s.uBidiLevel)
else if (!pItems[index].a.s.uBidiLevel || (overrides && overrides[cnt]))
{
if (pItems[index].a.s.uBidiLevel != baselevel)
pItems[index].a.s.fOverrideDirection = TRUE;
pItems[index].a.s.uBidiLevel = baselevel;
pItems[index].a.fLayoutRTL = layoutRTL;
pItems[index].a.fRTL = odd(baselevel);
if (pItems[index].a.eScript == Script_Numeric||
pItems[index].a.eScript == Script_Numeric2)
pItems[index].a.fLayoutRTL = layoutRTL;
else
pItems[index].a.fLayoutRTL = pItems[index].a.fRTL;
}
TRACE("index=%d cnt=%d iCharPos=%d\n", index, cnt, pItems[index].iCharPos);
@ -1613,6 +1707,8 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars,
res = S_OK;
nomemory:
heap_free(levels);
heap_free(overrides);
heap_free(layout_levels);
heap_free(strength);
heap_free(scripts);
return res;
@ -2567,9 +2663,100 @@ HRESULT WINAPI ScriptCPtoX(int iCP,
return S_OK;
}
/* Count the number of characters in a cluster and its starting index*/
static inline BOOL get_cluster_data(const WORD *pwLogClust, int cChars, int cluster_index, int *cluster_size, int *start_index)
{
int size = 0;
int i;
for (i = 0; i < cChars; i++)
{
if (pwLogClust[i] == cluster_index)
{
if (!size && start_index)
{
*start_index = i;
if (!cluster_size)
return TRUE;
}
size++;
}
else if (size) break;
}
if (cluster_size)
*cluster_size = size;
return (size > 0);
}
/*
To handle multi-glyph clusters we need to find all the glyphs that are
represented in the cluster. This involves finding the glyph whose
index is the cluster index as well as whose glyph indices are greater than
our cluster index but not part of a new cluster.
Then we sum all those glyphs' advances.
*/
static inline int get_cluster_advance(const int* piAdvance,
const SCRIPT_VISATTR *psva,
const WORD *pwLogClust, int cGlyphs,
int cChars, int cluster, int direction)
{
int glyph_start;
int glyph_end;
int i, advance;
if (direction > 0)
i = 0;
else
i = (cChars - 1);
for (glyph_start = -1, glyph_end = -1; i < cChars && i >= 0 && (glyph_start < 0 || glyph_end < 0); i+=direction)
{
if (glyph_start < 0 && pwLogClust[i] != cluster) continue;
if (pwLogClust[i] == cluster && glyph_start < 0) glyph_start = pwLogClust[i];
if (glyph_start >= 0 && glyph_end < 0 && pwLogClust[i] != cluster) glyph_end = pwLogClust[i];
}
if (glyph_end < 0)
{
if (direction > 0)
glyph_end = cGlyphs;
else
{
/* Don't fully understand multi-glyph reversed clusters yet,
* do they occur for real or just in our test? */
FIXME("multi-glyph reversed clusters found\n");
glyph_end = glyph_start + 1;
}
}
/* Check for fClusterStart, finding this generally would mean a malformed set of data */
for (i = glyph_start+1; i< glyph_end; i++)
{
if (psva[i].fClusterStart)
{
glyph_end = i;
break;
}
}
for (advance = 0, i = glyph_start; i < glyph_end; i++)
advance += piAdvance[i];
return advance;
}
/***********************************************************************
* ScriptXtoCP (USP10.@)
*
* Basic algorithm :
* use piAdvance to find the cluster we are looking at
* Find the character that is the first character of the cluster
* That is our base piCP
* If the script snaps to cluster boundries (Hebrew, Indic, Thai) then we
* are good Otherwise if the cluster is larger than 1 glyph we need to
* determine how far through the cluster to advance the cursor.
*/
HRESULT WINAPI ScriptXtoCP(int iX,
int cChars,
@ -2581,16 +2768,11 @@ HRESULT WINAPI ScriptXtoCP(int iX,
int *piCP,
int *piTrailing)
{
int item;
float iPosX;
float iLastPosX;
int iSpecial = -1;
int iCluster = -1;
int clust_size = 1;
int cjump = 0;
int advance;
float special_size = 0.0;
int direction = 1;
int iPosX;
int i;
int glyph_index, cluster_index;
int cluster_size;
TRACE("(%d,%d,%d,%p,%p,%p,%p,%p,%p)\n",
iX, cChars, cGlyphs, pwLogClust, psva, piAdvance,
@ -2599,128 +2781,156 @@ HRESULT WINAPI ScriptXtoCP(int iX,
if (psa->fRTL && ! psa->fLogicalOrder)
direction = -1;
if (direction<0)
/* Handle an iX < 0 */
if (iX < 0)
{
int max_clust = pwLogClust[0];
if (iX < 0)
if (direction < 0)
{
*piCP = cChars;
*piTrailing = 0;
return S_OK;
}
else
{
*piCP = -1;
*piTrailing = 1;
}
return S_OK;
}
for (item=0; item < cChars; item++)
if (pwLogClust[item] > max_clust)
/* Looking for non-reversed clusters in a reversed string */
if (direction < 0)
{
int max_clust = pwLogClust[0];
for (i=0; i< cChars; i++)
if (pwLogClust[i] > max_clust)
{
ERR("We do not handle non reversed clusters properly\n");
FIXME("We do not handle non reversed clusters properly\n");
break;
}
}
if (iX < 0)
/* find the glyph_index based in iX */
if (direction > 0)
{
*piCP = -1;
*piTrailing = 1;
return S_OK;
for (glyph_index = -1, iPosX = iX; iPosX >=0 && glyph_index < cGlyphs; iPosX -= piAdvance[glyph_index+1], glyph_index++)
;
}
else
{
for (glyph_index = -1, iPosX = iX; iPosX > 0 && glyph_index < cGlyphs; iPosX -= piAdvance[glyph_index+1], glyph_index++)
;
}
iPosX = iLastPosX = 0;
if (direction > 0)
item = 0;
else
item = cChars - 1;
for (; iPosX <= iX && item < cChars && item >= 0; item+=direction)
TRACE("iPosX %i -> glyph_index %i (%i)\n", iPosX, glyph_index, cGlyphs);
*piTrailing = 0;
if (glyph_index >= 0 && glyph_index < cGlyphs)
{
iLastPosX = iPosX;
if (iSpecial == -1 &&
(iCluster == -1 ||
(iCluster != -1 &&
((direction > 0 && iCluster+clust_size <= item) ||
(direction < 0 && iCluster-clust_size >= item))
)
)
)
/* find the cluster */
if (direction > 0 )
for (i = 0, cluster_index = pwLogClust[0]; i < cChars && pwLogClust[i] <= glyph_index; cluster_index=pwLogClust[i++])
;
else
for (i = 0, cluster_index = pwLogClust[0]; i < cChars && pwLogClust[i] >= glyph_index; cluster_index=pwLogClust[i++])
;
TRACE("cluster_index %i\n", cluster_index);
if (direction < 0 && iPosX >= 0 && glyph_index != cluster_index)
{
int check;
int clust = pwLogClust[item];
/* We are off the end of the string */
*piCP = -1;
*piTrailing = 1;
return S_OK;
}
iCluster = -1;
cjump = 0;
clust_size = get_cluster_size(pwLogClust, cChars, item, direction,
&iCluster, &check);
advance = get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, clust, direction);
get_cluster_data(pwLogClust, cChars, cluster_index, &cluster_size, &i);
if (check >= cChars && direction > 0)
TRACE("first char index %i\n",i);
if (scriptInformation[psa->eScript].props.fNeedsCaretInfo)
{
/* Check trailing */
if (glyph_index != cluster_index ||
(direction > 0 && abs(iPosX) <= (piAdvance[glyph_index] / 2)) ||
(direction < 0 && abs(iPosX) >= (piAdvance[glyph_index] / 2)))
*piTrailing = cluster_size;
}
else
{
if (cluster_size > 1)
{
int glyph;
for (glyph = clust; glyph < cGlyphs; glyph++)
special_size += get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, glyph, direction);
iSpecial = item;
special_size /= (cChars - item);
iPosX += special_size;
}
else
{
if (scriptInformation[psa->eScript].props.fNeedsCaretInfo)
/* Be part way through the glyph cluster based on size and position */
int cluster_advance = get_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, cluster_index, direction);
double cluster_part_width = cluster_advance / (float)cluster_size;
double adv;
int part_index;
/* back up to the beginning of the cluster */
for (adv = iPosX, part_index = cluster_index; part_index <= glyph_index; part_index++)
adv += piAdvance[part_index];
if (adv > iX) adv = iX;
TRACE("Multi-char cluster, no snap\n");
TRACE("cluster size %i, pre-cluster iPosX %f\n",cluster_size, adv);
TRACE("advance %i divides into %f per char\n", cluster_advance, cluster_part_width);
if (direction > 0)
{
if (!cjump)
iPosX += advance;
cjump++;
for (part_index = 0; adv >= 0; adv-=cluster_part_width, part_index++)
;
if (part_index) part_index--;
}
else
iPosX += advance / (float)clust_size;
}
}
else if (iSpecial != -1)
iPosX += special_size;
else /* (iCluster != -1) */
{
int adv = get_glyph_cluster_advance(piAdvance, psva, pwLogClust, cGlyphs, cChars, pwLogClust[iCluster], direction);
if (scriptInformation[psa->eScript].props.fNeedsCaretInfo)
{
if (!cjump)
iPosX += adv;
cjump++;
{
for (part_index = 0; adv > 0; adv-=cluster_part_width, part_index++)
;
if (part_index > cluster_size)
{
adv += cluster_part_width;
part_index=cluster_size;
}
}
TRACE("base_char %i part_index %i, leftover advance %f\n",i, part_index, adv);
if (direction > 0)
i += part_index;
else
i += (cluster_size - part_index);
/* Check trailing */
if ((direction > 0 && fabs(adv) <= (cluster_part_width / 2.0)) ||
(direction < 0 && adv && fabs(adv) >= (cluster_part_width / 2.0)))
*piTrailing = 1;
}
else
iPosX += adv / (float)clust_size;
{
/* Check trailing */
if ((direction > 0 && abs(iPosX) <= (piAdvance[glyph_index] / 2)) ||
(direction < 0 && abs(iPosX) >= (piAdvance[glyph_index] / 2)))
*piTrailing = 1;
}
}
}
if (direction > 0)
{
if (iPosX > iX)
item--;
if (item < cChars && ((iPosX - iLastPosX) / 2.0) + iX >= iPosX)
{
if (scriptInformation[psa->eScript].props.fNeedsCaretInfo && clust_size > 1)
item+=(clust_size-1);
*piTrailing = 1;
}
else
*piTrailing = 0;
}
else
{
if (iX == iLastPosX)
item++;
if (iX >= iLastPosX && iX <= iPosX)
item++;
TRACE("Point falls outside of string\n");
if (glyph_index < 0)
i = cChars-1;
else /* (glyph_index >= cGlyphs) */
i = cChars;
if (iLastPosX == iX)
*piTrailing = 0;
else if (item < 0 || ((iLastPosX - iPosX) / 2.0) + iX <= iLastPosX)
/* If not snaping in the reverse direction (such as Hebrew) Then 0
point flow to the next character */
if (direction < 0)
{
if (scriptInformation[psa->eScript].props.fNeedsCaretInfo && clust_size > 1)
item-=(clust_size-1);
*piTrailing = 1;
if (!scriptInformation[psa->eScript].props.fNeedsCaretInfo && abs(iPosX) == piAdvance[glyph_index])
i++;
else
*piTrailing = 1;
}
else
*piTrailing = 0;
}
*piCP = item;
*piCP = i;
TRACE("*piCP=%d\n", *piCP);
TRACE("*piTrailing=%d\n", *piTrailing);
@ -3095,7 +3305,11 @@ HRESULT WINAPI ScriptPlaceOpenType( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_ANALYSIS
for (i = 0; i < cGlyphs; i++)
{
ABC abc;
if (!get_cache_glyph_widths(psc, pwGlyphs[i], &abc))
if (pGlyphProps[i].sva.fZeroWidth)
{
abc.abcA = abc.abcB = abc.abcC = 0;
}
else if (!get_cache_glyph_widths(psc, pwGlyphs[i], &abc))
{
if (!hdc) return E_PENDING;
if ((get_cache_pitch_family(psc) & TMPF_TRUETYPE) && !psa->fNoGlyphIndex)
@ -3420,7 +3634,6 @@ HRESULT WINAPI ScriptLayout(int runs, const BYTE *level, int *vistolog, int *log
if (!indexs)
return E_OUTOFMEMORY;
if (vistolog)
{
for( ich = 0; ich < runs; ich++)
@ -3429,11 +3642,9 @@ HRESULT WINAPI ScriptLayout(int runs, const BYTE *level, int *vistolog, int *log
ich = 0;
while (ich < runs)
ich += BIDI_ReorderV2lLevel(0, indexs+ich, level+ich, runs - ich, FALSE);
for (ich = 0; ich < runs; ich++)
vistolog[ich] = indexs[ich];
memcpy(vistolog, indexs, runs * sizeof(*vistolog));
}
if (logtovis)
{
for( ich = 0; ich < runs; ich++)
@ -3442,8 +3653,7 @@ HRESULT WINAPI ScriptLayout(int runs, const BYTE *level, int *vistolog, int *log
ich = 0;
while (ich < runs)
ich += BIDI_ReorderL2vLevel(0, indexs+ich, level+ich, runs - ich, FALSE);
for (ich = 0; ich < runs; ich++)
logtovis[ich] = indexs[ich];
memcpy(logtovis, indexs, runs * sizeof(*logtovis));
}
heap_free(indexs);

View file

@ -244,7 +244,7 @@ typedef void (*reorder_function)(LPWSTR pwChar, IndicSyllable *syllable, lexical
int USP10_FindGlyphInLogClust(const WORD* pwLogClust, int cChars, WORD target) DECLSPEC_HIDDEN;
BOOL BIDI_DetermineLevels( LPCWSTR lpString, INT uCount, const SCRIPT_STATE *s,
const SCRIPT_CONTROL *c, WORD *lpOutLevels ) DECLSPEC_HIDDEN;
const SCRIPT_CONTROL *c, WORD *lpOutLevels, WORD *lpOutOverrides ) DECLSPEC_HIDDEN;
BOOL BIDI_GetStrengths(LPCWSTR lpString, INT uCount, const SCRIPT_CONTROL *c,
WORD* lpStrength) DECLSPEC_HIDDEN;
INT BIDI_ReorderV2lLevel(int level, int *pIndexs, const BYTE* plevel, int cch, BOOL fReverse) DECLSPEC_HIDDEN;

View file

@ -193,7 +193,7 @@ reactos/dll/win32/twain_32 # Synced to WineStaging-1.7.55
reactos/dll/win32/updspapi # Synced to WineStaging-1.7.55
reactos/dll/win32/url # Synced to WineStaging-1.7.55
reactos/dll/win32/urlmon # Synced to WineStaging-1.9.4
reactos/dll/win32/usp10 # Synced to WineStaging-1.7.55
reactos/dll/win32/usp10 # Synced to WineStaging-1.9.4
reactos/dll/win32/uxtheme # Forked
reactos/dll/win32/vbscript # Synced to WineStaging-1.7.55
reactos/dll/win32/version # Synced to WineStaging-1.7.55