summaryrefslogtreecommitdiff
path: root/pango/pangowin32-fontcache.c
diff options
context:
space:
mode:
authorTor Lillqvist <tml@novell.com>2007-02-27 09:08:07 +0000
committerTor Lillqvist <tml@src.gnome.org>2007-02-27 09:08:07 +0000
commit1731f6a91c35ec595480d079a792951bfd83d6b4 (patch)
tree627a54fc3e2b690b226e745ff1b899de22673087 /pango/pangowin32-fontcache.c
parent9e66ba61aaf08836f58448506339ca69d02764a7 (diff)
downloadpango-1731f6a91c35ec595480d079a792951bfd83d6b4.tar.gz
This change was supposed to go in the trunk before 1.16.0, but it didn't
2007-02-26 Tor Lillqvist <tml@novell.com> This change was supposed to go in the trunk before 1.16.0, but it didn't quite get there in time. So, to have a clear cut for this somewhat fundamental change in underlying workings (although there should be no user-visible changes), I will build and distribute Win32 binaries only starting from 1.16.1. Use wide character API for fonts on Windows. Rename functions and variables that deal with LOGFONTW structs to emphasize this. (#407315) * pango/pangowin32.c * pango/pangowin32-fontcache.c * pango/pangowin32-fontmap.c: Use LOGFONTW all over the place instead of LOGFONT, and adapt code accordingly. Use wide character Win32 API. * pango/pangowin32.c (pango_win32_font_neww): Renamed from pango_win32_font_new(), as it now takes a LOGFONTW pointer. This is a private function and can be renamed though it is exported as it is used from the pangocairo DLL. (pango_win32_font_logfont): Mention explicitly in doc comment that it returns a LOGFONTA, and recommend to use pango_win32_font_logfontw() instead. (pango_win32_font_logfontw): New function. * pango/pangowin32-fontcache.c (pango_win32_font_cache_load): Must keep this function that takes a LOGFONTA pointer as it is declared in the public header. (pango_win32_font_cache_loadw): New public function that takes a LOGFONTW pointer. * pango/pangowin32-fontmap.c (pango_win32_font_description_from_logfont): Mention explicitly in the doc comment that it takes a LOGFONTA pointer. (pango_win32_font_description_from_logfontw): New public function that takes a LOGFONTW pointer. (pango_win32_make_matching_logfontw): Rename from pango_win32_make_matching_logfont() to emphasize it takes a LOGFONTW pointer. * pango/pangowin32.h: Declare new public functions. * pango/pangowin32-private.h: Declare new private functions, drop removed ones. * pango/pangocairo-win32font.c (_pango_cairo_win32_font_new): Simplify now that we call pango_win32_make_matching_logfontw(). * pango/pangowin32.def: Add new functions, rename internal functions that now use LOGFONTW. 2007-02-26 Tor Lillqvist <tml@novell.com> Fix brokenness in the code that tries to ensure that all fonts also have italic variants. Now the code hopefully actually does what it was supposed to. (Which is not necessarily the right thing to do, though. It can be argued that we should not list synthesized italic font styles, we should just silently generate them if asked for. We don't want synthesized italic (or synthesized bold) styles showing up in the font selector. They don't show up when using a fontconfig-based Pango backend either.) (#110521) * pango/pangowin32-fontmap.c (logfont_nosize_hash, logfont_nosize_equal): Don't use the lfItalic field as such, just its nonzeroness. When being enumerated, italic fonts show up with lfItalic=255, but our code looks up italic versions of fonts by passing a key LOGFONT with lfItalic=1. (first_match): Not needed any more, see below. (ensure_italic): This is now called on the entries in the size_infos hash table, not families. The code used to randomly look for the first matching font in size_infoswith the family name being handled. (pango_win32_font_map_init): Iterate through the size_infos hash table with ensure_italic, not through the families table. * pango/pangowin32-fontcache.c (logfontw_hash, logfontw_equal): Look at just nonzeroness of lfItalic here, too. svn path=/trunk/; revision=2204
Diffstat (limited to 'pango/pangowin32-fontcache.c')
-rw-r--r--pango/pangowin32-fontcache.c141
1 files changed, 98 insertions, 43 deletions
diff --git a/pango/pangowin32-fontcache.c b/pango/pangowin32-fontcache.c
index 96005e59..88d2bc0c 100644
--- a/pango/pangowin32-fontcache.c
+++ b/pango/pangowin32-fontcache.c
@@ -1,8 +1,9 @@
/* Pango
- * pangowin32-fontcache.c: Cache of HFONTs by LOGFONT
+ * pangowin32-fontcache.c: Cache of HFONTs by LOGFONTW
*
* Copyright (C) 2000 Red Hat Software
* Copyright (C) 2000 Tor Lillqvist
+ * Copyright (C) 2007 Novell, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -46,15 +47,15 @@ struct _PangoWin32FontCache
struct _CacheEntry
{
- LOGFONT logfont;
- HFONT hfont;
+ LOGFONTW logfontw;
+ HFONT hfont;
gint ref_count;
GList *mru;
};
static void
-free_cache_entry (LOGFONT *logfont,
+free_cache_entry (LOGFONTW *logfont,
CacheEntry *entry,
PangoWin32FontCache *cache)
{
@@ -87,28 +88,42 @@ pango_win32_font_cache_free (PangoWin32FontCache *cache)
}
static guint
-logfont_hash (gconstpointer v)
+wcs_hash (gconstpointer v)
+{
+ /* 31 bit hash function */
+ const wchar_t *p = v;
+ guint32 h = *p;
+
+ if (h)
+ for (p += 1; *p != '\0'; p++)
+ h = (h << 5) - h + *p;
+
+ return h;
+}
+
+static guint
+logfontw_hash (gconstpointer v)
{
- const LOGFONT *lfp = v;
+ const LOGFONTW *lfp = v;
- return g_str_hash (lfp->lfFaceName) +
- lfp->lfItalic +
+ return wcs_hash (lfp->lfFaceName) +
+ (lfp->lfItalic != 0) +
lfp->lfWeight/10 +
lfp->lfOrientation +
abs (lfp->lfHeight) * 10;
}
static gint
-logfont_equal (gconstpointer v1,
- gconstpointer v2)
+logfontw_equal (gconstpointer v1,
+ gconstpointer v2)
{
- const LOGFONT *lfp1 = v1, *lfp2 = v2;
+ const LOGFONTW *lfp1 = v1, *lfp2 = v2;
- return (strcmp (lfp1->lfFaceName, lfp2->lfFaceName) == 0
+ return (wcscmp (lfp1->lfFaceName, lfp2->lfFaceName) == 0
&& lfp1->lfPitchAndFamily == lfp2->lfPitchAndFamily
&& lfp1->lfStrikeOut == lfp2->lfStrikeOut
&& lfp1->lfUnderline == lfp2->lfUnderline
- && lfp1->lfItalic == lfp2->lfItalic
+ && (lfp1->lfItalic != 0) == (lfp2->lfItalic != 0)
&& lfp1->lfWeight == lfp2->lfWeight
&& lfp1->lfOrientation == lfp2->lfOrientation
&& lfp1->lfEscapement == lfp2->lfEscapement
@@ -131,7 +146,7 @@ pango_win32_font_cache_new (void)
cache = g_slice_new (PangoWin32FontCache);
- cache->forward = g_hash_table_new (logfont_hash, logfont_equal);
+ cache->forward = g_hash_table_new (logfontw_hash, logfontw_equal);
cache->back = g_hash_table_new (g_direct_hash, g_direct_equal);
cache->mru = NULL;
@@ -150,7 +165,7 @@ cache_entry_unref (PangoWin32FontCache *cache,
{
PING (("removing cache entry %p", entry->hfont));
- g_hash_table_remove (cache->forward, &entry->logfont);
+ g_hash_table_remove (cache->forward, &entry->logfontw);
g_hash_table_remove (cache->back, entry->hfont);
free_cache_entry (NULL, entry, cache);
@@ -160,9 +175,9 @@ cache_entry_unref (PangoWin32FontCache *cache,
/**
* pango_win32_font_cache_load:
* @cache: a #PangoWin32FontCache
- * @logfont: a pointer to a LOGFONT structure describing the font to load.
+ * @logfont: a pointer to a LOGFONTA structure describing the font to load.
*
- * Creates a HFONT from a LOGFONT. The
+ * Creates a HFONT from a LOGFONTA. The
* result may be newly loaded, or it may have been previously
* stored
*
@@ -172,10 +187,42 @@ cache_entry_unref (PangoWin32FontCache *cache,
**/
HFONT
pango_win32_font_cache_load (PangoWin32FontCache *cache,
- const LOGFONT *lfp)
+ const LOGFONTA *lfp)
+{
+ LOGFONTW lf;
+
+ /* We know that the lfFaceName is the last member in the structs */
+ *(LOGFONTA *)&lf = *lfp;
+
+ if (!MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
+ lfp->lfFaceName, -1,
+ lf.lfFaceName, G_N_ELEMENTS (lf.lfFaceName)))
+ return NULL;
+
+ return pango_win32_font_cache_loadw (cache, &lf);
+}
+
+/**
+ * pango_win32_font_cache_loadw:
+ * @cache: a #PangoWin32FontCache
+ * @logfont: a pointer to a LOGFONTW structure describing the font to load.
+ *
+ * Creates a HFONT from a LOGFONTW. The
+ * result may be newly loaded, or it may have been previously
+ * stored
+ *
+ * Return value: The font structure, or %NULL if the font could
+ * not be loaded. In order to free this structure, you must call
+ * pango_win32_font_cache_unload().
+ *
+ * Since: 1.16
+ **/
+HFONT
+pango_win32_font_cache_loadw (PangoWin32FontCache *cache,
+ const LOGFONTW *lfp)
{
CacheEntry *entry;
- LOGFONT lf;
+ LOGFONTW lf;
HFONT hfont;
int tries;
@@ -229,14 +276,14 @@ pango_win32_font_cache_load (PangoWin32FontCache *cache,
"height=%ld,width=%ld,escapement=%ld,orientation=%ld,"
"weight=%ld,%s%s%s"
"charset=%d,outprecision=%d,clipprecision=%d,"
- "quality=%d,pitchandfamily=%#.02x,facename=\"%s\")",
+ "quality=%d,pitchandfamily=%#.02x,facename=\"%S\")",
lf.lfHeight, lf.lfWidth, lf.lfEscapement, lf.lfOrientation,
lf.lfWeight, (lf.lfItalic ? "italic," : ""),
(lf.lfUnderline ? "underline," : ""),
(lf.lfStrikeOut ? "strikeout," : ""),
lf.lfCharSet, lf.lfOutPrecision, lf.lfClipPrecision,
lf.lfQuality, lf.lfPitchAndFamily, lf.lfFaceName));
- hfont = CreateFontIndirect (&lf);
+ hfont = CreateFontIndirectW (&lf);
if (hfont != NULL)
{
@@ -247,42 +294,50 @@ pango_win32_font_cache_load (PangoWin32FontCache *cache,
/* If we fail, try some similar fonts often found on Windows. */
if (tries == 0)
{
- if (g_ascii_strcasecmp (lf.lfFaceName, "helvetica") == 0)
- strcpy (lf.lfFaceName, "arial");
- else if (g_ascii_strcasecmp (lf.lfFaceName, "new century schoolbook") == 0)
- strcpy (lf.lfFaceName, "century schoolbook");
- else if (g_ascii_strcasecmp (lf.lfFaceName, "courier") == 0)
- strcpy (lf.lfFaceName, "courier new");
- else if (g_ascii_strcasecmp (lf.lfFaceName, "lucida") == 0)
- strcpy (lf.lfFaceName, "lucida sans unicode");
- else if (g_ascii_strcasecmp (lf.lfFaceName, "lucidatypewriter") == 0)
- strcpy (lf.lfFaceName, "lucida console");
- else if (g_ascii_strcasecmp (lf.lfFaceName, "times") == 0)
- strcpy (lf.lfFaceName, "times new roman");
+ gchar *p = g_utf16_to_utf8 (lf.lfFaceName, -1, NULL, NULL, NULL);
+ if (!p)
+ ; /* Nothing */
+ else if (g_ascii_strcasecmp (p, "helvetica") == 0)
+ wcscpy (lf.lfFaceName, L"arial");
+ else if (g_ascii_strcasecmp (p, "new century schoolbook") == 0)
+ wcscpy (lf.lfFaceName, L"century schoolbook");
+ else if (g_ascii_strcasecmp (p, "courier") == 0)
+ wcscpy (lf.lfFaceName, L"courier new");
+ else if (g_ascii_strcasecmp (p, "lucida") == 0)
+ wcscpy (lf.lfFaceName, L"lucida sans unicode");
+ else if (g_ascii_strcasecmp (p, "lucidatypewriter") == 0)
+ wcscpy (lf.lfFaceName, L"lucida console");
+ else if (g_ascii_strcasecmp (p, "times") == 0)
+ wcscpy (lf.lfFaceName, L"times new roman");
+ g_free (p);
}
else if (tries == 1)
{
- if (g_ascii_strcasecmp (lf.lfFaceName, "courier") == 0)
+ gchar *p = g_utf16_to_utf8 (lf.lfFaceName, -1, NULL, NULL, NULL);
+ if (!p)
+ ; /* Nothing */
+ else if (g_ascii_strcasecmp (p, "courier") == 0)
{
- strcpy (lf.lfFaceName, "");
+ wcscpy (lf.lfFaceName, L"");
lf.lfPitchAndFamily |= FF_MODERN;
}
- else if (g_ascii_strcasecmp (lf.lfFaceName, "times new roman") == 0)
+ else if (g_ascii_strcasecmp (p, "times new roman") == 0)
{
- strcpy (lf.lfFaceName, "");
+ wcscpy (lf.lfFaceName, L"");
lf.lfPitchAndFamily |= FF_ROMAN;
}
- else if (g_ascii_strcasecmp (lf.lfFaceName, "helvetica") == 0
- || g_ascii_strcasecmp (lf.lfFaceName, "lucida") == 0)
+ else if (g_ascii_strcasecmp (p, "helvetica") == 0
+ || g_ascii_strcasecmp (p, "lucida") == 0)
{
- strcpy (lf.lfFaceName, "");
+ wcscpy (lf.lfFaceName, L"");
lf.lfPitchAndFamily |= FF_SWISS;
}
else
{
- strcpy (lf.lfFaceName, "");
+ wcscpy (lf.lfFaceName, L"");
lf.lfPitchAndFamily = (lf.lfPitchAndFamily & 0x0F) | FF_DONTCARE;
}
+ g_free (p);
}
else
break;
@@ -294,13 +349,13 @@ pango_win32_font_cache_load (PangoWin32FontCache *cache,
entry = g_slice_new (CacheEntry);
- entry->logfont = lf;
+ entry->logfontw = lf;
entry->hfont = hfont;
entry->ref_count = 1;
entry->mru = NULL;
- g_hash_table_insert (cache->forward, &entry->logfont, entry);
+ g_hash_table_insert (cache->forward, &entry->logfontw, entry);
g_hash_table_insert (cache->back, entry->hfont, entry);
}