aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenichi Handa2008-05-14 01:42:33 +0000
committerKenichi Handa2008-05-14 01:42:33 +0000
commitf0c557507cae98312e85c88e88562e6fbe52496d (patch)
tree6751e3a0281371655a60847fd7c6d263787e26f0 /src
parentb51238f5ce0a25760f1779655e587f1f284caaa4 (diff)
downloademacs-f0c557507cae98312e85c88e88562e6fbe52496d.tar.gz
emacs-f0c557507cae98312e85c88e88562e6fbe52496d.zip
Include <stdlib.h> and "ccl.h".
(struct xfont_info): New structure. (xfont_query_font): Deleted. (xfont_find_ccl_program): Renamed from x_find_ccl_program and moved from xterm.c. (xfont_driver): Adjusted for the change of struct font_driver. (compare_font_names): New function. (xfont_list_pattern): Sort font names case insensitively. Make font_entity by calling font_make_entity. Avoid auto-scaled fonts. (xfont_list): Return a list, not vector. (xfont_match): If the font doesn't have QCname property, generate a name from the other font properties. (xfont_open): Return a font-ojbect. Adjusted for the change of struct font. Get underline_thickness and underline_position from font property. Don't update dpyinfo->smallest_font_height and dpyinfo->smallest_char_width. (xfont_close): Don't free struct font. (xfont_prepare_face): Adjusted for the change of struct font. (xfont_done_face): Deleted. (xfont_has_char): Adjusted for the change of struct font. (xfont_encode_char, xfont_draw): Likewise. (xfont_check): New function.
Diffstat (limited to 'src')
-rw-r--r--src/xfont.c537
1 files changed, 267 insertions, 270 deletions
diff --git a/src/xfont.c b/src/xfont.c
index f13f3e5e36c..8f400687a8a 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -23,6 +23,7 @@ Boston, MA 02110-1301, USA. */
23 23
24#include <config.h> 24#include <config.h>
25#include <stdio.h> 25#include <stdio.h>
26#include <stdlib.h>
26#include <X11/Xlib.h> 27#include <X11/Xlib.h>
27 28
28#include "lisp.h" 29#include "lisp.h"
@@ -34,57 +35,26 @@ Boston, MA 02110-1301, USA. */
34#include "charset.h" 35#include "charset.h"
35#include "fontset.h" 36#include "fontset.h"
36#include "font.h" 37#include "font.h"
38#include "ccl.h"
37 39
38 40
39/* X core font driver. */ 41/* X core font driver. */
40 42
43struct xfont_info
44{
45 struct font font;
46 Display *display;
47 XFontStruct *xfont;
48};
49
41/* Prototypes of support functions. */ 50/* Prototypes of support functions. */
42extern void x_clear_errors P_ ((Display *)); 51extern void x_clear_errors P_ ((Display *));
43 52
44static char *xfont_query_font P_ ((Display *, char *, Lisp_Object));
45static XCharStruct *xfont_get_pcm P_ ((XFontStruct *, XChar2b *)); 53static XCharStruct *xfont_get_pcm P_ ((XFontStruct *, XChar2b *));
54static void xfont_find_ccl_program P_ ((struct font *));
46static int xfont_registry_charsets P_ ((Lisp_Object, struct charset **, 55static int xfont_registry_charsets P_ ((Lisp_Object, struct charset **,
47 struct charset **)); 56 struct charset **));
48 57
49static char *
50xfont_query_font (display, name, spec)
51 Display *display;
52 char *name;
53 Lisp_Object spec;
54{
55 XFontStruct *font;
56
57 BLOCK_INPUT;
58 x_catch_errors (display);
59 font = XLoadQueryFont (display, name);
60 name = NULL;
61 if (x_had_errors_p (display))
62 {
63 /* This error is perhaps due to insufficient memory on X
64 server. Let's just ignore it. */
65 x_clear_errors (display);
66 }
67 else if (font)
68 {
69 unsigned long value;
70
71 if (XGetFontProperty (font, XA_FONT, &value))
72 {
73 char *n = (char *) XGetAtomName (display, (Atom) value);
74
75 if (font_parse_xlfd (n, spec) >= 0)
76 name = n;
77 else
78 XFree (n);
79 }
80 XFreeFont (display, font);
81 }
82 x_uncatch_errors ();
83 UNBLOCK_INPUT;
84
85 return name;
86}
87
88 58
89/* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B 59/* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
90 is not contained in the font. */ 60 is not contained in the font. */
@@ -154,25 +124,60 @@ xfont_get_pcm (xfont, char2b)
154 ? NULL : pcm); 124 ? NULL : pcm);
155} 125}
156 126
127/* Find a CCL program for a font specified by FONTP, and set the member
128 `encoder' of the structure. */
129
130static void
131xfont_find_ccl_program (font)
132 struct font *font;
133{
134 Lisp_Object list, elt;
135
136 elt = Qnil;
137 for (list = Vfont_ccl_encoder_alist; CONSP (list); list = XCDR (list))
138 {
139 elt = XCAR (list);
140 if (CONSP (elt)
141 && STRINGP (XCAR (elt))
142 && ((fast_string_match_ignore_case (XCAR (elt),
143 font->props[FONT_NAME_INDEX])
144 >= 0)
145 || (fast_string_match_ignore_case (XCAR (elt),
146 font->props[FONT_FULLNAME_INDEX])
147 >= 0)))
148 break;
149 }
150
151 if (! NILP (list))
152 {
153 struct ccl_program *ccl
154 = (struct ccl_program *) xmalloc (sizeof (struct ccl_program));
155
156 if (setup_ccl_program (ccl, XCDR (elt)) < 0)
157 xfree (ccl);
158 else
159 font->font_encoder = ccl;
160 }
161}
162
157static Lisp_Object xfont_get_cache P_ ((FRAME_PTR)); 163static Lisp_Object xfont_get_cache P_ ((FRAME_PTR));
158static Lisp_Object xfont_list P_ ((Lisp_Object, Lisp_Object)); 164static Lisp_Object xfont_list P_ ((Lisp_Object, Lisp_Object));
159static Lisp_Object xfont_match P_ ((Lisp_Object, Lisp_Object)); 165static Lisp_Object xfont_match P_ ((Lisp_Object, Lisp_Object));
160static Lisp_Object xfont_list_family P_ ((Lisp_Object)); 166static Lisp_Object xfont_list_family P_ ((Lisp_Object));
161static struct font *xfont_open P_ ((FRAME_PTR, Lisp_Object, int)); 167static Lisp_Object xfont_open P_ ((FRAME_PTR, Lisp_Object, int));
162static void xfont_close P_ ((FRAME_PTR, struct font *)); 168static void xfont_close P_ ((FRAME_PTR, struct font *));
163static int xfont_prepare_face P_ ((FRAME_PTR, struct face *)); 169static int xfont_prepare_face P_ ((FRAME_PTR, struct face *));
164#if 0
165static void xfont_done_face P_ ((FRAME_PTR, struct face *));
166#endif
167static int xfont_has_char P_ ((Lisp_Object, int)); 170static int xfont_has_char P_ ((Lisp_Object, int));
168static unsigned xfont_encode_char P_ ((struct font *, int)); 171static unsigned xfont_encode_char P_ ((struct font *, int));
169static int xfont_text_extents P_ ((struct font *, unsigned *, int, 172static int xfont_text_extents P_ ((struct font *, unsigned *, int,
170 struct font_metrics *)); 173 struct font_metrics *));
171static int xfont_draw P_ ((struct glyph_string *, int, int, int, int, int)); 174static int xfont_draw P_ ((struct glyph_string *, int, int, int, int, int));
175static int xfont_check P_ ((FRAME_PTR, struct font *));
172 176
173struct font_driver xfont_driver = 177struct font_driver xfont_driver =
174 { 178 {
175 0, /* Qx */ 179 0, /* Qx */
180 0, /* case insensitive */
176 xfont_get_cache, 181 xfont_get_cache,
177 xfont_list, 182 xfont_list,
178 xfont_match, 183 xfont_match,
@@ -181,11 +186,13 @@ struct font_driver xfont_driver =
181 xfont_open, 186 xfont_open,
182 xfont_close, 187 xfont_close,
183 xfont_prepare_face, 188 xfont_prepare_face,
184 NULL /*xfont_done_face*/, 189 NULL,
185 xfont_has_char, 190 xfont_has_char,
186 xfont_encode_char, 191 xfont_encode_char,
187 xfont_text_extents, 192 xfont_text_extents,
188 xfont_draw 193 xfont_draw,
194 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
195 xfont_check
189 }; 196 };
190 197
191extern Lisp_Object QCname; 198extern Lisp_Object QCname;
@@ -201,6 +208,14 @@ xfont_get_cache (f)
201 208
202extern Lisp_Object Vface_alternative_font_registry_alist; 209extern Lisp_Object Vface_alternative_font_registry_alist;
203 210
211static int
212compare_font_names (const void *name1, const void *name2)
213{
214 return strcasecmp (*(const char **) name1, *(const char **) name2);
215}
216
217static Lisp_Object xfont_list_pattern P_ ((Lisp_Object, Display *, char *));
218
204static Lisp_Object 219static Lisp_Object
205xfont_list_pattern (frame, display, pattern) 220xfont_list_pattern (frame, display, pattern)
206 Lisp_Object frame; 221 Lisp_Object frame;
@@ -230,54 +245,55 @@ xfont_list_pattern (frame, display, pattern)
230 XFreeFontNames (names); 245 XFreeFontNames (names);
231 } 246 }
232 247
233 for (i = 0; i < num_fonts; i++) 248 if (num_fonts > 0)
234 { 249 {
235 Lisp_Object entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil); 250 char **indices = alloca (sizeof (char *) * num_fonts);
236 int result;
237 251
238 ASET (entity, FONT_TYPE_INDEX, Qx); 252 for (i = 0; i < num_fonts; i++)
239 ASET (entity, FONT_FRAME_INDEX, frame); 253 indices[i] = names[i];
254 qsort (indices, num_fonts, sizeof (char *), compare_font_names);
240 255
241 result = font_parse_xlfd (names[i], entity); 256 for (i = 0; i < num_fonts; i++)
242 if (result < 0)
243 { 257 {
244 /* This may be an alias name. Try to get the full XLFD name 258 Lisp_Object entity;
245 from XA_FONT property of the font. */ 259 int result;
246 XFontStruct *font = XLoadQueryFont (display, names[i]);
247 unsigned long value;
248 260
249 if (! font) 261 if (i > 0 && strcasecmp (indices[i - 1], indices[i]) == 0)
250 continue; 262 continue;
251 if (XGetFontProperty (font, XA_FONT, &value))
252 {
253 char *name = (char *) XGetAtomName (display, (Atom) value);
254 int len = strlen (name);
255
256 /* If DXPC (a Differential X Protocol Compressor)
257 Ver.3.7 is running, XGetAtomName will return null
258 string. We must avoid such a name. */
259 if (len > 0)
260 result = font_parse_xlfd (name, entity);
261 XFree (name);
262 }
263 XFreeFont (display, font);
264 }
265 263
266 if (result == 0) 264 entity = font_make_entity ();
267 { 265 ASET (entity, FONT_TYPE_INDEX, Qx);
268 Lisp_Object val = AREF (entity, FONT_EXTRA_INDEX);
269 char *p = (char *) SDATA (SYMBOL_NAME (val));
270 266
271 /* P == "RESX-RESY-SPACING-AVGWIDTH. We rejust this font if 267 result = font_parse_xlfd (indices[i], entity);
272 it's an autoscaled one (i.e. RESX > 0 && AVGWIDTH == 0). */ 268 if (result < 0)
273 if (atoi (p) > 0)
274 { 269 {
275 p += SBYTES (SYMBOL_NAME (val)); 270 /* This may be an alias name. Try to get the full XLFD name
276 while (p[-1] != '-') p--; 271 from XA_FONT property of the font. */
277 if (atoi (p) == 0) 272 XFontStruct *font = XLoadQueryFont (display, indices[i]);
273 unsigned long value;
274
275 if (! font)
278 continue; 276 continue;
277 if (XGetFontProperty (font, XA_FONT, &value))
278 {
279 char *name = (char *) XGetAtomName (display, (Atom) value);
280 int len = strlen (name);
281
282 /* If DXPC (a Differential X Protocol Compressor)
283 Ver.3.7 is running, XGetAtomName will return null
284 string. We must avoid such a name. */
285 if (len > 0)
286 result = font_parse_xlfd (name, entity);
287 XFree (name);
288 }
289 XFreeFont (display, font);
279 } 290 }
280 list = Fcons (entity, list); 291
292 if (result == 0
293 /* Avoid auto-scaled fonts. */
294 && (XINT (AREF (entity, FONT_DPI_INDEX)) == 0
295 || XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) > 0))
296 list = Fcons (entity, list);
281 } 297 }
282 } 298 }
283 299
@@ -293,63 +309,68 @@ xfont_list (frame, spec)
293{ 309{
294 FRAME_PTR f = XFRAME (frame); 310 FRAME_PTR f = XFRAME (frame);
295 Display *display = FRAME_X_DISPLAY_INFO (f)->display; 311 Display *display = FRAME_X_DISPLAY_INFO (f)->display;
296 Lisp_Object list, val, extra, font_name; 312 Lisp_Object registry, list, val, extra, font_name;
313 Lisp_Object dpi, avgwidth;
297 int len; 314 int len;
298 char name[256]; 315 char name[256];
299 316
300 extra = AREF (spec, FONT_EXTRA_INDEX); 317 extra = AREF (spec, FONT_EXTRA_INDEX);
301 font_name = Qnil;
302 if (CONSP (extra)) 318 if (CONSP (extra))
303 { 319 {
304 val = assq_no_quit (QCotf, extra); 320 val = assq_no_quit (QCotf, extra);
305 if (! NILP (val)) 321 if (! NILP (val))
306 return null_vector; 322 return Qnil;
307 val = assq_no_quit (QCscript, extra); 323 val = assq_no_quit (QCscript, extra);
308 if (! NILP (val)) 324 if (! NILP (val))
309 return null_vector; 325 return Qnil;
310 val = assq_no_quit (QClanguage, extra); 326 val = assq_no_quit (QClang, extra);
311 if (! NILP (val)) 327 if (! NILP (val))
312 return null_vector; 328 return Qnil;
313 val = assq_no_quit (QCname, extra);
314 if (CONSP (val))
315 font_name = XCDR (val);
316 } 329 }
317 330
318 if (STRINGP (font_name) 331 registry = AREF (spec, FONT_REGISTRY_INDEX);
319 && ! strchr ((char *) SDATA (font_name), ':')) 332 if (NILP (registry))
320 list = xfont_list_pattern (frame, display, (char *) SDATA (font_name)); 333 ASET (spec, FONT_REGISTRY_INDEX, Qiso8859_1);
321 else if ((len = font_unparse_xlfd (spec, 0, name, 256)) < 0) 334 len = font_unparse_xlfd (spec, 0, name, 256);
322 return null_vector; 335 ASET (spec, FONT_REGISTRY_INDEX, registry);
323 else 336 if (len < 0)
337 return Qnil;
338 list = xfont_list_pattern (frame, display, name);
339 if (NILP (list) && NILP (registry))
324 { 340 {
325 list = xfont_list_pattern (frame, display, name); 341 /* Try iso10646-1 */
326 if (NILP (list)) 342 char *r = name + len - 9; /* 9 == strlen (iso8859-1) */
343
344 if (r - name + 10 < 256) /* 10 == strlen (iso10646-1) */
327 { 345 {
328 Lisp_Object registry = AREF (spec, FONT_REGISTRY_INDEX); 346 strcpy (r, "iso10646-1");
329 Lisp_Object alter; 347 list = xfont_list_pattern (frame, display, name);
348 }
349 }
350 if (NILP (list) && ! NILP (registry))
351 {
352 Lisp_Object alter;
330 353
331 if (! NILP (registry) 354 if ((alter = Fassoc (SYMBOL_NAME (registry),
332 && (alter = Fassoc (SYMBOL_NAME (registry), 355 Vface_alternative_font_registry_alist),
333 Vface_alternative_font_registry_alist), 356 CONSP (alter)))
334 CONSP (alter))) 357 {
335 { 358 /* Pointer to REGISTRY-ENCODING field. */
336 /* Pointer to REGISTRY-ENCODING field. */ 359 char *r = name + len - SBYTES (SYMBOL_NAME (registry));
337 char *r = name + len - SBYTES (SYMBOL_NAME (registry)); 360
338 361 for (alter = XCDR (alter); CONSP (alter); alter = XCDR (alter))
339 for (alter = XCDR (alter); CONSP (alter); alter = XCDR (alter)) 362 if (STRINGP (XCAR (alter))
340 if (STRINGP (XCAR (alter)) 363 && ((r - name) + SBYTES (XCAR (alter))) < 256)
341 && ((r - name) + SBYTES (XCAR (alter))) < 255) 364 {
342 { 365 strcpy (r, (char *) SDATA (XCAR (alter)));
343 strcpy (r, (char *) SDATA (XCAR (alter))); 366 list = xfont_list_pattern (frame, display, name);
344 list = xfont_list_pattern (frame, display, name); 367 if (! NILP (list))
345 if (! NILP (list)) 368 break;
346 break; 369 }
347 }
348 }
349 } 370 }
350 } 371 }
351 372
352 return (NILP (list) ? null_vector : Fvconcat (1, &list)); 373 return list;
353} 374}
354 375
355static Lisp_Object 376static Lisp_Object
@@ -359,18 +380,23 @@ xfont_match (frame, spec)
359 FRAME_PTR f = XFRAME (frame); 380 FRAME_PTR f = XFRAME (frame);
360 Display *display = FRAME_X_DISPLAY_INFO (f)->display; 381 Display *display = FRAME_X_DISPLAY_INFO (f)->display;
361 Lisp_Object extra, val, entity; 382 Lisp_Object extra, val, entity;
362 char *name; 383 char buf[256], *name;
363 XFontStruct *xfont; 384 XFontStruct *xfont;
364 unsigned long value; 385 unsigned long value;
365 386
366 extra = AREF (spec, FONT_EXTRA_INDEX); 387 extra = AREF (spec, FONT_EXTRA_INDEX);
367 val = assq_no_quit (QCname, extra); 388 val = assq_no_quit (QCname, extra);
368 if (! CONSP (val) || ! STRINGP (XCDR (val))) 389 if (! CONSP (val) || ! STRINGP (XCDR (val)))
369 return Qnil; 390 {
391 if (font_unparse_xlfd (spec, 0, buf, 256) < 0)
392 return Qnil;
393 name = buf;
394 }
395 else
396 name = (char *) SDATA (XCDR (val));
370 397
371 BLOCK_INPUT; 398 BLOCK_INPUT;
372 entity = Qnil; 399 entity = Qnil;
373 name = (char *) SDATA (XCDR (val));
374 xfont = XLoadQueryFont (display, name); 400 xfont = XLoadQueryFont (display, name);
375 if (xfont) 401 if (xfont)
376 { 402 {
@@ -386,9 +412,8 @@ xfont_match (frame, spec)
386 string. We must avoid such a name. */ 412 string. We must avoid such a name. */
387 if (len > 0) 413 if (len > 0)
388 { 414 {
389 entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil); 415 entity = font_make_entity ();
390 ASET (entity, FONT_TYPE_INDEX, Qx); 416 ASET (entity, FONT_TYPE_INDEX, Qx);
391 ASET (entity, FONT_FRAME_INDEX, frame);
392 if (font_parse_xlfd (name, entity) < 0) 417 if (font_parse_xlfd (name, entity) < 0)
393 entity = Qnil; 418 entity = Qnil;
394 } 419 }
@@ -453,8 +478,8 @@ xfont_list_family (frame)
453 continue; 478 continue;
454 last_len = p1 - p0; 479 last_len = p1 - p0;
455 last_family = p0; 480 last_family = p0;
456 family = intern_downcase (p0, last_len); 481 family = make_unibyte_string (p0, last_len);
457 if (! memq_no_quit (family, list)) 482 if (NILP (Fassoc_string (family, list, Qt)))
458 list = Fcons (family, list); 483 list = Fcons (family, list);
459 } 484 }
460 485
@@ -465,7 +490,9 @@ xfont_list_family (frame)
465 return list; 490 return list;
466} 491}
467 492
468static struct font * 493extern Lisp_Object QCavgwidth;
494
495static Lisp_Object
469xfont_open (f, entity, pixel_size) 496xfont_open (f, entity, pixel_size)
470 FRAME_PTR f; 497 FRAME_PTR f;
471 Lisp_Object entity; 498 Lisp_Object entity;
@@ -478,20 +505,29 @@ xfont_open (f, entity, pixel_size)
478 unsigned long value; 505 unsigned long value;
479 Lisp_Object registry; 506 Lisp_Object registry;
480 struct charset *encoding, *repertory; 507 struct charset *encoding, *repertory;
508 Lisp_Object font_object, fullname;
481 struct font *font; 509 struct font *font;
482 XFontStruct *xfont; 510 XFontStruct *xfont;
511 int i;
483 512
484 /* At first, check if we know how to encode characters for this 513 /* At first, check if we know how to encode characters for this
485 font. */ 514 font. */
486 registry = AREF (entity, FONT_REGISTRY_INDEX); 515 registry = AREF (entity, FONT_REGISTRY_INDEX);
487 if (font_registry_charsets (registry, &encoding, &repertory) < 0) 516 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
488 return NULL; 517 return Qnil;
489 518
490 if (XINT (AREF (entity, FONT_SIZE_INDEX)) != 0) 519 if (XINT (AREF (entity, FONT_SIZE_INDEX)) != 0)
491 pixel_size = XINT (AREF (entity, FONT_SIZE_INDEX)); 520 pixel_size = XINT (AREF (entity, FONT_SIZE_INDEX));
521 else if (pixel_size == 0)
522 {
523 if (FRAME_FONT (f))
524 pixel_size = FRAME_FONT (f)->pixel_size;
525 else
526 pixel_size = 14;
527 }
492 len = font_unparse_xlfd (entity, pixel_size, name, 256); 528 len = font_unparse_xlfd (entity, pixel_size, name, 256);
493 if (len <= 0) 529 if (len <= 0)
494 return NULL; 530 return Qnil;
495 531
496 BLOCK_INPUT; 532 BLOCK_INPUT;
497 x_catch_errors (display); 533 x_catch_errors (display);
@@ -503,147 +539,122 @@ xfont_open (f, entity, pixel_size)
503 x_clear_errors (display); 539 x_clear_errors (display);
504 xfont = NULL; 540 xfont = NULL;
505 } 541 }
542 fullname = Qnil;
543 /* Try to get the full name of FONT. */
544 if (xfont && XGetFontProperty (xfont, XA_FONT, &value))
545 {
546 char *p0, *p;
547 int dashes = 0;
548
549 p0 = p = (char *) XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);;
550 /* Count the number of dashes in the "full name".
551 If it is too few, this isn't really the font's full name,
552 so don't use it.
553 In X11R4, the fonts did not come with their canonical names
554 stored in them. */
555 while (*p)
556 {
557 if (*p == '-')
558 dashes++;
559 p++;
560 }
561
562 if (dashes >= 13)
563 fullname = Fdowncase (make_unibyte_string (p0, p - p0));
564 XFree (p0);
565 }
506 x_uncatch_errors (); 566 x_uncatch_errors ();
507 UNBLOCK_INPUT; 567 UNBLOCK_INPUT;
508 568
509 if (! xfont) 569 if (! xfont)
510 return NULL; 570 return Qnil;
511 font = malloc (sizeof (struct font)); 571
512 font->format = Qx; 572 font_object = font_make_object (VECSIZE (struct xfont_info));
513 font->font.font = xfont; 573 ASET (font_object, FONT_TYPE_INDEX, Qx);
514 font->entity = entity; 574 if (STRINGP (fullname))
575 font_parse_xlfd (SDATA (fullname), font_object);
576 for (i = 1; i < FONT_ENTITY_MAX; i++)
577 ASET (font_object, i, AREF (entity, i));
578 ASET (font_object, FONT_SIZE_INDEX, make_number (pixel_size));
579 if (STRINGP (fullname))
580 ASET (font_object, FONT_NAME_INDEX, fullname);
581 else
582 ASET (font_object, FONT_NAME_INDEX, make_unibyte_string (name, len));
583 ASET (font_object, FONT_FULLNAME_INDEX, fullname);
584 ASET (font_object, FONT_FILE_INDEX, Qnil);
585 ASET (font_object, FONT_FORMAT_INDEX, Qx);
586 font = XFONT_OBJECT (font_object);
587 ((struct xfont_info *) font)->xfont = xfont;
588 ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f);
515 font->pixel_size = pixel_size; 589 font->pixel_size = pixel_size;
516 font->driver = &xfont_driver; 590 font->driver = &xfont_driver;
517 font->font.name = malloc (len + 1);
518 if (! font->font.name)
519 {
520 XFreeFont (display, xfont);
521 free (font);
522 return NULL;
523 }
524 bcopy (name, font->font.name, len + 1);
525 font->font.charset = encoding->id;
526 font->encoding_charset = encoding->id; 591 font->encoding_charset = encoding->id;
527 font->repertory_charset = repertory ? repertory->id : -1; 592 font->repertory_charset = repertory ? repertory->id : -1;
528 font->ascent = xfont->ascent; 593 font->ascent = xfont->ascent;
529 font->descent = xfont->descent; 594 font->descent = xfont->descent;
530 595 font->height = font->ascent + font->descent;
596 font->min_width = xfont->min_bounds.width;
531 if (xfont->min_bounds.width == xfont->max_bounds.width) 597 if (xfont->min_bounds.width == xfont->max_bounds.width)
532 { 598 {
533 /* Fixed width font. */ 599 /* Fixed width font. */
534 font->font.average_width = font->font.space_width 600 font->average_width = font->space_width = xfont->min_bounds.width;
535 = xfont->min_bounds.width;
536 } 601 }
537 else 602 else
538 { 603 {
539 XChar2b char2b;
540 XCharStruct *pcm; 604 XCharStruct *pcm;
605 XChar2b char2b;
606 Lisp_Object val;
541 607
542 char2b.byte1 = 0x00, char2b.byte2 = 0x20; 608 char2b.byte1 = 0x00, char2b.byte2 = 0x20;
543 pcm = xfont_get_pcm (xfont, &char2b); 609 pcm = xfont_get_pcm (xfont, &char2b);
544 if (pcm) 610 if (pcm)
545 font->font.space_width = pcm->width; 611 font->space_width = pcm->width;
546 else 612 else
547 font->font.space_width = xfont->max_bounds.width; 613 font->space_width = 0;
548 614
549 font->font.average_width 615 val = Ffont_get (font_object, QCavgwidth);
550 = (XGetFontProperty (xfont, dpyinfo->Xatom_AVERAGE_WIDTH, &value) 616 if (INTEGERP (val))
551 ? (long) value / 10 : 0); 617 font->average_width = XINT (val);
552 if (font->font.average_width < 0) 618 if (font->average_width < 0)
553 font->font.average_width = - font->font.average_width; 619 font->average_width = - font->average_width;
554 if (font->font.average_width == 0) 620 if (font->average_width == 0
555 { 621 && encoding->ascii_compatible_p)
556 if (pcm)
557 {
558 int width = pcm->width;
559 for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
560 if ((pcm = xfont_get_pcm (xfont, &char2b)) != NULL)
561 width += pcm->width;
562 font->font.average_width = width / 95;
563 }
564 else
565 font->font.average_width = xfont->max_bounds.width;
566 }
567 }
568 font->min_width = xfont->min_bounds.width;
569 if (font->min_width <= 0)
570 font->min_width = font->font.space_width;
571
572 BLOCK_INPUT;
573 /* Try to get the full name of FONT. Put it in FULL_NAME. */
574 if (XGetFontProperty (xfont, XA_FONT, &value))
575 {
576 char *full_name = NULL, *p0, *p;
577 int dashes = 0;
578
579 p0 = p = (char *) XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);;
580 /* Count the number of dashes in the "full name".
581 If it is too few, this isn't really the font's full name,
582 so don't use it.
583 In X11R4, the fonts did not come with their canonical names
584 stored in them. */
585 while (*p)
586 { 622 {
587 if (*p == '-') 623 int width = font->space_width, n = pcm != NULL;
588 dashes++;
589 p++;
590 }
591 624
592 if (dashes >= 13) 625 for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
593 { 626 if ((pcm = xfont_get_pcm (xfont, &char2b)) != NULL)
594 full_name = (char *) malloc (p - p0 + 1); 627 width += pcm->width, n++;
595 if (full_name) 628 font->average_width = width / n;
596 bcopy (p0, full_name, p - p0 + 1);
597 } 629 }
598 XFree (p0);
599
600 if (full_name)
601 font->font.full_name = full_name;
602 else
603 font->font.full_name = font->font.name;
604 } 630 }
605 font->file_name = NULL;
606 631
607 font->font.size = xfont->max_bounds.width; 632 BLOCK_INPUT;
608 font->font.height = xfont->ascent + xfont->descent; 633 font->underline_thickness
609 font->font.baseline_offset 634 = (XGetFontProperty (xfont, XA_UNDERLINE_THICKNESS, &value)
635 ? (long) value : 0);
636 font->underline_position
637 = (XGetFontProperty (xfont, XA_UNDERLINE_POSITION, &value)
638 ? (long) value : -1);
639 font->baseline_offset
610 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_BASELINE_OFFSET, &value) 640 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_BASELINE_OFFSET, &value)
611 ? (long) value : 0); 641 ? (long) value : 0);
612 font->font.relative_compose 642 font->relative_compose
613 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_RELATIVE_COMPOSE, &value) 643 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_RELATIVE_COMPOSE, &value)
614 ? (long) value : 0); 644 ? (long) value : 0);
615 font->font.default_ascent 645 font->default_ascent
616 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_DEFAULT_ASCENT, &value) 646 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_DEFAULT_ASCENT, &value)
617 ? (long) value : 0); 647 ? (long) value : 0);
618 font->font.vertical_centering
619 = (STRINGP (Vvertical_centering_font_regexp)
620 && (fast_c_string_match_ignore_case
621 (Vvertical_centering_font_regexp, font->font.full_name) >= 0));
622
623 UNBLOCK_INPUT; 648 UNBLOCK_INPUT;
624 649
625 dpyinfo->n_fonts++; 650 if (NILP (fullname))
626 651 fullname = AREF (font_object, FONT_NAME_INDEX);
627 /* Set global flag fonts_changed_p to non-zero if the font loaded 652 font->vertical_centering
628 has a character with a smaller width than any other character 653 = (STRINGP (Vvertical_centering_font_regexp)
629 before, or if the font loaded has a smaller height than any other 654 && (fast_string_match_ignore_case
630 font loaded before. If this happens, it will make a glyph matrix 655 (Vvertical_centering_font_regexp, fullname) >= 0));
631 reallocation necessary. */
632 if (dpyinfo->n_fonts == 1)
633 {
634 dpyinfo->smallest_font_height = font->font.height;
635 dpyinfo->smallest_char_width = font->min_width;
636 fonts_changed_p = 1;
637 }
638 else
639 {
640 if (dpyinfo->smallest_font_height > font->font.height)
641 dpyinfo->smallest_font_height = font->font.height, fonts_changed_p |= 1;
642 if (dpyinfo->smallest_char_width > font->min_width)
643 dpyinfo->smallest_char_width = font->min_width, fonts_changed_p |= 1;
644 }
645 656
646 return font; 657 return font_object;
647} 658}
648 659
649static void 660static void
@@ -652,14 +663,8 @@ xfont_close (f, font)
652 struct font *font; 663 struct font *font;
653{ 664{
654 BLOCK_INPUT; 665 BLOCK_INPUT;
655 XFreeFont (FRAME_X_DISPLAY (f), font->font.font); 666 XFreeFont (FRAME_X_DISPLAY (f), ((struct xfont_info *) font)->xfont);
656 UNBLOCK_INPUT; 667 UNBLOCK_INPUT;
657
658 if (font->font.name != font->font.full_name)
659 free (font->font.full_name);
660 free (font->font.name);
661 free (font);
662 FRAME_X_DISPLAY_INFO (f)->n_fonts--;
663} 668}
664 669
665static int 670static int
@@ -668,28 +673,13 @@ xfont_prepare_face (f, face)
668 struct face *face; 673 struct face *face;
669{ 674{
670 BLOCK_INPUT; 675 BLOCK_INPUT;
671 XSetFont (FRAME_X_DISPLAY (f), face->gc, face->font->fid); 676 XSetFont (FRAME_X_DISPLAY (f), face->gc,
677 ((struct xfont_info *) face->font)->xfont->fid);
672 UNBLOCK_INPUT; 678 UNBLOCK_INPUT;
673 679
674 return 0; 680 return 0;
675} 681}
676 682
677#if 0
678static void
679xfont_done_face (f, face)
680 FRAME_PTR f;
681 struct face *face;
682{
683 if (face->extra)
684 {
685 BLOCK_INPUT;
686 XFreeGC (FRAME_X_DISPLAY (f), (GC) face->extra);
687 UNBLOCK_INPUT;
688 face->extra = NULL;
689 }
690}
691#endif /* 0 */
692
693static int 683static int
694xfont_has_char (entity, c) 684xfont_has_char (entity, c)
695 Lisp_Object entity; 685 Lisp_Object entity;
@@ -710,6 +700,7 @@ xfont_encode_char (font, c)
710 struct font *font; 700 struct font *font;
711 int c; 701 int c;
712{ 702{
703 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
713 struct charset *charset; 704 struct charset *charset;
714 unsigned code; 705 unsigned code;
715 XChar2b char2b; 706 XChar2b char2b;
@@ -726,7 +717,7 @@ xfont_encode_char (font, c)
726 } 717 }
727 char2b.byte1 = code >> 8; 718 char2b.byte1 = code >> 8;
728 char2b.byte2 = code & 0xFF; 719 char2b.byte2 = code & 0xFF;
729 return (xfont_get_pcm (font->font.font, &char2b) ? code : FONT_INVALID_CODE); 720 return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE);
730} 721}
731 722
732static int 723static int
@@ -736,6 +727,7 @@ xfont_text_extents (font, code, nglyphs, metrics)
736 int nglyphs; 727 int nglyphs;
737 struct font_metrics *metrics; 728 struct font_metrics *metrics;
738{ 729{
730 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
739 int width = 0; 731 int width = 0;
740 int i, x; 732 int i, x;
741 733
@@ -749,7 +741,7 @@ xfont_text_extents (font, code, nglyphs, metrics)
749 if (code[i] >= 0x10000) 741 if (code[i] >= 0x10000)
750 continue; 742 continue;
751 char2b.byte1 = code[i] >> 8, char2b.byte2 = code[i] & 0xFF; 743 char2b.byte1 = code[i] >> 8, char2b.byte2 = code[i] & 0xFF;
752 pcm = xfont_get_pcm (font->font.font, &char2b); 744 pcm = xfont_get_pcm (xfont, &char2b);
753 if (! pcm) 745 if (! pcm)
754 continue; 746 continue;
755 if (metrics->lbearing > width + pcm->lbearing) 747 if (metrics->lbearing > width + pcm->lbearing)
@@ -772,20 +764,15 @@ xfont_draw (s, from, to, x, y, with_background)
772 struct glyph_string *s; 764 struct glyph_string *s;
773 int from, to, x, y, with_background; 765 int from, to, x, y, with_background;
774{ 766{
775 XFontStruct *xfont = s->face->font; 767 XFontStruct *xfont = ((struct xfont_info *) s->font)->xfont;
776 int len = to - from; 768 int len = to - from;
777 GC gc = s->gc; 769 GC gc = s->gc;
778 int i; 770 int i;
779 771
780 if (gc != s->face->gc) 772 if (s->gc != s->face->gc)
781 { 773 {
782 XGCValues xgcv;
783 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (s->f);
784
785 BLOCK_INPUT; 774 BLOCK_INPUT;
786 XGetGCValues (s->display, gc, GCFont, &xgcv); 775 XSetFont (s->display, gc, xfont->fid);
787 if (xgcv.font != xfont->fid)
788 XSetFont (s->display, gc, xfont->fid);
789 UNBLOCK_INPUT; 776 UNBLOCK_INPUT;
790 } 777 }
791 778
@@ -849,6 +836,16 @@ xfont_draw (s, from, to, x, y, with_background)
849 return len; 836 return len;
850} 837}
851 838
839static int
840xfont_check (f, font)
841 FRAME_PTR f;
842 struct font *font;
843{
844 struct xfont_info *xfont = (struct xfont_info *) font;
845
846 return (FRAME_X_DISPLAY (f) == xfont->display ? 0 : -1);
847}
848
852 849
853void 850void
854syms_of_xfont () 851syms_of_xfont ()