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

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