[patch] PangoFT2FontCache::remove
- From: Sven Neumann <sven gimp org>
- To: <gtk-devel-list gnome org>
- Subject: [patch] PangoFT2FontCache::remove
- Date: 13 Mar 2001 21:04:37 +0100
Hi,
> > b) Add some sort of callback from the internal font cache so that when
> > fonts are dropped an external glyph cache can be notified. I don'r think
> > caching glyphs when not cacheing other font information is useful, so this
> > should be enough to make it possible to use <pango_ft2_get_face(),
> > glyph_index> to index the images in the glyph cache.
OK, here's a patch that changes PangoFT2FontCache to be a GObject that
emits a "remove" signal if a face gets unloaded from the cache.
The problem is that the signal is never emitted since the faces are
never removed. Although the fontcache removes faces from its MRU list
and unrefs them as soon as there are more than 10 fonts, they are never
really removed from the cache since pango_ft2_font_cache_unload() is
never called, so the refcount never drops to zero.
Please use the patch if you like it, but to make it really work, the
caching in PangoFT2 will need some more changes.
Salut, Sven
Index: pangoft2-fontcache.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangoft2-fontcache.c,v
retrieving revision 1.8
diff -u -r1.8 pangoft2-fontcache.c
--- pangoft2-fontcache.c 2000/12/21 09:54:01 1.8
+++ pangoft2-fontcache.c 2001/03/13 19:56:25
@@ -24,6 +24,7 @@
#include <string.h>
+
/* Font cache
*/
@@ -35,6 +36,8 @@
struct _PangoFT2FontCache
{
+ GObject parent_instance;
+
FT_Library library;
GHashTable *forward;
@@ -45,6 +48,11 @@
int mru_count;
};
+struct _PangoFT2FontCacheClass
+{
+ GObjectClass parent_class;
+};
+
struct _CacheEntry
{
PangoFT2OA oa;
@@ -54,79 +62,91 @@
GList *mru;
};
-static void
-free_cache_entry (PangoFT2OA *oa,
- CacheEntry *entry,
- PangoFT2FontCache *cache)
+
+enum
{
- FT_Error error;
+ REMOVE,
+ LAST_SIGNAL
+};
- PING (("FT_Done_Face (%p)", entry->face));
+static GObjectClass *parent_class;
+static guint font_cache_signals[LAST_SIGNAL] = { 0, };
- error = FT_Done_Face (entry->face);
- if (error != FT_Err_Ok)
- g_warning ("Error from FT_Done_Face: %s",
- pango_ft2_ft_strerror (error));
- g_free (entry);
-}
+static void pango_ft2_font_cache_init (PangoFT2FontCache *cache);
+static void pango_ft2_font_cache_class_init (PangoFT2FontCacheClass *class);
+static void pango_ft2_font_cache_finalize (GObject *object);
+
+static void free_cache_entry (PangoFT2OA *oa,
+ CacheEntry *entry,
+ PangoFT2FontCache *cache);
+static guint oa_hash (gconstpointer v);
+static gint oa_equal (gconstpointer v1,
+ gconstpointer v2);
+static void cache_entry_unref (PangoFT2FontCache *cache,
+ CacheEntry *entry);
-/**
- * pango_ft2_font_cache_free:
- * @cache: a #PangoFT2FontCache
- *
- * Free a #PangoFT2FontCache and all associated memory. All fonts loaded
- * through this font cache will be freed along with the cache.
- **/
-void
-pango_ft2_font_cache_free (PangoFT2FontCache *cache)
+
+GType
+pango_ft2_font_cache_get_type (void)
{
- g_return_if_fail (cache != NULL);
-
- g_hash_table_foreach (cache->forward, (GHFunc)free_cache_entry, cache);
-
- g_hash_table_destroy (cache->forward);
- g_hash_table_destroy (cache->back);
+ static GType object_type = 0;
- g_list_free (cache->mru);
+ if (!object_type)
+ {
+ static const GTypeInfo object_info =
+ {
+ sizeof (PangoFT2FontCacheClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) pango_ft2_font_cache_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PangoFT2FontCache),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) pango_ft2_font_cache_init,
+ };
+
+ object_type = g_type_register_static (G_TYPE_OBJECT,
+ "PangoFT2FontCache",
+ &object_info, 0);
+ }
+
+ return object_type;
}
-static guint
-oa_hash (gconstpointer v)
+static void
+pango_ft2_font_cache_class_init (PangoFT2FontCacheClass *class)
{
- PangoFT2OA *oa = (PangoFT2OA *) v;
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GType param_types[1] = { G_TYPE_POINTER };
- if (oa->open_args->flags & ft_open_memory)
- return (guint) oa->open_args->memory_base;
- else if (oa->open_args->flags == ft_open_pathname)
- return g_str_hash (oa->open_args->pathname);
- else if (oa->open_args->flags & ft_open_stream)
- return (guint) oa->open_args->stream;
- else
- return 0;
+ parent_class = g_type_class_peek_parent (class);
+
+ font_cache_signals[REMOVE] =
+ g_signal_newv ("remove",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ NULL, /* class closure */
+ NULL, NULL, /* accumulator */
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE,
+ 1, param_types);
+
+ object_class->finalize = pango_ft2_font_cache_finalize;
}
-static gint
-oa_equal (gconstpointer v1,
- gconstpointer v2)
+static void
+pango_ft2_font_cache_init (PangoFT2FontCache *cache)
{
- PangoFT2OA *oa1 = (PangoFT2OA *) v1;
- PangoFT2OA *oa2 = (PangoFT2OA *) v2;
+ cache->library = NULL;
- if (oa1->open_args->flags != oa2->open_args->flags)
- return 0;
- else if (oa1->open_args->flags & ft_open_memory)
- return (oa1->open_args->memory_base == oa2->open_args->memory_base &&
- oa1->face_index == oa2->face_index);
- else if (oa1->open_args->flags == ft_open_pathname)
- return (strcmp (oa1->open_args->pathname,
- oa2->open_args->pathname) == 0 &&
- oa1->face_index == oa2->face_index);
- else if (oa1->open_args->flags & ft_open_stream)
- return (oa1->open_args->stream == oa2->open_args->stream &&
- oa1->face_index == oa2->face_index);
- else
- return 0;
+ cache->forward = g_hash_table_new (oa_hash, oa_equal);
+ cache->back = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ cache->mru = NULL;
+ cache->mru_tail = NULL;
+ cache->mru_count = 0;
}
/**
@@ -135,41 +155,40 @@
*
* Create a font cache.
*
- * Return value: The new font cache. This must be freed with
- * pango_ft2_font_cache_free().
+ * Return value: The new font cache object. All fonts loaded
+ * through this font cache will be freed if the object gets
+ * destroyed.
**/
PangoFT2FontCache *
pango_ft2_font_cache_new (FT_Library library)
{
PangoFT2FontCache *cache;
- cache = g_new (PangoFT2FontCache, 1);
+ g_return_val_if_fail (library != NULL, NULL);
- cache->library = library;
-
- cache->forward = g_hash_table_new (oa_hash, oa_equal);
- cache->back = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- cache->mru = NULL;
- cache->mru_tail = NULL;
- cache->mru_count = 0;
+ cache = g_object_new (pango_ft2_font_cache_get_type (), NULL);
+
+ cache->library = library;
- return cache;
+ return PANGO_FT2_FONT_CACHE (cache);
}
static void
-cache_entry_unref (PangoFT2FontCache *cache,
- CacheEntry *entry)
+pango_ft2_font_cache_finalize (GObject *object)
{
- entry->ref_count--;
- PING (("face:%p ref_count:%d", entry->face, entry->ref_count));
- if (entry->ref_count == 0)
- {
- g_hash_table_remove (cache->forward, &entry->oa);
- g_hash_table_remove (cache->back, entry->face);
+ PangoFT2FontCache *cache;
- free_cache_entry (NULL, entry, cache);
- }
+ cache = PANGO_FT2_FONT_CACHE (object);
+
+ g_hash_table_foreach (cache->forward, (GHFunc)free_cache_entry, cache);
+
+ g_hash_table_destroy (cache->forward);
+ g_hash_table_destroy (cache->back);
+
+ g_list_free (cache->mru);
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
/**
@@ -194,7 +213,7 @@
CacheEntry *entry;
PangoFT2OA oa;
- g_return_val_if_fail (cache != NULL, NULL);
+ g_return_val_if_fail (PANGO_FT2_IS_FONT_CACHE (cache), NULL);
g_return_val_if_fail (args != NULL, NULL);
oa.open_args = args;
@@ -299,7 +318,7 @@
{
CacheEntry *entry;
- g_return_if_fail (cache != NULL);
+ g_return_if_fail (PANGO_FT2_IS_FONT_CACHE (cache));
g_return_if_fail (face != NULL);
entry = g_hash_table_lookup (cache->back, face);
@@ -307,4 +326,77 @@
PING (("pango_ft2_font_cache_unload"));
cache_entry_unref (cache, entry);
+}
+
+static guint
+oa_hash (gconstpointer v)
+{
+ PangoFT2OA *oa = (PangoFT2OA *) v;
+
+ if (oa->open_args->flags & ft_open_memory)
+ return (guint) oa->open_args->memory_base;
+ else if (oa->open_args->flags == ft_open_pathname)
+ return g_str_hash (oa->open_args->pathname);
+ else if (oa->open_args->flags & ft_open_stream)
+ return (guint) oa->open_args->stream;
+ else
+ return 0;
+}
+
+static gint
+oa_equal (gconstpointer v1,
+ gconstpointer v2)
+{
+ PangoFT2OA *oa1 = (PangoFT2OA *) v1;
+ PangoFT2OA *oa2 = (PangoFT2OA *) v2;
+
+ if (oa1->open_args->flags != oa2->open_args->flags)
+ return 0;
+ else if (oa1->open_args->flags & ft_open_memory)
+ return (oa1->open_args->memory_base == oa2->open_args->memory_base &&
+ oa1->face_index == oa2->face_index);
+ else if (oa1->open_args->flags == ft_open_pathname)
+ return (strcmp (oa1->open_args->pathname,
+ oa2->open_args->pathname) == 0 &&
+ oa1->face_index == oa2->face_index);
+ else if (oa1->open_args->flags & ft_open_stream)
+ return (oa1->open_args->stream == oa2->open_args->stream &&
+ oa1->face_index == oa2->face_index);
+ else
+ return 0;
+}
+
+static void
+free_cache_entry (PangoFT2OA *oa,
+ CacheEntry *entry,
+ PangoFT2FontCache *cache)
+{
+ FT_Error error;
+
+ PING (("FT_Done_Face (%p)", entry->face));
+ g_signal_emit (G_OBJECT (cache),
+ font_cache_signals[REMOVE], 0,
+ entry->face);
+
+ error = FT_Done_Face (entry->face);
+ if (error != FT_Err_Ok)
+ g_warning ("Error from FT_Done_Face: %s",
+ pango_ft2_ft_strerror (error));
+
+ g_free (entry);
+}
+
+static void
+cache_entry_unref (PangoFT2FontCache *cache,
+ CacheEntry *entry)
+{
+ entry->ref_count--;
+ PING (("face:%p ref_count:%d", entry->face, entry->ref_count));
+ if (entry->ref_count == 0)
+ {
+ g_hash_table_remove (cache->forward, &entry->oa);
+ g_hash_table_remove (cache->back, entry->face);
+
+ free_cache_entry (NULL, entry, cache);
+ }
}
Index: pangoft2-fontmap.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangoft2-fontmap.c,v
retrieving revision 1.10
diff -u -r1.10 pangoft2-fontmap.c
--- pangoft2-fontmap.c 2001/02/04 07:04:06 1.10
+++ pangoft2-fontmap.c 2001/03/13 19:56:26
@@ -360,7 +360,7 @@
g_list_foreach (ft2fontmap->freed_fonts->head, (GFunc)g_object_unref, NULL);
g_queue_free (ft2fontmap->freed_fonts);
- pango_ft2_font_cache_free (ft2fontmap->font_cache);
+ g_object_unref (G_OBJECT (ft2fontmap->font_cache));
FT_Done_FreeType (ft2fontmap->library);
Index: pangoft2.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pangoft2.h,v
retrieving revision 1.5
diff -u -r1.5 pangoft2.h
--- pangoft2.h 2001/01/07 04:54:28 1.5
+++ pangoft2.h 2001/03/13 19:56:28
@@ -78,8 +78,17 @@
/* API for libraries that want to use PangoFT2 mixed with classic
* FT2 fonts.
*/
-typedef struct _PangoFT2FontCache PangoFT2FontCache;
+#define PANGO_TYPE_FT2_FONT_CACHE (pango_ft2_font_cache_get_type ())
+#define PANGO_FT2_FONT_CACHE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FT2_FONT_CACHE, PangoFT2FontCache))
+#define PANGO_FT2_FONT_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FT2_FONT_CACHE, PangoFT2FontCacheClass))
+#define PANGO_FT2_IS_FONT_CACHE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FT2_FONT_CACHE))
+#define PANGO_FT2_IS_FONT_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_FT2_FONT_CACHE))
+
+typedef struct _PangoFT2FontCache PangoFT2FontCache;
+typedef struct _PangoFT2FontCacheClass PangoFT2FontCacheClass;
+
+GType pango_ft2_font_cache_get_type (void);
PangoFT2FontCache *pango_ft2_font_cache_new (FT_Library library);
void pango_ft2_font_cache_free (PangoFT2FontCache *cache);
FT_Face pango_ft2_font_cache_load (PangoFT2FontCache *cache,
@@ -87,6 +96,7 @@
FT_Long face_index);
void pango_ft2_font_cache_unload (PangoFT2FontCache *cache,
FT_Face face);
+
PangoFontMap *pango_ft2_font_map_for_display (void);
void pango_ft2_shutdown_display (void);
PangoFT2FontCache *pango_ft2_font_map_get_font_cache (PangoFontMap *font_map);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]