=== modified file 'src/alloc.c' --- src/alloc.c 2013-10-23 16:07:30 +0000 +++ src/alloc.c 2013-10-24 05:48:47 +0000 @@ -2837,6 +2837,24 @@ return vroundup (size); } +/* Called when VECTOR is finally reclaimed by GC. + For now this is needed for font objects only. */ + +static void +finalize_vector (struct Lisp_Vector *vector) +{ + if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT) + && ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) + == FONT_OBJECT_MAX)) + { + struct font *font = (struct font *) vector; + + eassert (font->driver); + if (font->driver->finalize) + font->driver->finalize (font); + } +} + /* Reclaim space used by unmarked vectors. */ static void @@ -2871,6 +2889,7 @@ { ptrdiff_t total_bytes; + finalize_vector (vector); nbytes = vector_nbytes (vector); total_bytes = nbytes; next = ADVANCE (vector, nbytes); @@ -2882,6 +2901,7 @@ { if (VECTOR_MARKED_P (next)) break; + finalize_vector (next); nbytes = vector_nbytes (next); total_bytes += nbytes; next = ADVANCE (next, nbytes); === modified file 'src/font.h' --- src/font.h 2013-09-15 17:58:46 +0000 +++ src/font.h 2013-10-24 05:47:08 +0000 @@ -548,6 +548,10 @@ /* Close FONT on frame F. */ void (*close) (struct frame *f, struct font *font); + /* Finalize FONT when Lisp font-object is reclaimed. + NOTE: this is called by GC. */ + void (*finalize) (struct font *font); + /* Optional (if FACE->extra is not used). Prepare FACE for displaying characters by FONT on frame F by storing some data in FACE->extra. If successful, return 0. === modified file 'src/ftfont.c' --- src/ftfont.c 2013-10-11 06:32:29 +0000 +++ src/ftfont.c 2013-10-24 05:39:56 +0000 @@ -530,6 +530,7 @@ NULL, /* free_entity */ ftfont_open, ftfont_close, + NULL, /* no finalizer yet */ /* We can't draw a text without device dependent functions. */ NULL, /* prepare_face */ NULL, /* done_face */ === modified file 'src/xfont.c' --- src/xfont.c 2013-09-24 06:43:20 +0000 +++ src/xfont.c 2013-10-24 05:44:40 +0000 @@ -120,6 +120,7 @@ static Lisp_Object xfont_list_family (struct frame *); static Lisp_Object xfont_open (struct frame *, Lisp_Object, int); static void xfont_close (struct frame *, struct font *); +static void xfont_finalize (struct font *); static int xfont_prepare_face (struct frame *, struct face *); static int xfont_has_char (Lisp_Object, int); static unsigned xfont_encode_char (struct font *, int); @@ -139,6 +140,7 @@ NULL, xfont_open, xfont_close, + xfont_finalize, xfont_prepare_face, NULL, xfont_has_char, @@ -892,9 +894,24 @@ static void xfont_close (struct frame *f, struct font *font) { - block_input (); - XFreeFont (FRAME_X_DISPLAY (f), ((struct xfont_info *) font)->xfont); - unblock_input (); + xfont_finalize (font); +} + +/* Finalize X font FONT. NOTE: this is called by GC. */ + +static void +xfont_finalize (struct font *font) +{ + struct xfont_info *xfi = (struct xfont_info *) font; + + if (xfi->xfont) + { + eassert (xfi->display); + block_input (); + XFreeFont (xfi->display, xfi->xfont); + unblock_input (); + xfi->xfont = NULL; + } } static int === modified file 'src/xftfont.c' --- src/xftfont.c 2013-08-03 03:29:03 +0000 +++ src/xftfont.c 2013-10-24 05:43:12 +0000 @@ -494,10 +494,22 @@ if (xftfont_info->otf) OTF_close (xftfont_info->otf); #endif - block_input (); - XftUnlockFace (xftfont_info->xftfont); - XftFontClose (xftfont_info->display, xftfont_info->xftfont); - unblock_input (); + if (xftfont_info->xftfont) + { + block_input (); + XftUnlockFace (xftfont_info->xftfont); + XftFontClose (xftfont_info->display, xftfont_info->xftfont); + unblock_input (); + xftfont_info->xftfont = NULL; + } +} + +/* Finalize XFT font FONT. NOTE: this is called by GC. */ + +static void +xftfont_finalize (struct font *font) +{ + xftfont_close (NULL, font); } static int @@ -763,6 +775,7 @@ xftfont_driver.match = xftfont_match; xftfont_driver.open = xftfont_open; xftfont_driver.close = xftfont_close; + xftfont_driver.finalize = xftfont_finalize; xftfont_driver.prepare_face = xftfont_prepare_face; xftfont_driver.done_face = xftfont_done_face; xftfont_driver.has_char = xftfont_has_char;