Module: wine Branch: master Commit: a7071662f7e75da4c936f532a07e132f252c3a4a URL: http://source.winehq.org/git/wine.git/?a=commit;h=a7071662f7e75da4c936f532a0...
Author: Aric Stewart aric@codeweavers.com Date: Mon Aug 29 06:49:40 2011 -0500
usp10: Display and handle bidi runs in the correct order in ScriptString functions.
---
dlls/usp10/usp10.c | 58 +++++++++++++++++++++++++++++++++++----------------- 1 files changed, 39 insertions(+), 19 deletions(-)
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index 38f6c3a..105990b 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -334,6 +334,7 @@ typedef struct { StringGlyphs* glyphs; SCRIPT_LOGATTR* logattrs; SIZE* sz; + int* logical2visual; } StringAnalysis;
static inline void *heap_alloc(SIZE_T size) @@ -910,6 +911,7 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, SCRIPT_CONTROL sControl; SCRIPT_STATE sState; int i, num_items = 255; + BYTE *BidiLevel;
TRACE("(%p,%p,%d,%d,%d,0x%x,%d,%p,%p,%p,%p,%p,%p)\n", hdc, pString, cString, cGlyphs, iCharset, dwFlags, iReqWidth, @@ -965,6 +967,11 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, if (!(analysis->glyphs = heap_alloc_zero(sizeof(StringGlyphs) * analysis->numItems))) goto error;
+ if (!(analysis->logical2visual = heap_alloc_zero(sizeof(int) * analysis->numItems))) + goto error; + if (!(BidiLevel = heap_alloc_zero(analysis->numItems))) + goto error; + for (i = 0; i < analysis->numItems; i++) { SCRIPT_CACHE *sc = (SCRIPT_CACHE *)&analysis->sc; @@ -994,8 +1001,13 @@ HRESULT WINAPI ScriptStringAnalyse(HDC hdc, const void *pString, int cString, analysis->glyphs[i].pGoffset = pGoffset; analysis->glyphs[i].abc = abc; analysis->glyphs[i].iMaxPosX= -1; + + BidiLevel[i] = analysis->pItem[i].a.s.uBidiLevel; }
+ ScriptLayout(analysis->numItems, BidiLevel, NULL, analysis->logical2visual); + heap_free(BidiLevel); + *pssa = analysis; return S_OK;
@@ -1003,6 +1015,7 @@ error: heap_free(analysis->glyphs); heap_free(analysis->logattrs); heap_free(analysis->pItem); + heap_free(analysis->logical2visual); heap_free(analysis->sc); heap_free(analysis); return hr; @@ -1064,24 +1077,23 @@ HRESULT WINAPI ScriptStringOut(SCRIPT_STRING_ANALYSIS ssa, uOptions |= ETO_GLYPH_INDEX; analysis->pItem[0].a.fNoGlyphIndex = FALSE; /* say that we have glyphs */
+ TRACE("numItems %d\n", analysis->numItems); + /* * Copy the string items into the output buffer */ - - TRACE("numItems %d\n", analysis->numItems); - cnt = 0; for (item = 0; item < analysis->numItems; item++) { - memcpy(&glyphs[cnt], analysis->glyphs[item].glyphs, - sizeof(WCHAR) * analysis->glyphs[item].numGlyphs); + memcpy(&glyphs[cnt], analysis->glyphs[analysis->logical2visual[item]].glyphs, + sizeof(WCHAR) * analysis->glyphs[analysis->logical2visual[item]].numGlyphs);
- TRACE("Item %d, Glyphs %d ", item, analysis->glyphs[item].numGlyphs); - for (x = cnt; x < analysis->glyphs[item].numGlyphs + cnt; x ++) + TRACE("Item %d, Glyphs %d ", analysis->logical2visual[item], analysis->glyphs[analysis->logical2visual[item]].numGlyphs); + for (x = cnt; x < analysis->glyphs[analysis->logical2visual[item]].numGlyphs + cnt; x ++) TRACE("%04x", glyphs[x]); TRACE("\n");
- cnt += analysis->glyphs[item].numGlyphs; /* point to the end of the copied text */ + cnt += analysis->glyphs[analysis->logical2visual[item]].numGlyphs; /* point to the end of the copied text */ }
hr = ScriptTextOut(analysis->hdc, (SCRIPT_CACHE *)&analysis->sc, iX, iY, @@ -1102,7 +1114,7 @@ HRESULT WINAPI ScriptStringOut(SCRIPT_STRING_ANALYSIS ssa, */ HRESULT WINAPI ScriptStringCPtoX(SCRIPT_STRING_ANALYSIS ssa, int icp, BOOL fTrailing, int* pX) { - int i; + int item; int runningX = 0; StringAnalysis* analysis = ssa;
@@ -1117,10 +1129,13 @@ HRESULT WINAPI ScriptStringCPtoX(SCRIPT_STRING_ANALYSIS ssa, int icp, BOOL fTrai return E_INVALIDARG; }
- for(i=0; i<analysis->numItems; i++) + for(item=0; item<analysis->numItems; item++) { - int CP = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos; + int CP, i; int offset; + + i = analysis->logical2visual[item]; + CP = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos; /* initialize max extents for uninitialized runs */ if (analysis->glyphs[i].iMaxPosX == -1) { @@ -1134,13 +1149,13 @@ HRESULT WINAPI ScriptStringCPtoX(SCRIPT_STRING_ANALYSIS ssa, int icp, BOOL fTrai &analysis->pItem[i].a, &analysis->glyphs[i].iMaxPosX); }
- if (icp >= CP) + if (icp >= analysis->pItem[i+1].iCharPos || icp < analysis->pItem[i].iCharPos) { runningX += analysis->glyphs[i].iMaxPosX; - icp -= CP; continue; }
+ icp -= analysis->pItem[i].iCharPos; ScriptCPtoX(icp, fTrailing, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust, analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance, &analysis->pItem[i].a, &offset); @@ -1162,8 +1177,7 @@ HRESULT WINAPI ScriptStringCPtoX(SCRIPT_STRING_ANALYSIS ssa, int icp, BOOL fTrai HRESULT WINAPI ScriptStringXtoCP(SCRIPT_STRING_ANALYSIS ssa, int iX, int* piCh, int* piTrailing) { StringAnalysis* analysis = ssa; - int i; - int runningCp = 0; + int item;
TRACE("(%p), %d, (%p), (%p)\n", ssa, iX, piCh, piTrailing);
@@ -1185,9 +1199,15 @@ HRESULT WINAPI ScriptStringXtoCP(SCRIPT_STRING_ANALYSIS ssa, int iX, int* piCh, return S_OK; }
- for(i=0; i<analysis->numItems; i++) + for(item=0; item<analysis->numItems; item++) { - int CP = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos; + int i; + int CP; + + for (i = 0; i < analysis->numItems && analysis->logical2visual[i] != item; i++) + /* nothing */; + + CP = analysis->pItem[i+1].iCharPos - analysis->pItem[i].iCharPos; /* initialize max extents for uninitialized runs */ if (analysis->glyphs[i].iMaxPosX == -1) { @@ -1204,14 +1224,13 @@ HRESULT WINAPI ScriptStringXtoCP(SCRIPT_STRING_ANALYSIS ssa, int iX, int* piCh, if (iX > analysis->glyphs[i].iMaxPosX) { iX -= analysis->glyphs[i].iMaxPosX; - runningCp += CP; continue; }
ScriptXtoCP(iX, CP, analysis->glyphs[i].numGlyphs, analysis->glyphs[i].pwLogClust, analysis->glyphs[i].psva, analysis->glyphs[i].piAdvance, &analysis->pItem[i].a, piCh, piTrailing); - *piCh += runningCp; + *piCh += analysis->pItem[i].iCharPos;
return S_OK; } @@ -1264,6 +1283,7 @@ HRESULT WINAPI ScriptStringFree(SCRIPT_STRING_ANALYSIS *pssa) heap_free(analysis->logattrs); heap_free(analysis->sz); heap_free(analysis->sc); + heap_free(analysis->logical2visual); heap_free(analysis);
if (invalid) return E_INVALIDARG;