root/src/sfntfont.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sfnt_setup_coding_system
  2. sfnt_safe_decode_coding_object_1
  3. sfnt_safe_decode_coding_object_2
  4. sfnt_safe_decode_coding_object
  5. sfnt_decode_font_string
  6. sfnt_decode_family_style
  7. sfnt_decode_foundry_name
  8. sfnt_decode_instance_name
  9. sfnt_parse_style
  10. sfnt_parse_languages
  11. sfnt_registry_for_subtable
  12. sfntfont_identify_cmap
  13. sfnt_grok_registry
  14. sfnt_replace_fonts_p
  15. sfnt_enum_font_1
  16. sfnt_enum_font
  17. sfntfont_charset_for_name
  18. sfntfont_charset_for_cmap
  19. sfntfont_select_cmap
  20. sfntfont_read_cmap
  21. sfntfont_glyph_valid
  22. sfntfont_lookup_char
  23. sfntfont_registries_compatible_p
  24. sfntfont_list_1
  25. sfntfont_registry_for_desc
  26. sfntfont_desc_to_entity
  27. sfntfont_list
  28. sfntfont_match
  29. sfntfont_get_glyph
  30. sfntfont_free_glyph
  31. sfntfont_dereference_outline
  32. sfntfont_get_glyph_outline
  33. sfntfont_free_outline_cache
  34. sfntfont_dereference_raster
  35. sfntfont_get_glyph_raster
  36. sfntfont_free_raster_cache
  37. sfntfont_lookup_glyph
  38. sfntfont_probe_widths
  39. sfntfont_setup_interpreter
  40. sfnt_close_tables
  41. sfnt_open_tables
  42. sfnt_reference_font_tables
  43. sfnt_dereference_font_tables
  44. sfntfont_open
  45. sfntfont_encode_char
  46. sfntfont_measure_pcm
  47. sfntfont_text_extents
  48. sfntfont_close
  49. sfntfont_draw
  50. sfntfont_list_family
  51. sfntfont_get_variation_glyphs
  52. sfntfont_detect_sigbus
  53. sfntfont_unmap_blob
  54. sfntfont_get_font_table
  55. sfntfont_begin_hb_font
  56. syms_of_sfntfont
  57. mark_sfntfont
  58. init_sfntfont
  59. init_sfntfont_vendor

     1 /* sfnt format font driver for GNU Emacs.
     2 
     3 Copyright (C) 2023 Free Software Foundation, Inc.
     4 
     5 This file is part of GNU Emacs.
     6 
     7 GNU Emacs is free software: you can redistribute it and/or modify
     8 it under the terms of the GNU General Public License as published by
     9 the Free Software Foundation, either version 3 of the License, or (at
    10 your option) any later version.
    11 
    12 GNU Emacs is distributed in the hope that it will be useful,
    13 but WITHOUT ANY WARRANTY; without even the implied warranty of
    14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15 GNU General Public License for more details.
    16 
    17 You should have received a copy of the GNU General Public License
    18 along with GNU Emacs.  If not, write to the Free Software Foundation,
    19 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
    20 
    21 #include <config.h>
    22 
    23 #include <fcntl.h>
    24 #include <ctype.h>
    25 
    26 #include "lisp.h"
    27 
    28 #include "blockinput.h"
    29 #include "charset.h"
    30 #include "coding.h"
    31 #include "font.h"
    32 #include "frame.h"
    33 #include "math.h"
    34 #include "sfnt.h"
    35 #include "sfntfont.h"
    36 
    37 #ifdef HAVE_HARFBUZZ
    38 #include <hb.h>
    39 #include <hb-ot.h>
    40 #endif /* HAVE_HARFBUZZ */
    41 
    42 /* For FRAME_FONT.  */
    43 #include TERM_HEADER
    44 
    45 /* Generic font driver for sfnt-based fonts (currently TrueType, but
    46    it would be easy to add CFF support in the future with a PostScript
    47    renderer.)
    48 
    49    This is not a complete font driver.  Hooks must be supplied by the
    50    platform implementer to draw glyphs.  */
    51 
    52 
    53 
    54 /* Tables associated with each font, be it distortable or not.  This
    55    allows different font objects sharing the same underlying font file
    56    to share tables.  */
    57 
    58 struct sfnt_font_tables
    59 {
    60   /* Various tables required to use the font.  */
    61   struct sfnt_cmap_table *cmap;
    62   struct sfnt_hhea_table *hhea;
    63   struct sfnt_maxp_table *maxp;
    64   struct sfnt_head_table *head;
    65   struct sfnt_hmtx_table *hmtx;
    66   struct sfnt_glyf_table *glyf;
    67   struct sfnt_loca_table_short *loca_short;
    68   struct sfnt_loca_table_long *loca_long;
    69   struct sfnt_prep_table *prep;
    70   struct sfnt_fpgm_table *fpgm;
    71   struct sfnt_cvt_table *cvt;
    72   struct sfnt_fvar_table *fvar;
    73   struct sfnt_avar_table *avar;
    74   struct sfnt_gvar_table *gvar;
    75   struct sfnt_cvar_table *cvar;
    76 
    77   /* The selected character map.  */
    78   struct sfnt_cmap_encoding_subtable_data *cmap_data;
    79 
    80   /* Data identifying that character map.  */
    81   struct sfnt_cmap_encoding_subtable cmap_subtable;
    82 
    83   /* The UVS context.  */
    84   struct sfnt_uvs_context *uvs;
    85 
    86 #ifdef HAVE_MMAP
    87   /* Whether or not the glyph table has been mmapped.  */
    88   bool glyf_table_mapped;
    89 #endif /* HAVE_MMAP */
    90 
    91 #ifdef HAVE_HARFBUZZ
    92   /* File descriptor associated with this font.  */
    93   int fd;
    94 
    95   /* The table directory of the font file.  */
    96   struct sfnt_offset_subtable *directory;
    97 #endif /* HAVE_HARFBUZZ */
    98 };
    99 
   100 /* Description of a font that hasn't been opened.  */
   101 
   102 struct sfnt_font_desc
   103 {
   104   /* Next font in this list.  */
   105   struct sfnt_font_desc *next;
   106 
   107   /* Family name of the font.  */
   108   Lisp_Object family;
   109 
   110   /* Style name of the font.  */
   111   Lisp_Object style;
   112 
   113   /* Designer (foundry) of the font.  */
   114   Lisp_Object designer;
   115 
   116   /* Style tokens that could not be parsed.  */
   117   Lisp_Object adstyle;
   118 
   119   /* List of design languages.  */
   120   Lisp_Object languages;
   121 
   122   /* Font registry that this font supports.  */
   123   Lisp_Object registry;
   124 
   125   /* Vector of instances.  Each element is another of the instance's
   126      `style', `adstyle', and numeric width, weight, and slant.  May be
   127      nil.  */
   128   Lisp_Object instances;
   129 
   130   /* Numeric width, weight, slant and spacing.  */
   131   int width, weight, slant, spacing;
   132 
   133   /* Path to the font file.  */
   134   char *path;
   135 
   136   /* char table consisting of characters already known to be
   137      present in the font.  */
   138   Lisp_Object char_cache;
   139 
   140   /* Whether or not the character map can't be used by Emacs.  */
   141   bool cmap_invalid;
   142 
   143   /* The header of the cmap being used.  May be invalid, in which case
   144      platform_id will be 500.  */
   145   struct sfnt_cmap_encoding_subtable subtable;
   146 
   147   /* The offset of the table directory within PATH.  */
   148   off_t offset;
   149 
   150   /* The number of glyphs in this font.  Used to catch invalid cmap
   151      tables.  This is actually the number of glyphs - 1.  */
   152   int num_glyphs;
   153 
   154   /* The number of references to the font tables below.  */
   155   int refcount;
   156 
   157   /* List of font tables.  */
   158   struct sfnt_font_tables *tables;
   159 };
   160 
   161 /* List of fonts.  */
   162 
   163 static struct sfnt_font_desc *system_fonts;
   164 
   165 /* Font enumeration and matching.  The sfnt driver assumes it can read
   166    data from each font at startup.  It then reads the head, meta and
   167    name tables to determine font data, and records the font in a list
   168    of system fonts that is then matched against.  */
   169 
   170 /* Set up the coding system CODING to decode string data from the
   171    given platform id ID and platform specific id PLATFORM_SPECIFIC_ID.
   172    Value is 0 upon success, 1 upon failure.  */
   173 
   174 static int
   175 sfnt_setup_coding_system (enum sfnt_platform_id id, int platform_specific_id,
   176                           struct coding_system *coding)
   177 {
   178   Lisp_Object system;
   179 
   180   system = Qnil;
   181 
   182   /* Figure out what coding system to use.  */
   183 
   184   switch (id)
   185     {
   186     case SFNT_PLATFORM_UNICODE:
   187       system = Qutf_16be;
   188       break;
   189 
   190     case SFNT_PLATFORM_MACINTOSH:
   191 
   192       if (platform_specific_id == SFNT_MACINTOSH_ROMAN)
   193         system = Qmac_roman;
   194       else
   195         /* MULE doesn't support the rest... */
   196         system = Qnil;
   197 
   198       break;
   199 
   200     case SFNT_PLATFORM_MICROSOFT:
   201       system = Qutf_16be;
   202 
   203       /* Not sure if this is right.  */
   204       if (platform_specific_id == SFNT_MICROSOFT_BIG_FIVE)
   205         system = Qchinese_big5;
   206 
   207       break;
   208 
   209     default:
   210       system = Qnil;
   211     }
   212 
   213   if (NILP (system))
   214     return 1;
   215 
   216   setup_coding_system (system, coding);
   217   return 0;
   218 }
   219 
   220 /* Globals used to communicate inside the condition-case wrapper.  */
   221 static struct coding_system *sfnt_font_coding;
   222 
   223 /* The src_object being encoded from.  This should be on the stack as
   224    well, or it will get garbage collected.  */
   225 static Lisp_Object sfnt_font_src_object;
   226 
   227 /* From-position.  */
   228 static ptrdiff_t sfnt_font_from, sfnt_font_from_byte;
   229 
   230 /* To-position.  */
   231 static ptrdiff_t sfnt_font_to, sfnt_font_to_byte;
   232 
   233 /* Destination object.  Once again, this should also be on the
   234    stack.  */
   235 static Lisp_Object sfnt_font_dst_object;
   236 
   237 /* Error flag.  Set to true if a signal was caught.  */
   238 static bool sfnt_font_signal;
   239 
   240 static Lisp_Object
   241 sfnt_safe_decode_coding_object_1 (void)
   242 {
   243   decode_coding_object (sfnt_font_coding,
   244                         sfnt_font_src_object,
   245                         sfnt_font_from,
   246                         sfnt_font_from_byte,
   247                         sfnt_font_to,
   248                         sfnt_font_to_byte,
   249                         sfnt_font_dst_object);
   250   return Qnil;
   251 }
   252 
   253 static Lisp_Object
   254 sfnt_safe_decode_coding_object_2 (Lisp_Object error)
   255 {
   256   sfnt_font_signal = true;
   257 
   258   return Qnil;
   259 }
   260 
   261 /* Like decode_coding_object, but return 1 if a signal happens.  Value
   262    is otherwise 0.  */
   263 
   264 static int
   265 sfnt_safe_decode_coding_object (struct coding_system *coding,
   266                                 Lisp_Object src_object,
   267                                 ptrdiff_t from, ptrdiff_t from_byte,
   268                                 ptrdiff_t to, ptrdiff_t to_byte,
   269                                 Lisp_Object dst_object)
   270 {
   271   sfnt_font_coding = coding;
   272   sfnt_font_src_object = src_object;
   273   sfnt_font_from = from;
   274   sfnt_font_from_byte = from_byte;
   275   sfnt_font_to = to;
   276   sfnt_font_to_byte = to_byte;
   277   sfnt_font_dst_object = dst_object;
   278   sfnt_font_signal = false;
   279 
   280   internal_condition_case (sfnt_safe_decode_coding_object_1,
   281                            Qt,
   282                            sfnt_safe_decode_coding_object_2);
   283 
   284   return (int) sfnt_font_signal;
   285 }
   286 
   287 /* Decode the specified string DATA.  The encoding is determined based
   288    on PLATFORM_ID, PLATFORM_SPECIFIC_ID and LANGUAGE_ID.  Consult
   289    sfnt.h and the TrueType Reference Manual for more details.  LENGTH
   290    is the length of DATA in bytes.
   291 
   292    Value is nil upon failure, else the decoded string.  */
   293 
   294 static Lisp_Object
   295 sfnt_decode_font_string (unsigned char *data, enum sfnt_platform_id id,
   296                          int platform_specific_id, int language_id,
   297                          size_t length)
   298 {
   299   struct coding_system coding;
   300 
   301   memset (&coding, 0, sizeof coding);
   302   sfnt_setup_coding_system (id, platform_specific_id, &coding);
   303   coding.mode |= CODING_MODE_SAFE_ENCODING;
   304   coding.mode |= CODING_MODE_LAST_BLOCK;
   305   /* Suppress producing escape sequences for composition.  */
   306   coding.common_flags &= ~CODING_ANNOTATION_MASK;
   307   coding.source = data;
   308 
   309   if (sfnt_safe_decode_coding_object (&coding, Qnil, 0, 0,
   310                                       length, length, Qt))
   311     return Qnil;
   312 
   313   return coding.dst_object;
   314 }
   315 
   316 /* Decode the family and style names from the name table NAME.  Return
   317    0 and the family and style names upon success, else 1.  */
   318 
   319 static int
   320 sfnt_decode_family_style (struct sfnt_name_table *name,
   321                           Lisp_Object *family, Lisp_Object *style)
   322 {
   323   struct sfnt_name_record family_rec, style_rec;
   324   unsigned char *family_data, *style_data;
   325 
   326   family_data = sfnt_find_name (name, SFNT_NAME_FONT_FAMILY,
   327                                 &family_rec);
   328   style_data = sfnt_find_name (name, SFNT_NAME_FONT_SUBFAMILY,
   329                                &style_rec);
   330 
   331   if (!family_data || !style_data)
   332     return 1;
   333 
   334   /* Now decode the data.  */
   335   *family = sfnt_decode_font_string (family_data,
   336                                      family_rec.platform_id,
   337                                      family_rec.platform_specific_id,
   338                                      family_rec.language_id,
   339                                      family_rec.length);
   340   *style = sfnt_decode_font_string (style_data,
   341                                     style_rec.platform_id,
   342                                     style_rec.platform_specific_id,
   343                                     style_rec.language_id,
   344                                     style_rec.length);
   345 
   346   /* Return whether or not it was successful.  */
   347   return (!NILP (*family) && !NILP (*style)) ? 0 : 1;
   348 }
   349 
   350 /* Decode the foundry names from the name table NAME.  Return the
   351    foundry name, or nil upon failure.  */
   352 
   353 static Lisp_Object
   354 sfnt_decode_foundry_name (struct sfnt_name_table *name)
   355 {
   356   struct sfnt_name_record designer_rec;
   357   unsigned char *designer_data;
   358 
   359   designer_data = sfnt_find_name (name, SFNT_NAME_DESIGNER,
   360                                   &designer_rec);
   361 
   362   if (!designer_data)
   363     return Qnil;
   364 
   365   return sfnt_decode_font_string (designer_data,
   366                                   designer_rec.platform_id,
   367                                   designer_rec.platform_specific_id,
   368                                   designer_rec.language_id,
   369                                   designer_rec.length);
   370 }
   371 
   372 /* Decode the name of the specified font INSTANCE using the given NAME
   373    table.  Return the name of that instance, or nil upon failure.  */
   374 
   375 static Lisp_Object
   376 sfnt_decode_instance_name (struct sfnt_instance *instance,
   377                            struct sfnt_name_table *name)
   378 {
   379   struct sfnt_name_record name_rec;
   380   unsigned char *name_data;
   381 
   382   name_data = sfnt_find_name (name, instance->name_id,
   383                               &name_rec);
   384 
   385   if (!name_data)
   386     return Qnil;
   387 
   388   return sfnt_decode_font_string (name_data,
   389                                   name_rec.platform_id,
   390                                   name_rec.platform_specific_id,
   391                                   name_rec.language_id,
   392                                   name_rec.length);
   393 }
   394 
   395 struct sfnt_style_desc
   396 {
   397   /* The C string to match against.  */
   398   const char *c_string;
   399 
   400   /* The value of the style field.  */
   401   int value;
   402 };
   403 
   404 /* Array of style descriptions describing weight.  */
   405 static struct sfnt_style_desc sfnt_weight_descriptions[] =
   406   {
   407     { "thin", 0,                },
   408     { "extralight", 40,         },
   409     { "ultralight", 40,         },
   410     { "light", 50,              },
   411     { "demilight", 55,          },
   412     { "semilight", 55,          },
   413     { "book", 75,               },
   414     { "medium", 100,            },
   415     { "demibold", 180,          },
   416     { "semibold", 180,          },
   417     { "bold", 200,              },
   418     { "extrabold", 205,         },
   419     { "ultrabold", 205,         },
   420     { "black", 210,             },
   421     { "heavy", 210,             },
   422     { "extrablack", 215,        },
   423     { "ultrablack", 215,        },
   424   };
   425 
   426 /* Array of style descriptions describing slant.  */
   427 static struct sfnt_style_desc sfnt_slant_descriptions[] =
   428   {
   429     { "italic", 200,    },
   430     { "oblique", 210,   },
   431   };
   432 
   433 /* Array of style descriptions describing width.  */
   434 static struct sfnt_style_desc sfnt_width_descriptions[] =
   435   {
   436     { "ultracondensed", 50,     },
   437     { "extracondensed", 63,     },
   438     { "condensed", 75,          },
   439     { "semicondensed", 87,      },
   440     { "semiexpanded", 113,      },
   441     { "expanded", 125,          },
   442     { "extraexpanded", 150,     },
   443     { "ultraexpanded", 200,     },
   444   };
   445 
   446 /* Figure out DESC->width, DESC->weight, DESC->slant and DESC->spacing
   447    based on the style name passed as STYLE_NAME.
   448 
   449    Also append any unknown tokens to DESC->adstyle.  */
   450 
   451 static void
   452 sfnt_parse_style (Lisp_Object style_name, struct sfnt_font_desc *desc)
   453 {
   454   char *style, *single, *saveptr;
   455   int i;
   456   USE_SAFE_ALLOCA;
   457 
   458   /* Fill in default values.  slant seems to not be consistent with
   459      Fontconfig.  */
   460   desc->weight = 80;
   461   desc->slant = 100;
   462   desc->width = 100;
   463 
   464   /* Split the style into tokens delimited by spaces.  Attempt to find
   465      a token specifying each of the weight, slant, or width attributes
   466      using their respective descriptions arrays as a reference.  */
   467 
   468   SAFE_ALLOCA_STRING (style, Fdowncase (style_name));
   469   saveptr = NULL;
   470 
   471   while ((single = strtok_r (style, " ", &saveptr)))
   472     {
   473       style = NULL;
   474 
   475       if (desc->weight == 80)
   476         {
   477           /* Weight hasn't been found yet.  Scan through the weight
   478              table.  */
   479           for (i = 0; i < ARRAYELTS (sfnt_weight_descriptions); ++i)
   480             {
   481               if (!strcmp (sfnt_weight_descriptions[i].c_string,
   482                            single))
   483                 {
   484                   /* Weight found.  Continue on reading the slant and
   485                      width.  */
   486                   desc->weight = sfnt_weight_descriptions[i].value;
   487                   goto next;
   488                 }
   489             }
   490         }
   491 
   492       if (desc->slant == 100)
   493         {
   494           /* Slant hasn't been found yet.  Scan through the slant
   495              table.  */
   496           for (i = 0; i < ARRAYELTS (sfnt_slant_descriptions); ++i)
   497             {
   498               if (!strcmp (sfnt_slant_descriptions[i].c_string,
   499                            single))
   500                 {
   501                   /* Slant found.  Continue on reading the weight and
   502                      width.  */
   503                   desc->slant = sfnt_slant_descriptions[i].value;
   504                   goto next;
   505                 }
   506             }
   507         }
   508 
   509       if (desc->width == 100)
   510         {
   511           /* Width hasn't been found yet.  Scan through the width
   512              table.  */
   513           for (i = 0; i < ARRAYELTS (sfnt_width_descriptions); ++i)
   514             {
   515               if (!strcmp (sfnt_width_descriptions[i].c_string,
   516                            single))
   517                 {
   518                   /* Width found.  Continue on reading the slant and
   519                      weight.  */
   520                   desc->width = sfnt_width_descriptions[i].value;
   521                   goto next;
   522                 }
   523             }
   524         }
   525 
   526       /* This token is extraneous or was not recognized.  Capitalize
   527          the first letter and set it as the adstyle.  */
   528 
   529       if (strlen (single))
   530         {
   531           if (islower (single[0]))
   532             single[0] = toupper (single[0]);
   533 
   534           if (NILP (desc->adstyle))
   535             desc->adstyle = build_string (single);
   536           else
   537             desc->adstyle = CALLN (Fconcat, desc->adstyle,
   538                                    build_string (" "),
   539                                    build_string (single));
   540         }
   541 
   542     next:
   543       continue;
   544     }
   545 
   546   SAFE_FREE ();
   547 }
   548 
   549 /* Parse the list of design languages in META, a font metadata table,
   550    and place the results in DESC->languages.  Do nothing if there is
   551    no such metadata.  */
   552 
   553 static void
   554 sfnt_parse_languages (struct sfnt_meta_table *meta,
   555                       struct sfnt_font_desc *desc)
   556 {
   557   char *data, *metadata, *tag;
   558   struct sfnt_meta_data_map map;
   559   char *saveptr;
   560 
   561   /* Look up the ``design languages'' metadata.  This is a comma (and
   562      possibly space) separated list of scripts that the font was
   563      designed for.  Here is an example of one such tag:
   564 
   565        zh-Hans,Jpan,Kore
   566 
   567      for a font that covers Simplified Chinese, along with Japanese
   568      and Korean text.  */
   569 
   570   saveptr = NULL;
   571   data = sfnt_find_metadata (meta, SFNT_META_DATA_TAG_DLNG,
   572                              &map);
   573 
   574   if (!data)
   575     {
   576       /* Fall back to the supported languages metadata.  */
   577       data = sfnt_find_metadata (meta, SFNT_META_DATA_TAG_SLNG,
   578                                  &map);
   579 
   580       if (!data)
   581         return;
   582     }
   583 
   584   USE_SAFE_ALLOCA;
   585 
   586   /* Now copy metadata and add a trailing NULL byte.  */
   587 
   588   if (map.data_length >= SIZE_MAX)
   589     memory_full (SIZE_MAX);
   590 
   591   metadata = SAFE_ALLOCA ((size_t) map.data_length + 1);
   592   memcpy (metadata, data, map.data_length);
   593   metadata[map.data_length] = '\0';
   594 
   595   /* Loop through each script-language tag.  Note that there may be
   596      extra leading spaces.  */
   597   while ((tag = strtok_r (metadata, ",", &saveptr)))
   598     {
   599       metadata = NULL;
   600 
   601       if (strstr (tag, "Hans") || strstr (tag, "Hant"))
   602         desc->languages = Fcons (Qzh, desc->languages);
   603 
   604       if (strstr (tag, "Japn"))
   605         desc->languages = Fcons (Qja, desc->languages);
   606 
   607       if (strstr (tag, "Kore"))
   608         desc->languages = Fcons (Qko, desc->languages);
   609     }
   610 
   611   SAFE_FREE ();
   612 }
   613 
   614 /* Return the font registry corresponding to the encoding subtable
   615    SUBTABLE.
   616 
   617    Under X, the font registry is an atom registered with the Open
   618    Group uniquely identifying the organization which defines the
   619    font's character set.
   620 
   621    In practice, the registry overlaps with the character set itself.
   622    So Emacs just uses the ``registry'' field of each font object and
   623    entity to represent both instead.  */
   624 
   625 static Lisp_Object
   626 sfnt_registry_for_subtable (struct sfnt_cmap_encoding_subtable *subtable)
   627 {
   628   switch (subtable->platform_id)
   629     {
   630     case SFNT_PLATFORM_UNICODE:
   631       /* Reject variation selector and last resort tables.  */
   632       if ((subtable->platform_specific_id
   633            == SFNT_UNICODE_VARIATION_SEQUENCES)
   634           || (subtable->platform_specific_id
   635               == SFNT_UNICODE_LAST_RESORT))
   636         return Qnil;
   637 
   638       return Qiso10646_1;
   639 
   640     case SFNT_PLATFORM_MACINTOSH:
   641 
   642       switch (subtable->platform_specific_id)
   643         {
   644         case SFNT_MACINTOSH_ROMAN:
   645           /* X calls mac-roman ``apple-roman''.  */
   646           return Qapple_roman;
   647 
   648         default:
   649           /* Some other Macintosh charset not supported by Emacs.  */
   650           return Qnil;
   651         }
   652 
   653     case SFNT_PLATFORM_MICROSOFT:
   654 
   655       /* Microsoft specific encodings.  */
   656 
   657       switch (subtable->platform_specific_id)
   658         {
   659         case SFNT_MICROSOFT_SYMBOL:
   660         case SFNT_MICROSOFT_UNICODE_BMP:
   661           /* Symbols in the Unicode PUA are still Unicode.  */
   662           return Qiso10646_1;
   663 
   664         case SFNT_MICROSOFT_SHIFT_JIS:
   665           return Qjisx0208_1983_0;
   666 
   667         case SFNT_MICROSOFT_PRC:
   668           return Qgbk;
   669 
   670         case SFNT_MICROSOFT_JOHAB:
   671           return Qksc5601_1987_0;
   672 
   673         case SFNT_MICROSOFT_UNICODE_UCS_4:
   674           return Qiso10646_1;
   675         }
   676 
   677     default:
   678       return Qnil;
   679     }
   680 }
   681 
   682 /* Return the type of characters that the cmap subtable SUBTABLE maps
   683    from.  Value is:
   684 
   685    2 if SUBTABLE maps from Unicode characters, including those outside
   686    the Unicode Basic Multilingual Plane (BMP).
   687 
   688    1 if SUBTABLE maps from Unicode characters within the BMP.
   689 
   690    0 if SUBTABLE maps from some other character set that Emacs knows
   691    about.
   692 
   693    3 if SUBTABLE cannot be used by Emacs.  */
   694 
   695 static int
   696 sfntfont_identify_cmap (struct sfnt_cmap_encoding_subtable subtable)
   697 {
   698   switch (subtable.platform_id)
   699     {
   700     case SFNT_PLATFORM_UNICODE:
   701 
   702       /* Reject variation selector and last resort tables.  */
   703       if ((subtable.platform_specific_id
   704            == SFNT_UNICODE_VARIATION_SEQUENCES)
   705           || (subtable.platform_specific_id
   706               == SFNT_UNICODE_LAST_RESORT))
   707         return 3;
   708 
   709       /* 1.0, 1.1, ISO-10646-1993, and 2.0_BMP tables are all within
   710          the BMP.  */
   711       if (subtable.platform_specific_id < SFNT_UNICODE_2_0)
   712         return 1;
   713 
   714       return 2;
   715 
   716     case SFNT_PLATFORM_MACINTOSH:
   717 
   718       switch (subtable.platform_specific_id)
   719         {
   720         case SFNT_MACINTOSH_ROMAN:
   721           /* mac-roman */
   722           return 0;
   723 
   724         default:
   725           /* Some other Macintosh charset not supported by Emacs.  */
   726           return 3;
   727         }
   728 
   729     case SFNT_PLATFORM_MICROSOFT:
   730 
   731       /* Microsoft specific encodings.  */
   732 
   733       switch (subtable.platform_specific_id)
   734         {
   735         case SFNT_MICROSOFT_SYMBOL:
   736           /* Symbols in the Unicode PUA are still Unicode.  */
   737           return 1;
   738 
   739         case SFNT_MICROSOFT_UNICODE_BMP:
   740           return 1;
   741 
   742         case SFNT_MICROSOFT_SHIFT_JIS:
   743           /* PCK aka japanese-jisx0208.  */
   744           return 0;
   745 
   746         case SFNT_MICROSOFT_PRC:
   747           /* GBK, GB2312 or GB18030.  */
   748           return 0;
   749 
   750         case SFNT_MICROSOFT_JOHAB:
   751           /* KS C 5601-1992, aka korean-ksc5601.  */
   752           return 0;
   753 
   754         case SFNT_MICROSOFT_UNICODE_UCS_4:
   755           /* Unicode past the BMP.  */
   756           return 2;
   757         }
   758 
   759     default:
   760       return 3;
   761     }
   762 }
   763 
   764 /* Figure out which registry DESC, backed by FD, whose table directory
   765    is SUBTABLE, is likely to support.
   766 
   767    Read the header of each subtable in the character map and compute
   768    the registry to use; then, set DESC->registry to that value.  */
   769 
   770 static void
   771 sfnt_grok_registry (int fd, struct sfnt_font_desc *desc,
   772                     struct sfnt_offset_subtable *subtable)
   773 {
   774   struct sfnt_cmap_table *cmap;
   775   struct sfnt_cmap_encoding_subtable *subtables;
   776   int i;
   777 
   778   cmap = sfnt_read_cmap_table (fd, subtable, &subtables, NULL);
   779 
   780   if (!cmap)
   781     return;
   782 
   783   /* Now pick the ``best'' character map the same way as sfntfont_open
   784      does.  The caveat is that since the subtable data has not been
   785      read, Emacs cannot determine whether or not the encoding subtable
   786      is valid.
   787 
   788      Once platform_id is set, that value becomes much more
   789      reliable.  */
   790 
   791   /* First look for a non-BMP Unicode cmap.  */
   792 
   793   for (i = 0; i < cmap->num_subtables; ++i)
   794     {
   795       if (sfntfont_identify_cmap (subtables[i]) == 2)
   796         {
   797           desc->registry
   798             = sfnt_registry_for_subtable (&subtables[i]);
   799           goto done;
   800         }
   801     }
   802 
   803   /* Next, look for a BMP only Unicode cmap.  */
   804 
   805   for (i = 0; i < cmap->num_subtables; ++i)
   806     {
   807       if (sfntfont_identify_cmap (subtables[i]) == 1)
   808         {
   809           desc->registry
   810             = sfnt_registry_for_subtable (&subtables[i]);
   811           goto done;
   812         }
   813     }
   814 
   815   /* Finally, use the first cmap that appears and can be
   816      identified.  */
   817 
   818   for (i = 0; i < cmap->num_subtables; ++i)
   819     {
   820       if (sfntfont_identify_cmap (subtables[i]) == 0)
   821         {
   822           desc->registry
   823             = sfnt_registry_for_subtable (&subtables[i]);
   824           goto done;
   825         }
   826     }
   827 
   828   /* There are no cmaps available to Emacs.  */
   829  done:
   830   xfree (cmap);
   831   xfree (subtables);
   832 }
   833 
   834 /* Return whether or not the font description PREV conflicts with the
   835    newer font description DESC, and should be removed from the list of
   836    system fonts.
   837 
   838    If PREV is a variable font, potentially adjust its list of
   839    instances.  */
   840 
   841 static bool
   842 sfnt_replace_fonts_p (struct sfnt_font_desc *prev,
   843                       struct sfnt_font_desc *desc)
   844 {
   845   int i, width, weight, slant, count_instance;
   846   Lisp_Object tem;
   847   bool family_equal_p;
   848 
   849   family_equal_p = !NILP (Fstring_equal (prev->family,
   850                                          desc->family));
   851 
   852   if ((!NILP (desc->instances)
   853        || !NILP (Fstring_equal (prev->style, desc->style)))
   854       && family_equal_p)
   855     return true;
   856 
   857   if (NILP (prev->instances) || !family_equal_p)
   858     return false;
   859 
   860   /* Look through instances in PREV to see if DESC provides the same
   861      thing.  */
   862 
   863   count_instance = 0;
   864   for (i = 0; i < ASIZE (prev->instances); ++i)
   865     {
   866       tem = AREF (prev->instances, i);
   867 
   868       if (NILP (tem))
   869         continue;
   870 
   871       width = XFIXNUM (AREF (tem, 2));
   872       weight = XFIXNUM (AREF (tem, 3));
   873       slant = XFIXNUM (AREF (tem, 4));
   874 
   875       if (desc->width == width
   876           && desc->weight == weight
   877           && desc->slant == slant)
   878         {
   879           /* Remove this instance.  */
   880           ASET (prev->instances, i, Qnil);
   881           continue;
   882         }
   883 
   884       count_instance++;
   885     }
   886 
   887   /* Remove this desc if there are no more instances.  */
   888   return count_instance < 1;
   889 }
   890 
   891 /* Enumerate the offset subtable SUBTABLES in the file FD, whose file
   892    name is FILE.  OFFSET should be the offset of the subtable within
   893    the font file, and is recorded for future use.  Value is 1 upon
   894    failure, else 0.  */
   895 
   896 static int
   897 sfnt_enum_font_1 (int fd, const char *file,
   898                   struct sfnt_offset_subtable *subtables,
   899                   off_t offset)
   900 {
   901   struct sfnt_font_desc *desc, **next, *prev;
   902   struct sfnt_head_table *head;
   903   struct sfnt_name_table *name;
   904   struct sfnt_meta_table *meta;
   905   struct sfnt_maxp_table *maxp;
   906   struct sfnt_fvar_table *fvar;
   907   struct sfnt_font_desc temp;
   908   Lisp_Object family, style, instance, style1;
   909   int i;
   910 
   911   /* Create the font desc and copy in the file name.  */
   912   desc = xzalloc (sizeof *desc + strlen (file) + 1);
   913   desc->path = (char *) (desc + 1);
   914   memcpy (desc->path, file, strlen (file) + 1);
   915   desc->offset = offset;
   916 
   917   /* Check that this is a TrueType font.  */
   918   if (subtables->scaler_type != SFNT_SCALER_TRUE
   919       && subtables->scaler_type != SFNT_SCALER_VER1)
   920     goto bail1;
   921 
   922   /* Read required tables.  */
   923   head = sfnt_read_head_table (fd, subtables);
   924   if (!head)
   925     goto bail1;
   926 
   927   name = sfnt_read_name_table (fd, subtables);
   928   if (!name)
   929     goto bail2;
   930 
   931   maxp = sfnt_read_maxp_table (fd, subtables);
   932   if (!maxp)
   933     goto bail3;
   934 
   935   /* meta is not required, nor present on many non-Apple fonts.  */
   936   meta = sfnt_read_meta_table (fd, subtables);
   937 
   938   /* Decode the family and style from the name table.  */
   939   if (sfnt_decode_family_style (name, &family, &style))
   940     goto bail4;
   941 
   942   /* See if this is a distortable/variable/multiple master font (all
   943      three terms mean the same time.)  */
   944   fvar = sfnt_read_fvar_table (fd, subtables);
   945 
   946   /* Set the family.  */
   947   desc->family = family;
   948   desc->designer = sfnt_decode_foundry_name (name);
   949   desc->char_cache = Qnil;
   950   desc->subtable.platform_id = 500;
   951 
   952   /* Set the largest glyph identifier.  */
   953   desc->num_glyphs = maxp->num_glyphs;
   954 
   955   /* Parse the style.  */
   956   sfnt_parse_style (style, desc);
   957 
   958   /* If the meta table exists, parse the list of design languages.  */
   959   if (meta)
   960     sfnt_parse_languages (meta, desc);
   961 
   962   /* Figure out the spacing.  Some fancy test like what Fontconfig
   963      does is probably in order but not really necessary.  */
   964   if (!NILP (Fstring_search (Fdowncase (family),
   965                              build_string ("mono"),
   966                              Qnil)))
   967     desc->spacing = 100; /* FC_MONO */
   968 
   969   /* Finally add mac-style flags.  Allow them to override styles that
   970      have not been found.  */
   971 
   972   if (head->mac_style & 01 && desc->weight == 80) /* Bold */
   973     desc->weight = 200;
   974 
   975   if (head->mac_style & 02 && desc->slant == 0) /* Italic */
   976     desc->slant = 100;
   977 
   978   /* Figure out what registry this font is likely to support.  */
   979   sfnt_grok_registry (fd, desc, subtables);
   980 
   981   if (fvar && fvar->instance_count)
   982     {
   983       /* If there is an fvar table with instances, then this is a font
   984          which defines different axes along which the points in each
   985          glyph can be changed.
   986 
   987          Instead of enumerating the font itself, enumerate each
   988          instance within, which specifies how to configure each axis
   989          to achieve a specified style.  */
   990 
   991       desc->instances = make_vector (fvar->instance_count, Qnil);
   992 
   993       for (i = 0; i < fvar->instance_count; ++i)
   994         {
   995           style1 = sfnt_decode_instance_name (&fvar->instance[i],
   996                                               name);
   997 
   998           if (NILP (style1))
   999             continue;
  1000 
  1001           /* Now parse the style.  */
  1002           temp.adstyle = Qnil;
  1003           sfnt_parse_style (style1, &temp);
  1004 
  1005           /* Set each field of the vector.  */
  1006           instance = make_vector (5, Qnil);
  1007           ASET (instance, 0, style1);
  1008           ASET (instance, 1, temp.adstyle);
  1009           ASET (instance, 2, make_fixnum (temp.width));
  1010           ASET (instance, 3, make_fixnum (temp.weight));
  1011           ASET (instance, 4, make_fixnum (temp.slant));
  1012 
  1013           /* Place the vector in desc->instances.  */
  1014           ASET (desc->instances, i, instance);
  1015         }
  1016     }
  1017 
  1018   /* Set the style, link the desc onto system_fonts and return.  */
  1019   desc->style = style;
  1020   desc->next = system_fonts;
  1021   system_fonts = desc;
  1022 
  1023   /* Remove any fonts which have the same style as this one.  For
  1024      distortable fonts, only remove overlapping styles, unless this is
  1025      also a distortable font.  */
  1026 
  1027   next = &system_fonts->next;
  1028   prev = *next;
  1029   for (; *next; prev = *next)
  1030     {
  1031       if (sfnt_replace_fonts_p (prev, desc))
  1032         {
  1033           *next = prev->next;
  1034           xfree (prev);
  1035         }
  1036       else
  1037         next = &prev->next;
  1038     }
  1039 
  1040   xfree (fvar);
  1041   xfree (meta);
  1042   xfree (maxp);
  1043   xfree (name);
  1044   xfree (head);
  1045   return 0;
  1046 
  1047  bail4:
  1048   xfree (meta);
  1049   xfree (maxp);
  1050  bail3:
  1051   xfree (name);
  1052  bail2:
  1053   xfree (head);
  1054  bail1:
  1055   xfree (desc);
  1056   return 1;
  1057 }
  1058 
  1059 /* Enumerate the font FILE into the list of system fonts.  Return 1 if
  1060    it could not be enumerated, 0 otherwise.
  1061 
  1062    Remove any font whose family and style is a duplicate of this one.
  1063 
  1064    FILE can either be a TrueType collection file containing TrueType
  1065    fonts, or a TrueType font itself.  */
  1066 
  1067 int
  1068 sfnt_enum_font (const char *file)
  1069 {
  1070   int fd, rc;
  1071   struct sfnt_offset_subtable *subtables;
  1072   struct sfnt_ttc_header *ttc;
  1073   size_t i;
  1074 
  1075   /* Now open the font for reading.  */
  1076   fd = emacs_open (file, O_RDONLY, 0);
  1077 
  1078   if (fd == -1)
  1079     goto bail;
  1080 
  1081   /* Read the table directory.  */
  1082   subtables = sfnt_read_table_directory (fd);
  1083 
  1084   if (subtables == (struct sfnt_offset_subtable *) -1)
  1085     {
  1086       /* This is actually a TrueType container file.  Go back to the
  1087          beginning and read the TTC header.  */
  1088 
  1089       if (lseek (fd, 0, SEEK_SET))
  1090         goto bail0;
  1091 
  1092       ttc = sfnt_read_ttc_header (fd);
  1093 
  1094       if (!ttc)
  1095         goto bail0;
  1096 
  1097       /* Enumerate each of the fonts in the collection.  */
  1098 
  1099       for (i = 0; i < ttc->num_fonts; ++i)
  1100         {
  1101           if (lseek (fd, ttc->offset_table[i], SEEK_SET)
  1102               != ttc->offset_table[i])
  1103             continue;
  1104 
  1105           subtables = sfnt_read_table_directory (fd);
  1106 
  1107           if (!subtables)
  1108             continue;
  1109 
  1110           sfnt_enum_font_1 (fd, file, subtables,
  1111                             ttc->offset_table[i]);
  1112           xfree (subtables);
  1113         }
  1114 
  1115       /* Always treat reading containers as having been
  1116          successful.  */
  1117 
  1118       emacs_close (fd);
  1119       xfree (ttc);
  1120       return 0;
  1121     }
  1122 
  1123   if (!subtables)
  1124     goto bail0;
  1125 
  1126   /* Now actually enumerate this font.  */
  1127   rc = sfnt_enum_font_1 (fd, file, subtables, 0);
  1128   xfree (subtables);
  1129   emacs_close (fd);
  1130   return rc;
  1131 
  1132  bail0:
  1133   emacs_close (fd);
  1134  bail:
  1135   return 1;
  1136 }
  1137 
  1138 
  1139 
  1140 /* Font discovery and matching.  */
  1141 
  1142 static struct charset *
  1143 sfntfont_charset_for_name (Lisp_Object symbol)
  1144 {
  1145   ptrdiff_t idx;
  1146   int id;
  1147 
  1148   idx = CHARSET_SYMBOL_HASH_INDEX (symbol);
  1149 
  1150   if (idx == -1)
  1151     return NULL;
  1152 
  1153   /* Vcharset_hash_table is not a real variable, so Lisp programs
  1154      can't clobber it.  */
  1155   id = XFIXNUM (AREF (HASH_VALUE (XHASH_TABLE (Vcharset_hash_table),
  1156                                   idx),
  1157                       charset_id));
  1158 
  1159   return CHARSET_FROM_ID (id);
  1160 }
  1161 
  1162 /* Return the character set corresponding to a cmap subtable SUBTABLE.
  1163    Value is NULL if the subtable is not supported.  */
  1164 
  1165 static struct charset *
  1166 sfntfont_charset_for_cmap (struct sfnt_cmap_encoding_subtable subtable)
  1167 {
  1168   switch (subtable.platform_id)
  1169     {
  1170     case SFNT_PLATFORM_UNICODE:
  1171       /* Reject variation selector and last resort tables.  */
  1172       if ((subtable.platform_specific_id
  1173            == SFNT_UNICODE_VARIATION_SEQUENCES)
  1174           || (subtable.platform_specific_id
  1175               == SFNT_UNICODE_LAST_RESORT))
  1176         return NULL;
  1177 
  1178       /* 1.0, 1.1, ISO-10646-1993, and 2.0_BMP tables are all within
  1179          the BMP.  */
  1180       if (subtable.platform_specific_id < SFNT_UNICODE_2_0)
  1181         return sfntfont_charset_for_name (Qunicode_bmp);
  1182 
  1183       return sfntfont_charset_for_name (Qunicode);
  1184 
  1185     case SFNT_PLATFORM_MACINTOSH:
  1186 
  1187       switch (subtable.platform_specific_id)
  1188         {
  1189         case SFNT_MACINTOSH_ROMAN:
  1190           return sfntfont_charset_for_name (Qmac_roman);
  1191 
  1192         default:
  1193           /* Some other Macintosh charset not supported by Emacs.  */
  1194           return NULL;
  1195         }
  1196 
  1197     case SFNT_PLATFORM_MICROSOFT:
  1198 
  1199       /* Microsoft specific encodings.  */
  1200 
  1201       switch (subtable.platform_specific_id)
  1202         {
  1203         case SFNT_MICROSOFT_SYMBOL:
  1204           /* Symbols in the Unicode PUA are still Unicode.  */
  1205           return sfntfont_charset_for_name (Qunicode);
  1206 
  1207         case SFNT_MICROSOFT_UNICODE_BMP:
  1208           return sfntfont_charset_for_name (Qunicode_bmp);
  1209 
  1210         case SFNT_MICROSOFT_SHIFT_JIS:
  1211           /* PCK aka japanese-jisx0208.  */
  1212           return sfntfont_charset_for_name (Qjapanese_jisx0208);
  1213 
  1214         case SFNT_MICROSOFT_PRC:
  1215           /* GBK, GB2312 or GB18030.  */
  1216           return sfntfont_charset_for_name (Qgbk);
  1217 
  1218         case SFNT_MICROSOFT_JOHAB:
  1219           /* KS C 5601-1992, aka korean-ksc5601.  */
  1220           return sfntfont_charset_for_name (Qkorean_ksc5601);
  1221 
  1222         case SFNT_MICROSOFT_UNICODE_UCS_4:
  1223           /* Unicode past the BMP.  */
  1224           return sfntfont_charset_for_name (Qucs);
  1225         }
  1226 
  1227     default:
  1228       return NULL;
  1229     }
  1230 }
  1231 
  1232 /* Pick the best character map in the cmap table CMAP.  Use the
  1233    subtables in SUBTABLES and DATA.  Return the subtable data and the
  1234    subtable in *SUBTABLE upon success, NULL otherwise.
  1235 
  1236    If FORMAT14 is non-NULL, return any associated format 14 variation
  1237    selection context in *FORMAT14 should the selected charcter map be
  1238    a Unicode character map.  */
  1239 
  1240 static struct sfnt_cmap_encoding_subtable_data *
  1241 sfntfont_select_cmap (struct sfnt_cmap_table *cmap,
  1242                       struct sfnt_cmap_encoding_subtable *subtables,
  1243                       struct sfnt_cmap_encoding_subtable_data **data,
  1244                       struct sfnt_cmap_encoding_subtable *subtable,
  1245                       struct sfnt_cmap_format_14 **format14)
  1246 {
  1247   int i, j;
  1248 
  1249   /* First look for a non-BMP Unicode cmap.  */
  1250 
  1251   for (i = 0; i < cmap->num_subtables; ++i)
  1252     {
  1253       if (data[i] && sfntfont_identify_cmap (subtables[i]) == 2)
  1254         {
  1255           *subtable = subtables[i];
  1256 
  1257           if (!format14)
  1258             return data[i];
  1259 
  1260           /* Search for a correspoinding format 14 character map.
  1261              This is used in conjunction with the selected character
  1262              map to map variation sequences.  */
  1263 
  1264           for (j = 0; j < cmap->num_subtables; ++j)
  1265             {
  1266               if (data[j]
  1267                   && subtables[j].platform_id == SFNT_PLATFORM_UNICODE
  1268                   && (subtables[j].platform_specific_id
  1269                       == SFNT_UNICODE_VARIATION_SEQUENCES)
  1270                   && data[j]->format == 14)
  1271                 *format14 = (struct sfnt_cmap_format_14 *) data[j];
  1272             }
  1273 
  1274           return data[i];
  1275         }
  1276     }
  1277 
  1278   /* Next, look for a BMP only Unicode cmap.  */
  1279 
  1280   for (i = 0; i < cmap->num_subtables; ++i)
  1281     {
  1282       if (data[i] && sfntfont_identify_cmap (subtables[i]) == 1)
  1283         {
  1284           *subtable = subtables[i];
  1285 
  1286           if (!format14)
  1287             return data[i];
  1288 
  1289           /* Search for a correspoinding format 14 character map.
  1290              This is used in conjunction with the selected character
  1291              map to map variation sequences.  */
  1292 
  1293           for (j = 0; j < cmap->num_subtables; ++j)
  1294             {
  1295               if (data[j]
  1296                   && subtables[j].platform_id == SFNT_PLATFORM_UNICODE
  1297                   && (subtables[j].platform_specific_id
  1298                       == SFNT_UNICODE_VARIATION_SEQUENCES)
  1299                   && data[j]->format == 14)
  1300                 *format14 = (struct sfnt_cmap_format_14 *) data[j];
  1301             }
  1302 
  1303           return data[i];
  1304         }
  1305     }
  1306 
  1307   /* Finally, use the first cmap that appears and can be
  1308      identified.  */
  1309 
  1310   for (i = 0; i < cmap->num_subtables; ++i)
  1311     {
  1312       if (data[i] && sfntfont_identify_cmap (subtables[i]) == 0)
  1313         {
  1314           *subtable = subtables[i];
  1315           return data[i];
  1316         }
  1317     }
  1318 
  1319   /* There are no cmaps available to Emacs.  */
  1320   return NULL;
  1321 }
  1322 
  1323 /* Read the cmap from the font descriptor DESC, and place it in CMAP.
  1324    Keep *CMAP untouched if opening the cmap fails.  Set SUBTABLE to
  1325    the cmap's header upon success.  */
  1326 
  1327 static void
  1328 sfntfont_read_cmap (struct sfnt_font_desc *desc,
  1329                     struct sfnt_cmap_encoding_subtable_data **cmap,
  1330                     struct sfnt_cmap_encoding_subtable *subtable)
  1331 {
  1332   struct sfnt_offset_subtable *font;
  1333   struct sfnt_cmap_encoding_subtable *subtables;
  1334   struct sfnt_cmap_encoding_subtable_data **data;
  1335   struct sfnt_cmap_table *table;
  1336   int fd, i;
  1337 
  1338   /* Pick a character map and place it in *CMAP.  */
  1339   fd = emacs_open (desc->path, O_RDONLY, 0);
  1340 
  1341   if (fd < 0)
  1342     return;
  1343 
  1344   font = sfnt_read_table_directory (fd);
  1345 
  1346   if (!font)
  1347     {
  1348       emacs_close (fd);
  1349       return;
  1350     }
  1351 
  1352   table = sfnt_read_cmap_table (fd, font, &subtables,
  1353                                 &data);
  1354   xfree (font);
  1355 
  1356   if (!table)
  1357     {
  1358       emacs_close (fd);
  1359       return;
  1360     }
  1361 
  1362   /* Now pick the best character map.  */
  1363 
  1364   *cmap = sfntfont_select_cmap (table, subtables, data,
  1365                                 subtable, NULL);
  1366 
  1367   /* Free the cmap data.  */
  1368 
  1369   for (i = 0; i < table->num_subtables; ++i)
  1370     {
  1371       if (data[i] != *cmap)
  1372         xfree (data[i]);
  1373     }
  1374 
  1375   xfree (data);
  1376   xfree (subtables);
  1377   xfree (table);
  1378   emacs_close (fd);
  1379 }
  1380 
  1381 /* Return whether or not CHARACTER has an associated mapping in CMAP,
  1382    and the mapping points to a valid glyph.  DESC is the font
  1383    descriptor associated with the font.  */
  1384 
  1385 static bool
  1386 sfntfont_glyph_valid (struct sfnt_font_desc *desc,
  1387                       sfnt_char font_character,
  1388                       struct sfnt_cmap_encoding_subtable_data *cmap)
  1389 {
  1390   sfnt_glyph glyph;
  1391 
  1392   glyph = sfnt_lookup_glyph (font_character, cmap);
  1393 
  1394   if (!glyph)
  1395     return false;
  1396 
  1397   return glyph <= desc->num_glyphs;
  1398 }
  1399 
  1400 /* Look up a character CHARACTER in the font description DESC.  Cache
  1401    the results.  Return true if the character exists, false otherwise.
  1402 
  1403    If *CMAP is NULL, select a character map for the font and save it
  1404    there.  Otherwise, use the character map in *CMAP.  Save data
  1405    associated with the character map in *SUBTABLE.  */
  1406 
  1407 static bool
  1408 sfntfont_lookup_char (struct sfnt_font_desc *desc, Lisp_Object character,
  1409                       struct sfnt_cmap_encoding_subtable_data **cmap,
  1410                       struct sfnt_cmap_encoding_subtable *subtable)
  1411 {
  1412   Lisp_Object cached;
  1413   sfnt_char font_character;
  1414   struct charset *charset;
  1415   bool present;
  1416 
  1417   /* Return false for characters that don't fit in a char table.  */
  1418   if (XFIXNUM (character) > INT_MAX || XFIXNUM (character) < 0)
  1419     return false;
  1420 
  1421   if (!NILP (desc->char_cache))
  1422     {
  1423       cached = char_table_ref (desc->char_cache,
  1424                                XFIXNUM (character));
  1425       if (!NILP (cached))
  1426         return (EQ (cached, Qlambda) ? false : true);
  1427     }
  1428 
  1429   if (!*cmap && !desc->cmap_invalid)
  1430     sfntfont_read_cmap (desc, cmap, subtable);
  1431 
  1432   /* Check that a cmap is now present.  */
  1433   if (!*cmap)
  1434     {
  1435       /* Opening the cmap failed.  Set desc->cmap_invalid to avoid
  1436          opening it again.  */
  1437       desc->cmap_invalid = true;
  1438       return false;
  1439     }
  1440 
  1441   /* Otherwise, encode the character.  */
  1442 
  1443   charset = sfntfont_charset_for_cmap (*subtable);
  1444   if (!charset)
  1445     /* Emacs missing charsets? */
  1446     return false;
  1447 
  1448   font_character = ENCODE_CHAR (charset, (int) XFIXNUM (character));
  1449 
  1450   if (font_character == CHARSET_INVALID_CODE (charset))
  1451     return false;
  1452 
  1453   /* Now return whether or not the glyph is present.  Noto Sans
  1454      Georgian comes with a corrupt format 4 cmap table that somehow
  1455      tries to express glyphs greater than 65565.  */
  1456   present = sfntfont_glyph_valid (desc, font_character, *cmap);
  1457 
  1458   /* Cache the result.  Store Qlambda when not present, Qt
  1459      otherwise.  */
  1460 
  1461   if (NILP (desc->char_cache))
  1462     desc->char_cache = Fmake_char_table (Qfont_lookup_cache,
  1463                                          Qnil);
  1464 
  1465   Fset_char_table_range (desc->char_cache, character,
  1466                          present ? Qt : Qlambda);
  1467   return present;
  1468 }
  1469 
  1470 /* Return whether or not the specified registry A is ``compatible''
  1471    with registry B.
  1472 
  1473    Compatibility does not refer to whether or not the font registries
  1474    have an identical character set or repertory of characters.
  1475 
  1476    Instead, it refers to whether or not Emacs expects looking for A to
  1477    result in fonts used with B.  */
  1478 
  1479 static bool
  1480 sfntfont_registries_compatible_p (Lisp_Object a, Lisp_Object b)
  1481 {
  1482   if (EQ (a, Qiso8859_1) && EQ (b, Qiso10646_1))
  1483     return true;
  1484 
  1485   return EQ (a, b);
  1486 }
  1487 
  1488 /* Return whether or not the font description DESC satisfactorily
  1489    matches the font specification FONT_SPEC.
  1490 
  1491    Value is 0 if there is no match, -1 if there is a match against
  1492    DESC itself, and the number of matching instances if the style
  1493    matches one or more instances defined in in DESC.  Return the index
  1494    of each matching instance in INSTANCES; it should be SIZE big.  */
  1495 
  1496 static int
  1497 sfntfont_list_1 (struct sfnt_font_desc *desc, Lisp_Object spec,
  1498                  int *instances, int size)
  1499 {
  1500   Lisp_Object tem, extra, tail;
  1501   struct sfnt_cmap_encoding_subtable_data *cmap;
  1502   size_t i;
  1503   struct sfnt_cmap_encoding_subtable subtable;
  1504   int instance, num_instance;
  1505   Lisp_Object item;
  1506 
  1507   /* cmap and subtable are caches for sfntfont_lookup_char.  */
  1508 
  1509   /* Check that the family name in SPEC matches DESC->family if it is
  1510      specified.  */
  1511 
  1512   tem = AREF (spec, FONT_FAMILY_INDEX);
  1513 
  1514   /* If TEM is a family listed in Vsfnt_default_family_alist,
  1515      then use that instead.  */
  1516 
  1517   if (SYMBOLP (tem) && CONSP (Vsfnt_default_family_alist))
  1518     {
  1519       tail = Vsfnt_default_family_alist;
  1520       FOR_EACH_TAIL_SAFE (tail)
  1521         {
  1522           if (!CONSP (XCAR (tail)))
  1523             continue;
  1524 
  1525           if (STRINGP (XCAR (XCAR (tail)))
  1526               && STRINGP (XCDR (XCAR (tail)))
  1527               && !NILP (Fstring_equal (SYMBOL_NAME (tem),
  1528                                        XCAR (XCAR (tail)))))
  1529             {
  1530               /* Special family found.  */
  1531               tem = Fintern (XCDR (XCAR (tail)), Qnil);
  1532               break;
  1533             }
  1534         }
  1535     }
  1536 
  1537   if (!NILP (tem) && NILP (Fstring_equal (SYMBOL_NAME (tem),
  1538                                           desc->family)))
  1539     return 0;
  1540 
  1541   instance = -1;
  1542 
  1543   /* If a registry is set and wrong, then reject the font desc
  1544      immediately.  This detects 50% of mismatches from fontset.c.
  1545 
  1546      If DESC->registry is nil, then the registry couldn't be
  1547      determined beforehand.  */
  1548 
  1549   tem = AREF (spec, FONT_REGISTRY_INDEX);
  1550   if (!NILP (tem) && !NILP (desc->registry)
  1551       && !sfntfont_registries_compatible_p (tem, desc->registry))
  1552     return 0;
  1553 
  1554   /* Check the style.  If DESC is a fixed font, just check once.
  1555      Otherwise, check each instance.  */
  1556 
  1557   if (NILP (desc->instances))
  1558     {
  1559       tem = AREF (spec, FONT_ADSTYLE_INDEX);
  1560       if (!NILP (tem) && NILP (Fequal (tem, desc->adstyle)))
  1561         return 0;
  1562 
  1563       if (FONT_WIDTH_NUMERIC (spec) != -1
  1564           && FONT_WIDTH_NUMERIC (spec) != desc->width)
  1565         return 0;
  1566 
  1567       if (FONT_WEIGHT_NUMERIC (spec) != -1
  1568           && FONT_WEIGHT_NUMERIC (spec) != desc->weight)
  1569         return 0;
  1570 
  1571       if (FONT_SLANT_NUMERIC (spec) != -1
  1572           && FONT_SLANT_NUMERIC (spec) != desc->slant)
  1573         return 0;
  1574     }
  1575   else
  1576     {
  1577       num_instance = 0;
  1578 
  1579       /* Find the indices of instances in this distortable font which
  1580          match the given font spec.  */
  1581 
  1582       for (i = 0; i < ASIZE (desc->instances); ++i)
  1583         {
  1584           item = AREF (desc->instances, i);
  1585 
  1586           if (NILP (item))
  1587             continue;
  1588 
  1589           /* Check that the adstyle specified matches.  */
  1590 
  1591           tem = AREF (spec, FONT_ADSTYLE_INDEX);
  1592           if (!NILP (tem) && NILP (Fequal (tem, AREF (item, 1))))
  1593             continue;
  1594 
  1595           /* Check the style.  */
  1596 
  1597           if (FONT_WIDTH_NUMERIC (spec) != -1
  1598               && (FONT_WIDTH_NUMERIC (spec)
  1599                   != XFIXNUM (AREF (item, 2))))
  1600             continue;
  1601 
  1602           if (FONT_WEIGHT_NUMERIC (spec) != -1
  1603               && (FONT_WEIGHT_NUMERIC (spec)
  1604                   != XFIXNUM (AREF (item, 3))))
  1605             continue;
  1606 
  1607           if (FONT_SLANT_NUMERIC (spec) != -1
  1608               && (FONT_SLANT_NUMERIC (spec)
  1609                   != XFIXNUM (AREF (item, 4))))
  1610             continue;
  1611 
  1612           if (num_instance == size)
  1613             break;
  1614 
  1615           /* A matching instance has been found.  Set its index, then
  1616              go back to the rest of the font matching.  */
  1617           instances[num_instance++] = i;
  1618         }
  1619 
  1620       instance = num_instance;
  1621     }
  1622 
  1623   /* Handle extras.  */
  1624   extra = AREF (spec, FONT_EXTRA_INDEX);
  1625 
  1626   if (NILP (extra))
  1627     return instance;
  1628 
  1629   tem = assq_no_quit (QCscript, extra);
  1630   cmap = NULL;
  1631 
  1632   if (!NILP (tem))
  1633     {
  1634       /* If a script has been specified, look up its representative
  1635          characters and see if they are present in the font.  This
  1636          requires reading the cmap.  */
  1637       tem = assq_no_quit (XCDR (tem), Vscript_representative_chars);
  1638 
  1639       if (CONSP (tem) && VECTORP (XCDR (tem)))
  1640         {
  1641           tem = XCDR (tem);
  1642 
  1643           /* The vector contains characters, of which one must be
  1644              present in the font.  */
  1645           for (i = 0; i < ASIZE (tem); ++i)
  1646             {
  1647               if (FIXNUMP (AREF (tem, i)))
  1648                 {
  1649                   if (!sfntfont_lookup_char (desc, AREF (tem, i),
  1650                                              &cmap, &subtable))
  1651                     goto fail;
  1652 
  1653                   /* One character is enough to pass a font.  Don't
  1654                      look at too many.  */
  1655                   break;
  1656                 }
  1657             }
  1658         }
  1659       else if (CONSP (tem) && CONSP (XCDR (tem)))
  1660         {
  1661           tem = XCDR (tem);
  1662 
  1663           /* tem is a list of each characters, all of which must be
  1664              present in the font.  */
  1665           FOR_EACH_TAIL_SAFE (tem)
  1666             {
  1667               if (FIXNUMP (XCAR (tem))
  1668                   && !sfntfont_lookup_char (desc, XCAR (tem), &cmap,
  1669                                             &subtable))
  1670                 goto fail;
  1671             }
  1672 
  1673           /* One or more characters are missing.  */
  1674           if (!NILP (tem))
  1675             goto fail;
  1676         }
  1677       /* Fail if there are no matching fonts at all.  */
  1678       else if (NILP (tem))
  1679         goto fail;
  1680     }
  1681 
  1682   /* Now check that the language is supported.  */
  1683   tem = assq_no_quit (QClang, extra);
  1684   if (!NILP (tem) && NILP (Fmemq (tem, desc->languages)))
  1685     goto fail;
  1686 
  1687   /* Set desc->subtable if cmap was specified.  */
  1688   if (cmap)
  1689     desc->subtable = subtable;
  1690 
  1691   xfree (cmap);
  1692   return instance;
  1693 
  1694  fail:
  1695   /* The cmap might've been read in and require deallocation.  */
  1696   xfree (cmap);
  1697   return 0;
  1698 }
  1699 
  1700 /* Type of font entities and font objects created.  */
  1701 static Lisp_Object sfnt_vendor_name;
  1702 
  1703 /* Font driver used in font objects created.  */
  1704 static const struct font_driver *sfnt_font_driver;
  1705 
  1706 /* Return the font registry corresponding to the font descriptor DESC.
  1707    Under X, the font registry is an atom registered with the Open
  1708    Group uniquely identifying the organization which defines the
  1709    font's character set.
  1710 
  1711    In practice, the registry overlaps with the character set itself.
  1712    So Emacs just uses the ``registry'' field to represent both
  1713    instead.  */
  1714 
  1715 static Lisp_Object
  1716 sfntfont_registry_for_desc (struct sfnt_font_desc *desc)
  1717 {
  1718   struct sfnt_cmap_encoding_subtable_data *cmap;
  1719 
  1720   cmap = NULL;
  1721 
  1722   if (desc->cmap_invalid)
  1723     return Qnil;
  1724 
  1725   if (desc->subtable.platform_id == 500)
  1726     {
  1727       /* Read in the cmap to determine the registry.  */
  1728       sfntfont_read_cmap (desc, &cmap, &desc->subtable);
  1729 
  1730       if (!cmap)
  1731         {
  1732           desc->cmap_invalid = true;
  1733           return Qnil;
  1734         }
  1735     }
  1736 
  1737   xfree (cmap);
  1738 
  1739   if (desc->subtable.platform_id != 500)
  1740     /* desc->subtable.platform_id is now set.  CMAP is already free,
  1741        because it is not actually used.  */
  1742     return sfnt_registry_for_subtable (&desc->subtable);
  1743 
  1744   return Qnil;
  1745 }
  1746 
  1747 /* Return a font-entity that represents the font descriptor (unopened
  1748    font) DESC.  If INSTANCE is more than or equal to 1, then it is the
  1749    index of the instance in DESC that should be opened plus 1; in that
  1750    case, DESC must be a distortable font.  */
  1751 
  1752 static Lisp_Object
  1753 sfntfont_desc_to_entity (struct sfnt_font_desc *desc, int instance)
  1754 {
  1755   Lisp_Object entity, vector;
  1756 
  1757   entity = font_make_entity ();
  1758 
  1759   ASET (entity, FONT_TYPE_INDEX, sfnt_vendor_name);
  1760 
  1761   if (!NILP (desc->designer))
  1762     ASET (entity, FONT_FOUNDRY_INDEX,
  1763           Fintern (desc->designer, Qnil));
  1764 
  1765   ASET (entity, FONT_FAMILY_INDEX, Fintern (desc->family, Qnil));
  1766   ASET (entity, FONT_ADSTYLE_INDEX, Qnil);
  1767   ASET (entity, FONT_REGISTRY_INDEX,
  1768         sfntfont_registry_for_desc (desc));
  1769 
  1770   /* Size of 0 means the font is scalable.  */
  1771   ASET (entity, FONT_SIZE_INDEX, make_fixnum (0));
  1772   ASET (entity, FONT_AVGWIDTH_INDEX, make_fixnum (0));
  1773   ASET (entity, FONT_SPACING_INDEX,
  1774         make_fixnum (desc->spacing));
  1775 
  1776   if (instance >= 1)
  1777     {
  1778       if (NILP (desc->instances)
  1779           || instance > ASIZE (desc->instances))
  1780         emacs_abort ();
  1781 
  1782       vector = AREF (desc->instances, instance - 1);
  1783       FONT_SET_STYLE (entity, FONT_WIDTH_INDEX,
  1784                       AREF (vector, 2));
  1785       FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX,
  1786                       AREF (vector, 3));
  1787       FONT_SET_STYLE (entity, FONT_SLANT_INDEX,
  1788                       AREF (vector, 4));
  1789       ASET (entity, FONT_ADSTYLE_INDEX, AREF (vector, 1));      
  1790     }
  1791   else
  1792     {
  1793       FONT_SET_STYLE (entity, FONT_WIDTH_INDEX,
  1794                       make_fixnum (desc->width));
  1795       FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX,
  1796                       make_fixnum (desc->weight));
  1797       FONT_SET_STYLE (entity, FONT_SLANT_INDEX,
  1798                       make_fixnum (desc->slant));
  1799       ASET (entity, FONT_ADSTYLE_INDEX, desc->adstyle);
  1800     }
  1801 
  1802   /* Set FONT_EXTRA_INDEX to a pointer to the font description.  Font
  1803      descriptions are never supposed to be freed.  */
  1804 
  1805   ASET (entity, FONT_EXTRA_INDEX,
  1806         (instance >= 1
  1807          ? list2 (Fcons (Qfont_entity, make_mint_ptr (desc)),
  1808                   Fcons (Qfont_instance, make_fixnum (instance - 1)))
  1809          : list1 (Fcons (Qfont_entity, make_mint_ptr (desc)))));
  1810 
  1811   return entity;
  1812 }
  1813 
  1814 /* Return a list of font-entities matching the specified
  1815    FONT_SPEC.  */
  1816 
  1817 Lisp_Object
  1818 sfntfont_list (struct frame *f, Lisp_Object font_spec)
  1819 {
  1820   Lisp_Object matching, tem;
  1821   struct sfnt_font_desc *desc;
  1822   int i, rc, instances[100];
  1823 
  1824   matching = Qnil;
  1825 
  1826   block_input ();
  1827   /* Returning irrelevant results on receiving an OTF form will cause
  1828      fontset.c to loop over and over, making displaying some
  1829      characters very slow.  */
  1830   tem = assq_no_quit (QCotf, AREF (font_spec, FONT_EXTRA_INDEX));
  1831   if (CONSP (tem) && !NILP (XCDR (tem)))
  1832     {
  1833       unblock_input ();
  1834       return Qnil;
  1835     }
  1836 
  1837   /* Loop through known system fonts and add them one-by-one.  */
  1838 
  1839   for (desc = system_fonts; desc; desc = desc->next)
  1840     {
  1841       rc = sfntfont_list_1 (desc, font_spec, instances,
  1842                             ARRAYELTS (instances));
  1843 
  1844       if (rc < 0)
  1845         matching = Fcons (sfntfont_desc_to_entity (desc, 0),
  1846                           matching);
  1847       else if (rc)
  1848         {
  1849           /* Add each matching instance.  */
  1850 
  1851           for (i = 0; i < rc; ++i)
  1852             matching = Fcons (sfntfont_desc_to_entity (desc,
  1853                                                        instances[i] + 1),
  1854                               matching);
  1855         }
  1856     }
  1857 
  1858   unblock_input ();
  1859 
  1860   return matching;
  1861 }
  1862 
  1863 /* Return the first font-entity matching the specified FONT_SPEC.  */
  1864 
  1865 Lisp_Object
  1866 sfntfont_match (struct frame *f, Lisp_Object font_spec)
  1867 {
  1868   Lisp_Object matches;
  1869 
  1870   matches = sfntfont_list (f, font_spec);
  1871 
  1872   if (!NILP (matches))
  1873     return XCAR (matches);
  1874 
  1875   return Qnil;
  1876 }
  1877 
  1878 
  1879 
  1880 enum
  1881   {
  1882     SFNT_OUTLINE_CACHE_SIZE = 256,
  1883     SFNT_RASTER_CACHE_SIZE  = 128,
  1884   };
  1885 
  1886 /* Caching subsystem.  Generating outlines from glyphs is expensive,
  1887    and so is rasterizing them, so two caches are maintained for both
  1888    glyph outlines and rasters.
  1889 
  1890    Computing metrics also requires some expensive processing if the
  1891    glyph has instructions or distortions.  */
  1892 
  1893 struct sfnt_outline_cache
  1894 {
  1895   /* Next and last cache buckets.  */
  1896   struct sfnt_outline_cache *next, *last;
  1897 
  1898   /* Pointer to outline.  */
  1899   struct sfnt_glyph_outline *outline;
  1900 
  1901   /* Reference to glyph metrics.  */
  1902   struct sfnt_glyph_metrics metrics;
  1903 
  1904   /* What glyph this caches.  */
  1905   sfnt_glyph glyph;
  1906 };
  1907 
  1908 struct sfnt_raster_cache
  1909 {
  1910   /* Next and last cache buckets.  */
  1911   struct sfnt_raster_cache *next, *last;
  1912 
  1913   /* Pointer to raster.  */
  1914   struct sfnt_raster *raster;
  1915 
  1916   /* What glyph this caches.  */
  1917   sfnt_glyph glyph;
  1918 };
  1919 
  1920 struct sfntfont_get_glyph_outline_dcontext
  1921 {
  1922   /* Long and short loca tables.  */
  1923   struct sfnt_loca_table_long *loca_long;
  1924   struct sfnt_loca_table_short *loca_short;
  1925 
  1926   /* glyf table.  */
  1927   struct sfnt_glyf_table *glyf;
  1928 
  1929   /* Variation settings, or NULL.  */
  1930   struct sfnt_blend *blend;
  1931 };
  1932 
  1933 /* Return the glyph identified by GLYPH_ID from the glyf and loca
  1934    table specified in DCONTEXT.  Set *NEED_FREE to true.  */
  1935 
  1936 static struct sfnt_glyph *
  1937 sfntfont_get_glyph (sfnt_glyph glyph_id, void *dcontext,
  1938                     bool *need_free)
  1939 {
  1940   struct sfntfont_get_glyph_outline_dcontext *tables;
  1941   struct sfnt_glyph *glyph;
  1942   struct sfnt_metrics_distortion distortion;
  1943 
  1944   tables = dcontext;
  1945   *need_free = true;
  1946 
  1947   glyph = sfnt_read_glyph (glyph_id, tables->glyf,
  1948                            tables->loca_short,
  1949                            tables->loca_long);
  1950 
  1951   if (tables->blend && glyph)
  1952     {
  1953       if (glyph->simple)
  1954         sfnt_vary_simple_glyph (tables->blend, glyph_id, glyph,
  1955                                 &distortion);
  1956       else
  1957         sfnt_vary_compound_glyph (tables->blend, glyph_id, glyph,
  1958                                   &distortion);
  1959     }
  1960 
  1961   /* Note that the distortion is not relevant for compound glyphs.  */
  1962   return glyph;
  1963 }
  1964 
  1965 /* Free the glyph identified by GLYPH.  */
  1966 
  1967 static void
  1968 sfntfont_free_glyph (struct sfnt_glyph *glyph, void *dcontext)
  1969 {
  1970   sfnt_free_glyph (glyph);
  1971 }
  1972 
  1973 /* Dereference the outline OUTLINE.  Free it once refcount reaches
  1974    0.  */
  1975 
  1976 static void
  1977 sfntfont_dereference_outline (struct sfnt_glyph_outline *outline)
  1978 {
  1979   eassert (outline->refcount > 0);
  1980 
  1981   if (--outline->refcount)
  1982     return;
  1983 
  1984   xfree (outline);
  1985 }
  1986 
  1987 /* Get the outline corresponding to the specified GLYPH_CODE in CACHE.
  1988    Use the scale factor SCALE, the glyf table GLYF, and the head table
  1989    HEAD.  Keep *CACHE_SIZE updated with the number of elements in the
  1990    cache.
  1991 
  1992    Distort the glyph using BLEND if INDEX is not -1.
  1993 
  1994    Use the offset information in the long or short loca tables
  1995    LOCA_LONG and LOCA_SHORT, whichever is set.
  1996 
  1997    Use the specified HMTX, HEAD, HHEA and MAXP tables when instructing
  1998    compound glyphs.
  1999 
  2000    If INTERPRETER is non-NULL, then possibly use it and the
  2001    interpreter graphics STATE to instruct the glyph.
  2002 
  2003    If METRICS is non-NULL, return the scaled glyph metrics after
  2004    variation and instructing.
  2005 
  2006    Return the outline with an incremented reference count and enter
  2007    the generated outline into CACHE upon success, possibly discarding
  2008    any older outlines, or NULL on failure.  */
  2009 
  2010 static struct sfnt_glyph_outline *
  2011 sfntfont_get_glyph_outline (sfnt_glyph glyph_code,
  2012                             struct sfnt_outline_cache *cache,
  2013                             sfnt_fixed scale, int *cache_size,
  2014                             struct sfnt_blend *blend,
  2015                             int index,
  2016                             struct sfnt_glyf_table *glyf,
  2017                             struct sfnt_head_table *head,
  2018                             struct sfnt_hmtx_table *hmtx,
  2019                             struct sfnt_hhea_table *hhea,
  2020                             struct sfnt_maxp_table *maxp,
  2021                             struct sfnt_loca_table_short *loca_short,
  2022                             struct sfnt_loca_table_long *loca_long,
  2023                             struct sfnt_interpreter *interpreter,
  2024                             struct sfnt_glyph_metrics *metrics,
  2025                             struct sfnt_graphics_state *state)
  2026 {
  2027   struct sfnt_outline_cache *start;
  2028   struct sfnt_glyph_outline *outline;
  2029   struct sfnt_glyph *glyph;
  2030   struct sfntfont_get_glyph_outline_dcontext dcontext;
  2031   struct sfnt_instructed_outline *value;
  2032   const char *error;
  2033   struct sfnt_glyph_metrics temp;
  2034   struct sfnt_metrics_distortion distortion;
  2035 
  2036   start = cache->next;
  2037   distortion.advance = 0;
  2038 
  2039   /* See if the outline is already cached.  */
  2040   for (; start != cache; start = start->next)
  2041     {
  2042       if (start->glyph == glyph_code)
  2043         {
  2044           /* Move start to the start of the ring.  Then increase
  2045              start->outline->refcount and return it.  */
  2046 
  2047           start->last->next = start->next;
  2048           start->next->last = start->last;
  2049 
  2050           start->next = cache->next;
  2051           start->last = cache;
  2052           start->next->last = start;
  2053           start->last->next = start;
  2054           start->outline->refcount++;
  2055 
  2056           if (metrics)
  2057             *metrics = start->metrics;
  2058 
  2059           return start->outline;
  2060         }
  2061     }
  2062 
  2063   /* Not already cached.  Get the glyph.  */
  2064   glyph = sfnt_read_glyph (glyph_code, glyf,
  2065                            loca_short, loca_long);
  2066 
  2067   if (!glyph)
  2068     return NULL;
  2069 
  2070   /* Distort the glyph if necessary.  */
  2071 
  2072   if (index != -1)
  2073     {
  2074       if (glyph->simple)
  2075         {
  2076           if (sfnt_vary_simple_glyph (blend, glyph_code,
  2077                                       glyph, &distortion))
  2078             {
  2079               sfnt_free_glyph (glyph);
  2080               return NULL;
  2081             }
  2082         }
  2083       else if (sfnt_vary_compound_glyph (blend, glyph_code,
  2084                                          glyph, &distortion))
  2085         {
  2086           sfnt_free_glyph (glyph);
  2087           return NULL;
  2088         }
  2089     }
  2090 
  2091   /* Try to instruct the glyph if INTERPRETER is specified.  */
  2092 
  2093   outline = NULL;
  2094 
  2095   dcontext.loca_long = loca_long;
  2096   dcontext.loca_short = loca_short;
  2097   dcontext.glyf = glyf;
  2098   dcontext.blend = (index != -1 ? blend : NULL);
  2099 
  2100   /* Now load the glyph's unscaled metrics into TEMP.  */
  2101 
  2102   if (sfnt_lookup_glyph_metrics (glyph_code, -1, &temp, hmtx, hhea,
  2103                                  head, maxp))
  2104     goto fail;
  2105 
  2106   /* Add the advance width distortion.  */
  2107   temp.advance += distortion.advance;
  2108 
  2109   if (interpreter)
  2110     {
  2111       if (glyph->simple)
  2112         {
  2113           /* Restore the interpreter state from the snapshot taken
  2114              after loading the preprogram.  */
  2115           interpreter->state = *state;
  2116 
  2117           error = sfnt_interpret_simple_glyph (glyph, interpreter,
  2118                                                &temp, &value);
  2119         }
  2120       else
  2121         /* Restoring the interpreter state is done by
  2122            sfnt_interpret_compound_glyph; all that must be done here
  2123            is to give the graphics state to that function.  */
  2124         error = sfnt_interpret_compound_glyph (glyph, interpreter,
  2125                                                state,
  2126                                                sfntfont_get_glyph,
  2127                                                sfntfont_free_glyph,
  2128                                                hmtx, hhea, maxp,
  2129                                                &temp, &dcontext,
  2130                                                &value);
  2131 
  2132       if (!error)
  2133         {
  2134           outline = sfnt_build_instructed_outline (value);
  2135           xfree (value);
  2136         }
  2137     }
  2138 
  2139   if (!outline)
  2140     {
  2141       if (!interpreter)
  2142         outline = sfnt_build_glyph_outline (glyph, scale,
  2143                                             &temp,
  2144                                             sfntfont_get_glyph,
  2145                                             sfntfont_free_glyph,
  2146                                             &dcontext);
  2147       else
  2148         outline = sfnt_build_glyph_outline (glyph, scale,
  2149                                             &temp,
  2150                                             sfntfont_get_glyph,
  2151                                             sfntfont_free_glyph,
  2152                                             &dcontext);
  2153     }
  2154 
  2155   /* At this point, the glyph metrics are unscaled.  Scale them up.
  2156      If INTERPRETER is set, use the scale placed within.  */
  2157 
  2158   sfnt_scale_metrics (&temp, scale);
  2159 
  2160  fail:
  2161 
  2162   xfree (glyph);
  2163 
  2164   if (!outline)
  2165     return NULL;
  2166 
  2167   if (index != -1)
  2168     /* Finally, adjust the left side bearing of the glyph metrics by
  2169        the origin point of the outline, should a distortion have been
  2170        applied.  The left side bearing is the distance from the origin
  2171        point to the left most point on the X axis.  */
  2172     temp.lbearing = outline->xmin - outline->origin;
  2173 
  2174   start = xmalloc (sizeof *start);
  2175   start->glyph = glyph_code;
  2176   start->outline = outline;
  2177   start->metrics = temp;
  2178 
  2179   /* One reference goes to the cache.  The second reference goes to
  2180      the caller.  */
  2181   outline->refcount = 2;
  2182 
  2183   /* Link start onto the cache.  */
  2184   start->next = cache->next;
  2185   start->last = cache;
  2186   start->next->last = start;
  2187   start->last->next = start;
  2188 
  2189   /* Update the cache size.  */
  2190   (*cache_size)++;
  2191 
  2192   /* Figure out if the least recently used element has to be
  2193      evicted.  */
  2194   if (*cache_size > SFNT_OUTLINE_CACHE_SIZE)
  2195     {
  2196       start = cache->last;
  2197       eassert (start != cache);
  2198 
  2199       /* Free the least recently used entry in the cache.  */
  2200       start->last->next = start->next;
  2201       start->next->last = start->last;
  2202       sfntfont_dereference_outline (start->outline);
  2203       xfree (start);
  2204 
  2205       (*cache_size)--;
  2206     }
  2207 
  2208   /* Return the cached outline and metrics.  */
  2209 
  2210   if (metrics)
  2211     *metrics = temp;
  2212 
  2213   return outline;
  2214 }
  2215 
  2216 /* Free the outline cache referred to by CACHE.  Dereference each
  2217    outline contained therein.  */
  2218 
  2219 static void
  2220 sfntfont_free_outline_cache (struct sfnt_outline_cache *cache)
  2221 {
  2222   struct sfnt_outline_cache *next, *last;
  2223 
  2224   /* Handle partly initialized fonts.  */
  2225   if (!cache->next)
  2226     return;
  2227 
  2228   for (next = cache->next; next != cache;)
  2229     {
  2230       last = next;
  2231       next = next->next;
  2232 
  2233       sfntfont_dereference_outline (last->outline);
  2234       xfree (last);
  2235     }
  2236 
  2237   cache->next = cache;
  2238   cache->last = cache;
  2239 }
  2240 
  2241 /* Dereference the raster RASTER.  Free it once refcount reaches
  2242    0.  */
  2243 
  2244 static void
  2245 sfntfont_dereference_raster (struct sfnt_raster *raster)
  2246 {
  2247   eassert (raster->refcount > 0);
  2248 
  2249   if (--raster->refcount)
  2250     return;
  2251 
  2252   xfree (raster);
  2253 }
  2254 
  2255 /* Get the raster corresponding to the specified GLYPH_CODE in CACHE.
  2256    Use the outline named OUTLINE.  Keep *CACHE_SIZE updated with the
  2257    number of elements in the cache.  */
  2258 
  2259 static struct sfnt_raster *
  2260 sfntfont_get_glyph_raster (sfnt_glyph glyph_code,
  2261                            struct sfnt_raster_cache *cache,
  2262                            struct sfnt_glyph_outline *outline,
  2263                            int *cache_size)
  2264 {
  2265   struct sfnt_raster_cache *start;
  2266   struct sfnt_raster *raster;
  2267 
  2268   /* See if the raster is already cached.  */
  2269   start = cache->next;
  2270 
  2271   for (; start != cache; start = start->next)
  2272     {
  2273       if (start->glyph == glyph_code)
  2274         {
  2275           /* Move start to the start of the ring.  Them, increase
  2276              start->raster->refcount and return it.  */
  2277 
  2278           start->last->next = start->next;
  2279           start->next->last = start->last;
  2280 
  2281           start->next = cache->next;
  2282           start->last = cache;
  2283           start->next->last = start;
  2284           start->last->next = start;
  2285           start->raster->refcount++;
  2286 
  2287           return start->raster;
  2288         }
  2289     }
  2290 
  2291   /* Not already cached.  Raster the outline.  */
  2292   raster = sfnt_raster_glyph_outline (outline);
  2293 
  2294   if (!raster)
  2295     return NULL;
  2296 
  2297   start = xmalloc (sizeof *start);
  2298   start->glyph = glyph_code;
  2299   start->raster = raster;
  2300 
  2301   /* One reference goes to the cache.  The second reference goes to
  2302      the caller.  */
  2303   raster->refcount = 2;
  2304 
  2305   /* Link start onto the cache.  */
  2306   start->next = cache->next;
  2307   start->last = cache;
  2308   start->next->last = start;
  2309   start->last->next = start;
  2310 
  2311   /* Update the cache size.  */
  2312   (*cache_size)++;
  2313 
  2314   /* Figure out if the least recently used element has to be
  2315      evicted.  */
  2316   if (*cache_size > SFNT_OUTLINE_CACHE_SIZE)
  2317     {
  2318       start = cache->last;
  2319       eassert (start != cache);
  2320 
  2321       /* Free the least recently used entry in the cache.  */
  2322       start->last->next = start->next;
  2323       start->next->last = start->last;
  2324       sfntfont_dereference_raster (start->raster);
  2325       xfree (start);
  2326 
  2327       (*cache_size)--;
  2328     }
  2329 
  2330   /* Return the cached raster.  */
  2331   return raster;
  2332 }
  2333 
  2334 /* Free the raster cache referred to by CACHE.  Dereference each
  2335    raster contained therein.  */
  2336 
  2337 static void
  2338 sfntfont_free_raster_cache (struct sfnt_raster_cache *cache)
  2339 {
  2340   struct sfnt_raster_cache *next, *last;
  2341 
  2342   /* Handle partly initialized fonts.  */
  2343   if (!cache->next)
  2344     return;
  2345 
  2346   for (next = cache->next; next != cache;)
  2347     {
  2348       last = next;
  2349       next = next->next;
  2350 
  2351       sfntfont_dereference_raster (last->raster);
  2352       xfree (last);
  2353     }
  2354 
  2355   cache->next = cache;
  2356   cache->last = cache;
  2357 }
  2358 
  2359 
  2360 
  2361 /* Opening fonts.  */
  2362 
  2363 struct sfnt_font_info
  2364 {
  2365   /* Parent font structure.  */
  2366   struct font font;
  2367 
  2368 #ifdef HAVE_MMAP
  2369   /* The next font in this chain.  */
  2370   struct sfnt_font_info *next;
  2371 #endif /* HAVE_MMAP */
  2372 
  2373   /* The font description used to create this font.  Used to
  2374      dereference tables associated with this font.  */
  2375   struct sfnt_font_desc *desc;
  2376 
  2377   /* Various tables required to use the font.  */
  2378   struct sfnt_cmap_table *cmap;
  2379   struct sfnt_hhea_table *hhea;
  2380   struct sfnt_maxp_table *maxp;
  2381   struct sfnt_head_table *head;
  2382   struct sfnt_hmtx_table *hmtx;
  2383   struct sfnt_glyf_table *glyf;
  2384   struct sfnt_loca_table_short *loca_short;
  2385   struct sfnt_loca_table_long *loca_long;
  2386   struct sfnt_prep_table *prep;
  2387   struct sfnt_fpgm_table *fpgm;
  2388   struct sfnt_cvt_table *cvt;
  2389 
  2390   /* The selected character map.  */
  2391   struct sfnt_cmap_encoding_subtable_data *cmap_data;
  2392 
  2393   /* Data identifying that character map.  */
  2394   struct sfnt_cmap_encoding_subtable cmap_subtable;
  2395 
  2396   /* The UVS context.  */
  2397   struct sfnt_uvs_context *uvs;
  2398 
  2399   /* Outline cache.  */
  2400   struct sfnt_outline_cache outline_cache;
  2401 
  2402   /* Number of elements in the outline cache.  */
  2403   int outline_cache_size;
  2404 
  2405   /* Raster cache.  */
  2406   struct sfnt_raster_cache raster_cache;
  2407 
  2408   /* Number of elements in the raster cache.  */
  2409   int raster_cache_size;
  2410 
  2411   /* Interpreter for grid fitting (if enabled).  */
  2412   struct sfnt_interpreter *interpreter;
  2413 
  2414   /* Graphics state after the execution of the font and control value
  2415      programs.  */
  2416   struct sfnt_graphics_state state;
  2417 
  2418   /* Factor used to convert from em space to pixel space.  */
  2419   sfnt_fixed scale;
  2420 
  2421   /* The blend (configuration of this multiple master font).  */
  2422   struct sfnt_blend blend;
  2423 
  2424   /* The index of the named instance used to initialize BLEND.
  2425      -1 if BLEND is not initialized.  */
  2426   int instance;
  2427 
  2428 #ifdef HAVE_MMAP
  2429   /* Whether or not the glyph table has been mmapped.  */
  2430   bool glyf_table_mapped;
  2431 #endif /* HAVE_MMAP */
  2432 
  2433 #ifdef HAVE_HARFBUZZ
  2434   /* HarfBuzz font object.  */
  2435   hb_font_t *hb_font;
  2436 
  2437   /* File descriptor associated with this font.  */
  2438   int fd;
  2439 
  2440   /* The table directory of the font file.  */
  2441   struct sfnt_offset_subtable *directory;
  2442 #endif /* HAVE_HARFBUZZ */
  2443 };
  2444 
  2445 #ifdef HAVE_MMAP
  2446 
  2447 /* List of all open fonts.  */
  2448 
  2449 static struct sfnt_font_info *open_fonts;
  2450 
  2451 #endif /* HAVE_MMAP */
  2452 
  2453 /* Look up the glyph corresponding to the character C in FONT.  Return
  2454    0 upon failure, and the glyph otherwise.  */
  2455 
  2456 static sfnt_glyph
  2457 sfntfont_lookup_glyph (struct sfnt_font_info *font_info, int c)
  2458 {
  2459   struct charset *charset;
  2460   sfnt_char character;
  2461   sfnt_glyph glyph;
  2462 
  2463   charset = CHARSET_FROM_ID (font_info->font.encoding_charset);
  2464 
  2465   if (!charset)
  2466     return 0;
  2467 
  2468   character = ENCODE_CHAR (charset, c);
  2469 
  2470   if (character == CHARSET_INVALID_CODE (charset))
  2471     return 0;
  2472 
  2473   /* Do the actual lookup with the encoded character.  */
  2474   glyph = sfnt_lookup_glyph (character, font_info->cmap_data);
  2475 
  2476   return glyph;
  2477 }
  2478 
  2479 /* Probe and set FONT_INFO->font.average_width,
  2480    FONT_INFO->font.space_width, and FONT_INFO->font.min_width
  2481    according to the tables contained therein.  */
  2482 
  2483 static void
  2484 sfntfont_probe_widths (struct sfnt_font_info *font_info)
  2485 {
  2486   int i, num_characters, total_width;
  2487   sfnt_glyph glyph;
  2488   struct sfnt_glyph_metrics metrics;
  2489 
  2490   num_characters = 0;
  2491   total_width = 0;
  2492 
  2493   /* First set some reasonable default values.  */
  2494   font_info->font.average_width = font_info->font.pixel_size;
  2495   font_info->font.space_width = font_info->font.pixel_size;
  2496   font_info->font.min_width = 1;
  2497 
  2498   /* Next, loop through the common ASCII characters.  Tally up their
  2499      advance widths and set space_width if necessary.  */
  2500   for (i = 0; i < 127; ++i)
  2501     {
  2502       glyph = sfntfont_lookup_glyph (font_info, i);
  2503 
  2504       if (!glyph)
  2505         continue;
  2506 
  2507       /* Now look up the metrics of this glyph.  */
  2508       if (sfnt_lookup_glyph_metrics (glyph, font_info->font.pixel_size,
  2509                                      &metrics, font_info->hmtx,
  2510                                      font_info->hhea, font_info->head,
  2511                                      font_info->maxp))
  2512         continue;
  2513 
  2514       /* Increase the number of characters.  */
  2515       num_characters++;
  2516 
  2517       /* Add the advance to total_width.  */
  2518       total_width += SFNT_CEIL_FIXED (metrics.advance) / 65536;
  2519 
  2520       /* Update min_width if it hasn't been set yet or is wider.  */
  2521       if (font_info->font.min_width == 1
  2522           || font_info->font.min_width > metrics.advance / 65536)
  2523         font_info->font.min_width = metrics.advance / 65536;
  2524 
  2525       /* If i is the space character, set the space width.  Make sure
  2526          to round this up.  */
  2527       if (i == 32)
  2528         font_info->font.space_width
  2529           = SFNT_CEIL_FIXED (metrics.advance) / 65536;
  2530     }
  2531 
  2532   /* Now, if characters were found, set average_width.  */
  2533   if (num_characters)
  2534     font_info->font.average_width = total_width / num_characters;
  2535 }
  2536 
  2537 /* Initialize the instruction interpreter for INFO.  Load the font and
  2538    preprogram for the pixel size in INFO and its corresponding point
  2539    size POINT_SIZE.  Use the FVAR table in DESC.
  2540 
  2541    The font tables in INFO must already have been initialized.
  2542 
  2543    Set INFO->interpreter upon success, and leave that field intact
  2544    otherwise.  */
  2545 
  2546 static void
  2547 sfntfont_setup_interpreter (struct sfnt_font_info *info,
  2548                             struct sfnt_font_desc *desc,
  2549                             int point_size)
  2550 {
  2551   struct sfnt_cvt_table *cvt;
  2552   struct sfnt_fpgm_table *fpgm;
  2553   struct sfnt_prep_table *prep;
  2554   struct sfnt_interpreter *interpreter;
  2555   const char *error;
  2556   struct sfnt_graphics_state state;
  2557 
  2558   /* Load the cvt, fpgm and prep already read.  */
  2559 
  2560   cvt  = info->cvt ;
  2561   fpgm = info->fpgm;
  2562   prep = info->prep;
  2563 
  2564   /* If both fpgm and prep are NULL, this font likely has no
  2565      instructions, so don't bother setting up the interpreter.  */
  2566 
  2567   if (!fpgm && !prep)
  2568     goto bail;
  2569 
  2570   /* If the interpreter does not use the operand stack at all, it is
  2571      useless.  In addition, some broken fonts specify some unnecessary
  2572      instructions in prep and set head->max_stack_elements to 0.
  2573 
  2574      Don't create the interpreter in that case.  */
  2575 
  2576   if (!info->maxp->max_stack_elements)
  2577     goto bail;
  2578 
  2579   /* Now, create the interpreter using the limits in info->maxp and
  2580      info->head.  CVT can be NULL.  */
  2581 
  2582   interpreter = sfnt_make_interpreter (info->maxp, cvt, info->head,
  2583                                        desc->tables->fvar,
  2584                                        info->font.pixel_size,
  2585                                        point_size);
  2586 
  2587   /* Bail if the interpreter couldn't be created.  */
  2588   if (!interpreter)
  2589     goto bail;
  2590 
  2591   if (fpgm)
  2592     {
  2593       /* Otherwise, evaluate the font and cvt programs.
  2594 
  2595          FIXME: make sure infinite loops inside these programs
  2596          cannot lock up Emacs.  */
  2597 
  2598       error = sfnt_interpret_font_program (interpreter, fpgm);
  2599 
  2600       if (error)
  2601         {
  2602           /* If an error occurs, log it to the *Messages* buffer.  */
  2603           message_with_string ("While interpreting font program: %s",
  2604                                build_string (error), true);
  2605           goto bail1;
  2606         }
  2607 
  2608       /* Save the graphics state.  */
  2609       state = interpreter->state;
  2610     }
  2611 
  2612   if (prep)
  2613     {
  2614       /* This will overwrite state if the instruction control is set
  2615          appropriately.  */
  2616       error = sfnt_interpret_control_value_program (interpreter, prep,
  2617                                                     &state);
  2618 
  2619       if (error)
  2620         {
  2621           /* If an error occurs, log it to the *Messages* buffer.  */
  2622           message_with_string ("While interpreting preprogram: %s",
  2623                                build_string (error), true);
  2624           goto bail1;
  2625         }
  2626     }
  2627 
  2628   /* The interpreter has been properly set up.  */
  2629   info->fpgm = fpgm;
  2630   info->prep = prep;
  2631   info->cvt = cvt;
  2632   info->state = state;
  2633   info->interpreter = interpreter;
  2634 
  2635   return;
  2636 
  2637  bail1:
  2638   xfree (interpreter);
  2639  bail:
  2640   return;
  2641 }
  2642 
  2643 /* Free each of the tables opened by `sfnt_open_tables', and possibly
  2644    file descriptors as well.  Then, free TABLES itself.  */
  2645 
  2646 static void
  2647 sfnt_close_tables (struct sfnt_font_tables *tables)
  2648 {
  2649   int rc;
  2650 
  2651   xfree (tables->cmap);
  2652   xfree (tables->hhea);
  2653   xfree (tables->maxp);
  2654   xfree (tables->head);
  2655   xfree (tables->hmtx);
  2656 #ifdef HAVE_MMAP
  2657   if (tables->glyf_table_mapped)
  2658     {
  2659       rc = sfnt_unmap_glyf_table (tables->glyf);
  2660 
  2661       if (rc)
  2662         emacs_abort ();
  2663     }
  2664   else
  2665 #endif /* HAVE_MMAP */
  2666     xfree (tables->glyf);
  2667   xfree (tables->loca_short);
  2668   xfree (tables->loca_long);
  2669   xfree (tables->prep);
  2670   xfree (tables->fpgm);
  2671   xfree (tables->cvt);
  2672   xfree (tables->fvar);
  2673   xfree (tables->avar);
  2674   xfree (tables->gvar);
  2675   xfree (tables->cvar);
  2676   xfree (tables->cmap_data);
  2677 
  2678   if (tables->uvs)
  2679     sfnt_free_uvs_context (tables->uvs);
  2680 
  2681 #ifdef HAVE_HARFBUZZ
  2682   /* Close the font file.  */
  2683 
  2684   if (tables->fd != -1)
  2685     {
  2686       emacs_close (tables->fd);
  2687       tables->fd = -1;
  2688     }
  2689 
  2690   /* Free its table directory.  */
  2691   xfree (tables->directory);
  2692   tables->directory = NULL;
  2693 #endif
  2694 }
  2695 
  2696 /* Open font tables associated with the specified font description
  2697    DESC.  Return the font tables, or NULL upon failure.  */
  2698 
  2699 static struct sfnt_font_tables *
  2700 sfnt_open_tables (struct sfnt_font_desc *desc)
  2701 {
  2702   struct sfnt_font_tables *tables;
  2703   struct sfnt_offset_subtable *subtable;
  2704   int fd, i, rc;
  2705   struct sfnt_cmap_encoding_subtable *subtables;
  2706   struct sfnt_cmap_encoding_subtable_data **data;
  2707   struct sfnt_cmap_format_14 *format14;
  2708 
  2709   tables = xzalloc (sizeof *tables);
  2710 
  2711   /* Open the font.  */
  2712   fd = emacs_open (desc->path, O_RDONLY, 0);
  2713 
  2714   if (fd == -1)
  2715     goto bail;
  2716 
  2717   /* Seek to the offset specified to the table directory.  */
  2718 
  2719   if (desc->offset
  2720       && lseek (fd, desc->offset, SEEK_SET) != desc->offset)
  2721     goto bail;
  2722 
  2723   /* Read the offset subtable.  */
  2724   subtable = sfnt_read_table_directory (fd);
  2725 
  2726   if (!subtable)
  2727     goto bail1;
  2728 
  2729   /* Read required tables.  This font backend is supposed to be used
  2730      mostly on devices with flash memory, so the order in which they
  2731      are read is insignificant.  */
  2732 
  2733   tables->cmap = sfnt_read_cmap_table (fd, subtable, &subtables,
  2734                                        &data);
  2735   if (!tables->cmap)
  2736     goto bail2;
  2737 
  2738   format14 = NULL;
  2739   tables->cmap_data
  2740     = sfntfont_select_cmap (tables->cmap,
  2741                             subtables, data,
  2742                             &tables->cmap_subtable,
  2743                             &format14);
  2744 
  2745   if (format14)
  2746     {
  2747       /* Build a UVS context from this format 14 mapping table.  A UVS
  2748          context contains each variation selector supported by the
  2749          font, and a list of ``non-default'' mappings between base
  2750          characters and variation glyph IDs.  */
  2751 
  2752       tables->uvs = sfnt_create_uvs_context (format14, fd);
  2753       xfree (format14);
  2754     }
  2755 
  2756   for (i = 0; i < tables->cmap->num_subtables; ++i)
  2757     {
  2758       if (data[i] != tables->cmap_data
  2759           /* format14 has already been freed.  */
  2760           && data[i] != (struct sfnt_cmap_encoding_subtable_data *) format14)
  2761         xfree (data[i]);
  2762     }
  2763 
  2764   xfree (subtables);
  2765   xfree (data);
  2766 
  2767   if (!tables->cmap_data)
  2768     goto bail3;
  2769 
  2770   /* Read the hhea, maxp, glyf, and head tables.  */
  2771   tables->hhea = sfnt_read_hhea_table (fd, subtable);
  2772   tables->maxp = sfnt_read_maxp_table (fd, subtable);
  2773 
  2774 #ifdef HAVE_MMAP
  2775 
  2776   /* First try to map the glyf table.  If that fails, then read the
  2777      glyf table.  */
  2778 
  2779   tables->glyf = sfnt_map_glyf_table (fd, subtable);
  2780 
  2781   /* Next, if this fails, read the glyf table.  */
  2782 
  2783   if (!tables->glyf)
  2784 #endif /* HAVE_MMAP */
  2785     tables->glyf = sfnt_read_glyf_table (fd, subtable);
  2786 #ifdef HAVE_MMAP
  2787   else
  2788     tables->glyf_table_mapped = true;
  2789 #endif /* HAVE_MMAP */
  2790 
  2791   tables->head = sfnt_read_head_table (fd, subtable);
  2792 
  2793   /* If any of those tables couldn't be read, bail.  */
  2794   if (!tables->hhea || !tables->maxp || !tables->glyf
  2795       || !tables->head)
  2796     goto bail4;
  2797 
  2798   /* Now figure out which kind of loca table must be read based on
  2799      head->index_to_loc_format.  */
  2800 
  2801   if (tables->head->index_to_loc_format)
  2802     {
  2803       tables->loca_long
  2804         = sfnt_read_loca_table_long (fd, subtable);
  2805 
  2806       if (!tables->loca_long)
  2807         goto bail4;
  2808     }
  2809   else
  2810     {
  2811       tables->loca_short
  2812         = sfnt_read_loca_table_short (fd, subtable);
  2813 
  2814       if (!tables->loca_short)
  2815         goto bail4;
  2816     }
  2817 
  2818   /* Read the horizontal metrics table.  */
  2819   tables->hmtx = sfnt_read_hmtx_table (fd, subtable,
  2820                                        tables->hhea,
  2821                                        tables->maxp);
  2822   if (!tables->hmtx)
  2823     goto bail5;
  2824 
  2825   /* Read instruction related font tables.  These might not be
  2826      present, which is OK, since instructing fonts is optional.  */
  2827   tables->prep = sfnt_read_prep_table (fd, subtable);
  2828   tables->fpgm = sfnt_read_fpgm_table (fd, subtable);
  2829   tables->cvt  = sfnt_read_cvt_table (fd, subtable);
  2830 
  2831   /* Read distortion related tables.  These might not be present.  */
  2832   tables->fvar = sfnt_read_fvar_table (fd, subtable);
  2833   tables->avar = sfnt_read_avar_table (fd, subtable);
  2834   tables->gvar = sfnt_read_gvar_table (fd, subtable);
  2835 
  2836   if (tables->cvt && tables->fvar)
  2837     tables->cvar = sfnt_read_cvar_table (fd, subtable, tables->fvar,
  2838                                          tables->cvt);
  2839 
  2840 #ifdef HAVE_HARFBUZZ
  2841   /* Now copy over the subtable if necessary, as it is needed to read
  2842      extra font tables required by HarfBuzz.  */
  2843   tables->directory = subtable;
  2844   tables->fd = fd;
  2845 #else /* !HAVE_HARFBUZZ */
  2846   /* Otherwise, close the fd and free the table directory.  */
  2847   xfree (subtable);
  2848   emacs_close (fd);
  2849 #endif /* HAVE_HARFBUZZ */
  2850 
  2851   return tables;
  2852 
  2853  bail5:
  2854   xfree (tables->loca_long);
  2855   xfree (tables->loca_short);
  2856  bail4:
  2857   xfree (tables->hhea);
  2858   xfree (tables->maxp);
  2859 
  2860 #ifdef HAVE_MMAP
  2861   if (tables->glyf_table_mapped)
  2862     {
  2863       rc = sfnt_unmap_glyf_table (tables->glyf);
  2864 
  2865       if (rc)
  2866         emacs_abort ();
  2867     }
  2868   else
  2869 #endif /* HAVE_MMAP */
  2870     xfree (tables->glyf);
  2871 
  2872   xfree (tables->head);
  2873 
  2874   /* This comes under bail4 due to a peculiarity of how the four
  2875      tables above are validated.  */
  2876   xfree (tables->cmap_data);
  2877  bail3:
  2878   if (tables->uvs)
  2879     sfnt_free_uvs_context (tables->uvs);
  2880 
  2881   xfree (tables->cmap);
  2882  bail2:
  2883   xfree (subtable);
  2884  bail1:
  2885   emacs_close (fd);
  2886  bail:
  2887   xfree (tables);
  2888   return NULL;
  2889 }
  2890 
  2891 /* Open or reference font tables corresponding to the specified font
  2892    DESC.  Return NULL upon failure.  */
  2893 
  2894 static struct sfnt_font_tables *
  2895 sfnt_reference_font_tables (struct sfnt_font_desc *desc)
  2896 {
  2897   if (desc->refcount)
  2898     {
  2899       desc->refcount++;
  2900       return desc->tables;
  2901     }
  2902 
  2903   desc->tables = sfnt_open_tables (desc);
  2904 
  2905   if (!desc->tables)
  2906     return NULL;
  2907 
  2908   desc->refcount++;
  2909   return desc->tables;
  2910 }
  2911 
  2912 /* Dereference font tables corresponding to the specified font
  2913    DESC.  */
  2914 
  2915 static void
  2916 sfnt_dereference_font_tables (struct sfnt_font_desc *desc)
  2917 {
  2918   if (!desc->refcount)
  2919     emacs_abort ();
  2920 
  2921   if (--desc->refcount)
  2922     return;
  2923 
  2924   sfnt_close_tables (desc->tables);
  2925   desc->tables = NULL;
  2926   return;
  2927 }
  2928 
  2929 /* Open the font corresponding to the font-entity FONT_ENTITY.  Return
  2930    nil upon failure, else the opened font-object.  */
  2931 
  2932 Lisp_Object
  2933 sfntfont_open (struct frame *f, Lisp_Object font_entity,
  2934                int pixel_size)
  2935 {
  2936   struct sfnt_font_info *font_info;
  2937   struct font *font;
  2938   struct sfnt_font_desc *desc;
  2939   Lisp_Object font_object;
  2940   struct charset *charset;
  2941   int point_size, instance, i;
  2942   Display_Info *dpyinfo;
  2943   struct sfnt_font_tables *tables;
  2944   Lisp_Object tem;
  2945 
  2946   if (XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX)) != 0)
  2947     pixel_size = XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX));
  2948   else if (pixel_size == 0)
  2949     {
  2950       /* This bit was copied from xfont.c.  The values might need
  2951          adjustment.  */
  2952 
  2953       if (FRAME_FONT (f))
  2954         pixel_size = FRAME_FONT (f)->pixel_size;
  2955       else
  2956         pixel_size = 12;
  2957     }
  2958 
  2959   /* Now find the font description corresponding to FONT_ENTITY.  */
  2960 
  2961   tem = AREF (font_entity, FONT_EXTRA_INDEX);
  2962   if (NILP (tem))
  2963     return Qnil;
  2964 
  2965   desc = xmint_pointer (XCDR (XCAR (tem)));
  2966 
  2967   /* Finally, see if a specific instance is associated with
  2968      FONT_ENTITY.  */
  2969 
  2970   instance = -1;
  2971   if (!NILP (XCDR (tem)))
  2972     instance = XFIXNUM (XCDR (XCAR (XCDR (tem))));
  2973 
  2974   /* Build the font object.  */
  2975   font_object = font_make_object (VECSIZE (struct sfnt_font_info),
  2976                                   font_entity, pixel_size);
  2977   font_info = (struct sfnt_font_info *) XFONT_OBJECT (font_object);
  2978 
  2979   block_input ();
  2980 
  2981   /* Initialize all the font driver specific data.  */
  2982 
  2983   font_info->cmap = NULL;
  2984   font_info->hhea = NULL;
  2985   font_info->maxp = NULL;
  2986   font_info->head = NULL;
  2987   font_info->glyf = NULL;
  2988   font_info->hmtx = NULL;
  2989   font_info->loca_short = NULL;
  2990   font_info->loca_long = NULL;
  2991   font_info->cmap_data = NULL;
  2992   font_info->prep = NULL;
  2993   font_info->fpgm = NULL;
  2994   font_info->cvt = NULL;
  2995   font_info->uvs = NULL;
  2996 
  2997   font_info->outline_cache.next = &font_info->outline_cache;
  2998   font_info->outline_cache.last = &font_info->outline_cache;
  2999   font_info->outline_cache_size = 0;
  3000   font_info->raster_cache.next = &font_info->raster_cache;
  3001   font_info->raster_cache.last = &font_info->raster_cache;
  3002   font_info->raster_cache_size = 0;
  3003   font_info->interpreter = NULL;
  3004   font_info->scale = 0;
  3005   font_info->instance = -1;
  3006   font_info->blend.coords = NULL;
  3007 #ifdef HAVE_MMAP
  3008   font_info->glyf_table_mapped = false;
  3009 #endif /* HAVE_MMAP */
  3010 #ifdef HAVE_HARFBUZZ
  3011   font_info->hb_font = NULL;
  3012   font_info->fd = -1;
  3013   font_info->directory = NULL;
  3014 #endif /* HAVE_HARFBUZZ */
  3015 
  3016   /* Read required tables.  This font backend is supposed to be used
  3017      mostly on devices with flash memory, so the order in which they
  3018      are read is insignificant.  */
  3019 
  3020   tables = sfnt_reference_font_tables (desc);
  3021 
  3022   if (!tables)
  3023     goto bail;
  3024 
  3025   /* Copy fields from the table structure to the font for fast
  3026      access.  */
  3027   font_info->cmap = tables->cmap;
  3028   font_info->hhea = tables->hhea;
  3029   font_info->maxp = tables->maxp;
  3030   font_info->head = tables->head;
  3031   font_info->hmtx = tables->hmtx;
  3032   font_info->glyf = tables->glyf;
  3033   font_info->loca_short = tables->loca_short;
  3034   font_info->loca_long = tables->loca_long;
  3035   font_info->prep = tables->prep;
  3036   font_info->fpgm = tables->fpgm;
  3037   font_info->cvt  = tables->cvt ;
  3038   font_info->cmap_data = tables->cmap_data;
  3039   font_info->cmap_subtable = tables->cmap_subtable;
  3040   font_info->uvs = tables->uvs;
  3041 
  3042   /* Calculate the font's scaling factor.  */
  3043   font_info->scale = sfnt_get_scale (font_info->head, pixel_size);
  3044 
  3045   /* Fill in font data.  */
  3046   font = &font_info->font;
  3047   font->pixel_size = pixel_size;
  3048   font->driver = sfnt_font_driver;
  3049   font->encoding_charset = font->repertory_charset = -1;
  3050 
  3051   /* Figure out which character set to use.  */
  3052   charset = sfntfont_charset_for_cmap (font_info->cmap_subtable);
  3053 
  3054   if (!charset)
  3055     goto bail6;
  3056 
  3057   /* Set the character set IDs.  */
  3058   font->encoding_charset = charset->id;
  3059   font->repertory_charset = charset->id;
  3060 
  3061   /* Figure out the font ascent and descent.  */
  3062   font->ascent
  3063     = ceil (font_info->hhea->ascent
  3064             * pixel_size * 1.0 / font_info->head->units_per_em);
  3065   font->descent
  3066     = -floor (font_info->hhea->descent
  3067               * pixel_size * 1.0 / font_info->head->units_per_em);
  3068   font->height = font->ascent + font->descent;
  3069 
  3070   /* Set font->max_width to the maximum advance width.  */
  3071   font->max_width = (font_info->hhea->advance_width_max
  3072                      * pixel_size * 1.0 / font_info->head->units_per_em);
  3073 
  3074   /* Set generic attributes such as type and style.  */
  3075   ASET (font_object, FONT_TYPE_INDEX, sfnt_vendor_name);
  3076 
  3077   if (!NILP (desc->designer))
  3078     ASET (font_object, FONT_FOUNDRY_INDEX,
  3079           Fintern (desc->designer, Qnil));
  3080 
  3081   ASET (font_object, FONT_FAMILY_INDEX, Fintern (desc->family, Qnil));
  3082   ASET (font_object, FONT_ADSTYLE_INDEX, Qnil);
  3083   ASET (font_object, FONT_REGISTRY_INDEX,
  3084         sfntfont_registry_for_desc (desc));
  3085 
  3086   /* Size of 0 means the font is scalable.  */
  3087   ASET (font_object, FONT_SIZE_INDEX, make_fixnum (0));
  3088   ASET (font_object, FONT_AVGWIDTH_INDEX, make_fixnum (0));
  3089   ASET (font_object, FONT_SPACING_INDEX,
  3090         make_fixnum (desc->spacing));
  3091 
  3092   /* Set the font style.  */
  3093 
  3094   FONT_SET_STYLE (font_object, FONT_WIDTH_INDEX,
  3095                   make_fixnum (desc->width));
  3096   FONT_SET_STYLE (font_object, FONT_WEIGHT_INDEX,
  3097                   make_fixnum (desc->weight));
  3098   FONT_SET_STYLE (font_object, FONT_SLANT_INDEX,
  3099                   make_fixnum (desc->slant));
  3100 
  3101   ASET (font_object, FONT_ADSTYLE_INDEX, Qnil);
  3102 
  3103   /* Find out the minimum, maximum and average widths.  */
  3104   sfntfont_probe_widths (font_info);
  3105 
  3106   /* Clear various offsets.  */
  3107   font_info->font.baseline_offset = 0;
  3108   font_info->font.relative_compose = 0;
  3109   font_info->font.default_ascent = 0;
  3110   font_info->font.vertical_centering = 0;
  3111   font_info->font.underline_position = -1;
  3112   font_info->font.underline_thickness = 0;
  3113 
  3114   /* Now try to set up grid fitting for this font.  */
  3115   dpyinfo = FRAME_DISPLAY_INFO (f);
  3116   point_size = PIXEL_TO_POINT (pixel_size, (dpyinfo->resx
  3117                                             * dpyinfo->resy
  3118                                             / 2));
  3119   sfntfont_setup_interpreter (font_info, desc, point_size);
  3120 
  3121   /* If an instance was specified and the font is distortable, set up
  3122      the blend.  */
  3123 
  3124   if (instance != -1
  3125       && desc->tables->fvar && desc->tables->gvar
  3126       /* Make sure the instance is within range.  */
  3127       && instance < desc->tables->fvar->instance_count)
  3128     {
  3129       tem = AREF (desc->instances, instance);
  3130 
  3131       if (!NILP (tem))
  3132         {
  3133           sfnt_init_blend (&font_info->blend, desc->tables->fvar,
  3134                            desc->tables->gvar, desc->tables->avar,
  3135                            desc->tables->cvar);
  3136 
  3137           /* Copy over the coordinates.  */
  3138           for (i = 0; i < desc->tables->fvar->axis_count; ++i)
  3139             font_info->blend.coords[i]
  3140               = desc->tables->fvar->instance[instance].coords[i];
  3141 
  3142           sfnt_normalize_blend (&font_info->blend);
  3143 
  3144           /* Test whether or not the instance is actually redundant,
  3145              as all of its axis are at their default values.  If so,
  3146              free the instance.  */
  3147 
  3148           for (i = 0; i < desc->tables->fvar->axis_count; ++i)
  3149             {
  3150               if (font_info->blend.norm_coords[i])
  3151                 break;
  3152             }
  3153 
  3154           if (i == desc->tables->fvar->axis_count)
  3155             {
  3156               sfnt_free_blend (&font_info->blend);
  3157               goto cancel_blend;
  3158             }
  3159 
  3160           /* If an interpreter was specified, distort it now.  */
  3161 
  3162           if (font_info->interpreter)
  3163             sfnt_vary_interpreter (font_info->interpreter,
  3164                                    &font_info->blend);
  3165 
  3166           font_info->instance = instance;
  3167 
  3168           /* Replace the style information with that of the
  3169              instance.  */
  3170 
  3171           FONT_SET_STYLE (font_object, FONT_WIDTH_INDEX,
  3172                           AREF (tem, 2));
  3173           FONT_SET_STYLE (font_object, FONT_WEIGHT_INDEX,
  3174                           AREF (tem, 3));
  3175           FONT_SET_STYLE (font_object, FONT_SLANT_INDEX,
  3176                           AREF (tem, 4));
  3177           ASET (font_object, FONT_ADSTYLE_INDEX, Qnil);   
  3178         }
  3179     }
  3180 
  3181  cancel_blend:
  3182   /* Calculate the xfld name.  */
  3183   font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil);
  3184 
  3185 #ifdef HAVE_HARFBUZZ
  3186   /* HarfBuzz will potentially read font tables after the font has
  3187      been opened by Emacs.  Keep the font open, and record its offset
  3188      subtable.  */
  3189   font_info->fd = tables->fd;
  3190   font_info->directory = tables->directory;
  3191 #endif /* HAVE_HARFBUZZ */
  3192 
  3193   /* Set font->desc so that font tables can be dereferenced if
  3194      anything goes wrong.  */
  3195   font_info->desc = desc;
  3196 
  3197 #ifdef HAVE_MMAP
  3198   /* Link the font onto the font table.  */
  3199   font_info->next = open_fonts;
  3200   open_fonts = font_info;
  3201 #endif /* HAVE_MMAP */
  3202 
  3203   /* All done.  */
  3204   unblock_input ();
  3205   return font_object;
  3206 
  3207  bail6:
  3208   sfnt_dereference_font_tables (desc);
  3209   font_info->desc = NULL;
  3210  bail:
  3211   unblock_input ();
  3212   return Qnil;
  3213 }
  3214 
  3215 
  3216 
  3217 /* Metrics computation and other similar font backend functions.  */
  3218 
  3219 /* Return the glyph code corresponding to C inside the font-object
  3220    FONT.  Value is the glyph code upon success, else
  3221    FONT_INVALID_CODE.  */
  3222 
  3223 unsigned int
  3224 sfntfont_encode_char (struct font *font, int c)
  3225 {
  3226   sfnt_glyph glyph;
  3227 
  3228   /* Now look up the glyph.  */
  3229   glyph = sfntfont_lookup_glyph ((struct sfnt_font_info *) font, c);
  3230 
  3231   if (!glyph)
  3232     return FONT_INVALID_CODE;
  3233 
  3234   return glyph;
  3235 }
  3236 
  3237 /* Measure the single glyph GLYPH in the font FONT and return its
  3238    metrics in *PCM.
  3239 
  3240    Instruct the glyph if possible.
  3241 
  3242    Value is 0 upon success, 1 otherwise.  */
  3243 
  3244 static int
  3245 sfntfont_measure_pcm (struct sfnt_font_info *font, sfnt_glyph glyph,
  3246                       struct font_metrics *pcm)
  3247 {
  3248   struct sfnt_glyph_metrics metrics;
  3249   struct sfnt_glyph_outline *outline;
  3250 
  3251   /* Now get the glyph outline, which is required to obtain the rsb,
  3252      ascent and descent.  */
  3253   outline = sfntfont_get_glyph_outline (glyph, &font->outline_cache,
  3254                                         font->scale,
  3255                                         &font->outline_cache_size,
  3256                                         &font->blend,
  3257                                         font->instance,
  3258                                         font->glyf, font->head,
  3259                                         font->hmtx, font->hhea,
  3260                                         font->maxp,
  3261                                         font->loca_short,
  3262                                         font->loca_long,
  3263                                         font->interpreter, &metrics,
  3264                                         &font->state);
  3265 
  3266   if (!outline)
  3267     return 1;
  3268 
  3269   /* Round the left side bearing downwards.  */
  3270   pcm->lbearing = SFNT_FLOOR_FIXED (metrics.lbearing) / 65536;
  3271   pcm->rbearing = SFNT_CEIL_FIXED (outline->xmax) / 65536;
  3272 
  3273   /* Round the advance, ascent and descent upwards.  */
  3274   pcm->width = SFNT_CEIL_FIXED (metrics.advance) / 65536;
  3275   pcm->ascent = SFNT_CEIL_FIXED (outline->ymax) / 65536;
  3276   pcm->descent = SFNT_CEIL_FIXED (-outline->ymin) / 65536;
  3277 
  3278   sfntfont_dereference_outline (outline);
  3279   return 0;
  3280 }
  3281 
  3282 /* Return the total text extents of NGLYPHS glyphs given as CODE in
  3283    the single font metrics array METRICS.  */
  3284 
  3285 void
  3286 sfntfont_text_extents (struct font *font, const unsigned int *code,
  3287                        int nglyphs, struct font_metrics *metrics)
  3288 {
  3289   int i, total_width;
  3290   struct font_metrics pcm;
  3291 
  3292   total_width = 0;
  3293 
  3294   /* First clear the metrics array.  */
  3295   memset (metrics, 0, sizeof *metrics);
  3296 
  3297   /* Get the metrcs one by one, then sum them up.  */
  3298   for (i = 0; i < nglyphs; ++i)
  3299     {
  3300       if (!sfntfont_measure_pcm ((struct sfnt_font_info *) font,
  3301                                  code[i], &pcm))
  3302         {
  3303           /* Add the per-char metric (PCM) to the metrics in
  3304              METRICS.  */
  3305 
  3306           if (total_width + pcm.lbearing < metrics->lbearing)
  3307             metrics->lbearing = total_width + pcm.lbearing;
  3308 
  3309           if (total_width + pcm.rbearing > metrics->rbearing)
  3310             metrics->rbearing = total_width + pcm.rbearing;
  3311 
  3312           if (pcm.ascent > metrics->ascent)
  3313             metrics->ascent = pcm.ascent;
  3314 
  3315           if (pcm.descent > metrics->descent)
  3316             metrics->descent = pcm.descent;
  3317 
  3318           total_width += pcm.width;
  3319         }
  3320     }
  3321 
  3322   metrics->width = total_width;
  3323 }
  3324 
  3325 /* Close the font FONT, discarding all tables inside it and
  3326    dereferencing all cached outlines and rasters.  */
  3327 
  3328 void
  3329 sfntfont_close (struct font *font)
  3330 {
  3331   struct sfnt_font_info *info;
  3332 #ifdef HAVE_MMAP
  3333   struct sfnt_font_info **next;
  3334 #endif /* HAVE_MMAP */
  3335 
  3336   info = (struct sfnt_font_info *) font;
  3337 
  3338   /* If info->desc is still set, dereference the font tables.  */
  3339   if (info->desc)
  3340     sfnt_dereference_font_tables (info->desc);
  3341   info->desc = NULL;
  3342 
  3343   /* Free the interpreter, which is created on a per font basis.  */
  3344   xfree (info->interpreter);
  3345 
  3346   /* Clear these fields.  It seems that close can be called twice,
  3347      once during font driver destruction, and once during GC.  */
  3348 
  3349   info->cmap = NULL;
  3350   info->hhea = NULL;
  3351   info->maxp = NULL;
  3352   info->head = NULL;
  3353   info->hhea = NULL;
  3354   info->glyf = NULL;
  3355   info->loca_short = NULL;
  3356   info->loca_long = NULL;
  3357   info->cmap_data = NULL;
  3358   info->prep = NULL;
  3359   info->fpgm = NULL;
  3360   info->cvt = NULL;
  3361   info->interpreter = NULL;
  3362   info->uvs = NULL;
  3363 
  3364   /* Deinitialize the blend.  */
  3365   if (info->instance != -1 && info->blend.coords)
  3366     sfnt_free_blend (&info->blend);
  3367   info->instance = -1;
  3368 
  3369 #ifdef HAVE_MMAP
  3370 
  3371   /* Unlink INFO.  */
  3372 
  3373   next = &open_fonts;
  3374   while (*next && (*next) != info)
  3375     next = &(*next)->next;
  3376 
  3377   if (*next)
  3378     *next = info->next;
  3379   info->next = NULL;
  3380 
  3381 #endif /* HAVE_MMAP */
  3382 
  3383 #ifdef HAVE_HARFBUZZ
  3384   /* These fields will be freed or closed by
  3385      sfnt_dereference_font_tables, but clear them here for good
  3386      measure.  */
  3387   info->directory = NULL;
  3388   info->fd = -1;
  3389 
  3390   /* Free any hb_font created.  */
  3391 
  3392   if (info->hb_font)
  3393     {
  3394       hb_font_destroy (info->hb_font);
  3395       info->hb_font = NULL;
  3396     }
  3397 #endif
  3398 
  3399   sfntfont_free_outline_cache (&info->outline_cache);
  3400   sfntfont_free_raster_cache (&info->raster_cache);
  3401 }
  3402 
  3403 
  3404 
  3405 /* Glyph display.  */
  3406 
  3407 /* Function called to actually draw rasters to the glass.  */
  3408 static sfntfont_put_glyph_proc sfnt_put_glyphs;
  3409 
  3410 /* Draw glyphs in S->char2b starting from FROM to TO, with the origin
  3411    at X and baseline at Y.  Fill the background from X, Y +
  3412    FONT_DESCENT to X + S->background_width, Y - FONT_ASCENT with the
  3413    background color if necessary.  Use the foreground and background
  3414    colors in S->gc.  */
  3415 
  3416 int
  3417 sfntfont_draw (struct glyph_string *s, int from, int to,
  3418                int x, int y, bool with_background)
  3419 {
  3420   int length;
  3421   struct sfnt_raster **rasters;
  3422   int *x_coords, current_x, i;
  3423   struct sfnt_glyph_outline *outline;
  3424   struct font *font;
  3425   struct sfnt_font_info *info;
  3426   struct sfnt_glyph_metrics metrics;
  3427 
  3428   length = to - from;
  3429   font = s->font;
  3430   info = (struct sfnt_font_info *) font;
  3431 
  3432   rasters = alloca (length * sizeof *rasters);
  3433   x_coords = alloca (length * sizeof *x_coords);
  3434   current_x = x;
  3435 
  3436   /* Get rasters and outlines for them.  */
  3437   for (i = from; i < to; ++i)
  3438     {
  3439       /* Look up the outline.  */
  3440       outline = sfntfont_get_glyph_outline (s->char2b[i],
  3441                                             &info->outline_cache,
  3442                                             info->scale,
  3443                                             &info->outline_cache_size,
  3444                                             &info->blend,
  3445                                             info->instance,
  3446                                             info->glyf, info->head,
  3447                                             info->hmtx, info->hhea,
  3448                                             info->maxp,
  3449                                             info->loca_short,
  3450                                             info->loca_long,
  3451                                             info->interpreter,
  3452                                             &metrics,
  3453                                             &info->state);
  3454       x_coords[i - from] = 0;
  3455 
  3456       if (!outline)
  3457         {
  3458           rasters[i - from] = NULL;
  3459           continue;
  3460         }
  3461 
  3462       /* Rasterize the outline.  */
  3463       rasters[i - from] = sfntfont_get_glyph_raster (s->char2b[i],
  3464                                                      &info->raster_cache,
  3465                                                      outline,
  3466                                                      &info->raster_cache_size);
  3467       sfntfont_dereference_outline (outline);
  3468 
  3469       if (!rasters[i - from])
  3470         continue;
  3471 
  3472       /* Now work out where to put the outline.  */
  3473       x_coords[i - from] = current_x;
  3474 
  3475       if (s->padding_p)
  3476         current_x += 1;
  3477       else
  3478         current_x += SFNT_CEIL_FIXED (metrics.advance) / 65536;
  3479     }
  3480 
  3481   /* Call the window system function to put the glyphs to the
  3482      frame.  */
  3483   sfnt_put_glyphs (s, from, to, x, y, with_background,
  3484                    rasters, x_coords);
  3485 
  3486   /* Dereference all the rasters.  */
  3487   for (i = 0; i < from - to; ++i)
  3488     {
  3489       if (rasters[i])
  3490         sfntfont_dereference_raster (rasters[i]);
  3491     }
  3492 
  3493   return 1;
  3494 }
  3495 
  3496 
  3497 
  3498 /* Other callbacks.  */
  3499 
  3500 /* Return a list of each font family known to Emacs.  F is supposed to
  3501    be a frame but is ignored.  */
  3502 
  3503 Lisp_Object
  3504 sfntfont_list_family (struct frame *f)
  3505 {
  3506   Lisp_Object families;
  3507   struct sfnt_font_desc *desc;
  3508 
  3509   families = Qnil;
  3510 
  3511   for (desc = system_fonts; desc; desc = desc->next)
  3512     /* Add desc->family to the list.  */
  3513     families = Fcons (desc->family, families);
  3514 
  3515   /* Not sure if deleting duplicates is worth it.  Is this ever
  3516      called? */
  3517   return families;
  3518 }
  3519 
  3520 
  3521 
  3522 /* Unicode Variation Selector (UVS) support.  This is typically
  3523    required for Harfbuzz.  */
  3524 
  3525 /* Given a FONT object, a character C, and VARIATIONS, return the
  3526    number of non-default variation glyphs, and their glyph ids in
  3527    VARIATIONS.
  3528 
  3529    For each variation selector character K with a non-default glyph in
  3530    the variation selector range 0xFE00 to 0xFE0F, set variations[K -
  3531    0xFE0] to its ID.
  3532 
  3533    For each variation selector character K with a non-default glyph in
  3534    the variation selector range 0xE0100 to 0xE01EF, set variations[K -
  3535    0xE0100 + 16] to its ID.
  3536 
  3537    If value is more than 0, set all other members of VARIATIONS to 0.
  3538    Else, the contents of VARIATIONS are undefined.  */
  3539 
  3540 int
  3541 sfntfont_get_variation_glyphs (struct font *font, int c,
  3542                                unsigned variations[256])
  3543 {
  3544   struct sfnt_font_info *info;
  3545   size_t i;
  3546   int n;
  3547   struct sfnt_mapped_variation_selector_record *record;
  3548 
  3549   info = (struct sfnt_font_info *) font;
  3550   n = 0;
  3551 
  3552   /* Return 0 if there is no UVS mapping table.  */
  3553 
  3554   if (!info->uvs)
  3555     return 0;
  3556 
  3557   /* Clear the variations array.  */
  3558 
  3559   memset (variations, 0, sizeof *variations * 256);
  3560 
  3561   /* Find the first 0xFExx selector.  */
  3562 
  3563   i = 0;
  3564   while (i < info->uvs->num_records
  3565          && info->uvs->records[i].selector < 0xfe00)
  3566     ++i;
  3567 
  3568   /* Fill in selectors 0 to 15.  */
  3569 
  3570   while (i < info->uvs->num_records
  3571          && info->uvs->records[i].selector <= 0xfe0f)
  3572     {
  3573       record = &info->uvs->records[i];
  3574 
  3575       /* If record has no non-default mappings, continue on to the
  3576          next selector.  */
  3577 
  3578       if (!record->nondefault_uvs)
  3579         goto next_selector;
  3580 
  3581       /* Handle invalid unsorted tables.  */
  3582 
  3583       if (record->selector < 0xfe00)
  3584         return 0;
  3585 
  3586       /* Find the glyph ID associated with C and put it in
  3587          VARIATIONS.  */
  3588 
  3589       variations[info->uvs->records[i].selector - 0xfe00]
  3590         = sfnt_variation_glyph_for_char (record->nondefault_uvs, c);
  3591 
  3592       if (variations[info->uvs->records[i].selector - 0xfe00])
  3593         ++n;
  3594 
  3595     next_selector:
  3596       ++i;
  3597     }
  3598 
  3599   /* Find the first 0xE0100 selector.  */
  3600 
  3601   i = 0;
  3602   while (i < info->uvs->num_records
  3603          && info->uvs->records[i].selector < 0xe0100)
  3604     ++i;
  3605 
  3606   /* Fill in selectors 16 to 255.  */
  3607 
  3608   while (i < info->uvs->num_records
  3609          && info->uvs->records[i].selector <= 0xe01ef)
  3610     {
  3611       record = &info->uvs->records[i];
  3612 
  3613       /* If record has no non-default mappings, continue on to the
  3614          next selector.  */
  3615 
  3616       if (!record->nondefault_uvs)
  3617         goto next_selector_1;
  3618 
  3619       /* Handle invalid unsorted tables.  */
  3620 
  3621       if (record->selector < 0xe0100)
  3622         return 0;
  3623 
  3624       /* Find the glyph ID associated with C and put it in
  3625          VARIATIONS.  */
  3626 
  3627       variations[info->uvs->records[i].selector - 0xe0100 + 16]
  3628         = sfnt_variation_glyph_for_char (record->nondefault_uvs, c);
  3629 
  3630       if (variations[info->uvs->records[i].selector - 0xe0100 + 16])
  3631         ++n;
  3632 
  3633     next_selector_1:
  3634       ++i;
  3635     }
  3636 
  3637   return n;
  3638 }
  3639 
  3640 
  3641 
  3642 /* mmap specific stuff.  */
  3643 
  3644 #ifdef HAVE_MMAP
  3645 
  3646 /* Return whether or not ADDR lies in a mapped glyph, and bus faults
  3647    should be ignored.  */
  3648 
  3649 bool
  3650 sfntfont_detect_sigbus (void *addr)
  3651 {
  3652   struct sfnt_font_info *info;
  3653 
  3654   for (info = open_fonts; info; info = info->next)
  3655     {
  3656       if (info->glyf_table_mapped
  3657           && (unsigned char *) addr >= info->glyf->glyphs
  3658           && (unsigned char *) addr < (info->glyf->glyphs
  3659                                        + info->glyf->size))
  3660         return true;
  3661     }
  3662 
  3663   return false;
  3664 }
  3665 
  3666 #endif
  3667 
  3668 
  3669 
  3670 /* Harfbuzz font support.  */
  3671 
  3672 #ifdef HAVE_HARFBUZZ
  3673 
  3674 #ifdef HAVE_MMAP
  3675 
  3676 /* Unmap the specified table.  */
  3677 
  3678 static void
  3679 sfntfont_unmap_blob (void *ptr)
  3680 {
  3681   if (sfnt_unmap_table (ptr))
  3682     emacs_abort ();
  3683 
  3684   xfree (ptr);
  3685 }
  3686 
  3687 #endif /* HAVE_MMAP */
  3688 
  3689 /* Given a font DATA and a tag TAG, return the data of the
  3690    corresponding font table as a HarfBuzz blob.  */
  3691 
  3692 static hb_blob_t *
  3693 sfntfont_get_font_table (hb_face_t *face, hb_tag_t tag, void *data)
  3694 {
  3695   size_t size;
  3696   struct sfnt_font_info *info;
  3697 #ifdef HAVE_MMAP
  3698   struct sfnt_mapped_table *table;
  3699   hb_blob_t *blob;
  3700 
  3701   info = data;
  3702   table = xmalloc (sizeof *table);
  3703 
  3704   if (!sfnt_map_table (info->fd, info->directory, tag,
  3705                        table))
  3706     {
  3707       /* Create an hb_blob_t and return it.
  3708          TODO: record this mapping properly so that SIGBUS can
  3709          be handled.  */
  3710 
  3711       blob = hb_blob_create (table->data, table->length,
  3712                              HB_MEMORY_MODE_READONLY,
  3713                              table, sfntfont_unmap_blob);
  3714 
  3715       /* Note that sfntfont_unmap_blob will be called if the empty
  3716          blob is returned.  */
  3717       return blob;
  3718     }
  3719 
  3720   xfree (table);
  3721 #else /* !HAVE_MMAP */
  3722 
  3723   /* Try to read the table conventionally.  */
  3724   info = data;
  3725 #endif /* HAVE_MMAP */
  3726 
  3727   data = sfnt_read_table (info->fd, info->directory, tag,
  3728                           &size);
  3729 
  3730   if (!data)
  3731     return NULL;
  3732 
  3733   return hb_blob_create (data, size, HB_MEMORY_MODE_WRITABLE,
  3734                          data, xfree);
  3735 }
  3736 
  3737 /* Create or return a HarfBuzz font object corresponding to the
  3738    specified FONT.  Return the scale to convert between fwords and
  3739    pixels in POSITION_UNIT.  */
  3740 
  3741 hb_font_t *
  3742 sfntfont_begin_hb_font (struct font *font, double *position_unit)
  3743 {
  3744   struct sfnt_font_info *info;
  3745   hb_face_t *face;
  3746   int factor;
  3747 
  3748   info = (struct sfnt_font_info *) font;
  3749 
  3750   if (info->hb_font)
  3751     {
  3752       /* Calculate the scale factor.  */
  3753       *position_unit = 1.0 / 64.0;
  3754       return info->hb_font;
  3755     }
  3756 
  3757   /* Create a face and then a font.  */
  3758   face = hb_face_create_for_tables (sfntfont_get_font_table, font,
  3759                                     NULL);
  3760 
  3761   if (hb_face_get_glyph_count (face) > 0)
  3762     {
  3763       info->hb_font = hb_font_create (face);
  3764       if (!info->hb_font)
  3765         goto bail;
  3766 
  3767       factor = font->pixel_size;
  3768 
  3769       /* Set the scale and PPEM values.  */
  3770       hb_font_set_scale (info->hb_font, factor * 64, factor * 64);
  3771       hb_font_set_ppem (info->hb_font, factor, factor);
  3772 
  3773 #ifdef HAVE_HB_FONT_SET_VAR_NAMED_INSTANCE
  3774       /* Set the instance if this is a distortable font.  */
  3775       if (info->instance != -1)
  3776         hb_font_set_var_named_instance (info->hb_font,
  3777                                         info->instance);
  3778 #endif /* HAVE_HB_FONT_SET_VAR_NAMED_INSTANCE */
  3779 
  3780       /* This is needed for HarfBuzz before 2.0.0; it is the default
  3781          in later versions.  */
  3782       hb_ot_font_set_funcs (info->hb_font);
  3783     }
  3784 
  3785  bail:
  3786   hb_face_destroy (face);
  3787 
  3788   /* Calculate the scale factor.  */
  3789   *position_unit = 1.0 / 64.0;
  3790   return info->hb_font;
  3791 }
  3792 
  3793 #endif /* HAVE_HARFBUZZ */
  3794 
  3795 
  3796 
  3797 void
  3798 syms_of_sfntfont (void)
  3799 {
  3800   DEFSYM (Qutf_16be, "utf-16be");
  3801   DEFSYM (Qmac_roman, "mac-roman");
  3802   DEFSYM (Qchinese_big5, "chinese-big5");
  3803   DEFSYM (Qunicode_bmp, "unicode-bmp");
  3804   DEFSYM (Qucs, "ucs");
  3805   DEFSYM (Qjapanese_jisx0208, "japanese-jisx0208");
  3806   DEFSYM (Qgbk, "gbk");
  3807   DEFSYM (Qkorean_ksc5601, "korean-ksc5601");
  3808   DEFSYM (Qapple_roman, "apple-roman");
  3809   DEFSYM (Qjisx0208_1983_0, "jisx0208.1983-0");
  3810   DEFSYM (Qksc5601_1987_0, "ksc5601.1987-0");
  3811   DEFSYM (Qzh, "zh");
  3812   DEFSYM (Qja, "ja");
  3813   DEFSYM (Qko, "ko");
  3814   DEFSYM (Qfont_instance, "font-instance");
  3815 
  3816   /* Char-table purpose.  */
  3817   DEFSYM (Qfont_lookup_cache, "font-lookup-cache");
  3818 
  3819   /* Set up staticpros.  */
  3820   sfnt_vendor_name = Qnil;
  3821   staticpro (&sfnt_vendor_name);
  3822 
  3823   /* This variable is supposed to be set by the platform specific part
  3824      of the font backend.  */
  3825   DEFVAR_LISP ("sfnt-default-family-alist", Vsfnt_default_family_alist,
  3826     doc: /* Alist between "emulated" and actual font family names.
  3827 
  3828 Much Emacs code assumes that font families named "Monospace" and "Sans
  3829 Serif" exist, and map to the default monospace and Sans Serif fonts on
  3830 a system.  When the `sfnt' font driver is asked to look for a font
  3831 with one of the families in this alist, it uses its value instead.  */);
  3832   Vsfnt_default_family_alist = Qnil;
  3833 }
  3834 
  3835 void
  3836 mark_sfntfont (void)
  3837 {
  3838   struct sfnt_font_desc *desc;
  3839 
  3840   /* Mark each font desc.  */
  3841   for (desc = system_fonts; desc; desc = desc->next)
  3842     {
  3843       mark_object (desc->family);
  3844       mark_object (desc->style);
  3845       mark_object (desc->adstyle);
  3846       mark_object (desc->instances);
  3847       mark_object (desc->languages);
  3848       mark_object (desc->registry);
  3849       mark_object (desc->char_cache);
  3850       mark_object (desc->designer);
  3851     }
  3852 }
  3853 
  3854 void
  3855 init_sfntfont (void)
  3856 {
  3857 
  3858 }
  3859 
  3860 
  3861 
  3862 /* Initialize the sfntfont font driver.  VENDOR_TYPE is the type of
  3863    all font entities created.  DRIVER is the font driver that is saved
  3864    in font objects.  PUT_GLYPHS is a function that is called with 8
  3865    arguments, S, FROM, TO, X, Y, WITH_BACKGROUND, RASTERS, and
  3866    X_COORDS, and should draw all the rasters in RASTERS to S->f,
  3867    originating at X_COORDS[i], Y, along with filling the background if
  3868    WITH_BACKGROUND is specified.  */
  3869 
  3870 void
  3871 init_sfntfont_vendor (Lisp_Object vendor_name,
  3872                       const struct font_driver *driver,
  3873                       sfntfont_put_glyph_proc put_glyphs)
  3874 {
  3875   sfnt_vendor_name = vendor_name;
  3876   sfnt_font_driver = driver;
  3877   sfnt_put_glyphs = put_glyphs;
  3878 }

/* [<][>][^][v][top][bottom][index][help] */