From 35559d161e99ca91fb8e64aa73b954045a0d33f1 Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Mon, 4 Jun 2012 11:14:27 -0500 Subject: [PATCH] usp10: Correct glyph caching beyond the BMP. (cherry picked from commit 7fbf72c40083f7f97a12e60de247d94b635f400d) --- 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 90b125934e8..7cb6920dc93 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 558eb554200..013e3836855 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; -- 2.11.4.GIT