summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorTor Lillqvist <tml@iki.fi>2010-06-26 16:05:13 +0300
committerTor Lillqvist <tml@iki.fi>2010-06-26 16:09:10 +0300
commit3882c7dcaa00c0489c4bfdd582b3fefe5e3741b9 (patch)
tree416793ba7b09513026c4f2856a35d1aa96d0d0da /modules
parente4880b237e9056a95ad2ca25798f84d7372629f1 (diff)
downloadpango-3882c7dcaa00c0489c4bfdd582b3fefe5e3741b9.tar.gz
Improve performance on Windows especially for non-Latin scripts
The use of Uniscribe script caches was decidedly suboptimal. Use one persistent SCRIPT_CACHE per Win32 font and script. Patch by by David E. Hollingsworth and Fredrik Corneliusson, from bug
Diffstat (limited to 'modules')
-rw-r--r--modules/basic/basic-win32.c50
1 files changed, 38 insertions, 12 deletions
diff --git a/modules/basic/basic-win32.c b/modules/basic/basic-win32.c
index 1565a7c7..22aafdb5 100644
--- a/modules/basic/basic-win32.c
+++ b/modules/basic/basic-win32.c
@@ -31,6 +31,8 @@
#include "pangowin32.h"
+extern HFONT _pango_win32_font_get_hfont (PangoFont *font);
+
#ifndef PANGO_MODULE_PREFIX
#define PANGO_MODULE_PREFIX _pango_basic_win32
#endif
@@ -500,8 +502,7 @@ itemize_shape_and_place (PangoFont *font,
wchar_t *wtext,
int wlen,
const PangoAnalysis *analysis,
- PangoGlyphString *glyphs,
- SCRIPT_CACHE *script_cache)
+ PangoGlyphString *glyphs)
{
int i;
int item, nitems, item_step;
@@ -510,6 +511,11 @@ itemize_shape_and_place (PangoFont *font,
SCRIPT_STATE state;
SCRIPT_ITEM items[100];
double scale = pango_win32_font_get_metrics_factor (font);
+ HFONT hfont = _pango_win32_font_get_hfont (font);
+ static GHashTable *script_cache_hash = NULL;
+
+ if (!script_cache_hash)
+ script_cache_hash = g_hash_table_new (g_int64_hash, g_int64_equal);
memset (&control, 0, sizeof (control));
memset (&state, 0, sizeof (state));
@@ -556,9 +562,11 @@ itemize_shape_and_place (PangoFont *font,
int advances[1000];
GOFFSET offsets[1000];
ABC abc;
- int script = items[item].a.eScript;
+ gint32 script = items[item].a.eScript;
int ng;
int char_offset;
+ SCRIPT_CACHE *script_cache;
+ gint64 font_and_script_key;
memset (advances, 0, sizeof (advances));
memset (offsets, 0, sizeof (offsets));
@@ -584,9 +592,33 @@ itemize_shape_and_place (PangoFont *font,
items[item].a.fNoGlyphIndex ? " fNoGlyphIndex" : "",
items[item].iCharPos, items[item+1].iCharPos-1, itemlen);
#endif
+ /* Create a hash key based on hfont and script engine */
+ font_and_script_key = (((gint64) ((gint32) hfont)) << 32) | script;
+
+ /* Get the script cache for this hfont and script */
+ script_cache = g_hash_table_lookup (script_cache_hash, &font_and_script_key);
+ if (!script_cache)
+ {
+ gint64 *key_n;
+ SCRIPT_CACHE *new_script_cache;
+
+ key_n = g_new (gint64, 1);
+ *key_n = font_and_script_key;
+
+ new_script_cache = g_new0 (SCRIPT_CACHE, 1);
+ script_cache = new_script_cache;
+
+ /* Insert the new value */
+ g_hash_table_insert (script_cache_hash, key_n, new_script_cache);
+
+#ifdef BASIC_WIN32_DEBUGGING
+ if (pango_win32_debug)
+ g_print (" New SCRIPT_CACHE for font %p and script %d\n", hfont, script);
+#endif
+ }
items[item].a.fRTL = analysis->level % 2;
- if ((*script_shape) (hdc, &script_cache[script],
+ if ((*script_shape) (hdc, script_cache,
wtext + items[item].iCharPos, itemlen,
G_N_ELEMENTS (iglyphs),
&items[item].a,
@@ -616,7 +648,7 @@ itemize_shape_and_place (PangoFont *font,
nglyphs, glyphs->log_clusters + ng,
char_offset);
- if ((*script_place) (hdc, &script_cache[script], iglyphs, nglyphs,
+ if ((*script_place) (hdc, script_cache, iglyphs, nglyphs,
visattrs, &items[item].a,
advances, offsets, &abc))
{
@@ -676,9 +708,7 @@ uniscribe_shape (PangoFont *font,
{
wchar_t *wtext;
long wlen;
- int i;
gboolean retval = TRUE;
- SCRIPT_CACHE script_cache[100];
if (!pango_win32_font_select_font (font, hdc))
return FALSE;
@@ -689,11 +719,7 @@ uniscribe_shape (PangoFont *font,
if (retval)
{
- memset (script_cache, 0, sizeof (script_cache));
- retval = itemize_shape_and_place (font, hdc, wtext, wlen, analysis, glyphs, script_cache);
- for (i = 0; i < G_N_ELEMENTS (script_cache); i++)
- if (script_cache[i])
- (*script_free_cache)(&script_cache[i]);
+ retval = itemize_shape_and_place (font, hdc, wtext, wlen, analysis, glyphs);
}
if (retval)