g_object_unref on PangoWin32FontMap fails
Submitted by Matthew Flatt
Link to original bug (#649293)
Description
If a PangoWin32FontMap has any "freed" fonts cached, then attempting to free the PangoWin32FontMap triggers an assertion failure as the "freed" fonts are actually freed in the finalizer.
I think the problem is that the fonts hold a weak reference to the font map, and the weak reference is cleared before the finalizer can free the fonts.
With apologies for providing Racket code instead of C code (it would take me a long time to set up my environment for C code), here's a demonstration that should be easy to port to any language:
#lang racket/base (require racket/draw/unsafe/pango)
(define fontmap (pango_cairo_font_map_new)) (define context (pango_font_map_create_context fontmap))
(define desc (pango_font_description_new)) (pango_font_description_set_family desc "Arial") (pango_font_description_set_absolute_size desc 120)
(define layout (pango_layout_new context)) (pango_layout_set_font_description layout desc) (pango_layout_set_text layout "hello")
;; Ensure that font is created and freed: (let ([logical (make-PangoRectangle 0 0 0 0)]) (pango_layout_get_extents layout #f logical))
(g_object_unref layout) (g_object_unref context)
;; Assertion failure happens here: (g_object_unref fontmap)
I'm not sure how to fix the problem properly, but I note that pango_win32_shutdown_display() calls a private pango_win32_fontmap_cache_clear() function to clear the cache of "freed" fonts before attempting to unref the default font map. It seems like that should somehow be built into the unref process for a Win32 font map.
(My workaround in Racket uses code equivalent to pango_win32_fontmap_cache_clear(), but that involves accessing private fields, etc.)
Version: 1.28.x