Module: wine Branch: master Commit: 7fbf72c40083f7f97a12e60de247d94b635f400d URL: http://source.winehq.org/git/wine.git/?a=commit;h=7fbf72c40083f7f97a12e60de2...
Author: Aric Stewart aric@codeweavers.com Date: Mon Jun 4 11:14:27 2012 -0500
usp10: Correct glyph caching beyond the BMP.
---
dlls/usp10/usp10.c | 23 ++++++++++++++++++----- dlls/usp10/usp10_internal.h | 6 +++++- 2 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/dlls/usp10/usp10.c b/dlls/usp10/usp10.c index ff842b0..8942a42 100644 --- a/dlls/usp10/usp10.c +++ b/dlls/usp10/usp10.c @@ -746,18 +746,24 @@ static inline BYTE get_cache_pitch_family(SCRIPT_CACHE *psc)
static inline WORD get_cache_glyph(SCRIPT_CACHE *psc, DWORD c) { - WORD *block = ((ScriptCache *)*psc)->glyphs[c >> GLYPH_BLOCK_SHIFT]; + CacheGlyphPage *page = ((ScriptCache *)*psc)->page[c / 0x10000]; + WORD *block;
+ if (!page) return 0; + block = page->glyphs[(c % 0x10000) >> GLYPH_BLOCK_SHIFT]; if (!block) return 0; - return block[c & GLYPH_BLOCK_MASK]; + return block[(c % 0x10000) & GLYPH_BLOCK_MASK]; }
static inline WORD set_cache_glyph(SCRIPT_CACHE *psc, WCHAR c, WORD glyph) { - WORD **block = &((ScriptCache *)*psc)->glyphs[c >> GLYPH_BLOCK_SHIFT]; + CacheGlyphPage **page = &((ScriptCache *)*psc)->page[c / 0x10000]; + WORD **block; + if (!*page && !(*page = heap_alloc_zero(sizeof(CacheGlyphPage)))) return 0;
+ block = &(*page)->glyphs[(c % 0x10000) >> GLYPH_BLOCK_SHIFT]; if (!*block && !(*block = heap_alloc_zero(sizeof(WORD) * GLYPH_BLOCK_SIZE))) return 0; - return ((*block)[c & GLYPH_BLOCK_MASK] = glyph); + return ((*block)[(c % 0x10000) & GLYPH_BLOCK_MASK] = glyph); }
static inline BOOL get_cache_glyph_widths(SCRIPT_CACHE *psc, WORD glyph, ABC *abc) @@ -965,9 +971,16 @@ HRESULT WINAPI ScriptFreeCache(SCRIPT_CACHE *psc) unsigned int i; for (i = 0; i < GLYPH_MAX / GLYPH_BLOCK_SIZE; i++) { - heap_free(((ScriptCache *)*psc)->glyphs[i]); heap_free(((ScriptCache *)*psc)->widths[i]); } + for (i = 0; i < 0x10; i++) + { + int j; + if (((ScriptCache *)*psc)->page[i]) + for (j = 0; j < GLYPH_MAX / GLYPH_BLOCK_SIZE; j++) + heap_free(((ScriptCache *)*psc)->page[i]->glyphs[j]); + heap_free(((ScriptCache *)*psc)->page[i]); + } heap_free(((ScriptCache *)*psc)->GSUB_Table); heap_free(((ScriptCache *)*psc)->GDEF_Table); heap_free(((ScriptCache *)*psc)->CMAP_Table); diff --git a/dlls/usp10/usp10_internal.h b/dlls/usp10/usp10_internal.h index 558eb55..013e383 100644 --- a/dlls/usp10/usp10_internal.h +++ b/dlls/usp10/usp10_internal.h @@ -151,10 +151,14 @@ typedef struct { } LoadedScript;
typedef struct { + WORD *glyphs[GLYPH_MAX / GLYPH_BLOCK_SIZE]; +} CacheGlyphPage; + +typedef struct { LOGFONTW lf; TEXTMETRICW tm; BOOL sfnt; - WORD *glyphs[GLYPH_MAX / GLYPH_BLOCK_SIZE]; + CacheGlyphPage *page[0x10]; ABC *widths[GLYPH_MAX / GLYPH_BLOCK_SIZE]; LPVOID GSUB_Table; LPVOID GDEF_Table;