aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2006-06-09 02:15:05 +0000
committerKenichi Handa2006-06-09 02:15:05 +0000
commitc2801c99bed19470fd4799355056ae0816aa47b4 (patch)
treec849b3bd17f2a5655dc77db76c9d2c0e550cc38f /src
parent02dacbbc4f5681826be277dc03fd1e865cf8c04b (diff)
downloademacs-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.c198
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. */
43Lisp_Object Qfreetype; 44Lisp_Object Qfreetype;
44 45
46/* Flag to tell if FcInit is areadly called or not. */
45static int fc_initialized; 47static int fc_initialized;
48
49/* Handle to a FreeType library instance. */
46static FT_Library ft_library; 50static FT_Library ft_library;
47 51
52/* Cache for FreeType fonts. */
48static Lisp_Object freetype_font_cache; 53static Lisp_Object freetype_font_cache;
49 54
50static Lisp_Object Qiso8859_1, Qiso10646_1, Qunicode_bmp; 55/* Fontconfig's charset used for finding fonts of registry
51 56 "iso8859-1". */
52static FcCharSet *cs_iso8859_1; 57static 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
85Lisp_Object
86ftfont_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
80static Lisp_Object ftfont_get_cache P_ ((Lisp_Object)); 149static Lisp_Object ftfont_get_cache P_ ((Lisp_Object));
81static int ftfont_parse_name P_ ((FRAME_PTR, char *, Lisp_Object)); 150static int ftfont_parse_name P_ ((FRAME_PTR, char *, Lisp_Object));
82static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object)); 151static Lisp_Object ftfont_list P_ ((Lisp_Object, Lisp_Object));
@@ -135,8 +204,6 @@ static Lisp_Object
135ftfont_get_cache (frame) 204ftfont_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
180ftfont_list (frame, spec) 247ftfont_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
719syms_of_ftfont () 768syms_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);