emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/android 67a325243c6 3/6: Refactor sfntfont.c


From: Po Lu
Subject: feature/android 67a325243c6 3/6: Refactor sfntfont.c
Date: Mon, 27 Mar 2023 04:45:37 -0400 (EDT)

branch: feature/android
commit 67a325243c6942ff367b24211999554690c328d2
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Refactor sfntfont.c
    
    * src/sfntfont.c (struct sfnt_font_tables): New structure.
    (struct sfnt_font_desc): New field `tables'.
    (struct sfnt_font_info): New field `desc'.
    (sfntfont_setup_interpreter): Drop fd arguments and don't try to
    load interpreter tables.
    (sfnt_open_tables, sfnt_close_tables): New functions.
    (sfnt_reference_font_tables, sfnt_dereference_font_tables): New
    functions.
    (sfntfont_open, sfntfont_close): Implement in terms of those
    functions in order to share tables.
---
 src/sfntfont.c | 569 ++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 358 insertions(+), 211 deletions(-)

diff --git a/src/sfntfont.c b/src/sfntfont.c
index e4579d62154..09aa89a9cdd 100644
--- a/src/sfntfont.c
+++ b/src/sfntfont.c
@@ -51,6 +51,48 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
USA.  */
 
 
 
+/* Tables associated with each font, be it distortable or not.  This
+   allows different font objects sharing the same underlying font file
+   to share tables.  */
+
+struct sfnt_font_tables
+{
+  /* Various tables required to use the font.  */
+  struct sfnt_cmap_table *cmap;
+  struct sfnt_hhea_table *hhea;
+  struct sfnt_maxp_table *maxp;
+  struct sfnt_head_table *head;
+  struct sfnt_hmtx_table *hmtx;
+  struct sfnt_glyf_table *glyf;
+  struct sfnt_loca_table_short *loca_short;
+  struct sfnt_loca_table_long *loca_long;
+  struct sfnt_prep_table *prep;
+  struct sfnt_fpgm_table *fpgm;
+  struct sfnt_cvt_table *cvt;
+
+  /* The selected character map.  */
+  struct sfnt_cmap_encoding_subtable_data *cmap_data;
+
+  /* Data identifying that character map.  */
+  struct sfnt_cmap_encoding_subtable cmap_subtable;
+
+  /* The UVS context.  */
+  struct sfnt_uvs_context *uvs;
+
+#ifdef HAVE_MMAP
+  /* Whether or not the glyph table has been mmapped.  */
+  bool glyf_table_mapped;
+#endif /* HAVE_MMAP */
+
+#ifdef HAVE_HARFBUZZ
+  /* File descriptor associated with this font.  */
+  int fd;
+
+  /* The table directory of the font file.  */
+  struct sfnt_offset_subtable *directory;
+#endif /* HAVE_HARFBUZZ */
+};
+
 /* Description of a font that hasn't been opened.  */
 
 struct sfnt_font_desc
@@ -99,6 +141,12 @@ struct sfnt_font_desc
   /* The number of glyphs in this font.  Used to catch invalid cmap
      tables.  This is actually the number of glyphs - 1.  */
   int num_glyphs;
+
+  /* The number of references to the font tables below.  */
+  int refcount;
+
+  /* List of font tables.  */
+  struct sfnt_font_tables *tables;
 };
 
 /* List of fonts.  */
@@ -1808,7 +1856,7 @@ sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
                                              &temp,
                                              sfntfont_get_glyph,
                                              sfntfont_free_glyph,
-                                             &dcontext);         
+                                             &dcontext);
        }
     }
 
@@ -2011,6 +2059,10 @@ struct sfnt_font_info
   struct sfnt_font_info *next;
 #endif /* HAVE_MMAP */
 
+  /* The font description used to create this font.  Used to
+     dereference tables associated with this font.  */
+  struct sfnt_font_desc *desc;
+
   /* Various tables required to use the font.  */
   struct sfnt_cmap_table *cmap;
   struct sfnt_hhea_table *hhea;
