Mercurial > hg > xemacs-beta
annotate src/font-mgr.c @ 4407:4ee73bbe4f8e
Always use boyer_moore in ASCII or Latin-1 buffers with ASCII search strings.
2007-12-26 Aidan Kehoe <kehoea@parhasard.net>
* casetab.c:
Extend and correct some case table documentation.
* search.c (search_buffer):
Correct a bug where only the first entry for a character in the
case equivalence table was examined in determining if the
Boyer-Moore search algorithm is appropriate.
If there are case mappings outside of the charset and row of the
characters specified in the search string, those case mappings can
be safely ignored (and Boyer-Moore search can be used) if we know
from the buffer statistics that the corresponding characters cannot
occur.
* search.c (boyer_moore):
Assert that we haven't been passed a string with varying
characters sets or rows within character sets. That's what
simple_search is for.
In the very rare event that a character in the search string has a
canonical case mapping that is not in the same character set and
row, don't try to search for the canonical character, search for
some other character that is in the the desired character set and
row. Assert that the case table isn't corrupt.
Do not search for any character case mappings that cannot possibly
occur in the buffer, given the buffer metadata about its
contents.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Wed, 26 Dec 2007 17:30:16 +0100 |
parents | dfd878799ef0 |
children | a23ac8f90a49 |
rev | line source |
---|---|
3354 | 1 /* Lisp font handling implementation for X with Xft. |
2 | |
3 Copyright (C) 2003 Eric Knauel and Matthias Neubauer | |
4 Copyright (C) 2005 Eric Knauel | |
3906 | 5 Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. |
3354 | 6 |
7 Authors: Eric Knauel <knauel@informatik.uni-tuebingen.de> | |
8 Matthias Neubauer <neubauer@informatik.uni-freiburg.de> | |
9 Stephen J. Turnbull <stephen@xemacs.org> | |
10 Created: 27 Oct 2003 | |
3906 | 11 Updated: 14 April 2007 by Stephen J. Turnbull |
3354 | 12 |
13 This file is part of XEmacs. | |
14 | |
15 XEmacs is free software; you can redistribute it and/or modify it | |
16 under the terms of the GNU General Public License as published by the | |
17 Free Software Foundation; either version 2, or (at your option) any | |
18 later version. | |
19 | |
20 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
21 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
22 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
23 for more details. | |
24 | |
25 You should have received a copy of the GNU General Public License | |
26 along with XEmacs; see the file COPYING. If not, write to | |
27 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
28 Boston, MA 02111-1307, USA. */ | |
29 | |
30 /* Synched up with: Not in GNU Emacs. */ | |
31 | |
32 /* This module provides the Lisp interface to fonts in X11, including Xft, | |
33 but (at least at first) not GTK+ or Qt. | |
34 | |
35 Sealevel code should be in ../lwlib/lwlib-fonts.c or | |
36 ../lwlib/lwlib-colors.c. | |
37 */ | |
38 | |
39 #include <config.h> | |
40 #include "lisp.h" | |
41 #include "device.h" | |
42 #include "device-impl.h" | |
43 #include "console-x-impl.h" | |
44 #include "objects-x.h" | |
45 #include "objects-x-impl.h" | |
46 #include "hash.h" | |
47 #include "font-mgr.h" | |
48 | |
49 /* #### TO DO #### | |
50 . The "x-xft-*" and "x_xft_*" nomenclature is mostly redundant, especially | |
51 if we separate X fonts from Xft fonts, and use fontconfig more generally. | |
52 . We should support the most recent Xft first, old Xft libraries later. | |
53 . We may (think about it) wish to use fontconfig generally, even if we're | |
54 not using Xft. Either way, names that are really from fontconfig should | |
55 use the Fc* namespace. | |
56 . Mule-ize this file. | |
57 . Separate X Font Struct ops from Xft Font ops; give precedence to Xft but | |
58 allow fallback to X. | |
59 . Push decisions about font choice, defaults, fallbacks to Lisp; if we | |
60 really need efficiency, can reimplement in C later. | |
61 . Implement symbols interned in this file in the Q* namespace. | |
62 . Implement FcMatrix (Lisp vector). | |
63 . Implement FcCharSets (Lisp chartable? For implementation hints, see | |
64 FcCharSetFirstPage and FcCharSetNextPage). | |
65 . Implement FcConfigs. | |
66 DONE | |
67 . Fontconfig fontnames are encoded in UTF-8. | |
68 */ | |
69 | |
3360 | 70 Lisp_Object Qfont_mgr; |
3354 | 71 Lisp_Object Qfc_patternp; |
72 /* Lisp_Object Qfc_result_match; */ /* FcResultMatch */ | |
73 Lisp_Object Qfc_result_type_mismatch; /* FcResultTypeMismatch */ | |
74 Lisp_Object Qfc_result_no_match; /* FcResultNoMatch */ | |
75 Lisp_Object Qfc_result_no_id; /* FcResultNoId */ | |
76 Lisp_Object Qfc_internal_error; | |
77 Lisp_Object Vxlfd_font_name_regexp; /* #### Really needed? */ | |
3935 | 78 Fixnum xft_version; |
79 Fixnum fc_version; | |
3354 | 80 Fixnum debug_xft; /* Set to 1 enables lots of obnoxious messages. |
81 Setting it to 2 or 3 enables even more. */ | |
3931 | 82 #ifdef FONTCONFIG_EXPOSE_CONFIG |
83 Lisp_Object Qfc_configp; | |
84 static Lisp_Object Vfc_config_weak_list; | |
85 #endif | |
3354 | 86 |
87 /**************************************************************** | |
88 * FcPattern objects * | |
89 ****************************************************************/ | |
90 | |
91 static void | |
92 finalize_fc_pattern (void *header, int UNUSED (for_disksave)) | |
93 { | |
94 struct fc_pattern *p = (struct fc_pattern *) header; | |
95 if (p->fcpatPtr) | |
96 { | |
97 FcPatternDestroy (p->fcpatPtr); | |
98 p->fcpatPtr = 0; | |
99 } | |
100 } | |
101 | |
3906 | 102 static void |
103 print_fc_pattern (Lisp_Object obj, Lisp_Object printcharfun, | |
104 int UNUSED(escapeflag)) | |
105 { | |
106 struct fc_pattern *c = XFCPATTERN (obj); | |
107 if (print_readably) | |
108 printing_unreadable_object ("#<fc-pattern 0x%x>", c->header.uid); | |
109 write_fmt_string (printcharfun, "#<fc-pattern 0x%x>", c->header.uid); | |
110 } | |
111 | |
112 /* #### We really need an equal method and a hash method (required if you | |
113 have an equal method). For the equal method, we can probably use one | |
114 or both of | |
115 | |
116 -- Function: FcBool FcPatternEqual (const FcPattern *pa, const | |
117 FcPattern *pb); | |
118 Returns whether PA and PB are exactly alike. | |
119 | |
120 -- Function: FcBool FcPatternEqualSubset (const FcPattern *pa, const | |
121 FcPattern *pb, const FcObjectSet *os) | |
122 Returns whether PA and PB have exactly the same values for all of | |
123 the objects in OS. | |
124 | |
125 For the hash, we'll have to extract some subset of attributes. | |
126 | |
127 #### Crap. It's altogether unobvious what we need. x_color_instance | |
128 does have a hash method, but fonts are apparently special. I get the | |
129 feeling that for this to work properly we're going to need to switch | |
130 to fontconfig-based font specifications (although we can allow the | |
131 platform syntaxes, the underlying specification object will need to | |
132 conform to the fontconfig API, or more precisely the font-mgr API). | |
133 | |
134 I think the whole `font-truename' interface needs to be dropped. */ | |
135 | |
3354 | 136 static const struct memory_description fcpattern_description [] = { |
137 /* #### nothing here, is this right?? */ | |
138 { XD_END } | |
139 }; | |
140 | |
3906 | 141 DEFINE_LRECORD_IMPLEMENTATION("fc-pattern", fc_pattern, 0, |
142 0, print_fc_pattern, finalize_fc_pattern, | |
143 0, 0, fcpattern_description, | |
3354 | 144 struct fc_pattern); |
145 | |
146 /* | |
147 * Helper Functions | |
148 */ | |
149 static Lisp_Object make_xlfd_font_regexp (void); | |
150 static void string_list_to_fcobjectset (Lisp_Object list, FcObjectSet *os); | |
151 | |
152 /* | |
153 extract the C representation of the Lisp string STR and convert it | |
154 to the encoding used by the Fontconfig API for property and font | |
155 names. I suppose that Qnative is the right encoding, the manual | |
156 doesn't say much about this topic. This functions assumes that STR | |
157 is a Lisp string. | |
158 */ | |
159 #define extract_fcapi_string(str) \ | |
3469 | 160 (NEW_LISP_STRING_TO_EXTERNAL ((str), Qfc_font_name_encoding)) |
3354 | 161 |
3906 | 162 #define build_fcapi_string(str) \ |
163 (build_ext_string ((Extbyte *) (str), Qfc_font_name_encoding)) | |
164 | |
3360 | 165 /* #### This homebrew lashup should be replaced with FcConstants. |
166 | |
167 fontconfig assumes that objects (property names) are statically allocated, | |
3354 | 168 and you will get bizarre results if you pass Lisp string data or strings |
169 allocated on the stack as objects. fontconfig _does_ copy values, so we | |
170 (I hope) don't have to worry about that member. | |
171 | |
172 Probably these functions don't get called so often that the memory leak | |
173 due to strdup'ing every time we add a property would matter, but XEmacs | |
174 _is_ a long-running process. So we hash them. | |
175 | |
176 I suspect that using symbol names or even keywords does not provide | |
177 assurance that the string won't move in memory. So we hash them | |
3360 | 178 ourselves; hash.c hashtables do not interpret the value pointers. |
179 | |
180 This array should be FcChar8**, but GCC 4.x bitches about signedness. */ | |
181 static Extbyte *fc_standard_properties[] = { | |
182 /* treated specially, ordered first */ | |
183 "family", "size", | |
184 /* remaining are alphabetized by group */ | |
185 /* standard properties in fontconfig and Xft v.2 */ | |
186 "antialias", "aspect", "autohint", "charset", "dpi", "file", | |
3354 | 187 "foundry", "ftface", "globaladvance", "hinting", "index", "lang", |
188 "minspace", "outline", "pixelsize", "rasterizer", "rgba", "scalable", | |
3360 | 189 "scale", "slant", "spacing", "style", "verticallayout", "weight", |
190 /* common in modern fonts */ | |
191 "fontformat", "fontversion", | |
3354 | 192 /* obsolete after Xft v. 1 */ |
193 "charwidth", "charheight", "core", "encoding", "render" | |
194 }; | |
195 | |
196 static struct hash_table *fc_property_name_hash_table; | |
197 | |
198 /* #### Maybe fc_intern should be exposed to LISP? The idea is that | |
199 fc-pattern-add could warn or error if the property isn't interned. */ | |
200 | |
3469 | 201 static const Extbyte * |
3354 | 202 fc_intern (Lisp_Object property) |
203 { | |
204 const void *dummy; | |
3469 | 205 const Extbyte *prop = extract_fcapi_string (property); |
3354 | 206 const void *val = gethash (prop, fc_property_name_hash_table, &dummy); |
207 | |
208 /* extract_fcapi_string returns something alloca'd | |
209 so we can just drop the old value of prop on the floor */ | |
210 if (val) | |
3469 | 211 prop = (const Extbyte *) val; |
3354 | 212 else |
213 { | |
3469 | 214 prop = (const Extbyte *) FcStrCopy ((FcChar8 *) prop); |
3354 | 215 puthash (prop, NULL, fc_property_name_hash_table); |
216 } | |
217 return prop; | |
218 } | |
219 | |
220 DEFUN("fc-pattern-p", Ffc_pattern_p, 1, 1, 0, /* | |
221 Returns t if OBJECT is of type fc-pattern, nil otherwise. | |
222 */ | |
223 (object)) | |
224 { | |
225 return FCPATTERNP(object) ? Qt : Qnil; | |
226 } | |
227 | |
228 DEFUN("fc-pattern-create", Ffc_pattern_create, 0, 0, 0, /* | |
229 Return a new, empty fc-pattern object. | |
230 */ | |
231 ()) | |
232 { | |
233 fc_pattern *fcpat = | |
234 ALLOC_LCRECORD_TYPE (struct fc_pattern, &lrecord_fc_pattern); | |
235 | |
236 fcpat->fcpatPtr = FcPatternCreate(); | |
237 return wrap_fcpattern(fcpat); | |
238 } | |
239 | |
240 DEFUN("fc-name-parse", Ffc_name_parse, 1, 1, 0, /* | |
241 Parse an Fc font name and return its representation as a fc pattern object. | |
242 */ | |
243 (name)) | |
244 { | |
245 struct fc_pattern *fcpat = | |
246 ALLOC_LCRECORD_TYPE (struct fc_pattern, &lrecord_fc_pattern); | |
247 | |
3906 | 248 CHECK_STRING(name); |
3354 | 249 |
3469 | 250 fcpat->fcpatPtr = FcNameParse ((FcChar8 *) extract_fcapi_string (name)); |
3354 | 251 return wrap_fcpattern(fcpat); |
252 } | |
253 | |
254 /* #### Ga-a-ack! Xft's similar function is actually a different API. | |
255 We provide both. */ | |
256 DEFUN("fc-name-unparse", Ffc_name_unparse, 1, 1, 0, /* | |
257 Unparse an fc pattern object to a string. | |
258 */ | |
259 (pattern)) | |
260 { | |
261 CHECK_FCPATTERN(pattern); | |
3906 | 262 return build_fcapi_string (FcNameUnparse (XFCPATTERN_PTR (pattern))); |
3354 | 263 } |
264 | |
265 DEFUN("fc-pattern-duplicate", Ffc_pattern_duplicate, 1, 1, 0, /* | |
266 Make a copy of the fc pattern object PATTERN and return it. | |
267 */ | |
268 (pattern)) | |
269 { | |
270 struct fc_pattern *copy = NULL; | |
271 CHECK_FCPATTERN(pattern); | |
272 | |
273 copy = ALLOC_LCRECORD_TYPE (struct fc_pattern, &lrecord_fc_pattern); | |
274 copy->fcpatPtr = FcPatternDuplicate(XFCPATTERN_PTR(pattern)); | |
275 return wrap_fcpattern(copy); | |
276 } | |
277 | |
278 DEFUN("fc-pattern-add", Ffc_pattern_add, 3, 3, 0, /* | |
279 Add attributes to the pattern object PATTERN. PROPERTY is a string naming | |
280 the attribute to add, VALUE the value for this attribute. | |
281 | |
282 VALUE may be a string, integer, float, or symbol, in which case the value | |
283 will be added as an FcChar8[], int, double, or FcBool respectively. | |
284 */ | |
285 (pattern, property, value)) | |
286 { | |
287 Bool res = 0; | |
3469 | 288 const Extbyte *obj; |
3354 | 289 FcPattern *fcpat; |
290 | |
291 CHECK_FCPATTERN(pattern); | |
292 CHECK_STRING(property); | |
293 | |
294 obj = fc_intern (property); | |
295 fcpat = XFCPATTERN_PTR (pattern); | |
296 | |
297 if (STRINGP(value)) | |
298 { | |
299 FcChar8 *str = (FcChar8 *) extract_fcapi_string (value); | |
300 res = FcPatternAddString (fcpat, obj, str); | |
301 } | |
302 else if (INTP(value)) | |
303 { | |
304 res = FcPatternAddInteger (fcpat, obj, XINT(value)); | |
305 } | |
306 else if (FLOATP(value)) | |
307 { | |
308 res = FcPatternAddDouble (fcpat, obj, (double) XFLOAT_DATA(value)); | |
309 } | |
310 else if (SYMBOLP(value)) | |
311 { | |
312 res = FcPatternAddBool (fcpat, obj, !NILP(value)); | |
313 } | |
314 /* else ... maybe we should wta here? */ | |
315 | |
316 return res ? Qt : Qnil; | |
317 } | |
318 | |
319 DEFUN("fc-pattern-del", Ffc_pattern_del, 2, 2, 0, /* | |
320 Remove attribute PROPERTY from fc pattern object OBJECT. | |
321 */ | |
322 (pattern, property)) | |
323 { | |
324 Bool res; | |
325 | |
326 CHECK_FCPATTERN(pattern); | |
327 CHECK_STRING(property); | |
328 | |
3469 | 329 res = FcPatternDel(XFCPATTERN_PTR(pattern), extract_fcapi_string (property)); |
3354 | 330 return res ? Qt : Qnil; |
331 } | |
332 | |
333 /* Generic interface to FcPatternGet() | |
334 * Don't support the losing symbol-for-property interface. | |
335 */ | |
336 DEFUN("fc-pattern-get", Ffc_pattern_get, 2, 4, 0, /* | |
337 From PATTERN, extract PROPERTY for the ID'th member, of type TYPE. | |
338 | |
339 PATTERN is an Xft (fontconfig) pattern object. | |
340 PROPERTY is a string naming an fontconfig font property. | |
341 Optional ID is a nonnegative integer indexing the list of values for PROPERTY | |
342 stored in PATTERN, defaulting to 0 (the first value). | |
343 Optional TYPE is a symbol, one of 'string, 'boolean, 'integer, 'float, | |
344 'double, 'matrix, 'charset, or 'void, corresponding to the FcValue types. | |
345 ('float is an alias for 'double). | |
346 | |
347 The Lisp types returned will conform to TYPE: | |
348 string string | |
349 boolean `t' or `nil' | |
350 integer integer | |
351 double (float) float | |
352 matrix not implemented | |
353 charset not implemented | |
354 void not implemented | |
355 | |
356 Symbols with names of the form "fc-result-DESCRIPTION" are returned when | |
357 the desired value is not available. These are | |
358 | |
359 fc-result-type-mismatch the value found has an unexpected type | |
360 fc-result-no-match there is no such attribute | |
361 fc-result-no-id there is no value for the requested ID | |
362 | |
363 The types of the following standard properties are predefined by fontconfig. | |
364 The symbol 'fc-result-type-mismatch will be returned if the object exists but | |
365 TYPE does not match the predefined type. It is best not to specify a type | |
366 for predefined properties, as a mistake here ensures error returns on the | |
367 correct type. | |
368 | |
369 Each standard property has a convenience accessor defined in fontconfig.el, | |
370 named in the form "fc-pattern-get-PROPERTY". The convenience functions are | |
371 preferred to `fc-pattern-get' since a typo in the string naming a property | |
372 will result in a silent null return, while a typo in a function name will | |
373 usually result in a compiler or runtime \"not fboundp\" error. You may use | |
374 `defsubst' to define convenience functions for non-standard properties. | |
375 | |
376 family String Font family name | |
377 style String Font style. Overrides weight and slant | |
378 slant Int Italic, oblique or roman | |
379 weight Int Light, medium, demibold, bold or black | |
380 size Double Point size | |
381 aspect Double Stretches glyphs horizontally before hinting | |
382 pixelsize Double Pixel size | |
383 spacing Int Proportional, monospace or charcell | |
384 foundry String Font foundry name | |
385 antialias Bool Whether glyphs can be antialiased | |
386 hinting Bool Whether the rasterizer should use hinting | |
387 verticallayout Bool Use vertical layout | |
388 autohint Bool Use autohinter instead of normal hinter | |
389 globaladvance Bool Use font global advance data | |
390 file String The filename holding the font | |
391 index Int The index of the font within the file | |
392 ftface FT_Face Use the specified FreeType face object | |
393 rasterizer String Which rasterizer is in use | |
394 outline Bool Whether the glyphs are outlines | |
395 scalable Bool Whether glyphs can be scaled | |
396 scale Double Scale factor for point->pixel conversions | |
397 dpi Double Target dots per inch | |
398 rgba Int unknown, rgb, bgr, vrgb, vbgr, none - subpixel geometry | |
399 minspace Bool Eliminate leading from line spacing | |
400 charset CharSet Unicode chars encoded by the font | |
401 lang String List of RFC-3066-style languages this font supports | |
402 | |
403 The FT_Face, Matrix, CharSet types are unimplemented, so the corresponding | |
404 properties are not accessible from Lisp at this time. If the value of a | |
405 property returned has type FT_Face, FcCharSet, or FcMatrix, | |
406 `fc-result-type-mismatch' is returned. | |
407 | |
408 The following properties which were standard in Xft v.1 are obsolete in | |
409 Xft v.2: encoding, charwidth, charheight, core, and render. */ | |
410 (pattern, property, id, type)) | |
411 { | |
3469 | 412 Extbyte *fc_property; |
3354 | 413 FcResult fc_result; |
414 FcValue fc_value; | |
415 | |
416 /* | |
417 process arguments | |
418 */ | |
419 CHECK_FCPATTERN (pattern); | |
420 | |
421 #if 0 | |
422 /* Don't support the losing symbol-for-property interface. */ | |
423 property = SYMBOLP (property) ? symbol_name (XSYMBOL (property)) : property; | |
424 #endif | |
425 if (STRINGP (property)) | |
426 { | |
3469 | 427 fc_property = extract_fcapi_string (property); |
3354 | 428 } |
429 else | |
430 { | |
431 /* if we allow symbols, this would need to be | |
432 list3 (Qlambda, list1 (Qobject), | |
433 list3 (Qor, list2 (Qstringp, Qobject), | |
434 list2 (Qsymbolp, Qobject))) | |
435 or something like that? */ | |
436 dead_wrong_type_argument (Qstringp, property); | |
437 } | |
438 | |
439 if (!NILP (id)) CHECK_NATNUM (id); | |
440 if (!NILP (type)) CHECK_SYMBOL (type); | |
441 | |
442 /* get property */ | |
443 fc_result = FcPatternGet (XFCPATTERN_PTR (pattern), | |
444 fc_property, | |
445 NILP (id) ? 0 : XINT(id), | |
446 &fc_value); | |
447 | |
448 switch (fc_result) | |
449 { | |
450 case FcResultMatch: | |
451 /* wrap it and return */ | |
452 switch (fc_value.type) | |
453 { | |
454 case FcTypeInteger: | |
455 return ((!NILP (type) && !EQ (type, Qinteger)) | |
456 ? Qfc_result_type_mismatch : make_int (fc_value.u.i)); | |
457 case FcTypeDouble: | |
458 return ((!NILP (type) && !EQ (type, intern ("double")) | |
459 && !EQ (type, Qfloat)) | |
460 ? Qfc_result_type_mismatch : make_float (fc_value.u.d)); | |
461 case FcTypeString: | |
462 return ((!NILP (type) && !EQ (type, Qstring)) | |
463 ? Qfc_result_type_mismatch | |
3906 | 464 : build_fcapi_string (fc_value.u.s)); |
3354 | 465 case FcTypeBool: |
466 return ((!NILP (type) && !EQ (type, Qboolean)) | |
467 ? Qfc_result_type_mismatch : fc_value.u.b ? Qt : Qnil); | |
468 case FcTypeMatrix: | |
469 return Qfc_result_type_mismatch; | |
470 /* #### unimplemented | |
471 return ((!NILP (type) && !EQ (type, intern ("matrix"))) | |
472 ? Qfc_result_type_mismatch : make_int (fc_value.u.m)); | |
473 */ | |
474 case FcTypeCharSet: | |
475 return Qfc_result_type_mismatch; | |
476 /* #### unimplemented | |
477 return ((!NILP (type) && !EQ (type, intern ("charset"))) | |
478 ? Qfc_result_type_mismatch : make_int (fc_value.u.c)); | |
479 */ | |
480 } | |
481 case FcResultTypeMismatch: | |
482 return Qfc_result_type_mismatch; | |
483 case FcResultNoMatch: | |
484 return Qfc_result_no_match; | |
485 case FcResultNoId: | |
486 return Qfc_result_no_id; | |
487 default: | |
488 return Qfc_internal_error; | |
489 } | |
490 } | |
491 | |
492 DEFUN("fc-font-match", Ffc_font_match, 2, 2, 0, /* | |
493 Return the font on DEVICE that most closely matches PATTERN. | |
494 | |
495 DEVICE is an X11 device. | |
496 PATTERN is a fontconfig pattern object. | |
497 Returns a fontconfig pattern object representing the closest match to the | |
498 given pattern, or an error code. Possible error codes are | |
499 `fc-result-no-match' and `fc-result-no-id'. */ | |
500 (device, pattern)) | |
501 { | |
502 FcResult res; | |
3906 | 503 struct fc_pattern *res_fcpat; |
3354 | 504 |
3906 | 505 CHECK_FCPATTERN(pattern); |
3354 | 506 if (NILP(device)) |
507 return Qnil; | |
508 CHECK_X_DEVICE(device); | |
509 if (!DEVICE_LIVE_P(XDEVICE(device))) | |
510 return Qnil; | |
511 | |
3906 | 512 res_fcpat = ALLOC_LCRECORD_TYPE (struct fc_pattern, &lrecord_fc_pattern); |
3360 | 513 { |
514 FcPattern *p = XFCPATTERN_PTR(pattern); | |
515 FcConfig *fcc = FcConfigGetCurrent (); | |
516 | |
517 FcConfigSubstitute (fcc, p, FcMatchPattern); | |
518 FcDefaultSubstitute (p); | |
519 res_fcpat->fcpatPtr = FcFontMatch (fcc, p, &res); | |
520 } | |
521 | |
3354 | 522 if (res_fcpat->fcpatPtr == NULL) |
523 switch (res) { | |
524 case FcResultNoMatch: | |
525 return Qfc_result_no_match; | |
526 case FcResultNoId: | |
527 return Qfc_result_no_id; | |
528 default: | |
529 return Qfc_internal_error; | |
530 } | |
531 else | |
532 return wrap_fcpattern(res_fcpat); | |
533 } | |
534 | |
3931 | 535 enum DestroyFontsetP { DestroyNo = 0, DestroyYes = 1 }; |
536 | |
3354 | 537 static Lisp_Object |
3931 | 538 fontset_to_list (FcFontSet *fontset, enum DestroyFontsetP destroyp) |
3354 | 539 { |
540 int idx; | |
541 Lisp_Object fontlist = Qnil; | |
542 fc_pattern *fcpat; | |
543 | |
544 /* #### improve this error message */ | |
545 if (!fontset) | |
546 Fsignal (Qinvalid_state, | |
547 list1 (build_string ("failed to create FcFontSet"))); | |
548 for (idx = 0; idx < fontset->nfont; ++idx) | |
549 { | |
550 fcpat = | |
551 ALLOC_LCRECORD_TYPE (struct fc_pattern, &lrecord_fc_pattern); | |
552 fcpat->fcpatPtr = FcPatternDuplicate (fontset->fonts[idx]); | |
553 fontlist = Fcons (wrap_fcpattern(fcpat), fontlist); | |
554 } | |
3931 | 555 if (destroyp) |
556 FcFontSetDestroy (fontset); | |
3354 | 557 return fontlist; |
558 } | |
559 | |
560 /* #### fix this name to correspond to Ben's new nomenclature */ | |
561 DEFUN("fc-list-fonts-pattern-objects", Ffc_list_fonts_pattern_objects, | |
562 3, 3, 0, /* | |
563 Return a list of fonts on DEVICE that match PATTERN for PROPERTIES. | |
564 Each font is represented by a fontconfig pattern object. | |
565 | |
566 DEVICE is an X11 device. | |
567 PATTERN is a fontconfig pattern to be matched. | |
568 PROPERTIES is a list of property names (strings) that should match. | |
569 | |
570 #### DEVICE is unused, ignored, and may be removed if it's not needed to | |
571 match other font-listing APIs. */ | |
572 (UNUSED (device), pattern, properties)) | |
573 { | |
574 FcObjectSet *os; | |
575 FcFontSet *fontset; | |
576 | |
577 CHECK_FCPATTERN (pattern); | |
578 CHECK_LIST (properties); | |
579 | |
580 os = FcObjectSetCreate (); | |
581 string_list_to_fcobjectset (properties, os); | |
582 /* #### why don't we need to do the "usual substitutions"? */ | |
583 fontset = FcFontList (NULL, XFCPATTERN_PTR (pattern), os); | |
584 FcObjectSetDestroy (os); | |
585 | |
3931 | 586 return fontset_to_list (fontset, DestroyYes); |
3354 | 587 |
588 } | |
589 | |
590 /* #### maybe this can/should be folded into fc-list-fonts-pattern-objects? */ | |
591 DEFUN("fc-font-sort", Ffc_font_sort, 2, 4, 0, /* | |
592 Return a list of all fonts sorted by proximity to PATTERN. | |
593 Each font is represented by a fontconfig pattern object. | |
594 | |
595 DEVICE is an X11 device. | |
596 PATTERN is a fontconfig pattern to be matched. | |
597 Optional argument TRIM, if non-nil, means to trim trailing fonts that do not | |
598 contribute new characters to the union repertoire. | |
599 | |
600 #### Optional argument NOSUB, if non-nil, suppresses some of the usual | |
601 property substitutions. DON'T USE THIS in production code, it is intended | |
602 for exploring behavior of fontconfig and will be removed when this code is | |
603 stable. | |
604 | |
605 #### DEVICE is unused, ignored, and may be removed if it's not needed to | |
606 match other font-listing APIs. */ | |
607 (UNUSED (device), pattern, trim, nosub)) | |
608 { | |
609 CHECK_FCPATTERN (pattern); | |
610 | |
611 { | |
612 FcConfig *fcc = FcConfigGetCurrent(); | |
613 FcFontSet *fontset; | |
614 FcPattern *p = XFCPATTERN_PTR (pattern); | |
615 FcResult fcresult; | |
616 | |
617 if (NILP(nosub)) /* #### temporary debug hack */ | |
618 FcDefaultSubstitute (p); | |
619 FcConfigSubstitute (fcc, p, FcMatchPattern); | |
620 fontset = FcFontSort (fcc, p, !NILP(trim), NULL, &fcresult); | |
621 | |
3931 | 622 return fontset_to_list (fontset, DestroyYes); |
623 } | |
624 } | |
625 | |
626 #ifdef FONTCONFIG_EXPOSE_CONFIG | |
627 | |
628 /* Configuration routines --- for debugging | |
629 Don't depend on these routines being available in the future! | |
630 | |
631 3.2.10 Initialization | |
632 --------------------- | |
633 | |
634 An FcConfig object holds the internal representation of a configuration. | |
635 There is a default configuration which applications may use by passing | |
636 0 to any function using the data within an FcConfig. | |
637 */ | |
638 | |
639 static void | |
640 finalize_fc_config (void *header, int UNUSED (for_disksave)) | |
641 { | |
642 struct fc_config *p = (struct fc_config *) header; | |
643 if (p->fccfgPtr && p->fccfgPtr != FcConfigGetCurrent()) | |
644 { | |
645 /* If we get here, all of *our* references are garbage (see comment on | |
646 fc_config_create_using() for why), and the only reference that | |
647 fontconfig keeps is the current FcConfig. */ | |
648 FcConfigDestroy (p->fccfgPtr); | |
649 } | |
650 p->fccfgPtr = 0; | |
651 } | |
652 | |
653 static void | |
654 print_fc_config (Lisp_Object obj, Lisp_Object printcharfun, | |
655 int UNUSED(escapeflag)) | |
656 { | |
657 struct fc_config *c = XFCCONFIG (obj); | |
658 if (print_readably) | |
659 printing_unreadable_object ("#<fc-config 0x%x>", c->header.uid); | |
660 write_fmt_string (printcharfun, "#<fc-config 0x%x>", c->header.uid); | |
661 } | |
662 | |
663 static const struct memory_description fcconfig_description [] = { | |
664 /* #### nothing here, is this right?? */ | |
665 { XD_END } | |
666 }; | |
667 | |
668 DEFINE_LRECORD_IMPLEMENTATION("fc-config", fc_config, 0, | |
669 0, print_fc_config, finalize_fc_config, 0, 0, | |
670 fcconfig_description, | |
671 struct fc_config); | |
672 | |
673 /* We obviously need to be careful about garbage collecting the current | |
674 FcConfig. I infer from the documentation of FcConfigDestroy that that | |
675 is the only reference maintained by fontconfig. | |
676 So we keep track of our own references on a weak list, and only cons a | |
677 new object if we don't already have a reference to it there. */ | |
678 | |
679 static Lisp_Object | |
680 fc_config_create_using (FcConfig * (*create_function) ()) | |
681 { | |
682 FcConfig *fc = (*create_function) (); | |
683 Lisp_Object configs = XWEAK_LIST_LIST (Vfc_config_weak_list); | |
684 | |
685 /* Linear search: fc_configs are not going to multiply like conses. */ | |
686 { | |
687 LIST_LOOP_2 (cfg, configs) | |
688 if (fc == XFCCONFIG_PTR (cfg)) | |
689 return cfg; | |
690 } | |
691 | |
692 { | |
693 fc_config *fccfg = | |
694 ALLOC_LCRECORD_TYPE (struct fc_config, &lrecord_fc_config); | |
695 fccfg->fccfgPtr = fc; | |
696 configs = Fcons (wrap_fcconfig (fccfg), configs); | |
697 XWEAK_LIST_LIST (Vfc_config_weak_list) = configs; | |
698 return wrap_fcconfig (fccfg); | |
3354 | 699 } |
700 } | |
701 | |
3931 | 702 DEFUN("fc-config-p", Ffc_config_p, 1, 1, 0, /* |
703 Returns t if OBJECT is of type fc-config, nil otherwise. | |
704 */ | |
705 (object)) | |
706 { | |
707 return FCCONFIGP (object) ? Qt : Qnil; | |
708 } | |
709 | |
710 DEFUN("fc-config-create", Ffc_config_create, 0, 0, 0, /* | |
711 -- Function: FcConfig *FcConfigCreate (void) | |
712 Creates an empty configuration. */ | |
713 ()) | |
714 { | |
715 return fc_config_create_using (&FcConfigCreate); | |
716 } | |
717 | |
718 #if 0 | |
719 /* I'm sorry, but we just don't do this in Lisp, OK? | |
720 Don't even think about implementing this. */ | |
721 DEFUN("fc-config-destroy", Ffc_config_destroy, 1, 1, 0, /* | |
722 -- Function: void FcConfigDestroy (FcConfig *config) | |
723 Destroys a configuration and any data associated with it. Note | |
724 that calling this function with the return value from | |
725 FcConfigGetCurrent will place the library in an indeterminate | |
726 state. */ | |
727 (config)) | |
728 { | |
729 signal_error (Qunimplemented, "No user-servicable parts!", | |
730 intern ("fc-config-destroy"); | |
731 } | |
732 #endif | |
733 | |
734 DEFUN("fc-config-get-current", Ffc_config_get_current, 0, 0, 0, /* | |
735 -- Function: FcConfig *FcConfigGetCurrent (void) | |
736 Returns the current default configuration. */ | |
737 ()) | |
738 { | |
739 return fc_config_create_using (&FcConfigGetCurrent); | |
740 } | |
741 | |
742 DEFUN("fc-config-up-to-date", Ffc_config_up_to_date, 1, 1, 0, /* | |
743 -- Function: FcBool FcConfigUptoDate (FcConfig *config) | |
744 Checks all of the files related to 'config' and returns whether the | |
745 in-memory version is in sync with the disk version. */ | |
746 (config)) | |
747 { | |
748 CHECK_FCCONFIG (config); | |
749 return FcConfigUptoDate (XFCCONFIG_PTR (config)) == FcFalse ? Qnil : Qt; | |
750 } | |
751 | |
752 DEFUN("fc-config-build-fonts", Ffc_config_build_fonts, 1, 1, 0, /* | |
753 -- Function: FcBool FcConfigBuildFonts (FcConfig *config) | |
754 Builds the set of available fonts for the given configuration. | |
755 Note that any changes to the configuration after this call have | |
756 indeterminate effects. Returns FcFalse if this operation runs out | |
757 of memory. | |
758 XEmacs: signal out-of-memory, or return nil on success. */ | |
759 (config)) | |
760 { | |
761 CHECK_FCCONFIG (config); | |
762 if (FcConfigBuildFonts (XFCCONFIG_PTR (config)) == FcFalse) | |
763 out_of_memory ("FcConfigBuildFonts failed", config); | |
764 return Qnil; | |
765 } | |
766 | |
767 /* Calls its argument on `config', which must be defined by the caller. */ | |
768 | |
769 #define FCSTRLIST_TO_LISP_USING(source) do { \ | |
770 FcChar8 *thing; \ | |
771 FcStrList *thing_list; \ | |
772 Lisp_Object value = Qnil; \ | |
773 CHECK_FCCONFIG (config); \ | |
774 thing_list = source (XFCCONFIG_PTR(config)); \ | |
775 /* Yes, we need to do this check -- sheesh, Keith! */ \ | |
776 if (!thing_list) \ | |
777 return Qnil; \ | |
778 while ((thing = FcStrListNext (thing_list))) \ | |
779 value = Fcons (build_fcapi_string (thing), value); \ | |
780 FcStrListDone (thing_list); \ | |
781 return value; \ | |
782 } while (0) | |
783 | |
784 DEFUN("fc-config-get-config-dirs", Ffc_config_get_config_dirs, 1, 1, 0, /* | |
785 -- Function: FcStrList *FcConfigGetConfigDirs (FcConfig *config) | |
786 Returns the list of font directories specified in the | |
787 configuration files for 'config'. Does not include any | |
788 subdirectories. */ | |
789 (config)) | |
790 { | |
791 FCSTRLIST_TO_LISP_USING (FcConfigGetConfigDirs); | |
792 } | |
793 | |
794 DEFUN("fc-config-get-font-dirs", Ffc_config_get_font_dirs, 1, 1, 0, /* | |
795 -- Function: FcStrList *FcConfigGetFontDirs (FcConfig *config) | |
796 Returns the list of font directories in 'config'. This includes the | |
797 configured font directories along with any directories below those | |
798 in the filesystem. */ | |
799 (config)) | |
800 { | |
801 FCSTRLIST_TO_LISP_USING (FcConfigGetFontDirs); | |
802 } | |
803 | |
804 DEFUN("fc-config-get-config-files", Ffc_config_get_config_files, 1, 1, 0, /* | |
805 -- Function: FcStrList *FcConfigGetConfigFiles (FcConfig *config) | |
806 Returns the list of known configuration files used to generate | |
807 'config'. Note that this will not include any configuration done | |
808 with FcConfigParse. */ | |
809 (config)) | |
810 { | |
811 FCSTRLIST_TO_LISP_USING (FcConfigGetConfigFiles); | |
812 } | |
813 | |
814 #undef FCSTRLIST_TO_LISP_USING | |
815 | |
816 DEFUN("fc-config-get-cache", Ffc_config_get_cache, 1, 1, 0, /* | |
817 -- Function: char *FcConfigGetCache (FcConfig *config) | |
818 Returns the name of the file used to store per-user font | |
819 information. */ | |
820 (config)) | |
821 { | |
822 CHECK_FCCONFIG (config); | |
823 /* Surely FcConfigGetCache just casts an FcChar8* to char*. */ | |
824 return build_fcapi_string ((FcChar8 *) FcConfigGetCache (XFCCONFIG_PTR (config))); | |
825 } | |
826 | |
827 DEFUN("fc-config-get-fonts", Ffc_config_get_fonts, 2, 2, 0, /* | |
828 -- Function: FcFontSet *FcConfigGetFonts (FcConfig *config, FcSetName set) | |
829 Returns one of the two sets of fonts from the configuration as | |
830 specified by 'set'. | |
831 `FcSetName' | |
832 Specifies one of the two sets of fonts available in a | |
833 configuration; FcSetSystem for those fonts specified in the | |
834 configuration and FcSetApplication which holds fonts provided by | |
835 the application. */ | |
836 (config, set)) | |
837 { | |
838 FcSetName name = FcSetSystem; | |
839 FcFontSet *fs = NULL; | |
840 | |
841 CHECK_FCCONFIG (config); | |
842 CHECK_SYMBOL (set); | |
843 | |
844 if (EQ (set, intern ("fc-set-system"))) | |
845 name = FcSetSystem; | |
846 else if (EQ (set, intern ("fc-set-application"))) | |
847 name = FcSetApplication; | |
848 else | |
849 wtaerror ("must be in (fc-set-system fc-set-application)", set); | |
850 | |
851 fs = FcConfigGetFonts (XFCCONFIG_PTR (config), name); | |
852 return fs ? fontset_to_list (fs, DestroyNo) : Qnil; | |
853 } | |
854 | |
855 DEFUN("fc-config-set-current", Ffc_config_set_current, 1, 1, 0, /* | |
856 -- Function: FcBool FcConfigSetCurrent (FcConfig *config) | |
857 Sets the current default configuration to 'config'. Implicitly | |
858 calls FcConfigBuildFonts if necessary, returning FcFalse if that | |
859 call fails. | |
860 XEmacs: signals out-of-memory if FcConfigBuildFonts fails, or args-out-of-range | |
861 if the resulting FcConfig has no fonts (which would crash XEmacs if installed). | |
862 */ | |
863 (config)) | |
864 { | |
865 CHECK_FCCONFIG (config); | |
866 /* *sigh* "Success" DOES NOT mean you have any fonts available. It is | |
867 easy to crash fontconfig, and XEmacs with it. Without the following | |
868 check, this will do it: | |
869 (progn | |
870 (fc-config-set-current (fc-config-create)) | |
871 (set-face-font 'default "serif-12")) | |
872 */ | |
873 | |
874 if (FcConfigBuildFonts (XFCCONFIG_PTR (config)) == FcFalse) | |
875 out_of_memory ("FcConfigBuildFonts failed", config); | |
876 /* #### We'd like to avoid this consing, and FcConfigGetFonts sometimes | |
877 returns NULL, but it doesn't always. This will do for now .... */ | |
878 if (NILP (Ffc_config_get_fonts (config, intern ("fc-set-system"))) | |
879 && NILP (Ffc_config_get_fonts (config, intern ("fc-set-application")))) | |
880 signal_error (intern ("args-out-of-range"), "no fonts found", config); | |
881 /* Should never happen, but I don't trust Keith anymore .... */ | |
882 if (FcConfigSetCurrent (XFCCONFIG_PTR (config)) == FcFalse) | |
883 out_of_memory ("FcConfigBuildFonts failed in set", config); | |
884 return Qnil; | |
885 } | |
886 | |
887 DEFUN("fc-config-get-blanks", Ffc_config_get_blanks, 1, 1, 0, /* | |
888 -- Function: FcBlanks *FcConfigGetBlanks (FcConfig *config) | |
889 Returns the FcBlanks object associated with the given | |
890 configuration, if no blanks were present in the configuration, | |
891 this function will return 0. | |
892 XEmacs: should convert to a chartable. | |
893 #### Unimplemented. */ | |
894 (config)) | |
895 { | |
896 CHECK_FCCONFIG (config); | |
897 signal_error (Qunimplemented, "no method to convert FcBlanks object", | |
898 intern ("fc-config-get-blanks")); | |
899 } | |
900 | |
901 DEFUN("fc-config-get-rescan-interval", Ffc_config_get_rescan_interval, 1, 1, 0, /* | |
4328
dfd878799ef0
Autoconfiscate the recent fontconfig spelling change.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3935
diff
changeset
|
902 -- Function: int FcConfigGetRescanInterval (FcConfig *config) |
3931 | 903 Returns the interval between automatic checks of the configuration |
904 (in seconds) specified in 'config'. The configuration is checked | |
905 during a call to FcFontList when this interval has passed since | |
906 the last check. */ | |
907 (config)) | |
908 { | |
909 CHECK_FCCONFIG (config); | |
4328
dfd878799ef0
Autoconfiscate the recent fontconfig spelling change.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3935
diff
changeset
|
910 return make_int (FcConfigGetRescanInterval (XFCCONFIG_PTR (config))); |
3931 | 911 } |
912 | |
913 DEFUN("fc-config-set-rescan-interval", Ffc_config_set_rescan_interval, 2, 2, 0, /* | |
4328
dfd878799ef0
Autoconfiscate the recent fontconfig spelling change.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3935
diff
changeset
|
914 -- Function: FcBool FcConfigSetRescanInterval (FcConfig *config, int |
3931 | 915 rescanInterval) |
916 Sets the rescan interval; returns FcFalse if an error occurred. | |
917 XEmacs: signal such error, or return nil on success. */ | |
918 (config, rescan_interval)) | |
919 { | |
920 CHECK_FCCONFIG (config); | |
921 CHECK_INT (rescan_interval); | |
4328
dfd878799ef0
Autoconfiscate the recent fontconfig spelling change.
Aidan Kehoe <kehoea@parhasard.net>
parents:
3935
diff
changeset
|
922 if (FcConfigSetRescanInterval (XFCCONFIG_PTR (config), |
3931 | 923 XINT (rescan_interval)) == FcFalse) |
924 signal_error (Qio_error, "FcConfigSetRescanInverval barfed", | |
925 intern ("fc-config-set-rescan-interval")); | |
926 return Qnil; | |
927 } | |
928 | |
929 /* #### This might usefully be made interactive. */ | |
930 DEFUN("fc-config-app-font-add-file", Ffc_config_app_font_add_file, 2, 2, 0, /* | |
931 -- Function: FcBool FcConfigAppFontAddFile (FcConfig *config, const | |
932 char *file) | |
933 Adds an application-specific font to the configuration. */ | |
934 (config, file)) | |
935 { | |
936 CHECK_FCCONFIG (config); | |
937 CHECK_STRING (file); | |
938 if (FcConfigAppFontAddFile | |
939 (XFCCONFIG_PTR (config), | |
940 /* #### FIXME! is this really Qnative? */ | |
941 (FcChar8 *) NEW_LISP_STRING_TO_EXTERNAL ((file), Qnative)) == FcFalse) | |
942 return Qnil; | |
943 else | |
944 return Qt; | |
945 } | |
946 | |
947 /* #### This might usefully be made interactive. */ | |
948 DEFUN("fc-config-app-font-add-dir", Ffc_config_app_font_add_dir, 2, 2, 0, /* | |
949 -- Function: FcBool FcConfigAppFontAddDir (FcConfig *config, const | |
950 char *dir) | |
951 Scans the specified directory for fonts, adding each one found to | |
952 the application-specific set of fonts. */ | |
953 (config, dir)) | |
954 { | |
955 CHECK_FCCONFIG (config); | |
956 CHECK_STRING (dir); | |
957 if (FcConfigAppFontAddDir | |
958 (XFCCONFIG_PTR (config), | |
959 /* #### FIXME! is this really Qnative? */ | |
960 (FcChar8 *) NEW_LISP_STRING_TO_EXTERNAL ((dir), Qnative)) == FcFalse) | |
961 return Qnil; | |
962 else | |
963 return Qt; | |
964 } | |
965 | |
966 /* #### This might usefully be made interactive. */ | |
967 DEFUN("fc-config-app-font-clear", Ffc_config_app_font_clear, 1, 1, 0, /* | |
968 -- Function: void FcConfigAppFontClear (FcConfig *config) | |
969 Clears the set of application-specific fonts. */ | |
970 (config)) | |
971 { | |
972 CHECK_FCCONFIG (config); | |
973 FcConfigAppFontClear (XFCCONFIG_PTR (config)); | |
974 return Qnil; | |
975 } | |
976 | |
977 /* These functions provide some control over how the default | |
978 configuration of the library is initialized. (This configuration is | |
979 normally implicitly initialized.) */ | |
980 | |
981 DEFUN("fc-config-filename", Ffc_config_filename, 1, 1, 0, /* | |
982 -- Function: char *FcConfigFilename (const char *name) | |
983 Given the specified external entity name, return the associated | |
984 filename. This provides applications a way to convert various | |
985 configuration file references into filename form. | |
986 | |
987 A null or empty 'name' indicates that the default configuration | |
988 file should be used; which file this references can be overridden | |
989 with the FC_CONFIG_FILE environment variable. Next, if the name | |
990 starts with '~', it refers to a file in the current users home | |
991 directory. Otherwise if the name doesn't start with '/', it | |
992 refers to a file in the default configuration directory; the | |
993 built-in default directory can be overridden with the | |
994 FC_CONFIG_DIR environment variable. */ | |
995 (name)) | |
996 { | |
997 char *fcname = ""; | |
998 | |
999 if (!NILP (name)) | |
1000 { | |
1001 CHECK_STRING (name); | |
1002 /* #### FIXME! is this really Qnative? */ | |
1003 fcname = NEW_LISP_STRING_TO_EXTERNAL (name, Qnative); | |
1004 } | |
1005 return (build_fcapi_string (FcConfigFilename ((FcChar8 *) fcname))); | |
1006 } | |
1007 | |
1008 DEFUN("fc-init-load-config", Ffc_init_load_config, 0, 0, 0, /* | |
1009 -- Function: FcConfig *FcInitLoadConfig (void) | |
1010 Loads the default configuration file and returns the resulting | |
1011 configuration. Does not load any font information. */ | |
1012 ()) | |
1013 { | |
1014 return fc_config_create_using (&FcInitLoadConfig); | |
1015 } | |
1016 | |
1017 DEFUN("fc-init-load-config-and-fonts", Ffc_init_load_config_and_fonts, 0, 0, 0, /* | |
1018 -- Function: FcConfig *FcInitLoadConfigAndFonts (void) | |
1019 Loads the default configuration file and builds information about | |
1020 the available fonts. Returns the resulting configuration. */ | |
1021 ()) | |
1022 { | |
1023 return fc_config_create_using (&FcInitLoadConfigAndFonts); | |
1024 } | |
1025 | |
1026 DEFUN("fc-init", Ffc_init, 0, 0, 0, /* | |
1027 -- Function: FcBool FcInit (void) | |
1028 Loads the default configuration file and the fonts referenced | |
1029 therein and sets the default configuration to that result. | |
1030 Returns whether this process succeeded or not. If the default | |
1031 configuration has already been loaded, this routine does nothing | |
1032 and returns FcTrue. */ | |
1033 ()) | |
1034 { | |
1035 return (FcInit () == FcTrue) ? Qt : Qnil; | |
1036 } | |
1037 | |
1038 DEFUN("fc-get-version", Ffc_get_version, 0, 0, 0, /* | |
1039 -- Function: int FcGetVersion (void) | |
1040 Returns the version number of the library. | |
3935 | 1041 XEmacs: No, this should NOT return a pretty string. |
3931 | 1042 (let ((i (fc-get-version))) |
1043 (format "%d.%d.%d" (/ i 10000) (mod (/ i 100) 100) (mod i 100))) | |
3935 | 1044 gives the usual x.y.z format. This is the version of the .so. It can be |
1045 checked against `fc-version', which is the version of fontconfig.h. | |
1046 It's probably not a disaster if `(> (fc-get-version) fc-version)'. */ | |
3931 | 1047 ()) |
1048 { | |
1049 return make_int (FcGetVersion ()); | |
1050 } | |
1051 | |
1052 DEFUN("fc-init-reinitialize", Ffc_init_reinitialize, 0, 0, 0, /* | |
1053 -- Function: FcBool FcInitReinitialize (void) | |
1054 Forces the default configuration file to be reloaded and resets | |
1055 the default configuration. */ | |
1056 ()) | |
1057 { | |
1058 return (FcInitReinitialize () == FcTrue) ? Qt : Qnil; | |
1059 } | |
1060 | |
1061 DEFUN("fc-init-bring-up-to-date", Ffc_init_bring_up_to_date, 0, 0, 0, /* | |
1062 -- Function: FcBool FcInitBringUptoDate (void) | |
1063 Checks the rescan interval in the default configuration, checking | |
1064 the configuration if the interval has passed and reloading the | |
1065 configuration when any changes are detected. */ | |
1066 ()) | |
1067 { | |
1068 return (FcInitBringUptoDate () == FcTrue) ? Qt : Qnil; | |
1069 } | |
1070 | |
1071 #endif /* FONTCONFIG_EXPOSE_CONFIG */ | |
1072 | |
3354 | 1073 DEFUN("xlfd-font-name-p", Fxlfd_font_name_p, 1, 1, 0, /* |
1074 Check whether the string FONTNAME is a XLFD font name. */ | |
1075 (fontname)) | |
1076 { | |
1077 CHECK_STRING(fontname); | |
1078 /* #### should bind `case-fold-search' here? */ | |
1079 return Fstring_match(Vxlfd_font_name_regexp, fontname, Qnil, Qnil); | |
1080 } | |
1081 | |
1082 /* FcPatternPrint: there is no point in having wrappers fc-pattern-print, | |
1083 Ffc_pattern_print since this function prints to stdout. */ | |
1084 | |
1085 /* Initialization of font-mgr */ | |
1086 | |
1087 #define XE_XLFD_SEPARATOR "-" | |
1088 /* XLFD specifies ISO 8859-1 encoding, but we can't handle non-ASCII | |
1089 in Mule when this function is called. So use HPC. */ | |
1090 #if 0 | |
1091 #define XE_XLFD_PREFIX "\\(\\+[\040-\176\240-\377]*\\)?-" | |
1092 #define XE_XLFD_OPT_TEXT "\\([\040-\044\046-\176\240-\377]*\\)" | |
1093 #define XE_XLFD_TEXT "\\([\040-\044\046-\176\240-\377]+\\)" | |
1094 #else | |
1095 #define XE_XLFD_PREFIX "\\(\\+[\040-\176]*\\)?-" | |
1096 #define XE_XLFD_OPT_TEXT "\\([^-]*\\)" | |
1097 #define XE_XLFD_TEXT "\\([^-]+\\)" | |
1098 #endif | |
1099 | |
1100 #define XE_XLFD_SLANT "\\([0-9ior?*][iot]?\\)" | |
1101 #define XE_XLFD_SPACING "\\([cmp?*]\\)" | |
1102 /* Hyphen as minus conflicts with use as separator. */ | |
1103 #define XE_XLFD_OPT_NEGATE "~?" | |
1104 #define XE_XLFD_NUMBER "\\([0-9?*]+\\)" | |
1105 #define XE_XLFD_PSIZE "\\([0-9?*]+\\|\\[[ 0-9+~.e?*]+\\]\\)" | |
1106 | |
1107 /* Call this only from the init code | |
1108 #### This is really horrible, let's get rid of it, please. */ | |
1109 static Lisp_Object | |
1110 make_xlfd_font_regexp (void) | |
1111 { | |
1112 struct gcpro gcpro1; | |
1113 unsigned i; | |
1114 Lisp_Object reg = Qnil; | |
1115 const Extbyte *re[] = /* #### This could just be catenated by | |
1116 cpp and passed to build_ext_string. */ | |
1117 { | |
1118 /* Regular expression matching XLFDs as defined by XLFD v. 1.5. | |
1119 Matches must be case-insensitive. | |
1120 PSIZE is a pixel or point size, which may be a "matrix". The | |
1121 syntax of a matrix is not checked, just some lexical properties. | |
1122 AFAICT none of the TEXT fields except adstyle is optional. | |
1123 | |
1124 NB. It should not be a problem if this matches "too much", since | |
1125 an "old" server will simply not be able to find a matching font. */ | |
1126 "\\`", | |
1127 XE_XLFD_PREFIX, /* prefix */ | |
1128 XE_XLFD_TEXT, /* foundry */ | |
1129 XE_XLFD_SEPARATOR, | |
1130 XE_XLFD_TEXT, /* family */ | |
1131 XE_XLFD_SEPARATOR, | |
1132 XE_XLFD_TEXT, /* weight */ | |
1133 XE_XLFD_SEPARATOR, | |
1134 XE_XLFD_SLANT, /* slant */ | |
1135 XE_XLFD_SEPARATOR, | |
1136 XE_XLFD_TEXT, /* swidth */ | |
1137 XE_XLFD_SEPARATOR, | |
1138 XE_XLFD_OPT_TEXT, /* adstyle */ | |
1139 XE_XLFD_SEPARATOR, | |
1140 XE_XLFD_PSIZE, /* pixelsize */ | |
1141 XE_XLFD_SEPARATOR, | |
1142 XE_XLFD_PSIZE, /* pointsize */ | |
1143 XE_XLFD_SEPARATOR, | |
1144 XE_XLFD_NUMBER, /* resx */ | |
1145 XE_XLFD_SEPARATOR, | |
1146 XE_XLFD_NUMBER, /* resy */ | |
1147 XE_XLFD_SEPARATOR, | |
1148 XE_XLFD_SPACING, /* spacing */ | |
1149 XE_XLFD_SEPARATOR, | |
1150 XE_XLFD_OPT_NEGATE, /* avgwidth */ | |
1151 XE_XLFD_NUMBER, | |
1152 XE_XLFD_SEPARATOR, | |
1153 XE_XLFD_TEXT, /* registry */ | |
1154 XE_XLFD_SEPARATOR, | |
1155 XE_XLFD_TEXT, /* encoding */ | |
1156 "\\'" | |
1157 }; | |
1158 | |
1159 GCPRO1 (reg); | |
1160 for (i = 0; i < sizeof(re)/sizeof(Extbyte *); i++) | |
1161 { | |
1162 /* #### Currently this is Host Portable Coding, not ISO 8859-1. */ | |
1163 reg = concat2(reg, build_ext_string (re[i], Qx_font_name_encoding)); | |
1164 } | |
1165 | |
1166 RETURN_UNGCPRO (reg); | |
1167 } | |
1168 #undef XE_XLFD_SEPARATOR | |
1169 #undef XE_XLFD_PREFIX | |
1170 #undef XE_XLFD_OPT_TEXT | |
1171 #undef XE_XLFD_TEXT | |
1172 #undef XE_XLFD_OPT_SLANT | |
1173 #undef XE_XLFD_OPT_SPACING | |
1174 #undef XE_XLFD_OPT_NEGATE | |
1175 #undef XE_XLFD_NUMBER | |
1176 #undef XE_XLFD_PSIZE | |
1177 | |
1178 #define MINL(x,y) ((((unsigned long) (x)) < ((unsigned long) (y))) \ | |
1179 ? ((unsigned long) (x)) : ((unsigned long) (y))) | |
1180 | |
1181 static void | |
1182 string_list_to_fcobjectset (Lisp_Object list, FcObjectSet *os) | |
1183 { | |
1184 EXTERNAL_LIST_LOOP_2 (elt, list) | |
1185 { | |
3469 | 1186 const Extbyte *s; |
3354 | 1187 |
1188 CHECK_STRING (elt); | |
1189 s = fc_intern (elt); | |
1190 FcObjectSetAdd (os, s); | |
1191 } | |
1192 } | |
1193 | |
1194 void | |
1195 syms_of_font_mgr (void) | |
1196 { | |
1197 INIT_LRECORD_IMPLEMENTATION(fc_pattern); | |
1198 | |
1199 DEFSYMBOL_MULTIWORD_PREDICATE(Qfc_patternp); | |
1200 | |
1201 DEFSYMBOL(Qfc_result_type_mismatch); | |
1202 DEFSYMBOL(Qfc_result_no_match); | |
1203 DEFSYMBOL(Qfc_result_no_id); | |
1204 DEFSYMBOL(Qfc_internal_error); | |
3360 | 1205 DEFSYMBOL(Qfont_mgr); |
3354 | 1206 |
1207 DEFSUBR(Ffc_pattern_p); | |
1208 DEFSUBR(Ffc_pattern_create); | |
1209 DEFSUBR(Ffc_name_parse); | |
1210 DEFSUBR(Ffc_name_unparse); | |
1211 DEFSUBR(Ffc_pattern_duplicate); | |
1212 DEFSUBR(Ffc_pattern_add); | |
1213 DEFSUBR(Ffc_pattern_del); | |
1214 DEFSUBR(Ffc_pattern_get); | |
1215 DEFSUBR(Ffc_list_fonts_pattern_objects); | |
1216 DEFSUBR(Ffc_font_sort); | |
1217 DEFSUBR(Ffc_font_match); | |
1218 DEFSUBR(Fxlfd_font_name_p); | |
3931 | 1219 |
1220 #ifdef FONTCONFIG_EXPOSE_CONFIG | |
1221 INIT_LRECORD_IMPLEMENTATION(fc_config); | |
1222 | |
1223 DEFSYMBOL_MULTIWORD_PREDICATE(Qfc_configp); | |
1224 | |
1225 DEFSUBR(Ffc_config_p); | |
1226 DEFSUBR(Ffc_config_create); | |
1227 #if 0 | |
1228 DEFSUBR(Ffc_config_destroy); | |
1229 #endif | |
1230 DEFSUBR(Ffc_config_set_current); | |
1231 DEFSUBR(Ffc_config_get_current); | |
1232 DEFSUBR(Ffc_config_up_to_date); | |
1233 DEFSUBR(Ffc_config_build_fonts); | |
1234 DEFSUBR(Ffc_config_get_config_dirs); | |
1235 DEFSUBR(Ffc_config_get_font_dirs); | |
1236 DEFSUBR(Ffc_config_get_config_files); | |
1237 DEFSUBR(Ffc_config_get_cache); | |
1238 DEFSUBR(Ffc_config_get_fonts); | |
1239 DEFSUBR(Ffc_config_get_blanks); | |
1240 DEFSUBR(Ffc_config_get_rescan_interval); | |
1241 DEFSUBR(Ffc_config_set_rescan_interval); | |
1242 DEFSUBR(Ffc_config_app_font_add_file); | |
1243 DEFSUBR(Ffc_config_app_font_add_dir); | |
1244 DEFSUBR(Ffc_config_app_font_clear); | |
1245 DEFSUBR(Ffc_config_filename); | |
1246 DEFSUBR(Ffc_init_load_config); | |
1247 DEFSUBR(Ffc_init_load_config_and_fonts); | |
1248 DEFSUBR(Ffc_init); | |
1249 DEFSUBR(Ffc_get_version); | |
1250 DEFSUBR(Ffc_init_reinitialize); | |
1251 DEFSUBR(Ffc_init_bring_up_to_date); | |
1252 #endif /* FONTCONFIG_EXPOSE_CONFIG */ | |
3354 | 1253 } |
1254 | |
1255 void | |
1256 vars_of_font_mgr (void) | |
1257 { | |
3935 | 1258 /* #### The next two DEFVARs belong somewhere else. */ |
3354 | 1259 |
1260 /* #### I know, but the right fix is use the generic debug facility. */ | |
1261 DEFVAR_INT ("xft-debug-level", &debug_xft /* | |
1262 Level of debugging messages to issue to stderr for Xft. | |
1263 A nonnegative integer. Set to 0 to suppress all warnings. | |
1264 Default is 1 to ensure a minimum of debugging output at initialization. | |
1265 Higher levels give even more information. | |
1266 */ ); | |
1267 debug_xft = 1; | |
1268 | |
3935 | 1269 DEFVAR_CONST_INT("xft-version", &xft_version /* |
3354 | 1270 The major version number of the Xft library being used. |
1271 */ ); | |
3935 | 1272 xft_version = XFT_VERSION; |
1273 | |
1274 DEFVAR_CONST_INT("fc-version", &fc_version /* | |
1275 The version number of fontconfig.h. It can be checked against | |
1276 `(fc-get-version)', which is the version of the .so. | |
1277 It's probably not a disaster if `(> (fc-get-version) fc-version)'. | |
1278 */ ); | |
1279 fc_version = FC_VERSION; | |
3354 | 1280 |
3360 | 1281 Fprovide (intern ("font-mgr")); |
3354 | 1282 } |
1283 | |
1284 void | |
1285 complex_vars_of_font_mgr (void) | |
1286 { | |
3931 | 1287 #ifdef FONTCONFIG_EXPOSE_CONFIG |
1288 Vfc_config_weak_list = make_weak_list (WEAK_LIST_SIMPLE); | |
1289 staticpro (&Vfc_config_weak_list); | |
1290 #endif | |
1291 | |
3354 | 1292 DEFVAR_LISP("xft-xlfd-font-regexp", &Vxlfd_font_name_regexp /* |
1293 The regular expression used to match XLFD font names. */ | |
1294 ); | |
1295 Vxlfd_font_name_regexp = make_xlfd_font_regexp(); | |
1296 } | |
1297 | |
1298 void | |
1299 reinit_vars_of_font_mgr (void) | |
1300 { | |
1301 int i, size = (int) countof (fc_standard_properties); | |
1302 | |
1303 FcInit (); | |
1304 | |
1305 fc_property_name_hash_table = make_string_hash_table (size); | |
1306 for (i = 0; i < size; ++i) | |
1307 puthash (fc_standard_properties[i], NULL, fc_property_name_hash_table); | |
1308 } | |
1309 |