summaryrefslogtreecommitdiff
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
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
-rw-r--r--ChangeLog82
-rw-r--r--pango/pangocairo-win32font.c23
-rw-r--r--pango/pangowin32-fontcache.c141
-rw-r--r--pango/pangowin32-fontmap.c458
-rw-r--r--pango/pangowin32-private.h16
-rw-r--r--pango/pangowin32.c66
-rw-r--r--pango/pangowin32.def6
-rw-r--r--pango/pangowin32.h11
8 files changed, 590 insertions, 213 deletions
diff --git a/ChangeLog b/ChangeLog
index 47559ee9..a0f0b66e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,85 @@
+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.
+
2007-02-26 Behdad Esfahbod <behdad@gnome.org>
* === Released 1.16.0 ===
diff --git a/pango/pangocairo-win32font.c b/pango/pangocairo-win32font.c
index edfce056..4710c3ff 100644
--- a/pango/pangocairo-win32font.c
+++ b/pango/pangocairo-win32font.c
@@ -84,20 +84,7 @@ pango_cairo_win32_font_get_font_face (PangoCairoFont *font)
if (cwfont->font_face == NULL)
{
- LOGFONTW logfontw;
-
- /* Count here on the fact that all the struct fields are the
- * same for LOGFONTW and LOGFONTA except lfFaceName which is the
- * last field
- */
- memcpy (&logfontw, &win32font->logfont, sizeof (LOGFONTA));
-
- if (!MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
- win32font->logfont.lfFaceName, -1,
- logfontw.lfFaceName, G_N_ELEMENTS (logfontw.lfFaceName)))
- logfontw.lfFaceName[0] = 0; /* Hopefully this will select some font */
-
- cwfont->font_face = cairo_win32_font_face_create_for_logfontw (&logfontw);
+ cwfont->font_face = cairo_win32_font_face_create_for_logfontw (&win32font->logfontw);
/* Failure of the above should only occur for out of memory,
* we can't proceed at that point
@@ -544,10 +531,10 @@ _pango_cairo_win32_font_new (PangoCairoWin32FontMap *cwfontmap,
else
cairo_matrix_init_identity (&cwfont->ctm);
- pango_win32_make_matching_logfont (win32font->fontmap,
- &face->logfont,
- win32font->size,
- &win32font->logfont);
+ pango_win32_make_matching_logfontw (win32font->fontmap,
+ &face->logfontw,
+ win32font->size,
+ &win32font->logfontw);
cwfont->options = cairo_font_options_copy (_pango_cairo_context_get_merged_font_options (context));
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);
}
diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c
index facaf25e..2f98d453 100644
--- a/pango/pangowin32-fontmap.c
+++ b/pango/pangowin32-fontmap.c
@@ -4,6 +4,7 @@
* Copyright (C) 2000 Red Hat Software
* Copyright (C) 2000 Tor Lillqvist
* Copyright (C) 2001 Alexander Larsson
+ * 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
@@ -52,7 +53,7 @@ struct _PangoWin32Family
struct _PangoWin32SizeInfo
{
- GSList *logfonts;
+ GSList *logfontws;
};
#define PANGO_WIN32_TYPE_FAMILY (pango_win32_family_get_type ())
@@ -75,18 +76,18 @@ static PangoFont *pango_win32_font_map_load_font (PangoFontMap
PangoContext *context,
const PangoFontDescription *description);
static void pango_win32_font_map_list_families (PangoFontMap *fontmap,
- PangoFontFamily ***families,
- int *n_families);
+ PangoFontFamily ***families,
+ int *n_families);
-static PangoFont *pango_win32_font_map_real_find_font (PangoWin32FontMap *win32fontmap,
- PangoContext *context,
- PangoWin32Face *face,
- const PangoFontDescription *description);
+static PangoFont *pango_win32_font_map_real_find_font (PangoWin32FontMap *win32fontmap,
+ PangoContext *context,
+ PangoWin32Face *face,
+ const PangoFontDescription *description);
static void pango_win32_fontmap_cache_clear (PangoWin32FontMap *win32fontmap);
static void pango_win32_insert_font (PangoWin32FontMap *fontmap,
- LOGFONT *lfp);
+ LOGFONTW *lfp);
static PangoWin32FontMap *default_fontmap = NULL;
@@ -96,7 +97,7 @@ G_DEFINE_TYPE (PangoWin32FontMap, pango_win32_font_map, PANGO_TYPE_FONT_MAP)
(((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))
static guint
-case_insensitive_hash (const char *key)
+case_insensitive_str_hash (const char *key)
{
const char *p = key;
guint h = TOLOWER (*p);
@@ -111,37 +112,63 @@ case_insensitive_hash (const char *key)
}
static gboolean
-case_insensitive_equal (const char *key1,
- const char *key2)
+case_insensitive_str_equal (const char *key1,
+ const char *key2)
{
- return (g_ascii_strcasecmp (key1, key2) == 0);
+ while (*key1 && *key2 && TOLOWER (*key1) == TOLOWER (*key2))
+ key1++, key2++;
+ return (!*key1 && !*key2);
}
-/* A hash function for LOGFONTs that takes into consideration only
+static guint
+case_insensitive_wcs_hash (const wchar_t *key)
+{
+ const wchar_t *p = key;
+ guint h = TOLOWER (*p);
+
+ if (h)
+ {
+ for (p += 1; *p != '\0'; p++)
+ h = (h << 5) - h + TOLOWER (*p);
+ }
+
+ return h;
+}
+
+static gboolean
+case_insensitive_wcs_equal (const wchar_t *key1,
+ const wchar_t *key2)
+{
+ while (*key1 && *key2 && TOLOWER (*key1) == TOLOWER (*key2))
+ key1++, key2++;
+ return (!*key1 && !*key2);
+}
+
+/* A hash function for LOGFONTWs that takes into consideration only
* those fields that indicate a specific .ttf file is in use:
* lfFaceName, lfItalic and lfWeight. Dunno how correct this is.
*/
static guint
-logfont_nosize_hash (const LOGFONT *lfp)
+logfontw_nosize_hash (const LOGFONTW *lfp)
{
- return case_insensitive_hash (lfp->lfFaceName) + lfp->lfItalic + lfp->lfWeight;
+ return case_insensitive_wcs_hash (lfp->lfFaceName) + (lfp->lfItalic != 0) + lfp->lfWeight;
}
/* Ditto comparison function */
static gboolean
-logfont_nosize_equal (const LOGFONT *lfp1,
- const LOGFONT *lfp2)
+logfontw_nosize_equal (const LOGFONTW *lfp1,
+ const LOGFONTW *lfp2)
{
- return (case_insensitive_equal (lfp1->lfFaceName, lfp2->lfFaceName)
- && lfp1->lfItalic == lfp2->lfItalic
+ return (case_insensitive_wcs_equal (lfp1->lfFaceName, lfp2->lfFaceName)
+ && (lfp1->lfItalic != 0) == (lfp2->lfItalic != 0)
&& lfp1->lfWeight == lfp2->lfWeight);
}
static int CALLBACK
-pango_win32_inner_enum_proc (LOGFONT *lfp,
- TEXTMETRIC *metrics,
- DWORD fontType,
- LPARAM lParam)
+pango_win32_inner_enum_proc (LOGFONTW *lfp,
+ TEXTMETRICW *metrics,
+ DWORD fontType,
+ LPARAM lParam)
{
PangoWin32FontMap *win32fontmap = (PangoWin32FontMap *)lParam;
@@ -155,41 +182,27 @@ pango_win32_inner_enum_proc (LOGFONT *lfp,
}
static int CALLBACK
-pango_win32_enum_proc (LOGFONT *lfp,
- TEXTMETRIC *metrics,
- DWORD fontType,
- LPARAM lParam)
+pango_win32_enum_proc (LOGFONTW *lfp,
+ TEXTMETRICW *metrics,
+ DWORD fontType,
+ LPARAM lParam)
{
- LOGFONT lf;
+ LOGFONTW lf;
- PING(("%s", lfp->lfFaceName));
+ PING(("%S", lfp->lfFaceName));
if (fontType != TRUETYPE_FONTTYPE)
return 1;
lf = *lfp;
- EnumFontFamiliesExA (pango_win32_hdc, &lf,
- (FONTENUMPROC) pango_win32_inner_enum_proc,
+ EnumFontFamiliesExW (pango_win32_hdc, &lf,
+ (FONTENUMPROCW) pango_win32_inner_enum_proc,
lParam, 0);
return 1;
}
-static gboolean
-first_match (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- LOGFONT *lfp = (LOGFONT *)key;
- LOGFONT *lfp2 = (LOGFONT *)((PangoWin32SizeInfo *)value)->logfonts->data;
- gchar *name = (gchar *)user_data;
-
- if (strcmp (lfp->lfFaceName, name) == 0 && lfp->lfWeight == lfp2->lfWeight)
- return TRUE;
- return FALSE;
-}
-
typedef struct _ItalicHelper
{
PangoWin32FontMap *fontmap;
@@ -202,42 +215,41 @@ ensure_italic (gpointer key,
gpointer user_data)
{
ItalicHelper *helper = (ItalicHelper *)user_data;
- /* PangoWin32Family *win32family = (PangoWin32Family *)value; */
+ PangoWin32SizeInfo *sip = (PangoWin32SizeInfo *) value;
+ GSList *list = sip->logfontws;
- PangoWin32SizeInfo *sip = (PangoWin32SizeInfo *)g_hash_table_find (helper->fontmap->size_infos, first_match, key);
- if (sip)
+ while (list)
{
- GSList *list = sip->logfonts;
-
- while (list)
+ LOGFONTW *lfp = (LOGFONTW *) list->data;
+ PING(("%S it=%d wt=%ld", lfp->lfFaceName, lfp->lfItalic, lfp->lfWeight));
+ if (!lfp->lfItalic)
{
- LOGFONT *lfp = (LOGFONT *)list->data;
- if (!lfp->lfItalic)
+ /* we have a non italic variant, look if there is an italic */
+ LOGFONTW logfontw = *lfp;
+ logfontw.lfItalic = 1;
+ sip = (PangoWin32SizeInfo *) g_hash_table_lookup (helper->fontmap->size_infos, &logfontw);
+ if (!sip)
{
- /* we have a non italic variant, look if there is an italic */
- LOGFONT logfont = *lfp;
- logfont.lfItalic = 1;
- sip = (PangoWin32SizeInfo *)g_hash_table_find (helper->fontmap->size_infos, first_match, &logfont);
- if (!sip)
- {
- /* remember the non italic variant to be added later as italic */
- helper->list = g_slist_append (helper->list, lfp);
- }
+ /* remember the non italic variant to be added later as italic */
+ PING(("synthesizing italic"));
+ helper->list = g_slist_append (helper->list, lfp);
}
- list = list->next;
}
+ list = list->next;
}
}
static void
pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
{
- LOGFONT logfont;
+ LOGFONTW logfont;
+ ItalicHelper helper = { win32fontmap, NULL };
+ GSList *list;
- win32fontmap->families = g_hash_table_new ((GHashFunc) case_insensitive_hash,
- (GEqualFunc) case_insensitive_equal);
+ win32fontmap->families = g_hash_table_new ((GHashFunc) case_insensitive_str_hash,
+ (GEqualFunc) case_insensitive_str_equal);
win32fontmap->size_infos =
- g_hash_table_new ((GHashFunc) logfont_nosize_hash, (GEqualFunc) logfont_nosize_equal);
+ g_hash_table_new ((GHashFunc) logfontw_nosize_hash, (GEqualFunc) logfontw_nosize_equal);
win32fontmap->n_fonts = 0;
win32fontmap->font_cache = pango_win32_font_cache_new ();
@@ -245,26 +257,23 @@ pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
memset (&logfont, 0, sizeof (logfont));
logfont.lfCharSet = DEFAULT_CHARSET;
- EnumFontFamiliesExA (pango_win32_hdc, &logfont, (FONTENUMPROC) pango_win32_enum_proc,
- (LPARAM)win32fontmap, 0);
-
- /* create synthetic italic entries */
- {
- ItalicHelper helper = { win32fontmap, NULL };
- GSList *list;
-
- g_hash_table_foreach (win32fontmap->families, ensure_italic, &helper);
- /* cant modify while iterating */
- list = helper.list;
- while (list)
- {
- LOGFONT logfont = *((LOGFONT *)list->data);
- logfont.lfItalic = 1;
- pango_win32_insert_font (win32fontmap, &logfont);
- list = list->next;
- }
- g_slist_free (helper.list);
- }
+ EnumFontFamiliesExW (pango_win32_hdc, &logfont,
+ (FONTENUMPROCW) pango_win32_enum_proc,
+ (LPARAM) win32fontmap, 0);
+
+ /* Create synthetic italic entries */
+ g_hash_table_foreach (win32fontmap->size_infos, ensure_italic, &helper);
+
+ /* Can't modify while iterating */
+ list = helper.list;
+ while (list)
+ {
+ LOGFONTW logfontw = *((LOGFONTW *)list->data);
+ logfontw.lfItalic = 1;
+ pango_win32_insert_font (win32fontmap, &logfontw);
+ list = list->next;
+ }
+ g_slist_free (helper.list);
win32fontmap->resolution = (PANGO_SCALE / (double) GetDeviceCaps (pango_win32_hdc, LOGPIXELSY)) * 72.0;
}
@@ -540,7 +549,7 @@ pango_win32_font_map_real_find_font (PangoWin32FontMap *win32fontmap,
if (pango_font_description_get_size_is_absolute (description))
size = (int) 0.5 + (size * win32fontmap->resolution) / PANGO_SCALE;
- PING(("got best match:%s size=%d",face->logfont.lfFaceName,size));
+ PING(("got best match:%S size=%d",face->logfontw.lfFaceName,size));
while (tmp_list)
{
@@ -558,7 +567,7 @@ pango_win32_font_map_real_find_font (PangoWin32FontMap *win32fontmap,
tmp_list = tmp_list->next;
}
- win32font = pango_win32_font_new (fontmap, &face->logfont, size);
+ win32font = pango_win32_font_neww (fontmap, &face->logfontw, size);
if (!win32font)
return NULL;
@@ -571,7 +580,7 @@ pango_win32_font_map_real_find_font (PangoWin32FontMap *win32fontmap,
}
static gchar *
-get_family_name (const LOGFONT *lfp)
+get_family_nameA (const LOGFONTA *lfp)
{
HFONT hfont;
HFONT oldhfont;
@@ -696,13 +705,13 @@ get_family_name (const LOGFONT *lfp)
/**
* pango_win32_font_description_from_logfont:
- * @lfp: a LOGFONT
+ * @lfp: a LOGFONTA
*
- * Creates a #PangoFontDescription that matches the specified LOGFONT.
+ * Creates a #PangoFontDescription that matches the specified LOGFONTA.
*
- * The face name, italicness and weight fields in the LOGFONT are used
+ * The face name, italicness and weight fields in the LOGFONTA are used
* to set up the resulting #PangoFontDescription. If the face name in
- * the LOGFONT contains non-ASCII characters the font is temporarily
+ * the LOGFONTA contains non-ASCII characters the font is temporarily
* loaded (using CreateFontIndirect()) and an ASCII (usually English)
* name for it is looked up from the font name tables in the font
* data. If that doesn't work, the face name is converted from the
@@ -723,7 +732,201 @@ pango_win32_font_description_from_logfont (const LOGFONT *lfp)
PangoWeight weight;
PangoStretch stretch;
- family = get_family_name (lfp);
+ family = get_family_nameA (lfp);
+
+ if (!lfp->lfItalic)
+ style = PANGO_STYLE_NORMAL;
+ else
+ style = PANGO_STYLE_ITALIC;
+
+ variant = PANGO_VARIANT_NORMAL;
+
+ /* The PangoWeight values PANGO_WEIGHT_* map exactly do Windows FW_*
+ * values. Is this on purpose? Quantize the weight to exact
+ * PANGO_WEIGHT_* values. Is this a good idea?
+ */
+ if (lfp->lfWeight == FW_DONTCARE)
+ weight = PANGO_WEIGHT_NORMAL;
+ else if (lfp->lfWeight <= (FW_ULTRALIGHT + FW_LIGHT) / 2)
+ weight = PANGO_WEIGHT_ULTRALIGHT;
+ else if (lfp->lfWeight <= (FW_LIGHT + FW_NORMAL) / 2)
+ weight = PANGO_WEIGHT_LIGHT;
+ else if (lfp->lfWeight <= (FW_NORMAL + FW_BOLD) / 2)
+ weight = PANGO_WEIGHT_NORMAL;
+ else if (lfp->lfWeight <= (FW_BOLD + FW_ULTRABOLD) / 2)
+ weight = PANGO_WEIGHT_BOLD;
+ else if (lfp->lfWeight <= (FW_ULTRABOLD + FW_HEAVY) / 2)
+ weight = PANGO_WEIGHT_ULTRABOLD;
+ else
+ weight = PANGO_WEIGHT_HEAVY;
+
+ /* XXX No idea how to figure out the stretch */
+ stretch = PANGO_STRETCH_NORMAL;
+
+ description = pango_font_description_new ();
+ pango_font_description_set_family (description, family);
+ pango_font_description_set_style (description, style);
+ pango_font_description_set_weight (description, weight);
+ pango_font_description_set_stretch (description, stretch);
+ pango_font_description_set_variant (description, variant);
+
+ return description;
+}
+
+static gchar *
+get_family_nameW (const LOGFONTW *lfp)
+{
+ HFONT hfont;
+ HFONT oldhfont;
+
+ struct name_header header;
+ struct name_record record;
+
+ gint unicode_ix = -1, mac_ix = -1, microsoft_ix = -1;
+ gint name_ix;
+ gchar *codeset;
+
+ gchar *string = NULL;
+ gchar *name;
+
+ gint i, l;
+ gsize nbytes;
+
+ /* If lfFaceName is ASCII, assume it is the common (English) name
+ * for the font. Is this valid? Do some TrueType fonts have
+ * different names in French, German, etc, and does the system
+ * return these if the locale is set to use French, German, etc?
+ */
+ l = wcslen (lfp->lfFaceName);
+ for (i = 0; i < l; i++)
+ if (lfp->lfFaceName[i] < ' ' || lfp->lfFaceName[i] > '~')
+ break;
+
+ if (i == l)
+ return g_utf16_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);
+
+ if ((hfont = CreateFontIndirectW (lfp)) == NULL)
+ goto fail0;
+
+ if ((oldhfont = SelectObject (pango_win32_hdc, hfont)) == NULL)
+ goto fail1;
+
+ if (!pango_win32_get_name_header (pango_win32_hdc, &header))
+ goto fail2;
+
+ PING (("%d name records", header.num_records));
+
+ for (i = 0; i < header.num_records; i++)
+ {
+ if (!pango_win32_get_name_record (pango_win32_hdc, i, &record))
+ goto fail2;
+
+ if ((record.name_id != 1 && record.name_id != 16) || record.string_length <= 0)
+ continue;
+
+ PING(("platform:%d encoding:%d language:%04x name_id:%d",
+ record.platform_id, record.encoding_id, record.language_id, record.name_id));
+
+ if (record.platform_id == APPLE_UNICODE_PLATFORM_ID ||
+ record.platform_id == ISO_PLATFORM_ID)
+ unicode_ix = i;
+ else if (record.platform_id == MACINTOSH_PLATFORM_ID &&
+ record.encoding_id == 0 && /* Roman */
+ record.language_id == 0) /* English */
+ mac_ix = i;
+ else if (record.platform_id == MICROSOFT_PLATFORM_ID)
+ if ((microsoft_ix == -1 ||
+ PRIMARYLANGID (record.language_id) == LANG_ENGLISH) &&
+ (record.encoding_id == SYMBOL_ENCODING_ID ||
+ record.encoding_id == UNICODE_ENCODING_ID ||
+ record.encoding_id == UCS4_ENCODING_ID))
+ microsoft_ix = i;
+ }
+
+ if (microsoft_ix >= 0)
+ name_ix = microsoft_ix;
+ else if (mac_ix >= 0)
+ name_ix = mac_ix;
+ else if (unicode_ix >= 0)
+ name_ix = unicode_ix;
+ else
+ goto fail2;
+
+ if (!pango_win32_get_name_record (pango_win32_hdc, name_ix, &record))
+ goto fail2;
+
+ string = g_malloc (record.string_length + 1);
+ if (GetFontData (pango_win32_hdc, NAME,
+ header.string_storage_offset + record.string_offset,
+ string, record.string_length) != record.string_length)
+ goto fail2;
+
+ string[record.string_length] = '\0';
+
+ if (name_ix == microsoft_ix)
+ if (record.encoding_id == SYMBOL_ENCODING_ID ||
+ record.encoding_id == UNICODE_ENCODING_ID)
+ codeset = "UTF-16BE";
+ else
+ codeset = "UCS-4BE";
+ else if (name_ix == mac_ix)
+ codeset = "MacRoman";
+ else /* name_ix == unicode_ix */
+ codeset = "UCS-4BE";
+
+ name = g_convert (string, record.string_length, "UTF-8", codeset, NULL, &nbytes, NULL);
+ if (name == NULL)
+ goto fail2;
+ g_free (string);
+
+ PING(("%s", name));
+
+ SelectObject (pango_win32_hdc, oldhfont);
+ DeleteObject (hfont);
+
+ return name;
+
+ fail2:
+ g_free (string);
+ SelectObject (pango_win32_hdc, oldhfont);
+
+ fail1:
+ DeleteObject (hfont);
+
+ fail0:
+ return g_utf16_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL);
+}
+
+/**
+ * pango_win32_font_description_from_logfontw:
+ * @lfp: a LOGFONTW
+ *
+ * Creates a #PangoFontDescription that matches the specified LOGFONTW.
+ *
+ * The face name, italicness and weight fields in the LOGFONTW are used
+ * to set up the resulting #PangoFontDescription. If the face name in
+ * the LOGFONTW contains non-ASCII characters the font is temporarily
+ * loaded (using CreateFontIndirect()) and an ASCII (usually English)
+ * name for it is looked up from the font name tables in the font
+ * data. If that doesn't work, the face name is converted from UTF-16
+ * to UTF-8 and that is used.
+ *
+ * Return value: the newly allocated #PangoFontDescription, which
+ * should be freed using pango_font_description_free()
+ *
+ * Since: 1.16
+ */
+PangoFontDescription *
+pango_win32_font_description_from_logfontw (const LOGFONTW *lfp)
+{
+ PangoFontDescription *description;
+ gchar *family;
+ PangoStyle style;
+ PangoVariant variant;
+ PangoWeight weight;
+ PangoStretch stretch;
+
+ family = get_family_nameW (lfp);
if (!lfp->lfItalic)
style = PANGO_STYLE_NORMAL;
@@ -764,24 +967,26 @@ pango_win32_font_description_from_logfont (const LOGFONT *lfp)
return description;
}
-/* This inserts the given font into the size_infos table. If a SizeInfo
- * already exists with the same typeface name, then the font is added
- * to the SizeInfos list, else a new SizeInfo is created and inserted
- * in the table.
+
+/* This inserts the given font into the size_infos table. If a
+ * SizeInfo already exists with the same typeface name, italicness and
+ * weight, then the font is added to the SizeInfo's list, else a
+ * new SizeInfo is created and inserted in the table.
*/
static void
pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
- LOGFONT *lfp)
+ LOGFONTW *lfp)
{
- LOGFONT *lfp2 = NULL;
+ LOGFONTW *lfp2 = NULL;
PangoFontDescription *description;
PangoWin32Family *font_family;
PangoWin32Face *win32face;
PangoWin32SizeInfo *size_info;
GSList *tmp_list;
gint i;
+ gchar *p;
- PING(("face=%s,charset=%d,it=%d,wt=%ld,ht=%ld",lfp->lfFaceName,lfp->lfCharSet,lfp->lfItalic,lfp->lfWeight,lfp->lfHeight));
+ PING(("face=%S,charset=%d,it=%d,wt=%ld,ht=%ld",lfp->lfFaceName,lfp->lfCharSet,lfp->lfItalic,lfp->lfWeight,lfp->lfHeight));
/* Ignore Symbol fonts (which don't have any Unicode mapping
* table). We could also be fancy and use the PostScript glyph name
@@ -791,27 +996,28 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
if (lfp->lfCharSet == SYMBOL_CHARSET)
return;
- /* First insert the LOGFONT into the list of LOGFONTs for the typeface name
+ /* First insert the LOGFONTW into the list of LOGFONTWs for the
+ * typeface name, italicness and weight.
*/
size_info = g_hash_table_lookup (win32fontmap->size_infos, lfp);
if (!size_info)
{
PING(("SizeInfo not found"));
size_info = g_new (PangoWin32SizeInfo, 1);
- size_info->logfonts = NULL;
+ size_info->logfontws = NULL;
- lfp2 = g_new (LOGFONT, 1);
+ lfp2 = g_new (LOGFONTW, 1);
*lfp2 = *lfp;
g_hash_table_insert (win32fontmap->size_infos, lfp2, size_info);
}
else
{
- /* Don't store logfonts that differ only in charset
+ /* Don't store LOGFONTWs that differ only in charset
*/
- tmp_list = size_info->logfonts;
+ tmp_list = size_info->logfontws;
while (tmp_list)
{
- LOGFONT *rover = tmp_list->data;
+ LOGFONTW *rover = tmp_list->data;
/* We know that lfWeight, lfItalic and lfFaceName match. We
* don't check lfHeight and lfWidth, those are used
@@ -832,15 +1038,15 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
if (lfp2 == NULL)
{
- lfp2 = g_new (LOGFONT, 1);
+ lfp2 = g_new (LOGFONTW, 1);
*lfp2 = *lfp;
}
- size_info->logfonts = g_slist_prepend (size_info->logfonts, lfp2);
+ size_info->logfontws = g_slist_prepend (size_info->logfontws, lfp2);
- PING(("g_slist_length(size_info->logfonts)=%d", g_slist_length(size_info->logfonts)));
+ PING(("g_slist_length(size_info->logfontws)=%d", g_slist_length(size_info->logfontws)));
- description = pango_win32_font_description_from_logfont (lfp2);
+ description = pango_win32_font_description_from_logfontw (lfp2);
/* In some cases, extracting a name for a font can fail; such fonts
* aren't usable for us
@@ -858,7 +1064,7 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
for (i = 0; i < PANGO_WIN32_N_COVERAGES; i++)
win32face->coverages[i] = NULL;
- win32face->logfont = *lfp;
+ win32face->logfontw = *lfp;
win32face->cmap_format = 0;
win32face->cmap = NULL;
@@ -905,31 +1111,33 @@ pango_win32_insert_font (PangoWin32FontMap *win32fontmap,
/* Some other magic names */
/* Recognize just "courier" for "courier new" */
- if (g_ascii_strcasecmp (win32face->logfont.lfFaceName, "courier new") == 0)
+ p = g_utf16_to_utf8 (win32face->logfontw.lfFaceName, -1, NULL, NULL, NULL);
+ if (p && g_ascii_strcasecmp (p, "courier new") == 0)
{
font_family = pango_win32_get_font_family (win32fontmap, "courier");
font_family->font_entries = g_slist_append (font_family->font_entries, win32face);
win32fontmap->n_fonts++;
}
+ g_free (p);
#endif
}
-/* Given a LOGFONT and size, make a matching LOGFONT corresponding to
+/* Given a LOGFONTW and size, make a matching LOGFONTW corresponding to
* an installed font.
*/
void
-pango_win32_make_matching_logfont (PangoFontMap *fontmap,
- const LOGFONT *lfp,
- int size,
- LOGFONT *out)
+pango_win32_make_matching_logfontw (PangoFontMap *fontmap,
+ const LOGFONTW *lfp,
+ int size,
+ LOGFONTW *out)
{
PangoWin32FontMap *win32fontmap;
GSList *tmp_list;
PangoWin32SizeInfo *size_info;
- LOGFONT *closest_match = NULL;
+ LOGFONTW *closest_match = NULL;
gint match_distance = 0;
- PING(("lfp.face=%s,wt=%ld,ht=%ld,size:%d",lfp->lfFaceName,lfp->lfWeight,lfp->lfHeight,size));
+ PING(("lfp.face=%S,wt=%ld,ht=%ld,size:%d",lfp->lfFaceName,lfp->lfWeight,lfp->lfHeight,size));
win32fontmap = PANGO_WIN32_FONT_MAP (fontmap);
size_info = g_hash_table_lookup (win32fontmap->size_infos, lfp);
@@ -940,11 +1148,11 @@ pango_win32_make_matching_logfont (PangoFontMap *fontmap,
return;
}
- tmp_list = size_info->logfonts;
+ tmp_list = size_info->logfontws;
while (tmp_list)
{
- LOGFONT *tmp_logfont = tmp_list->data;
- int font_size = abs (tmp_logfont->lfHeight);
+ LOGFONTW *tmp_logfontw = tmp_list->data;
+ int font_size = abs (tmp_logfontw->lfHeight);
if (size != -1)
{
@@ -954,7 +1162,7 @@ pango_win32_make_matching_logfont (PangoFontMap *fontmap,
new_distance < match_distance ||
(new_distance < PANGO_SCALE && font_size != 0))
{
- closest_match = tmp_logfont;
+ closest_match = tmp_logfontw;
match_distance = new_distance;
}
}
diff --git a/pango/pangowin32-private.h b/pango/pangowin32-private.h
index 504e3c24..d91452be 100644
--- a/pango/pangowin32-private.h
+++ b/pango/pangowin32-private.h
@@ -98,7 +98,7 @@ struct _PangoWin32FontMap
/* Map Pango family names to PangoWin32Family structs */
GHashTable *families;
- /* Map LOGFONTS (taking into account only the lfFaceName, lfItalic
+ /* Map LOGFONTWs (taking into account only the lfFaceName, lfItalic
* and lfWeight fields) to PangoWin32SizeInfo structs.
*/
GHashTable *size_infos;
@@ -123,7 +123,7 @@ struct _PangoWin32Font
{
PangoFont font;
- LOGFONT logfont;
+ LOGFONTW logfontw;
int size;
GSList *metrics_by_lang;
@@ -159,7 +159,7 @@ struct _PangoWin32Face
{
PangoFontFace parent_instance;
- LOGFONT logfont;
+ LOGFONTW logfontw;
PangoFontDescription *description;
PangoCoverage *coverages[PANGO_WIN32_N_COVERAGES];
char *face_name;
@@ -258,14 +258,14 @@ struct name_record
GType pango_win32_font_get_type (void);
-PangoWin32Font *pango_win32_font_new (PangoFontMap *fontmap,
- const LOGFONT *lfp,
+PangoWin32Font *pango_win32_font_neww (PangoFontMap *fontmap,
+ const LOGFONTW *lfp,
int size);
PangoMap * pango_win32_get_shaper_map (PangoLanguage *lang);
-void pango_win32_make_matching_logfont (PangoFontMap *fontmap,
- const LOGFONT *lfp,
+void pango_win32_make_matching_logfontw (PangoFontMap *fontmap,
+ const LOGFONTW *lfp,
int size,
- LOGFONT *out);
+ LOGFONTW *out);
PangoCoverage * pango_win32_font_entry_get_coverage (PangoWin32Face *face,
PangoLanguage *lang);
void pango_win32_font_entry_set_coverage (PangoWin32Face *face,
diff --git a/pango/pangowin32.c b/pango/pangowin32.c
index b34182ae..c3aabb27 100644
--- a/pango/pangowin32.c
+++ b/pango/pangowin32.c
@@ -4,6 +4,7 @@
* Copyright (C) 1999 Red Hat Software
* Copyright (C) 2000 Tor Lillqvist
* Copyright (C) 2001 Alexander Larsson
+ * 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
@@ -93,11 +94,11 @@ pango_win32_get_hfont (PangoFont *font)
{
cache = pango_win32_font_map_get_font_cache (win32font->fontmap);
- win32font->hfont = pango_win32_font_cache_load (cache, &win32font->logfont);
+ win32font->hfont = pango_win32_font_cache_loadw (cache, &win32font->logfontw);
if (!win32font->hfont)
{
- gchar *face_utf8 = g_locale_to_utf8 (win32font->logfont.lfFaceName,
- -1, NULL, NULL, NULL);
+ gchar *face_utf8 = g_utf16_to_utf8 (win32font->logfontw.lfFaceName,
+ -1, NULL, NULL, NULL);
g_warning ("Cannot load font '%s\n", face_utf8);
g_free (face_utf8);
return NULL;
@@ -216,9 +217,9 @@ pango_win32_font_class_init (PangoWin32FontClass *class)
}
PangoWin32Font *
-pango_win32_font_new (PangoFontMap *fontmap,
- const LOGFONT *lfp,
- int size)
+pango_win32_font_neww (PangoFontMap *fontmap,
+ const LOGFONTW *lfp,
+ int size)
{
PangoWin32Font *result;
@@ -231,8 +232,7 @@ pango_win32_font_new (PangoFontMap *fontmap,
g_object_ref (fontmap);
result->size = size;
- pango_win32_make_matching_logfont (fontmap, lfp, size,
- &result->logfont);
+ pango_win32_make_matching_logfontw (fontmap, lfp, size, &result->logfontw);
return result;
}
@@ -676,22 +676,60 @@ pango_win32_font_real_get_metrics_factor (PangoFont *font)
* pango_win32_font_logfont:
* @font: a #PangoFont which must be from the Win32 backend
*
- * Determine the LOGFONT struct for the specified font.
+ * Determine the LOGFONTA struct for the specified font. Note that
+ * Pango internally uses LOGFONTW structs, so if converting the UTF-16
+ * face name in the LOGFONTW struct to system codepage fails, the
+ * returned LOGFONTA will have an emppty face name. To get the
+ * LOGFONTW of a PangoFont, use pango_win32_font_logfontw(). It
+ * is recommended to do that always even if you don't expect
+ * to come across fonts with odd names.
*
- * Return value: A newly allocated LOGFONT struct. It must be
+ * Return value: A newly allocated LOGFONTA struct. It must be
* freed with g_free().
**/
-LOGFONT *
+LOGFONTA *
pango_win32_font_logfont (PangoFont *font)
{
PangoWin32Font *win32font = (PangoWin32Font *)font;
- LOGFONT *lfp;
+ LOGFONTA *lfp;
g_return_val_if_fail (font != NULL, NULL);
g_return_val_if_fail (PANGO_WIN32_IS_FONT (font), NULL);
- lfp = g_new (LOGFONT, 1);
- *lfp = win32font->logfont;
+ lfp = g_new (LOGFONTA, 1);
+
+ *lfp = *(LOGFONTA*) &win32font->logfontw;
+ if (!WideCharToMultiByte (CP_ACP, 0,
+ win32font->logfontw.lfFaceName, -1,
+ lfp->lfFaceName, G_N_ELEMENTS (lfp->lfFaceName),
+ NULL, NULL))
+ lfp->lfFaceName[0] = '\0';
+
+ return lfp;
+}
+
+/**
+ * pango_win32_font_logfontw:
+ * @font: a #PangoFont which must be from the Win32 backend
+ *
+ * Determine the LOGFONTW struct for the specified font.
+ *
+ * Return value: A newly allocated LOGFONTW struct. It must be
+ * freed with g_free().
+ *
+ *Since: 1.16
+ **/
+LOGFONTW *
+pango_win32_font_logfontw (PangoFont *font)
+{
+ PangoWin32Font *win32font = (PangoWin32Font *)font;
+ LOGFONTW *lfp;
+
+ g_return_val_if_fail (font != NULL, NULL);
+ g_return_val_if_fail (PANGO_WIN32_IS_FONT (font), NULL);
+
+ lfp = g_new (LOGFONTW, 1);
+ *lfp = win32font->logfontw;
return lfp;
}
diff --git a/pango/pangowin32.def b/pango/pangowin32.def
index 65d62c4f..0940d7d3 100644
--- a/pango/pangowin32.def
+++ b/pango/pangowin32.def
@@ -1,9 +1,11 @@
EXPORTS
pango_win32_font_cache_free
pango_win32_font_cache_load
+ pango_win32_font_cache_loadw
pango_win32_font_cache_new
pango_win32_font_cache_unload
pango_win32_font_description_from_logfont
+ pango_win32_font_description_from_logfontw
pango_win32_font_entry_get_coverage
pango_win32_font_entry_remove
pango_win32_font_get_glyph_index
@@ -12,7 +14,7 @@ EXPORTS
pango_win32_font_map_for_display
pango_win32_font_map_get_font_cache
pango_win32_font_map_get_type
- pango_win32_font_new
+ pango_win32_font_neww
pango_win32_font_logfont
pango_win32_font_done_font
pango_win32_font_get_metrics_factor
@@ -24,7 +26,7 @@ EXPORTS
pango_win32_get_debug_flag
pango_win32_get_shaper_map
pango_win32_get_unknown_glyph
- pango_win32_make_matching_logfont
+ pango_win32_make_matching_logfontw
pango_win32_render
pango_win32_render_layout
pango_win32_render_layout_line
diff --git a/pango/pangowin32.h b/pango/pangowin32.h
index 18293993..8e07218e 100644
--- a/pango/pangowin32.h
+++ b/pango/pangowin32.h
@@ -96,7 +96,9 @@ PangoWin32FontCache *pango_win32_font_cache_new (void);
void pango_win32_font_cache_free (PangoWin32FontCache *cache);
HFONT pango_win32_font_cache_load (PangoWin32FontCache *cache,
- const LOGFONT *logfont);
+ const LOGFONTA *logfont);
+HFONT pango_win32_font_cache_loadw (PangoWin32FontCache *cache,
+ const LOGFONTW *logfont);
void pango_win32_font_cache_unload (PangoWin32FontCache *cache,
HFONT hfont);
@@ -104,9 +106,12 @@ PangoFontMap *pango_win32_font_map_for_display (void);
void pango_win32_shutdown_display (void);
PangoWin32FontCache *pango_win32_font_map_get_font_cache (PangoFontMap *font_map);
-LOGFONT *pango_win32_font_logfont (PangoFont *font);
+LOGFONTA *pango_win32_font_logfont (PangoFont *font);
+LOGFONTW *pango_win32_font_logfontw (PangoFont *font);
-PangoFontDescription *pango_win32_font_description_from_logfont (const LOGFONT *lfp);
+PangoFontDescription *pango_win32_font_description_from_logfont (const LOGFONTA *lfp);
+
+PangoFontDescription *pango_win32_font_description_from_logfontw (const LOGFONTW *lfp);
G_END_DECLS