@@ -2161,20 +2213,17 @@ sfntfont_probe_widths (struct sfnt_font_info *font_info)
     font_info->font.average_width = total_width / num_characters;
 }
 
-/* Initialize the instruction interpreter for INFO, whose file and
-   offset subtable should be respectively FD and SUBTABLE.  Load the
-   font and preprogram for the pixel size in INFO and its
-   corresponding point size POINT_SIZE.
+/* Initialize the instruction interpreter for INFO.  Load the font and
+   preprogram for the pixel size in INFO and its corresponding point
+   size POINT_SIZE.
 
    The font tables in INFO must already have been initialized.
 
-   Set INFO->interpreter, INFO->cvt, INFO->prep, INFO->fpgm and
-   INFO->state upon success, and leave those fields intact
+   Set INFO->interpreter upon success, and leave that field intact
    otherwise.  */
 
 static void
-sfntfont_setup_interpreter (int fd, struct sfnt_font_info *info,
-                           struct sfnt_offset_subtable *subtable,
+sfntfont_setup_interpreter (struct sfnt_font_info *info,
                            int point_size)
 {
   struct sfnt_cvt_table *cvt;
@@ -2184,12 +2233,11 @@ sfntfont_setup_interpreter (int fd, struct 
sfnt_font_info *info,
   const char *error;
   struct sfnt_graphics_state state;
 
-  /* Try to read the control value program, cvt, and font program
-     tables.  */
+  /* Load the cvt, fpgm and prep already read.  */
 
-  cvt = sfnt_read_cvt_table (fd, subtable);
-  fpgm = sfnt_read_fpgm_table (fd, subtable);
-  prep = sfnt_read_prep_table (fd, subtable);
+  cvt  = info->cvt ;
+  fpgm = info->fpgm;
+  prep = info->prep;
 
   /* If both fpgm and prep are NULL, this font likely has no
      instructions, so don't bother setting up the interpreter.  */
@@ -2199,6 +2247,7 @@ sfntfont_setup_interpreter (int fd, struct sfnt_font_info 
*info,
 
   /* Now, create the interpreter using the limits in info->maxp and
      info->head.  CVT can be NULL.  */
+
   interpreter = sfnt_make_interpreter (info->maxp, cvt, info->head,
                                       info->font.pixel_size,
                                       point_size);
@@ -2256,92 +2305,72 @@ sfntfont_setup_interpreter (int fd, struct 
sfnt_font_info *info,
  bail1:
   xfree (interpreter);
  bail:
-  xfree (cvt);
-  xfree (fpgm);
-  xfree (prep);
+  return;
 }
 
-/* Open the font corresponding to the font-entity FONT_ENTITY.  Return
-   nil upon failure, else the opened font-object.  */
+/* Free each of the tables opened by `sfnt_open_tables', and possibly
+   file descriptors as well.  Then, free TABLES itself.  */
 
-Lisp_Object
-sfntfont_open (struct frame *f, Lisp_Object font_entity,
-              int pixel_size)
+static void
+sfnt_close_tables (struct sfnt_font_tables *tables)
 {
-  struct sfnt_font_info *font_info;
-  struct font *font;
-  struct sfnt_font_desc *desc;
-  Lisp_Object font_object;
-  int fd, i;
-#ifdef HAVE_MMAP
   int rc;
-#endif /* HAVE_MMAP */
-  struct sfnt_offset_subtable *subtable;
-  struct sfnt_cmap_encoding_subtable *subtables;
-  struct sfnt_cmap_encoding_subtable_data **data;
-  struct charset *charset;
-  int point_size;
-  Display_Info *dpyinfo;
-  struct sfnt_cmap_format_14 *format14;
 
-  if (XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX)) != 0)
-    pixel_size = XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX));
-  else if (pixel_size == 0)
+  xfree (tables->cmap);
+  xfree (tables->hhea);
+  xfree (tables->maxp);
+  xfree (tables->head);
+  xfree (tables->hmtx);
+#ifdef HAVE_MMAP
+  if (tables->glyf_table_mapped)
     {
-      /* This bit was copied from xfont.c.  The values might need
-        adjustment.  */
+      rc = sfnt_unmap_glyf_table (tables->glyf);
 
-      if (FRAME_FONT (f))
-       pixel_size = FRAME_FONT (f)->pixel_size;
-      else
-       pixel_size = 12;
+      if (rc)
+       emacs_abort ();
     }
+  else
+#endif /* HAVE_MMAP */
+    xfree (tables->glyf);
+  xfree (tables->loca_short);
+  xfree (tables->loca_long);
+  xfree (tables->prep);
+  xfree (tables->fpgm);
+  xfree (tables->cvt);
+  xfree (tables->cmap_data);
 
-  /* Now find the font description corresponding to FONT_ENTITY.  */
-
-  if (NILP (AREF (font_entity, FONT_EXTRA_INDEX)))
-    return Qnil;
+  if (tables->uvs)
+    sfnt_free_uvs_context (tables->uvs);
 
-  desc = xmint_pointer (XCDR (XCAR (AREF (font_entity, FONT_EXTRA_INDEX))));
+#ifdef HAVE_HARFBUZZ
+  /* Close the font file.  */
 
-  /* Build the font object.  */
-  font_object = font_make_object (VECSIZE (struct sfnt_font_info),
-                                 font_entity, pixel_size);
-  font_info = (struct sfnt_font_info *) XFONT_OBJECT (font_object);
+  if (tables->fd != -1)
+    {
+      emacs_close (tables->fd);
+      tables->fd = -1;
+    }
 
-  block_input ();
+  /* Free its table directory.  */
+  xfree (tables->directory);
+  tables->directory = NULL;
+#endif
+}
 
