diff -aur old/ChangeLog new/ChangeLog --- old/ChangeLog 2008-12-06 14:35:33.037390818 +0800 +++ new/ChangeLog 2008-12-06 14:35:11.475339336 +0800 @@ -1,3 +1,39 @@ +2008-12-05 Behdad Esfahbod <behdad@gnome.org> + + Bug 563356 – The input area of firefox and the blank width after text + in gnome-menu was stretched too wide, under pango-1.22.3 + + * docs/tmpl/fonts.sgml: + * pango/pango-impl-utils.h: + * pango/pangocairo-atsuifont.c + (pango_cairo_atsui_font_create_metrics_for_context): + * pango/pangocairo-win32font.c + (pango_cairo_win32_font_create_metrics_for_context): + * pango/pangofc-font.c (pango_fc_font_create_metrics_for_context): + For approximate_char_width calculation take each char's width into + account. That is, do a weighted average instead of uniform average. + g_unichar_iszerowidth() chars count as 0, g_unichar_iswide() chars + count 2, and the rest count as 1. Pretty much wcwidth() behavior. + See bug report for rationale. + +2008-11-28 Behdad Esfahbod <behdad@gnome.org> + + Bug 562574 – Pangocariowin32 is leaking every cairo font it ever + creates + + * pango/pangocairo-atsuifont.c (pango_cairo_atsui_font_finalize): + * pango/pangocairo-win32font.c (pango_cairo_win32_font_finalize): + Finalize shared pangocairo font resources. Oops! + + * pango/pangocairo-font.c (_pango_cairo_font_private_finalize): + Protect against multiple calls to finalize. This is practiced by the + pangocairo-fcfont when a font is shutdown and then finalized. + +2008-11-26 Behdad Esfahbod <behdad@gnome.org> + + * examples/cairotwisted.c (parametrize_path), (point_on_path): + Handle close_path correctly. + 2008-11-23 Behdad Esfahbod <behdad@gnome.org> * === Released 1.22.3 === diff -aur old/docs/tmpl/fonts.sgml new/docs/tmpl/fonts.sgml --- old/docs/tmpl/fonts.sgml 2008-12-06 14:35:11.450807479 +0800 +++ new/docs/tmpl/fonts.sgml 2008-12-06 14:34:53.771786070 +0800 @@ -441,7 +441,10 @@ @descent: the distance from the baseline to the lowest point of the glyphs of the font. This is positive in practically all fonts. @approximate_char_width: approximate average width of the regular glyphs of - the font. + the font. Note that for this calculation, East Asian characters + (those passing g_unichar_iswide()) are counted as double-width. + This produces a more uniform value for this measure across languages + and results in more uniform and more expected UI sizes. @approximate_digit_width: approximate average width of the glyphs for digits of the font. @underline_position: position of the underline. This is normally negative. diff -aur old/examples/cairotwisted.c new/examples/cairotwisted.c --- old/examples/cairotwisted.c 2008-12-06 14:35:32.900725834 +0800 +++ new/examples/cairotwisted.c 2008-12-06 14:35:11.264059243 +0800 @@ -216,7 +216,7 @@ parametrize_path (cairo_path_t *path) { int i; - cairo_path_data_t *data, current_point; + cairo_path_data_t *data, last_move_to, current_point; parametrization_t *parametrization; parametrization = malloc (path->num_data * sizeof (parametrization[0])); @@ -226,8 +226,13 @@ parametrization[i] = 0.0; switch (data->header.type) { case CAIRO_PATH_MOVE_TO: + last_move_to = data[1]; current_point = data[1]; break; + case CAIRO_PATH_CLOSE_PATH: + /* Make it look like it's a line_to to last_move_to */ + data = (&last_move_to) - 1; + /* fall through */ case CAIRO_PATH_LINE_TO: parametrization[i] = two_points_distance (¤t_point, &data[1]); current_point = data[1]; @@ -245,8 +250,6 @@ current_point = data[3]; break; - case CAIRO_PATH_CLOSE_PATH: - break; default: g_assert_not_reached (); } @@ -320,7 +323,7 @@ { int i; double ratio, the_y = *y, the_x = *x, dx, dy; - cairo_path_data_t *data, current_point; + cairo_path_data_t *data, last_move_to, current_point; cairo_path_t *path = param->path; parametrization_t *parametrization = param->parametrization; @@ -333,6 +336,7 @@ switch (data->header.type) { case CAIRO_PATH_MOVE_TO: current_point = data[1]; + last_move_to = data[1]; break; case CAIRO_PATH_LINE_TO: current_point = data[1]; @@ -352,6 +356,10 @@ case CAIRO_PATH_MOVE_TO: break; + case CAIRO_PATH_CLOSE_PATH: + /* Make it look like it's a line_to to last_move_to */ + data = (&last_move_to) - 1; + /* fall through */ case CAIRO_PATH_LINE_TO: { ratio = the_x / parametrization[i]; @@ -424,8 +432,6 @@ *y += dx * ratio; } break; - case CAIRO_PATH_CLOSE_PATH: - break; default: g_assert_not_reached (); } diff -aur old/pango/pango-impl-utils.h new/pango/pango-impl-utils.h --- old/pango/pango-impl-utils.h 2008-12-06 14:35:22.291559359 +0800 +++ new/pango/pango-impl-utils.h 2008-12-06 14:35:03.550729660 +0800 @@ -23,6 +23,7 @@ #ifndef __PANGO_IMPL_UTILS_H__ #define __PANGO_IMPL_UTILS_H__ +#include <glib.h> #include <glib-object.h> #include <pango/pango.h> @@ -92,6 +93,36 @@ PangoRectangle *ink_rect, PangoRectangle *logical_rect); + +/* We define these functions static here because we don't want to add public API + * for them (if anything, it belongs to glib, but glib found it trivial enough + * not to add API for). At some point metrics calculations will be + * centralized and this mess can be minimized. Or so I hope. + */ + +static inline G_GNUC_UNUSED int +pango_unichar_width (gunichar c) +{ + return G_UNLIKELY (g_unichar_iszerowidth (c)) ? 0 : + G_UNLIKELY (g_unichar_iswide (c)) ? 2 : 1; +} + +static G_GNUC_UNUSED glong +pango_utf8_strwidth (const gchar *p) +{ + glong len = 0; + g_return_val_if_fail (p != NULL, 0); + + while (*p) + { + len += pango_unichar_width (g_utf8_get_char (p)); + p = g_utf8_next_char (p); + } + + return len; +} + + G_END_DECLS #endif /* __PANGO_IMPL_UTILS_H__ */ diff -aur old/pango/pangocairo-atsuifont.c new/pango/pangocairo-atsuifont.c --- old/pango/pangocairo-atsuifont.c 2008-12-06 14:35:23.464057615 +0800 +++ new/pango/pangocairo-atsuifont.c 2008-12-06 14:35:04.914061436 +0800 @@ -24,6 +24,7 @@ #import <Cocoa/Cocoa.h> +#include "pango-impl-utils.h" #include "pangoatsui-private.h" #include "pangocairo.h" #include "pangocairo-private.h" @@ -148,7 +149,7 @@ pango_layout_set_text (layout, sample_str, -1); pango_layout_get_extents (layout, NULL, &extents); - metrics->approximate_char_width = extents.width / g_utf8_strlen (sample_str, -1); + metrics->approximate_char_width = extents.width / pango_utf8_strwidth (sample_str); pango_layout_set_text (layout, "0123456789", -1); metrics->approximate_digit_width = max_glyph_width (layout); @@ -174,6 +175,10 @@ static void pango_cairo_atsui_font_finalize (GObject *object) { + PangoCairoATSUIFont *cafont = (PangoCairoATSUIFont *) object; + + _pango_cairo_font_private_finalize (&cafont->cf_priv); + G_OBJECT_CLASS (pango_cairo_atsui_font_parent_class)->finalize (object); } @@ -191,7 +196,7 @@ } static void -pango_cairo_atsui_font_init (PangoCairoATSUIFont *cafont) +pango_cairo_atsui_font_init (PangoCairoATSUIFont *cafont G_GNUC_UNUSED) { } diff -aur old/pango/pangocairo-fcfont.c new/pango/pangocairo-fcfont.c --- old/pango/pangocairo-fcfont.c 2008-12-06 14:35:22.840724772 +0800 +++ new/pango/pangocairo-fcfont.c 2008-12-06 14:35:04.294060844 +0800 @@ -88,7 +88,7 @@ static void pango_cairo_fc_font_finalize (GObject *object) { - PangoCairoFcFont *cffont = (PangoCairoFcFont *) (object); + PangoCairoFcFont *cffont = (PangoCairoFcFont *) object; _pango_cairo_font_private_finalize (&cffont->cf_priv); @@ -162,7 +162,7 @@ } static void -pango_cairo_fc_font_init (PangoCairoFcFont *cffont) +pango_cairo_fc_font_init (PangoCairoFcFont *cffont G_GNUC_UNUSED) { } diff -aur old/pango/pangocairo-font.c new/pango/pangocairo-font.c --- old/pango/pangocairo-font.c 2008-12-06 14:35:23.387391067 +0800 +++ new/pango/pangocairo-font.c 2008-12-06 14:35:04.840728398 +0800 @@ -560,14 +560,18 @@ if (cf_priv->scaled_font) cairo_scaled_font_destroy (cf_priv->scaled_font); + cf_priv->scaled_font = NULL; _pango_cairo_font_hex_box_info_destroy (cf_priv->hbi); + cf_priv->hbi = NULL; if (cf_priv->glyph_extents_cache) g_free (cf_priv->glyph_extents_cache); + cf_priv->glyph_extents_cache = NULL; g_slist_foreach (cf_priv->metrics_by_lang, (GFunc)free_metrics_info, NULL); g_slist_free (cf_priv->metrics_by_lang); + cf_priv->metrics_by_lang = NULL; } gboolean diff -aur old/pango/pangocairo-win32font.c new/pango/pangocairo-win32font.c --- old/pango/pangocairo-win32font.c 2008-12-06 14:35:22.500726273 +0800 +++ new/pango/pangocairo-win32font.c 2008-12-06 14:35:03.990726207 +0800 @@ -150,7 +150,7 @@ pango_layout_set_text (layout, sample_str, -1); pango_layout_get_extents (layout, NULL, &extents); - metrics->approximate_char_width = extents.width / g_utf8_strlen (sample_str, -1); + metrics->approximate_char_width = extents.width / pango_utf8_strwidth (sample_str); pango_layout_set_text (layout, "0123456789", -1); metrics->approximate_digit_width = max_glyph_width (layout); @@ -164,6 +164,10 @@ static void pango_cairo_win32_font_finalize (GObject *object) { + PangoCairoWin32Font *cwfont = (PangoCairoWin32Font *) object; + + _pango_cairo_font_private_finalize (&cwfont->cf_priv); + G_OBJECT_CLASS (pango_cairo_win32_font_parent_class)->finalize (object); } @@ -225,7 +229,7 @@ } static void -pango_cairo_win32_font_init (PangoCairoWin32Font *cwfont) +pango_cairo_win32_font_init (PangoCairoWin32Font *cwfont G_GNUC_UNUSED) { } diff -aur old/pango/pangofc-font.c new/pango/pangofc-font.c --- old/pango/pangofc-font.c 2008-12-06 14:35:23.117390557 +0800 +++ new/pango/pangofc-font.c 2008-12-06 14:35:04.564059609 +0800 @@ -496,7 +496,7 @@ pango_layout_get_extents (layout, NULL, &extents); metrics->approximate_char_width = - extents.width / g_utf8_strlen (sample_str, -1); + extents.width / pango_utf8_strwidth (sample_str); pango_layout_set_text (layout, "0123456789", -1); metrics->approximate_digit_width = max_glyph_width (layout);