Aric Stewart : usp10: Handle surrogate pairs when shaping.
Alexandre Julliard
julliard at winehq.org
Mon Dec 19 13:39:22 CST 2011
Module: wine
Branch: master
Commit: 4fbb6fd66d82667a5e678d6c37868a425c93f403
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4fbb6fd66d82667a5e678d6c37868a425c93f403
Author: Aric Stewart <aric at 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);
More information about the wine-cvs
mailing list