ftfont.c 72.5 KB
Newer Older
Kenichi Handa's avatar
Kenichi Handa committed
1
/* ftfont.c -- FreeType font driver.
2
   Copyright (C) 2006-2011 Free Software Foundation, Inc.
3
   Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
Kenichi Handa's avatar
Kenichi Handa committed
4 5 6 7 8
     National Institute of Advanced Industrial Science and Technology (AIST)
     Registration Number H13PRO009

This file is part of GNU Emacs.

9
GNU Emacs is free software: you can redistribute it and/or modify
Kenichi Handa's avatar
Kenichi Handa committed
10
it under the terms of the GNU General Public License as published by
11 12
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Kenichi Handa's avatar
Kenichi Handa committed
13 14 15 16 17 18 19

GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

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/>.  */
Kenichi Handa's avatar
Kenichi Handa committed
21 22 23

#include <config.h>
#include <stdio.h>
24
#include <setjmp.h>
Kenichi Handa's avatar
Kenichi Handa committed
25 26 27 28 29 30 31 32 33 34 35

#include <fontconfig/fontconfig.h>
#include <fontconfig/fcfreetype.h>

#include "lisp.h"
#include "dispextern.h"
#include "frame.h"
#include "blockinput.h"
#include "character.h"
#include "charset.h"
#include "coding.h"
Kenichi Handa's avatar
Kenichi Handa committed
36
#include "composite.h"
Kenichi Handa's avatar
Kenichi Handa committed
37 38
#include "fontset.h"
#include "font.h"
39
#include "ftfont.h"
Kenichi Handa's avatar
Kenichi Handa committed
40

41
/* Symbolic type of this font-driver.  */
42
static Lisp_Object Qfreetype;
Kenichi Handa's avatar
Kenichi Handa committed
43

44 45 46
/* Fontconfig's generic families and their aliases.  */
static Lisp_Object Qmonospace, Qsans_serif, Qserif, Qmono, Qsans, Qsans__serif;

Juanma Barranquero's avatar
Juanma Barranquero committed
47
/* Flag to tell if FcInit is already called or not.  */
Kenichi Handa's avatar
Kenichi Handa committed
48
static int fc_initialized;
49 50

/* Handle to a FreeType library instance.  */
Kenichi Handa's avatar
Kenichi Handa committed
51 52
static FT_Library ft_library;

53
/* Cache for FreeType fonts.  */
Kenichi Handa's avatar
Kenichi Handa committed
54 55
static Lisp_Object freetype_font_cache;

56
/* Cache for FT_Face and FcCharSet. */
Kenichi Handa's avatar
Kenichi Handa committed
57
static Lisp_Object ft_face_cache;
Kenichi Handa's avatar
Kenichi Handa committed
58 59 60 61 62 63 64

/* The actual structure for FreeType font that can be casted to struct
   font.  */

struct ftfont_info
{
  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 69 70
  int maybe_otf;	/* Flag to tell if this may be OTF or not.  */
  OTF *otf;
#endif	/* HAVE_LIBOTF */
71 72
  FT_Size ft_size;
  int index;
73
  FT_Matrix matrix;
Kenichi Handa's avatar
Kenichi Handa committed
74 75
};

76 77 78 79 80 81 82
enum ftfont_cache_for
  {
    FTFONT_CACHE_FOR_FACE,
    FTFONT_CACHE_FOR_CHARSET,
    FTFONT_CACHE_FOR_ENTITY
  };

83
static Lisp_Object ftfont_pattern_entity (FcPattern *, Lisp_Object);
Kenichi Handa's avatar
Kenichi Handa committed
84

85 86 87 88
static Lisp_Object ftfont_resolve_generic_family (Lisp_Object,
                                                  FcPattern *);
static Lisp_Object ftfont_lookup_cache (Lisp_Object,
                                        enum ftfont_cache_for);
89

90
static void ftfont_filter_properties (Lisp_Object font, Lisp_Object alist);
91

92
Lisp_Object ftfont_font_format (FcPattern *, Lisp_Object);
93 94 95

#define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM))

