From 518294482880277704165413f44fdb1425d0f364 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Sat, 5 Mar 2016 10:30:03 +0000 Subject: [PATCH] [USP10] Sync with Wine Staging 1.9.4. CORE-10912 svn path=/trunk/; revision=70939 --- reactos/dll/win32/usp10/bidi.c | 19 +- reactos/dll/win32/usp10/indicsyllable.c | 208 +++++----- reactos/dll/win32/usp10/opentype.c | 73 +++- reactos/dll/win32/usp10/usp10.c | 482 ++++++++++++++++------- reactos/dll/win32/usp10/usp10_internal.h | 2 +- reactos/media/doc/README.WINE | 2 +- 6 files changed, 537 insertions(+), 249 deletions(-) diff --git a/reactos/dll/win32/usp10/bidi.c b/reactos/dll/win32/usp10/bidi.c index c65628c4239..7cedd0c006d 100644 --- a/reactos/dll/win32/usp10/bidi.c +++ b/reactos/dll/win32/usp10/bidi.c @@ -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 */ diff --git a/reactos/dll/win32/usp10/indicsyllable.c b/reactos/dll/win32/usp10/indicsyllable.c index 81b90cf1ea2..b3f7ca2e1ec 100644 --- a/reactos/dll/win32/usp10/indicsyllable.c +++ b/reactos/dll/win32/usp10/indicsyllable.c @@ -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 }; diff --git a/reactos/dll/win32/usp10/opentype.c b/reactos/dll/win32/usp10/opentype.c index 9664765a459..45173da8c8a 100644 --- a/reactos/dll/win32/usp10/opentype.c +++ b/reactos/dll/win32/usp10/opentype.c @@ -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; } diff --git a/reactos/dll/win32/usp10/usp10.c b/reactos/dll/win32/usp10/usp10.c index 2b11afc0696..38cf4dff828 100644 --- a/reactos/dll/win32/usp10/usp10.c +++ b/reactos/dll/win32/usp10/usp10.c @@ -26,6 +26,7 @@ #include "usp10_internal.h" +#include #include #include @@ -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(;iuBidiLevel) && 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); diff --git a/reactos/dll/win32/usp10/usp10_internal.h b/reactos/dll/win32/usp10/usp10_internal.h index 8d048d838f4..2f5443ee466 100644 --- a/reactos/dll/win32/usp10/usp10_internal.h +++ b/reactos/dll/win32/usp10/usp10_internal.h @@ -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; diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 1dc84e56fbe..62eebe28629 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -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