summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog37
-rw-r--r--pango/pangocairo-win32font.c177
-rw-r--r--pango/pangowin32-fontmap.c24
-rw-r--r--pango/pangowin32-private.h7
-rw-r--r--pango/pangowin32.c8
5 files changed, 194 insertions, 59 deletions
diff --git a/ChangeLog b/ChangeLog
index f6251530..26269c02 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);