Kenichi Handa's avatar
Kenichi Handa committed
96
static struct
Kenichi Handa's avatar
Kenichi Handa committed
97
{
98
  /* registry name */
99
  const char *name;
Kenichi Handa's avatar
Kenichi Handa committed
100 101
  /* characters to distinguish the charset from the others */
  int uniquifier[6];
102
  /* additional constraint by language */
103
  const char *lang;
Kenichi Handa's avatar
Kenichi Handa committed
104 105 106
  /* set on demand */
  FcCharSet *fc_charset;
} fc_charset_table[] =
107
  { { "iso8859-1", { 0x00A0, 0x00A1, 0x00B4, 0x00BC, 0x00D0 } },
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
    { "iso8859-2", { 0x00A0, 0x010E }},
    { "iso8859-3", { 0x00A0, 0x0108 }},
    { "iso8859-4", { 0x00A0, 0x00AF, 0x0128, 0x0156, 0x02C7 }},
    { "iso8859-5", { 0x00A0, 0x0401 }},
    { "iso8859-6", { 0x00A0, 0x060C }},
    { "iso8859-7", { 0x00A0, 0x0384 }},
    { "iso8859-8", { 0x00A0, 0x05D0 }},
    { "iso8859-9", { 0x00A0, 0x00A1, 0x00BC, 0x011E }},
    { "iso8859-10", { 0x00A0, 0x00D0, 0x0128, 0x2015 }},
    { "iso8859-11", { 0x00A0, 0x0E01 }},
    { "iso8859-13", { 0x00A0, 0x201C }},
    { "iso8859-14", { 0x00A0, 0x0174 }},
    { "iso8859-15", { 0x00A0, 0x00A1, 0x00D0, 0x0152 }},
    { "iso8859-16", { 0x00A0, 0x0218}},
    { "gb2312.1980-0", { 0x4E13 }, "zh-cn"},
    { "big5-0", { 0xF6B1 }, "zh-tw" },
    { "jisx0208.1983-0", { 0x4E55 }, "ja"},
    { "ksc5601.1985-0", { 0xAC00 }, "ko"},
    { "cns11643.1992-1", { 0xFE32 }, "zh-tw"},
    { "cns11643.1992-2", { 0x4E33, 0x7934 }},
    { "cns11643.1992-3", { 0x201A9 }},
    { "cns11643.1992-4", { 0x20057 }},
    { "cns11643.1992-5", { 0x20000 }},
    { "cns11643.1992-6", { 0x20003 }},
    { "cns11643.1992-7", { 0x20055 }},
    { "gbk-0", { 0x4E06 }, "zh-cn"},
    { "jisx0212.1990-0", { 0x4E44 }},
    { "jisx0213.2000-1", { 0xFA10 }, "ja"},
    { "jisx0213.2000-2", { 0xFA49 }},
    { "jisx0213.2004-1", { 0x20B9F }},
    { "viscii1.1-1", { 0x1EA0, 0x1EAE, 0x1ED2 }, "vi"},
    { "tis620.2529-1", { 0x0E01 }, "th"},
140 141
    { "windows-1251", { 0x0401, 0x0490 }, "ru"},
    { "koi8-r", { 0x0401, 0x2219 }, "ru"},
142
    { "mulelao-1", { 0x0E81 }, "lo"},
143
    { "unicode-sip", { 0x20000 }},
Kenichi Handa's avatar
Kenichi Handa committed
144 145
    { NULL }
  };
Kenichi Handa's avatar
Kenichi Handa committed
146

Kenichi Handa's avatar
Kenichi Handa committed
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
/* Dirty hack for handing ADSTYLE property.

   Fontconfig (actually the underlying FreeType) gives such ADSTYLE
   font property of PCF/BDF fonts in FC_STYLE.  And, "Bold",
   "Oblique", "Italic", or any non-normal SWIDTH property names
   (e.g. SemiCondensed) are appended.  In addition, if there's no
   ADSTYLE property nor non-normal WEIGHT/SLANT/SWIDTH properties,
   "Regular" is used for FC_STYLE (see the function
   pcf_interpret_style in src/pcf/pcfread.c of FreeType).

   Unfortunately this behavior is not documented, so the following
   code may fail if FreeType changes the behavior in the future.  */

static Lisp_Object
get_adstyle_property (FcPattern *p)
{
163 164
  FcChar8 *fcstr;
  char *str, *end;
Kenichi Handa's avatar
Kenichi Handa committed
165 166
  Lisp_Object adstyle;

167
  if (FcPatternGetString (p, FC_STYLE, 0, &fcstr) != FcResultMatch)
Kenichi Handa's avatar
Kenichi Handa committed
168
    return Qnil;
169
  str = (char *) fcstr;
Kenichi Handa's avatar
Kenichi Handa committed
170 171 172
  for (end = str; *end && *end != ' '; end++);
  if (*end)
    {
173 174 175 176 177
      char *newstr = alloca (end - str + 1);
      memcpy (newstr, str, end - str);
      newstr[end - str] = '\0';
      end = newstr + (end - str);
      str = newstr;
Kenichi Handa's avatar
Kenichi Handa committed
178 179 180 181 182 183
    }
  if (xstrcasecmp (str, "Regular") == 0
      || xstrcasecmp (str, "Bold") == 0
      || xstrcasecmp (str, "Oblique") == 0
      || xstrcasecmp (str, "Italic") == 0)
    return Qnil;
184
  adstyle = font_intern_prop (str, end - str, 1);
Kenichi Handa's avatar
Kenichi Handa committed
185 186 187 188 189
  if (font_style_to_value (FONT_WIDTH_INDEX, adstyle, 0) >= 0)
    return Qnil;
  return adstyle;
}

