diff options
author | Tor Lillqvist <tml@iki.fi> | 1999-10-20 22:58:37 +0000 |
---|---|---|
committer | Tor Lillqvist <tml@src.gnome.org> | 1999-10-20 22:58:37 +0000 |
commit | b1c28ea6561e1ba494dfacf114e6c2dda36829b8 (patch) | |
tree | 4aa88c05bcaa91512d88cacd04c5428354b52f4c /gdk/win32 | |
parent | d8ce1977dde12b9de2e5331ef614c47e96ce0aff (diff) | |
download | gtk+-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.c | 62 | ||||
-rw-r--r-- | gdk/win32/gdkdrawable-win32.c | 62 | ||||
-rw-r--r-- | gdk/win32/gdkfont-win32.c | 184 | ||||
-rw-r--r-- | gdk/win32/gdkfont.c | 184 | ||||
-rw-r--r-- | gdk/win32/gdkprivate-win32.h | 12 | ||||
-rw-r--r-- | gdk/win32/gdkprivate.h | 12 |
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 |