summaryrefslogtreecommitdiff
path: root/gdk/win32
diff options
context:
space:
mode:
authorTor Lillqvist <tml@iki.fi>1999-10-20 22:58:37 +0000
committerTor Lillqvist <tml@src.gnome.org>1999-10-20 22:58:37 +0000
commitb1c28ea6561e1ba494dfacf114e6c2dda36829b8 (patch)
tree4aa88c05bcaa91512d88cacd04c5428354b52f4c /gdk/win32
parentd8ce1977dde12b9de2e5331ef614c47e96ce0aff (diff)
downloadgtk+-b1c28ea6561e1ba494dfacf114e6c2dda36829b8.tar.gz
Add more font private data.
1999-10-21 Tor Lillqvist <tml@iki.fi> * gdk/win32/gdkprivate.h: Add more font private data. * gdk/win32/gdkfont.c * gdk/win32/gdkdraw.c: Revamped handling of multi-byte charset fonts and strings. Now works much better. You still have to have a correct font selected, though. No fontset emulation yet.
Diffstat (limited to 'gdk/win32')
-rw-r--r--gdk/win32/gdkdraw.c62
-rw-r--r--gdk/win32/gdkdrawable-win32.c62
-rw-r--r--gdk/win32/gdkfont-win32.c184
-rw-r--r--gdk/win32/gdkfont.c184
-rw-r--r--gdk/win32/gdkprivate-win32.h12
-rw-r--r--gdk/win32/gdkprivate.h12
6 files changed, 466 insertions, 50 deletions
diff --git a/gdk/win32/gdkdraw.c b/gdk/win32/gdkdraw.c
index 8006e1e864..593c98cd80 100644
--- a/gdk/win32/gdkdraw.c
+++ b/gdk/win32/gdkdraw.c
@@ -455,6 +455,8 @@ gdk_draw_text (GdkDrawable *drawable,
HDC hdc;
HFONT xfont;
HGDIOBJ oldfont;
+ wchar_t *wcstr;
+ gint wlen;
g_return_if_fail (drawable != NULL);
g_return_if_fail (font != NULL);
@@ -463,6 +465,10 @@ gdk_draw_text (GdkDrawable *drawable,
if (GDK_DRAWABLE_DESTROYED (drawable))
return;
+
+ if (text_length == 0)
+ return;
+
drawable_private = (GdkDrawablePrivate*) drawable;
gc_private = (GdkGCPrivate*) gc;
font_private = (GdkFontPrivate*) font;
@@ -482,9 +488,24 @@ gdk_draw_text (GdkDrawable *drawable,
if ((oldfont = SelectObject (hdc, xfont)) == NULL)
g_warning ("gdk_draw_text: SelectObject failed");
- if (!TextOutA (hdc, x, y, text, text_length))
- g_warning ("gdk_draw_text: TextOutA failed");
- SelectObject (hdc, oldfont);
+ if (font_private->cpinfo.MaxCharSize > 1)
+ {
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = MultiByteToWideChar (font_private->codepage, 0,
+ text, text_length,
+ wcstr, text_length)) == 0)
+ g_warning ("gdk_draw_text: MultiByteToWideChar failed");
+ else if (!TextOutW (hdc, x, y, wcstr, wlen))
+ g_warning ("gdk_draw_text: TextOutW failed");
+ g_free (wcstr);
+ }
+ else
+ {
+ if (!TextOutA (hdc, x, y, text, text_length))
+ g_warning ("gdk_draw_text: TextOutA failed");
+ }
+ if (oldfont != NULL)
+ SelectObject (hdc, oldfont);
gdk_gc_postdraw (drawable_private, gc_private);
}
else
@@ -503,7 +524,7 @@ gdk_draw_text_wc (GdkDrawable *drawable,
GdkDrawablePrivate *drawable_private;
GdkFontPrivate *font_private;
GdkGCPrivate *gc_private;
- gint i;
+ gint i, wlen;
wchar_t *wcstr;
guchar *str;
@@ -514,6 +535,10 @@ gdk_draw_text_wc (GdkDrawable *drawable,
if (GDK_DRAWABLE_DESTROYED (drawable))
return;
+
+ if (text_length == 0)
+ return;
+
drawable_private = (GdkDrawablePrivate*) drawable;
gc_private = (GdkGCPrivate*) gc;
font_private = (GdkFontPrivate*) font;
@@ -535,8 +560,8 @@ gdk_draw_text_wc (GdkDrawable *drawable,
text_length));
if ((oldfont = SelectObject (hdc, xfont)) == NULL)
- g_warning ("gdk_draw_text: SelectObject failed");
-#if 0 /* No. Don't use TextOutW. Compare to the X11 version,
+ g_warning ("gdk_draw_text_wc: SelectObject failed");
+#if 0 /* No. Don't use TextOutW directly. Compare to the X11 version,
* it uses plain XDrawString for GDK_FONT_FONT fonts, too.
* TextOutW by definition interprets the string as Unicode.
* We don't have that, but either chars from some single-byte codepage
@@ -546,17 +571,32 @@ gdk_draw_text_wc (GdkDrawable *drawable,
for (i = 0; i < text_length; i++)
wcstr[i] = text[i];
if (!TextOutW (hdc, x, y, wcstr, text_length))
- g_warning ("gdk_draw_text: TextOutW failed");
+ g_warning ("gdk_draw_text_wc: TextOutW failed");
g_free (wcstr);
#else
str = g_new (guchar, text_length);
- for (i=0; i<text_length; i++)
+ for (i = 0; i < text_length; i++)
str[i] = text[i];
- if (!TextOutA (hdc, x, y, str, text_length))
- g_warning ("gdk_draw_text: TextOutA failed");
+ if (font_private->cpinfo.MaxCharSize > 1)
+ {
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = MultiByteToWideChar (font_private->codepage, 0,
+ str, text_length,
+ wcstr, text_length)) == 0)
+ g_warning ("gdk_draw_text: MultiByteToWideChar failed");
+ else if (!TextOutW (hdc, x, y, wcstr, wlen))
+ g_warning ("gdk_draw_text_wc: TextOutW failed");
+ g_free (wcstr);
+ }
+ else
+ {
+ if (!TextOutA (hdc, x, y, str, text_length))
+ g_warning ("gdk_draw_text_wc: TextOutA failed");
+ }
g_free (str);
#endif
- SelectObject (hdc, oldfont);
+ if (oldfont != NULL)
+ SelectObject (hdc, oldfont);
gdk_gc_postdraw (drawable_private, gc_private);
}
else
diff --git a/gdk/win32/gdkdrawable-win32.c b/gdk/win32/gdkdrawable-win32.c
index 8006e1e864..593c98cd80 100644
--- a/gdk/win32/gdkdrawable-win32.c
+++ b/gdk/win32/gdkdrawable-win32.c
@@ -455,6 +455,8 @@ gdk_draw_text (GdkDrawable *drawable,
HDC hdc;
HFONT xfont;
HGDIOBJ oldfont;
+ wchar_t *wcstr;
+ gint wlen;
g_return_if_fail (drawable != NULL);
g_return_if_fail (font != NULL);
@@ -463,6 +465,10 @@ gdk_draw_text (GdkDrawable *drawable,
if (GDK_DRAWABLE_DESTROYED (drawable))
return;
+
+ if (text_length == 0)
+ return;
+
drawable_private = (GdkDrawablePrivate*) drawable;
gc_private = (GdkGCPrivate*) gc;
font_private = (GdkFontPrivate*) font;
@@ -482,9 +488,24 @@ gdk_draw_text (GdkDrawable *drawable,
if ((oldfont = SelectObject (hdc, xfont)) == NULL)
g_warning ("gdk_draw_text: SelectObject failed");
- if (!TextOutA (hdc, x, y, text, text_length))
- g_warning ("gdk_draw_text: TextOutA failed");
- SelectObject (hdc, oldfont);
+ if (font_private->cpinfo.MaxCharSize > 1)
+ {
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = MultiByteToWideChar (font_private->codepage, 0,
+ text, text_length,
+ wcstr, text_length)) == 0)
+ g_warning ("gdk_draw_text: MultiByteToWideChar failed");
+ else if (!TextOutW (hdc, x, y, wcstr, wlen))
+ g_warning ("gdk_draw_text: TextOutW failed");
+ g_free (wcstr);
+ }
+ else
+ {
+ if (!TextOutA (hdc, x, y, text, text_length))
+ g_warning ("gdk_draw_text: TextOutA failed");
+ }
+ if (oldfont != NULL)
+ SelectObject (hdc, oldfont);
gdk_gc_postdraw (drawable_private, gc_private);
}
else
@@ -503,7 +524,7 @@ gdk_draw_text_wc (GdkDrawable *drawable,
GdkDrawablePrivate *drawable_private;
GdkFontPrivate *font_private;
GdkGCPrivate *gc_private;
- gint i;
+ gint i, wlen;
wchar_t *wcstr;
guchar *str;
@@ -514,6 +535,10 @@ gdk_draw_text_wc (GdkDrawable *drawable,
if (GDK_DRAWABLE_DESTROYED (drawable))
return;
+
+ if (text_length == 0)
+ return;
+
drawable_private = (GdkDrawablePrivate*) drawable;
gc_private = (GdkGCPrivate*) gc;
font_private = (GdkFontPrivate*) font;
@@ -535,8 +560,8 @@ gdk_draw_text_wc (GdkDrawable *drawable,
text_length));
if ((oldfont = SelectObject (hdc, xfont)) == NULL)
- g_warning ("gdk_draw_text: SelectObject failed");
-#if 0 /* No. Don't use TextOutW. Compare to the X11 version,
+ g_warning ("gdk_draw_text_wc: SelectObject failed");
+#if 0 /* No. Don't use TextOutW directly. Compare to the X11 version,
* it uses plain XDrawString for GDK_FONT_FONT fonts, too.
* TextOutW by definition interprets the string as Unicode.
* We don't have that, but either chars from some single-byte codepage
@@ -546,17 +571,32 @@ gdk_draw_text_wc (GdkDrawable *drawable,
for (i = 0; i < text_length; i++)
wcstr[i] = text[i];
if (!TextOutW (hdc, x, y, wcstr, text_length))
- g_warning ("gdk_draw_text: TextOutW failed");
+ g_warning ("gdk_draw_text_wc: TextOutW failed");
g_free (wcstr);
#else
str = g_new (guchar, text_length);
- for (i=0; i<text_length; i++)
+ for (i = 0; i < text_length; i++)
str[i] = text[i];
- if (!TextOutA (hdc, x, y, str, text_length))
- g_warning ("gdk_draw_text: TextOutA failed");
+ if (font_private->cpinfo.MaxCharSize > 1)
+ {
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = MultiByteToWideChar (font_private->codepage, 0,
+ str, text_length,
+ wcstr, text_length)) == 0)
+ g_warning ("gdk_draw_text: MultiByteToWideChar failed");
+ else if (!TextOutW (hdc, x, y, wcstr, wlen))
+ g_warning ("gdk_draw_text_wc: TextOutW failed");
+ g_free (wcstr);
+ }
+ else
+ {
+ if (!TextOutA (hdc, x, y, str, text_length))
+ g_warning ("gdk_draw_text_wc: TextOutA failed");
+ }
g_free (str);
#endif
- SelectObject (hdc, oldfont);
+ if (oldfont != NULL)
+ SelectObject (hdc, oldfont);
gdk_gc_postdraw (drawable_private, gc_private);
}
else
diff --git a/gdk/win32/gdkfont-win32.c b/gdk/win32/gdkfont-win32.c
index 9c2649eded..d28c1f77c0 100644
--- a/gdk/win32/gdkfont-win32.c
+++ b/gdk/win32/gdkfont-win32.c
@@ -89,6 +89,33 @@ gdk_font_hash_lookup (GdkFontType type, const gchar *font_name)
}
}
+static const char *
+charset_name (DWORD charset)
+{
+ switch (charset)
+ {
+ case ANSI_CHARSET: return "ANSI";
+ case DEFAULT_CHARSET: return "DEFAULT";
+ case SYMBOL_CHARSET: return "SYMBOL";
+ case SHIFTJIS_CHARSET: return "SHIFTJIS";
+ case HANGEUL_CHARSET: return "HANGEUL";
+ case GB2312_CHARSET: return "GB2312";
+ case CHINESEBIG5_CHARSET: return "CHINESEBIG5";
+ case JOHAB_CHARSET: return "JOHAB";
+ case HEBREW_CHARSET: return "HEBREW";
+ case ARABIC_CHARSET: return "ARABIC";
+ case GREEK_CHARSET: return "GREEK";
+ case TURKISH_CHARSET: return "TURKISH";
+ case VIETNAMESE_CHARSET: return "VIETNAMESE";
+ case THAI_CHARSET: return "THAI";
+ case EASTEUROPE_CHARSET: return "EASTEUROPE";
+ case RUSSIAN_CHARSET: return "RUSSIAN";
+ case MAC_CHARSET: return "MAC";
+ case BALTIC_CHARSET: return "BALTIC";
+ }
+ return "unknown";
+}
+
GdkFont*
gdk_font_load (const gchar *font_name)
{
@@ -98,6 +125,7 @@ gdk_font_load (const gchar *font_name)
LOGFONT logfont;
HGDIOBJ oldfont;
TEXTMETRIC textmetric;
+ CHARSETINFO csi;
HANDLE *f;
DWORD fdwItalic, fdwUnderline, fdwStrikeOut, fdwCharSet,
fdwOutputPrecision, fdwClipPrecision, fdwQuality, fdwPitchAndFamily;
@@ -283,10 +311,8 @@ gdk_font_load (const gchar *font_name)
fdwCharSet = HANGEUL_CHARSET;
else if (g_strcasecmp (encoding, "chinesebig5") == 0)
fdwCharSet = CHINESEBIG5_CHARSET;
-#ifdef JOHAB_CHARSET
else if (g_strcasecmp (encoding, "johab") == 0)
fdwCharSet = JOHAB_CHARSET;
-#endif
else if (g_strcasecmp (encoding, "hebrew") == 0)
fdwCharSet = HEBREW_CHARSET;
else if (g_strcasecmp (encoding, "arabic") == 0)
@@ -395,12 +421,21 @@ gdk_font_load (const gchar *font_name)
GetObject (private->xfont, sizeof (logfont), &logfont);
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextMetrics (gdk_DC, &textmetric);
+ private->charset = GetTextCharsetInfo (gdk_DC, &private->fs, 0);
SelectObject (gdk_DC, oldfont);
+ TranslateCharsetInfo ((DWORD *) private->charset, &csi, TCI_SRCCHARSET);
+ private->codepage = csi.ciACP;
+ GetCPInfo (private->codepage, &private->cpinfo);
font->ascent = textmetric.tmAscent;
font->descent = textmetric.tmDescent;
- GDK_NOTE (MISC, g_print ("... = %#x asc %d desc %d\n",
- private->xfont, font->ascent, font->descent));
+ GDK_NOTE (MISC, g_print ("... = %#x charset %s codepage %d (max %d bytes) "
+ "asc %d desc %d\n",
+ private->xfont,
+ charset_name (private->charset),
+ private->codepage,
+ private->cpinfo.MaxCharSize,
+ font->ascent, font->descent));
/* This memory is leaked, so shoot me. */
f = g_new (HANDLE, 1);
@@ -429,6 +464,9 @@ gdk_font_ref (GdkFont *font)
private = (GdkFontPrivate*) font;
private->ref_count += 1;
+
+ GDK_NOTE (MISC, g_print ("gdk_font_ref %#x %d\n",
+ private->xfont, private->ref_count));
return font;
}
@@ -442,6 +480,12 @@ gdk_font_unref (GdkFont *font)
g_return_if_fail (private->ref_count > 0);
private->ref_count -= 1;
+
+ GDK_NOTE (MISC, g_print ("gdk_font_unref %#x %d%s\n",
+ private->xfont,
+ private->ref_count,
+ (private->ref_count == 0 ? " freeing" : "")));
+
if (private->ref_count == 0)
{
gdk_font_hash_remove (font->type, font);
@@ -449,8 +493,6 @@ gdk_font_unref (GdkFont *font)
switch (font->type)
{
case GDK_FONT_FONT:
- GDK_NOTE (MISC, g_print ("gdk_font_unref %#x\n", private->xfont));
-
gdk_xid_table_remove ((HANDLE) ((guint) private->xfont + HFONT_DITHER));
DeleteObject (private->xfont);
break;
@@ -513,18 +555,39 @@ gdk_text_width (GdkFont *font,
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
- gint width;
+ gint width, wlen;
+ wchar_t *wcstr;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
+ if (text_length == 0)
+ return 0;
+
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
oldfont = SelectObject (gdk_DC, private->xfont);
- GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
+ if (private->cpinfo.MaxCharSize > 1)
+ {
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = MultiByteToWideChar (private->codepage, 0,
+ text, text_length,
+ wcstr, text_length)) == 0)
+ {
+ g_warning ("gdk_text_width: MultiByteToWideChar failed");
+ size.cx = 0;
+ }
+ else
+ GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
+ g_free (wcstr);
+ }
+ else
+ {
+ GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
+ }
SelectObject (gdk_DC, oldfont);
width = size.cx;
break;
@@ -545,11 +608,14 @@ gdk_text_width_wc (GdkFont *font,
SIZE size;
wchar_t *wcstr;
guchar *str;
- gint i, width;
+ gint i, width, wlen;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
+ if (text_length == 0)
+ return 0;
+
private = (GdkFontPrivate*) font;
switch (font->type)
@@ -566,9 +632,26 @@ gdk_text_width_wc (GdkFont *font,
g_free (wcstr);
#else
str = g_new (guchar, text_length);
- for (i=0; i<text_length; i++)
+ for (i = 0; i < text_length; i++)
str[i] = text[i];
- GetTextExtentPoint32A (gdk_DC, str, text_length, &size);
+ if (private->cpinfo.MaxCharSize > 1)
+ {
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = MultiByteToWideChar (private->codepage, 0,
+ str, text_length,
+ wcstr, text_length)) == 0)
+ {
+ g_warning ("gdk_text_width_wc: MultiByteToWideChar failed");
+ size.cx = 0;
+ }
+ else
+ GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
+ g_free (wcstr);
+ }
+ else
+ {
+ GetTextExtentPoint32A (gdk_DC, str, text_length, &size);
+ }
g_free (str);
#endif
SelectObject (gdk_DC, oldfont);
@@ -618,17 +701,52 @@ gdk_text_extents (GdkFont *font,
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
+ gint wlen;
+ wchar_t *wcstr;
g_return_if_fail (font != NULL);
g_return_if_fail (text != NULL);
+ if (text_length == 0)
+ {
+ if (lbearing)
+ *lbearing = 0;
+ if (rbearing)
+ *rbearing = 0;
+ if (width)
+ *width = 0;
+ if (ascent)
+ *ascent = 0;
+ if (descent)
+ *descent = 0;
+ return;
+ }
+
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
oldfont = SelectObject (gdk_DC, private->xfont);
- GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
+ if (private->cpinfo.MaxCharSize > 1)
+ {
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = MultiByteToWideChar (private->codepage, 0,
+ text, text_length,
+ wcstr, text_length)) == 0)
+ {
+ g_warning ("gdk_text_extents: MultiByteToWideChar failed");
+ size.cx = 0;
+ size.cy = 0;
+ }
+ else
+ GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
+ g_free (wcstr);
+ }
+ else
+ {
+ GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
+ }
SelectObject (gdk_DC, oldfont);
/* XXX This is all quite bogus */
if (lbearing)
@@ -667,6 +785,21 @@ gdk_text_extents_wc (GdkFont *font,
g_return_if_fail (font != NULL);
g_return_if_fail (text != NULL);
+ if (text_length == 0)
+ {
+ if (lbearing)
+ *lbearing = 0;
+ if (rbearing)
+ *rbearing = 0;
+ if (width)
+ *width = 0;
+ if (ascent)
+ *ascent = 0;
+ if (descent)
+ *descent = 0;
+ return;
+ }
+
private = (GdkFontPrivate*) font;
switch (font->type)
@@ -765,18 +898,41 @@ gdk_text_height (GdkFont *font,
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
- gint height;
+ gint height, wlen;
+ wchar_t *wcstr;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
+ if (text_length == 0)
+ return 0;
+
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
oldfont = SelectObject (gdk_DC, private->xfont);
- GetTextExtentPoint32 (gdk_DC, text, text_length, &size);
+ if (private->cpinfo.MaxCharSize > 1)
+ {
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = MultiByteToWideChar (private->codepage, 0,
+ text, text_length,
+ wcstr, text_length)) == 0)
+ {
+ g_warning ("gdk_text_height: MultiByteToWideChar failed "
+ "text = %.*s (%d)",
+ text_length, text, text_length);
+ size.cy = 0;
+ }
+ else
+ GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
+ g_free (wcstr);
+ }
+ else
+ {
+ GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
+ }
SelectObject (gdk_DC, oldfont);
height = size.cy;
break;
diff --git a/gdk/win32/gdkfont.c b/gdk/win32/gdkfont.c
index 9c2649eded..d28c1f77c0 100644
--- a/gdk/win32/gdkfont.c
+++ b/gdk/win32/gdkfont.c
@@ -89,6 +89,33 @@ gdk_font_hash_lookup (GdkFontType type, const gchar *font_name)
}
}
+static const char *
+charset_name (DWORD charset)
+{
+ switch (charset)
+ {
+ case ANSI_CHARSET: return "ANSI";
+ case DEFAULT_CHARSET: return "DEFAULT";
+ case SYMBOL_CHARSET: return "SYMBOL";
+ case SHIFTJIS_CHARSET: return "SHIFTJIS";
+ case HANGEUL_CHARSET: return "HANGEUL";
+ case GB2312_CHARSET: return "GB2312";
+ case CHINESEBIG5_CHARSET: return "CHINESEBIG5";
+ case JOHAB_CHARSET: return "JOHAB";
+ case HEBREW_CHARSET: return "HEBREW";
+ case ARABIC_CHARSET: return "ARABIC";
+ case GREEK_CHARSET: return "GREEK";
+ case TURKISH_CHARSET: return "TURKISH";
+ case VIETNAMESE_CHARSET: return "VIETNAMESE";
+ case THAI_CHARSET: return "THAI";
+ case EASTEUROPE_CHARSET: return "EASTEUROPE";
+ case RUSSIAN_CHARSET: return "RUSSIAN";
+ case MAC_CHARSET: return "MAC";
+ case BALTIC_CHARSET: return "BALTIC";
+ }
+ return "unknown";
+}
+
GdkFont*
gdk_font_load (const gchar *font_name)
{
@@ -98,6 +125,7 @@ gdk_font_load (const gchar *font_name)
LOGFONT logfont;
HGDIOBJ oldfont;
TEXTMETRIC textmetric;
+ CHARSETINFO csi;
HANDLE *f;
DWORD fdwItalic, fdwUnderline, fdwStrikeOut, fdwCharSet,
fdwOutputPrecision, fdwClipPrecision, fdwQuality, fdwPitchAndFamily;
@@ -283,10 +311,8 @@ gdk_font_load (const gchar *font_name)
fdwCharSet = HANGEUL_CHARSET;
else if (g_strcasecmp (encoding, "chinesebig5") == 0)
fdwCharSet = CHINESEBIG5_CHARSET;
-#ifdef JOHAB_CHARSET
else if (g_strcasecmp (encoding, "johab") == 0)
fdwCharSet = JOHAB_CHARSET;
-#endif
else if (g_strcasecmp (encoding, "hebrew") == 0)
fdwCharSet = HEBREW_CHARSET;
else if (g_strcasecmp (encoding, "arabic") == 0)
@@ -395,12 +421,21 @@ gdk_font_load (const gchar *font_name)
GetObject (private->xfont, sizeof (logfont), &logfont);
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextMetrics (gdk_DC, &textmetric);
+ private->charset = GetTextCharsetInfo (gdk_DC, &private->fs, 0);
SelectObject (gdk_DC, oldfont);
+ TranslateCharsetInfo ((DWORD *) private->charset, &csi, TCI_SRCCHARSET);
+ private->codepage = csi.ciACP;
+ GetCPInfo (private->codepage, &private->cpinfo);
font->ascent = textmetric.tmAscent;
font->descent = textmetric.tmDescent;
- GDK_NOTE (MISC, g_print ("... = %#x asc %d desc %d\n",
- private->xfont, font->ascent, font->descent));
+ GDK_NOTE (MISC, g_print ("... = %#x charset %s codepage %d (max %d bytes) "
+ "asc %d desc %d\n",
+ private->xfont,
+ charset_name (private->charset),
+ private->codepage,
+ private->cpinfo.MaxCharSize,
+ font->ascent, font->descent));
/* This memory is leaked, so shoot me. */
f = g_new (HANDLE, 1);
@@ -429,6 +464,9 @@ gdk_font_ref (GdkFont *font)
private = (GdkFontPrivate*) font;
private->ref_count += 1;
+
+ GDK_NOTE (MISC, g_print ("gdk_font_ref %#x %d\n",
+ private->xfont, private->ref_count));
return font;
}
@@ -442,6 +480,12 @@ gdk_font_unref (GdkFont *font)
g_return_if_fail (private->ref_count > 0);
private->ref_count -= 1;
+
+ GDK_NOTE (MISC, g_print ("gdk_font_unref %#x %d%s\n",
+ private->xfont,
+ private->ref_count,
+ (private->ref_count == 0 ? " freeing" : "")));
+
if (private->ref_count == 0)
{
gdk_font_hash_remove (font->type, font);
@@ -449,8 +493,6 @@ gdk_font_unref (GdkFont *font)
switch (font->type)
{
case GDK_FONT_FONT:
- GDK_NOTE (MISC, g_print ("gdk_font_unref %#x\n", private->xfont));
-
gdk_xid_table_remove ((HANDLE) ((guint) private->xfont + HFONT_DITHER));
DeleteObject (private->xfont);
break;
@@ -513,18 +555,39 @@ gdk_text_width (GdkFont *font,
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
- gint width;
+ gint width, wlen;
+ wchar_t *wcstr;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
+ if (text_length == 0)
+ return 0;
+
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
oldfont = SelectObject (gdk_DC, private->xfont);
- GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
+ if (private->cpinfo.MaxCharSize > 1)
+ {
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = MultiByteToWideChar (private->codepage, 0,
+ text, text_length,
+ wcstr, text_length)) == 0)
+ {
+ g_warning ("gdk_text_width: MultiByteToWideChar failed");
+ size.cx = 0;
+ }
+ else
+ GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
+ g_free (wcstr);
+ }
+ else
+ {
+ GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
+ }
SelectObject (gdk_DC, oldfont);
width = size.cx;
break;
@@ -545,11 +608,14 @@ gdk_text_width_wc (GdkFont *font,
SIZE size;
wchar_t *wcstr;
guchar *str;
- gint i, width;
+ gint i, width, wlen;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
+ if (text_length == 0)
+ return 0;
+
private = (GdkFontPrivate*) font;
switch (font->type)
@@ -566,9 +632,26 @@ gdk_text_width_wc (GdkFont *font,
g_free (wcstr);
#else
str = g_new (guchar, text_length);
- for (i=0; i<text_length; i++)
+ for (i = 0; i < text_length; i++)
str[i] = text[i];
- GetTextExtentPoint32A (gdk_DC, str, text_length, &size);
+ if (private->cpinfo.MaxCharSize > 1)
+ {
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = MultiByteToWideChar (private->codepage, 0,
+ str, text_length,
+ wcstr, text_length)) == 0)
+ {
+ g_warning ("gdk_text_width_wc: MultiByteToWideChar failed");
+ size.cx = 0;
+ }
+ else
+ GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
+ g_free (wcstr);
+ }
+ else
+ {
+ GetTextExtentPoint32A (gdk_DC, str, text_length, &size);
+ }
g_free (str);
#endif
SelectObject (gdk_DC, oldfont);
@@ -618,17 +701,52 @@ gdk_text_extents (GdkFont *font,
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
+ gint wlen;
+ wchar_t *wcstr;
g_return_if_fail (font != NULL);
g_return_if_fail (text != NULL);
+ if (text_length == 0)
+ {
+ if (lbearing)
+ *lbearing = 0;
+ if (rbearing)
+ *rbearing = 0;
+ if (width)
+ *width = 0;
+ if (ascent)
+ *ascent = 0;
+ if (descent)
+ *descent = 0;
+ return;
+ }
+
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
oldfont = SelectObject (gdk_DC, private->xfont);
- GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
+ if (private->cpinfo.MaxCharSize > 1)
+ {
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = MultiByteToWideChar (private->codepage, 0,
+ text, text_length,
+ wcstr, text_length)) == 0)
+ {
+ g_warning ("gdk_text_extents: MultiByteToWideChar failed");
+ size.cx = 0;
+ size.cy = 0;
+ }
+ else
+ GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
+ g_free (wcstr);
+ }
+ else
+ {
+ GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
+ }
SelectObject (gdk_DC, oldfont);
/* XXX This is all quite bogus */
if (lbearing)
@@ -667,6 +785,21 @@ gdk_text_extents_wc (GdkFont *font,
g_return_if_fail (font != NULL);
g_return_if_fail (text != NULL);
+ if (text_length == 0)
+ {
+ if (lbearing)
+ *lbearing = 0;
+ if (rbearing)
+ *rbearing = 0;
+ if (width)
+ *width = 0;
+ if (ascent)
+ *ascent = 0;
+ if (descent)
+ *descent = 0;
+ return;
+ }
+
private = (GdkFontPrivate*) font;
switch (font->type)
@@ -765,18 +898,41 @@ gdk_text_height (GdkFont *font,
GdkFontPrivate *private;
HGDIOBJ oldfont;
SIZE size;
- gint height;
+ gint height, wlen;
+ wchar_t *wcstr;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
+ if (text_length == 0)
+ return 0;
+
private = (GdkFontPrivate*) font;
switch (font->type)
{
case GDK_FONT_FONT:
oldfont = SelectObject (gdk_DC, private->xfont);
- GetTextExtentPoint32 (gdk_DC, text, text_length, &size);
+ if (private->cpinfo.MaxCharSize > 1)
+ {
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = MultiByteToWideChar (private->codepage, 0,
+ text, text_length,
+ wcstr, text_length)) == 0)
+ {
+ g_warning ("gdk_text_height: MultiByteToWideChar failed "
+ "text = %.*s (%d)",
+ text_length, text, text_length);
+ size.cy = 0;
+ }
+ else
+ GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
+ g_free (wcstr);
+ }
+ else
+ {
+ GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
+ }
SelectObject (gdk_DC, oldfont);
height = size.cy;
break;
diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h
index 5df4fe7358..a45044d8e6 100644
--- a/gdk/win32/gdkprivate-win32.h
+++ b/gdk/win32/gdkprivate-win32.h
@@ -42,6 +42,14 @@
#define CLR_INVALID CLR_NONE
#endif
+/* Some charsets are missing */
+#ifndef JOHAB_CHARSET
+#define JOHAB_CHARSET 130
+#endif
+#ifndef VIETNAMESE_CHARSET
+#define VIETNAMESE_CHARSET 163
+#endif
+
/* MB_CUR_MAX is missing */
#ifndef MB_CUR_MAX
extern int *__imp___mb_cur_max;
@@ -300,6 +308,10 @@ struct _GdkFontPrivate
guint ref_count;
GSList *names;
+ DWORD charset;
+ UINT codepage;
+ CPINFO cpinfo;
+ FONTSIGNATURE fs;
};
struct _GdkCursorPrivate
diff --git a/gdk/win32/gdkprivate.h b/gdk/win32/gdkprivate.h
index 5df4fe7358..a45044d8e6 100644
--- a/gdk/win32/gdkprivate.h
+++ b/gdk/win32/gdkprivate.h
@@ -42,6 +42,14 @@
#define CLR_INVALID CLR_NONE
#endif
+/* Some charsets are missing */
+#ifndef JOHAB_CHARSET
+#define JOHAB_CHARSET 130
+#endif
+#ifndef VIETNAMESE_CHARSET
+#define VIETNAMESE_CHARSET 163
+#endif
+
/* MB_CUR_MAX is missing */
#ifndef MB_CUR_MAX
extern int *__imp___mb_cur_max;
@@ -300,6 +308,10 @@ struct _GdkFontPrivate
guint ref_count;
GSList *names;
+ DWORD charset;
+ UINT codepage;
+ CPINFO cpinfo;
+ FONTSIGNATURE fs;
};
struct _GdkCursorPrivate