From cf86e18b159f754d6e5537b7b9cbefc32297f7d2 Mon Sep 17 00:00:00 2001 From: Dmitry Antipov Date: Thu, 12 Dec 2013 18:26:06 +0400 Subject: [PATCH] * font.h (struct font_entity) [HAVE_NS]: New field to record font driver which was used to create this entity. (struct font) [HAVE_WINDOW_SYSTEM]: New field to record frame where the font was opened. (font_close_object): Add prototype. * font.c (font_make_entity) [HAVE_NS]: Zero out driver field. (font_close_object): Not static any more. Lost frame arg. Adjust comment and users. * alloc.c (cleanup_vector): Call font_close_object to adjust per-frame font counters correctly. If HAVE_NS, also call driver-specific cleanup for font-entity objects. * ftfont.c (ftfont_open): * nsfont.m (nsfont_open): * w32font.c (w32font_open_internal): * xfont.c (xfont_open): * xftfont.c (xftfont_open): Save frame pointer in font object. * macfont.m (macfont_open): Likewise. (macfont_descriptor_entity): Save driver pointer to be able to call its free_entity routine when font-entity is swept. * ftxfont.c (ftxfont_open): Add eassert because frame pointer should be saved by ftfont_driver.open. --- src/ChangeLog | 24 ++++++++++++++++++++++++ src/alloc.c | 20 ++++++++++++++++---- src/font.c | 20 ++++++++++++-------- src/font.h | 7 +++++++ src/ftfont.c | 1 + src/ftxfont.c | 1 + src/macfont.m | 2 ++ src/nsfont.m | 1 + src/w32font.c | 1 + src/xfont.c | 1 + src/xftfont.c | 1 + 11 files changed, 67 insertions(+), 12 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 33675599390..e0f9b9e8689 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,27 @@ +2013-12-12 Dmitry Antipov + + * font.h (struct font_entity) [HAVE_NS]: New field to record + font driver which was used to create this entity. + (struct font) [HAVE_WINDOW_SYSTEM]: New field to record + frame where the font was opened. + (font_close_object): Add prototype. + * font.c (font_make_entity) [HAVE_NS]: Zero out driver field. + (font_close_object): Not static any more. Lost frame arg. + Adjust comment and users. + * alloc.c (cleanup_vector): Call font_close_object to adjust + per-frame font counters correctly. If HAVE_NS, also call + driver-specific cleanup for font-entity objects. + * ftfont.c (ftfont_open): + * nsfont.m (nsfont_open): + * w32font.c (w32font_open_internal): + * xfont.c (xfont_open): + * xftfont.c (xftfont_open): Save frame pointer in font object. + * macfont.m (macfont_open): Likewise. + (macfont_descriptor_entity): Save driver pointer to be able + to call its free_entity routine when font-entity is swept. + * ftxfont.c (ftxfont_open): Add eassert because frame + pointer should be saved by ftfont_driver.open. + 2013-12-12 Dmitry Antipov * xterm.c (x_make_frame_visible): Restore hack which is needed when diff --git a/src/alloc.c b/src/alloc.c index aeda42637cd..022d1e5dcbb 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -2874,10 +2874,22 @@ vector_nbytes (struct Lisp_Vector *v) static void cleanup_vector (struct Lisp_Vector *vector) { - if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT) - && ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) - == FONT_OBJECT_MAX)) - ((struct font *) vector)->driver->close ((struct font *) vector); + if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT)) + { + ptrdiff_t size = vector->header.size & PSEUDOVECTOR_SIZE_MASK; + Lisp_Object obj = make_lisp_ptr (vector, Lisp_Vectorlike); + + if (size == FONT_OBJECT_MAX) + font_close_object (obj); +#ifdef HAVE_NS + else if (size == FONT_ENTITY_MAX) + { + struct font_entity *entity = (struct font_entity *) vector; + if (entity->driver && entity->driver->free_entity) + entity->driver->free_entity (obj); + } +#endif /* HAVE_NS */ + } } /* Reclaim space used by unmarked vectors. */ diff --git a/src/font.c b/src/font.c index fb56b3d3fb3..d0a10332028 100644 --- a/src/font.c +++ b/src/font.c @@ -173,6 +173,9 @@ font_make_entity (void) allocate_pseudovector (VECSIZE (struct font_entity), FONT_ENTITY_MAX, PVEC_FONT)); XSETFONT (font_entity, entity); +#ifdef HAVE_NS + entity->driver = NULL; +#endif return font_entity; } @@ -2881,10 +2884,10 @@ font_open_entity (struct frame *f, Lisp_Object entity, int pixel_size) } -/* Close FONT_OBJECT that is opened on frame F. */ +/* Close FONT_OBJECT. */ -static void -font_close_object (struct frame *f, Lisp_Object font_object) +void +font_close_object (Lisp_Object font_object) { struct font *font = XFONT_OBJECT (font_object); @@ -2894,8 +2897,9 @@ font_close_object (struct frame *f, Lisp_Object font_object) FONT_ADD_LOG ("close", font_object, Qnil); font->driver->close (font); #ifdef HAVE_WINDOW_SYSTEM - eassert (FRAME_DISPLAY_INFO (f)->n_fonts); - FRAME_DISPLAY_INFO (f)->n_fonts--; + eassert (font->frame); + eassert (FRAME_DISPLAY_INFO (font->frame)->n_fonts); + FRAME_DISPLAY_INFO (font->frame)->n_fonts--; #endif } @@ -4548,11 +4552,11 @@ DEFUN ("open-font", Fopen_font, Sopen_font, 1, 3, 0, } DEFUN ("close-font", Fclose_font, Sclose_font, 1, 2, 0, - doc: /* Close FONT-OBJECT. */) + doc: /* Close FONT-OBJECT. Optional FRAME is unused. */) (Lisp_Object font_object, Lisp_Object frame) { CHECK_FONT_OBJECT (font_object); - font_close_object (decode_live_frame (frame), font_object); + font_close_object (font_object); return Qnil; } @@ -4887,7 +4891,7 @@ If the named font is not yet loaded, return nil. */) /* As font_object is still in FONT_OBJLIST of the entity, we can't close it now. Perhaps, we should manage font-objects by `reference-count'. */ - font_close_object (f, font_object); + font_close_object (font_object); #endif return info; } diff --git a/src/font.h b/src/font.h index 539ebeba52a..7781816860a 100644 --- a/src/font.h +++ b/src/font.h @@ -265,6 +265,9 @@ struct font_entity { struct vectorlike_header header; Lisp_Object props[FONT_ENTITY_MAX]; +#ifdef HAVE_NS + struct font_driver *driver; +#endif }; /* A value which may appear in the member `encoding' of struct font @@ -316,6 +319,9 @@ struct font #if defined (HAVE_WINDOW_SYSTEM) + /* The frame where the font was opened. */ + struct frame *frame; + /* Vertical pixel width of the underline. If is zero if that information is not in the font. */ int underline_thickness; @@ -735,6 +741,7 @@ extern Lisp_Object merge_font_spec (Lisp_Object, Lisp_Object); extern Lisp_Object font_make_entity (void); extern Lisp_Object font_make_object (int, Lisp_Object, int); +extern void font_close_object (Lisp_Object); extern Lisp_Object find_font_encoding (Lisp_Object); extern int font_registry_charsets (Lisp_Object, struct charset **, diff --git a/src/ftfont.c b/src/ftfont.c index 6a2303ab4a7..36780454257 100644 --- a/src/ftfont.c +++ b/src/ftfont.c @@ -1236,6 +1236,7 @@ ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size) ASET (font_object, FONT_FILE_INDEX, filename); ASET (font_object, FONT_FORMAT_INDEX, ftfont_font_format (NULL, filename)); font = XFONT_OBJECT (font_object); + font->frame = f; ftfont_info = (struct ftfont_info *) font; ftfont_info->ft_size = ft_face->size; ftfont_info->index = XINT (idx); diff --git a/src/ftxfont.c b/src/ftxfont.c index d1aa3e40403..b44905d88cd 100644 --- a/src/ftxfont.c +++ b/src/ftxfont.c @@ -255,6 +255,7 @@ ftxfont_open (struct frame *f, Lisp_Object entity, int pixel_size) if (NILP (font_object)) return Qnil; font = XFONT_OBJECT (font_object); + eassert (font->frame == f); font->driver = &ftxfont_driver; return font_object; } diff --git a/src/macfont.m b/src/macfont.m index 10623eb12fe..66833cd1b80 100644 --- a/src/macfont.m +++ b/src/macfont.m @@ -882,6 +882,7 @@ macfont_descriptor_entity (FontDescriptorRef desc, Lisp_Object extra, CFStringRef name; entity = font_make_entity (); + XFONT_ENTITY (entity)->driver = &macfont_driver; ASET (entity, FONT_TYPE_INDEX, macfont_driver.type); ASET (entity, FONT_REGISTRY_INDEX, Qiso10646_1); @@ -2491,6 +2492,7 @@ macfont_open (struct frame * f, Lisp_Object entity, int pixel_size) ASET (font_object, FONT_FULLNAME_INDEX, AREF (font_object, FONT_NAME_INDEX)); font = XFONT_OBJECT (font_object); + font->frame = f; font->pixel_size = size; font->driver = &macfont_driver; font->encoding_charset = font->repertory_charset = -1; diff --git a/src/nsfont.m b/src/nsfont.m index 0f546408316..a794c9eed41 100644 --- a/src/nsfont.m +++ b/src/nsfont.m @@ -805,6 +805,7 @@ nsfont_open (struct frame *f, Lisp_Object font_entity, int pixel_size) return Qnil; /* FIXME: other terms do, but return Qnil causes segfault */ } + font->frame = f; font_info->glyphs = xzalloc (0x100 * sizeof *font_info->glyphs); font_info->metrics = xzalloc (0x100 * sizeof *font_info->metrics); diff --git a/src/w32font.c b/src/w32font.c index 654e0d9cae4..20469274969 100644 --- a/src/w32font.c +++ b/src/w32font.c @@ -999,6 +999,7 @@ w32font_open_internal (struct frame *f, Lisp_Object font_entity, = DECODE_SYSTEM (build_string (logfont.lfFaceName)); } + font->frame = f; font->max_width = w32_font->metrics.tmMaxCharWidth; /* Parts of Emacs display assume that height = ascent + descent... so height is defined later, after ascent and descent. diff --git a/src/xfont.c b/src/xfont.c index d4d6ee7c10f..83ef604d5cd 100644 --- a/src/xfont.c +++ b/src/xfont.c @@ -806,6 +806,7 @@ xfont_open (struct frame *f, Lisp_Object entity, int pixel_size) ASET (font_object, FONT_FILE_INDEX, Qnil); ASET (font_object, FONT_FORMAT_INDEX, Qx); font = XFONT_OBJECT (font_object); + font->frame = f; ((struct xfont_info *) font)->xfont = xfont; ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f); font->pixel_size = pixel_size; diff --git a/src/xftfont.c b/src/xftfont.c index 37b33b3ead8..6423f8e19b3 100644 --- a/src/xftfont.c +++ b/src/xftfont.c @@ -365,6 +365,7 @@ xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size) ASET (font_object, FONT_FORMAT_INDEX, ftfont_font_format (xftfont->pattern, filename)); font = XFONT_OBJECT (font_object); + font->frame = f; font->pixel_size = size; font->driver = &xftfont_driver; font->encoding_charset = font->repertory_charset = -1; -- 2.39.2