1 /* ftfont.c -- FreeType font driver.
   2    Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
   3    Copyright (C) 2006, 2007, 2008, 2009, 2010
   4      National Institute of Advanced Industrial Science and Technology (AIST)
   5      Registration Number H13PRO009
   6 
   7 This file is part of GNU Emacs.
   8 
   9 GNU Emacs is free software: you can redistribute it and/or modify
  10 it under the terms of the GNU General Public License as published by
  11 the Free Software Foundation, either version 3 of the License, or
  12 (at your option) any later version.
  13 
  14 GNU Emacs is distributed in the hope that it will be useful,
  15 but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 GNU General Public License for more details.
  18 
  19 You should have received a copy of the GNU General Public License
  20 along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
  21 
  22 #include <config.h>
  23 #include <stdio.h>
  24 #include <setjmp.h>
  25 
  26 #include <fontconfig/fontconfig.h>
  27 #include <fontconfig/fcfreetype.h>
  28 
  29 #include "lisp.h"
  30 #include "dispextern.h"
  31 #include "frame.h"
  32 #include "blockinput.h"
  33 #include "character.h"
  34 #include "charset.h"
  35 #include "coding.h"
  36 #include "composite.h"
  37 #include "fontset.h"
  38 #include "font.h"
  39 #include "ftfont.h"
  40 
  41 /* Symbolic type of this font-driver.  */
  42 Lisp_Object Qfreetype;
  43 
  44 /* Fontconfig's generic families and their aliases.  */
  45 static Lisp_Object Qmonospace, Qsans_serif, Qserif, Qmono, Qsans, Qsans__serif;
  46 
  47 /* Flag to tell if FcInit is already called or not.  */
  48 static int fc_initialized;
  49 
  50 /* Handle to a FreeType library instance.  */
  51 static FT_Library ft_library;
  52 
  53 /* Cache for FreeType fonts.  */
  54 static Lisp_Object freetype_font_cache;
  55 
  56 /* Cache for FT_Face and FcCharSet. */
  57 static Lisp_Object ft_face_cache;
  58 
  59 /* The actual structure for FreeType font that can be casted to struct
  60    font.  */
  61 
  62 struct ftfont_info
  63 {
  64   struct font font;
  65 #ifdef HAVE_LIBOTF
  66   /* The following four members must be here in this order to be
  67      compatible with struct xftfont_info (in xftfont.c).  */
  68   int maybe_otf;        /* Flag to tell if this may be OTF or not.  */
  69   OTF *otf;
  70 #endif  /* HAVE_LIBOTF */
  71   FT_Size ft_size;
  72   int index;
  73   FT_Matrix matrix;
  74 };
  75 
  76 enum ftfont_cache_for
  77   {
  78     FTFONT_CACHE_FOR_FACE,
  79     FTFONT_CACHE_FOR_CHARSET,
  80     FTFONT_CACHE_FOR_ENTITY
  81   };
  82 
  83 static Lisp_Object ftfont_pattern_entity P_ ((FcPattern *, Lisp_Object));
  84 
  85 static Lisp_Object ftfont_resolve_generic_family P_ ((Lisp_Object,
  86                                                       FcPattern *));
  87 static Lisp_Object ftfont_lookup_cache P_ ((Lisp_Object,
  88                                             enum ftfont_cache_for));
  89 
  90 static void ftfont_filter_properties P_ ((Lisp_Object font, Lisp_Object alist));
  91                                                 
  92 Lisp_Object ftfont_font_format P_ ((FcPattern *, Lisp_Object));
  93 
  94 #define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM))
  95 
  96 static struct
  97 {
  98   /* registry name */
  99   char *name;
 100   /* characters to distinguish the charset from the others */
 101   int uniquifier[6];
 102   /* additional constraint by language */
 103   char *lang;
 104   /* set on demand */
 105   FcCharSet *fc_charset;
 106 } fc_charset_table[] =
 107   { { "iso8859-1", { 0x00A0, 0x00A1, 0x00B4, 0x00BC, 0x00D0 } },
 108     { "iso8859-2", { 0x00A0, 0x010E }},
 109     { "iso8859-3", { 0x00A0, 0x0108 }},
 110     { "iso8859-4", { 0x00A0, 0x00AF, 0x0128, 0x0156, 0x02C7 }},
 111     { "iso8859-5", { 0x00A0, 0x0401 }},
 112     { "iso8859-6", { 0x00A0, 0x060C }},
 113     { "iso8859-7", { 0x00A0, 0x0384 }},
 114     { "iso8859-8", { 0x00A0, 0x05D0 }},
 115     { "iso8859-9", { 0x00A0, 0x00A1, 0x00BC, 0x011E }},
 116     { "iso8859-10", { 0x00A0, 0x00D0, 0x0128, 0x2015 }},
 117     { "iso8859-11", { 0x00A0, 0x0E01 }},
 118     { "iso8859-13", { 0x00A0, 0x201C }},
 119     { "iso8859-14", { 0x00A0, 0x0174 }},
 120     { "iso8859-15", { 0x00A0, 0x00A1, 0x00D0, 0x0152 }},
 121     { "iso8859-16", { 0x00A0, 0x0218}},
 122     { "gb2312.1980-0", { 0x4E13 }, "zh-cn"},
 123     { "big5-0", { 0xF6B1 }, "zh-tw" },
 124     { "jisx0208.1983-0", { 0x4E55 }, "ja"},
 125     { "ksc5601.1985-0", { 0xAC00 }, "ko"},
 126     { "cns11643.1992-1", { 0xFE32 }, "zh-tw"},
 127     { "cns11643.1992-2", { 0x4E33, 0x7934 }},
 128     { "cns11643.1992-3", { 0x201A9 }},
 129     { "cns11643.1992-4", { 0x20057 }},
 130     { "cns11643.1992-5", { 0x20000 }},
 131     { "cns11643.1992-6", { 0x20003 }},
 132     { "cns11643.1992-7", { 0x20055 }},
 133     { "gbk-0", { 0x4E06 }, "zh-cn"},
 134     { "jisx0212.1990-0", { 0x4E44 }},
 135     { "jisx0213.2000-1", { 0xFA10 }, "ja"},
 136     { "jisx0213.2000-2", { 0xFA49 }},
 137     { "jisx0213.2004-1", { 0x20B9F }},
 138     { "viscii1.1-1", { 0x1EA0, 0x1EAE, 0x1ED2 }, "vi"},
 139     { "tis620.2529-1", { 0x0E01 }, "th"},
 140     { "windows-1251", { 0x0401, 0x0490 }, "ru"},
 141     { "koi8-r", { 0x0401, 0x2219 }, "ru"},
 142     { "mulelao-1", { 0x0E81 }, "lo"},
 143     { "unicode-sip", { 0x20000 }},
 144     { NULL }
 145   };
 146 
 147 extern Lisp_Object Qc, Qm, Qp, Qd;
 148 
 149 /* Dirty hack for handing ADSTYLE property.
 150 
 151    Fontconfig (actually the underlying FreeType) gives such ADSTYLE
 152    font property of PCF/BDF fonts in FC_STYLE.  And, "Bold",
 153    "Oblique", "Italic", or any non-normal SWIDTH property names
 154    (e.g. SemiCondensed) are appended.  In addition, if there's no
 155    ADSTYLE property nor non-normal WEIGHT/SLANT/SWIDTH properties,
 156    "Regular" is used for FC_STYLE (see the function
 157    pcf_interpret_style in src/pcf/pcfread.c of FreeType).
 158 
 159    Unfortunately this behavior is not documented, so the following
 160    code may fail if FreeType changes the behavior in the future.  */
 161 
 162 static Lisp_Object
 163 get_adstyle_property (FcPattern *p)
 164 {
 165   char *str, *end;
 166   Lisp_Object adstyle;
 167 
 168   if (FcPatternGetString (p, FC_STYLE, 0, (FcChar8 **) &str) != FcResultMatch)
 169     return Qnil;
 170   for (end = str; *end && *end != ' '; end++);
 171   if (*end)
 172     {
 173       char *p = alloca (end - str + 1);
 174       memcpy (p, str, end - str);
 175       p[end - str] = '\0';
 176       end = p + (end - str);
 177       str = p;
 178     }
 179   if (xstrcasecmp (str, "Regular") == 0
 180       || xstrcasecmp (str, "Bold") == 0
 181       || xstrcasecmp (str, "Oblique") == 0
 182       || xstrcasecmp (str, "Italic") == 0)
 183     return Qnil;
 184   adstyle = font_intern_prop (str, end - str, 1);
 185   if (font_style_to_value (FONT_WIDTH_INDEX, adstyle, 0) >= 0)
 186     return Qnil;
 187   return adstyle;
 188 }
 189 
 190 static Lisp_Object
 191 ftfont_pattern_entity (p, extra)
 192      FcPattern *p;
 193      Lisp_Object extra;
 194 {
 195   Lisp_Object key, cache, entity;
 196   char *file, *str;
 197   int index;
 198   int numeric;
 199   double dbl;
 200   FcBool b;
 201 
 202   if (FcPatternGetString (p, FC_FILE, 0, (FcChar8 **) &file) != FcResultMatch)
 203     return Qnil;
 204   if (FcPatternGetInteger (p, FC_INDEX, 0, &index) != FcResultMatch)
 205     return Qnil;
 206 
 207   key = Fcons (make_unibyte_string ((char *) file, strlen ((char *) file)),
 208                make_number (index));
 209   cache = ftfont_lookup_cache (key, FTFONT_CACHE_FOR_ENTITY);
 210   entity = XCAR (cache);
 211   if (! NILP (entity))
 212     {
 213       Lisp_Object val = font_make_entity ();
 214       int i;
 215 
 216       for (i = 0; i < FONT_OBJLIST_INDEX; i++)
 217         ASET (val, i, AREF (entity, i));
 218       return val;
 219     }
 220   entity = font_make_entity ();
 221   XSETCAR (cache, entity);
 222 
 223   ASET (entity, FONT_TYPE_INDEX, Qfreetype);
 224   ASET (entity, FONT_REGISTRY_INDEX, Qiso10646_1);
 225 
 226   if (FcPatternGetString (p, FC_FOUNDRY, 0, (FcChar8 **) &str) == FcResultMatch)
 227     ASET (entity, FONT_FOUNDRY_INDEX, font_intern_prop (str, strlen (str), 1));
 228   if (FcPatternGetString (p, FC_FAMILY, 0, (FcChar8 **) &str) == FcResultMatch)
 229     ASET (entity, FONT_FAMILY_INDEX, font_intern_prop (str, strlen (str), 1));
 230   if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch)
 231     {
 232       if (numeric >= FC_WEIGHT_REGULAR && numeric < FC_WEIGHT_MEDIUM)
 233         numeric = FC_WEIGHT_MEDIUM;
 234       FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX, make_number (numeric));
 235     }
 236   if (FcPatternGetInteger (p, FC_SLANT, 0, &numeric) == FcResultMatch)
 237     {
 238       numeric += 100;
 239       FONT_SET_STYLE (entity, FONT_SLANT_INDEX, make_number (numeric));
 240     }
 241   if (FcPatternGetInteger (p, FC_WIDTH, 0, &numeric) == FcResultMatch)
 242     {
 243       FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, make_number (numeric));
 244     }
 245   if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch)
 246     {
 247       ASET (entity, FONT_SIZE_INDEX, make_number (dbl));
 248     }
 249   else
 250     ASET (entity, FONT_SIZE_INDEX, make_number (0));
 251   if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) == FcResultMatch)
 252     ASET (entity, FONT_SPACING_INDEX, make_number (numeric));
 253   if (FcPatternGetDouble (p, FC_DPI, 0, &dbl) == FcResultMatch)
 254     {
 255       int dpi = dbl;
 256       ASET (entity, FONT_DPI_INDEX, make_number (dpi));
 257     }
 258   if (FcPatternGetBool (p, FC_SCALABLE, 0, &b) == FcResultMatch
 259       && b == FcTrue)
 260     {
 261       ASET (entity, FONT_SIZE_INDEX, make_number (0));
 262       ASET (entity, FONT_AVGWIDTH_INDEX, make_number (0));
 263     }
 264   else
 265     {
 266       /* As this font is not scalable, parhaps this is a BDF or PCF
 267          font. */ 
 268       FT_Face ft_face;
 269 
 270       ASET (entity, FONT_ADSTYLE_INDEX, get_adstyle_property (p));
 271       if ((ft_library || FT_Init_FreeType (&ft_library) == 0)
 272           && FT_New_Face (ft_library, file, index, &ft_face) == 0)
 273         {
 274           BDF_PropertyRec rec;
 275 
 276           if (FT_Get_BDF_Property (ft_face, "AVERAGE_WIDTH", &rec) == 0
 277               && rec.type == BDF_PROPERTY_TYPE_INTEGER)
 278             ASET (entity, FONT_AVGWIDTH_INDEX, make_number (rec.u.integer));
 279           FT_Done_Face (ft_face);
 280         }
 281     }
 282 
 283   ASET (entity, FONT_EXTRA_INDEX, Fcopy_sequence (extra));
 284   font_put_extra (entity, QCfont_entity, key);
 285   return entity;
 286 }
 287 
 288 
 289 static Lisp_Object ftfont_generic_family_list;
 290 
 291 static Lisp_Object
 292 ftfont_resolve_generic_family (family, pattern)
 293      Lisp_Object family;
 294      FcPattern *pattern;
 295 {
 296   Lisp_Object slot;
 297   FcPattern *match;
 298   FcResult result;
 299   FcLangSet *langset;
 300 
 301   family = Fintern (Fdowncase (SYMBOL_NAME (family)), Qnil);
 302   if (EQ (family, Qmono))
 303     family = Qmonospace;
 304   else if (EQ (family, Qsans) || EQ (family, Qsans__serif))
 305     family = Qsans_serif;
 306   slot = assq_no_quit (family, ftfont_generic_family_list);
 307   if (! CONSP (slot))
 308     return Qnil;
 309   if (! EQ (XCDR (slot), Qt))
 310     return XCDR (slot);
 311   pattern = FcPatternDuplicate (pattern);
 312   if (! pattern)
 313     goto err;
 314   FcPatternDel (pattern, FC_FOUNDRY);
 315   FcPatternDel (pattern, FC_FAMILY);
 316   FcPatternAddString (pattern, FC_FAMILY, SYMBOL_FcChar8 (family));
 317   if (FcPatternGetLangSet (pattern, FC_LANG, 0, &langset) != FcResultMatch)
 318     {
 319       /* This is to avoid the effect of locale.  */
 320       langset = FcLangSetCreate ();
 321       FcLangSetAdd (langset, "en");
 322       FcPatternAddLangSet (pattern, FC_LANG, langset);
 323       FcLangSetDestroy (langset);
 324     }
 325   FcConfigSubstitute (NULL, pattern, FcMatchPattern);
 326   FcDefaultSubstitute (pattern);
 327   match = FcFontMatch (NULL, pattern, &result);
 328   if (match)
 329     {
 330       FcChar8 *fam;
 331 
 332       if (FcPatternGetString (match, FC_FAMILY, 0, &fam) == FcResultMatch)
 333         family = intern ((char *) fam);
 334     }
 335   else
 336     family = Qnil;
 337   XSETCDR (slot, family);
 338   if (match) FcPatternDestroy (match);
 339  err:
 340   if (pattern) FcPatternDestroy (pattern);
 341   return family;
 342 }
 343 
 344 struct ftfont_cache_data
 345 {
 346   FT_Face ft_face;
 347   FcCharSet *fc_charset;
 348 };
 349 
 350 static Lisp_Object
 351 ftfont_lookup_cache (key, cache_for)
 352      Lisp_Object key;
 353      enum ftfont_cache_for cache_for;
 354 {
 355   Lisp_Object cache, val, entity;
 356   struct ftfont_cache_data *cache_data;
 357 
 358   if (FONT_ENTITY_P (key))
 359     {
 360       entity = key;
 361       val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
 362       xassert (CONSP (val));
 363       key = XCDR (val);
 364     }
 365   else
 366     entity = Qnil;
 367 
 368   if (NILP (ft_face_cache))
 369     cache = Qnil;
 370   else
 371     cache = Fgethash (key, ft_face_cache, Qnil);
 372   if (NILP (cache))
 373     {
 374       if (NILP (ft_face_cache))
 375         {
 376           Lisp_Object args[2];
 377 
 378           args[0] = QCtest;
 379           args[1] = Qequal;
 380           ft_face_cache = Fmake_hash_table (2, args);
 381         }
 382       cache_data = xmalloc (sizeof (struct ftfont_cache_data));
 383       cache_data->ft_face = NULL;
 384       cache_data->fc_charset = NULL;
 385       val = make_save_value (NULL, 0);
 386       XSAVE_VALUE (val)->integer = 0;
 387       XSAVE_VALUE (val)->pointer = cache_data;
 388       cache = Fcons (Qnil, val);
 389       Fputhash (key, cache, ft_face_cache);
 390     }
 391   else
 392     {
 393       val = XCDR (cache);
 394       cache_data = XSAVE_VALUE (val)->pointer;
 395     }
 396 
 397   if (cache_for == FTFONT_CACHE_FOR_ENTITY)
 398     return cache;
 399 
 400   if (cache_for == FTFONT_CACHE_FOR_FACE
 401       ? ! cache_data->ft_face : ! cache_data->fc_charset)
 402     {
 403       char *filename = (char *) SDATA (XCAR (key));
 404       int index = XINT (XCDR (key));
 405 
 406       if (cache_for == FTFONT_CACHE_FOR_FACE)
 407         {
 408           if (! ft_library
 409               && FT_Init_FreeType (&ft_library) != 0)
 410             return Qnil;
 411           if (FT_New_Face (ft_library, filename, index, &cache_data->ft_face)
 412               != 0)
 413             return Qnil;
 414         }
 415       else
 416         {
 417           FcPattern *pat = NULL;
 418           FcFontSet *fontset = NULL;
 419           FcObjectSet *objset = NULL;
 420           FcCharSet *charset = NULL;
 421 
 422           pat = FcPatternBuild (0, FC_FILE, FcTypeString, (FcChar8 *) filename,
 423                                 FC_INDEX, FcTypeInteger, index, NULL);
 424           if (! pat)
 425             goto finish;
 426           objset = FcObjectSetBuild (FC_CHARSET, FC_STYLE, NULL);
 427           if (! objset)
 428             goto finish;
 429           fontset = FcFontList (NULL, pat, objset);
 430           if (! fontset)
 431             goto finish;
 432           if (fontset && fontset->nfont > 0
 433               && (FcPatternGetCharSet (fontset->fonts[0], FC_CHARSET, 0,
 434                                        &charset)
 435                   == FcResultMatch))
 436             cache_data->fc_charset = FcCharSetCopy (charset);
 437           else
 438             cache_data->fc_charset = FcCharSetCreate ();
 439 
 440         finish:
 441           if (fontset)
 442             FcFontSetDestroy (fontset);
 443           if (objset)
 444             FcObjectSetDestroy (objset);
 445           if (pat)
 446             FcPatternDestroy (pat);
 447         }
 448     }
 449   return cache;
 450 }
 451 
 452 FcCharSet *
 453 ftfont_get_fc_charset (entity)
 454      Lisp_Object entity;
 455 {
 456   Lisp_Object val, cache;
 457   struct ftfont_cache_data *cache_data;
 458 
 459   cache = ftfont_lookup_cache (entity, FTFONT_CACHE_FOR_CHARSET);
 460   val = XCDR (cache);
 461   cache_data = XSAVE_VALUE (val)->pointer;
 462   return cache_data->fc_charset;
 463 }
 464 
 465 #ifdef HAVE_LIBOTF
 466 static OTF *
 467 ftfont_get_otf (ftfont_info)
 468      struct ftfont_info *ftfont_info;
 469 {
 470   OTF *otf;
 471 
 472   if (ftfont_info->otf)
 473     return ftfont_info->otf;
 474   if (! ftfont_info->maybe_otf)
 475     return NULL;
 476   otf = OTF_open_ft_face (ftfont_info->ft_size->face);
 477   if (! otf || OTF_get_table (otf, "head") < 0)
 478     {
 479       if (otf)
 480         OTF_close (otf);
 481       ftfont_info->maybe_otf = 0;
 482       return NULL;
 483     }
 484   ftfont_info->otf = otf;
 485   return otf;
 486 }
 487 #endif  /* HAVE_LIBOTF */
 488 
 489 static Lisp_Object ftfont_get_cache P_ ((FRAME_PTR));
 490 static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object));
 491 static Lisp_Object ftfont_match P_ ((Lisp_Object, Lisp_Object));
 492 static Lisp_Object ftfont_list_family P_ ((Lisp_Object));
 493 static Lisp_Object ftfont_open P_ ((FRAME_PTR, Lisp_Object, int));
 494 static void ftfont_close P_ ((FRAME_PTR, struct font *));
 495 static int ftfont_has_char P_ ((Lisp_Object, int));
 496 static unsigned ftfont_encode_char P_ ((struct font *, int));
 497 static int ftfont_text_extents P_ ((struct font *, unsigned *, int,
 498                                     struct font_metrics *));
 499 static int ftfont_get_bitmap P_ ((struct font *, unsigned,
 500                                   struct font_bitmap *, int));
 501 static int ftfont_anchor_point P_ ((struct font *, unsigned, int,
 502                                     int *, int *));
 503 static Lisp_Object ftfont_otf_capability P_ ((struct font *));
 504 static Lisp_Object ftfont_shape P_ ((Lisp_Object));
 505 
 506 #ifdef HAVE_OTF_GET_VARIATION_GLYPHS
 507 static int ftfont_variation_glyphs P_ ((struct font *, int c,
 508                                         unsigned variations[256]));
 509 #endif /* HAVE_OTF_GET_VARIATION_GLYPHS */
 510 
 511 struct font_driver ftfont_driver =
 512   {
 513     0,                          /* Qfreetype */
 514     0,                          /* case insensitive */
 515     ftfont_get_cache,
 516     ftfont_list,
 517     ftfont_match,
 518     ftfont_list_family,
 519     NULL,                       /* free_entity */
 520     ftfont_open,
 521     ftfont_close,
 522     /* We can't draw a text without device dependent functions.  */
 523     NULL,                       /* prepare_face */
 524     NULL,                       /* done_face */
 525     ftfont_has_char,
 526     ftfont_encode_char,
 527     ftfont_text_extents,
 528     /* We can't draw a text without device dependent functions.  */
 529     NULL,                       /* draw */
 530     ftfont_get_bitmap,
 531     NULL,                       /* get_bitmap */
 532     NULL,                       /* free_bitmap */
 533     NULL,                       /* get_outline */
 534     ftfont_anchor_point,
 535 #ifdef HAVE_LIBOTF
 536     ftfont_otf_capability,
 537 #else  /* not HAVE_LIBOTF */
 538     NULL,
 539 #endif  /* not HAVE_LIBOTF */
 540     NULL,                       /* otf_drive */
 541     NULL,                       /* start_for_frame */
 542     NULL,                       /* end_for_frame */
 543 #if defined (HAVE_M17N_FLT) && defined (HAVE_LIBOTF)
 544     ftfont_shape,
 545 #else  /* not (HAVE_M17N_FLT && HAVE_LIBOTF) */
 546     NULL,
 547 #endif  /* not (HAVE_M17N_FLT && HAVE_LIBOTF) */
 548     NULL,                       /* check */
 549 
 550 #ifdef HAVE_OTF_GET_VARIATION_GLYPHS
 551     ftfont_variation_glyphs,
 552 #else
 553     NULL,
 554 #endif
 555 
 556     ftfont_filter_properties, /* filter_properties */
 557   };
 558 
 559 extern Lisp_Object QCname;
 560 
 561 static Lisp_Object
 562 ftfont_get_cache (f)
 563      FRAME_PTR f;
 564 {
 565   return freetype_font_cache;
 566 }
 567 
 568 static int
 569 ftfont_get_charset (registry)
 570      Lisp_Object registry;
 571 {
 572   char *str = (char *) SDATA (SYMBOL_NAME (registry));
 573   char *re = alloca (SBYTES (SYMBOL_NAME (registry)) * 2 + 1);
 574   Lisp_Object regexp;
 575   int i, j;
 576 
 577   for (i = j = 0; i < SBYTES (SYMBOL_NAME (registry)); i++, j++)
 578     {
 579       if (str[i] == '.')
 580         re[j++] = '\\';
 581       else if (str[i] == '*')
 582         re[j++] = '.';
 583       re[j] = str[i];
 584       if (re[j] == '?')
 585         re[j] = '.';
 586     }
 587   re[j] = '\0';
 588   regexp = make_unibyte_string (re, j);
 589   for (i = 0; fc_charset_table[i].name; i++)
 590     if (fast_c_string_match_ignore_case (regexp, fc_charset_table[i].name) >= 0)
 591       break;
 592   if (! fc_charset_table[i].name)
 593     return -1;
 594   if (! fc_charset_table[i].fc_charset)
 595     {
 596       FcCharSet *charset = FcCharSetCreate ();
 597       int *uniquifier = fc_charset_table[i].uniquifier;
 598 
 599       if (! charset)
 600         return -1;
 601       for (j = 0; uniquifier[j]; j++)
 602         if (! FcCharSetAddChar (charset, uniquifier[j]))
 603           {
 604             FcCharSetDestroy (charset);
 605             return -1;
 606           }
 607       fc_charset_table[i].fc_charset = charset;
 608     }
 609   return i;
 610 }
 611 
 612 struct OpenTypeSpec
 613 {
 614   Lisp_Object script;
 615   unsigned int script_tag, langsys_tag;
 616   int nfeatures[2];
 617   unsigned int *features[2];
 618 };
 619 
 620 #define OTF_SYM_TAG(SYM, TAG)                                   \
 621   do {                                                          \
 622     unsigned char *p = SDATA (SYMBOL_NAME (SYM));               \
 623     TAG = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];     \
 624   } while (0)
 625 
 626 #define OTF_TAG_STR(TAG, P)                     \
 627   do {                                          \
 628     (P)[0] = (char) (TAG >> 24);                \
 629     (P)[1] = (char) ((TAG >> 16) & 0xFF);       \
 630     (P)[2] = (char) ((TAG >> 8) & 0xFF);        \
 631     (P)[3] = (char) (TAG & 0xFF);               \
 632     (P)[4] = '\0';                              \
 633   } while (0)
 634 
 635 #define OTF_TAG_SYM(SYM, TAG)                   \
 636   do {                                          \
 637     char str[5];                                \
 638                                                 \
 639     OTF_TAG_STR (TAG, str);                     \
 640     (SYM) = font_intern_prop (str, 4, 1);       \
 641   } while (0)
 642 
 643 
 644 static struct OpenTypeSpec *
 645 ftfont_get_open_type_spec (Lisp_Object otf_spec)
 646 {
 647   struct OpenTypeSpec *spec = malloc (sizeof (struct OpenTypeSpec));
 648   Lisp_Object val;
 649   int i, j, negative;
 650 
 651   if (! spec)
 652     return NULL;
 653   spec->script = XCAR (otf_spec);
 654   if (! NILP (spec->script))
 655     {
 656       OTF_SYM_TAG (spec->script, spec->script_tag);
 657       val = assq_no_quit (spec->script, Votf_script_alist);
 658       if (CONSP (val) && SYMBOLP (XCDR (val)))
 659         spec->script = XCDR (val);
 660       else
 661         spec->script = Qnil;
 662     }
 663   else
 664     spec->script_tag = 0x44464C54;      /* "DFLT" */
 665   otf_spec = XCDR (otf_spec);
 666   spec->langsys_tag = 0;
 667   if (! NILP (otf_spec))
 668     {
 669       val = XCAR (otf_spec);
 670       if (! NILP (val))
 671         OTF_SYM_TAG (val, spec->langsys_tag);
 672       otf_spec = XCDR (otf_spec);
 673     }
 674   spec->nfeatures[0] = spec->nfeatures[1] = 0;
 675   for (i = 0; i < 2 && ! NILP (otf_spec); i++, otf_spec = XCDR (otf_spec))
 676     {
 677       Lisp_Object len;
 678 
 679       val = XCAR (otf_spec);
 680       if (NILP (val))
 681         continue;
 682       len = Flength (val);
 683       spec->features[i] = malloc (sizeof (int) * XINT (len));
 684       if (! spec->features[i])
 685         {
 686           if (i > 0 && spec->features[0])
 687             free (spec->features[0]);
 688           free (spec);
 689           return NULL;
 690         }
 691       for (j = 0, negative = 0; CONSP (val); val = XCDR (val))
 692         {
 693           if (NILP (XCAR (val)))
 694             negative = 1;
 695           else
 696             {
 697               unsigned int tag;
 698 
 699               OTF_SYM_TAG (XCAR (val), tag);
 700               spec->features[i][j++] = negative ? tag & 0x80000000 : tag;
 701             }
 702         }
 703       spec->nfeatures[i] = j;
 704     }
 705   return spec;
 706 }
 707 
 708 static FcPattern *ftfont_spec_pattern P_ ((Lisp_Object, char *,
 709                                            struct OpenTypeSpec **,
 710                                            char **langname));
 711 
 712 static FcPattern *
 713 ftfont_spec_pattern (spec, otlayout, otspec, langname)
 714      Lisp_Object spec;
 715      char *otlayout;
 716      struct OpenTypeSpec **otspec;
 717      char **langname;
 718 {
 719   Lisp_Object tmp, extra;
 720   FcPattern *pattern = NULL;
 721   FcCharSet *charset = NULL;
 722   FcLangSet *langset = NULL;
 723   int n;
 724   int dpi = -1;
 725   int scalable = -1;
 726   Lisp_Object script = Qnil;
 727   Lisp_Object registry;
 728   int fc_charset_idx;
 729 
 730   if ((n = FONT_SLANT_NUMERIC (spec)) >= 0
 731       && n < 100)
 732     /* Fontconfig doesn't support reverse-italic/obligue.  */
 733     return NULL;
 734 
 735   if (INTEGERP (AREF (spec, FONT_DPI_INDEX)))
 736     dpi = XINT (AREF (spec, FONT_DPI_INDEX));
 737   if (INTEGERP (AREF (spec, FONT_AVGWIDTH_INDEX))
 738       && XINT (AREF (spec, FONT_AVGWIDTH_INDEX)) == 0)
 739     scalable = 1;
 740 
 741   registry = AREF (spec, FONT_REGISTRY_INDEX);
 742   if (NILP (registry)
 743       || EQ (registry, Qascii_0)
 744       || EQ (registry, Qiso10646_1)
 745       || EQ (registry, Qunicode_bmp))
 746     fc_charset_idx = -1;
 747   else
 748     {
 749       FcChar8 *lang;
 750 
 751       fc_charset_idx = ftfont_get_charset (registry);
 752       if (fc_charset_idx < 0)
 753         return NULL;
 754       charset = fc_charset_table[fc_charset_idx].fc_charset;
 755       *langname = fc_charset_table[fc_charset_idx].lang;
 756       lang = (FcChar8 *) *langname;
 757       if (lang)
 758         {
 759           langset = FcLangSetCreate ();
 760           if (! langset)
 761             goto err;
 762           FcLangSetAdd (langset, lang);
 763         }
 764     }
 765 
 766   otlayout[0] = '\0';
 767   for (extra = AREF (spec, FONT_EXTRA_INDEX);
 768        CONSP (extra); extra = XCDR (extra))
 769     {
 770       Lisp_Object key, val;
 771 
 772       key = XCAR (XCAR (extra)), val = XCDR (XCAR (extra));
 773       if (EQ (key, QCdpi))
 774         dpi = XINT (val);
 775       else if (EQ (key, QClang))
 776         {
 777           if (! langset)
 778             langset = FcLangSetCreate ();
 779           if (! langset)
 780             goto err;
 781           if (SYMBOLP (val))
 782             {
 783               if (! FcLangSetAdd (langset, SYMBOL_FcChar8 (val)))
 784                 goto err;
 785             }
 786           else
 787             for (; CONSP (val); val = XCDR (val))
 788               if (SYMBOLP (XCAR (val))
 789                   && ! FcLangSetAdd (langset, SYMBOL_FcChar8 (XCAR (val))))
 790                 goto err;
 791         }
 792       else if (EQ (key, QCotf))
 793         {
 794           *otspec = ftfont_get_open_type_spec (val);
 795           if (! *otspec)
 796             return NULL;
 797           strcat (otlayout, "otlayout:");
 798           OTF_TAG_STR ((*otspec)->script_tag, otlayout + 9);
 799           script = (*otspec)->script;
 800         }
 801       else if (EQ (key, QCscript))
 802         script = val;
 803       else if (EQ (key, QCscalable))
 804         scalable = ! NILP (val);
 805     }
 806 
 807   if (! NILP (script) && ! charset)
 808     {
 809       Lisp_Object chars = assq_no_quit (script, Vscript_representative_chars);
 810 
 811       if (CONSP (chars) && CONSP (CDR (chars)))
 812         {
 813           charset = FcCharSetCreate ();
 814           if (! charset)
 815             goto err;
 816           for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars))
 817             if (CHARACTERP (XCAR (chars))
 818                 && ! FcCharSetAddChar (charset, XUINT (XCAR (chars))))
 819               goto err;
 820         }
 821     }
 822 
 823   pattern = FcPatternCreate ();
 824   if (! pattern)
 825     goto err;
 826   tmp = AREF (spec, FONT_FOUNDRY_INDEX);
 827   if (! NILP (tmp)
 828       && ! FcPatternAddString (pattern, FC_FOUNDRY, SYMBOL_FcChar8 (tmp)))
 829     goto err;
 830   tmp = AREF (spec, FONT_FAMILY_INDEX);
 831   if (! NILP (tmp)
 832       && ! FcPatternAddString (pattern, FC_FAMILY, SYMBOL_FcChar8 (tmp)))
 833     goto err;
 834   if (charset
 835       && ! FcPatternAddCharSet (pattern, FC_CHARSET, charset))
 836     goto err;
 837   if (langset
 838       && ! FcPatternAddLangSet (pattern, FC_LANG, langset))
 839     goto err;
 840   if (dpi >= 0
 841       && ! FcPatternAddDouble (pattern, FC_DPI, dpi))
 842     goto err;
 843   if (scalable >= 0
 844       && ! FcPatternAddBool (pattern, FC_SCALABLE, scalable ? FcTrue : FcFalse))
 845     goto err;
 846 
 847   goto finish;
 848 
 849  err:
 850   /* We come here because of unexpected error in fontconfig API call
 851      (usually insufficient memory).  */
 852   if (pattern)
 853     {
 854       FcPatternDestroy (pattern);
 855       pattern = NULL;
 856     }
 857   if (*otspec)
 858     {
 859       if ((*otspec)->nfeatures[0] > 0)
 860         free ((*otspec)->features[0]);
 861       if ((*otspec)->nfeatures[1] > 0)
 862         free ((*otspec)->features[1]);
 863       free (*otspec);
 864       *otspec = NULL;
 865     }
 866 
 867  finish:
 868   if (langset) FcLangSetDestroy (langset);
 869   if (charset && fc_charset_idx < 0) FcCharSetDestroy (charset);
 870   return pattern;
 871 }
 872 
 873 static Lisp_Object
 874 ftfont_list (frame, spec)
 875      Lisp_Object frame, spec;
 876 {
 877   Lisp_Object val = Qnil, family, adstyle;
 878   int i;
 879   FcPattern *pattern;
 880   FcFontSet *fontset = NULL;
 881   FcObjectSet *objset = NULL;
 882   FcCharSet *charset;
 883   Lisp_Object chars = Qnil;
 884   FcResult result;
 885   char otlayout[15];            /* For "otlayout:XXXX" */
 886   struct OpenTypeSpec *otspec = NULL;
 887   int spacing = -1;
 888   char *langname = NULL;
 889 
 890   if (! fc_initialized)
 891     {
 892       FcInit ();
 893       fc_initialized = 1;
 894     }
 895 
 896   pattern = ftfont_spec_pattern (spec, otlayout, &otspec, &langname);
 897   if (! pattern)
 898     return Qnil;
 899   if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) != FcResultMatch)
 900     {
 901       val = assq_no_quit (QCscript, AREF (spec, FONT_EXTRA_INDEX));
 902       if (! NILP (val))
 903         {
 904           val = assq_no_quit (XCDR (val), Vscript_representative_chars);
 905           if (CONSP (val) && VECTORP (XCDR (val)))
 906             chars = XCDR (val);
 907         }
 908       val = Qnil;
 909     }
 910   if (INTEGERP (AREF (spec, FONT_SPACING_INDEX)))
 911     spacing = XINT (AREF (spec, FONT_SPACING_INDEX));
 912   family = AREF (spec, FONT_FAMILY_INDEX);
 913   if (! NILP (family))
 914     {
 915       Lisp_Object resolved;
 916 
 917       resolved = ftfont_resolve_generic_family (family, pattern);
 918       if (! NILP (resolved))
 919         {
 920           FcPatternDel (pattern, FC_FAMILY);
 921           if (! FcPatternAddString (pattern, FC_FAMILY,
 922                                     SYMBOL_FcChar8 (resolved)))
 923             goto err;
 924         }
 925     }
 926   adstyle = AREF (spec, FONT_ADSTYLE_INDEX);
 927   if (! NILP (adstyle) && SBYTES (SYMBOL_NAME (adstyle)) == 0)
 928     adstyle = Qnil;
 929   objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT,
 930                              FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, FC_SCALABLE,
 931                              FC_STYLE, FC_FILE, FC_INDEX,
 932 #ifdef FC_CAPABILITY
 933                              FC_CAPABILITY,
 934 #endif  /* FC_CAPABILITY */
 935 #ifdef FC_FONTFORMAT
 936                              FC_FONTFORMAT,
 937 #endif
 938                              NULL);
 939   if (! objset)
 940     goto err;
 941   if (! NILP (chars))
 942     FcObjectSetAdd (objset, FC_CHARSET);
 943 
 944   fontset = FcFontList (NULL, pattern, objset);
 945   if (! fontset || fontset->nfont == 0)
 946     goto finish;
 947 #if 0
 948   /* Need fix because this finds any fonts.  */
 949   if (fontset->nfont == 0 && ! NILP (family))
 950     {
 951       /* Try maching with configuration.  For instance, the
 952          configuration may specify "Nimbus Mono L" as an alias of
 953          "Courier".  */
 954       FcPattern *pat = FcPatternBuild (0, FC_FAMILY, FcTypeString,
 955                                        SYMBOL_FcChar8 (family), NULL);
 956       FcChar8 *fam;
 957 
 958       if (FcConfigSubstitute (NULL, pat, FcMatchPattern) == FcTrue)
 959         {
 960           for (i = 0;
 961                FcPatternGetString (pat, FC_FAMILY, i, &fam) == FcResultMatch;
 962                i++)
 963             {
 964               FcPatternDel (pattern, FC_FAMILY);
 965               FcPatternAddString (pattern, FC_FAMILY, fam);
 966               FcFontSetDestroy (fontset);
 967               fontset = FcFontList (NULL, pattern, objset);
 968               if (fontset && fontset->nfont > 0)
 969                 break;
 970             }
 971         }
 972     }
 973 #endif
 974   for (i = 0; i < fontset->nfont; i++)
 975     {
 976       Lisp_Object entity;
 977 
 978       if (spacing >= 0)
 979         {
 980           int this;
 981 
 982           if ((FcPatternGetInteger (fontset->fonts[i], FC_SPACING, 0, &this)
 983                == FcResultMatch)
 984               && spacing != this)
 985             continue;
 986         }
 987 
 988 #ifdef FC_CAPABILITY
 989       if (otlayout[0])
 990         {
 991           FcChar8 *this;
 992 
 993           if (FcPatternGetString (fontset->fonts[i], FC_CAPABILITY, 0, &this)
 994               != FcResultMatch
 995               || ! strstr ((char *) this, otlayout))
 996             continue;
 997         }
 998 #endif  /* FC_CAPABILITY */
 999 #ifdef HAVE_LIBOTF
1000       if (otspec)
1001         {
1002           FcChar8 *file;
1003           OTF *otf;
1004 
1005           if (FcPatternGetString (fontset->fonts[i], FC_FILE, 0, &file)
1006               != FcResultMatch)
1007             continue;
1008           otf = OTF_open ((char *) file);
1009           if (! otf)
1010             continue;
1011           if (OTF_check_features (otf, 1,
1012                                   otspec->script_tag, otspec->langsys_tag,
1013                                   otspec->features[0],
1014                                   otspec->nfeatures[0]) != 1
1015               || OTF_check_features (otf, 0,
1016                                      otspec->script_tag, otspec->langsys_tag,
1017                                      otspec->features[1],
1018                                      otspec->nfeatures[1]) != 1)
1019             continue;
1020         }
1021 #endif  /* HAVE_LIBOTF */
1022       if (VECTORP (chars))
1023         {
1024           int j;
1025 
1026           if (FcPatternGetCharSet (fontset->fonts[i], FC_CHARSET, 0, &charset)
1027               != FcResultMatch)
1028             continue;
1029           for (j = 0; j < ASIZE (chars); j++)
1030             if (NATNUMP (AREF (chars, j))
1031                 && FcCharSetHasChar (charset, XFASTINT (AREF (chars, j))))
1032               break;
1033           if (j == ASIZE (chars))
1034             continue;
1035         }
1036       if (! NILP (adstyle) || langname)
1037         {
1038           Lisp_Object this_adstyle = get_adstyle_property (fontset->fonts[i]);
1039 
1040           if (! NILP (adstyle)
1041               && (NILP (this_adstyle)
1042                   || xstrcasecmp (SDATA (SYMBOL_NAME (adstyle)),
1043                                   SDATA (SYMBOL_NAME (this_adstyle))) != 0))
1044             continue;
1045           if (langname
1046               && ! NILP (this_adstyle)
1047               && xstrcasecmp (langname, SDATA (SYMBOL_NAME (this_adstyle))))
1048             continue;
1049         }
1050       entity = ftfont_pattern_entity (fontset->fonts[i],
1051                                       AREF (spec, FONT_EXTRA_INDEX));
1052       if (! NILP (entity))
1053         val = Fcons (entity, val);
1054     }
1055   val = Fnreverse (val);
1056   goto finish;
1057 
1058  err:
1059   /* We come here because of unexpected error in fontconfig API call
1060      (usually insufficient memory).  */
1061   val = Qnil;
1062 
1063  finish:
1064   FONT_ADD_LOG ("ftfont-list", spec, val);
1065   if (objset) FcObjectSetDestroy (objset);
1066   if (fontset) FcFontSetDestroy (fontset);
1067   if (pattern) FcPatternDestroy (pattern);
1068   return val;
1069 }
1070 
1071 static Lisp_Object
1072 ftfont_match (frame, spec)
1073      Lisp_Object frame, spec;
1074 {
1075   Lisp_Object entity = Qnil;
1076   FcPattern *pattern, *match = NULL;
1077   FcResult result;
1078   char otlayout[15];            /* For "otlayout:XXXX" */
1079   struct OpenTypeSpec *otspec = NULL;
1080   char *langname = NULL;
1081 
1082   if (! fc_initialized)
1083     {
1084       FcInit ();
1085       fc_initialized = 1;
1086     }
1087 
1088   pattern = ftfont_spec_pattern (spec, otlayout, &otspec, &langname);
1089   if (! pattern)
1090     return Qnil;
1091 
1092   if (INTEGERP (AREF (spec, FONT_SIZE_INDEX)))
1093     {
1094       FcValue value;
1095 
1096       value.type = FcTypeDouble;
1097       value.u.d = XINT (AREF (spec, FONT_SIZE_INDEX));
1098       FcPatternAdd (pattern, FC_PIXEL_SIZE, value, FcFalse);
1099     }
1100   if (FcConfigSubstitute (NULL, pattern, FcMatchPattern) == FcTrue)
1101     {
1102       FcDefaultSubstitute (pattern);
1103       match = FcFontMatch (NULL, pattern, &result);
1104       if (match)
1105         {
1106           entity = ftfont_pattern_entity (match, AREF (spec, FONT_EXTRA_INDEX));
1107           FcPatternDestroy (match);
1108           if (! NILP (AREF (spec, FONT_FAMILY_INDEX))
1109               && NILP (assq_no_quit (AREF (spec, FONT_FAMILY_INDEX),
1110                                      ftfont_generic_family_list))
1111               && NILP (Fstring_equal (AREF (spec, FONT_FAMILY_INDEX),
1112                                       AREF (entity, FONT_FAMILY_INDEX))))
1113             entity = Qnil;
1114         }
1115     }
1116   FcPatternDestroy (pattern);
1117 
1118   FONT_ADD_LOG ("ftfont-match", spec, entity);
1119   return entity;
1120 }
1121 
1122 static Lisp_Object
1123 ftfont_list_family (frame)
1124      Lisp_Object frame;
1125 {
1126   Lisp_Object list = Qnil;
1127   FcPattern *pattern = NULL;
1128   FcFontSet *fontset = NULL;
1129   FcObjectSet *objset = NULL;
1130   int i;
1131 
1132   if (! fc_initialized)
1133     {
1134       FcInit ();
1135       fc_initialized = 1;
1136     }
1137 
1138   pattern = FcPatternCreate ();
1139   if (! pattern)
1140     goto finish;
1141   objset = FcObjectSetBuild (FC_FAMILY, NULL);
1142   if (! objset)
1143     goto finish;
1144   fontset = FcFontList (NULL, pattern, objset);
1145   if (! fontset)
1146     goto finish;
1147 
1148   for (i = 0; i < fontset->nfont; i++)
1149     {
1150       FcPattern *pat = fontset->fonts[i];
1151       FcChar8 *str;
1152 
1153       if (FcPatternGetString (pat, FC_FAMILY, 0, &str) == FcResultMatch)
1154         list = Fcons (intern ((char *) str), list);
1155     }
1156 
1157  finish:
1158   if (objset) FcObjectSetDestroy (objset);
1159   if (fontset) FcFontSetDestroy (fontset);
1160   if (pattern) FcPatternDestroy (pattern);
1161 
1162   return list;
1163 }
1164 
1165 
1166 static Lisp_Object
1167 ftfont_open (f, entity, pixel_size)
1168      FRAME_PTR f;
1169      Lisp_Object entity;
1170      int pixel_size;
1171 {
1172   struct ftfont_info *ftfont_info;
1173   struct font *font;
1174   struct ftfont_cache_data *cache_data;
1175   FT_Face ft_face;
1176   FT_Size ft_size;
1177   FT_UInt size;
1178   Lisp_Object val, filename, index, cache, font_object;
1179   int scalable;
1180   int spacing;
1181   char name[256];
1182   int i, len;
1183   int upEM;
1184 
1185   val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
1186   if (! CONSP (val))
1187     return Qnil;
1188   val = XCDR (val);
1189   cache = ftfont_lookup_cache (entity, FTFONT_CACHE_FOR_FACE);
1190   if (NILP (cache))
1191     return Qnil;
1192   filename = XCAR (val);
1193   index = XCDR (val);
1194   val = XCDR (cache);
1195   cache_data = XSAVE_VALUE (XCDR (cache))->pointer;
1196   ft_face = cache_data->ft_face;
1197   if (XSAVE_VALUE (val)->integer > 0)
1198     {
1199       /* FT_Face in this cache is already used by the different size.  */
1200       if (FT_New_Size (ft_face, &ft_size) != 0)
1201         return Qnil;
1202       if (FT_Activate_Size (ft_size) != 0)
1203         {
1204           FT_Done_Size (ft_size);
1205           return Qnil;
1206         }
1207     }
1208   XSAVE_VALUE (val)->integer++;
1209   size = XINT (AREF (entity, FONT_SIZE_INDEX));
1210   if (size == 0)
1211     size = pixel_size;
1212   if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0)
1213     {
1214       if (XSAVE_VALUE (val)->integer == 0)
1215         FT_Done_Face (ft_face);
1216       return Qnil;
1217     }
1218 
1219   font_object = font_make_object (VECSIZE (struct ftfont_info), entity, size);
1220   ASET (font_object, FONT_TYPE_INDEX, Qfreetype);
1221   len = font_unparse_xlfd (entity, size, name, 256);
1222   if (len > 0)
1223     ASET (font_object, FONT_NAME_INDEX, make_string (name, len));
1224   len = font_unparse_fcname (entity, size, name, 256);
1225   if (len > 0)
1226     ASET (font_object, FONT_FULLNAME_INDEX, make_string (name, len));
1227   else
1228     ASET (font_object, FONT_FULLNAME_INDEX,
1229           AREF (font_object, FONT_NAME_INDEX));
1230   ASET (font_object, FONT_FILE_INDEX, filename);
1231   ASET (font_object, FONT_FORMAT_INDEX, ftfont_font_format (NULL, filename));
1232   font = XFONT_OBJECT (font_object);
1233   ftfont_info = (struct ftfont_info *) font;
1234   ftfont_info->ft_size = ft_face->size;
1235   ftfont_info->index = XINT (index);
1236 #ifdef HAVE_LIBOTF
1237   ftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT;
1238   ftfont_info->otf = NULL;
1239 #endif  /* HAVE_LIBOTF */
1240   /* This means that there's no need of transformation.  */
1241   ftfont_info->matrix.xx = 0;
1242   font->pixel_size = size;
1243   font->driver = &ftfont_driver;
1244   font->encoding_charset = font->repertory_charset = -1;
1245 
1246   upEM = ft_face->units_per_EM;
1247   scalable = (INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX))
1248               && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0);
1249   if (scalable)
1250     {
1251       font->ascent = ft_face->ascender * size / upEM;
1252       font->descent = - ft_face->descender * size / upEM;
1253       font->height = ft_face->height * size / upEM;
1254     }
1255   else
1256     {
1257       font->ascent = ft_face->size->metrics.ascender >> 6;
1258       font->descent = - ft_face->size->metrics.descender >> 6;
1259       font->height = ft_face->size->metrics.height >> 6;
1260     }
1261   if (INTEGERP (AREF (entity, FONT_SPACING_INDEX)))
1262     spacing = XINT (AREF (entity, FONT_SPACING_INDEX));
1263   else
1264     spacing = FC_PROPORTIONAL;
1265   if (spacing != FC_PROPORTIONAL)
1266     font->min_width = font->average_width = font->space_width
1267       = (scalable ? ft_face->max_advance_width * size / upEM
1268          : ft_face->size->metrics.max_advance >> 6);
1269   else
1270     {
1271       int n;
1272 
1273       font->min_width = font->average_width = font->space_width = 0;
1274       for (i = 32, n = 0; i < 127; i++)
1275         if (FT_Load_Char (ft_face, i, FT_LOAD_DEFAULT) == 0)
1276           {
1277             int this_width = ft_face->glyph->metrics.horiAdvance >> 6;
1278 
1279             if (this_width > 0
1280                 && (! font->min_width || font->min_width > this_width))
1281               font->min_width = this_width;
1282             if (i == 32)
1283               font->space_width = this_width;
1284             font->average_width += this_width;
1285             n++;
1286           }
1287       if (n > 0)
1288         font->average_width /= n;
1289     }
1290 
1291   font->baseline_offset = 0;
1292   font->relative_compose = 0;
1293   font->default_ascent = 0;
1294   font->vertical_centering = 0;
1295   if (scalable)
1296     {
1297       font->underline_position = -ft_face->underline_position * size / upEM;
1298       font->underline_thickness = ft_face->underline_thickness * size / upEM;
1299     }
1300   else
1301     {
1302       font->underline_position = -1;
1303       font->underline_thickness = 0;
1304     }
1305 
1306   return font_object;
1307 }
1308 
1309 static void
1310 ftfont_close (f, font)
1311      FRAME_PTR f;
1312      struct font *font;
1313 {
1314   struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
1315   Lisp_Object val, cache;
1316 
1317   val = Fcons (font->props[FONT_FILE_INDEX], make_number (ftfont_info->index));
1318   cache = ftfont_lookup_cache (val, FTFONT_CACHE_FOR_FACE);
1319   xassert (CONSP (cache));
1320   val = XCDR (cache);
1321   (XSAVE_VALUE (val)->integer)--;
1322   if (XSAVE_VALUE (val)->integer == 0)
1323     {
1324       struct ftfont_cache_data *cache_data = XSAVE_VALUE (val)->pointer;
1325 
1326       FT_Done_Face (cache_data->ft_face);
1327 #ifdef HAVE_LIBOTF
1328       if (ftfont_info->otf)
1329         OTF_close (ftfont_info->otf);
1330 #endif
1331       cache_data->ft_face = NULL;
1332     }
1333   else
1334     FT_Done_Size (ftfont_info->ft_size);
1335 }
1336 
1337 static int
1338 ftfont_has_char (font, c)
1339      Lisp_Object font;
1340      int c;
1341 {
1342   struct charset *cs = NULL;
1343 
1344   if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qja)
1345       && charset_jisx0208 >= 0)
1346     cs = CHARSET_FROM_ID (charset_jisx0208);
1347   else if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qko)
1348       && charset_ksc5601 >= 0)
1349     cs = CHARSET_FROM_ID (charset_ksc5601);
1350   if (cs)
1351     return (ENCODE_CHAR (cs, c) != CHARSET_INVALID_CODE (cs));
1352 
1353   if (FONT_ENTITY_P (font))
1354     {
1355       FcCharSet *charset = ftfont_get_fc_charset (font);
1356 
1357       return (FcCharSetHasChar (charset, c) == FcTrue);
1358     }
1359   else
1360     {
1361       struct ftfont_info *ftfont_info;
1362 
1363       ftfont_info = (struct ftfont_info *) XFONT_OBJECT (font);
1364       return (FT_Get_Char_Index (ftfont_info->ft_size->face, (FT_ULong) c)
1365               != 0);
1366     }
1367 }
1368 
1369 static unsigned
1370 ftfont_encode_char (font, c)
1371      struct font *font;
1372      int c;
1373 {
1374   struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
1375   FT_Face ft_face = ftfont_info->ft_size->face;
1376   FT_ULong charcode = c;
1377   FT_UInt code = FT_Get_Char_Index (ft_face, charcode);
1378 
1379   return (code > 0 ? code : FONT_INVALID_CODE);
1380 }
1381 
1382 static int
1383 ftfont_text_extents (font, code, nglyphs, metrics)
1384      struct font *font;
1385      unsigned *code;
1386      int nglyphs;
1387      struct font_metrics *metrics;
1388 {
1389   struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
1390   FT_Face ft_face = ftfont_info->ft_size->face;
1391   int width = 0;
1392   int i, first;
1393 
1394   if (ftfont_info->ft_size != ft_face->size)
1395     FT_Activate_Size (ftfont_info->ft_size);
1396   if (metrics)
1397     bzero (metrics, sizeof (struct font_metrics));
1398   for (i = 0, first = 1; i < nglyphs; i++)
1399     {
1400       if (FT_Load_Glyph (ft_face, code[i], FT_LOAD_DEFAULT) == 0)
1401         {
1402           FT_Glyph_Metrics *m = &ft_face->glyph->metrics;
1403 
1404           if (first)
1405             {
1406               if (metrics)
1407                 {
1408                   metrics->lbearing = m->horiBearingX >> 6;
1409                   metrics->rbearing = (m->horiBearingX + m->width) >> 6;
1410                   metrics->ascent = m->horiBearingY >> 6;
1411                   metrics->descent = (m->height - m->horiBearingY) >> 6;
1412                 }
1413               first = 0;
1414             }
1415           if (metrics)
1416             {
1417               if (metrics->lbearing > width + (m->horiBearingX >> 6))
1418                 metrics->lbearing = width + (m->horiBearingX >> 6);
1419               if (metrics->rbearing
1420                   < width + ((m->horiBearingX + m->width) >> 6))
1421                 metrics->rbearing
1422                   = width + ((m->horiBearingX + m->width) >> 6);
1423               if (metrics->ascent < (m->horiBearingY >> 6))
1424                 metrics->ascent = m->horiBearingY >> 6;
1425               if (metrics->descent > ((m->height - m->horiBearingY) >> 6))
1426                 metrics->descent = (m->height - m->horiBearingY) >> 6;
1427             }
1428           width += m->horiAdvance >> 6;
1429         }
1430       else
1431         {
1432           width += font->space_width;
1433         }
1434     }
1435   if (metrics)
1436     metrics->width = width;
1437 
1438   return width;
1439 }
1440 
1441 static int
1442 ftfont_get_bitmap (font, code, bitmap, bits_per_pixel)
1443      struct font *font;
1444      unsigned code;
1445      struct font_bitmap *bitmap;
1446      int bits_per_pixel;
1447 {
1448   struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
1449   FT_Face ft_face = ftfont_info->ft_size->face;
1450   FT_Int32 load_flags = FT_LOAD_RENDER;
1451 
1452   if (ftfont_info->ft_size != ft_face->size)
1453     FT_Activate_Size (ftfont_info->ft_size);
1454   if (bits_per_pixel == 1)
1455     {
1456 #ifdef FT_LOAD_TARGET_MONO
1457       load_flags |= FT_LOAD_TARGET_MONO;
1458 #else
1459       load_flags |= FT_LOAD_MONOCHROME;
1460 #endif
1461     }
1462   else if (bits_per_pixel != 8)
1463     /* We don't support such a rendering.  */
1464     return -1;
1465 
1466   if (FT_Load_Glyph (ft_face, code, load_flags) != 0)
1467     return -1;
1468   bitmap->bits_per_pixel
1469     = (ft_face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO ? 1
1470        : ft_face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY ? 8
1471        : ft_face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD ? 8
1472        : ft_face->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD_V ? 8
1473        : -1);
1474   if (bitmap->bits_per_pixel < 0)
1475     /* We don't suport that kind of pixel mode.  */
1476     return -1;
1477   bitmap->rows = ft_face->glyph->bitmap.rows;
1478   bitmap->width = ft_face->glyph->bitmap.width;
1479   bitmap->pitch = ft_face->glyph->bitmap.pitch;
1480   bitmap->buffer = ft_face->glyph->bitmap.buffer;
1481   bitmap->left = ft_face->glyph->bitmap_left;
1482   bitmap->top = ft_face->glyph->bitmap_top;
1483   bitmap->advance = ft_face->glyph->metrics.horiAdvance >> 6;
1484   bitmap->extra = NULL;
1485 
1486   return 0;
1487 }
1488 
1489 static int
1490 ftfont_anchor_point (font, code, index, x, y)
1491      struct font *font;
1492      unsigned code;
1493      int index;
1494      int *x, *y;
1495 {
1496   struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
1497   FT_Face ft_face = ftfont_info->ft_size->face;
1498 
1499   if (ftfont_info->ft_size != ft_face->size)
1500     FT_Activate_Size (ftfont_info->ft_size);
1501   if (FT_Load_Glyph (ft_face, code, FT_LOAD_DEFAULT) != 0)
1502     return -1;
1503   if (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
1504     return -1;
1505   if (index >= ft_face->glyph->outline.n_points)
1506     return -1;
1507   *x = ft_face->glyph->outline.points[index].x;
1508   *y = ft_face->glyph->outline.points[index].y;
1509   return 0;
1510 }
1511 
1512 #ifdef HAVE_LIBOTF
1513 
1514 static Lisp_Object
1515 ftfont_otf_features (gsub_gpos)
1516      OTF_GSUB_GPOS *gsub_gpos;
1517 {
1518   Lisp_Object scripts, langsyses, features, sym;
1519   int i, j, k, l;
1520 
1521   for (scripts = Qnil, i = gsub_gpos->ScriptList.ScriptCount - 1; i >= 0; i--)
1522     {
1523       OTF_Script *otf_script = gsub_gpos->ScriptList.Script + i;
1524 
1525       for (langsyses = Qnil, j = otf_script->LangSysCount - 1; j >= -1; j--)
1526         {
1527           OTF_LangSys *otf_langsys;
1528 
1529           if (j >= 0)
1530             otf_langsys = otf_script->LangSys + j;
1531           else if (otf_script->DefaultLangSysOffset)
1532             otf_langsys = &otf_script->DefaultLangSys;
1533           else
1534             break;
1535 
1536           for (features = Qnil, k = otf_langsys->FeatureCount - 1; k >= 0; k--)
1537             {
1538               l = otf_langsys->FeatureIndex[k];
1539               if (l >= gsub_gpos->FeatureList.FeatureCount)
1540                 continue;
1541               OTF_TAG_SYM (sym, gsub_gpos->FeatureList.Feature[l].FeatureTag);
1542               features = Fcons (sym, features);
1543             }
1544           if (j >= 0)
1545             OTF_TAG_SYM (sym, otf_script->LangSysRecord[j].LangSysTag);
1546           else
1547             sym = Qnil;
1548           langsyses = Fcons (Fcons (sym, features), langsyses);
1549         }
1550 
1551       OTF_TAG_SYM (sym, gsub_gpos->ScriptList.Script[i].ScriptTag);
1552       scripts = Fcons (Fcons (sym, langsyses), scripts);
1553     }
1554   return scripts;
1555 
1556 }
1557 
1558 
1559 static Lisp_Object
1560 ftfont_otf_capability (font)
1561      struct font *font;
1562 {
1563   struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
1564   OTF *otf = ftfont_get_otf (ftfont_info);
1565   Lisp_Object gsub_gpos;
1566 
1567   if (! otf)
1568     return Qnil;
1569   gsub_gpos = Fcons (Qnil, Qnil);
1570   if (OTF_get_table (otf, "GSUB") == 0
1571       && otf->gsub->FeatureList.FeatureCount > 0)
1572     XSETCAR (gsub_gpos, ftfont_otf_features (otf->gsub));
1573   if (OTF_get_table (otf, "GPOS") == 0
1574       && otf->gpos->FeatureList.FeatureCount > 0)
1575     XSETCDR (gsub_gpos, ftfont_otf_features (otf->gpos));
1576   return gsub_gpos;
1577 }
1578 
1579 #ifdef HAVE_M17N_FLT
1580 
1581 #if (((LIBOTF_MAJOR_VERSION > 1) || (LIBOTF_RELEASE_NUMBER >= 10))      \
1582      && ((M17NLIB_MAJOR_VERSION > 1) || (M17NLIB_MINOR_VERSION >= 6)))
1583 /* We can use the new feature of libotf and m17n-flt to handle the
1584    character encoding scheme introduced in Unicode 5.1 and 5.2 for
1585    some Agian scripts.  */
1586 #define M17N_FLT_USE_NEW_FEATURE
1587 #endif
1588 
1589 struct MFLTFontFT
1590 {
1591   MFLTFont flt_font;
1592   struct font *font;
1593   FT_Face ft_face;
1594   OTF *otf;
1595   FT_Matrix *matrix;
1596 };
1597 
1598 static int
1599 ftfont_get_glyph_id (font, gstring, from, to)
1600      MFLTFont *font;
1601      MFLTGlyphString *gstring;
1602      int from, to;
1603 {
1604   struct MFLTFontFT *flt_font_ft = (struct MFLTFontFT *) font;
1605   FT_Face ft_face = flt_font_ft->ft_face;
1606   MFLTGlyph *g;
1607 
1608   for (g = gstring->glyphs + from; from < to; g++, from++)
1609     if (! g->encoded)
1610       {
1611         FT_UInt code = FT_Get_Char_Index (ft_face, g->code);
1612 
1613         g->code = code > 0 ? code : FONT_INVALID_CODE;
1614         g->encoded = 1;
1615       }
1616   return 0;
1617 }
1618 
1619 /* Operators for 26.6 fixed fractional pixel format */
1620 
1621 #define FLOOR(x)    ((x) & -64)
1622 #define CEIL(x)     (((x)+63) & -64)
1623 #define ROUND(x)    (((x)+32) & -64)
1624 
1625 static int
1626 ftfont_get_metrics (font, gstring, from, to)
1627      MFLTFont *font;
1628      MFLTGlyphString *gstring;
1629      int from, to;
1630 {
1631   struct MFLTFontFT *flt_font_ft = (struct MFLTFontFT *) font;
1632   FT_Face ft_face = flt_font_ft->ft_face;
1633   MFLTGlyph *g;
1634 
1635   for (g = gstring->glyphs + from; from < to; g++, from++)
1636     if (! g->measured)
1637       {
1638         if (g->code != FONT_INVALID_CODE)
1639           {
1640             FT_Glyph_Metrics *m;
1641             int lbearing, rbearing, ascent, descent, xadv;
1642 
1643             if (FT_Load_Glyph (ft_face, g->code, FT_LOAD_DEFAULT) != 0)
1644               abort ();
1645             m = &ft_face->glyph->metrics;
1646             if (flt_font_ft->matrix)
1647               {
1648                 FT_Vector v[4];
1649                 int i;
1650 
1651                 v[0].x = v[1].x = m->horiBearingX;
1652                 v[2].x = v[3].x = m->horiBearingX + m->width;
1653                 v[0].y = v[2].y = m->horiBearingY;
1654                 v[1].y = v[3].y = m->horiBearingY - m->height;
1655                 for (i = 0; i < 4; i++)
1656                   FT_Vector_Transform (v + i, flt_font_ft->matrix);
1657                 g->lbearing = v[0].x < v[1].x ? FLOOR (v[0].x) : FLOOR (v[1].x);
1658                 g->rbearing = v[2].x > v[3].x ? CEIL (v[2].x) : CEIL (v[3].x);
1659                 g->ascent = v[0].y > v[2].y ? CEIL (v[0].y) : CEIL (v[2].y);
1660                 g->descent = v[1].y < v[3].y ? - FLOOR (v[1].y) : - FLOOR (v[3].y);
1661               }
1662             else
1663               {
1664                 g->lbearing = FLOOR (m->horiBearingX);
1665                 g->rbearing = CEIL (m->horiBearingX + m->width);
1666                 g->ascent = CEIL (m->horiBearingY);
1667                 g->descent = - FLOOR (m->horiBearingY - m->height);
1668               }
1669             g->xadv = ROUND (ft_face->glyph->advance.x);
1670           }
1671         else
1672           {
1673             g->lbearing = 0;
1674             g->rbearing = g->xadv = flt_font_ft->font->space_width << 6;
1675             g->ascent = flt_font_ft->font->ascent << 6;
1676             g->descent = flt_font_ft->font->descent << 6;
1677           }
1678         g->yadv = 0;
1679         g->measured = 1;
1680       }
1681   return 0;
1682 }
1683 
1684 static int
1685 ftfont_check_otf (MFLTFont *font, MFLTOtfSpec *spec)
1686 {
1687   struct MFLTFontFT *flt_font_ft = (struct MFLTFontFT *) font;
1688   OTF *otf = flt_font_ft->otf;
1689   OTF_Tag *tags;
1690   int i, n, negative;
1691 
1692   for (i = 0; i < 2; i++)
1693     {
1694       if (! spec->features[i])
1695         continue;
1696       for (n = 0; spec->features[i][n]; n++);
1697       tags = alloca (sizeof (OTF_Tag) * n);
1698       for (n = 0, negative = 0; spec->features[i][n]; n++)
1699         {
1700           if (spec->features[i][n] == 0xFFFFFFFF)
1701             negative = 1;
1702           else if (negative)
1703             tags[n - 1] = spec->features[i][n] | 0x80000000;
1704           else
1705             tags[n] = spec->features[i][n];
1706         }
1707 #ifdef M17N_FLT_USE_NEW_FEATURE
1708       if (OTF_check_features (otf, i == 0, spec->script, spec->langsys,
1709                               tags, n - negative) != 1)
1710         return 0;
1711 #else  /* not M17N_FLT_USE_NEW_FEATURE */
1712       if (n - negative > 0
1713           && OTF_check_features (otf, i == 0, spec->script, spec->langsys,
1714                                  tags, n - negative) != 1)
1715         return 0;
1716 #endif  /* not M17N_FLT_USE_NEW_FEATURE */
1717     }
1718   return 1;
1719 }
1720 
1721 #define DEVICE_DELTA(table, size)                               \
1722   (((size) >= (table).StartSize && (size) <= (table).EndSize)   \
1723    ? (table).DeltaValue[(size) - (table).StartSize] << 6        \
1724    : 0)
1725 
1726 static void
1727 adjust_anchor (FT_Face ft_face, OTF_Anchor *anchor,
1728                unsigned code, int x_ppem, int y_ppem, int *x, int *y)
1729 {
1730   if (anchor->AnchorFormat == 2)
1731     {
1732       FT_Outline *outline;
1733       int ap = anchor->f.f1.AnchorPoint;
1734 
1735       FT_Load_Glyph (ft_face, (FT_UInt) code, FT_LOAD_MONOCHROME);
1736       outline = &ft_face->glyph->outline;
1737       if (ap < outline->n_points)
1738         {
1739           *x = outline->points[ap].x << 6;
1740           *y = outline->points[ap].y << 6;
1741         }
1742     }
1743   else if (anchor->AnchorFormat == 3)
1744     {
1745       if (anchor->f.f2.XDeviceTable.offset
1746           && anchor->f.f2.XDeviceTable.DeltaValue)
1747         *x += DEVICE_DELTA (anchor->f.f2.XDeviceTable, x_ppem);
1748       if (anchor->f.f2.YDeviceTable.offset
1749           && anchor->f.f2.YDeviceTable.DeltaValue)
1750         *y += DEVICE_DELTA (anchor->f.f2.YDeviceTable, y_ppem);
1751     }
1752 }
1753 
1754 static OTF_GlyphString otf_gstring;
1755 
1756 static void
1757 setup_otf_gstring (int size)
1758 {
1759   if (otf_gstring.size == 0)
1760     {
1761       otf_gstring.glyphs = (OTF_Glyph *) xmalloc (sizeof (OTF_Glyph) * size);
1762       otf_gstring.size = size;
1763     }
1764   else if (otf_gstring.size < size)
1765     {
1766       otf_gstring.glyphs = xrealloc (otf_gstring.glyphs,
1767                                      sizeof (OTF_Glyph) * size);
1768       otf_gstring.size = size;
1769     }
1770   otf_gstring.used = size;
1771   memset (otf_gstring.glyphs, 0, sizeof (OTF_Glyph) * size);
1772 }
1773 
1774 #ifdef M17N_FLT_USE_NEW_FEATURE
1775 
1776 /* Pack 32-bit OTF tag (0x7F7F7F7F) into 28-bit (0x0FFFFFFF).  */
1777 #define PACK_OTF_TAG(TAG)       \
1778   ((((TAG) & 0x7F000000) >> 3)  \
1779     | (((TAG) & 0x7F0000) >> 2) \
1780     | (((TAG) & 0x7F00) >> 1)   \
1781     | ((TAG) & 0x7F))
1782 
1783 /* Assuming that FONT is an OpenType font, apply OpenType features
1784    specified in SPEC on glyphs between FROM and TO of IN, and record
1785    the lastly applied feature in each glyph of IN.  If OUT is not
1786    NULL, append the resulting glyphs to OUT while storing glyph
1787    position adjustment information in ADJUSTMENT.  */
1788 
1789 static int
1790 ftfont_drive_otf (font, spec, in, from, to, out, adjustment)
1791      MFLTFont *font;
1792      MFLTOtfSpec *spec;
1793      MFLTGlyphString *in;
1794      int from, to;
1795      MFLTGlyphString *out;
1796      MFLTGlyphAdjustment *adjustment;
1797 {
1798   struct MFLTFontFT *flt_font_ft = (struct MFLTFontFT *) font;
1799   FT_Face ft_face = flt_font_ft->ft_face;
1800   OTF *otf = flt_font_ft->otf;
1801   int len = to - from;
1802   int i, j, gidx;
1803   OTF_Glyph *otfg;
1804   char script[5], *langsys = NULL;
1805   char *gsub_features = NULL, *gpos_features = NULL;
1806   OTF_Feature *features;
1807 
1808   if (len == 0)
1809     return from;
1810   OTF_tag_name (spec->script, script);
1811   if (spec->langsys)
1812     {
1813       langsys = alloca (5);
1814       OTF_tag_name (spec->langsys, langsys);
1815     }
1816   for (i = 0; i < 2; i++)
1817     {
1818       char *p;
1819 
1820       if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF)
1821         {
1822           for (j = 0; spec->features[i][j]; j++);
1823           if (i == 0)
1824             p = gsub_features = alloca (6 * j);
1825           else
1826             p = gpos_features = alloca (6 * j);
1827           for (j = 0; spec->features[i][j]; j++)
1828             {
1829               if (spec->features[i][j] == 0xFFFFFFFF)
1830                 *p++ = '*', *p++ = ',';
1831               else
1832                 {
1833                   OTF_tag_name (spec->features[i][j], p);
1834                   p[4] = ',';
1835                   p += 5;
1836                 }
1837             }
1838           *--p = '\0';
1839         }
1840     }
1841 
1842   setup_otf_gstring (len);
1843   for (i = 0; i < len; i++)
1844     {
1845       otf_gstring.glyphs[i].c = in->glyphs[from + i].c;
1846       otf_gstring.glyphs[i].glyph_id = in->glyphs[from + i].code;
1847     }
1848 
1849   OTF_drive_gdef (otf, &otf_gstring);
1850   gidx = out ? out->used : from;
1851 
1852   if (gsub_features && out)
1853     {
1854       if (OTF_drive_gsub_with_log (otf, &otf_gstring, script, langsys,
1855                                    gsub_features) < 0)
1856         goto simple_copy;
1857       if (out->allocated < out->used + otf_gstring.used)
1858         return -2;
1859       features = otf->gsub->FeatureList.Feature;
1860       for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; )
1861         {
1862           MFLTGlyph *g;
1863           int min_from, max_to;
1864           int j;
1865           int feature_idx = otfg->positioning_type >> 4;
1866 
1867           g = out->glyphs + out->used;
1868           *g = in->glyphs[from + otfg->f.index.from];
1869           if (g->code != otfg->glyph_id)
1870             {
1871               g->c = 0;
1872               g->code = otfg->glyph_id;
1873               g->measured = 0;
1874             }
1875           out->used++;
1876           min_from = g->from;
1877           max_to = g->to;
1878           if (otfg->f.index.from < otfg->f.index.to)
1879             {
1880               /* OTFG substitutes multiple glyphs in IN.  */
1881               for (j = from + otfg->f.index.from + 1;
1882                    j <= from + otfg->f.index.to; j++)
1883                 {
1884                   if (min_from > in->glyphs[j].from)
1885                     min_from = in->glyphs[j].from;
1886                   if (max_to < in->glyphs[j].to)
1887                     max_to = in->glyphs[j].to;
1888                 }
1889               g->from = min_from;
1890               g->to = max_to;
1891             }
1892           if (feature_idx)
1893             {
1894               unsigned int tag = features[feature_idx - 1].FeatureTag;
1895               tag = PACK_OTF_TAG (tag);
1896               g->internal = (g->internal & ~0x1FFFFFFF) | tag;
1897             }
1898           for (i++, otfg++; (i < otf_gstring.used
1899                              && otfg->f.index.from == otfg[-1].f.index.from);
1900                i++, otfg++)
1901             {
1902               g = out->glyphs + out->used;
1903               *g = in->glyphs[from + otfg->f.index.to];
1904               if (g->code != otfg->glyph_id)
1905                 {
1906                   g->c = 0;
1907                   g->code = otfg->glyph_id;
1908                   g->measured = 0;
1909                 }
1910               feature_idx = otfg->positioning_type >> 4;
1911               if (feature_idx)
1912                 {
1913                   unsigned int tag = features[feature_idx - 1].FeatureTag;
1914                   tag = PACK_OTF_TAG (tag);
1915                   g->internal = (g->internal & ~0x1FFFFFFF) | tag;
1916                 }
1917               out->used++;
1918             }
1919         }
1920     }
1921   else if (gsub_features)
1922     {
1923       /* Just for checking which features will be applied.  */
1924       if (OTF_drive_gsub_with_log (otf, &otf_gstring, script, langsys,
1925                                    gsub_features) < 0)
1926         goto simple_copy;
1927       features = otf->gsub->FeatureList.Feature;
1928       for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; i++,
1929              otfg++)
1930         {
1931           int feature_idx = otfg->positioning_type >> 4;
1932 
1933           if (feature_idx)
1934             {
1935               unsigned int tag = features[feature_idx - 1].FeatureTag;
1936               tag = PACK_OTF_TAG (tag);
1937               for (j = otfg->f.index.from; j <= otfg->f.index.to; j++)
1938                 {
1939                   MFLTGlyph *g = in->glyphs + (from + j);
1940                   g->internal = (g->internal & ~0x1FFFFFFF) | tag;
1941                 }
1942             }
1943         }
1944     }
1945   else if (out)
1946     {
1947       if (out->allocated < out->used + len)
1948         return -2;
1949       for (i = 0; i < len; i++)
1950         out->glyphs[out->used++] = in->glyphs[from + i];
1951     }
1952 
1953   if (gpos_features && out)
1954     {
1955       MFLTGlyph *base = NULL, *mark = NULL, *g;
1956       int x_ppem, y_ppem, x_scale, y_scale;
1957 
1958       if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys,
1959                                    gpos_features) < 0)
1960         return to;
1961       features = otf->gpos->FeatureList.Feature;
1962       x_ppem = ft_face->size->metrics.x_ppem;
1963       y_ppem = ft_face->size->metrics.y_ppem;
1964       x_scale = ft_face->size->metrics.x_scale;
1965       y_scale = ft_face->size->metrics.y_scale;
1966 
1967       for (i = 0, otfg = otf_gstring.glyphs, g = out->glyphs + gidx;
1968            i < otf_gstring.used; i++, otfg++, g++)
1969         {
1970           MFLTGlyph *prev;
1971           int feature_idx = otfg->positioning_type >> 4;
1972 
1973           if (feature_idx)
1974             {
1975               unsigned int tag = features[feature_idx - 1].FeatureTag;
1976               tag = PACK_OTF_TAG (tag);
1977               g->internal = (g->internal & ~0x1FFFFFFF) | tag;
1978             }
1979 
1980           if (! otfg->glyph_id)
1981             continue;
1982           switch (otfg->positioning_type & 0xF)
1983             {
1984             case 0:
1985               break;
1986             case 1:             /* Single */
1987             case 2:             /* Pair */
1988               {
1989                 int format = otfg->f.f1.format;
1990 
1991                 if (format & OTF_XPlacement)
1992                   adjustment[i].xoff
1993                     = otfg->f.f1.value->XPlacement * x_scale / 0x10000;
1994                 if (format & OTF_XPlaDevice)
1995                   adjustment[i].xoff
1996                     += DEVICE_DELTA (otfg->f.f1.value->XPlaDevice, x_ppem);
1997                 if (format & OTF_YPlacement)
1998                   adjustment[i].yoff
1999                     = - (otfg->f.f1.value->YPlacement * y_scale / 0x10000);
2000                 if (format & OTF_YPlaDevice)
2001                   adjustment[i].yoff
2002                     -= DEVICE_DELTA (otfg->f.f1.value->YPlaDevice, y_ppem);
2003                 if (format & OTF_XAdvance)
2004                   adjustment[i].xadv
2005                     += otfg->f.f1.value->XAdvance * x_scale / 0x10000;
2006                 if (format & OTF_XAdvDevice)
2007                   adjustment[i].xadv
2008                     += DEVICE_DELTA (otfg->f.f1.value->XAdvDevice, x_ppem);
2009                 if (format & OTF_YAdvance)
2010                   adjustment[i].yadv
2011                     += otfg->f.f1.value->YAdvance * y_scale / 0x10000;
2012                 if (format & OTF_YAdvDevice)
2013                   adjustment[i].yadv
2014                     += DEVICE_DELTA (otfg->f.f1.value->YAdvDevice, y_ppem);
2015                 adjustment[i].set = 1;
2016               }
2017               break;
2018             case 3:             /* Cursive */
2019               /* Not yet supported.  */
2020               break;
2021             case 4:             /* Mark-to-Base */
2022             case 5:             /* Mark-to-Ligature */
2023               if (! base)
2024                 break;
2025               prev = base;
2026               goto label_adjust_anchor;
2027             default:            /* i.e. case 6 Mark-to-Mark */
2028               if (! mark)
2029                 break;
2030               prev = mark;
2031 
2032             label_adjust_anchor:
2033               {
2034                 int base_x, base_y, mark_x, mark_y;
2035                 int this_from, this_to;
2036 
2037                 base_x = otfg->f.f4.base_anchor->XCoordinate * x_scale / 0x10000;
2038                 base_y = otfg->f.f4.base_anchor->YCoordinate * y_scale / 0x10000;
2039                 mark_x = otfg->f.f4.mark_anchor->XCoordinate * x_scale / 0x10000;
2040                 mark_y = otfg->f.f4.mark_anchor->YCoordinate * y_scale / 0x10000;
2041 
2042                 if (otfg->f.f4.base_anchor->AnchorFormat != 1)
2043                   adjust_anchor (ft_face, otfg->f.f4.base_anchor,
2044                                  prev->code, x_ppem, y_ppem, &base_x, &base_y);
2045                 if (otfg->f.f4.mark_anchor->AnchorFormat != 1)
2046                   adjust_anchor (ft_face, otfg->f.f4.mark_anchor, g->code,
2047                                  x_ppem, y_ppem, &mark_x, &mark_y);
2048                 adjustment[i].xoff = (base_x - mark_x);
2049                 adjustment[i].yoff = - (base_y - mark_y);
2050                 adjustment[i].back = (g - prev);
2051                 adjustment[i].xadv = 0;
2052                 adjustment[i].advance_is_absolute = 1;
2053                 adjustment[i].set = 1;
2054                 this_from = g->from;
2055                 this_to = g->to;
2056                 for (j = 0; prev + j < g; j++)
2057                   {
2058                     if (this_from > prev[j].from)
2059                       this_from = prev[j].from;
2060                     if (this_to < prev[j].to)
2061                       this_to = prev[j].to;
2062                   }
2063                 for (; prev <= g; prev++)
2064                   {
2065                     prev->from = this_from;
2066                     prev->to = this_to;
2067                   }
2068               }
2069             }
2070           if (otfg->GlyphClass == OTF_GlyphClass0)
2071             base = mark = g;
2072           else if (otfg->GlyphClass == OTF_GlyphClassMark)
2073             mark = g;
2074           else
2075             base = g;
2076         }
2077     }
2078   else if (gpos_features)
2079     {
2080       if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys,
2081                                    gpos_features) < 0)
2082         return to;
2083       features = otf->gpos->FeatureList.Feature;
2084       for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used;
2085            i++, otfg++)
2086         if (otfg->positioning_type & 0xF)
2087           {
2088             int feature_idx = otfg->positioning_type >> 4;
2089 
2090             if (feature_idx)
2091               {
2092                 unsigned int tag = features[feature_idx - 1].FeatureTag;
2093                 tag = PACK_OTF_TAG (tag);
2094                 for (j = otfg->f.index.from; j <= otfg->f.index.to; j++)
2095                   {
2096                     MFLTGlyph *g = in->glyphs + (from + j);
2097                     g->internal = (g->internal & ~0x1FFFFFFF) | tag;
2098                   }
2099               }
2100           }
2101     }
2102   return to;
2103 
2104  simple_copy:
2105   if (! out)
2106     return to;
2107   if (out->allocated < out->used + len)
2108     return -2;
2109   font->get_metrics (font, in, from, to);
2110   memcpy (out->glyphs + out->used, in->glyphs + from,
2111           sizeof (MFLTGlyph) * len);
2112   out->used += len;
2113   return to;
2114 }
2115 
2116 static int 
2117 ftfont_try_otf (MFLTFont *font, MFLTOtfSpec *spec,
2118                 MFLTGlyphString *in, int from, int to)
2119 {
2120   return ftfont_drive_otf (font, spec, in, from, to, NULL, NULL);
2121 }
2122 
2123 #else  /* not M17N_FLT_USE_NEW_FEATURE */
2124 
2125 static int
2126 ftfont_drive_otf (font, spec, in, from, to, out, adjustment)
2127      MFLTFont *font;
2128      MFLTOtfSpec *spec;
2129      MFLTGlyphString *in;
2130      int from, to;
2131      MFLTGlyphString *out;
2132      MFLTGlyphAdjustment *adjustment;
2133 {
2134   struct MFLTFontFT *flt_font_ft = (struct MFLTFontFT *) font;
2135   FT_Face ft_face = flt_font_ft->ft_face;
2136   OTF *otf = flt_font_ft->otf;
2137   int len = to - from;
2138   int i, j, gidx;
2139   OTF_Glyph *otfg;
2140   char script[5], *langsys = NULL;
2141   char *gsub_features = NULL, *gpos_features = NULL;
2142 
2143   if (len == 0)
2144     return from;
2145   OTF_tag_name (spec->script, script);
2146   if (spec->langsys)
2147     {
2148       langsys = alloca (5);
2149       OTF_tag_name (spec->langsys, langsys);
2150     }
2151   for (i = 0; i < 2; i++)
2152     {
2153       char *p;
2154 
2155       if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF)
2156         {
2157           for (j = 0; spec->features[i][j]; j++);
2158           if (i == 0)
2159             p = gsub_features = alloca (6 * j);
2160           else
2161             p = gpos_features = alloca (6 * j);
2162           for (j = 0; spec->features[i][j]; j++)
2163             {
2164               if (spec->features[i][j] == 0xFFFFFFFF)
2165                 *p++ = '*', *p++ = ',';
2166               else
2167                 {
2168                   OTF_tag_name (spec->features[i][j], p);
2169                   p[4] = ',';
2170                   p += 5;
2171                 }
2172             }
2173           *--p = '\0';
2174         }
2175     }
2176 
2177   setup_otf_gstring (len);
2178   for (i = 0; i < len; i++)
2179     {
2180       otf_gstring.glyphs[i].c = in->glyphs[from + i].c;
2181       otf_gstring.glyphs[i].glyph_id = in->glyphs[from + i].code;
2182     }
2183 
2184   OTF_drive_gdef (otf, &otf_gstring);
2185   gidx = out->used;
2186 
2187   if (gsub_features)
2188     {
2189       if (OTF_drive_gsub (otf, &otf_gstring, script, langsys, gsub_features)
2190           < 0)
2191         goto simple_copy;
2192       if (out->allocated < out->used + otf_gstring.used)
2193         return -2;
2194       for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; )
2195         {
2196           MFLTGlyph *g;
2197           int min_from, max_to;
2198           int j;
2199 
2200           g = out->glyphs + out->used;
2201           *g = in->glyphs[from + otfg->f.index.from];
2202           if (g->code != otfg->glyph_id)
2203             {
2204               g->c = 0;
2205               g->code = otfg->glyph_id;
2206               g->measured = 0;
2207             }
2208           out->used++;
2209           min_from = g->from;
2210           max_to = g->to;
2211           if (otfg->f.index.from < otfg->f.index.to)
2212             {
2213               /* OTFG substitutes multiple glyphs in IN.  */
2214               for (j = from + otfg->f.index.from + 1;
2215                    j <= from + otfg->f.index.to; j++)
2216                 {
2217                   if (min_from > in->glyphs[j].from)
2218                     min_from = in->glyphs[j].from;
2219                   if (max_to < in->glyphs[j].to)
2220                     max_to = in->glyphs[j].to;
2221                 }
2222               g->from = min_from;
2223               g->to = max_to;
2224             }
2225           for (i++, otfg++; (i < otf_gstring.used
2226                              && otfg->f.index.from == otfg[-1].f.index.from);
2227                i++, otfg++)
2228             {
2229               g = out->glyphs + out->used;
2230               *g = in->glyphs[from + otfg->f.index.to];
2231               if (g->code != otfg->glyph_id)
2232                 {
2233                   g->c = 0;
2234                   g->code = otfg->glyph_id;
2235                   g->measured = 0;
2236                 }
2237               out->used++;
2238             }
2239         }
2240     }
2241   else
2242     {
2243       if (out->allocated < out->used + len)
2244         return -2;
2245       for (i = 0; i < len; i++)
2246         out->glyphs[out->used++] = in->glyphs[from + i];
2247     }
2248 
2249   if (gpos_features)
2250     {
2251       MFLTGlyph *base = NULL, *mark = NULL, *g;
2252       int x_ppem, y_ppem, x_scale, y_scale;
2253 
2254       if (OTF_drive_gpos (otf, &otf_gstring, script, langsys, gpos_features)
2255           < 0)
2256         return to;
2257 
2258       x_ppem = ft_face->size->metrics.x_ppem;
2259       y_ppem = ft_face->size->metrics.y_ppem;
2260       x_scale = ft_face->size->metrics.x_scale;
2261       y_scale = ft_face->size->metrics.y_scale;
2262 
2263       for (i = 0, otfg = otf_gstring.glyphs, g = out->glyphs + gidx;
2264            i < otf_gstring.used; i++, otfg++, g++)
2265         {
2266           MFLTGlyph *prev;
2267 
2268           if (! otfg->glyph_id)
2269             continue;
2270           switch (otfg->positioning_type)
2271             {
2272             case 0:
2273               break;
2274             case 1:             /* Single */
2275             case 2:             /* Pair */
2276               {
2277                 int format = otfg->f.f1.format;
2278 
2279                 if (format & OTF_XPlacement)
2280                   adjustment[i].xoff
2281                     = otfg->f.f1.value->XPlacement * x_scale / 0x10000;
2282                 if (format & OTF_XPlaDevice)
2283                   adjustment[i].xoff
2284                     += DEVICE_DELTA (otfg->f.f1.value->XPlaDevice, x_ppem);
2285                 if (format & OTF_YPlacement)
2286                   adjustment[i].yoff
2287                     = - (otfg->f.f1.value->YPlacement * y_scale / 0x10000);
2288                 if (format & OTF_YPlaDevice)
2289                   adjustment[i].yoff
2290                     -= DEVICE_DELTA (otfg->f.f1.value->YPlaDevice, y_ppem);
2291                 if (format & OTF_XAdvance)
2292                   adjustment[i].xadv
2293                     += otfg->f.f1.value->XAdvance * x_scale / 0x10000;
2294                 if (format & OTF_XAdvDevice)
2295                   adjustment[i].xadv
2296                     += DEVICE_DELTA (otfg->f.f1.value->XAdvDevice, x_ppem);
2297                 if (format & OTF_YAdvance)
2298                   adjustment[i].yadv
2299                     += otfg->f.f1.value->YAdvance * y_scale / 0x10000;
2300                 if (format & OTF_YAdvDevice)
2301                   adjustment[i].yadv
2302                     += DEVICE_DELTA (otfg->f.f1.value->YAdvDevice, y_ppem);
2303                 adjustment[i].set = 1;
2304               }
2305               break;
2306             case 3:             /* Cursive */
2307               /* Not yet supported.  */
2308               break;
2309             case 4:             /* Mark-to-Base */
2310             case 5:             /* Mark-to-Ligature */
2311               if (! base)
2312                 break;
2313               prev = base;
2314               goto label_adjust_anchor;
2315             default:            /* i.e. case 6 Mark-to-Mark */
2316               if (! mark)
2317                 break;
2318               prev = mark;
2319 
2320             label_adjust_anchor:
2321               {
2322                 int base_x, base_y, mark_x, mark_y;
2323                 int this_from, this_to;
2324 
2325                 base_x = otfg->f.f4.base_anchor->XCoordinate * x_scale / 0x10000;
2326                 base_y = otfg->f.f4.base_anchor->YCoordinate * y_scale / 0x10000;
2327                 mark_x = otfg->f.f4.mark_anchor->XCoordinate * x_scale / 0x10000;
2328                 mark_y = otfg->f.f4.mark_anchor->YCoordinate * y_scale / 0x10000;
2329 
2330                 if (otfg->f.f4.base_anchor->AnchorFormat != 1)
2331                   adjust_anchor (ft_face, otfg->f.f4.base_anchor,
2332                                  prev->code, x_ppem, y_ppem, &base_x, &base_y);
2333                 if (otfg->f.f4.mark_anchor->AnchorFormat != 1)
2334                   adjust_anchor (ft_face, otfg->f.f4.mark_anchor, g->code,
2335                                  x_ppem, y_ppem, &mark_x, &mark_y);
2336                 adjustment[i].xoff = (base_x - mark_x);
2337                 adjustment[i].yoff = - (base_y - mark_y);
2338                 adjustment[i].back = (g - prev);
2339                 adjustment[i].xadv = 0;
2340                 adjustment[i].advance_is_absolute = 1;
2341                 adjustment[i].set = 1;
2342                 this_from = g->from;
2343                 this_to = g->to;
2344                 for (j = 0; prev + j < g; j++)
2345                   {
2346                     if (this_from > prev[j].from)
2347                       this_from = prev[j].from;
2348                     if (this_to < prev[j].to)
2349                       this_to = prev[j].to;
2350                   }
2351                 for (; prev <= g; prev++)
2352                   {
2353                     prev->from = this_from;
2354                     prev->to = this_to;
2355                   }
2356               }
2357             }
2358           if (otfg->GlyphClass == OTF_GlyphClass0)
2359             base = mark = g;
2360           else if (otfg->GlyphClass == OTF_GlyphClassMark)
2361             mark = g;
2362           else
2363             base = g;
2364         }
2365     }
2366   return to;
2367 
2368  simple_copy:
2369   if (out->allocated < out->used + len)
2370     return -2;
2371   font->get_metrics (font, in, from, to);
2372   memcpy (out->glyphs + out->used, in->glyphs + from,
2373           sizeof (MFLTGlyph) * len);
2374   out->used += len;
2375   return to;
2376 }
2377 
2378 #endif  /* not M17N_FLT_USE_NEW_FEATURE */
2379 
2380 static MFLTGlyphString gstring;
2381 
2382 static int m17n_flt_initialized;
2383 
2384 extern Lisp_Object QCfamily;
2385 
2386 static Lisp_Object
2387 ftfont_shape_by_flt (lgstring, font, ft_face, otf, matrix)
2388      Lisp_Object lgstring;
2389      struct font *font;
2390      FT_Face ft_face;
2391      OTF *otf;
2392      FT_Matrix *matrix;
2393 {
2394   EMACS_UINT len = LGSTRING_GLYPH_LEN (lgstring);
2395   EMACS_UINT i;
2396   struct MFLTFontFT flt_font_ft;
2397   MFLT *flt = NULL;
2398   int with_variation_selector = 0;
2399 
2400   if (! m17n_flt_initialized)
2401     {
2402       M17N_INIT ();
2403 #ifdef M17N_FLT_USE_NEW_FEATURE
2404       mflt_enable_new_feature = 1;
2405       mflt_try_otf = ftfont_try_otf;
2406 #endif  /* M17N_FLT_USE_NEW_FEATURE */
2407       m17n_flt_initialized = 1;
2408     }
2409 
2410   for (i = 0; i < len; i++)
2411     {
2412       Lisp_Object g = LGSTRING_GLYPH (lgstring, i);
2413       int c;
2414 
2415       if (NILP (g))
2416         break;
2417       c = LGLYPH_CHAR (g);
2418       if (CHAR_VARIATION_SELECTOR_P (c))
2419         with_variation_selector++;
2420     }
2421   len = i;
2422   if (with_variation_selector)
2423     {
2424       setup_otf_gstring (len);
2425       for (i = 0; i < len; i++)
2426         {
2427           Lisp_Object g = LGSTRING_GLYPH (lgstring, i);
2428 
2429           otf_gstring.glyphs[i].c = LGLYPH_CHAR (g);
2430           otf_gstring.glyphs[i].f.index.from = LGLYPH_FROM (g);
2431           otf_gstring.glyphs[i].f.index.to = LGLYPH_TO (g);
2432         }
2433       OTF_drive_cmap (otf, &otf_gstring);
2434       for (i = 0; i < otf_gstring.used; i++)
2435         {
2436           OTF_Glyph *otfg = otf_gstring.glyphs + i;
2437           Lisp_Object g0 = LGSTRING_GLYPH (lgstring, otfg->f.index.from);
2438           Lisp_Object g1 = LGSTRING_GLYPH (lgstring, otfg->f.index.to);
2439 
2440           LGLYPH_SET_CODE (g0, otfg->glyph_id);
2441           LGLYPH_SET_TO (g0, LGLYPH_TO (g1));
2442           LGSTRING_SET_GLYPH (lgstring, i, g0);
2443         }
2444       if (len > otf_gstring.used)
2445         {
2446           len = otf_gstring.used;
2447           LGSTRING_SET_GLYPH (lgstring, len, Qnil);
2448         }
2449     }
2450 
2451   if (gstring.allocated == 0)
2452     {
2453       gstring.allocated = len * 2;
2454       gstring.glyph_size = sizeof (MFLTGlyph);
2455       gstring.glyphs = xmalloc (sizeof (MFLTGlyph) * gstring.allocated);
2456     }
2457   else if (gstring.allocated < len * 2)
2458     {
2459       gstring.allocated = len * 2;
2460       gstring.glyphs = xrealloc (gstring.glyphs,
2461                                  sizeof (MFLTGlyph) * gstring.allocated);
2462     }
2463   memset (gstring.glyphs, 0, sizeof (MFLTGlyph) * len);
2464   for (i = 0; i < len; i++)
2465     {
2466       Lisp_Object g = LGSTRING_GLYPH (lgstring, i);
2467 
2468       gstring.glyphs[i].c = LGLYPH_CHAR (g);
2469       if (with_variation_selector)
2470         {
2471           gstring.glyphs[i].code = LGLYPH_CODE (g);
2472           gstring.glyphs[i].encoded = 1;
2473         }
2474     }
2475 
2476   gstring.used = len;
2477   gstring.r2l = 0;
2478 
2479   {
2480     Lisp_Object family = Ffont_get (LGSTRING_FONT (lgstring), QCfamily);
2481 
2482     if (NILP (family))
2483       flt_font_ft.flt_font.family = Mnil;
2484     else
2485       flt_font_ft.flt_font.family
2486         = msymbol ((char *) SDATA (Fdowncase (SYMBOL_NAME (family))));
2487   }
2488   flt_font_ft.flt_font.x_ppem = ft_face->size->metrics.x_ppem;
2489   flt_font_ft.flt_font.y_ppem = ft_face->size->metrics.y_ppem;
2490   flt_font_ft.flt_font.get_glyph_id = ftfont_get_glyph_id;
2491   flt_font_ft.flt_font.get_metrics = ftfont_get_metrics;
2492   flt_font_ft.flt_font.check_otf = ftfont_check_otf;
2493   flt_font_ft.flt_font.drive_otf = ftfont_drive_otf;
2494   flt_font_ft.flt_font.internal = NULL;
2495   flt_font_ft.font = font;
2496   flt_font_ft.ft_face = ft_face;
2497   flt_font_ft.otf = otf;
2498   flt_font_ft.matrix = matrix->xx != 0 ? matrix : 0;
2499   if (len > 1
2500       && gstring.glyphs[1].c >= 0x300 && gstring.glyphs[1].c <= 0x36F)
2501     /* A little bit ad hoc.  Perhaps, shaper must get script and
2502        language information, and select a proper flt for them
2503        here.  */
2504     flt = mflt_get (msymbol ("combining"));
2505   for (i = 0; i < 3; i++)
2506     {
2507       int result = mflt_run (&gstring, 0, len, &flt_font_ft.flt_font, flt);
2508       if (result != -2)
2509         break;
2510       gstring.allocated += gstring.allocated;
2511       gstring.glyphs = xrealloc (gstring.glyphs,
2512                                  sizeof (MFLTGlyph) * gstring.allocated);
2513     }
2514   if (gstring.used > LGSTRING_GLYPH_LEN (lgstring))
2515     return Qnil;
2516   for (i = 0; i < gstring.used; i++)
2517     {
2518       MFLTGlyph *g = gstring.glyphs + i;
2519 
2520       g->from = LGLYPH_FROM (LGSTRING_GLYPH (lgstring, g->from));
2521       g->to = LGLYPH_TO (LGSTRING_GLYPH (lgstring, g->to));
2522     }
2523 
2524   for (i = 0; i < gstring.used; i++)
2525     {
2526       Lisp_Object lglyph = LGSTRING_GLYPH (lgstring, i);
2527       MFLTGlyph *g = gstring.glyphs + i;
2528 
2529       if (NILP (lglyph))
2530         {
2531           lglyph = Fmake_vector (make_number (LGLYPH_SIZE), Qnil);
2532           LGSTRING_SET_GLYPH (lgstring, i, lglyph);
2533         }
2534       LGLYPH_SET_FROM (lglyph, g->from);
2535       LGLYPH_SET_TO (lglyph, g->to);
2536       LGLYPH_SET_CHAR (lglyph, g->c);
2537       LGLYPH_SET_CODE (lglyph, g->code);
2538       LGLYPH_SET_WIDTH (lglyph, g->xadv >> 6);
2539       LGLYPH_SET_LBEARING (lglyph, g->lbearing >> 6);
2540       LGLYPH_SET_RBEARING (lglyph, g->rbearing >> 6);
2541       LGLYPH_SET_ASCENT (lglyph, g->ascent >> 6);
2542       LGLYPH_SET_DESCENT (lglyph, g->descent >> 6);
2543       if (g->adjusted)
2544         {
2545           Lisp_Object vec;
2546 
2547           vec = Fmake_vector (make_number (3), Qnil);
2548           ASET (vec, 0, make_number (g->xoff >> 6));
2549           ASET (vec, 1, make_number (g->yoff >> 6));
2550           ASET (vec, 2, make_number (g->xadv >> 6));
2551           LGLYPH_SET_ADJUSTMENT (lglyph, vec);
2552         }
2553     }
2554   return make_number (i);
2555 }
2556 
2557 Lisp_Object
2558 ftfont_shape (lgstring)
2559      Lisp_Object lgstring;
2560 {
2561   struct font *font;
2562   struct ftfont_info *ftfont_info;
2563   OTF *otf;
2564 
2565   CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring), font);
2566   ftfont_info = (struct ftfont_info *) font;
2567   otf = ftfont_get_otf (ftfont_info);
2568   if (! otf)
2569     return make_number (0);
2570   return ftfont_shape_by_flt (lgstring, font, ftfont_info->ft_size->face, otf,
2571                               &ftfont_info->matrix);
2572 }
2573 
2574 #endif  /* HAVE_M17N_FLT */
2575 
2576 #ifdef HAVE_OTF_GET_VARIATION_GLYPHS
2577 
2578 static int
2579 ftfont_variation_glyphs (font, c, variations)
2580      struct font *font;
2581      int c;
2582      unsigned variations[256];
2583 {
2584   struct ftfont_info *ftfont_info = (struct ftfont_info *) font;
2585   OTF *otf = ftfont_get_otf (ftfont_info);
2586 
2587   if (! otf)
2588     return 0;
2589   return OTF_get_variation_glyphs (otf, c, variations);
2590 }
2591 
2592 #endif  /* HAVE_OTF_GET_VARIATION_GLYPHS */
2593 #endif  /* HAVE_LIBOTF */
2594 
2595 Lisp_Object
2596 ftfont_font_format (FcPattern *pattern, Lisp_Object filename)
2597 {
2598   FcChar8 *str;
2599 
2600 #ifdef FC_FONTFORMAT
2601   if (pattern)
2602     {
2603       if (FcPatternGetString (pattern, FC_FONTFORMAT, 0, &str) != FcResultMatch)
2604         return Qnil;
2605       if (strcmp ((char *) str, "TrueType") == 0)
2606         return intern ("truetype");
2607       if (strcmp ((char *) str, "Type 1") == 0)
2608         return intern ("type1");
2609       if (strcmp ((char *) str, "PCF") == 0)
2610         return intern ("pcf");
2611       if (strcmp ((char *) str, "BDF") == 0)
2612         return intern ("bdf");
2613     }
2614 #endif  /* FC_FONTFORMAT */
2615   if (STRINGP (filename))
2616     {
2617       int len = SBYTES (filename);
2618 
2619       if (len >= 4)
2620         {
2621           str = (FcChar8 *) (SDATA (filename) + len - 4);
2622           if (xstrcasecmp ((char *) str, ".ttf") == 0)
2623             return intern ("truetype");
2624           if (xstrcasecmp ((char *) str, ".pfb") == 0)
2625             return intern ("type1");
2626           if (xstrcasecmp ((char *) str, ".pcf") == 0)
2627             return intern ("pcf");
2628           if (xstrcasecmp ((char *) str, ".bdf") == 0)
2629             return intern ("bdf");
2630         }
2631     }
2632   return intern ("unknown");
2633 }
2634 
2635 static const char *ftfont_booleans [] = {
2636   ":antialias",
2637   ":hinting",
2638   ":verticallayout",
2639   ":autohint",
2640   ":globaladvance",
2641   ":outline",
2642   ":scalable",
2643   ":minspace",
2644   ":embolden",
2645   NULL,
2646 };
2647 
2648 static const char *ftfont_non_booleans [] = {
2649   ":family",
2650   ":familylang",
2651   ":style",
2652   ":stylelang",
2653   ":fullname",
2654   ":fullnamelang",
2655   ":slant",
2656   ":weight",
2657   ":size",
2658   ":width",
2659   ":aspect",
2660   ":pixelsize",
2661   ":spacing",
2662   ":foundry",
2663   ":hintstyle",
2664   ":file",
2665   ":index",
2666   ":ftface",
2667   ":rasterizer",
2668   ":scale",
2669   ":dpi",
2670   ":rgba",
2671   ":lcdfilter",
2672   ":charset",
2673   ":lang",
2674   ":fontversion",
2675   ":capability",
2676   NULL,
2677 };
2678 
2679 static void
2680 ftfont_filter_properties (font, alist)
2681      Lisp_Object font;
2682      Lisp_Object alist;
2683 {
2684   Lisp_Object it;
2685   int i;
2686 
2687   /* Set boolean values to Qt or Qnil */
2688   for (i = 0; ftfont_booleans[i] != NULL; ++i)
2689     for (it = alist; ! NILP (it); it = XCDR (it))
2690       {
2691         Lisp_Object key = XCAR (XCAR (it));
2692         Lisp_Object val = XCDR (XCAR (it));
2693         char *keystr = SDATA (SYMBOL_NAME (key));
2694 
2695         if (strcmp (ftfont_booleans[i], keystr) == 0)
2696           {
2697             char *str = SYMBOLP (val) ? SDATA (SYMBOL_NAME (val)) : NULL;
2698             if (INTEGERP (val)) str = XINT (val) != 0 ? "true" : "false";
2699             if (str == NULL) str = "true";
2700 
2701             val = Qt;
2702             if (strcmp ("false", str) == 0 || strcmp ("False", str) == 0
2703                 || strcmp ("FALSE", str) == 0 || strcmp ("FcFalse", str) == 0
2704                 || strcmp ("off", str) == 0 || strcmp ("OFF", str) == 0
2705                 || strcmp ("Off", str) == 0)
2706               val = Qnil;
2707             Ffont_put (font, key, val);
2708           }
2709       }
2710 
2711   for (i = 0; ftfont_non_booleans[i] != NULL; ++i)
2712     for (it = alist; ! NILP (it); it = XCDR (it))
2713       {
2714         Lisp_Object key = XCAR (XCAR (it));
2715         Lisp_Object val = XCDR (XCAR (it));
2716         char *keystr = SDATA (SYMBOL_NAME (key));
2717         if (strcmp (ftfont_non_booleans[i], keystr) == 0)
2718           Ffont_put (font, key, val);
2719       }
2720 }
2721 
2722 
2723 void
2724 syms_of_ftfont ()
2725 {
2726   DEFSYM (Qfreetype, "freetype");
2727   DEFSYM (Qmonospace, "monospace");
2728   DEFSYM (Qsans_serif, "sans-serif");
2729   DEFSYM (Qserif, "serif");
2730   DEFSYM (Qmono, "mono");
2731   DEFSYM (Qsans, "sans");
2732   DEFSYM (Qsans__serif, "sans serif");
2733 
2734   staticpro (&freetype_font_cache);
2735   freetype_font_cache = Fcons (Qt, Qnil);
2736 
2737   staticpro (&ftfont_generic_family_list);
2738   ftfont_generic_family_list
2739     = Fcons (Fcons (Qmonospace, Qt),
2740              Fcons (Fcons (Qsans_serif, Qt),
2741                     Fcons (Fcons (Qsans, Qt), Qnil)));
2742 
2743   staticpro (&ft_face_cache);
2744   ft_face_cache = Qnil;
2745 
2746   ftfont_driver.type = Qfreetype;
2747   register_font_driver (&ftfont_driver, NULL);
2748 }
2749 
2750 /* arch-tag: 7cfa432c-33a6-4988-83d2-a82ed8604aca
2751    (do not change this comment) */