-  /* Initialize all the font driver specific data.  */
+/* Open font tables associated with the specified font description
+   DESC.  Return the font tables, or NULL upon failure.  */
 
-  font_info->cmap = NULL;
-  font_info->hhea = NULL;
-  font_info->maxp = NULL;
-  font_info->head = NULL;
-  font_info->glyf = NULL;
-  font_info->hmtx = NULL;
-  font_info->loca_short = NULL;
-  font_info->loca_long = NULL;
-  font_info->cmap_data = NULL;
-  font_info->prep = NULL;
-  font_info->fpgm = NULL;
-  font_info->cvt = NULL;
-  font_info->uvs = NULL;
+static struct sfnt_font_tables *
+sfnt_open_tables (struct sfnt_font_desc *desc)
+{
+  struct sfnt_font_tables *tables;
+  struct sfnt_offset_subtable *subtable;
+  int fd, i, rc;
+  struct sfnt_cmap_encoding_subtable *subtables;
+  struct sfnt_cmap_encoding_subtable_data **data;
+  struct sfnt_cmap_format_14 *format14;
 
-  font_info->outline_cache.next = &font_info->outline_cache;
-  font_info->outline_cache.last = &font_info->outline_cache;
-  font_info->outline_cache_size = 0;
-  font_info->raster_cache.next = &font_info->raster_cache;
-  font_info->raster_cache.last = &font_info->raster_cache;
-  font_info->raster_cache_size = 0;
-  font_info->interpreter = NULL;
-#ifdef HAVE_MMAP
-  font_info->glyf_table_mapped = false;
-#endif /* HAVE_MMAP */
-#ifdef HAVE_HARFBUZZ
-  font_info->hb_font = NULL;
-  font_info->fd = -1;
-  font_info->directory = NULL;
-#endif /* HAVE_HARFBUZZ */
+  tables = xzalloc (sizeof *tables);
 
   /* Open the font.  */
   fd = emacs_open (desc->path, O_RDONLY, 0);
@@ -2349,7 +2378,7 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
   if (fd == -1)
     goto bail;
 
-  /* Seek to the offset specified.  */
+  /* Seek to the offset specified to the table directory.  */
 
   if (desc->offset
       && lseek (fd, desc->offset, SEEK_SET) != desc->offset)
@@ -2365,17 +2394,16 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
      mostly on devices with flash memory, so the order in which they
      are read is insignificant.  */
 
-  /* Select a character map table.  */
-  font_info->cmap = sfnt_read_cmap_table (fd, subtable, &subtables,
-                                         &data);
-  if (!font_info->cmap)
+  tables->cmap = sfnt_read_cmap_table (fd, subtable, &subtables,
+                                      &data);
+  if (!tables->cmap)
     goto bail2;
 
   format14 = NULL;
-  font_info->cmap_data
-    = sfntfont_select_cmap (font_info->cmap,
+  tables->cmap_data
+    = sfntfont_select_cmap (tables->cmap,
                            subtables, data,
-                           &font_info->cmap_subtable,
+                           &tables->cmap_subtable,
                            &format14);
 
   if (format14)
@@ -2385,13 +2413,13 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
          font, and a list of ``non-default'' mappings between base
          characters and variation glyph IDs.  */
 
-      font_info->uvs = sfnt_create_uvs_context (format14, fd);
+      tables->uvs = sfnt_create_uvs_context (format14, fd);
       xfree (format14);
     }
 
-  for (i = 0; i < font_info->cmap->num_subtables; ++i)
+  for (i = 0; i < tables->cmap->num_subtables; ++i)
     {
-      if (data[i] != font_info->cmap_data
+      if (data[i] != tables->cmap_data
          /* format14 has already been freed.  */
          && data[i] != (struct sfnt_cmap_encoding_subtable_data *) format14)
        xfree (data[i]);
@@ -2400,66 +2428,260 @@ sfntfont_open (struct frame *f, Lisp_Object 
font_entity,
   xfree (subtables);
   xfree (data);
 
-  if (!font_info->cmap_data)
+  if (!tables->cmap_data)
     goto bail3;
 
   /* Read the hhea, maxp, glyf, and head tables.  */
-  font_info->hhea = sfnt_read_hhea_table (fd, subtable);
-  font_info->maxp = sfnt_read_maxp_table (fd, subtable);
+  tables->hhea = sfnt_read_hhea_table (fd, subtable);
+  tables->maxp = sfnt_read_maxp_table (fd, subtable);
 
 #ifdef HAVE_MMAP
 
   /* First try to map the glyf table.  If that fails, then read the
      glyf table.  */
 
-  font_info->glyf = sfnt_map_glyf_table (fd, subtable);
+  tables->glyf = sfnt_map_glyf_table (fd, subtable);
 
   /* Next, if this fails, read the glyf table.  */
 
-  if (!font_info->glyf)
+  if (!tables->glyf)
 #endif /* HAVE_MMAP */
-    font_info->glyf = sfnt_read_glyf_table (fd, subtable);
+    tables->glyf = sfnt_read_glyf_table (fd, subtable);
 #ifdef HAVE_MMAP
   else
-    font_info->glyf_table_mapped = true;
+    tables->glyf_table_mapped = true;
 #endif /* HAVE_MMAP */
 
-  font_info->head = sfnt_read_head_table (fd, subtable);
+  tables->head = sfnt_read_head_table (fd, subtable);
 
   /* If any of those tables couldn't be read, bail.  */
-  if (!font_info->hhea || !font_info->maxp || !font_info->glyf
-      || !font_info->head)
+  if (!tables->hhea || !tables->maxp || !tables->glyf
+      || !tables->head)
     goto bail4;
 
   /* Now figure out which kind of loca table must be read based on
      head->index_to_loc_format.  */
-  font_info->loca_short = NULL;
-  font_info->loca_long = NULL;
 
-  if (font_info->head->index_to_loc_format)
+  if (tables->head->index_to_loc_format)
     {
-      font_info->loca_long
+      tables->loca_long
        = sfnt_read_loca_table_long (fd, subtable);
 
-      if (!font_info->loca_long)
+      if (!tables->loca_long)
        goto bail4;
     }
   else
     {
-      font_info->loca_short
+      tables->loca_short
        = sfnt_read_loca_table_short (fd, subtable);
 
-      if (!font_info->loca_short)
+      if (!tables->loca_short)
        goto bail4;
     }
 
   /* Read the horizontal metrics table.  */
-  font_info->hmtx = sfnt_read_hmtx_table (fd, subtable,
-                                         font_info->hhea,
-                                         font_info->maxp);
-  if (!font_info->hmtx)
+  tables->hmtx = sfnt_read_hmtx_table (fd, subtable,
+                                      tables->hhea,
+                                      tables->maxp);
+  if (!tables->hmtx)
     goto bail5;
 
+#ifdef HAVE_HARFBUZZ
+  /* Now copy over the subtable if necessary, as it is needed to read
+     extra font tables required by HarfBuzz.  */
+  tables->directory = subtable;
+  tables->fd = fd;
+#else /* !HAVE_HARFBUZZ */
+  /* Otherwise, close the fd and free the table directory.  */
+  xfree (subtable);
+  emacs_close (fd);
+#endif /* HAVE_HARFBUZZ */
+
+  /* Read instruction related font tables.  These might not be
+     present, which is OK, since instructing fonts is optional.  */
+  tables->prep = sfnt_read_prep_table (fd, subtable);
+  tables->fpgm = sfnt_read_fpgm_table (fd, subtable);
+  tables->cvt  = sfnt_read_cvt_table (fd, subtable);
+
+  return tables;
+
+ bail5:
+  xfree (tables->loca_long);
+  xfree (tables->loca_short);
+ bail4:
+  xfree (tables->hhea);
+  xfree (tables->maxp);
+
+#ifdef HAVE_MMAP
+  if (tables->glyf_table_mapped)
+    {
+      rc = sfnt_unmap_glyf_table (tables->glyf);
+
+      if (rc)
+       emacs_abort ();
+    }
+  else
+#endif /* HAVE_MMAP */
+    xfree (tables->glyf);
+
+  xfree (tables->head);
+
+  /* This comes under bail4 due to a peculiarity of how the four
+     tables above are validated.  */
+  xfree (tables->cmap_data);
+ bail3:
+  if (tables->uvs)
+    sfnt_free_uvs_context (tables->uvs);
+
+  xfree (tables->cmap);
+ bail2:
+  xfree (subtable);
+ bail1:
+  emacs_close (fd);
+ bail:
+  xfree (tables);
+  return NULL;
+}
+
+/* Open or reference font tables corresponding to the specified font
+   DESC.  Return NULL upon failure.  */
+
+static struct sfnt_font_tables *
+sfnt_reference_font_tables (struct sfnt_font_desc *desc)
+{
+  if (desc->refcount)
+    {
+      desc->refcount++;
+      return desc->tables;
+    }
+
+  desc->tables = sfnt_open_tables (desc);
+
+  if (!desc->tables)
+    return NULL;
+
+  desc->refcount++;
+  return desc->tables;
+}
+
+/* Dereference font tables corresponding to the specified font
+   DESC.  */
+
+static void
+sfnt_dereference_font_tables (struct sfnt_font_desc *desc)
+{
+  if (!desc->refcount)
+    emacs_abort ();
+
+  if (--desc->refcount)
+    return;
+
+  sfnt_close_tables (desc->tables);
+  desc->tables = NULL;
+  return;
+}
+
+/* Open the font corresponding to the font-entity FONT_ENTITY.  Return
+   nil upon failure, else the opened font-object.  */
+
+Lisp_Object
+sfntfont_open (struct frame *f, Lisp_Object font_entity,
+              int pixel_size)
+{
+  struct sfnt_font_info *font_info;
+  struct font *font;
+  struct sfnt_font_desc *desc;
+  Lisp_Object font_object;
+  struct charset *charset;
+  int point_size;
+  Display_Info *dpyinfo;
+  struct sfnt_font_tables *tables;
+
+  if (XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX)) != 0)
+    pixel_size = XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX));
+  else if (pixel_size == 0)
+    {
+      /* This bit was copied from xfont.c.  The values might need
+        adjustment.  */
+
+      if (FRAME_FONT (f))
+       pixel_size = FRAME_FONT (f)->pixel_size;
+      else
+       pixel_size = 12;
+    }
+
+  /* Now find the font description corresponding to FONT_ENTITY.  */
+
+  if (NILP (AREF (font_entity, FONT_EXTRA_INDEX)))
+    return Qnil;
+
+  desc = xmint_pointer (XCDR (XCAR (AREF (font_entity, FONT_EXTRA_INDEX))));
+
+  /* Build the font object.  */
+  font_object = font_make_object (VECSIZE (struct sfnt_font_info),
+                                 font_entity, pixel_size);
+  font_info = (struct sfnt_font_info *) XFONT_OBJECT (font_object);
+
+  block_input ();
+
+  /* Initialize all the font driver specific data.  */
+
+  font_info->cmap = NULL;
+  font_info->hhea = NULL;
+  font_info->maxp = NULL;
+  font_info->head = NULL;
+  font_info->glyf = NULL;
+  font_info->hmtx = NULL;
+  font_info->loca_short = NULL;
+  font_info->loca_long = NULL;
+  font_info->cmap_data = NULL;
+  font_info->prep = NULL;
+  font_info->fpgm = NULL;
+  font_info->cvt = NULL;
+  font_info->uvs = NULL;
+
+  font_info->outline_cache.next = &font_info->outline_cache;
+  font_info->outline_cache.last = &font_info->outline_cache;
+  font_info->outline_cache_size = 0;
+  font_info->raster_cache.next = &font_info->raster_cache;
+  font_info->raster_cache.last = &font_info->raster_cache;
+  font_info->raster_cache_size = 0;
+  font_info->interpreter = NULL;
+#ifdef HAVE_MMAP
+  font_info->glyf_table_mapped = false;
+#endif /* HAVE_MMAP */
+#ifdef HAVE_HARFBUZZ
+  font_info->hb_font = NULL;
+  font_info->fd = -1;
+  font_info->directory = NULL;
+#endif /* HAVE_HARFBUZZ */
+
+  /* Read required tables.  This font backend is supposed to be used
+     mostly on devices with flash memory, so the order in which they
+     are read is insignificant.  */
+
+  tables = sfnt_reference_font_tables (desc);
+
+  if (!tables)
+    goto bail;
+
+  /* Copy fields from the table structure to the font for fast
+     access.  */
+  font_info->cmap = tables->cmap;
+  font_info->hhea = tables->hhea;
+  font_info->maxp = tables->maxp;
+  font_info->head = tables->head;
+  font_info->hmtx = tables->hmtx;
+  font_info->glyf = tables->glyf;
+  font_info->loca_short = tables->loca_short;
+  font_info->loca_long = tables->loca_long;
+  font_info->prep = tables->prep;
+  font_info->fpgm = tables->fpgm;
+  font_info->cvt  = tables->cvt ;
+  font_info->cmap_data = tables->cmap_data;
+  font_info->cmap_subtable = tables->cmap_subtable;
+  font_info->uvs = tables->uvs;
+
   /* Fill in font data.  */
   font = &font_info->font;
   font->pixel_size = pixel_size;
