diff options
| author | Kenichi Handa | 2006-06-09 02:15:05 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2006-06-09 02:15:05 +0000 |
| commit | c2801c99bed19470fd4799355056ae0816aa47b4 (patch) | |
| tree | c849b3bd17f2a5655dc77db76c9d2c0e550cc38f /src | |
| parent | 02dacbbc4f5681826be277dc03fd1e865cf8c04b (diff) | |
| download | emacs-c2801c99bed19470fd4799355056ae0816aa47b4.tar.gz emacs-c2801c99bed19470fd4799355056ae0816aa47b4.zip | |
(Qiso8859_1, Qiso10646_1, Qunicode_bmp): Moved to
font.c.
(ftfont_pattern_entity): New function.
(ftfont_get_cache): Assume that freetype_font_cache is already
initialized.
(ftfont_list): Handle the case that a file is specified in font
name. Use ftfont_pattern_entity to generate entities.
(ftfont_has_char): Check if the pattern contains FC_CHARSET.
(syms_of_ftfont): Initialize freetype_font_cache.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ftfont.c | 198 |
1 files changed, 122 insertions, 76 deletions
diff --git a/src/ftfont.c b/src/ftfont.c index 184ef2cba49..5d70257beec 100644 --- a/src/ftfont.c +++ b/src/ftfont.c | |||
| @@ -40,15 +40,20 @@ Boston, MA 02110-1301, USA. */ | |||
| 40 | #include "fontset.h" | 40 | #include "fontset.h" |
| 41 | #include "font.h" | 41 | #include "font.h" |
| 42 | 42 | ||
| 43 | /* Symbolic type of this font-driver. */ | ||
| 43 | Lisp_Object Qfreetype; | 44 | Lisp_Object Qfreetype; |
| 44 | 45 | ||
| 46 | /* Flag to tell if FcInit is areadly called or not. */ | ||
| 45 | static int fc_initialized; | 47 | static int fc_initialized; |
| 48 | |||
| 49 | /* Handle to a FreeType library instance. */ | ||
| 46 | static FT_Library ft_library; | 50 | static FT_Library ft_library; |
| 47 | 51 | ||
| 52 | /* Cache for FreeType fonts. */ | ||
| 48 | static Lisp_Object freetype_font_cache; | 53 | static Lisp_Object freetype_font_cache; |
| 49 | 54 | ||
| 50 | static Lisp_Object Qiso8859_1, Qiso10646_1, Qunicode_bmp; | 55 | /* Fontconfig's charset used for finding fonts of registry |
| 51 | 56 | "iso8859-1". */ | |
| 52 | static FcCharSet *cs_iso8859_1; | 57 | static FcCharSet *cs_iso8859_1; |
| 53 | 58 | ||
| 54 | /* The actual structure for FreeType font that can be casted to struct | 59 | /* The actual structure for FreeType font that can be casted to struct |
| @@ -77,6 +82,70 @@ ftfont_build_basic_charsets () | |||
| 77 | return 0; | 82 | return 0; |
| 78 | } | 83 | } |
| 79 | 84 | ||
| 85 | Lisp_Object | ||
| 86 | ftfont_pattern_entity (p, frame, registry, name) | ||
| 87 | FcPattern *p; | ||
| 88 | Lisp_Object frame, registry, name; | ||
| 89 | { | ||
| 90 | Lisp_Object entity; | ||
| 91 | FcChar8 *file; | ||
| 92 | FcCharSet *charset; | ||
| 93 | char *str; | ||
| 94 | int numeric; | ||
| 95 | double dbl; | ||
| 96 | |||
| 97 | if (FcPatternGetString (p, FC_FILE, 0, &file) != FcResultMatch) | ||
| 98 | return Qnil; | ||
| 99 | if (FcPatternGetCharSet (p, FC_CHARSET, 0, &charset) == FcResultMatch) | ||
| 100 | charset = NULL; | ||
| 101 | |||
| 102 | entity = Fmake_vector (make_number (FONT_ENTITY_MAX), null_string); | ||
| 103 | |||
| 104 | ASET (entity, FONT_TYPE_INDEX, Qfreetype); | ||
| 105 | ASET (entity, FONT_REGISTRY_INDEX, registry); | ||
| 106 | ASET (entity, FONT_FRAME_INDEX, frame); | ||
| 107 | ASET (entity, FONT_OBJLIST_INDEX, Qnil); | ||
| 108 | |||
| 109 | if (FcPatternGetString (p, FC_FOUNDRY, 0, (FcChar8 **) &str) == FcResultMatch) | ||
| 110 | ASET (entity, FONT_FOUNDRY_INDEX, intern_downcase (str, strlen (str))); | ||
| 111 | if (FcPatternGetString (p, FC_FAMILY, 0, (FcChar8 **) &str) == FcResultMatch) | ||
| 112 | ASET (entity, FONT_FAMILY_INDEX, intern_downcase (str, strlen (str))); | ||
| 113 | if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch) | ||
| 114 | ASET (entity, FONT_WEIGHT_INDEX, make_number (numeric)); | ||
| 115 | if (FcPatternGetInteger (p, FC_SLANT, 0, &numeric) == FcResultMatch) | ||
| 116 | ASET (entity, FONT_SLANT_INDEX, make_number (numeric + 100)); | ||
| 117 | if (FcPatternGetInteger (p, FC_WIDTH, 0, &numeric) == FcResultMatch) | ||
| 118 | ASET (entity, FONT_WIDTH_INDEX, make_number (numeric)); | ||
| 119 | if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch) | ||
| 120 | ASET (entity, FONT_SIZE_INDEX, make_number (dbl)); | ||
| 121 | else | ||
| 122 | ASET (entity, FONT_SIZE_INDEX, make_number (0)); | ||
| 123 | |||
| 124 | if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) != FcResultMatch) | ||
| 125 | numeric = FC_MONO; | ||
| 126 | file = FcStrCopy (file); | ||
| 127 | if (! file) | ||
| 128 | return Qnil; | ||
| 129 | |||
| 130 | p = FcPatternCreate (); | ||
| 131 | if (! p) | ||
| 132 | return Qnil; | ||
| 133 | |||
| 134 | if (FcPatternAddString (p, FC_FILE, file) == FcFalse | ||
| 135 | || (charset && FcPatternAddCharSet (p, FC_CHARSET, charset) == FcFalse) | ||
| 136 | || FcPatternAddInteger (p, FC_SPACING, numeric) == FcFalse | ||
| 137 | || (! NILP (name) | ||
| 138 | && (FcPatternAddString (p, FC_FILE, (FcChar8 *) SDATA (name)) | ||
| 139 | == FcFalse))) | ||
| 140 | { | ||
| 141 | FcPatternDestroy (p); | ||
| 142 | return Qnil; | ||
| 143 | } | ||
| 144 | ASET (entity, FONT_EXTRA_INDEX, make_save_value (p, 0)); | ||
| 145 | return entity; | ||
| 146 | } | ||
| 147 | |||
| 148 | |||
| 80 | static Lisp_Object ftfont_get_cache P_ ((Lisp_Object)); | 149 | static Lisp_Object ftfont_get_cache P_ ((Lisp_Object)); |
| 81 | static int ftfont_parse_name P_ ((FRAME_PTR, char *, Lisp_Object)); | 150 | static int ftfont_parse_name P_ ((FRAME_PTR, char *, Lisp_Object)); |
| 82 | static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object)); | 151 | static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object)); |
| @@ -135,8 +204,6 @@ static Lisp_Object | |||
| 135 | ftfont_get_cache (frame) | 204 | ftfont_get_cache (frame) |
| 136 | Lisp_Object frame; | 205 | Lisp_Object frame; |
| 137 | { | 206 | { |
| 138 | if (NILP (freetype_font_cache)) | ||
| 139 | freetype_font_cache = Fcons (Qt, Qnil); | ||
| 140 | return freetype_font_cache; | 207 | return freetype_font_cache; |
| 141 | } | 208 | } |
| 142 | 209 | ||
| @@ -180,14 +247,14 @@ static Lisp_Object | |||
| 180 | ftfont_list (frame, spec) | 247 | ftfont_list (frame, spec) |
| 181 | Lisp_Object frame, spec; | 248 | Lisp_Object frame, spec; |
| 182 | { | 249 | { |
| 183 | Lisp_Object val, tmp, extra, font_name; | 250 | Lisp_Object val, tmp, extra, font_name, file_name; |
| 184 | int i; | 251 | int i; |
| 185 | FcPattern *pattern = NULL; | 252 | FcPattern *pattern = NULL; |
| 186 | FcCharSet *charset = NULL; | 253 | FcCharSet *charset = NULL; |
| 187 | FcLangSet *langset = NULL; | 254 | FcLangSet *langset = NULL; |
| 188 | FcFontSet *fontset = NULL; | 255 | FcFontSet *fontset = NULL; |
| 189 | FcObjectSet *objset = NULL; | 256 | FcObjectSet *objset = NULL; |
| 190 | Lisp_Object registry = Qnil; | 257 | Lisp_Object registry = Qunicode_bmp; |
| 191 | 258 | ||
| 192 | val = null_vector; | 259 | val = null_vector; |
| 193 | 260 | ||
| @@ -208,12 +275,13 @@ ftfont_list (frame, spec) | |||
| 208 | && ftfont_build_basic_charsets () < 0) | 275 | && ftfont_build_basic_charsets () < 0) |
| 209 | goto err; | 276 | goto err; |
| 210 | charset = cs_iso8859_1; | 277 | charset = cs_iso8859_1; |
| 211 | registry = Qnil; | ||
| 212 | } | 278 | } |
| 279 | else if (! EQ (registry, Qiso10646_1) && ! EQ (registry, Qunicode_bmp)) | ||
| 280 | goto finish; | ||
| 213 | } | 281 | } |
| 214 | 282 | ||
| 215 | extra = AREF (spec, FONT_EXTRA_INDEX); | 283 | extra = AREF (spec, FONT_EXTRA_INDEX); |
| 216 | font_name = Qnil; | 284 | font_name = file_name = Qnil; |
| 217 | if (CONSP (extra)) | 285 | if (CONSP (extra)) |
| 218 | { | 286 | { |
| 219 | tmp = Fassq (QCotf, extra); | 287 | tmp = Fassq (QCotf, extra); |
| @@ -242,7 +310,11 @@ ftfont_list (frame, spec) | |||
| 242 | } | 310 | } |
| 243 | tmp = Fassq (QCname, extra); | 311 | tmp = Fassq (QCname, extra); |
| 244 | if (CONSP (tmp)) | 312 | if (CONSP (tmp)) |
| 245 | font_name = XCDR (tmp); | 313 | { |
| 314 | font_name = XCDR (tmp); | ||
| 315 | if (SDATA (font_name)[0] == ':') | ||
| 316 | file_name = font_name, font_name = Qnil; | ||
| 317 | } | ||
| 246 | tmp = Fassq (QCscript, extra); | 318 | tmp = Fassq (QCscript, extra); |
| 247 | if (CONSP (tmp) && ! charset) | 319 | if (CONSP (tmp) && ! charset) |
| 248 | { | 320 | { |
| @@ -263,12 +335,9 @@ ftfont_list (frame, spec) | |||
| 263 | } | 335 | } |
| 264 | } | 336 | } |
| 265 | 337 | ||
| 266 | if (! NILP (registry) && ! charset) | ||
| 267 | goto finish; | ||
| 268 | |||
| 269 | if (STRINGP (font_name)) | 338 | if (STRINGP (font_name)) |
| 270 | { | 339 | { |
| 271 | if (! isalpha (SDATA (font_name)[0])) | 340 | if (SDATA (font_name)[0] == '-') |
| 272 | goto finish; | 341 | goto finish; |
| 273 | pattern = FcNameParse (SDATA (font_name)); | 342 | pattern = FcNameParse (SDATA (font_name)); |
| 274 | if (! pattern) | 343 | if (! pattern) |
| @@ -276,7 +345,13 @@ ftfont_list (frame, spec) | |||
| 276 | } | 345 | } |
| 277 | else | 346 | else |
| 278 | { | 347 | { |
| 279 | pattern = FcPatternCreate (); | 348 | if (! NILP (file_name)) |
| 349 | { | ||
| 350 | pattern = FcNameParse (SDATA (file_name)); | ||
| 351 | FcPatternDel (pattern, FC_PIXEL_SIZE); | ||
| 352 | } | ||
| 353 | else | ||
| 354 | pattern = FcPatternCreate (); | ||
| 280 | if (! pattern) | 355 | if (! pattern) |
| 281 | goto err; | 356 | goto err; |
| 282 | 357 | ||
| @@ -311,68 +386,42 @@ ftfont_list (frame, spec) | |||
| 311 | if (langset | 386 | if (langset |
| 312 | && ! FcPatternAddLangSet (pattern, FC_LANG, langset)) | 387 | && ! FcPatternAddLangSet (pattern, FC_LANG, langset)) |
| 313 | goto err; | 388 | goto err; |
| 314 | objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT, | ||
| 315 | FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, | ||
| 316 | FC_CHARSET, FC_FILE, NULL); | ||
| 317 | if (! objset) | ||
| 318 | goto err; | ||
| 319 | 389 | ||
| 320 | BLOCK_INPUT; | 390 | if (STRINGP (font_name)) |
| 321 | fontset = FcFontList (NULL, pattern, objset); | ||
| 322 | UNBLOCK_INPUT; | ||
| 323 | if (! fontset) | ||
| 324 | goto err; | ||
| 325 | val = Qnil; | ||
| 326 | for (i = 0; i < fontset->nfont; i++) | ||
| 327 | { | 391 | { |
| 328 | FcPattern *p = fontset->fonts[i]; | 392 | FcPattern *pat; |
| 329 | FcChar8 *str, *file; | 393 | FcResult result; |
| 394 | Lisp_Object entity; | ||
| 395 | |||
| 396 | FcConfigSubstitute (NULL, pattern, FcMatchPattern); | ||
| 397 | FcDefaultSubstitute (pattern); | ||
| 398 | pat = FcFontMatch (NULL, pattern, &result); | ||
| 399 | entity = ftfont_pattern_entity (pat, frame, registry, font_name); | ||
| 400 | FcPatternDestroy (pat); | ||
| 401 | if (! NILP (entity)) | ||
| 402 | val = Fmake_vector (make_number (1), entity); | ||
| 403 | } | ||
| 404 | else | ||
| 405 | { | ||
| 406 | objset = FcObjectSetBuild (FC_FOUNDRY, FC_FAMILY, FC_WEIGHT, FC_SLANT, | ||
| 407 | FC_WIDTH, FC_PIXEL_SIZE, FC_SPACING, | ||
| 408 | FC_CHARSET, FC_FILE, NULL); | ||
| 409 | if (! objset) | ||
| 410 | goto err; | ||
| 330 | 411 | ||
| 331 | if (FcPatternGetString (p, FC_FILE, 0, &file) == FcResultMatch | 412 | fontset = FcFontList (NULL, pattern, objset); |
| 332 | && FcPatternGetCharSet (p, FC_CHARSET, 0, &charset) == FcResultMatch) | 413 | if (! fontset) |
| 414 | goto err; | ||
| 415 | val = Qnil; | ||
| 416 | for (i = 0; i < fontset->nfont; i++) | ||
| 333 | { | 417 | { |
| 334 | Lisp_Object entity = Fmake_vector (make_number (FONT_ENTITY_MAX), | 418 | Lisp_Object entity = ftfont_pattern_entity (fontset->fonts[i], |
| 335 | null_string); | 419 | frame, registry, Qnil); |
| 336 | int numeric; | 420 | if (! NILP (entity)) |
| 337 | double dbl; | 421 | val = Fcons (entity, val); |
| 338 | FcPattern *p0; | ||
| 339 | |||
| 340 | ASET (entity, FONT_TYPE_INDEX, Qfreetype); | ||
| 341 | ASET (entity, FONT_REGISTRY_INDEX, Qiso10646_1); | ||
| 342 | ASET (entity, FONT_FRAME_INDEX, frame); | ||
| 343 | ASET (entity, FONT_OBJLIST_INDEX, Qnil); | ||
| 344 | |||
| 345 | if (FcPatternGetString (p, FC_FOUNDRY, 0, &str) == FcResultMatch) | ||
| 346 | ASET (entity, FONT_FOUNDRY_INDEX, | ||
| 347 | intern_downcase ((char *) str, strlen ((char *) str))); | ||
| 348 | if (FcPatternGetString (p, FC_FAMILY, 0, &str) == FcResultMatch) | ||
| 349 | ASET (entity, FONT_FAMILY_INDEX, | ||
| 350 | intern_downcase ((char *) str, strlen ((char *) str))); | ||
| 351 | if (FcPatternGetInteger (p, FC_WEIGHT, 0, &numeric) == FcResultMatch) | ||
| 352 | ASET (entity, FONT_WEIGHT_INDEX, make_number (numeric)); | ||
| 353 | if (FcPatternGetInteger (p, FC_SLANT, 0, &numeric) == FcResultMatch) | ||
| 354 | ASET (entity, FONT_SLANT_INDEX, make_number (numeric + 100)); | ||
| 355 | if (FcPatternGetInteger (p, FC_WIDTH, 0, &numeric) == FcResultMatch) | ||
| 356 | ASET (entity, FONT_WIDTH_INDEX, make_number (numeric)); | ||
| 357 | if (FcPatternGetDouble (p, FC_PIXEL_SIZE, 0, &dbl) == FcResultMatch) | ||
| 358 | ASET (entity, FONT_SIZE_INDEX, make_number (dbl)); | ||
| 359 | else | ||
| 360 | ASET (entity, FONT_SIZE_INDEX, make_number (0)); | ||
| 361 | |||
| 362 | if (FcPatternGetInteger (p, FC_SPACING, 0, &numeric) != FcResultMatch) | ||
| 363 | numeric = FC_MONO; | ||
| 364 | p0 = FcPatternCreate (); | ||
| 365 | if (! p0 | ||
| 366 | || FcPatternAddString (p0, FC_FILE, file) == FcFalse | ||
| 367 | || FcPatternAddCharSet (p0, FC_CHARSET, charset) == FcFalse | ||
| 368 | || FcPatternAddInteger (p0, FC_SPACING, numeric) == FcFalse) | ||
| 369 | break; | ||
| 370 | ASET (entity, FONT_EXTRA_INDEX, make_save_value (p0, 0)); | ||
| 371 | |||
| 372 | val = Fcons (entity, val); | ||
| 373 | } | 422 | } |
| 423 | val = Fvconcat (1, &val); | ||
| 374 | } | 424 | } |
| 375 | val = Fvconcat (1, &val); | ||
| 376 | goto finish; | 425 | goto finish; |
| 377 | 426 | ||
| 378 | err: | 427 | err: |
| @@ -586,8 +635,8 @@ ftfont_has_char (entity, c) | |||
| 586 | 635 | ||
| 587 | val = AREF (entity, FONT_EXTRA_INDEX); | 636 | val = AREF (entity, FONT_EXTRA_INDEX); |
| 588 | pattern = XSAVE_VALUE (val)->pointer; | 637 | pattern = XSAVE_VALUE (val)->pointer; |
| 589 | FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset); | 638 | if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) != FcResultMatch) |
| 590 | 639 | return -1; | |
| 591 | return (FcCharSetHasChar (charset, (FcChar32) c) == FcTrue); | 640 | return (FcCharSetHasChar (charset, (FcChar32) c) == FcTrue); |
| 592 | } | 641 | } |
| 593 | 642 | ||
| @@ -719,12 +768,9 @@ void | |||
| 719 | syms_of_ftfont () | 768 | syms_of_ftfont () |
| 720 | { | 769 | { |
| 721 | staticpro (&freetype_font_cache); | 770 | staticpro (&freetype_font_cache); |
| 722 | freetype_font_cache = Qnil; | 771 | freetype_font_cache = Fcons (Qt, Qnil); |
| 723 | 772 | ||
| 724 | DEFSYM (Qfreetype, "freetype"); | 773 | DEFSYM (Qfreetype, "freetype"); |
| 725 | DEFSYM (Qiso8859_1, "iso8859-1"); | ||
| 726 | DEFSYM (Qiso10646_1, "iso10646-1"); | ||
| 727 | DEFSYM (Qunicode_bmp, "unicode-bmp"); | ||
| 728 | 774 | ||
| 729 | ftfont_driver.type = Qfreetype; | 775 | ftfont_driver.type = Qfreetype; |
| 730 | register_font_driver (&ftfont_driver, NULL); | 776 | register_font_driver (&ftfont_driver, NULL); |