190
static Lisp_Object
191
ftfont_pattern_entity (FcPattern *p, Lisp_Object extra)
192
{
193
  Lisp_Object key, cache, entity;
194 195
  FcChar8 *str;
  char *file;
196
  int idx;
197 198
  int numeric;
  double dbl;
199
  FcBool b;
200

201
  if (FcPatternGetString (p, FC_FILE, 0, &str) != FcResultMatch)
202
    return Qnil;
203
  if (FcPatternGetInteger (p, FC_INDEX, 0, &idx) != FcResultMatch)
204
    return Qnil;
205

206 207
  file = (char *) str;
  key = Fcons (make_unibyte_string (file, strlen (file)), make_number (idx));
208 209 210
  cache = ftfont_lookup_cache (key, FTFONT_CACHE_FOR_ENTITY);
  entity = XCAR (cache);
  if (! NILP (entity))
211 212 213 214 215 216
    {
      Lisp_Object val = font_make_entity ();
      int i;

      for (i = 0; i < FONT_OBJLIST_INDEX; i++)
	ASET (val, i, AREF (entity, i));
217 218 219 220

      ASET (val, FONT_EXTRA_INDEX, Fcopy_sequence (extra));
      font_put_extra (val, QCfont_entity, key);

221 222
      return val;
    }
223
  entity = font_make_entity ();
224
  XSETCAR (cache, entity);
225 226

  ASET (entity, FONT_TYPE_INDEX, Qfreetype);
227
  ASET (entity, FONT_REGISTRY_INDEX, Qiso10646_1);
228

229 230 231 232 233 234 235 236 237 238
  if (FcPatternGetString (p, FC_FOUNDRY, 0, &str) == FcResultMatch)
    {
      char *s = (char *) str;
      ASET (entity, FONT_FOUNDRY_INDEX, font_intern_prop (s, strlen (s), 1));
    }
  if (FcPatternGetString (p, FC_FAMILY, 0, &str) == FcResultMatch)
    {
      char *s = (char *) str;
      ASET (entity, FONT_FAMILY_INDEX, font_intern_prop (s, strlen (s), 1));
    }
239
  if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch)
240
    {
241 242 243
      if (numeric >= FC_WEIGHT_REGULAR && numeric < FC_WEIGHT_MEDIUM)
	numeric = FC_WEIGHT_MEDIUM;
      FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX, make_number (numeric));
244
    }
245
  if (FcPatternGetInteger (p, FC_SLANT, 0, &numeric) == FcResultMatch)
246 247 248 249
    {
      numeric += 100;
      FONT_SET_STYLE (entity, FONT_SLANT_INDEX, make_number (numeric));
    }
250
  if (FcPatternGetInteger (p, FC_WIDTH, 0, &numeric) == FcResultMatch)
251 252 253
    {
      FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, make_number (numeric));
    }
254
  if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch)
Kenichi Handa's avatar
Kenichi Handa committed
255 256 257
    {
      ASET (entity, FONT_SIZE_INDEX, make_number (dbl));
    }
258 259
  else
    ASET (entity, FONT_SIZE_INDEX, make_number (0));
260 261 262 263 264 265 266 267 268
  if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) == FcResultMatch)
    ASET (entity, FONT_SPACING_INDEX, make_number (numeric));
  if (FcPatternGetDouble (p, FC_DPI, 0, &dbl) == FcResultMatch)
    {
      int dpi = dbl;
      ASET (entity, FONT_DPI_INDEX, make_number (dpi));
    }
  if (FcPatternGetBool (p, FC_SCALABLE, 0, &b) == FcResultMatch
      && b == FcTrue)
269 270 271 272 273 274 275
    {
      ASET (entity, FONT_SIZE_INDEX, make_number (0));
      ASET (entity, FONT_AVGWIDTH_INDEX, make_number (0));
    }
  else
    {
      /* As this font is not scalable, parhaps this is a BDF or PCF
276
	 font. */
277 278 279 280
      FT_Face ft_face;

      ASET (entity, FONT_ADSTYLE_INDEX, get_adstyle_property (p));
      if ((ft_library || FT_Init_FreeType (&ft_library) == 0)
281
	  && FT_New_Face (ft_library, file, idx, &ft_face) == 0)
282 283 284 285 286 287 288 289 290
	{
	  BDF_PropertyRec rec;

	  if (FT_Get_BDF_Property (ft_face, "AVERAGE_WIDTH", &rec) == 0
	      && rec.type == BDF_PROPERTY_TYPE_INTEGER)
	    ASET (entity, FONT_AVGWIDTH_INDEX, make_number (rec.u.integer));
	  FT_Done_Face (ft_face);
	}
    }
291

292
  ASET (entity, FONT_EXTRA_INDEX, Fcopy_sequence (extra));
293
  font_put_extra (entity, QCfont_entity, key);
294 295 296
  return entity;
}

297

298 299 300
static Lisp_Object ftfont_generic_family_list;

static Lisp_Object
301
ftfont_resolve_generic_family (Lisp_Object family, FcPattern *pattern)
302
{
303
  Lisp_Object slot;
304
  FcPattern *match;
305
  FcResult result;
Kenichi Handa's avatar
Kenichi Handa committed
306
  FcLangSet *langset;
307

308
  family = Fintern (Fdowncase (SYMBOL_NAME (family)), Qnil);
309 310 311 312 313 314
  if (EQ (family, Qmono))
    family = Qmonospace;
  else if (EQ (family, Qsans) || EQ (family, Qsans__serif))
    family = Qsans_serif;
  slot = assq_no_quit (family, ftfont_generic_family_list);
  if (! CONSP (slot))
315
    return Qnil;
316 317
  if (! EQ (XCDR (slot), Qt))
    return XCDR (slot);
318
  pattern = FcPatternDuplicate (pattern);
319 320
  if (! pattern)
    goto err;
321
  FcPatternDel (pattern, FC_FOUNDRY);
322 323
  FcPatternDel (pattern, FC_FAMILY);
  FcPatternAddString (pattern, FC_FAMILY, SYMBOL_FcChar8 (family));
Kenichi Handa's avatar
Kenichi Handa committed
324 325 326
  if (FcPatternGetLangSet (pattern, FC_LANG, 0, &langset) != FcResultMatch)
    {
      /* This is to avoid the effect of locale.  */
327
      static const FcChar8 lang[] = "en";
Kenichi Handa's avatar
Kenichi Handa committed
328
      langset = FcLangSetCreate ();
329
      FcLangSetAdd (langset, lang);
Kenichi Handa's avatar
Kenichi Handa committed
330 331 332
      FcPatternAddLangSet (pattern, FC_LANG, langset);
      FcLangSetDestroy (langset);
    }
333
  FcConfigSubstitute (NULL, pattern, FcMatchPattern);
334 335 336
  FcDefaultSubstitute (pattern);
  match = FcFontMatch (NULL, pattern, &result);
  if (match)
337
    {
338 339 340 341
      FcChar8 *fam;

      if (FcPatternGetString (match, FC_FAMILY, 0, &fam) == FcResultMatch)
	family = intern ((char *) fam);
342
    }
343 344 345 346
  else
    family = Qnil;
  XSETCDR (slot, family);
  if (match) FcPatternDestroy (match);
347
 err:
348
  if (pattern) FcPatternDestroy (pattern);
349
  return family;
350 351
}

