summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorTor Lillqvist <tml@novell.com>2005-09-14 04:05:51 +0000
committerTor Lillqvist <tml@src.gnome.org>2005-09-14 04:05:51 +0000
commit76382d08e3a42c8dd425e308d73a6a4f0f49c9d9 (patch)
tree7f2a14733562614b2960aaca88ac9068b4733e13 /pango
parent74f0a825227c1fe752aa3bb0154f4837370c158f (diff)
downloadpango-76382d08e3a42c8dd425e308d73a6a4f0f49c9d9.tar.gz
Have a list of metrics by language instead of just one metrics.
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.
Diffstat (limited to 'pango')
-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
4 files changed, 157 insertions, 59 deletions
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);