diff options
| author | Kenichi Handa | 2008-05-19 07:21:25 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2008-05-19 07:21:25 +0000 |
| commit | 21988a0804b92c2130fe780ef0c9d7a66ff3ad45 (patch) | |
| tree | a85e04ddc8df0dfc9594c1540cb541935edd84a2 /src | |
| parent | 686ee703662283c9f84e9a72b8d8fb8a86d6c48c (diff) | |
| download | emacs-21988a0804b92c2130fe780ef0c9d7a66ff3ad45.tar.gz emacs-21988a0804b92c2130fe780ef0c9d7a66ff3ad45.zip | |
(cs_iso8859_1): Deleted.
(ft_face_cache): New variable.
(struct ftfont_info): New member fc_charset_idx;
(ftfont_build_basic_charsets): Deleted.
(fc_charset_table): New variable.
(ftfont_pattern_entity): New arg fc_charset_idx. Store (FILENAME
. FC_CHARSET_IDX) as :font-entity property in the font entity.
Callers changed.
(ftfont_lookup_cache, ftfont_get_charset): New funcitons.
(ftfont_spec_pattern): New argument fc_charset_idx. Check
registry more rigidly. Callers changed.
(ftfont_open, ftfont_close, ftfont_has_char): Adjustd for the
change of :font-entity property of the font.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ftfont.c | 341 |
1 files changed, 205 insertions, 136 deletions
diff --git a/src/ftfont.c b/src/ftfont.c index e11de08259b..6c86a7872e9 100644 --- a/src/ftfont.c +++ b/src/ftfont.c | |||
| @@ -51,9 +51,8 @@ static FT_Library ft_library; | |||
| 51 | /* Cache for FreeType fonts. */ | 51 | /* Cache for FreeType fonts. */ |
| 52 | static Lisp_Object freetype_font_cache; | 52 | static Lisp_Object freetype_font_cache; |
| 53 | 53 | ||
| 54 | /* Fontconfig's charset used for finding fonts of registry | 54 | /* Cache for FT_Face */ |
| 55 | "iso8859-1". */ | 55 | static Lisp_Object ft_face_cache; |
| 56 | static FcCharSet *cs_iso8859_1; | ||
| 57 | 56 | ||
| 58 | /* The actual structure for FreeType font that can be casted to struct | 57 | /* The actual structure for FreeType font that can be casted to struct |
| 59 | font. */ | 58 | font. */ |
| @@ -62,71 +61,95 @@ struct ftfont_info | |||
| 62 | { | 61 | { |
| 63 | struct font font; | 62 | struct font font; |
| 64 | FT_Size ft_size; | 63 | FT_Size ft_size; |
| 64 | int fc_charset_idx; | ||
| 65 | #ifdef HAVE_LIBOTF | 65 | #ifdef HAVE_LIBOTF |
| 66 | int maybe_otf; /* Flag to tell if this may be OTF or not. */ | 66 | int maybe_otf; /* Flag to tell if this may be OTF or not. */ |
| 67 | OTF *otf; | 67 | OTF *otf; |
| 68 | #endif /* HAVE_LIBOTF */ | 68 | #endif /* HAVE_LIBOTF */ |
| 69 | }; | 69 | }; |
| 70 | 70 | ||
| 71 | static int ftfont_build_basic_charsets P_ ((void)); | 71 | static Lisp_Object ftfont_pattern_entity P_ ((FcPattern *, Lisp_Object, int)); |
| 72 | static Lisp_Object ftfont_pattern_entity P_ ((FcPattern *, Lisp_Object)); | 72 | |
| 73 | static Lisp_Object ftfont_list_generic_family P_ ((Lisp_Object)); | 73 | static Lisp_Object ftfont_list_generic_family P_ ((Lisp_Object)); |
| 74 | Lisp_Object ftfont_font_format P_ ((FcPattern *)); | 74 | Lisp_Object ftfont_font_format P_ ((FcPattern *)); |
| 75 | 75 | ||
| 76 | #define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM)) | 76 | #define SYMBOL_FcChar8(SYM) (FcChar8 *) SDATA (SYMBOL_NAME (SYM)) |
| 77 | 77 | ||
| 78 | static int | 78 | static struct |
| 79 | ftfont_build_basic_charsets () | ||
| 80 | { | 79 | { |
| 81 | FcChar32 c; | 80 | /* charset name */ |
| 82 | 81 | char *name; | |
| 83 | cs_iso8859_1 = FcCharSetCreate (); | 82 | /* characters to distinguish the charset from the others */ |
| 84 | if (! cs_iso8859_1) | 83 | int uniquifier[6]; |
| 85 | return -1; | 84 | /* set in syms_of_ftfont */ |
| 86 | for (c = ' '; c < 127; c++) | 85 | int charset_id; |
| 87 | if (! FcCharSetAddChar (cs_iso8859_1, c)) | 86 | /* set on demand */ |
| 88 | return -1; | 87 | FcCharSet *fc_charset; |
| 89 | #if 0 | 88 | } fc_charset_table[] = |
| 90 | /* This part is currently disabled. Should be fixed later. */ | 89 | { { "iso-8859-1", { 0x00A0, 0x00A1, 0x00B4, 0x00BC, 0x00D0 }, -1 }, |
| 91 | for (c = 192; c < 256; c++) | 90 | { "iso-8859-2", { 0x00A0, 0x010E }}, |
| 92 | if (! FcCharSetAddChar (cs_iso8859_1, c)) | 91 | { "iso-8859-3", { 0x00A0, 0x0108 }}, |
| 93 | return -1; | 92 | { "iso-8859-4", { 0x00A0, 0x00AF, 0x0128, 0x0156, 0x02C7 }}, |
| 94 | #endif | 93 | { "iso-8859-5", { 0x00A0, 0x0401 }}, |
| 95 | return 0; | 94 | { "iso-8859-6", { 0x00A0, 0x060C }}, |
| 96 | } | 95 | { "iso-8859-7", { 0x00A0, 0x0384 }}, |
| 96 | { "iso-8859-8", { 0x00A0, 0x05D0 }}, | ||
| 97 | { "iso-8859-9", { 0x00A0, 0x00A1, 0x00BC, 0x011E }}, | ||
| 98 | { "iso-8859-10", { 0x00A0, 0x00D0, 0x0128, 0x2015 }}, | ||
| 99 | { "iso-8859-11", { 0x00A0, 0x0E01 }}, | ||
| 100 | { "iso-8859-13", { 0x00A0, 0x201C }}, | ||
| 101 | { "iso-8859-14", { 0x00A0, 0x0174 }}, | ||
| 102 | { "iso-8859-15", { 0x00A0, 0x00A1, 0x00D0, 0x0152 }}, | ||
| 103 | { "iso-8859-16", { 0x00A0, 0x0218}}, | ||
| 104 | { "chinese-gb2312", { 0x4E13 }}, | ||
| 105 | { "big5", { 0xF6B1 }}, | ||
| 106 | { "japanese-jisx0208", { 0x4E55 }}, | ||
| 107 | { "korean-ksc5601", { 0xAC00 }}, | ||
| 108 | { "chinese-cns11643-1", { 0xFE32 }}, | ||
| 109 | { "chinese-cns11643-2", { 0x4E33, 0x7934 }}, | ||
| 110 | { "chinese-cns11643-3", { 0x201A9 }}, | ||
| 111 | { "chinese-cns11643-4", { 0x20057 }}, | ||
| 112 | { "chinese-cns11643-5", { 0x20000 }}, | ||
| 113 | { "chinese-cns11643-6", { 0x20003 }}, | ||
| 114 | { "chinese-cns11643-7", { 0x20055 }}, | ||
| 115 | { "chinese-gbk", { 0x4E06 }}, | ||
| 116 | { "japanese-jisx0212", { 0x4E44 }}, | ||
| 117 | { "japanese-jisx0213-1", { 0xFA10 }}, | ||
| 118 | { "japanese-jisx0213-2", { 0xFA49 }}, | ||
| 119 | { "japanese-jisx0213.2004-1", { 0x20B9F }}, | ||
| 120 | { "viscii", { 0x1EA0, 0x1EAE, 0x1ED2 }}, | ||
| 121 | { "tis620", { 0x0E01 }}, | ||
| 122 | { "windows-1251", { 0x0401, 0x0490 }}, | ||
| 123 | { "koi8-r", { 0x0401, 0x2219 }}, | ||
| 124 | { "mule-lao", { 0x0E81 }}, | ||
| 125 | { NULL } | ||
| 126 | }; | ||
| 97 | 127 | ||
| 98 | extern Lisp_Object Qc, Qm, Qp, Qd; | 128 | extern Lisp_Object Qc, Qm, Qp, Qd; |
| 99 | 129 | ||
| 100 | static Lisp_Object | 130 | static Lisp_Object |
| 101 | ftfont_pattern_entity (p, registry) | 131 | ftfont_pattern_entity (p, registry, fc_charset_idx) |
| 102 | FcPattern *p; | 132 | FcPattern *p; |
| 103 | Lisp_Object registry; | 133 | Lisp_Object registry; |
| 134 | int fc_charset_idx; | ||
| 104 | { | 135 | { |
| 105 | Lisp_Object entity; | 136 | Lisp_Object entity; |
| 106 | FcChar8 *file, *fontformat; | 137 | char *file, *str; |
| 107 | FcCharSet *charset; | ||
| 108 | FcChar8 *str; | ||
| 109 | int numeric; | 138 | int numeric; |
| 110 | double dbl; | 139 | double dbl; |
| 111 | FcBool b; | 140 | FcBool b; |
| 112 | 141 | ||
| 113 | if (FcPatternGetString (p, FC_FILE, 0, &file) != FcResultMatch) | 142 | if (FcPatternGetString (p, FC_FILE, 0, (FcChar8 **) &file) != FcResultMatch) |
| 114 | return Qnil; | 143 | return Qnil; |
| 115 | if (FcPatternGetCharSet (p, FC_CHARSET, 0, &charset) != FcResultMatch) | ||
| 116 | charset = NULL; | ||
| 117 | #ifdef FC_FONTFORMAT | ||
| 118 | if (FcPatternGetString (p, FC_FONTFORMAT, 0, &fontformat) != FcResultMatch) | ||
| 119 | #endif /* FC_FONTFORMAT */ | ||
| 120 | fontformat = NULL; | ||
| 121 | 144 | ||
| 122 | entity = font_make_entity (); | 145 | entity = font_make_entity (); |
| 123 | 146 | ||
| 124 | ASET (entity, FONT_TYPE_INDEX, Qfreetype); | 147 | ASET (entity, FONT_TYPE_INDEX, Qfreetype); |
| 125 | ASET (entity, FONT_REGISTRY_INDEX, registry); | 148 | ASET (entity, FONT_REGISTRY_INDEX, registry); |
| 126 | 149 | ||
| 127 | if (FcPatternGetString (p, FC_FOUNDRY, 0, &str) == FcResultMatch) | 150 | if (FcPatternGetString (p, FC_FOUNDRY, 0, (FcChar8 **) &str) == FcResultMatch) |
| 128 | ASET (entity, FONT_FOUNDRY_INDEX, font_intern_prop (str, strlen (str))); | 151 | ASET (entity, FONT_FOUNDRY_INDEX, font_intern_prop (str, strlen (str))); |
| 129 | if (FcPatternGetString (p, FC_FAMILY, 0, &str) == FcResultMatch) | 152 | if (FcPatternGetString (p, FC_FAMILY, 0, (FcChar8 **) &str) == FcResultMatch) |
| 130 | ASET (entity, FONT_FAMILY_INDEX, font_intern_prop (str, strlen (str))); | 153 | ASET (entity, FONT_FAMILY_INDEX, font_intern_prop (str, strlen (str))); |
| 131 | if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch) | 154 | if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch) |
| 132 | { | 155 | { |
| @@ -158,26 +181,10 @@ ftfont_pattern_entity (p, registry) | |||
| 158 | && b == FcTrue) | 181 | && b == FcTrue) |
| 159 | ASET (entity, FONT_AVGWIDTH_INDEX, make_number (0)); | 182 | ASET (entity, FONT_AVGWIDTH_INDEX, make_number (0)); |
| 160 | 183 | ||
| 161 | file = FcStrCopy (file); | 184 | font_put_extra (entity, QCfont_entity, |
| 162 | if (! file) | 185 | Fcons (make_unibyte_string ((char *) file, |
| 163 | return Qnil; | 186 | strlen ((char *) file)), |
| 164 | p = FcPatternCreate (); | 187 | make_number (fc_charset_idx))); |
| 165 | if (! p) | ||
| 166 | return Qnil; | ||
| 167 | |||
| 168 | if (FcPatternAddString (p, FC_FILE, file) == FcFalse | ||
| 169 | || (charset | ||
| 170 | && FcPatternAddCharSet (p, FC_CHARSET, charset) == FcFalse) | ||
| 171 | #ifdef FC_FONTFORMAT | ||
| 172 | || (fontformat | ||
| 173 | && FcPatternAddString (p, FC_FONTFORMAT, fontformat) == FcFalse) | ||
| 174 | #endif /* FC_FONTFORMAT */ | ||
| 175 | ) | ||
| 176 | { | ||
| 177 | FcPatternDestroy (p); | ||
| 178 | return Qnil; | ||
| 179 | } | ||
| 180 | font_put_extra (entity, QCfont_entity, make_save_value (p, 0)); | ||
| 181 | return entity; | 188 | return entity; |
| 182 | } | 189 | } |
| 183 | 190 | ||
| @@ -188,12 +195,12 @@ static Lisp_Object | |||
| 188 | ftfont_list_generic_family (family) | 195 | ftfont_list_generic_family (family) |
| 189 | Lisp_Object family; | 196 | Lisp_Object family; |
| 190 | { | 197 | { |
| 191 | Lisp_Object slot, list, val; | 198 | Lisp_Object slot, list; |
| 192 | FcObjectSet *objset = NULL; | 199 | FcObjectSet *objset = NULL; |
| 193 | FcPattern *pattern = NULL, *pat = NULL; | 200 | FcPattern *pattern = NULL, *pat = NULL; |
| 194 | FcFontSet *fontset = NULL; | 201 | FcFontSet *fontset = NULL; |
| 195 | FcChar8 *fam; | 202 | FcChar8 *fam; |
| 196 | int i, j; | 203 | int i; |
| 197 | 204 | ||
| 198 | if (EQ (family, Qmono)) | 205 | if (EQ (family, Qmono)) |
| 199 | family = Qmonospace; | 206 | family = Qmonospace; |
| @@ -243,6 +250,35 @@ ftfont_list_generic_family (family) | |||
| 243 | return list; | 250 | return list; |
| 244 | } | 251 | } |
| 245 | 252 | ||
| 253 | Lisp_Object | ||
| 254 | ftfont_lookup_cache (filename) | ||
| 255 | Lisp_Object filename; | ||
| 256 | { | ||
| 257 | Lisp_Object cache, val; | ||
| 258 | |||
| 259 | cache = assoc_no_quit (filename, ft_face_cache); | ||
| 260 | if (NILP (cache)) | ||
| 261 | { | ||
| 262 | val = make_save_value (NULL, 0); | ||
| 263 | cache = Fcons (filename, val); | ||
| 264 | ft_face_cache = Fcons (cache, ft_face_cache); | ||
| 265 | } | ||
| 266 | else | ||
| 267 | val = XCDR (cache); | ||
| 268 | if (! XSAVE_VALUE (val)->pointer) | ||
| 269 | { | ||
| 270 | FT_Face ft_face; | ||
| 271 | |||
| 272 | if (! ft_library | ||
| 273 | && FT_Init_FreeType (&ft_library) != 0) | ||
| 274 | return Qnil; | ||
| 275 | if (FT_New_Face (ft_library, (char *) SDATA (filename), 0, &ft_face) != 0) | ||
| 276 | return Qnil; | ||
| 277 | XSAVE_VALUE (val)->pointer = ft_face; | ||
| 278 | } | ||
| 279 | return cache; | ||
| 280 | } | ||
| 281 | |||
| 246 | static Lisp_Object ftfont_get_cache P_ ((FRAME_PTR)); | 282 | static Lisp_Object ftfont_get_cache P_ ((FRAME_PTR)); |
| 247 | static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object)); | 283 | static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object)); |
| 248 | static Lisp_Object ftfont_match P_ ((Lisp_Object, Lisp_Object)); | 284 | static Lisp_Object ftfont_match P_ ((Lisp_Object, Lisp_Object)); |
| @@ -303,6 +339,50 @@ ftfont_get_cache (f) | |||
| 303 | return freetype_font_cache; | 339 | return freetype_font_cache; |
| 304 | } | 340 | } |
| 305 | 341 | ||
| 342 | static int | ||
| 343 | ftfont_get_charset (registry) | ||
| 344 | Lisp_Object registry; | ||
| 345 | { | ||
| 346 | struct charset *encoding; | ||
| 347 | int i, j; | ||
| 348 | |||
| 349 | if (font_registry_charsets (registry, &encoding, NULL) < 0) | ||
| 350 | return -1; | ||
| 351 | if (fc_charset_table[0].charset_id < 0) | ||
| 352 | /* Setup charset_id field of all elements. */ | ||
| 353 | for (i = 0; fc_charset_table[i].name; i++) | ||
| 354 | { | ||
| 355 | Lisp_Object sym = intern (fc_charset_table[i].name); | ||
| 356 | |||
| 357 | if (CHARSETP (sym)) | ||
| 358 | fc_charset_table[i].charset_id = XINT (CHARSET_SYMBOL_ID (sym)); | ||
| 359 | else | ||
| 360 | fc_charset_table[i].charset_id = -1; | ||
| 361 | } | ||
| 362 | |||
| 363 | for (i = 0; fc_charset_table[i].name; i++) | ||
| 364 | if (encoding->id == fc_charset_table[i].charset_id) | ||
| 365 | break; | ||
| 366 | if (! fc_charset_table[i].name) | ||
| 367 | return -1; | ||
| 368 | if (! fc_charset_table[i].fc_charset) | ||
| 369 | { | ||
| 370 | FcCharSet *charset = FcCharSetCreate (); | ||
| 371 | int *uniquifier = fc_charset_table[i].uniquifier; | ||
| 372 | |||
| 373 | if (! charset) | ||
| 374 | return -1; | ||
| 375 | for (j = 0; uniquifier[j]; j++) | ||
| 376 | if (! FcCharSetAddChar (charset, uniquifier[j])) | ||
| 377 | { | ||
| 378 | FcCharSetDestroy (charset); | ||
| 379 | return -1; | ||
| 380 | } | ||
| 381 | fc_charset_table[i].fc_charset = charset; | ||
| 382 | } | ||
| 383 | return i; | ||
| 384 | } | ||
| 385 | |||
| 306 | struct OpenTypeSpec | 386 | struct OpenTypeSpec |
| 307 | { | 387 | { |
| 308 | Lisp_Object script; | 388 | Lisp_Object script; |
| @@ -390,14 +470,17 @@ ftfont_get_open_type_spec (Lisp_Object otf_spec) | |||
| 390 | return spec; | 470 | return spec; |
| 391 | } | 471 | } |
| 392 | 472 | ||
| 473 | static FcPattern *ftfont_spec_pattern P_ ((Lisp_Object, int *, char *, | ||
| 474 | struct OpenTypeSpec **)); | ||
| 475 | |||
| 393 | static FcPattern * | 476 | static FcPattern * |
| 394 | ftfont_spec_pattern (spec, otlayout, otspec) | 477 | ftfont_spec_pattern (spec, fc_charset_idx, otlayout, otspec) |
| 395 | Lisp_Object spec; | 478 | Lisp_Object spec; |
| 479 | int *fc_charset_idx; | ||
| 396 | char *otlayout; | 480 | char *otlayout; |
| 397 | struct OpenTypeSpec **otspec; | 481 | struct OpenTypeSpec **otspec; |
| 398 | { | 482 | { |
| 399 | Lisp_Object val, tmp, extra; | 483 | Lisp_Object tmp, extra; |
| 400 | int i; | ||
| 401 | FcPattern *pattern = NULL; | 484 | FcPattern *pattern = NULL; |
| 402 | FcCharSet *charset = NULL; | 485 | FcCharSet *charset = NULL; |
| 403 | FcLangSet *langset = NULL; | 486 | FcLangSet *langset = NULL; |
| @@ -407,7 +490,7 @@ ftfont_spec_pattern (spec, otlayout, otspec) | |||
| 407 | int scalable = -1; | 490 | int scalable = -1; |
| 408 | Lisp_Object name = Qnil; | 491 | Lisp_Object name = Qnil; |
| 409 | Lisp_Object script = Qnil; | 492 | Lisp_Object script = Qnil; |
| 410 | Lisp_Object registry = Qunicode_bmp; | 493 | Lisp_Object registry; |
| 411 | 494 | ||
| 412 | if (! NILP (AREF (spec, FONT_ADSTYLE_INDEX)) | 495 | if (! NILP (AREF (spec, FONT_ADSTYLE_INDEX)) |
| 413 | && SBYTES (SYMBOL_NAME (AREF (spec, FONT_ADSTYLE_INDEX))) > 0) | 496 | && SBYTES (SYMBOL_NAME (AREF (spec, FONT_ADSTYLE_INDEX))) > 0) |
| @@ -426,20 +509,18 @@ ftfont_spec_pattern (spec, otlayout, otspec) | |||
| 426 | && XINT (AREF (spec, FONT_AVGWIDTH_INDEX)) == 0) | 509 | && XINT (AREF (spec, FONT_AVGWIDTH_INDEX)) == 0) |
| 427 | scalable = 1; | 510 | scalable = 1; |
| 428 | 511 | ||
| 429 | if (! NILP (AREF (spec, FONT_REGISTRY_INDEX))) | 512 | registry = AREF (spec, FONT_REGISTRY_INDEX); |
| 513 | if (NILP (registry) | ||
| 514 | || EQ (registry, Qiso10646_1) | ||
| 515 | || EQ (registry, Qunicode_bmp) | ||
| 516 | || EQ (registry, Qunicode_sip)) | ||
| 517 | *fc_charset_idx = -1; | ||
| 518 | else | ||
| 430 | { | 519 | { |
| 431 | registry = AREF (spec, FONT_REGISTRY_INDEX); | 520 | *fc_charset_idx = ftfont_get_charset (registry); |
| 432 | if (EQ (registry, Qiso8859_1)) | 521 | if (*fc_charset_idx < 0) |
| 433 | { | ||
| 434 | if (! cs_iso8859_1 | ||
| 435 | && ftfont_build_basic_charsets () < 0) | ||
| 436 | return NULL; | ||
| 437 | charset = cs_iso8859_1; | ||
| 438 | } | ||
| 439 | else if (! EQ (registry, Qiso10646_1) | ||
| 440 | && ! EQ (registry, Qunicode_bmp) | ||
| 441 | && ! EQ (registry, Qunicode_sip)) | ||
| 442 | return NULL; | 522 | return NULL; |
| 523 | charset = fc_charset_table[*fc_charset_idx].fc_charset; | ||
| 443 | } | 524 | } |
| 444 | 525 | ||
| 445 | otlayout[0] = '\0'; | 526 | otlayout[0] = '\0'; |
| @@ -547,7 +628,6 @@ ftfont_spec_pattern (spec, otlayout, otspec) | |||
| 547 | } | 628 | } |
| 548 | 629 | ||
| 549 | finish: | 630 | finish: |
| 550 | if (charset && charset != cs_iso8859_1) FcCharSetDestroy (charset); | ||
| 551 | if (langset) FcLangSetDestroy (langset); | 631 | if (langset) FcLangSetDestroy (langset); |
| 552 | return pattern; | 632 | return pattern; |
| 553 | } | 633 | } |
| @@ -556,16 +636,12 @@ static Lisp_Object | |||
| 556 | ftfont_list (frame, spec) | 636 | ftfont_list (frame, spec) |
| 557 | Lisp_Object frame, spec; | 637 | Lisp_Object frame, spec; |
| 558 | { | 638 | { |
| 559 | Lisp_Object val, tmp, registry, family, family_list; | 639 | Lisp_Object val, registry, family, family_list; |
| 560 | int i; | 640 | int i; |
| 561 | FcPattern *pattern; | 641 | FcPattern *pattern; |
| 562 | FcFontSet *fontset = NULL; | 642 | FcFontSet *fontset = NULL; |
| 563 | FcObjectSet *objset = NULL; | 643 | FcObjectSet *objset = NULL; |
| 564 | double pixel_size = 0; | 644 | int fc_charset_idx; |
| 565 | int weight = -1, slant = -1, width = -1; | ||
| 566 | double dpi = -1; | ||
| 567 | int spacing = -1; | ||
| 568 | int scalable = -1; | ||
| 569 | char otlayout[15]; /* For "otlayout:XXXX" */ | 645 | char otlayout[15]; /* For "otlayout:XXXX" */ |
| 570 | struct OpenTypeSpec *otspec = NULL; | 646 | struct OpenTypeSpec *otspec = NULL; |
| 571 | 647 | ||
| @@ -575,7 +651,7 @@ ftfont_list (frame, spec) | |||
| 575 | fc_initialized = 1; | 651 | fc_initialized = 1; |
| 576 | } | 652 | } |
| 577 | 653 | ||
| 578 | pattern = ftfont_spec_pattern (spec, otlayout, &otspec); | 654 | pattern = ftfont_spec_pattern (spec, &fc_charset_idx, otlayout, &otspec); |
| 579 | if (! pattern) | 655 | if (! pattern) |
| 580 | return Qnil; | 656 | return Qnil; |
| 581 | objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT, | 657 | objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT, |
| @@ -584,9 +660,6 @@ ftfont_list (frame, spec) | |||
| 584 | #ifdef FC_CAPABILITY | 660 | #ifdef FC_CAPABILITY |
| 585 | FC_CAPABILITY, | 661 | FC_CAPABILITY, |
| 586 | #endif /* FC_CAPABILITY */ | 662 | #endif /* FC_CAPABILITY */ |
| 587 | #ifdef FC_FONTFORMAT | ||
| 588 | FC_FONTFORMAT, | ||
| 589 | #endif /* FC_FONTFORMAT */ | ||
| 590 | NULL); | 663 | NULL); |
| 591 | if (! objset) | 664 | if (! objset) |
| 592 | goto err; | 665 | goto err; |
| @@ -618,8 +691,6 @@ ftfont_list (frame, spec) | |||
| 618 | for (i = 0; i < fontset->nfont; i++) | 691 | for (i = 0; i < fontset->nfont; i++) |
| 619 | { | 692 | { |
| 620 | Lisp_Object entity; | 693 | Lisp_Object entity; |
| 621 | int n; | ||
| 622 | double dbl; | ||
| 623 | 694 | ||
| 624 | #ifdef FC_CAPABILITY | 695 | #ifdef FC_CAPABILITY |
| 625 | if (otlayout[0]) | 696 | if (otlayout[0]) |
| @@ -655,7 +726,8 @@ ftfont_list (frame, spec) | |||
| 655 | continue; | 726 | continue; |
| 656 | } | 727 | } |
| 657 | #endif /* HAVE_LIBOTF */ | 728 | #endif /* HAVE_LIBOTF */ |
| 658 | entity = ftfont_pattern_entity (fontset->fonts[i], registry); | 729 | entity = ftfont_pattern_entity (fontset->fonts[i], registry, |
| 730 | fc_charset_idx); | ||
| 659 | if (! NILP (entity)) | 731 | if (! NILP (entity)) |
| 660 | val = Fcons (entity, val); | 732 | val = Fcons (entity, val); |
| 661 | } | 733 | } |
| @@ -680,11 +752,12 @@ static Lisp_Object | |||
| 680 | ftfont_match (frame, spec) | 752 | ftfont_match (frame, spec) |
| 681 | Lisp_Object frame, spec; | 753 | Lisp_Object frame, spec; |
| 682 | { | 754 | { |
| 683 | Lisp_Object extra, val, entity; | 755 | Lisp_Object entity; |
| 684 | FcPattern *pattern, *match = NULL; | 756 | FcPattern *pattern, *match = NULL; |
| 685 | FcResult result; | 757 | FcResult result; |
| 686 | char otlayout[15]; /* For "otlayout:XXXX" */ | 758 | char otlayout[15]; /* For "otlayout:XXXX" */ |
| 687 | struct OpenTypeSpec *otspec = NULL; | 759 | struct OpenTypeSpec *otspec = NULL; |
| 760 | int fc_charset_idx; | ||
| 688 | 761 | ||
| 689 | if (! fc_initialized) | 762 | if (! fc_initialized) |
| 690 | { | 763 | { |
| @@ -692,7 +765,7 @@ ftfont_match (frame, spec) | |||
| 692 | fc_initialized = 1; | 765 | fc_initialized = 1; |
| 693 | } | 766 | } |
| 694 | 767 | ||
| 695 | pattern = ftfont_spec_pattern (spec, otlayout, &otspec); | 768 | pattern = ftfont_spec_pattern (spec, &fc_charset_idx, otlayout, &otspec); |
| 696 | if (! pattern) | 769 | if (! pattern) |
| 697 | return Qnil; | 770 | return Qnil; |
| 698 | 771 | ||
| @@ -710,7 +783,7 @@ ftfont_match (frame, spec) | |||
| 710 | match = FcFontMatch (NULL, pattern, &result); | 783 | match = FcFontMatch (NULL, pattern, &result); |
| 711 | if (match) | 784 | if (match) |
| 712 | { | 785 | { |
| 713 | entity = ftfont_pattern_entity (match, Qunicode_bmp); | 786 | entity = ftfont_pattern_entity (match, Qunicode_bmp, fc_charset_idx); |
| 714 | FcPatternDestroy (match); | 787 | FcPatternDestroy (match); |
| 715 | if (! NILP (AREF (spec, FONT_FAMILY_INDEX)) | 788 | if (! NILP (AREF (spec, FONT_FAMILY_INDEX)) |
| 716 | && NILP (assq_no_quit (AREF (spec, FONT_FAMILY_INDEX), | 789 | && NILP (assq_no_quit (AREF (spec, FONT_FAMILY_INDEX), |
| @@ -781,10 +854,10 @@ ftfont_open (f, entity, pixel_size) | |||
| 781 | FT_Face ft_face; | 854 | FT_Face ft_face; |
| 782 | FT_Size ft_size; | 855 | FT_Size ft_size; |
| 783 | FT_UInt size; | 856 | FT_UInt size; |
| 784 | Lisp_Object val, font_object; | 857 | Lisp_Object val, filename, cache, font_object; |
| 858 | int fc_charset_idx; | ||
| 785 | FcPattern *pattern; | 859 | FcPattern *pattern; |
| 786 | FcChar8 *file = NULL, *fmt = NULL; | 860 | int scalable; |
| 787 | FcBool scalable; | ||
| 788 | int spacing; | 861 | int spacing; |
| 789 | char name[256]; | 862 | char name[256]; |
| 790 | int i, len; | 863 | int i, len; |
| @@ -794,26 +867,17 @@ ftfont_open (f, entity, pixel_size) | |||
| 794 | if (! CONSP (val)) | 867 | if (! CONSP (val)) |
| 795 | return Qnil; | 868 | return Qnil; |
| 796 | val = XCDR (val); | 869 | val = XCDR (val); |
| 797 | pattern = XSAVE_VALUE (val)->pointer; | 870 | filename = XCAR (val); |
| 798 | if (XSAVE_VALUE (val)->integer == 0) | 871 | fc_charset_idx = XINT (XCDR (val)); |
| 799 | { | 872 | cache = ftfont_lookup_cache (filename); |
| 800 | /* We have not yet created FT_Face for this font. */ | 873 | if (NILP (cache)) |
| 801 | if (! ft_library | 874 | return Qnil; |
| 802 | && FT_Init_FreeType (&ft_library) != 0) | 875 | filename = XCAR (cache); |
| 803 | return Qnil; | 876 | val = XCDR (cache); |
| 804 | if (FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch) | 877 | ft_face = XSAVE_VALUE (val)->pointer; |
| 805 | return Qnil; | 878 | if (XSAVE_VALUE (val)->integer > 0) |
| 806 | if (FT_New_Face (ft_library, (char *) file, 0, &ft_face) != 0) | ||
| 807 | return Qnil; | ||
| 808 | FcPatternAddFTFace (pattern, FC_FT_FACE, ft_face); | ||
| 809 | ft_size = ft_face->size; | ||
| 810 | XSAVE_VALUE (val)->integer++; | ||
| 811 | } | ||
| 812 | else | ||
| 813 | { | 879 | { |
| 814 | if (FcPatternGetFTFace (pattern, FC_FT_FACE, 0, &ft_face) | 880 | /* FT_Face in this cache is already used by the different size. */ |
| 815 | != FcResultMatch) | ||
| 816 | return Qnil; | ||
| 817 | if (FT_New_Size (ft_face, &ft_size) != 0) | 881 | if (FT_New_Size (ft_face, &ft_size) != 0) |
| 818 | return Qnil; | 882 | return Qnil; |
| 819 | if (FT_Activate_Size (ft_size) != 0) | 883 | if (FT_Activate_Size (ft_size) != 0) |
| @@ -821,8 +885,8 @@ ftfont_open (f, entity, pixel_size) | |||
| 821 | FT_Done_Size (ft_size); | 885 | FT_Done_Size (ft_size); |
| 822 | return Qnil; | 886 | return Qnil; |
| 823 | } | 887 | } |
| 824 | } | 888 | } |
| 825 | 889 | XSAVE_VALUE (val)->integer++; | |
| 826 | size = XINT (AREF (entity, FONT_SIZE_INDEX)); | 890 | size = XINT (AREF (entity, FONT_SIZE_INDEX)); |
| 827 | if (size == 0) | 891 | if (size == 0) |
| 828 | size = pixel_size; | 892 | size = pixel_size; |
| @@ -847,15 +911,12 @@ ftfont_open (f, entity, pixel_size) | |||
| 847 | else | 911 | else |
| 848 | ASET (font_object, FONT_FULLNAME_INDEX, | 912 | ASET (font_object, FONT_FULLNAME_INDEX, |
| 849 | AREF (font_object, FONT_NAME_INDEX)); | 913 | AREF (font_object, FONT_NAME_INDEX)); |
| 850 | if (! file | 914 | ASET (font_object, FONT_FILE_INDEX, filename); |
| 851 | && ! FcPatternGetString (pattern, FC_FILE, 0, &file) != FcResultMatch) | ||
| 852 | return Qnil; | ||
| 853 | ASET (font_object, FONT_FILE_INDEX, | ||
| 854 | make_unibyte_string ((char *) file, strlen ((char *) file))); | ||
| 855 | ASET (font_object, FONT_FORMAT_INDEX, ftfont_font_format (pattern)); | 915 | ASET (font_object, FONT_FORMAT_INDEX, ftfont_font_format (pattern)); |
| 856 | font = XFONT_OBJECT (font_object); | 916 | font = XFONT_OBJECT (font_object); |
| 857 | ftfont_info = (struct ftfont_info *) font; | 917 | ftfont_info = (struct ftfont_info *) font; |
| 858 | ftfont_info->ft_size = ft_size; | 918 | ftfont_info->ft_size = ft_face->size; |
| 919 | ftfont_info->fc_charset_idx = fc_charset_idx; | ||
| 859 | #ifdef HAVE_LIBOTF | 920 | #ifdef HAVE_LIBOTF |
| 860 | ftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT; | 921 | ftfont_info->maybe_otf = ft_face->face_flags & FT_FACE_FLAG_SFNT; |
| 861 | ftfont_info->otf = NULL; | 922 | ftfont_info->otf = NULL; |
| @@ -865,8 +926,8 @@ ftfont_open (f, entity, pixel_size) | |||
| 865 | font->encoding_charset = font->repertory_charset = -1; | 926 | font->encoding_charset = font->repertory_charset = -1; |
| 866 | 927 | ||
| 867 | upEM = ft_face->units_per_EM; | 928 | upEM = ft_face->units_per_EM; |
| 868 | if (! FcPatternGetBool (pattern, FC_SCALABLE, 0, &scalable) == FcResultMatch) | 929 | scalable = (INTEGERP (AREF (entity, FONT_AVGWIDTH_INDEX)) |
| 869 | scalable = FcFalse; | 930 | && XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0); |
| 870 | if (scalable) | 931 | if (scalable) |
| 871 | { | 932 | { |
| 872 | font->ascent = ft_face->ascender * size / upEM; | 933 | font->ascent = ft_face->ascender * size / upEM; |
| @@ -879,7 +940,9 @@ ftfont_open (f, entity, pixel_size) | |||
| 879 | font->descent = - ft_face->size->metrics.descender >> 6; | 940 | font->descent = - ft_face->size->metrics.descender >> 6; |
| 880 | font->height = ft_face->size->metrics.height >> 6; | 941 | font->height = ft_face->size->metrics.height >> 6; |
| 881 | } | 942 | } |
| 882 | if (FcPatternGetInteger (pattern, FC_SPACING, 0, &spacing) != FcResultMatch) | 943 | if (INTEGERP (AREF (entity, FONT_SPACING_INDEX))) |
| 944 | spacing = XINT (AREF (entity, FONT_SPACING_INDEX)); | ||
| 945 | else | ||
| 883 | spacing = FC_PROPORTIONAL; | 946 | spacing = FC_PROPORTIONAL; |
| 884 | if (spacing != FC_PROPORTIONAL) | 947 | if (spacing != FC_PROPORTIONAL) |
| 885 | font->min_width = font->average_width = font->space_width | 948 | font->min_width = font->average_width = font->space_width |
| @@ -931,18 +994,21 @@ ftfont_close (f, font) | |||
| 931 | struct font *font; | 994 | struct font *font; |
| 932 | { | 995 | { |
| 933 | struct ftfont_info *ftfont_info = (struct ftfont_info *) font; | 996 | struct ftfont_info *ftfont_info = (struct ftfont_info *) font; |
| 934 | Lisp_Object val; | 997 | Lisp_Object val, cache; |
| 935 | 998 | ||
| 936 | val = assq_no_quit (QCfont_entity, font->props[FONT_EXTRA_INDEX]); | 999 | cache = ftfont_lookup_cache (font->props[FONT_FILE_INDEX]); |
| 937 | val = XCDR (val); | 1000 | val = XCDR (cache); |
| 938 | (XSAVE_VALUE (val)->integer)--; | 1001 | (XSAVE_VALUE (val)->integer)--; |
| 939 | if (XSAVE_VALUE (val)->integer == 0) | 1002 | if (XSAVE_VALUE (val)->integer == 0) |
| 940 | { | 1003 | { |
| 941 | FT_Done_Face (ftfont_info->ft_size->face); | 1004 | FT_Face ft_face = XSAVE_VALUE (val)->pointer; |
| 1005 | |||
| 1006 | FT_Done_Face (ft_face); | ||
| 942 | #ifdef HAVE_LIBOTF | 1007 | #ifdef HAVE_LIBOTF |
| 943 | if (ftfont_info->otf) | 1008 | if (ftfont_info->otf) |
| 944 | OTF_close (ftfont_info->otf); | 1009 | OTF_close (ftfont_info->otf); |
| 945 | #endif | 1010 | #endif |
| 1011 | XSAVE_VALUE (val)->pointer = NULL; | ||
| 946 | } | 1012 | } |
| 947 | else | 1013 | else |
| 948 | FT_Done_Size (ftfont_info->ft_size); | 1014 | FT_Done_Size (ftfont_info->ft_size); |
| @@ -954,15 +1020,15 @@ ftfont_has_char (entity, c) | |||
| 954 | int c; | 1020 | int c; |
| 955 | { | 1021 | { |
| 956 | Lisp_Object val; | 1022 | Lisp_Object val; |
| 957 | FcPattern *pattern; | 1023 | int fc_charset_idx; |
| 958 | FcCharSet *charset; | 1024 | struct charset *charset; |
| 959 | 1025 | ||
| 960 | val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX)); | 1026 | val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX)); |
| 961 | val = XCDR (val); | 1027 | fc_charset_idx = XINT (XCDR (XCDR (val))); |
| 962 | pattern = XSAVE_VALUE (val)->pointer; | 1028 | if (fc_charset_idx < 0) |
| 963 | if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) != FcResultMatch) | ||
| 964 | return -1; | 1029 | return -1; |
| 965 | return (FcCharSetHasChar (charset, (FcChar32) c) == FcTrue); | 1030 | charset = CHARSET_FROM_ID (fc_charset_table[fc_charset_idx].charset_id); |
| 1031 | return (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset)); | ||
| 966 | } | 1032 | } |
| 967 | 1033 | ||
| 968 | static unsigned | 1034 | static unsigned |
| @@ -1316,7 +1382,6 @@ ftfont_drive_otf (font, spec, in, from, to, out, adjustment) | |||
| 1316 | return -2; | 1382 | return -2; |
| 1317 | for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; ) | 1383 | for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; ) |
| 1318 | { | 1384 | { |
| 1319 | OTF_Glyph *endg; | ||
| 1320 | MFLTGlyph *g; | 1385 | MFLTGlyph *g; |
| 1321 | int min_from, max_to; | 1386 | int min_from, max_to; |
| 1322 | int j; | 1387 | int j; |
| @@ -1550,7 +1615,8 @@ ftfont_shape_by_flt (lgstring, font, ft_face, otf) | |||
| 1550 | if (NILP (family)) | 1615 | if (NILP (family)) |
| 1551 | flt_font_ft.flt_font.family = Mnil; | 1616 | flt_font_ft.flt_font.family = Mnil; |
| 1552 | else | 1617 | else |
| 1553 | flt_font_ft.flt_font.family = msymbol (SDATA (SYMBOL_NAME (family))); | 1618 | flt_font_ft.flt_font.family |
| 1619 | = msymbol ((char *) SDATA (SYMBOL_NAME (family))); | ||
| 1554 | } | 1620 | } |
| 1555 | flt_font_ft.flt_font.x_ppem = ft_face->size->metrics.x_ppem; | 1621 | flt_font_ft.flt_font.x_ppem = ft_face->size->metrics.x_ppem; |
| 1556 | flt_font_ft.flt_font.y_ppem = ft_face->size->metrics.y_ppem; | 1622 | flt_font_ft.flt_font.y_ppem = ft_face->size->metrics.y_ppem; |
| @@ -1699,6 +1765,9 @@ syms_of_ftfont () | |||
| 1699 | Fcons (Fcons (Qsans_serif, Qt), | 1765 | Fcons (Fcons (Qsans_serif, Qt), |
| 1700 | Fcons (Fcons (Qsans, Qt), Qnil))); | 1766 | Fcons (Fcons (Qsans, Qt), Qnil))); |
| 1701 | 1767 | ||
| 1768 | staticpro (&ft_face_cache); | ||
| 1769 | ft_face_cache = Qnil; | ||
| 1770 | |||
| 1702 | ftfont_driver.type = Qfreetype; | 1771 | ftfont_driver.type = Qfreetype; |
| 1703 | register_font_driver (&ftfont_driver, NULL); | 1772 | register_font_driver (&ftfont_driver, NULL); |
| 1704 | } | 1773 | } |