Module: wine Branch: master Commit: 4fbb6fd66d82667a5e678d6c37868a425c93f403 URL: http://source.winehq.org/git/wine.git/?a=commit;h=4fbb6fd66d82667a5e678d6c37...
Author: Aric Stewart aric@codeweavers.com Date: Fri Dec 16 13:15:47 2011 -0600
usp10: Handle surrogate pairs when shaping.
---
dlls/usp10/usp10.c | 67 +++++++++++++++++++++++++++++++++++---------------- 1 files changed, 46 insertions(+), 21 deletions(-)
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index 5f1ac5c..7a32937 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -708,7 +708,7 @@ static inline BYTE get_cache_pitch_family(SCRIPT_CACHE *psc) return ((ScriptCache *)*psc)->tm.tmPitchAndFamily; }
-static inline WORD get_cache_glyph(SCRIPT_CACHE *psc, WCHAR c) +static inline WORD get_cache_glyph(SCRIPT_CACHE *psc, DWORD c) { WORD *block = ((ScriptCache *)*psc)->glyphs[c >> GLYPH_BLOCK_SHIFT];
@@ -2631,8 +2631,9 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc, SCRIPT_GLYPHPROP *pOutGlyphProps, int *pcGlyphs) { HRESULT hr; - unsigned int i; + unsigned int i,g; BOOL rtl; + int cluster;
TRACE("(%p, %p, %p, %s, %s, %p, %p, %d, %s, %d, %d, %p, %p, %p, %p, %p )\n", hdc, psc, psa, @@ -2688,35 +2689,59 @@ HRESULT WINAPI ScriptShapeOpenType( HDC hdc, SCRIPT_CACHE *psc,
rChars = heap_alloc(sizeof(WCHAR) * cChars); if (!rChars) return E_OUTOFMEMORY; - for (i = 0; i < cChars; i++) + for (i = 0, g = 0, cluster = 0; i < cChars; i++) { int idx = i; - WCHAR chInput; + DWORD chInput; + if (rtl) idx = cChars - 1 - i; - if (psa->fRTL) - chInput = mirror_char(pwcChars[idx]); - else - chInput = pwcChars[idx]; - /* special case for tabs */ - if (chInput == 0x0009) - chInput = 0x0020; - if (!(pwOutGlyphs[i] = get_cache_glyph(psc, chInput))) + if (!cluster) { - WORD glyph; - if (!hdc) + chInput = decode_surrogate_pair(pwcChars, idx, cChars); + if (!chInput) { - heap_free(rChars); - return E_PENDING; + if (psa->fRTL) + chInput = mirror_char(pwcChars[idx]); + else + chInput = pwcChars[idx]; + /* special case for tabs */ + if (chInput == 0x0009) + chInput = 0x0020; + rChars[i] = chInput; } - if (GetGlyphIndicesW(hdc, &chInput, 1, &glyph, 0) == GDI_ERROR) + else { - heap_free(rChars); - return S_FALSE; + rChars[i] = pwcChars[idx]; + rChars[i+1] = pwcChars[(rtl)?idx-1:idx+1]; + cluster = 1; } - pwOutGlyphs[i] = set_cache_glyph(psc, chInput, glyph); + if (!(pwOutGlyphs[g] = get_cache_glyph(psc, chInput))) + { + WORD glyph; + if (!hdc) + { + heap_free(rChars); + return E_PENDING; + } + if (CMAP_GetGlyphIndex(hdc, (ScriptCache *)*psc, chInput, &glyph, 0) == GDI_ERROR) + { + heap_free(rChars); + return S_FALSE; + } + pwOutGlyphs[g] = set_cache_glyph(psc, chInput, glyph); + } + g++; + } + else + { + int k; + cluster--; + pwLogClust[idx] = (rtl)?pwLogClust[idx+1]:pwLogClust[idx-1]; + for (k = (rtl)?idx-1:idx+1; k >= 0 && k < cChars; (rtl)?k--:k++) + pwLogClust[k]--; } - rChars[i] = chInput; } + *pcGlyphs = g;
SHAPE_ContextualShaping(hdc, (ScriptCache *)*psc, psa, rChars, cChars, pwOutGlyphs, pcGlyphs, cMaxGlyphs, pwLogClust); SHAPE_ApplyDefaultOpentypeFeatures(hdc, (ScriptCache *)*psc, psa, pwOutGlyphs, pcGlyphs, cMaxGlyphs, cChars, pwLogClust);