diff options
-rw-r--r-- | ChangeLog | 37 | ||||
-rw-r--r-- | pango/pangocairo-win32font.c | 177 | ||||
-rw-r--r-- | pango/pangowin32-fontmap.c | 24 | ||||
-rw-r--r-- | pango/pangowin32-private.h | 7 | ||||
-rw-r--r-- | pango/pangowin32.c | 8 |
5 files changed, 194 insertions, 59 deletions
@@ -1,3 +1,40 @@ +2005-09-14 Tor Lillqvist <tml@novell.com> + + * pango/pangocairo-win32font.c (struct _PangoCairoWin32Font): Have + a list of metrics by language instead of just one metrics. + + (pango_cairo_win32_font_get_scaled_font): Use the name cwfont + instead of cffont. + + (free_metrics_info, pango_cairo_win32_font_finalize): Free the + metrics by language list. + + (create_metrics_for_context): New helper function. Approximate the + character and digit widths correctly. (#314114) + + (pango_cairo_win32_font_get_metrics): Use the list of metrics by + language. Call create_metrics_for_context() to measure metrics. + + (_pango_cairo_win32_font_new): Keep the PangoWin32Font objects in + the PangoWin32Face::cached_fonts, like the pangowin32 backend + does. + + PangoWin32Face::cached_fonts isn't really a proper cache. It's a + list with unbound length, one PangoWin32Font per size. Once there + is cacheing in cairo this can be dropped presumably? What does the + pangofc backend do? There are too many levels of cacheing going + on: we have the stuff in pangowin32-fontcache.c (unused now with + cairo), the PangoWin32FontMap::freed_fonts cache, and the + PangoWin32::cached_fonts list. + + * pango/pangowin32-fontmap.c (pango_win32_fontmap_cache_remove, + pango_win32_fontmap_cache_clear): Use GQueue API instead of + manipulating pointers manually. + + * pango/pangowin32-private.h + * pango/pangowin32.c: Move PangoWin32MetricsInfo to the private + header file, as also pangocairo-win32font.c uses it. + 2005-09-13 Tor Lillqvist <tml@novell.com> * modules/basic/basic-win32.c: Drop unused font_cache variable and diff --git a/pango/pangocairo-win32font.c b/pango/pangocairo-win32font.c index aef7fa04..dc31b8b0 100644 --- a/pango/pangocairo-win32font.c +++ b/pango/pangocairo-win32font.c @@ -26,6 +26,7 @@ #include <string.h> #include "pango-fontmap.h" +#include "pango-utils.h" #include "pangocairo-private.h" #include "pangocairo-win32.h" @@ -53,7 +54,7 @@ struct _PangoCairoWin32Font cairo_matrix_t ctm; cairo_font_options_t *options; - PangoFontMetrics *metrics; + GSList *metrics_by_lang; }; struct _PangoCairoWin32FontClass @@ -77,9 +78,9 @@ pango_cairo_win32_font_get_font_face (PangoCairoFont *font) { LOGFONTW logfontw; - /* Count here on the fact that all the struct fields are - * in the same place for LOGFONTW and LOGFONTA and LOGFONTA - * is smaller + /* 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)); @@ -103,26 +104,26 @@ pango_cairo_win32_font_get_font_face (PangoCairoFont *font) static cairo_scaled_font_t * pango_cairo_win32_font_get_scaled_font (PangoCairoFont *font) { - PangoCairoWin32Font *cffont = PANGO_CAIRO_WIN32_FONT (font); + PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font); - if (!cffont->scaled_font) + if (!cwfont->scaled_font) { cairo_font_face_t *font_face; font_face = pango_cairo_win32_font_get_font_face (font); - cffont->scaled_font = cairo_scaled_font_create (font_face, - &cffont->font_matrix, - &cffont->ctm, - cffont->options); + cwfont->scaled_font = cairo_scaled_font_create (font_face, + &cwfont->font_matrix, + &cwfont->ctm, + cwfont->options); /* Failure of the above should only occur for out of memory, * we can't proceed at that point */ - if (!cffont->scaled_font) + if (!cwfont->scaled_font) g_error ("Unable create Cairo font"); } - return cffont->scaled_font; + return cwfont->scaled_font; } /******************************** @@ -151,13 +152,20 @@ G_DEFINE_TYPE_WITH_CODE (PangoCairoWin32Font, pango_cairo_win32_font, PANGO_TYPE { G_IMPLEMENT_INTERFACE (PANGO_TYPE_CAIRO_FONT, cairo_font_iface_init) }); static void +free_metrics_info (PangoWin32MetricsInfo *info) +{ + pango_font_metrics_unref (info->metrics); + g_free (info); +} + +static void pango_cairo_win32_font_finalize (GObject *object) { PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (object); - if (cwfont->metrics) - pango_font_metrics_unref (cwfont->metrics); - + g_slist_foreach (cwfont->metrics_by_lang, (GFunc)free_metrics_info, NULL); + g_slist_free (cwfont->metrics_by_lang); + if (cwfont->scaled_font) cairo_scaled_font_destroy (cwfont->scaled_font); @@ -208,36 +216,104 @@ pango_cairo_win32_font_get_glyph_extents (PangoFont *font, } static PangoFontMetrics * +create_metrics_for_context (PangoFont *font, + PangoContext *context) +{ + PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font); + PangoFontMetrics *metrics; + PangoFontDescription *font_desc; + PangoLayout *layout; + PangoRectangle extents; + PangoLanguage *language = pango_context_get_language (context); + const char *sample_str = pango_language_get_sample_string (language); + cairo_scaled_font_t *scaled_font; + cairo_font_extents_t font_extents; + double height; + + metrics = pango_font_metrics_new (); + + scaled_font = pango_cairo_win32_font_get_scaled_font (PANGO_CAIRO_FONT (cwfont)); + + cairo_scaled_font_extents (scaled_font, &font_extents); + cairo_win32_scaled_font_done_font (scaled_font); + + metrics->ascent = font_extents.ascent * PANGO_SCALE; + metrics->descent = font_extents.descent * PANGO_SCALE; + + /* FIXME: Should get the real settings for these from the TrueType + * font file. + */ + height = metrics->ascent + metrics->descent; + metrics->underline_thickness = height / 14; + metrics->underline_position = - metrics->underline_thickness; + metrics->strikethrough_thickness = metrics->underline_thickness; + metrics->strikethrough_position = height / 4; + + layout = pango_layout_new (context); + font_desc = pango_font_describe (font); + pango_layout_set_font_description (layout, font_desc); + 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); + + pango_layout_set_text (layout, "0123456789", -1); + pango_layout_get_extents (layout, NULL, &extents); + + metrics->approximate_digit_width = extents.width / 10; + + pango_font_description_free (font_desc); + g_object_unref (layout); + + return metrics; +} + +static PangoFontMetrics * pango_cairo_win32_font_get_metrics (PangoFont *font, PangoLanguage *language) { + PangoWin32Font *win32font = PANGO_WIN32_FONT (font); PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font); + PangoWin32MetricsInfo *info = NULL; /* Quiet gcc */ + GSList *tmp_list; + const char *sample_str = pango_language_get_sample_string (language); + + tmp_list = cwfont->metrics_by_lang; + while (tmp_list) + { + info = tmp_list->data; + + if (info->sample_str == sample_str) /* We _don't_ need strcmp */ + break; + + tmp_list = tmp_list->next; + } - if (!cwfont->metrics) + if (!tmp_list) { - double height; - cairo_scaled_font_t *scaled_font; - cairo_font_extents_t font_extents; - cwfont->metrics = pango_font_metrics_new (); + PangoContext *context; - scaled_font = pango_cairo_win32_font_get_scaled_font (PANGO_CAIRO_FONT (font)); + if (!win32font->fontmap) + return pango_font_metrics_new (); - cairo_scaled_font_extents (scaled_font, &font_extents); + info = g_new0 (PangoWin32MetricsInfo, 1); - cwfont->metrics->ascent = font_extents.ascent * PANGO_SCALE; - cwfont->metrics->descent = font_extents.descent * PANGO_SCALE; - cwfont->metrics->approximate_char_width = font_extents.max_x_advance * PANGO_SCALE; - cwfont->metrics->approximate_digit_width = font_extents.max_x_advance * PANGO_SCALE; + cwfont->metrics_by_lang = g_slist_prepend (cwfont->metrics_by_lang, + info); + + info->sample_str = sample_str; - height = font_extents.ascent + font_extents.descent; - - cwfont->metrics->underline_thickness = (PANGO_SCALE * height) / 14; - cwfont->metrics->underline_position = - cwfont->metrics->underline_thickness; - cwfont->metrics->strikethrough_thickness = cwfont->metrics->underline_thickness; - cwfont->metrics->strikethrough_position = (PANGO_SCALE * height) / 4; + context = pango_context_new (); + pango_context_set_font_map (context, win32font->fontmap); + pango_context_set_language (context, language); + pango_cairo_context_set_font_options (context, cwfont->options); + + info->metrics = create_metrics_for_context (font, context); + + g_object_unref (context); } - return pango_font_metrics_ref (cwfont->metrics); + return pango_font_metrics_ref (info->metrics); } static gboolean @@ -303,7 +379,36 @@ _pango_cairo_win32_font_new (PangoCairoWin32FontMap *cwfontmap, const PangoMatrix *pango_ctm; double size; double dpi; - +#define USE_FACE_CACHED_FONTS +#ifdef USE_FACE_CACHED_FONTS + PangoWin32FontMap *win32fontmap; + GSList *tmp_list; + int isize; +#endif + + g_return_val_if_fail (PANGO_IS_CAIRO_WIN32_FONT_MAP (cwfontmap), NULL); + +#ifdef USE_FACE_CACHED_FONTS + win32fontmap = PANGO_WIN32_FONT_MAP (cwfontmap); + isize = pango_font_description_get_size (desc); + if (!pango_font_description_get_size_is_absolute (desc)) + isize = (int) 0.5 + (isize * PANGO_SCALE) / win32fontmap->resolution; + + tmp_list = face->cached_fonts; + while (tmp_list) + { + win32font = tmp_list->data; + if (ABS (win32font->size- isize) < 2) + { + g_object_ref (win32font); + if (win32font->in_cache) + pango_win32_fontmap_cache_remove (PANGO_FONT_MAP (win32fontmap), win32font); + + return PANGO_FONT (win32font); + } + tmp_list = tmp_list->next; + } +#endif cwfont = g_object_new (PANGO_TYPE_CAIRO_WIN32_FONT, NULL); win32font = PANGO_WIN32_FONT (cwfont); @@ -312,6 +417,10 @@ _pango_cairo_win32_font_new (PangoCairoWin32FontMap *cwfontmap, win32font->win32face = face; +#ifdef USE_FACE_CACHED_FONTS + face->cached_fonts = g_slist_prepend (face->cached_fonts, win32font); +#endif + size = (double) pango_font_description_get_size (desc) / PANGO_SCALE; if (context) diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c index 37cb279c..171883fa 100644 --- a/pango/pangowin32-fontmap.c +++ b/pango/pangowin32-fontmap.c @@ -88,6 +88,8 @@ static void pango_win32_fontmap_cache_clear (PangoWin32FontMap static void pango_win32_insert_font (PangoWin32FontMap *fontmap, LOGFONT *lfp); +static PangoWin32FontMap *default_fontmap = NULL; + G_DEFINE_TYPE (PangoWin32FontMap, pango_win32_font_map, PANGO_TYPE_FONT_MAP) /* A hash function for LOGFONTs that takes into consideration only @@ -177,7 +179,6 @@ pango_win32_font_map_init (PangoWin32FontMap *win32fontmap) (LPARAM)win32fontmap, 0); win32fontmap->resolution = (PANGO_SCALE / (double) GetDeviceCaps (pango_win32_hdc, LOGPIXELSY)) * 72.0; - } static void @@ -199,8 +200,6 @@ pango_win32_font_map_class_init (PangoWin32FontMapClass *class) pango_module_register (&_pango_included_win32_modules[i]); } -static PangoWin32FontMap *default_fontmap = NULL; - /** * pango_win32_font_map_for_display: * @@ -1031,17 +1030,10 @@ pango_win32_fontmap_cache_remove (PangoFontMap *fontmap, PangoWin32Font *win32font) { PangoWin32FontMap *win32fontmap = PANGO_WIN32_FONT_MAP (fontmap); + GList *link = g_queue_find (win32fontmap->freed_fonts, win32font); - GList *link = g_list_find (win32fontmap->freed_fonts->head, win32font); - if (link == win32fontmap->freed_fonts->tail) - { - win32fontmap->freed_fonts->tail = win32fontmap->freed_fonts->tail->prev; - if (win32fontmap->freed_fonts->tail) - win32fontmap->freed_fonts->tail->next = NULL; - } - - win32fontmap->freed_fonts->head = g_list_delete_link (win32fontmap->freed_fonts->head, link); - win32fontmap->freed_fonts->length--; + if (link) + g_queue_delete_link (win32fontmap->freed_fonts, link); win32font->in_cache = FALSE; g_object_unref (win32font); @@ -1051,8 +1043,6 @@ static void pango_win32_fontmap_cache_clear (PangoWin32FontMap *win32fontmap) { g_list_foreach (win32fontmap->freed_fonts->head, (GFunc)g_object_unref, NULL); - g_list_free (win32fontmap->freed_fonts->head); - win32fontmap->freed_fonts->head = NULL; - win32fontmap->freed_fonts->tail = NULL; - win32fontmap->freed_fonts->length = 0; + g_queue_free (win32fontmap->freed_fonts); + win32fontmap->freed_fonts = g_queue_new (); } diff --git a/pango/pangowin32-private.h b/pango/pangowin32-private.h index 40916e4f..1e5e999c 100644 --- a/pango/pangowin32-private.h +++ b/pango/pangowin32-private.h @@ -84,6 +84,7 @@ typedef struct _PangoWin32Font PangoWin32Font; typedef struct _PangoWin32FontClass PangoWin32FontClass; typedef struct _PangoWin32Face PangoWin32Face; typedef struct _PangoWin32GlyphInfo PangoWin32GlyphInfo; +typedef struct _PangoWin32MetricsInfo PangoWin32MetricsInfo; struct _PangoWin32FontMap { @@ -173,6 +174,12 @@ struct _PangoWin32GlyphInfo PangoRectangle ink_rect; }; +struct _PangoWin32MetricsInfo +{ + const char *sample_str; + PangoFontMetrics *metrics; +}; + /* TrueType defines: */ #define MAKE_TT_TABLE_NAME(c1, c2, c3, c4) \ diff --git a/pango/pangowin32.c b/pango/pangowin32.c index b7769650..bd1908a9 100644 --- a/pango/pangowin32.c +++ b/pango/pangowin32.c @@ -42,14 +42,6 @@ HDC pango_win32_hdc; OSVERSIONINFO pango_win32_os_version_info; gboolean pango_win32_debug = FALSE; -typedef struct _PangoWin32MetricsInfo PangoWin32MetricsInfo; - -struct _PangoWin32MetricsInfo -{ - const char *sample_str; - PangoFontMetrics *metrics; -}; - static void pango_win32_font_dispose (GObject *object); static void pango_win32_font_finalize (GObject *object); |