352 353 354 355 356 357 358
struct ftfont_cache_data
{
  FT_Face ft_face;
  FcCharSet *fc_charset;
};

static Lisp_Object
359
ftfont_lookup_cache (Lisp_Object key, enum ftfont_cache_for cache_for)
Kenichi Handa's avatar
Kenichi Handa committed
360
{
Kenichi Handa's avatar
Kenichi Handa committed
361
  Lisp_Object cache, val, entity;
362
  struct ftfont_cache_data *cache_data;
Kenichi Handa's avatar
Kenichi Handa committed
363

Kenichi Handa's avatar
Kenichi Handa committed
364 365 366 367 368 369 370 371 372 373
  if (FONT_ENTITY_P (key))
    {
      entity = key;
      val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
      xassert (CONSP (val));
      key = XCDR (val);
    }
  else
    entity = Qnil;

374 375 376 377
  if (NILP (ft_face_cache))
    cache = Qnil;
  else
    cache = Fgethash (key, ft_face_cache, Qnil);
Kenichi Handa's avatar
Kenichi Handa committed
378 379
  if (NILP (cache))
    {
380 381 382 383 384 385 386 387
      if (NILP (ft_face_cache))
	{
	  Lisp_Object args[2];

	  args[0] = QCtest;
	  args[1] = Qequal;
	  ft_face_cache = Fmake_hash_table (2, args);
	}
388 389 390
      cache_data = xmalloc (sizeof (struct ftfont_cache_data));
      cache_data->ft_face = NULL;
      cache_data->fc_charset = NULL;
Kenichi Handa's avatar
Kenichi Handa committed
391
      val = make_save_value (NULL, 0);
392 393
      XSAVE_VALUE (val)->integer = 0;
      XSAVE_VALUE (val)->pointer = cache_data;
394 395
      cache = Fcons (Qnil, val);
      Fputhash (key, cache, ft_face_cache);
Kenichi Handa's avatar
Kenichi Handa committed
396 397 398
    }
  else
    {
399 400 401
      val = XCDR (cache);
      cache_data = XSAVE_VALUE (val)->pointer;
    }
402 403 404 405 406 407

  if (cache_for == FTFONT_CACHE_FOR_ENTITY)
    return cache;

  if (cache_for == FTFONT_CACHE_FOR_FACE
      ? ! cache_data->ft_face : ! cache_data->fc_charset)
408
    {
409
      char *filename = SSDATA (XCAR (key));
410
      int idx = XINT (XCDR (key));
Kenichi Handa's avatar
Kenichi Handa committed
411

412
      if (cache_for == FTFONT_CACHE_FOR_FACE)
413 414 415 416
	{
	  if (! ft_library
	      && FT_Init_FreeType (&ft_library) != 0)
	    return Qnil;
417
	  if (FT_New_Face (ft_library, filename, idx, &cache_data->ft_face)
418 419 420 421 422
	      != 0)
	    return Qnil;
	}
      else
	{
Kenichi Handa's avatar
Kenichi Handa committed
423 424 425 426
	  FcPattern *pat = NULL;
	  FcFontSet *fontset = NULL;
	  FcObjectSet *objset = NULL;
	  FcCharSet *charset = NULL;
427 428

	  pat = FcPatternBuild (0, FC_FILE, FcTypeString, (FcChar8 *) filename,
429
				FC_INDEX, FcTypeInteger, idx, NULL);
Kenichi Handa's avatar
Kenichi Handa committed
430 431 432 433 434
	  if (! pat)
	    goto finish;
	  objset = FcObjectSetBuild (FC_CHARSET, FC_STYLE, NULL);
	  if (! objset)
	    goto finish;
435
	  fontset = FcFontList (NULL, pat, objset);
Kenichi Handa's avatar
Kenichi Handa committed
436 437
	  if (! fontset)
	    goto finish;
438 439
	  if (fontset && fontset->nfont > 0
	      && (FcPatternGetCharSet (fontset->fonts[0], FC_CHARSET, 0,
440
				       &charset)
441 442
		  == FcResultMatch))
	    cache_data->fc_charset = FcCharSetCopy (charset);
443 444
	  else
	    cache_data->fc_charset = FcCharSetCreate ();
Kenichi Handa's avatar
Kenichi Handa committed
445 446 447 448 449 450 451 452

	finish:
	  if (fontset)
	    FcFontSetDestroy (fontset);
	  if (objset)
	    FcObjectSetDestroy (objset);
	  if (pat)
	    FcPatternDestroy (pat);
453
	}
Kenichi Handa's avatar
Kenichi Handa committed
454 455 456 457
    }
  return cache;
}

