comparison src/objects-x.c @ 3094:ad2f4ae9895b

[xemacs-hg @ 2005-11-26 11:45:47 by stephent] Xft merge. <87k6ev4p8q.fsf@tleepslib.sk.tsukuba.ac.jp>
author stephent
date Sat, 26 Nov 2005 11:46:25 +0000
parents 491f8cf78a9c
children 859a2346db99
comparison
equal deleted inserted replaced
3093:769dc945b085 3094:ad2f4ae9895b
36 #include "insdel.h" 36 #include "insdel.h"
37 37
38 #include "console-x-impl.h" 38 #include "console-x-impl.h"
39 #include "objects-x-impl.h" 39 #include "objects-x-impl.h"
40 40
41 #ifdef USE_XFT
42 #include "xft-fonts.h"
43 #endif
44
41 int x_handle_non_fully_specified_fonts; 45 int x_handle_non_fully_specified_fonts;
42 46
43 47
44 /************************************************************************/ 48 /************************************************************************/
45 /* color instances */ 49 /* color instances */
46 /************************************************************************/ 50 /************************************************************************/
47 51
48 /* Replacement for XAllocColor() that tries to return the nearest
49 available color if the colormap is full. Original was from FSFmacs,
50 but rewritten by Jareth Hein <jareth@camelot-soft.com> 97/11/25
51 Modified by Lee Kindness <lkindness@csl.co.uk> 31/08/99 to handle previous
52 total failure which was due to a read/write colorcell being the nearest
53 match - tries the next nearest...
54
55 Return value is 1 for normal success, 2 for nearest color success,
56 3 for Non-deallocable success. */
57 int
58 allocate_nearest_color (Display *display, Colormap colormap, Visual *visual,
59 XColor *color_def)
60 {
61 int status;
62
63 if (visual->X_CLASSFIELD == DirectColor || visual->X_CLASSFIELD == TrueColor)
64 {
65 if (XAllocColor (display, colormap, color_def) != 0)
66 {
67 status = 1;
68 }
69 else
70 {
71 /* We're dealing with a TrueColor/DirectColor visual, so play games
72 with the RGB values in the XColor struct. */
73 /* #### JH: I'm not sure how a call to XAllocColor can fail in a
74 TrueColor or DirectColor visual, so I will just reformat the
75 request to match the requirements of the visual, and re-issue
76 the request. If this fails for anybody, I wanna know about it
77 so I can come up with a better plan */
78
79 unsigned long rshift,gshift,bshift,rbits,gbits,bbits,junk;
80 junk = visual->red_mask;
81 rshift = 0;
82 while ((junk & 0x1) == 0) {
83 junk = junk >> 1;
84 rshift ++;
85 }
86 rbits = 0;
87 while (junk != 0) {
88 junk = junk >> 1;
89 rbits++;
90 }
91 junk = visual->green_mask;
92 gshift = 0;
93 while ((junk & 0x1) == 0) {
94 junk = junk >> 1;
95 gshift ++;
96 }
97 gbits = 0;
98 while (junk != 0) {
99 junk = junk >> 1;
100 gbits++;
101 }
102 junk = visual->blue_mask;
103 bshift = 0;
104 while ((junk & 0x1) == 0) {
105 junk = junk >> 1;
106 bshift ++;
107 }
108 bbits = 0;
109 while (junk != 0) {
110 junk = junk >> 1;
111 bbits++;
112 }
113
114 color_def->red = color_def->red >> (16 - rbits);
115 color_def->green = color_def->green >> (16 - gbits);
116 color_def->blue = color_def->blue >> (16 - bbits);
117 if (XAllocColor (display, colormap, color_def) != 0)
118 status = 1;
119 else
120 {
121 int rd, gr, bl;
122 /* #### JH: I'm punting here, knowing that doing this will at
123 least draw the color correctly. However, unless we convert
124 all of the functions that allocate colors (graphics
125 libraries, etc) to use this function doing this is very
126 likely to cause problems later... */
127
128 if (rbits > 8)
129 rd = color_def->red << (rbits - 8);
130 else
131 rd = color_def->red >> (8 - rbits);
132 if (gbits > 8)
133 gr = color_def->green << (gbits - 8);
134 else
135 gr = color_def->green >> (8 - gbits);
136 if (bbits > 8)
137 bl = color_def->blue << (bbits - 8);
138 else
139 bl = color_def->blue >> (8 - bbits);
140 color_def->pixel = (rd << rshift) | (gr << gshift) | (bl <<
141 bshift);
142 status = 3;
143 }
144 }
145 }
146 else
147 {
148 XColor *cells = NULL;
149 /* JH: I can't believe there's no way to go backwards from a
150 colormap ID and get its visual and number of entries, but X
151 apparently isn't built that way... */
152 int no_cells = visual->map_entries;
153 status = 0;
154
155 if (XAllocColor (display, colormap, color_def) != 0)
156 status = 1;
157 else while( status != 2 )
158 {
159 /* If we got to this point, the colormap is full, so we're
160 going to try and get the next closest color. The algorithm used
161 is a least-squares matching, which is what X uses for closest
162 color matching with StaticColor visuals. */
163 int nearest;
164 long nearest_delta, trial_delta;
165 int x;
166
167 if( cells == NULL )
168 {
169 cells = alloca_array (XColor, no_cells);
170 for (x = 0; x < no_cells; x++)
171 cells[x].pixel = x;
172
173 /* read the current colormap */
174 XQueryColors (display, colormap, cells, no_cells);
175 }
176
177 nearest = 0;
178 /* I'm assuming CSE so I'm not going to condense this. */
179 nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8))
180 * ((color_def->red >> 8) - (cells[0].red >> 8)))
181 +
182 (((color_def->green >> 8) - (cells[0].green >> 8))
183 * ((color_def->green >> 8) - (cells[0].green >>
184 8)))
185 +
186 (((color_def->blue >> 8) - (cells[0].blue >> 8))
187 * ((color_def->blue >> 8) - (cells[0].blue >>
188 8))));
189 for (x = 1; x < no_cells; x++)
190 {
191 trial_delta = ((((color_def->red >> 8) - (cells[x].red >> 8))
192 * ((color_def->red >> 8) - (cells[x].red >> 8)))
193 +
194 (((color_def->green >> 8) - (cells[x].green >> 8))
195 * ((color_def->green >> 8) - (cells[x].green >>
196 8)))
197 +
198 (((color_def->blue >> 8) - (cells[x].blue >> 8))
199 * ((color_def->blue >> 8) - (cells[x].blue >>
200 8))));
201
202 /* less? Ignore cells marked as previously failing */
203 if( (trial_delta < nearest_delta) &&
204 (cells[x].pixel != ULONG_MAX) )
205 {
206 nearest = x;
207 nearest_delta = trial_delta;
208 }
209 }
210 color_def->red = cells[nearest].red;
211 color_def->green = cells[nearest].green;
212 color_def->blue = cells[nearest].blue;
213 if (XAllocColor (display, colormap, color_def) != 0)
214 status = 2;
215 else
216 /* LSK: Either the colour map has changed since
217 * we read it, or the colour is allocated
218 * read/write... Mark this cmap entry so it's
219 * ignored in the next iteration.
220 */
221 cells[nearest].pixel = ULONG_MAX;
222 }
223 }
224 return status;
225 }
226
227 static int 52 static int
228 x_parse_nearest_color (struct device *d, XColor *color, Lisp_Object name, 53 x_parse_nearest_color (struct device *d, XColor *color, Lisp_Object name,
229 Error_Behavior errb) 54 Error_Behavior errb)
230 { 55 {
231 Display *dpy = DEVICE_X_DISPLAY (d); 56 Display *dpy = DEVICE_X_DISPLAY (d);
244 { 69 {
245 maybe_signal_error (Qgui_error, "Unrecognized color", 70 maybe_signal_error (Qgui_error, "Unrecognized color",
246 name, Qcolor, errb); 71 name, Qcolor, errb);
247 return 0; 72 return 0;
248 } 73 }
249 result = allocate_nearest_color (dpy, cmap, visual, color); 74 result = x_allocate_nearest_color (dpy, cmap, visual, color);
250 if (!result) 75 if (!result)
251 { 76 {
252 maybe_signal_error (Qgui_error, "Couldn't allocate color", 77 maybe_signal_error (Qgui_error, "Couldn't allocate color",
253 name, Qcolor, errb); 78 name, Qcolor, errb);
254 return 0; 79 return 0;
260 static int 85 static int
261 x_initialize_color_instance (Lisp_Color_Instance *c, Lisp_Object name, 86 x_initialize_color_instance (Lisp_Color_Instance *c, Lisp_Object name,
262 Lisp_Object device, Error_Behavior errb) 87 Lisp_Object device, Error_Behavior errb)
263 { 88 {
264 XColor color; 89 XColor color;
90 #ifdef USE_XFT
91 XftColor xftColor;
92 #endif
265 int result; 93 int result;
266 94
267 result = x_parse_nearest_color (XDEVICE (device), &color, name, errb); 95 result = x_parse_nearest_color (XDEVICE (device), &color, name, errb);
268 96
269 if (!result) 97 if (!result)
275 if (result == 3) 103 if (result == 3)
276 COLOR_INSTANCE_X_DEALLOC (c) = 0; 104 COLOR_INSTANCE_X_DEALLOC (c) = 0;
277 else 105 else
278 COLOR_INSTANCE_X_DEALLOC (c) = 1; 106 COLOR_INSTANCE_X_DEALLOC (c) = 1;
279 COLOR_INSTANCE_X_COLOR (c) = color; 107 COLOR_INSTANCE_X_COLOR (c) = color;
108
109 #ifdef USE_XFT
110 xftColor.pixel = color.pixel;
111 xftColor.color.red = color.red;
112 xftColor.color.green = color.green;
113 xftColor.color.blue = color.blue;
114 xftColor.color.alpha = 0xffff;
115
116 COLOR_INSTANCE_X_XFTCOLOR (c) = xftColor;
117 #endif
118
280 return 1; 119 return 1;
281 } 120 }
282 121
283 static void 122 static void
284 x_print_color_instance (Lisp_Color_Instance *c, 123 x_print_color_instance (Lisp_Color_Instance *c,
364 203
365 /************************************************************************/ 204 /************************************************************************/
366 /* font instances */ 205 /* font instances */
367 /************************************************************************/ 206 /************************************************************************/
368 207
208 #ifdef USE_XFT
209 /* #### all these #defines should probably move to xft-fonts.h */
210
211 /*
212 The format of a fontname (as returned by fontconfig) is not well-documented,
213 But the character repertoire is represented in an ASCII-compatible way. See
214 fccharset.c (FcCharSetUnparse). So we can use UTF-8 for long names.
215
216 Currently we have a hack where different versions of the unparsed name are
217 used in different contexts fairly arbitrarily. I don't think this is close
218 to coherency; even without the charset and lang properties fontconfig names
219 are too unwieldy to use. We need to rethink the approach here. I think
220 probably Lisp_Font_Instance.name should contain the font name as specified
221 to Lisp (almost surely much shorter than shortname, even, and most likely
222 wildcarded), while Lisp_Font_Instance.truename should contain the longname.
223 For now, I'm going to #ifdef the return values defaulting to short. -- sjt
224 */
225
226 /* DEBUGGING STUFF */
227
228 /* print message to stderr: one internal-format string argument */
229 #define DEBUG_XFT0(level,s) \
230 if (debug_xft > level) stderr_out (s)
231
232 /* print message to stderr: one formatted argument */
233 #define DEBUG_XFT1(level,format,x1) \
234 if (debug_xft > level) stderr_out (format, x1)
235
236 /* print message to stderr: two formatted arguments */
237 #define DEBUG_XFT2(level,format,x1,x2) \
238 if (debug_xft > level) stderr_out (format, x1, x2)
239
240 /* print message to stderr: three formatted arguments */
241 #define DEBUG_XFT3(level,format,x1,x2,x3) \
242 if (debug_xft > level) stderr_out (format, x1, x2, x3)
243
244 /* print message to stderr: four formatted arguments */
245 #define DEBUG_XFT4(level,format,x1,x2,x3,x4) \
246 if (debug_xft > level) stderr_out (format, x1, x2, x3, x4)
247
248 /* print an Xft pattern to stderr
249 LEVEL is the debug level (to compare to debug_xft)
250 FORMAT is a newline-terminated printf format with one %s for the pattern
251 and must be internal format (eg, pure ASCII)
252 PATTERN is an FcPattern *. */
253 #define PRINT_XFT_PATTERN(level,format,pattern) \
254 do { \
255 DECLARE_EISTRING (eistrpxft_name); \
256 FcChar8 *name = FcNameUnparse (pattern); \
257 \
258 eicpy_ext(eistrpxft_name, name, Qxft_font_name_encoding); \
259 DEBUG_XFT1 (level, format, eidata(eistrpxft_name)); \
260 free (name); \
261 } while (0)
262
263 /* print a progress message
264 LEVEL is the debug level (to compare to debug_xft)
265 FONT is the Xft font name in UTF-8 (the native encoding of Xft)
266 LANG is the language being checked for support (must be ASCII). */
267 #define CHECKING_LANG(level,font,lang) \
268 do { \
269 DECLARE_EISTRING (eistrcl_name); \
270 eicpy_ext(eistrcl_name, font, Qxft_font_name_encoding); \
271 DEBUG_XFT2 (level, "checking if %s handles %s\n", \
272 eidata(eistrcl_name), lang); \
273 } while (0)
274
275 #endif /* USE_XFT */
276
369 static int 277 static int
370 x_initialize_font_instance (Lisp_Font_Instance *f, Lisp_Object UNUSED (name), 278 x_initialize_font_instance (Lisp_Font_Instance *f, Lisp_Object UNUSED (name),
371 Lisp_Object device, Error_Behavior errb) 279 Lisp_Object device, Error_Behavior errb)
372 { 280 {
373 Display *dpy = DEVICE_X_DISPLAY (XDEVICE (device)); 281 Display *dpy = DEVICE_X_DISPLAY (XDEVICE (device));
374 XFontStruct *xf; 282 Extbyte *extname;
375 const Extbyte *extname; 283 XFontStruct *fs = NULL; /* _F_ont _S_truct */
376 284 #ifdef USE_XFT
285 XftFont *rf = NULL; /* _R_ender _F_ont (X Render extension) */
286 #else
287 #define rf (0)
288 #endif
289
290 #ifdef USE_XFT
291 DEBUG_XFT1 (2, "attempting to initialize font spec %s\n",
292 XSTRING_DATA(f->name));
293 /* #### serialize (optimize) these later... */
294 /* #### This function really needs to go away.
295 The problem is that the fontconfig/Xft functions work much too hard
296 to ensure that something is returned; but that something need not be
297 at all close to what we asked for. */
298 LISP_STRING_TO_EXTERNAL (f->name, extname, Qxft_font_name_encoding);
299 rf = xft_open_font_by_name (dpy, extname);
300 #endif
377 LISP_STRING_TO_EXTERNAL (f->name, extname, Qx_font_name_encoding); 301 LISP_STRING_TO_EXTERNAL (f->name, extname, Qx_font_name_encoding);
378 xf = XLoadQueryFont (dpy, extname); 302 fs = XLoadQueryFont (dpy, extname);
379 303
380 if (!xf) 304 if (!fs && !rf)
381 { 305 {
382 maybe_signal_error (Qgui_error, "Couldn't load font", f->name, Qfont, 306 /* #### should this refer to X and/or Xft? */
383 errb); 307 maybe_signal_error (Qgui_error, "Couldn't load font", f->name,
308 Qfont, errb);
384 return 0; 309 return 0;
385 } 310 }
386 311
387 if (!xf->max_bounds.width) 312 if (fs && !fs->max_bounds.width)
388 { 313 {
389 /* yes, this has been known to happen. */ 314 /* yes, this has been known to happen. */
390 XFreeFont (dpy, xf); 315 XFreeFont (dpy, fs);
316 fs = NULL;
391 maybe_signal_error (Qgui_error, "X font is too small", f->name, Qfont, 317 maybe_signal_error (Qgui_error, "X font is too small", f->name, Qfont,
392 errb); 318 errb);
393 return 0; 319 if (!rf)
394 } 320 return 0;
395 321 }
396 /* Don't allocate the data until we're sure that we will succeed, 322
397 or the finalize method may get fucked. */ 323 /* Now that we're sure that we will succeed, we can allocate data without
324 fear that the finalize method may get fucked. */
398 f->data = xnew (struct x_font_instance_data); 325 f->data = xnew (struct x_font_instance_data);
399 FONT_INSTANCE_X_FONT (f) = xf; 326
400 f->ascent = xf->ascent; 327 #ifdef USE_XFT
401 f->descent = xf->descent; 328 FONT_INSTANCE_X_XFTFONT (f) = rf;
402 f->height = xf->ascent + xf->descent; 329 if (rf)
403 { 330 /* Have an Xft font, initialize font info from it. */
404 /* following change suggested by Ted Phelps <phelps@dstc.edu.au> */ 331 {
405 int def_char = 'n'; /*xf->default_char;*/ 332 DEBUG_XFT4 (2, "pre-initial ascent %d descent %d width %d height %d\n",
406 int byte1, byte2; 333 f->ascent, f->descent, f->width, f->height);
407 334
408 once_more: 335 /* #### This shit is just plain wrong unless we have a character cell
409 byte1 = def_char >> 8; 336 font. It really hoses us on large repertoire Unicode fonts with
410 byte2 = def_char & 0xFF; 337 "double-width" characters. */
411 338 f->ascent = rf->ascent;
412 if (xf->per_char) 339 f->descent = rf->descent;
413 { 340 {
414 /* Old versions of the R5 font server have garbage (>63k) as 341 /* This is an approximation that AFAIK only gets used to compute
415 def_char. 'n' might not be a valid character. */ 342 cell size for estimating window dimensions. The test_string8
416 if (byte1 < (int) xf->min_byte1 || 343 is an ASCII string whose characters should approximate the
417 byte1 > (int) xf->max_byte1 || 344 distribution of widths expected in real text. */
418 byte2 < (int) xf->min_char_or_byte2 || 345 static const char test_string8[] = "Mmneei";
419 byte2 > (int) xf->max_char_or_byte2) 346 static const int len = sizeof (test_string8) - 1;
420 f->width = 0; 347 XGlyphInfo glyphinfo;
348
349 XftTextExtents8 (dpy, rf, test_string8, len, &glyphinfo);
350 /* #### maybe should be glyphinfo.xOff - glyphinfo.x? */
351 f->width = (2*glyphinfo.width + len)/(2*len);
352 }
353 f->height = rf->height;
354 f->proportional_p = 1; /* we can't recognize monospaced fonts! */
355
356 DEBUG_XFT4 (0, "initialized metrics ascent %d descent %d width %d height %d\n",
357 f->ascent, f->descent, f->width, f->height);
358 /* we also output on initialization of any font below */
359 DEBUG_XFT1 (2, "initialized Xft font %s\n", XSTRING_DATA(f->name));
360 fs = NULL; /* we don' need no steenkin' X font */
361 }
362 else
363 {
364 DEBUG_XFT1 (0, "couldn't initialize Xft font %s\n",
365 XSTRING_DATA(f->name));
366 }
367 #endif
368
369 FONT_INSTANCE_X_FONT (f) = fs;
370 if (fs)
371 /* Have to use a core font, initialize font info from it. */
372 {
373 f->ascent = fs->ascent;
374 f->descent = fs->descent;
375 f->height = fs->ascent + fs->descent;
376 {
377 /* following change suggested by Ted Phelps <phelps@dstc.edu.au> */
378 int def_char = 'n'; /*fs->default_char;*/
379 int byte1, byte2;
380
381 once_more:
382 byte1 = def_char >> 8;
383 byte2 = def_char & 0xFF;
384
385 if (fs->per_char)
386 {
387 /* Old versions of the R5 font server have garbage (>63k) as
388 def_char. 'n' might not be a valid character. */
389 if (byte1 < (int) fs->min_byte1 ||
390 byte1 > (int) fs->max_byte1 ||
391 byte2 < (int) fs->min_char_or_byte2 ||
392 byte2 > (int) fs->max_char_or_byte2)
393 f->width = 0;
394 else
395 f->width = fs->per_char[(byte1 - fs->min_byte1) *
396 (fs->max_char_or_byte2 -
397 fs->min_char_or_byte2 + 1) +
398 (byte2 - fs->min_char_or_byte2)].width;
399 }
421 else 400 else
422 f->width = xf->per_char[(byte1 - xf->min_byte1) * 401 f->width = fs->max_bounds.width;
423 (xf->max_char_or_byte2 - 402
424 xf->min_char_or_byte2 + 1) + 403 /* Some fonts have a default char whose width is 0. This is no good.
425 (byte2 - xf->min_char_or_byte2)].width; 404 If that's the case, first try 'n' as the default char, and if n has
426 } 405 0 width too (unlikely) then just use the max width. */
427 else 406 if (f->width == 0)
428 f->width = xf->max_bounds.width;
429
430 /* Some fonts have a default char whose width is 0. This is no good.
431 If that's the case, first try 'n' as the default char, and if n has
432 0 width too (unlikely) then just use the max width. */
433 if (f->width == 0)
434 {
435 if (def_char == (int) xf->default_char)
436 f->width = xf->max_bounds.width;
437 else
438 { 407 {
439 def_char = xf->default_char; 408 if (def_char == (int) fs->default_char)
440 goto once_more; 409 f->width = fs->max_bounds.width;
410 else
411 {
412 def_char = fs->default_char;
413 goto once_more;
414 }
441 } 415 }
442 } 416 }
443 } 417
444 /* If all characters don't exist then there could potentially be 418 /* If all characters don't exist then there could potentially be
445 0-width characters lurking out there. Not setting this flag 419 0-width characters lurking out there. Not setting this flag
446 trips an optimization that would make them appear to have width 420 trips an optimization that would make them appear to have width
447 to redisplay. This is bad. So we set it if not all characters 421 to redisplay. This is bad. So we set it if not all characters
448 have the same width or if not all characters are defined. 422 have the same width or if not all characters are defined. */
449 */ 423 /* #### This sucks. There is a measurable performance increase
450 /* #### This sucks. There is a measurable performance increase 424 when using proportional width fonts if this flag is not set.
451 when using proportional width fonts if this flag is not set. 425 Unfortunately so many of the fucking X fonts are not fully
452 Unfortunately so many of the fucking X fonts are not fully 426 defined that we could almost just get rid of this damn flag and
453 defined that we could almost just get rid of this damn flag and 427 make it an assertion. */
454 make it an assertion. */ 428 f->proportional_p = (fs->min_bounds.width != fs->max_bounds.width ||
455 f->proportional_p = (xf->min_bounds.width != xf->max_bounds.width || 429 (x_handle_non_fully_specified_fonts &&
456 (x_handle_non_fully_specified_fonts && 430 !fs->all_chars_exist));
457 !xf->all_chars_exist)); 431 }
432
433 #ifdef USE_XFT
434 if (debug_xft > 0)
435 {
436 int n = 3, d = 5;
437 /* check for weirdness */
438 if (n * f->height < d * f->width)
439 stderr_out ("font %s: width:height is %d:%d, larger than %d:%d\n",
440 XSTRING_DATA(f->name), f->width, f->height, n, d);
441 if (f->height <= 0 || f->width <= 0)
442 stderr_out ("bogus dimensions of font %s: width = %d, height = %d\n",
443 XSTRING_DATA(f->name), f->width, f->height);
444 stderr_out ("initialized font %s\n", XSTRING_DATA(f->name));
445 }
446 #else
447 #undef rf
448 #endif
458 449
459 return 1; 450 return 1;
460 } 451 }
461 452
462 static void 453 static void
463 x_print_font_instance (Lisp_Font_Instance *f, 454 x_print_font_instance (Lisp_Font_Instance *f,
464 Lisp_Object printcharfun, 455 Lisp_Object printcharfun,
465 int UNUSED (escapeflag)) 456 int UNUSED (escapeflag))
466 { 457 {
467 write_fmt_string (printcharfun, " 0x%lx", 458 if (FONT_INSTANCE_X_FONT (f))
468 (unsigned long) FONT_INSTANCE_X_FONT (f)->fid); 459 write_fmt_string (printcharfun, " font id: 0x%lx",
460 (unsigned long) FONT_INSTANCE_X_FONT (f)->fid);
461 #ifdef USE_XFT
462 /* #### What should we do here? For now, print the address. */
463 if (FONT_INSTANCE_X_XFTFONT (f))
464 write_fmt_string (printcharfun, " xft font: 0x%lx",
465 (unsigned long) FONT_INSTANCE_X_XFTFONT (f));
466 #endif
469 } 467 }
470 468
471 static void 469 static void
472 x_finalize_font_instance (Lisp_Font_Instance *f) 470 x_finalize_font_instance (Lisp_Font_Instance *f)
473 { 471 {
472
473 #ifdef USE_XFT
474 DEBUG_XFT1 (0, "finalizing %s\n", (STRINGP (f->name)
475 ? (char *) XSTRING_DATA (f->name)
476 : "(unnamed font)"));
477 #endif
474 478
475 if (f->data) 479 if (f->data)
476 { 480 {
477 if (DEVICE_LIVE_P (XDEVICE (f->device))) 481 if (DEVICE_LIVE_P (XDEVICE (f->device)))
478 { 482 {
479 Display *dpy = DEVICE_X_DISPLAY (XDEVICE (f->device)); 483 Display *dpy = DEVICE_X_DISPLAY (XDEVICE (f->device));
480 484
481 XFreeFont (dpy, FONT_INSTANCE_X_FONT (f)); 485 if (FONT_INSTANCE_X_FONT (f))
486 XFreeFont (dpy, FONT_INSTANCE_X_FONT (f));
487 #ifdef USE_XFT
488 if (FONT_INSTANCE_X_XFTFONT (f))
489 XftFontClose (dpy, FONT_INSTANCE_X_XFTFONT (f));
490 #endif
482 } 491 }
483 xfree (f->data, void *); 492 xfree (f->data, void *);
484 f->data = 0; 493 f->data = 0;
485 } 494 }
486 } 495 }
487 496
488 /* Determining the truename of a font is hard. (Big surprise.) 497 /* Determining the truename of a font is hard. (Big surprise.)
498
499 This is not true for fontconfig. Each font has a (nearly) canonical
500 representation up to permutation of the order of properties. It is
501 possible to construct a name which exactly identifies the properties of
502 the current font. However, it is theoretically possible that there exists
503 another font with a super set of those properties that would happen to get
504 selected. -- sjt
489 505
490 By "truename" we mean an XLFD-form name which contains no wildcards, yet 506 By "truename" we mean an XLFD-form name which contains no wildcards, yet
491 which resolves to *exactly* the same font as the one which we already have 507 which resolves to *exactly* the same font as the one which we already have
492 the (probably wildcarded) name and `XFontStruct' of. 508 the (probably wildcarded) name and `XFontStruct' of.
493 509
693 names = XListFonts (dpy, font_name, 1, &count); 709 names = XListFonts (dpy, font_name, 1, &count);
694 if (count) result = names [0]; 710 if (count) result = names [0];
695 #else 711 #else
696 /* But the world I live in is much more perverse. */ 712 /* But the world I live in is much more perverse. */
697 names = XListFonts (dpy, font_name, MAX_FONT_COUNT, &count); 713 names = XListFonts (dpy, font_name, MAX_FONT_COUNT, &count);
714 /* Find the lexicographic minimum of names[].
715 (#### Should we be comparing case-insensitively?) */
698 while (count--) 716 while (count--)
699 /* !!#### Not Mule-friendly */ 717 /* [[ !!#### Not Mule-friendly ]]
700 /* If names[count] is lexicographically less than result, use it. 718 Doesn't matter, XLFDs are HPC (old) or Latin1 (modern). If they
701 (#### Should we be comparing case-insensitively?) */ 719 aren't, who knows what they are? -- sjt */
702 if (result == 0 || (strcmp (result, names [count]) < 0)) 720 if (result == 0 || (strcmp (result, names [count]) < 0))
703 result = names [count]; 721 result = names [count];
704 #endif 722 #endif
705 723
706 if (result) 724 if (result)
771 789
772 static Lisp_Object 790 static Lisp_Object
773 x_font_instance_truename (Lisp_Font_Instance *f, Error_Behavior errb) 791 x_font_instance_truename (Lisp_Font_Instance *f, Error_Behavior errb)
774 { 792 {
775 struct device *d = XDEVICE (f->device); 793 struct device *d = XDEVICE (f->device);
794 Display *dpy = DEVICE_X_DISPLAY (d);
795 Extbyte *nameext;
796 char* xlfd;
797
798 /* #### restructure this so that we return a valid truename at the end,
799 and otherwise only return when we return something desperate that
800 doesn't get stored for future use. */
801
802 #ifdef USE_XFT
803 /* First, try an Xft font. */
804 if (NILP (FONT_INSTANCE_TRUENAME (f)) && FONT_INSTANCE_X_XFTFONT (f))
805 {
806 /* The font is already open, we just unparse. */
807 FcChar8 *res = FcNameUnparse (FONT_INSTANCE_X_XFTFONT (f)->pattern);
808 if (res)
809 {
810 FONT_INSTANCE_TRUENAME (f) = make_string (res, strlen (res));
811 free (res);
812 return FONT_INSTANCE_TRUENAME (f);
813 }
814 else
815 {
816 maybe_signal_error (Qgui_error,
817 "Couldn't unparse Xft font to truename",
818 Qnil, Qfont, errb);
819 /* used to return Qnil here */
820 }
821 }
822 #endif /* USE_XFT */
823
824 /* OK, fall back to core font. */
825 if (NILP (FONT_INSTANCE_TRUENAME (f))
826 && FONT_INSTANCE_X_FONT (f))
827 {
828 nameext = &xlfd[0];
829 LISP_STRING_TO_EXTERNAL (f->name, nameext, Qx_font_name_encoding);
830
831 FONT_INSTANCE_TRUENAME (f) =
832 x_font_truename (dpy, nameext, FONT_INSTANCE_X_FONT (f));
833 }
776 834
777 if (NILP (FONT_INSTANCE_TRUENAME (f))) 835 if (NILP (FONT_INSTANCE_TRUENAME (f)))
778 { 836 {
779 Display *dpy = DEVICE_X_DISPLAY (d); 837 /* Urk, no luck. Whine about our bad luck and exit. */
780 { 838 Lisp_Object font_instance = wrap_font_instance (f);
781 Extbyte *nameext; 839
782 840
783 LISP_STRING_TO_EXTERNAL (f->name, nameext, Qx_font_name_encoding); 841 maybe_signal_error (Qgui_error, "Couldn't determine font truename",
784 FONT_INSTANCE_TRUENAME (f) = 842 font_instance, Qfont, errb);
785 x_font_truename (dpy, nameext, FONT_INSTANCE_X_FONT (f)); 843 /* Ok, just this once, return the font name as the truename.
786 } 844 (This is only used by Fequal() right now.) */
787 if (NILP (FONT_INSTANCE_TRUENAME (f))) 845 return f->name;
788 { 846 }
789 Lisp_Object font_instance = wrap_font_instance (f); 847
790 848 /* Return what we found. */
791
792 maybe_signal_error (Qgui_error, "Couldn't determine font truename",
793 font_instance, Qfont, errb);
794 /* Ok, just this once, return the font name as the truename.
795 (This is only used by Fequal() right now.) */
796 return f->name;
797 }
798 }
799 return FONT_INSTANCE_TRUENAME (f); 849 return FONT_INSTANCE_TRUENAME (f);
800 } 850 }
801 851
802 static Lisp_Object 852 static Lisp_Object
803 x_font_instance_properties (Lisp_Font_Instance *f) 853 x_font_instance_properties (Lisp_Font_Instance *f)
804 { 854 {
805 struct device *d = XDEVICE (f->device); 855 struct device *d = XDEVICE (f->device);
806 int i; 856 int i;
807 Lisp_Object result = Qnil; 857 Lisp_Object result = Qnil;
808 Display *dpy = DEVICE_X_DISPLAY (d); 858 Display *dpy = DEVICE_X_DISPLAY (d);
809 XFontProp *props = FONT_INSTANCE_X_FONT (f)->properties; 859 XFontProp *props = NULL;
810 860
861 /* #### really should hack Xft fonts, too
862 Strategy: fontconfig must have an iterator for this purpose. */
863 if (! FONT_INSTANCE_X_FONT (f)) return result;
864
865 props = FONT_INSTANCE_X_FONT (f)->properties;
811 for (i = FONT_INSTANCE_X_FONT (f)->n_properties - 1; i >= 0; i--) 866 for (i = FONT_INSTANCE_X_FONT (f)->n_properties - 1; i >= 0; i--)
812 { 867 {
813 Lisp_Object name, value; 868 Lisp_Object name, value;
814 Atom atom = props [i].name; 869 Atom atom = props [i].name;
815 Ibyte *name_str = 0; 870 Ibyte *name_str = 0;
885 } 940 }
886 941
887 #ifdef MULE 942 #ifdef MULE
888 943
889 static int 944 static int
890 x_font_spec_matches_charset (struct device *UNUSED (d), Lisp_Object charset, 945 x_font_spec_matches_charset (struct device * USED_IF_XFT (d),
946 Lisp_Object charset,
891 const Ibyte *nonreloc, Lisp_Object reloc, 947 const Ibyte *nonreloc, Lisp_Object reloc,
892 Bytecount offset, Bytecount length, 948 Bytecount offset, Bytecount length,
893 int stage) 949 int stage)
894 { 950 {
895 if (stage) 951 if (stage)
952 #ifdef USE_XFT
953 {
954 Display *dpy = DEVICE_X_DISPLAY (d);
955 Extbyte *extname;
956 XftFont *rf;
957 const Ibyte *the_nonreloc;
958
959 if (!NILP(reloc))
960 {
961 the_nonreloc = XSTRING_DATA (reloc);
962 LISP_STRING_TO_EXTERNAL (reloc, extname, Qx_font_name_encoding);
963 rf = xft_open_font_by_name (dpy, extname);
964 return 0; /* #### maybe this will compile and run ;) */
965 }
966 }
967 #else
896 return 0; 968 return 0;
969 #endif
897 970
898 if (UNBOUNDP (charset)) 971 if (UNBOUNDP (charset))
899 return 1; 972 return 1;
900 /* Hack! Short font names don't have the registry in them, 973 /* Hack! Short font names don't have the registry in them,
901 so we just assume the user knows what they're doing in the 974 so we just assume the user knows what they're doing in the
902 case of ASCII. For other charsets, you gotta give the 975 case of ASCII. For other charsets, you gotta give the
903 long form; sorry buster. 976 long form; sorry buster.
977 #### FMH: this screws fontconfig/Xft?
978 STRATEGY: use fontconfig's ability to hack languages and character
979 sets (lang and charset properties).
980 #### Maybe we can use the fontconfig model to eliminate the difference
981 between faces and fonts? No - it looks like that would be an abuse
982 (fontconfig doesn't know about colors, although Xft does).
904 */ 983 */
905 if (EQ (charset, Vcharset_ascii)) 984 if (EQ (charset, Vcharset_ascii))
906 { 985 {
907 const Ibyte *the_nonreloc = nonreloc; 986 const Ibyte *the_nonreloc = nonreloc;
908 int i; 987 int i;
937 return (fast_string_match (XCHARSET_REGISTRY (charset), 1016 return (fast_string_match (XCHARSET_REGISTRY (charset),
938 nonreloc, reloc, offset, length, 1, 1017 nonreloc, reloc, offset, length, 1,
939 ERROR_ME, 0) >= 0); 1018 ERROR_ME, 0) >= 0);
940 } 1019 }
941 1020
1021 #ifdef USE_XFT
1022 /* #### debug functions: find a better place for us */
1023 const char *FcResultToString (FcResult r);
1024 const char *
1025 FcResultToString (FcResult r)
1026 {
1027 static char buffer[256];
1028 switch (r)
1029 {
1030 case FcResultMatch:
1031 return "FcResultMatch";
1032 case FcResultNoMatch:
1033 return "FcResultNoMatch";
1034 case FcResultTypeMismatch:
1035 return "FcResultTypeMismatch";
1036 case FcResultNoId:
1037 return "FcResultNoId";
1038 default:
1039 snprintf (buffer, 255, "FcResultUndocumentedValue (%d)", r);
1040 return buffer;
1041 }
1042 }
1043
1044 const char *FcTypeOfValueToString (FcValue v);
1045 const char *
1046 FcTypeOfValueToString (FcValue v)
1047 {
1048 static char buffer[256];
1049 switch (v.type)
1050 {
1051 case FcTypeMatrix:
1052 return "FcTypeMatrix";
1053 case FcTypeString:
1054 return "FcTypeString";
1055 case FcTypeVoid:
1056 return "FcTypeVoid";
1057 case FcTypeDouble:
1058 return "FcTypeDouble";
1059 case FcTypeInteger:
1060 return "FcTypeInteger";
1061 case FcTypeBool:
1062 return "FcTypeBool";
1063 case FcTypeCharSet:
1064 return "FcTypeCharSet";
1065 case FcTypeLangSet:
1066 return "FcTypeLangSet";
1067 /* #### There is no union member of this type, but there are void* and
1068 FcPattern* members, as of fontconfig.h FC_VERSION 10002 */
1069 case FcTypeFTFace:
1070 return "FcTypeFTFace";
1071 default:
1072 snprintf (buffer, 255, "FcTypeUndocumentedType (%d)", v.type);
1073 return buffer;
1074 }
1075 }
1076
1077 static FcCharSet *
1078 mule_to_fc_charset (Lisp_Object cs)
1079 {
1080 int ucode, i, j;
1081 FcCharSet *fccs;
1082
1083 CHECK_CHARSET (cs);
1084 fccs = FcCharSetCreate ();
1085 /* #### do we also need to deal with 94 vs. 96 charsets?
1086 ie, how are SP and DEL treated in ASCII? non-graphic should return -1 */
1087 if (1 == XCHARSET_DIMENSION (cs))
1088 /* Unicode tables are indexed by offsets from ASCII SP, not by ASCII */
1089 for (i = 0; i < 96; i++)
1090 {
1091 ucode = ((int *) XCHARSET_TO_UNICODE_TABLE (cs))[i];
1092 if (ucode >= 0)
1093 /* #### should check for allocation failure */
1094 FcCharSetAddChar (fccs, (FcChar32) ucode);
1095 }
1096 else if (2 == XCHARSET_DIMENSION (cs))
1097 /* Unicode tables are indexed by offsets from ASCII SP, not by ASCII */
1098 for (i = 0; i < 96; i++)
1099 for (j = 0; j < 96; j++)
1100 {
1101 ucode = ((int **) XCHARSET_TO_UNICODE_TABLE (cs))[i][j];
1102 if (ucode >= 0)
1103 /* #### should check for allocation failure */
1104 FcCharSetAddChar (fccs, (FcChar32) ucode);
1105 }
1106 else
1107 {
1108 FcCharSetDestroy (fccs);
1109 fccs = NULL;
1110 }
1111 return fccs;
1112 }
1113
1114 struct charset_reporter {
1115 Lisp_Object *charset;
1116 /* This is a debug facility, require ASCII. */
1117 Extbyte *language; /* ASCII, please */
1118 FcChar8 *rfc3066; /* ASCII, please */
1119 };
1120
1121 static struct charset_reporter charset_table[] =
1122 {
1123 /* #### It's my branch, my favorite charsets get checked first!
1124 That's a joke, Son.
1125 Ie, I don't know what I'm doing, so my charsets first is as good as
1126 any other arbitrary order. If you have a better idea, speak up! */
1127 { &Vcharset_ascii, "English", "en" },
1128 { &Vcharset_japanese_jisx0208, "Japanese", "ja" },
1129 { &Vcharset_japanese_jisx0212, "Japanese", "ja" },
1130 { &Vcharset_katakana_jisx0201, "Japanese", "ja" },
1131 { &Vcharset_latin_jisx0201, "Japanese", "ja" },
1132 { &Vcharset_japanese_jisx0208_1978, "Japanese", "ja" },
1133 { &Vcharset_greek_iso8859_7, "Greek", "el" },
1134 /* #### all the Chinese need checking
1135 Damn the blood-sucking ISO anyway. */
1136 { &Vcharset_chinese_gb2312, "simplified Chinese", "zh-CN" },
1137 { &Vcharset_korean_ksc5601, "Korean", "ko" },
1138 { &Vcharset_chinese_cns11643_1, "traditional Chinese", "zh-TW" },
1139 { &Vcharset_chinese_cns11643_2, "traditional Chinese", "zh-TW" },
1140 { &Vcharset_latin_iso8859_1, NULL, NULL },
1141 { &Vcharset_latin_iso8859_2, NULL, NULL },
1142 { &Vcharset_latin_iso8859_3, NULL, NULL },
1143 { &Vcharset_latin_iso8859_4, NULL, NULL },
1144 { &Vcharset_latin_iso8859_9, NULL, NULL },
1145 { &Vcharset_latin_iso8859_15, NULL, NULL },
1146 { &Vcharset_thai_tis620, NULL, NULL },
1147 { &Vcharset_arabic_iso8859_6, NULL, NULL },
1148 { &Vcharset_hebrew_iso8859_8, "Hebrew", "he" },
1149 { &Vcharset_cyrillic_iso8859_5, NULL, NULL },
1150 /* #### these probably are not quite right */
1151 { &Vcharset_chinese_big5_1, "traditional Chinese", "zh-TW" },
1152 { &Vcharset_chinese_big5_2, "traditional Chinese", "zh-TW" },
1153 { NULL, NULL, NULL }
1154 };
1155
1156 /* Choose appropriate font name for debug messages.
1157 Use only in the top half of next function (enforced with #undef). */
1158 #define SET_DEBUG_FONTNAME(name) \
1159 do { name = \
1160 debug_xft > 2 ? eistr_fullname \
1161 : debug_xft > 1 ? eistr_longname \
1162 : eistr_shortname } while (0)
1163
1164 #endif /* USE_XFT */
1165
942 /* find a font spec that matches font spec FONT and also matches 1166 /* find a font spec that matches font spec FONT and also matches
943 (the registry of) CHARSET. */ 1167 (the registry of) CHARSET. */
944 static Lisp_Object 1168 static Lisp_Object
945 x_find_charset_font (Lisp_Object device, Lisp_Object font, Lisp_Object charset, 1169 x_find_charset_font (Lisp_Object device, Lisp_Object font, Lisp_Object charset,
946 int stage) 1170 int stage)
947 { 1171 {
948 Extbyte **names; 1172 Extbyte **names;
949 int count = 0; 1173 int count = 0;
950 Lisp_Object result = Qnil;
951 const Extbyte *patternext; 1174 const Extbyte *patternext;
1175 Lisp_Object result = Qunbound;
952 int i; 1176 int i;
953 1177
1178 /* #### with Xft need to handle second stage here -- sjt
1179 Hm. Or maybe not. That would be cool. :-) */
954 if (stage) 1180 if (stage)
955 return Qnil; 1181 return Qnil;
956 1182
1183 #ifdef USE_XFT
1184 /* Fontconfig converts all FreeType names to UTF-8 before passing them
1185 back to callers---see fcfreetype.c (FcFreeTypeQuery).
1186 I don't believe this is documented. */
1187
1188 DEBUG_XFT1 (1, "confirming charset for font instance %s\n",
1189 XSTRING_DATA(font));
1190
1191 /* #### this looks like a fair amount of work, but the basic design
1192 has never been rethought, and it should be
1193
1194 what really should happen here is that we use FcFontSort (FcFontList?)
1195 to get a list of matching fonts, then pick the first (best) one that
1196 gives language or repertoire coverage.
1197 */
1198
1199 FcInit (); /* No-op if already initialized.
1200 In fontconfig 2.3.2, this cannot return
1201 failure, but that looks like a bug. We
1202 check for it with FcGetCurrentConfig(),
1203 which *can* fail. */
1204 if (!FcConfigGetCurrent()) /* #### We should expose FcInit* interfaces
1205 to LISP and decide when to reinitialize
1206 intelligently. */
1207 stderr_out ("Failed fontconfig initialization\n");
1208 else
1209 {
1210 FcPattern *fontxft; /* long-lived, freed at end of this block */
1211 FcResult fcresult;
1212 FcConfig *fcc;
1213 FcChar8 *lang = "en"; /* #### fix this bogus hack! */
1214 FcCharSet *fccs = NULL;
1215 DECLARE_EISTRING (eistr_shortname); /* user-friendly nickname */
1216 DECLARE_EISTRING (eistr_longname); /* omit FC_LANG and FC_CHARSET */
1217 DECLARE_EISTRING (eistr_fullname); /* everything */
1218
1219 LISP_STRING_TO_EXTERNAL (font, patternext, Qxft_font_name_encoding);
1220 fcc = FcConfigGetCurrent ();
1221
1222 /* parse the name, do the substitutions, and match the font */
1223
1224 {
1225 FcPattern *p = FcNameParse (patternext);
1226 PRINT_XFT_PATTERN (3, "FcNameParse'ed name is %s\n", p);
1227 /* #### Next two return FcBool, but what does the return mean? */
1228 /* The order is correct according the fontconfig docs. */
1229 FcConfigSubstitute (fcc, p, FcMatchPattern);
1230 PRINT_XFT_PATTERN (2, "FcConfigSubstitute'ed name is %s\n", p);
1231 FcDefaultSubstitute (p);
1232 PRINT_XFT_PATTERN (3, "FcDefaultSubstitute'ed name is %s\n", p);
1233 /* #### check fcresult of following match? */
1234 fontxft = FcFontMatch (fcc, p, &fcresult);
1235 /* this prints the long fontconfig name */
1236 PRINT_XFT_PATTERN (1, "FcFontMatch'ed name is %s\n", fontxft);
1237 FcPatternDestroy (p);
1238 }
1239
1240 /* heuristic to give reasonable-length names for debug reports
1241
1242 I considered #ifdef SUPPORT_FULL_FONTCONFIG_NAME etc but that's
1243 pointless. We're just going to remove this code once the font/
1244 face refactoring is done, but until then it could be very useful.
1245 */
1246 {
1247 FcPattern *p = FcFontRenderPrepare (fcc, fontxft, fontxft);
1248 FcChar8 *name;
1249
1250 /* full name, including language coverage and repertoire */
1251 name = FcNameUnparse (p);
1252 eicpy_ext (eistr_fullname, name, Qxft_font_name_encoding);
1253 free (name);
1254
1255 /* long name, omitting coverage and repertoire, plus a number
1256 of rarely useful properties */
1257 FcPatternDel (p, FC_CHARSET);
1258 FcPatternDel (p, FC_LANG);
1259 FcPatternDel (p, FC_WIDTH);
1260 FcPatternDel (p, FC_SPACING);
1261 FcPatternDel (p, FC_HINTING);
1262 FcPatternDel (p, FC_VERTICAL_LAYOUT);
1263 FcPatternDel (p, FC_AUTOHINT);
1264 FcPatternDel (p, FC_GLOBAL_ADVANCE);
1265 FcPatternDel (p, FC_INDEX);
1266 FcPatternDel (p, FC_SCALE);
1267 FcPatternDel (p, FC_FONTVERSION);
1268 name = FcNameUnparse (p);
1269 eicpy_ext (eistr_longname, name, Qxft_font_name_encoding);
1270 free (name);
1271
1272 /* nickname, just family and size, but
1273 "family" names usually have style, slant, and weight */
1274 FcPatternDel (p, FC_FOUNDRY);
1275 FcPatternDel (p, FC_STYLE);
1276 FcPatternDel (p, FC_SLANT);
1277 FcPatternDel (p, FC_WEIGHT);
1278 FcPatternDel (p, FC_PIXEL_SIZE);
1279 FcPatternDel (p, FC_OUTLINE);
1280 FcPatternDel (p, FC_SCALABLE);
1281 FcPatternDel (p, FC_DPI);
1282 name = FcNameUnparse (p);
1283 eicpy_ext (eistr_shortname, name, Qxft_font_name_encoding);
1284 free (name);
1285
1286 FcPatternDestroy (p);
1287 }
1288
1289 /* The language approach may better in the long run, but we can't use
1290 it based on Mule charsets; fontconfig doesn't provide a way to test
1291 for unions of languages, etc. That will require support from the
1292 text module.
1293
1294 Optimization: cache the generated FcCharSet in the Mule charset.
1295 Don't forget to destroy it if the Mule charset gets deallocated. */
1296
1297 struct charset_reporter *cr;
1298 for (cr = charset_table;
1299 cr->charset && !EQ (*(cr->charset), charset);
1300 cr++)
1301 ;
1302
1303 if (cr->rfc3066)
1304 {
1305 if (debug_xft > 0)
1306 {
1307 SET_DEBUG_FONTNAME (name);
1308 CHECKING_LANG (0, eidata(name), cr->language);
1309 }
1310 lang = cr->rfc3066;
1311 }
1312 else if (cr->charset)
1313 {
1314 /* what the hey, build 'em on the fly */
1315 /* #### in the case of error this could return NULL! */
1316 fccs = mule_to_fc_charset (charset);
1317 lang = XSTRING_DATA (XSYMBOL (XCHARSET_NAME (charset))-> name);
1318 }
1319 else
1320 {
1321 /* OK, we fell off the end of the table */
1322 warn_when_safe_lispobj (intern ("xft"), intern ("alert"),
1323 list2 (build_string ("unchecked charset"),
1324 charset));
1325 /* default to "en"
1326 #### THIS IS WRONG, WRONG, WRONG!!
1327 It is why we never fall through to XLFD-checking. */
1328 }
1329
1330 ASSERT_ASCTEXT_ASCII(lang);
1331
1332 if (fccs)
1333 {
1334 /* check for character set coverage */
1335 int i = 0;
1336 FcCharSet *v;
1337 FcResult r = FcPatternGetCharSet (fontxft, FC_CHARSET, i, &v);
1338
1339 if (r == FcResultTypeMismatch)
1340 {
1341 DEBUG_XFT0 (0, "Unexpected type return in charset value\n");
1342 result = Qnil;
1343 }
1344 else if (r == FcResultMatch && FcCharSetIsSubset (fccs, v))
1345 {
1346 /* The full pattern with the bitmap coverage is massively
1347 unwieldy, but the shorter names are's just *wrong*. We
1348 should have the full thing internally as truename, and
1349 filter stuff the client doesn't want to see on output.
1350 Should we just store it into the truename right here? */
1351 if (debug_xft > 0)
1352 {
1353 SET_DEBUG_FONTNAME (name);
1354 DEBUG_XFT2 (0, "Xft font %s supports %s\n",
1355 eidata(name), lang);
1356 }
1357 #ifdef RETURN_LONG_FONTCONFIG_NAMES
1358 result = eimake_string(eistr_fullname);
1359 #else
1360 result = eimake_string(eistr_longname);
1361 #endif
1362 }
1363 else
1364 {
1365 if (debug_xft > 0)
1366 {
1367 SET_DEBUG_FONTNAME (name);
1368 DEBUG_XFT2 (0, "Xft font %s doesn't support %s\n",
1369 eidata(name), lang);
1370 }
1371 result = Qnil;
1372 }
1373
1374 /* clean up */
1375 FcCharSetDestroy (fccs);
1376 }
1377 else
1378 {
1379 /* check for language coverage */
1380 int i = 0;
1381 FcValue v;
1382 /* the main event */
1383 FcResult r = FcPatternGet (fontxft, FC_LANG, i, &v);
1384
1385 if (r == FcResultMatch)
1386 {
1387 if (v.type != FcTypeLangSet) /* excessive paranoia */
1388 {
1389 ASSERT_ASCTEXT_ASCII(FcTypeOfValueToString(v));
1390 /* Urk! Fall back and punt to core font. */
1391 DEBUG_XFT1 (0, "Unexpected type of lang value (%s)\n",
1392 FcTypeOfValueToString (v));
1393 result = Qnil;
1394 }
1395 else if (FcLangSetHasLang (v.u.l, lang) != FcLangDifferentLang)
1396 {
1397 if (debug_xft > 0)
1398 {
1399 SET_DEBUG_FONTNAME (name);
1400 DEBUG_XFT2 (0, "Xft font %s supports %s\n",
1401 eidata(name), lang);
1402 }
1403 #ifdef RETURN_LONG_FONTCONFIG_NAMES
1404 result = eimake_string(eistr_fullname);
1405 #else
1406 result = eimake_string(eistr_longname);
1407 #endif
1408 }
1409 else
1410 {
1411 if (debug_xft > 0)
1412 {
1413 SET_DEBUG_FONTNAME (name);
1414 DEBUG_XFT2 (0, "Xft font %s doesn't support %s\n",
1415 eidata(name), lang);
1416 }
1417 result = Qnil;
1418 }
1419 }
1420 else
1421 {
1422 ASSERT_ASCTEXT_ASCII(FcResultToString(r));
1423 DEBUG_XFT1 (0, "Getting lang: unexpected result=%s\n",
1424 FcResultToString (r));
1425 result = Qnil;
1426 }
1427 }
1428
1429 /* clean up and maybe return */
1430 FcPatternDestroy (fontxft);
1431 if (!UNBOUNDP (result))
1432 return result;
1433 }
1434
1435 DEBUG_XFT1 (0, "shit happens, try X11 charset match for %s\n",
1436 XSTRING_DATA(font));
1437 #undef SET_DEBUG_FONTNAME
1438 #endif /* USE_XFT */
1439
957 LISP_STRING_TO_EXTERNAL (font, patternext, Qx_font_name_encoding); 1440 LISP_STRING_TO_EXTERNAL (font, patternext, Qx_font_name_encoding);
958
959 names = XListFonts (DEVICE_X_DISPLAY (XDEVICE (device)), 1441 names = XListFonts (DEVICE_X_DISPLAY (XDEVICE (device)),
960 patternext, MAX_FONT_COUNT, &count); 1442 patternext, MAX_FONT_COUNT, &count);
961 /* #### This code seems awfully bogus -- mrb */ 1443 /* #### This code seems awfully bogus -- mrb */
1444 /* #### fontconfig does it better -- sjt */
962 for (i = 0; i < count; i ++) 1445 for (i = 0; i < count; i ++)
963 { 1446 {
964 const Ibyte *intname; 1447 const Ibyte *intname;
965 Bytecount intlen; 1448 Bytecount intlen;
966 1449
1039 circumstances, it also causes a noticeable performance hit when using 1522 circumstances, it also causes a noticeable performance hit when using
1040 fixed-width fonts. Since most people don't use characters which could 1523 fixed-width fonts. Since most people don't use characters which could
1041 cause problems this is set to nil by default. 1524 cause problems this is set to nil by default.
1042 */ ); 1525 */ );
1043 x_handle_non_fully_specified_fonts = 0; 1526 x_handle_non_fully_specified_fonts = 0;
1527
1528 #ifdef USE_XFT
1529 Fprovide (intern ("xft-fonts"));
1530 #endif
1044 } 1531 }
1045 1532
1046 void 1533 void
1047 Xatoms_of_objects_x (struct device *d) 1534 Xatoms_of_objects_x (struct device *d)
1048 { 1535 {