@@ -2535,22 +2757,19 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
   point_size = PIXEL_TO_POINT (pixel_size, (dpyinfo->resx
                                            * dpyinfo->resy
                                            / 2));
-  sfntfont_setup_interpreter (fd, font_info, subtable,
-                             point_size);
+  sfntfont_setup_interpreter (font_info, point_size);
 
-#ifndef HAVE_HARFBUZZ
-  /* Close the font file descriptor.  */
-  emacs_close (fd);
-
-  /* Free the offset subtable.  */
-  xfree (subtable);
-#else /* HAVE_HARFBUZZ */
+#ifdef HAVE_HARFBUZZ
   /* HarfBuzz will potentially read font tables after the font has
      been opened by Emacs.  Keep the font open, and record its offset
      subtable.  */
-  font_info->fd = fd;
-  font_info->directory = subtable;
-#endif /* !HAVE_HARFBUZZ */
+  font_info->fd = tables->fd;
+  font_info->directory = tables->directory;
+#endif /* HAVE_HARFBUZZ */
+
+  /* Set font->desc so that font tables can be dereferenced if
+     anything goes wrong.  */
+  font_info->desc = desc;
 
 #ifdef HAVE_MMAP
   /* Link the font onto the font table.  */
@@ -2563,50 +2782,8 @@ sfntfont_open (struct frame *f, Lisp_Object font_entity,
   return font_object;
 
  bail6:
-  xfree (font_info->hmtx);
-  font_info->hmtx = NULL;
- bail5:
-  xfree (font_info->loca_long);
-  xfree (font_info->loca_short);
-  font_info->loca_long = NULL;
-  font_info->loca_short = NULL;
- bail4:
-  xfree (font_info->hhea);
-  xfree (font_info->maxp);
-
-#ifdef HAVE_MMAP
-  if (font_info->glyf_table_mapped)
-    {
-      rc = sfnt_unmap_glyf_table (font_info->glyf);
-
-      if (rc)
-       emacs_abort ();
-    }
-  else
-#endif /* HAVE_MMAP */
-    xfree (font_info->glyf);
-
-  xfree (font_info->head);
-  font_info->hhea = NULL;
-  font_info->maxp = NULL;
-  font_info->glyf = NULL;
-  font_info->head = NULL;
-
-  /* This comes in bail4 due to a peculiarity of how the four tables
-     above are validated.  */
-  xfree (font_info->cmap_data);
-  font_info->cmap_data = NULL;
- bail3:
-
-  if (font_info->uvs)
-    sfnt_free_uvs_context (font_info->uvs);
-
-  xfree (font_info->cmap);
-  font_info->cmap = NULL;
- bail2:
-  xfree (subtable);
- bail1:
-  emacs_close (fd);
+  sfnt_dereference_font_tables (desc);
+  font_info->desc = NULL;
  bail:
   unblock_input ();
   return Qnil;
@@ -2784,42 +2961,18 @@ sfntfont_close (struct font *font)
   struct sfnt_font_info *info;
 #ifdef HAVE_MMAP
   struct sfnt_font_info **next;
-  int rc;
 #endif /* HAVE_MMAP */
 
   info = (struct sfnt_font_info *) font;
-  xfree (info->cmap);
-  xfree (info->hhea);
-  xfree (info->maxp);
-  xfree (info->head);
-  xfree (info->hmtx);
 
-#ifdef HAVE_MMAP
-  if (info->glyf_table_mapped && info->glyf)
-    {
-      rc = sfnt_unmap_glyf_table (info->glyf);
+  /* If info->desc is still set, dereference the font tables.  */
+  if (info->desc)
+    sfnt_dereference_font_tables (info->desc);
+  info->desc = NULL;
 
-      if (rc)
-       emacs_abort ();
-    }
-  else
-#endif /* HAVE_MMAP */
-    xfree (info->glyf);
-
-  xfree (info->loca_short);
-  xfree (info->loca_long);
-  xfree (info->cmap_data);
-  xfree (info->prep);
-  xfree (info->fpgm);
-  xfree (info->cvt);
+  /* Free the interpreter, which is created on a per font basis.  */
   xfree (info->interpreter);
 
-  /* Deallocate any UVS context allocated to look up font variation
-     sequences.  */
-
-  if (info->uvs)
-    sfnt_free_uvs_context (info->uvs);
-
   /* Clear these fields.  It seems that close can be called twice,
      once during font driver destruction, and once during GC.  */
 
@@ -2853,17 +3006,11 @@ sfntfont_close (struct font *font)
 #endif /* HAVE_MMAP */
 
 #ifdef HAVE_HARFBUZZ
-  /* Close the font file.  */
-
-  if (info->fd != -1)
-    {
-      emacs_close (info->fd);
-      info->fd = -1;
-    }
-
-  /* Free its table directory.  */
-  xfree (info->directory);
+  /* These fields will be freed or closed by
+     sfnt_dereference_font_tables, but clear them here for good
+     measure.  */
   info->directory = NULL;
+  info->fd = -1;
 
   /* Free any hb_font created.  */
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]