458
FcCharSet *
459
ftfont_get_fc_charset (Lisp_Object entity)
460 461 462 463
{
  Lisp_Object val, cache;
  struct ftfont_cache_data *cache_data;

464
  cache = ftfont_lookup_cache (entity, FTFONT_CACHE_FOR_CHARSET);
465 466 467 468 469 470 471
  val = XCDR (cache);
  cache_data = XSAVE_VALUE (val)->pointer;
  return cache_data->fc_charset;
}

#ifdef HAVE_LIBOTF
static OTF *
Andreas Schwab's avatar
Andreas Schwab committed
472
ftfont_get_otf (struct ftfont_info *ftfont_info)
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492
{
  OTF *otf;

  if (ftfont_info->otf)
    return ftfont_info->otf;
  if (! ftfont_info->maybe_otf)
    return NULL;
  otf = OTF_open_ft_face (ftfont_info->ft_size->face);
  if (! otf || OTF_get_table (otf, "head") < 0)
    {
      if (otf)
	OTF_close (otf);
      ftfont_info->maybe_otf = 0;
      return NULL;
    }
  ftfont_info->otf = otf;
  return otf;
}
#endif	/* HAVE_LIBOTF */

493 494 495 496 497 498 499 500 501 502 503 504 505 506
static Lisp_Object ftfont_get_cache (FRAME_PTR);
static Lisp_Object ftfont_list (Lisp_Object, Lisp_Object);
static Lisp_Object ftfont_match (Lisp_Object, Lisp_Object);
static Lisp_Object ftfont_list_family (Lisp_Object);
static Lisp_Object ftfont_open (FRAME_PTR, Lisp_Object, int);
static void ftfont_close (FRAME_PTR, struct font *);
static int ftfont_has_char (Lisp_Object, int);
static unsigned ftfont_encode_char (struct font *, int);
static int ftfont_text_extents (struct font *, unsigned *, int,
                                struct font_metrics *);
static int ftfont_get_bitmap (struct font *, unsigned,
                              struct font_bitmap *, int);
static int ftfont_anchor_point (struct font *, unsigned, int,
                                int *, int *);
507
#ifdef HAVE_LIBOTF
508
static Lisp_Object ftfont_otf_capability (struct font *);
509
# ifdef HAVE_M17N_FLT
510
static Lisp_Object ftfont_shape (Lisp_Object);
511 512
# endif
#endif
513 514

#ifdef HAVE_OTF_GET_VARIATION_GLYPHS
515 516
static int ftfont_variation_glyphs (struct font *, int c,
                                    unsigned variations[256]);
517
#endif /* HAVE_OTF_GET_VARIATION_GLYPHS */
Kenichi Handa's avatar
Kenichi Handa committed
518 519 520

struct font_driver ftfont_driver =
  {
521
    0,				/* Qfreetype */
522
    0,				/* case insensitive */
Kenichi Handa's avatar
Kenichi Handa committed
523 524
    ftfont_get_cache,
    ftfont_list,
525
    ftfont_match,
Kenichi Handa's avatar
Kenichi Handa committed
526
    ftfont_list_family,
527
    NULL,			/* free_entity */
Kenichi Handa's avatar
Kenichi Handa committed
528 529 530
    ftfont_open,
    ftfont_close,
    /* We can't draw a text without device dependent functions.  */
531 532
    NULL,			/* prepare_face */
    NULL,			/* done_face */
Kenichi Handa's avatar
Kenichi Handa committed
533 534 535 536
    ftfont_has_char,
    ftfont_encode_char,
    ftfont_text_extents,
    /* We can't draw a text without device dependent functions.  */
537
    NULL,			/* draw */
Kenichi Handa's avatar
Kenichi Handa committed
538
    ftfont_get_bitmap,
539 540 541
    NULL,			/* get_bitmap */
    NULL,			/* free_bitmap */
    NULL,			/* get_outline */
Kenichi Handa's avatar
Kenichi Handa committed
542
    ftfont_anchor_point,
543 544 545
#ifdef HAVE_LIBOTF
    ftfont_otf_capability,
#else  /* not HAVE_LIBOTF */
Kenichi Handa's avatar
Kenichi Handa committed
546
    NULL,
547
#endif	/* not HAVE_LIBOTF */
548 549 550
    NULL,			/* otf_drive */
    NULL,			/* start_for_frame */
    NULL,			/* end_for_frame */
551
#if defined (HAVE_M17N_FLT) && defined (HAVE_LIBOTF)
552
    ftfont_shape,
553
#else  /* not (HAVE_M17N_FLT && HAVE_LIBOTF) */
554
    NULL,
555
#endif	/* not (HAVE_M17N_FLT && HAVE_LIBOTF) */
556
    NULL,			/* check */
557

558
#ifdef HAVE_OTF_GET_VARIATION_GLYPHS
559
    ftfont_variation_glyphs,
560
#else
561
    NULL,
562
#endif
563 564

    ftfont_filter_properties, /* filter_properties */
Kenichi Handa's avatar
Kenichi Handa committed
565 566 567
  };

