From 1768e0e4fde11a6dfdf2336536edce3c954f4474 Mon Sep 17 00:00:00 2001 From: Lauris Kaplinski Date: Fri, 8 Sep 2000 22:32:24 +0000 Subject: Some UTF-8 fixes and experimental 16-bit unicode font support svn path=/trunk/; revision=5279 --- addressbook/ChangeLog | 8 ++ addressbook/gui/minicard/e-minicard-label.c | 6 +- addressbook/gui/minicard/e-minicard.c | 10 +- addressbook/gui/widgets/e-minicard-label.c | 6 +- addressbook/gui/widgets/e-minicard.c | 10 +- e-util/ChangeLog | 4 + e-util/e-font.c | 210 ++++++++++++++++++++-------- shell/ChangeLog | 4 + shell/e-shell-view.c | 3 +- widgets/ChangeLog | 4 + widgets/e-text/e-text.c | 10 +- widgets/text/e-text.c | 10 +- 12 files changed, 197 insertions(+), 88 deletions(-) diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index 41b1cc542f..6305e90367 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -1,3 +1,11 @@ +2000-09-08 Lauris Kaplinski + + * gui/minicard/e-minicard-label.c (e_minicard_label_construct): + Use canvas default font + + * gui/minicard/e-minicard.c (e_minicard_realize): Ditto + (get_left_width): Ditto + 2000-09-08 Christopher James Lahey * contact-editor/e-contact-editor-categories.c: Fixed a few warnings. diff --git a/addressbook/gui/minicard/e-minicard-label.c b/addressbook/gui/minicard/e-minicard-label.c index e765a89f21..c0f45f67c9 100644 --- a/addressbook/gui/minicard/e-minicard-label.c +++ b/addressbook/gui/minicard/e-minicard-label.c @@ -220,11 +220,9 @@ e_minicard_label_construct (GnomeCanvasItem *item) { EMinicardLabel *e_minicard_label; GnomeCanvasGroup *group; - static GdkFont *font = NULL; + GdkFont *font; - if (font == NULL) { - font = gdk_font_load("lucidasans-10"); - } + font = ((GtkWidget *) item->canvas)->style->font; e_minicard_label = E_MINICARD_LABEL (item); group = GNOME_CANVAS_GROUP( item ); diff --git a/addressbook/gui/minicard/e-minicard.c b/addressbook/gui/minicard/e-minicard.c index e9bb85c89d..d870de7b25 100644 --- a/addressbook/gui/minicard/e-minicard.c +++ b/addressbook/gui/minicard/e-minicard.c @@ -285,7 +285,9 @@ e_minicard_realize (GnomeCanvasItem *item) "width", (double) ( e_minicard->width - 12 ), "clip", TRUE, "use_ellipsis", TRUE, - "font", "lucidasans-bold-10", +#if 0 + "font", "fixed-bold-10", +#endif "fill_color_gdk", &canvas->style->fg[GTK_STATE_NORMAL], "text", "", NULL ); @@ -626,11 +628,9 @@ get_left_width(EMinicard *e_minicard) gchar *name; ECardSimpleField field; gdouble width = -1; - static GdkFont *font = NULL; + GdkFont *font; - if (font == NULL) { - font = gdk_font_load("lucidasans-10"); - } + font = ((GtkWidget *) ((GnomeCanvasItem *) e_minicard)->canvas)->style->font; for(field = E_CARD_SIMPLE_FIELD_FULL_NAME; field != E_CARD_SIMPLE_FIELD_LAST; field++) { gdouble this_width; diff --git a/addressbook/gui/widgets/e-minicard-label.c b/addressbook/gui/widgets/e-minicard-label.c index e765a89f21..c0f45f67c9 100644 --- a/addressbook/gui/widgets/e-minicard-label.c +++ b/addressbook/gui/widgets/e-minicard-label.c @@ -220,11 +220,9 @@ e_minicard_label_construct (GnomeCanvasItem *item) { EMinicardLabel *e_minicard_label; GnomeCanvasGroup *group; - static GdkFont *font = NULL; + GdkFont *font; - if (font == NULL) { - font = gdk_font_load("lucidasans-10"); - } + font = ((GtkWidget *) item->canvas)->style->font; e_minicard_label = E_MINICARD_LABEL (item); group = GNOME_CANVAS_GROUP( item ); diff --git a/addressbook/gui/widgets/e-minicard.c b/addressbook/gui/widgets/e-minicard.c index e9bb85c89d..d870de7b25 100644 --- a/addressbook/gui/widgets/e-minicard.c +++ b/addressbook/gui/widgets/e-minicard.c @@ -285,7 +285,9 @@ e_minicard_realize (GnomeCanvasItem *item) "width", (double) ( e_minicard->width - 12 ), "clip", TRUE, "use_ellipsis", TRUE, - "font", "lucidasans-bold-10", +#if 0 + "font", "fixed-bold-10", +#endif "fill_color_gdk", &canvas->style->fg[GTK_STATE_NORMAL], "text", "", NULL ); @@ -626,11 +628,9 @@ get_left_width(EMinicard *e_minicard) gchar *name; ECardSimpleField field; gdouble width = -1; - static GdkFont *font = NULL; + GdkFont *font; - if (font == NULL) { - font = gdk_font_load("lucidasans-10"); - } + font = ((GtkWidget *) ((GnomeCanvasItem *) e_minicard)->canvas)->style->font; for(field = E_CARD_SIMPLE_FIELD_FULL_NAME; field != E_CARD_SIMPLE_FIELD_LAST; field++) { gdouble this_width; diff --git a/e-util/ChangeLog b/e-util/ChangeLog index 2c1e3a902a..19aca4a76f 100644 --- a/e-util/ChangeLog +++ b/e-util/ChangeLog @@ -1,3 +1,7 @@ +2000-09-08 Lauris Kaplinski + + * e-font.c: Use experimental 16-bit font stuff for EFonts + 2000-09-08 Dan Winship * e-popup-menu.h: remove consts from the EPopupMenu structure: the diff --git a/e-util/e-font.c b/e-util/e-font.c index cfee9f0923..15fa868254 100644 --- a/e-util/e-font.c +++ b/e-util/e-font.c @@ -16,58 +16,169 @@ #include #include "e-font.h" +#define FONT_TESTING + struct _EFont { - GdkFont font; + gint refcount; + GdkFont *font; + gboolean bytes; + unicode_iconv_t to; + unicode_iconv_t from; }; EFont * e_font_from_gdk_name (const gchar *name) { - GdkFont *font; + EFont * font; + GdkFont *gdkfont; - font = gdk_fontset_load (name); + gdkfont = gdk_fontset_load (name); + font = e_font_from_gdk_font (gdkfont); + gdk_font_unref (gdkfont); - return (EFont *) font; + return font; } EFont * -e_font_from_gdk_font (GdkFont *font) +e_font_from_gdk_font (GdkFont *gdkfont) { - gdk_font_ref (font); + EFont *font; + XFontStruct *xfs; + Atom font_atom, atom; + Bool status; + + gdk_font_ref (gdkfont); + + /* Try to find iso-10646-1 encoded font with same name */ + + font_atom = gdk_atom_intern ("FONT", FALSE); + if (gdkfont->type == GDK_FONT_FONTSET) { + XFontStruct **font_structs; + gint num_fonts; + gchar **font_names; + num_fonts = XFontsOfFontSet (GDK_FONT_XFONT (gdkfont), + &font_structs, + &font_names); + status = XGetFontProperty (font_structs[0], + font_atom, + &atom); + } else { + status = XGetFontProperty (GDK_FONT_XFONT (gdkfont), + font_atom, + &atom); + } + if (status) { + gchar *name, *p; + gchar *newname; + GdkFont *newfont; + gint i; + + name = gdk_atom_name (atom); + newname = alloca (strlen (name) + 12); + strcpy (newname, name); + p = newname; + for (i = 0; i < 13; i++) { + /* Skip hyphen */ + while (*p && (*p != '-')) p++; + if (*p) p++; + } + g_snprintf (p, 12, "ISO10646-1"); + newfont = gdk_font_load (newname); + if (newfont) { + gdk_font_unref (gdkfont); + gdkfont = newfont; + } + g_free (name); + } + + font = g_new (EFont, 1); + + xfs = GDK_FONT_XFONT (gdkfont); + + font->refcount = 1; + font->font = gdkfont; + font->bytes = ((xfs->min_byte1 != 0) || (xfs->max_byte1 != 0)) ? 2 : 1; + font->to = e_uiconv_to_gdk_font (font->font); + font->from = e_uiconv_from_gdk_font (font->font); + + return font; - return (EFont *) font; } void e_font_ref (EFont *font) { - gdk_font_ref (&font->font); + font->refcount++; } void e_font_unref (EFont *font) { - gdk_font_unref (&font->font); + font->refcount--; + + if (font->refcount < 1) { + gdk_font_unref (font->font); + g_free (font); + } } gint e_font_ascent (EFont * font) { - return font->font.ascent; + return font->font->ascent; } gint e_font_descent (EFont * font) { - return font->font.descent; + return font->font->descent; +} + +static gint +e_font_to_native (EFont *font, gchar *native, gchar *utf, gint bytes) +{ + char *ib, *ob; + size_t ibl, obl; + + ib = utf; + ibl = bytes; + ob = native; + obl = bytes * 4; + + while (ibl > 0) { + unicode_iconv (font->to, (const char **) &ib, &ibl, &ob, &obl); + if (ibl > 0) { + gint len; + if ((*ib & 0x80) == 0x00) len = 1; + else if ((*ib &0xe0) == 0xc0) len = 2; + else if ((*ib &0xf0) == 0xe0) len = 3; + else if ((*ib &0xf80) == 0xf0) len = 4; + else { + g_warning ("Invalid UTF-8 sequence"); + return ob - native; + } + ib += len; + ibl = bytes - (ib - utf); + if (ibl > bytes) ibl = 0; + if (font->bytes == 1) { + *ob++ = '_'; + obl--; + } else { + *((guint16 *) ob) = '_'; + ob += 2; + obl -= 2; + } + } + } + + return ob - native; } void e_font_draw_utf8_text (GdkDrawable *drawable, EFont *font, EFontStyle style, GdkGC *gc, gint x, gint y, gchar *text, gint numbytes) { - guchar *iso; - gchar *p; - gint uni, len; + gchar *native; + gint native_bytes; g_return_if_fail (drawable != NULL); g_return_if_fail (font != NULL); @@ -76,57 +187,55 @@ e_font_draw_utf8_text (GdkDrawable *drawable, EFont *font, EFontStyle style, Gdk if (numbytes < 1) return; - iso = alloca (numbytes); + native = alloca (numbytes * 4); - for (len = 0, p = text; p != NULL && p < (text + numbytes); len++, p = unicode_next_utf8 (p)) { - unicode_get_utf8 (p, &uni); - if ((uni < ' ') || (uni > 255)) uni = ' '; - iso[len] = uni; - } + native_bytes = e_font_to_native (font, native, text, numbytes); - gdk_draw_text (drawable, &font->font, gc, x, y, iso, len); + gdk_draw_text (drawable, font->font, gc, x, y, native, native_bytes); if (style & E_FONT_BOLD) - gdk_draw_text (drawable, &font->font, gc, x + 1, y, iso, len); + gdk_draw_text (drawable, font->font, gc, x + 1, y, native, native_bytes); } gint e_font_utf8_text_width (EFont *font, EFontStyle style, char *text, int numbytes) { - guchar *iso; - gchar *p; - gint uni, len; + gchar *native; + gint native_bytes; + gint width; g_return_val_if_fail (font != NULL, 0); g_return_val_if_fail (text != NULL, 0); - iso = alloca (numbytes); + if (numbytes < 1) return 0; - for (len = 0, p = text; p != NULL && p < (text + numbytes); len++, p = unicode_next_utf8 (p)) { - unicode_get_utf8 (p, &uni); - if ((uni < ' ') || (uni > 255)) uni = ' '; - iso[len] = uni; - } + native = alloca (numbytes * 4); - return gdk_text_width (&font->font, iso, len); + native_bytes = e_font_to_native (font, native, text, numbytes); + + width = gdk_text_width (font->font, native, native_bytes); + + return width; } gint e_font_utf8_char_width (EFont *font, EFontStyle style, char *text) { - unicode_char_t uni; - guchar iso; + gint len; g_return_val_if_fail (font != NULL, 0); g_return_val_if_fail (text != NULL, 0); - if (!unicode_get_utf8 (text, &uni)) return 0; - - if ((uni < ' ') || (uni > 255)) uni = ' '; - - iso = uni; + if ((*text & 0x80) == 0x00) len = 1; + else if ((*text &0xe0) == 0xc0) len = 2; + else if ((*text &0xf0) == 0xe0) len = 3; + else if ((*text &0xf80) == 0xf0) len = 4; + else { + g_warning ("Invalid UTF-8 sequence"); + return 0; + } - return gdk_text_width (&font->font, &iso, 1); + return e_font_utf8_text_width (font, style, text, len); } static const gchar * @@ -151,7 +260,8 @@ translate_encoding (const gchar *encoding) g_hash_table_insert (eh, "iso8859-13", "iso-8859-13"); g_hash_table_insert (eh, "iso8859-14", "iso-8859-14"); g_hash_table_insert (eh, "iso8859-15", "iso-8859-15"); - g_hash_table_insert (eh, "iso10646-1", "UCS2"); + g_hash_table_insert (eh, "iso10646-1", "UTF-16"); + g_hash_table_insert (eh, "koi8-r", "koi8-r"); } strncpy (e, encoding, 64); @@ -200,27 +310,9 @@ e_gdk_font_encoding (GdkFont *font) if (*p) p++; } -#if 0 - p = strchr (name, '-'); /* Foundry */ - p = strchr (p + 1, '-'); /* Family */ - p = strchr (p + 1, '-'); /* Weight */ - p = strchr (p + 1, '-'); /* Slant */ - p = strchr (p + 1, '-'); /* Set Width */ - p = strchr (p + 1, '-'); /* Add Style */ - p = strchr (p + 1, '-'); /* Pixel Size */ - p = strchr (p + 1, '-'); /* Point Size */ - p = strchr (p + 1, '-'); /* Resolution X */ - p = strchr (p + 1, '-'); /* Resolution Y */ - p = strchr (p + 1, '-'); /* Spacing */ - p = strchr (p + 1, '-'); /* Average Width */ - p = strchr (p + 1, '-'); /* Charset */ - - encoding = translate_encoding (p + 1); -#else if (!*p) return NULL; encoding = translate_encoding (p); -#endif g_free (name); diff --git a/shell/ChangeLog b/shell/ChangeLog index 5949d98878..b1f41c28b0 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,7 @@ +2000-09-08 Lauris Kaplinski + + * e-shell-view.c (update_for_current_uri): Translate UTF-8 string + 2000-09-08 Ettore Perazzoli * evolution-storage.c (list_through_listener_foreach): Don't crash diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c index a6acdb5b41..3480f01c4b 100644 --- a/shell/e-shell-view.c +++ b/shell/e-shell-view.c @@ -936,11 +936,12 @@ update_for_current_uri (EShellView *shell_view) if (folder == NULL) folder_name = _("None"); else - folder_name = e_folder_get_name (folder); + folder_name = e_utf8_to_gtk_string ((GtkWidget *) shell_view, e_folder_get_name (folder)); window_title = g_strdup_printf (_("Evolution - %s"), folder_name); gtk_window_set_title (GTK_WINDOW (shell_view), window_title); g_free (window_title); + g_free (folder_name); update_folder_title_bar (shell_view, folder); diff --git a/widgets/ChangeLog b/widgets/ChangeLog index 09425c22f6..00226f5cb0 100644 --- a/widgets/ChangeLog +++ b/widgets/ChangeLog @@ -1,3 +1,7 @@ +2000-09-08 Lauris Kaplinski + + * e-text/e-text.c (calc_line_widths): Fix byte/char confusion + 2000-08-30 Federico Mena Quintero * e-paned/e-hpaned.c (e_hpaned_motion): Do not flicker while diff --git a/widgets/e-text/e-text.c b/widgets/e-text/e-text.c index ed87f21c95..cb064c9c40 100644 --- a/widgets/e-text/e-text.c +++ b/widgets/e-text/e-text.c @@ -683,8 +683,8 @@ calc_line_widths (EText *text) { struct line *lines; int i; - int j; gdouble clip_width; + gchar *p; /* Make sure line has been split */ if (text->text && text->num_lines == 0) @@ -721,10 +721,10 @@ calc_line_widths (EText *text) clip_width >= 0) { if (text->font) { lines->ellipsis_length = 0; - for (j = 0; j < lines->length; j++ ) { - if (e_font_utf8_text_width (text->font, E_FONT_PLAIN, lines->text, j) + text->ellipsis_width - <= clip_width) - lines->ellipsis_length = j; + for (p = lines->text; p && *p && (p - lines->text) < lines->length; p = unicode_next_utf8 (p)) { + if (e_font_utf8_text_width (text->font, E_FONT_PLAIN, lines->text, p - lines->text) + + text->ellipsis_width <= clip_width) + lines->ellipsis_length = p - lines->text; else break; } diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c index ed87f21c95..cb064c9c40 100644 --- a/widgets/text/e-text.c +++ b/widgets/text/e-text.c @@ -683,8 +683,8 @@ calc_line_widths (EText *text) { struct line *lines; int i; - int j; gdouble clip_width; + gchar *p; /* Make sure line has been split */ if (text->text && text->num_lines == 0) @@ -721,10 +721,10 @@ calc_line_widths (EText *text) clip_width >= 0) { if (text->font) { lines->ellipsis_length = 0; - for (j = 0; j < lines->length; j++ ) { - if (e_font_utf8_text_width (text->font, E_FONT_PLAIN, lines->text, j) + text->ellipsis_width - <= clip_width) - lines->ellipsis_length = j; + for (p = lines->text; p && *p && (p - lines->text) < lines->length; p = unicode_next_utf8 (p)) { + if (e_font_utf8_text_width (text->font, E_FONT_PLAIN, lines->text, p - lines->text) + + text->ellipsis_width <= clip_width) + lines->ellipsis_length = p - lines->text; else break; } -- cgit v1.2.3