static Lisp_Object
568
ftfont_get_cache (FRAME_PTR f)
Kenichi Handa's avatar
Kenichi Handa committed
569 570 571 572
{
  return freetype_font_cache;
}

Kenichi Handa's avatar
Kenichi Handa committed
573
static int
574
ftfont_get_charset (Lisp_Object registry)
Kenichi Handa's avatar
Kenichi Handa committed
575
{
576
  char *str = SSDATA (SYMBOL_NAME (registry));
577 578
  char *re = alloca (SBYTES (SYMBOL_NAME (registry)) * 2 + 1);
  Lisp_Object regexp;
Kenichi Handa's avatar
Kenichi Handa committed
579 580
  int i, j;

581 582 583 584 585 586 587 588 589 590 591 592
  for (i = j = 0; i < SBYTES (SYMBOL_NAME (registry)); i++, j++)
    {
      if (str[i] == '.')
	re[j++] = '\\';
      else if (str[i] == '*')
	re[j++] = '.';
      re[j] = str[i];
      if (re[j] == '?')
	re[j] = '.';
    }
  re[j] = '\0';
  regexp = make_unibyte_string (re, j);
Kenichi Handa's avatar
Kenichi Handa committed
593
  for (i = 0; fc_charset_table[i].name; i++)
594
    if (fast_c_string_match_ignore_case (regexp, fc_charset_table[i].name) >= 0)
Kenichi Handa's avatar
Kenichi Handa committed
595 596 597 598 599
      break;
  if (! fc_charset_table[i].name)
    return -1;
  if (! fc_charset_table[i].fc_charset)
    {
600 601
      FcCharSet *charset = FcCharSetCreate ();
      int *uniquifier = fc_charset_table[i].uniquifier;
Kenichi Handa's avatar
Kenichi Handa committed
602

603 604 605 606 607 608
      if (! charset)
	return -1;
      for (j = 0; uniquifier[j]; j++)
	if (! FcCharSetAddChar (charset, uniquifier[j]))
	  {
	    FcCharSetDestroy (charset);
Kenichi Handa's avatar
Kenichi Handa committed
609
	    return -1;
610 611
	  }
      fc_charset_table[i].fc_charset = charset;
Kenichi Handa's avatar
Kenichi Handa committed
612 613 614 615
    }
  return i;
}

616 617
struct OpenTypeSpec
{
618 619
  Lisp_Object script;
  unsigned int script_tag, langsys_tag;
620 621 622 623
  int nfeatures[2];
  unsigned int *features[2];
};

624
#define OTF_SYM_TAG(SYM, TAG)					\
625
  do {								\
626 627
    unsigned char *p = SDATA (SYMBOL_NAME (SYM));		\
    TAG = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];	\
628 629
  } while (0)

630
#define OTF_TAG_STR(TAG, P)			\
631
  do {						\
632 633 634 635
    (P)[0] = (char) (TAG >> 24);		\
    (P)[1] = (char) ((TAG >> 16) & 0xFF);	\
    (P)[2] = (char) ((TAG >> 8) & 0xFF);	\
    (P)[3] = (char) (TAG & 0xFF);		\
636
    (P)[4] = '\0';				\
637 638
  } while (0)

639
#ifdef HAVE_LIBOTF
640 641 642 643 644 645 646
#define OTF_TAG_SYM(SYM, TAG)			\
  do {						\
    char str[5];				\
    						\
    OTF_TAG_STR (TAG, str);			\
    (SYM) = font_intern_prop (str, 4, 1);	\
  } while (0)
647
#endif
648 649


650 651 652 653 654 655 656 657 658
static struct OpenTypeSpec *
ftfont_get_open_type_spec (Lisp_Object otf_spec)
{
  struct OpenTypeSpec *spec = malloc (sizeof (struct OpenTypeSpec));
  Lisp_Object val;
  int i, j, negative;

  if (! spec)
    return NULL;
659
  spec->script = XCAR (otf_spec);
660
  if (! NILP (spec->script))
661 662 663 664 665 666 667 668
    {
      OTF_SYM_TAG (spec->script, spec->script_tag);
      val = assq_no_quit (spec->script, Votf_script_alist);
      if (CONSP (val) && SYMBOLP (XCDR (val)))
	spec->script = XCDR (val);
      else
	spec->script = Qnil;
    }
669
  else
670
    spec->script_tag = 0x44464C54; 	/* "DFLT" */
671
  otf_spec = XCDR (otf_spec);
Kenichi Handa's avatar
Kenichi Handa committed
672 673 674 675 676 677 678 679
  spec->langsys_tag = 0;
  if (! NILP (otf_spec))
    {
      val = XCAR (otf_spec);
      if (! NILP (val))
	OTF_SYM_TAG (val, spec->langsys_tag);
      otf_spec = XCDR (otf_spec);
    }
680
  spec->nfeatures[0] = spec->nfeatures[1] = 0;
Kenichi Handa's avatar
Kenichi Handa committed
681
  for (i = 0; i < 2 && ! NILP (otf_spec); i++, otf_spec = XCDR (otf_spec))
682 683 684 685 686 687 688
    {
      Lisp_Object len;

      val = XCAR (otf_spec);
      if (NILP (val))
	continue;
      len = Flength (val);
689 690 691 692
      spec->features[i] =
	(min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < XINT (len)
	 ? 0
	 : malloc (sizeof (int) * XINT (len)));
693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716
      if (! spec->features[i])
	{
	  if (i > 0 && spec->features[0])
	    free (spec->features[0]);
	  free (spec);
	  return NULL;
	}
      for (j = 0, negative = 0; CONSP (val); val = XCDR (val))
	{
	  if (NILP (XCAR (val)))
	    negative = 1;
	  else
	    {
	      unsigned int tag;

	      OTF_SYM_TAG (XCAR (val), tag);
	      spec->features[i][j++] = negative ? tag & 0x80000000 : tag;
	    }
	}
      spec->nfeatures[i] = j;
    }
  return spec;
}

717
static FcPattern *
718
ftfont_spec_pattern (Lisp_Object spec, char *otlayout, struct OpenTypeSpec **otspec, const char **langname)
Kenichi Handa's avatar
Kenichi Handa committed
719
{
Kenichi Handa's avatar
Kenichi Handa committed
720
  Lisp_Object tmp, extra;
Kenichi Handa's avatar
Kenichi Handa committed
721 722 723
  FcPattern *pattern = NULL;
  FcCharSet *charset = NULL;
  FcLangSet *langset = NULL;
724 725
  int n;
  int dpi = -1;
726
  int scalable = -1;
727
  Lisp_Object script = Qnil;
Kenichi Handa's avatar
Kenichi Handa committed
728
  Lisp_Object registry;
729
  int fc_charset_idx;
Kenichi Handa's avatar
Kenichi Handa committed
730

731 732
  if ((n = FONT_SLANT_NUMERIC (spec)) >= 0
      && n < 100)
733
    /* Fontconfig doesn't support reverse-italic/obligue.  */
734 735 736 737 738 739 740
    return NULL;

  if (INTEGERP (AREF (spec, FONT_DPI_INDEX)))
    dpi = XINT (AREF (spec, FONT_DPI_INDEX));
  if (INTEGERP (AREF (spec, FONT_AVGWIDTH_INDEX))
      && XINT (AREF (spec, FONT_AVGWIDTH_INDEX)) == 0)
    scalable = 1;
741

Kenichi Handa's avatar
Kenichi Handa committed
742 743
  registry = AREF (spec, FONT_REGISTRY_INDEX);
  if (NILP (registry)
744
      || EQ (registry, Qascii_0)
Kenichi Handa's avatar
Kenichi Handa committed
745
      || EQ (registry, Qiso10646_1)
746
      || EQ (registry, Qunicode_bmp))
747
    fc_charset_idx = -1;
Kenichi Handa's avatar
Kenichi Handa committed
748
  else
Kenichi Handa's avatar
Kenichi Handa committed
749
    {
750 751
      FcChar8 *lang;

752 753
      fc_charset_idx = ftfont_get_charset (registry);
      if (fc_charset_idx < 0)
754
	return NULL;
755
      charset = fc_charset_table[fc_charset_idx].fc_charset;
756 757
      *langname = fc_charset_table[fc_charset_idx].lang;
      lang = (FcChar8 *) *langname;
758 759 760 761 762 763 764
      if (lang)
	{
	  langset = FcLangSetCreate ();
	  if (! langset)
	    goto err;
	  FcLangSetAdd (langset, lang);
	}
Kenichi Handa's avatar
Kenichi Handa committed
765 766
    }

767
  otlayout[0] = '\0';
768 769
  for (extra = AREF (spec, FONT_EXTRA_INDEX);
       CONSP (extra); extra = XCDR (extra))
Kenichi Handa's avatar
Kenichi Handa committed
770
    {
771 772
      Lisp_Object key, val;

773 774
      key = XCAR (XCAR (extra)), val = XCDR (XCAR (extra));
      if (EQ (key, QCdpi))
775 776 777 778
	{
	  if (INTEGERP (val))
	    dpi = XINT (val);
	}
779
      else if (EQ (key, QClang))
Kenichi Handa's avatar
Kenichi Handa committed
780
	{
781 782
	  if (! langset)
	    langset = FcLangSetCreate ();
Kenichi Handa's avatar
Kenichi Handa committed
783 784
	  if (! langset)
	    goto err;
785
	  if (SYMBOLP (val))
Kenichi Handa's avatar
Kenichi Handa committed
786
	    {
787
	      if (! FcLangSetAdd (langset, SYMBOL_FcChar8 (val)))
Kenichi Handa's avatar
Kenichi Handa committed
788 789 790
		goto err;
	    }
	  else
791 792 793 794
	    for (; CONSP (val); val = XCDR (val))
	      if (SYMBOLP (XCAR (val))
		  && ! FcLangSetAdd (langset, SYMBOL_FcChar8 (XCAR (val))))
		goto err;
Kenichi Handa's avatar
Kenichi Handa committed
795
	}
796 797
      else if (EQ (key, QCotf))
	{
798 799 800 801 802 803 804 805 806
	  if (CONSP (val))
	    {
	      *otspec = ftfont_get_open_type_spec (val);
	      if (! *otspec)
		return NULL;
	      strcat (otlayout, "otlayout:");
	      OTF_TAG_STR ((*otspec)->script_tag, otlayout + 9);
	      script = (*otspec)->script;
	    }
807
	}
808 809 810 811 812
      else if (EQ (key, QCscript))
	script = val;
      else if (EQ (key, QCscalable))
	scalable = ! NILP (val);
    }
Kenichi Handa's avatar
Kenichi Handa committed
813

814 815 816 817
  if (! NILP (script) && ! charset)
    {
      Lisp_Object chars = assq_no_quit (script, Vscript_representative_chars);

818
      if (CONSP (chars) && CONSP (CDR (chars)))
819 820 821 822 823 824
	{
	  charset = FcCharSetCreate ();
	  if (! charset)
	    goto err;
	  for (chars = XCDR (chars); CONSP (chars); chars = XCDR (chars))
	    if (CHARACTERP (XCAR (chars))
825
		&& ! FcCharSetAddChar (charset, XFASTINT (XCAR (chars))))
826
	      goto err;
Kenichi Handa's avatar
Kenichi Handa committed
827 828 829
	}
    }

830
  pattern = FcPatternCreate ();
831 832 833
  if (! pattern)
    goto err;
  tmp = AREF (spec, FONT_FOUNDRY_INDEX);
834
  if (! NILP (tmp)
835 836
      && ! FcPatternAddString (pattern, FC_FOUNDRY, SYMBOL_FcChar8 (tmp)))
    goto err;
837 838 839 840
  tmp = AREF (spec, FONT_FAMILY_INDEX);
  if (! NILP (tmp)
      && ! FcPatternAddString (pattern, FC_FAMILY, SYMBOL_FcChar8 (tmp)))
    goto err;
Kenichi Handa's avatar
Kenichi Handa committed
841 842 843 844 845 846
  if (charset
      && ! FcPatternAddCharSet (pattern, FC_CHARSET, charset))
    goto err;
  if (langset
      && ! FcPatternAddLangSet (pattern, FC_LANG, langset))
    goto err;
847 848 849 850
  if (dpi >= 0
      && ! FcPatternAddDouble (pattern, FC_DPI, dpi))
    goto err;
  if (scalable >= 0
Kenichi Handa's avatar
Kenichi Handa committed
851
      && ! FcPatternAddBool (pattern, FC_SCALABLE, scalable ? FcTrue : FcFalse))
852
    goto err;
853

854
  goto finish;
Kenichi Handa's avatar
Kenichi Handa committed
855

856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875
 err:
  /* We come here because of unexpected error in fontconfig API call
     (usually insufficient memory).  */
  if (pattern)
    {
      FcPatternDestroy (pattern);
      pattern = NULL;
    }
  if (*otspec)
    {
      if ((*otspec)->nfeatures[0] > 0)
	free ((*otspec)->features[0]);
      if ((*otspec)->nfeatures[1] > 0)
	free ((*otspec)->features[1]);
      free (*otspec);
      *otspec = NULL;
    }

 finish:
  if (langset) FcLangSetDestroy (langset);
876
  if (charset && fc_charset_idx < 0) FcCharSetDestroy (charset);
877 878 879 880
  return pattern;
}

static Lisp_Object
881
ftfont_list (Lisp_Object frame, Lisp_Object spec)
882
{
Kenichi Handa's avatar
Kenichi Handa committed
883
  Lisp_Object val = Qnil, family, adstyle;
884 885 886 887
  int i;
  FcPattern *pattern;
  FcFontSet *fontset = NULL;
  FcObjectSet *objset = NULL;
888 889
  FcCharSet *charset;
  Lisp_Object chars = Qnil;
890 891
  char otlayout[15];		/* For "otlayout:XXXX" */
  struct OpenTypeSpec *otspec = NULL;
892
  int spacing = -1;
893
  const char *langname = NULL;
Juanma Barranquero's avatar
Juanma Barranquero committed
894

895 896 897 898 899 900
  if (! fc_initialized)
    {
      FcInit ();
      fc_initialized = 1;
    }

901
  pattern = ftfont_spec_pattern (spec, otlayout, &otspec, &langname);
902 903
  if (! pattern)
    return Qnil;
904 905 906 907 908 909 910 911 912 913 914
  if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) != FcResultMatch)
    {
      val = assq_no_quit (QCscript, AREF (spec, FONT_EXTRA_INDEX));
      if (! NILP (val))
	{
	  val = assq_no_quit (XCDR (val), Vscript_representative_chars);
	  if (CONSP (val) && VECTORP (XCDR (val)))
	    chars = XCDR (val);
	}
      val = Qnil;
    }
915 916
  if (INTEGERP (AREF (spec, FONT_SPACING_INDEX)))
    spacing = XINT (AREF (spec, FONT_SPACING_INDEX));
917 918 919 920 921
  family = AREF (spec, FONT_FAMILY_INDEX);
  if (! NILP (family))
    {
      Lisp_Object resolved;

922
      resolved = ftfont_resolve_generic_family (family, pattern);
923 924 925 926 927 928 929 930
      if (! NILP (resolved))
	{
	  FcPatternDel (pattern, FC_FAMILY);
	  if (! FcPatternAddString (pattern, FC_FAMILY,
				    SYMBOL_FcChar8 (resolved)))
	    goto err;
	}
    }
Kenichi Handa's avatar
Kenichi Handa committed
931 932 933
  adstyle = AREF (spec, FONT_ADSTYLE_INDEX);
  if (! NILP (adstyle) && SBYTES (SYMBOL_NAME (adstyle)) == 0)
    adstyle = Qnil;
934
  objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT,