(vc-delete-file): Don't try to resynch the buffer.
[emacs.git] / src / xfont.c
blobf84312413ca48c53b0cc9d5fff33ae94e3b8b4b9
1 /* xfont.c -- X core font driver.
2 Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
3 Copyright (C) 2006, 2007, 2008
4 National Institute of Advanced Industrial Science and Technology (AIST)
5 Registration Number H13PRO009
7 This file is part of GNU Emacs.
9 GNU Emacs is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 GNU Emacs is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <X11/Xlib.h>
27 #include "lisp.h"
28 #include "dispextern.h"
29 #include "xterm.h"
30 #include "frame.h"
31 #include "blockinput.h"
32 #include "character.h"
33 #include "charset.h"
34 #include "fontset.h"
35 #include "font.h"
36 #include "ccl.h"
39 /* X core font driver. */
41 struct xfont_info
43 struct font font;
44 Display *display;
45 XFontStruct *xfont;
48 /* Prototypes of support functions. */
49 extern void x_clear_errors P_ ((Display *));
51 static XCharStruct *xfont_get_pcm P_ ((XFontStruct *, XChar2b *));
52 static void xfont_find_ccl_program P_ ((struct font *));
54 /* Get metrics of character CHAR2B in XFONT. Value is null if CHAR2B
55 is not contained in the font. */
57 static XCharStruct *
58 xfont_get_pcm (xfont, char2b)
59 XFontStruct *xfont;
60 XChar2b *char2b;
62 /* The result metric information. */
63 XCharStruct *pcm = NULL;
65 font_assert (xfont && char2b);
67 if (xfont->per_char != NULL)
69 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
71 /* min_char_or_byte2 specifies the linear character index
72 corresponding to the first element of the per_char array,
73 max_char_or_byte2 is the index of the last character. A
74 character with non-zero CHAR2B->byte1 is not in the font.
75 A character with byte2 less than min_char_or_byte2 or
76 greater max_char_or_byte2 is not in the font. */
77 if (char2b->byte1 == 0
78 && char2b->byte2 >= xfont->min_char_or_byte2
79 && char2b->byte2 <= xfont->max_char_or_byte2)
80 pcm = xfont->per_char + char2b->byte2 - xfont->min_char_or_byte2;
82 else
84 /* If either min_byte1 or max_byte1 are nonzero, both
85 min_char_or_byte2 and max_char_or_byte2 are less than
86 256, and the 2-byte character index values corresponding
87 to the per_char array element N (counting from 0) are:
89 byte1 = N/D + min_byte1
90 byte2 = N\D + min_char_or_byte2
92 where:
94 D = max_char_or_byte2 - min_char_or_byte2 + 1
95 / = integer division
96 \ = integer modulus */
97 if (char2b->byte1 >= xfont->min_byte1
98 && char2b->byte1 <= xfont->max_byte1
99 && char2b->byte2 >= xfont->min_char_or_byte2
100 && char2b->byte2 <= xfont->max_char_or_byte2)
101 pcm = (xfont->per_char
102 + ((xfont->max_char_or_byte2 - xfont->min_char_or_byte2 + 1)
103 * (char2b->byte1 - xfont->min_byte1))
104 + (char2b->byte2 - xfont->min_char_or_byte2));
107 else
109 /* If the per_char pointer is null, all glyphs between the first
110 and last character indexes inclusive have the same
111 information, as given by both min_bounds and max_bounds. */
112 if (char2b->byte2 >= xfont->min_char_or_byte2
113 && char2b->byte2 <= xfont->max_char_or_byte2)
114 pcm = &xfont->max_bounds;
117 return ((pcm == NULL
118 || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0))
119 ? NULL : pcm);
122 /* Find a CCL program for a font specified by FONTP, and set the member
123 `encoder' of the structure. */
125 static void
126 xfont_find_ccl_program (font)
127 struct font *font;
129 Lisp_Object list, elt;
131 elt = Qnil;
132 for (list = Vfont_ccl_encoder_alist; CONSP (list); list = XCDR (list))
134 elt = XCAR (list);
135 if (CONSP (elt)
136 && STRINGP (XCAR (elt))
137 && ((fast_string_match_ignore_case (XCAR (elt),
138 font->props[FONT_NAME_INDEX])
139 >= 0)
140 || (fast_string_match_ignore_case (XCAR (elt),
141 font->props[FONT_FULLNAME_INDEX])
142 >= 0)))
143 break;
146 if (! NILP (list))
148 struct ccl_program *ccl
149 = (struct ccl_program *) xmalloc (sizeof (struct ccl_program));
151 if (setup_ccl_program (ccl, XCDR (elt)) < 0)
152 xfree (ccl);
153 else
154 font->font_encoder = ccl;
158 static Lisp_Object xfont_get_cache P_ ((FRAME_PTR));
159 static Lisp_Object xfont_list P_ ((Lisp_Object, Lisp_Object));
160 static Lisp_Object xfont_match P_ ((Lisp_Object, Lisp_Object));
161 static Lisp_Object xfont_list_family P_ ((Lisp_Object));
162 static Lisp_Object xfont_open P_ ((FRAME_PTR, Lisp_Object, int));
163 static void xfont_close P_ ((FRAME_PTR, struct font *));
164 static int xfont_prepare_face P_ ((FRAME_PTR, struct face *));
165 static int xfont_has_char P_ ((Lisp_Object, int));
166 static unsigned xfont_encode_char P_ ((struct font *, int));
167 static int xfont_text_extents P_ ((struct font *, unsigned *, int,
168 struct font_metrics *));
169 static int xfont_draw P_ ((struct glyph_string *, int, int, int, int, int));
170 static int xfont_check P_ ((FRAME_PTR, struct font *));
172 struct font_driver xfont_driver =
174 0, /* Qx */
175 0, /* case insensitive */
176 xfont_get_cache,
177 xfont_list,
178 xfont_match,
179 xfont_list_family,
180 NULL,
181 xfont_open,
182 xfont_close,
183 xfont_prepare_face,
184 NULL,
185 xfont_has_char,
186 xfont_encode_char,
187 xfont_text_extents,
188 xfont_draw,
189 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
190 xfont_check
193 extern Lisp_Object QCname;
195 static Lisp_Object
196 xfont_get_cache (f)
197 FRAME_PTR f;
199 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
201 return (dpyinfo->name_list_element);
204 extern Lisp_Object Vface_alternative_font_registry_alist;
206 static int
207 compare_font_names (const void *name1, const void *name2)
209 return xstrcasecmp (*(const char **) name1, *(const char **) name2);
212 static Lisp_Object xfont_list_pattern P_ ((Lisp_Object, Display *, char *));
214 static Lisp_Object
215 xfont_list_pattern (frame, display, pattern)
216 Lisp_Object frame;
217 Display *display;
218 char *pattern;
220 Lisp_Object list = Qnil;
221 int i, limit, num_fonts;
222 char **names;
224 BLOCK_INPUT;
225 x_catch_errors (display);
227 for (limit = 512; ; limit *= 2)
229 names = XListFonts (display, pattern, limit, &num_fonts);
230 if (x_had_errors_p (display))
232 /* This error is perhaps due to insufficient memory on X
233 server. Let's just ignore it. */
234 x_clear_errors (display);
235 num_fonts = 0;
236 break;
238 if (num_fonts < limit)
239 break;
240 XFreeFontNames (names);
243 if (num_fonts > 0)
245 char **indices = alloca (sizeof (char *) * num_fonts);
247 for (i = 0; i < num_fonts; i++)
248 indices[i] = names[i];
249 qsort (indices, num_fonts, sizeof (char *), compare_font_names);
251 for (i = 0; i < num_fonts; i++)
253 Lisp_Object entity;
254 int result;
256 if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
257 continue;
259 entity = font_make_entity ();
260 ASET (entity, FONT_TYPE_INDEX, Qx);
262 result = font_parse_xlfd (indices[i], entity);
263 if (result < 0)
265 /* This may be an alias name. Try to get the full XLFD name
266 from XA_FONT property of the font. */
267 XFontStruct *font = XLoadQueryFont (display, indices[i]);
268 unsigned long value;
270 if (! font)
271 continue;
272 if (XGetFontProperty (font, XA_FONT, &value))
274 char *name = (char *) XGetAtomName (display, (Atom) value);
275 int len = strlen (name);
277 /* If DXPC (a Differential X Protocol Compressor)
278 Ver.3.7 is running, XGetAtomName will return null
279 string. We must avoid such a name. */
280 if (len > 0)
281 result = font_parse_xlfd (name, entity);
282 XFree (name);
284 XFreeFont (display, font);
287 if (result == 0
288 /* Avoid auto-scaled fonts. */
289 && (XINT (AREF (entity, FONT_DPI_INDEX)) == 0
290 || XINT (AREF (entity, FONT_AVGWIDTH_INDEX)) > 0))
291 list = Fcons (entity, list);
293 XFreeFontNames (names);
296 x_uncatch_errors ();
297 UNBLOCK_INPUT;
299 font_add_log ("xfont-list", build_string (pattern), list);
300 return list;
303 static Lisp_Object
304 xfont_list (frame, spec)
305 Lisp_Object frame, spec;
307 FRAME_PTR f = XFRAME (frame);
308 Display *display = FRAME_X_DISPLAY_INFO (f)->display;
309 Lisp_Object registry, list, val, extra;
310 int len;
311 char name[256];
313 extra = AREF (spec, FONT_EXTRA_INDEX);
314 if (CONSP (extra))
316 val = assq_no_quit (QCotf, extra);
317 if (! NILP (val))
318 return Qnil;
319 val = assq_no_quit (QCscript, extra);
320 if (! NILP (val))
321 return Qnil;
322 val = assq_no_quit (QClang, extra);
323 if (! NILP (val))
324 return Qnil;
327 registry = AREF (spec, FONT_REGISTRY_INDEX);
328 if (NILP (registry))
329 ASET (spec, FONT_REGISTRY_INDEX, Qiso8859_1);
330 len = font_unparse_xlfd (spec, 0, name, 256);
331 ASET (spec, FONT_REGISTRY_INDEX, registry);
332 if (len < 0)
333 return Qnil;
334 list = xfont_list_pattern (frame, display, name);
335 if (NILP (list) && NILP (registry))
337 /* Try iso10646-1 */
338 char *r = name + len - 9; /* 9 == strlen (iso8859-1) */
340 if (r - name + 10 < 256) /* 10 == strlen (iso10646-1) */
342 strcpy (r, "iso10646-1");
343 list = xfont_list_pattern (frame, display, name);
346 if (NILP (list) && ! NILP (registry))
348 Lisp_Object alter;
350 if ((alter = Fassoc (SYMBOL_NAME (registry),
351 Vface_alternative_font_registry_alist),
352 CONSP (alter)))
354 /* Pointer to REGISTRY-ENCODING field. */
355 char *r = name + len - SBYTES (SYMBOL_NAME (registry));
357 for (alter = XCDR (alter); CONSP (alter); alter = XCDR (alter))
358 if (STRINGP (XCAR (alter))
359 && ((r - name) + SBYTES (XCAR (alter))) < 256)
361 strcpy (r, (char *) SDATA (XCAR (alter)));
362 list = xfont_list_pattern (frame, display, name);
363 if (! NILP (list))
364 break;
369 return list;
372 static Lisp_Object
373 xfont_match (frame, spec)
374 Lisp_Object frame, spec;
376 FRAME_PTR f = XFRAME (frame);
377 Display *display = FRAME_X_DISPLAY_INFO (f)->display;
378 Lisp_Object extra, val, entity;
379 char buf[256], *name;
380 XFontStruct *xfont;
381 unsigned long value;
383 extra = AREF (spec, FONT_EXTRA_INDEX);
384 val = assq_no_quit (QCname, extra);
385 if (! CONSP (val) || ! STRINGP (XCDR (val)))
387 if (font_unparse_xlfd (spec, 0, buf, 256) < 0)
388 return Qnil;
389 name = buf;
391 else
392 name = (char *) SDATA (XCDR (val));
394 BLOCK_INPUT;
395 entity = Qnil;
396 xfont = XLoadQueryFont (display, name);
397 if (xfont)
399 if (XGetFontProperty (xfont, XA_FONT, &value))
401 int len;
403 name = (char *) XGetAtomName (display, (Atom) value);
404 len = strlen (name);
406 /* If DXPC (a Differential X Protocol Compressor)
407 Ver.3.7 is running, XGetAtomName will return null
408 string. We must avoid such a name. */
409 if (len > 0)
411 entity = font_make_entity ();
412 ASET (entity, FONT_TYPE_INDEX, Qx);
413 if (font_parse_xlfd (name, entity) < 0)
414 entity = Qnil;
416 XFree (name);
418 XFreeFont (display, xfont);
420 UNBLOCK_INPUT;
422 font_add_log ("xfont-match", spec, entity);
423 return entity;
426 static Lisp_Object
427 xfont_list_family (frame)
428 Lisp_Object frame;
430 FRAME_PTR f = XFRAME (frame);
431 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
432 char **names;
433 int num_fonts, i;
434 Lisp_Object list;
435 char *last_family;
436 int last_len;
438 BLOCK_INPUT;
439 x_catch_errors (dpyinfo->display);
440 names = XListFonts (dpyinfo->display, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
441 0x8000, &num_fonts);
442 if (x_had_errors_p (dpyinfo->display))
444 /* This error is perhaps due to insufficient memory on X server.
445 Let's just ignore it. */
446 x_clear_errors (dpyinfo->display);
447 num_fonts = 0;
450 list = Qnil;
451 for (i = 0, last_len = 0; i < num_fonts; i++)
453 char *p0 = names[i], *p1;
454 Lisp_Object family;
456 p0++; /* skip the leading '-' */
457 while (*p0 && *p0 != '-') p0++; /* skip foundry */
458 if (! *p0)
459 continue;
460 p1 = ++p0;
461 while (*p1 && *p1 != '-') p1++; /* find the end of family */
462 if (! *p1 || p1 == p0)
463 continue;
464 if (last_len == p1 - p0
465 && bcmp (last_family, p0, last_len) == 0)
466 continue;
467 last_len = p1 - p0;
468 last_family = p0;
469 family = make_unibyte_string (p0, last_len);
470 if (NILP (Fassoc_string (family, list, Qt)))
471 list = Fcons (family, list);
474 XFreeFontNames (names);
475 x_uncatch_errors ();
476 UNBLOCK_INPUT;
478 return list;
481 extern Lisp_Object QCavgwidth;
483 static Lisp_Object
484 xfont_open (f, entity, pixel_size)
485 FRAME_PTR f;
486 Lisp_Object entity;
487 int pixel_size;
489 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
490 Display *display = dpyinfo->display;
491 char name[256];
492 int len;
493 unsigned long value;
494 Lisp_Object registry;
495 struct charset *encoding, *repertory;
496 Lisp_Object font_object, fullname;
497 struct font *font;
498 XFontStruct *xfont;
499 int i;
501 /* At first, check if we know how to encode characters for this
502 font. */
503 registry = AREF (entity, FONT_REGISTRY_INDEX);
504 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
505 return Qnil;
507 if (XINT (AREF (entity, FONT_SIZE_INDEX)) != 0)
508 pixel_size = XINT (AREF (entity, FONT_SIZE_INDEX));
509 else if (pixel_size == 0)
511 if (FRAME_FONT (f))
512 pixel_size = FRAME_FONT (f)->pixel_size;
513 else
514 pixel_size = 14;
516 len = font_unparse_xlfd (entity, pixel_size, name, 256);
517 if (len <= 0)
518 return Qnil;
520 BLOCK_INPUT;
521 x_catch_errors (display);
522 xfont = XLoadQueryFont (display, name);
523 if (x_had_errors_p (display))
525 /* This error is perhaps due to insufficient memory on X server.
526 Let's just ignore it. */
527 x_clear_errors (display);
528 xfont = NULL;
530 fullname = Qnil;
531 /* Try to get the full name of FONT. */
532 if (xfont && XGetFontProperty (xfont, XA_FONT, &value))
534 char *p0, *p;
535 int dashes = 0;
537 p0 = p = (char *) XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);;
538 /* Count the number of dashes in the "full name".
539 If it is too few, this isn't really the font's full name,
540 so don't use it.
541 In X11R4, the fonts did not come with their canonical names
542 stored in them. */
543 while (*p)
545 if (*p == '-')
546 dashes++;
547 p++;
550 if (dashes >= 13)
551 fullname = Fdowncase (make_unibyte_string (p0, p - p0));
552 XFree (p0);
554 x_uncatch_errors ();
555 UNBLOCK_INPUT;
557 if (! xfont)
558 return Qnil;
560 font_object = font_make_object (VECSIZE (struct xfont_info));
561 ASET (font_object, FONT_TYPE_INDEX, Qx);
562 if (STRINGP (fullname))
563 font_parse_xlfd ((char *) SDATA (fullname), font_object);
564 for (i = 1; i < FONT_ENTITY_MAX; i++)
565 ASET (font_object, i, AREF (entity, i));
566 ASET (font_object, FONT_SIZE_INDEX, make_number (pixel_size));
567 if (STRINGP (fullname))
568 ASET (font_object, FONT_NAME_INDEX, fullname);
569 else
570 ASET (font_object, FONT_NAME_INDEX, make_unibyte_string (name, len));
571 ASET (font_object, FONT_FULLNAME_INDEX, fullname);
572 ASET (font_object, FONT_FILE_INDEX, Qnil);
573 ASET (font_object, FONT_FORMAT_INDEX, Qx);
574 font = XFONT_OBJECT (font_object);
575 ((struct xfont_info *) font)->xfont = xfont;
576 ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f);
577 font->pixel_size = pixel_size;
578 font->driver = &xfont_driver;
579 font->encoding_charset = encoding->id;
580 font->repertory_charset = repertory ? repertory->id : -1;
581 font->ascent = xfont->ascent;
582 font->descent = xfont->descent;
583 font->height = font->ascent + font->descent;
584 font->min_width = xfont->min_bounds.width;
585 if (xfont->min_bounds.width == xfont->max_bounds.width)
587 /* Fixed width font. */
588 font->average_width = font->space_width = xfont->min_bounds.width;
590 else
592 XCharStruct *pcm;
593 XChar2b char2b;
594 Lisp_Object val;
596 char2b.byte1 = 0x00, char2b.byte2 = 0x20;
597 pcm = xfont_get_pcm (xfont, &char2b);
598 if (pcm)
599 font->space_width = pcm->width;
600 else
601 font->space_width = 0;
603 val = Ffont_get (font_object, QCavgwidth);
604 if (INTEGERP (val))
605 font->average_width = XINT (val);
606 if (font->average_width < 0)
607 font->average_width = - font->average_width;
608 if (font->average_width == 0
609 && encoding->ascii_compatible_p)
611 int width = font->space_width, n = pcm != NULL;
613 for (char2b.byte2 = 33; char2b.byte2 <= 126; char2b.byte2++)
614 if ((pcm = xfont_get_pcm (xfont, &char2b)) != NULL)
615 width += pcm->width, n++;
616 font->average_width = width / n;
620 BLOCK_INPUT;
621 font->underline_thickness
622 = (XGetFontProperty (xfont, XA_UNDERLINE_THICKNESS, &value)
623 ? (long) value : 0);
624 font->underline_position
625 = (XGetFontProperty (xfont, XA_UNDERLINE_POSITION, &value)
626 ? (long) value : -1);
627 font->baseline_offset
628 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_BASELINE_OFFSET, &value)
629 ? (long) value : 0);
630 font->relative_compose
631 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_RELATIVE_COMPOSE, &value)
632 ? (long) value : 0);
633 font->default_ascent
634 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_DEFAULT_ASCENT, &value)
635 ? (long) value : 0);
636 UNBLOCK_INPUT;
638 if (NILP (fullname))
639 fullname = AREF (font_object, FONT_NAME_INDEX);
640 font->vertical_centering
641 = (STRINGP (Vvertical_centering_font_regexp)
642 && (fast_string_match_ignore_case
643 (Vvertical_centering_font_regexp, fullname) >= 0));
645 return font_object;
648 static void
649 xfont_close (f, font)
650 FRAME_PTR f;
651 struct font *font;
653 BLOCK_INPUT;
654 XFreeFont (FRAME_X_DISPLAY (f), ((struct xfont_info *) font)->xfont);
655 UNBLOCK_INPUT;
658 static int
659 xfont_prepare_face (f, face)
660 FRAME_PTR f;
661 struct face *face;
663 BLOCK_INPUT;
664 XSetFont (FRAME_X_DISPLAY (f), face->gc,
665 ((struct xfont_info *) face->font)->xfont->fid);
666 UNBLOCK_INPUT;
668 return 0;
671 static int
672 xfont_has_char (entity, c)
673 Lisp_Object entity;
674 int c;
676 Lisp_Object registry = AREF (entity, FONT_REGISTRY_INDEX);
677 struct charset *repertory;
679 if (font_registry_charsets (registry, NULL, &repertory) < 0)
680 return -1;
681 if (! repertory)
682 return -1;
683 return (ENCODE_CHAR (repertory, c) != CHARSET_INVALID_CODE (repertory));
686 static unsigned
687 xfont_encode_char (font, c)
688 struct font *font;
689 int c;
691 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
692 struct charset *charset;
693 unsigned code;
694 XChar2b char2b;
696 charset = CHARSET_FROM_ID (font->encoding_charset);
697 code = ENCODE_CHAR (charset, c);
698 if (code == CHARSET_INVALID_CODE (charset))
699 return FONT_INVALID_CODE;
700 if (font->repertory_charset >= 0)
702 charset = CHARSET_FROM_ID (font->repertory_charset);
703 return (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset)
704 ? code : FONT_INVALID_CODE);
706 char2b.byte1 = code >> 8;
707 char2b.byte2 = code & 0xFF;
708 return (xfont_get_pcm (xfont, &char2b) ? code : FONT_INVALID_CODE);
711 static int
712 xfont_text_extents (font, code, nglyphs, metrics)
713 struct font *font;
714 unsigned *code;
715 int nglyphs;
716 struct font_metrics *metrics;
718 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
719 int width = 0;
720 int i, x;
722 if (metrics)
723 bzero (metrics, sizeof (struct font_metrics));
724 for (i = 0, x = 0; i < nglyphs; i++)
726 XChar2b char2b;
727 static XCharStruct *pcm;
729 if (code[i] >= 0x10000)
730 continue;
731 char2b.byte1 = code[i] >> 8, char2b.byte2 = code[i] & 0xFF;
732 pcm = xfont_get_pcm (xfont, &char2b);
733 if (! pcm)
734 continue;
735 if (metrics->lbearing > width + pcm->lbearing)
736 metrics->lbearing = width + pcm->lbearing;
737 if (metrics->rbearing < width + pcm->rbearing)
738 metrics->rbearing = width + pcm->rbearing;
739 if (metrics->ascent < pcm->ascent)
740 metrics->ascent = pcm->ascent;
741 if (metrics->descent < pcm->descent)
742 metrics->descent = pcm->descent;
743 width += pcm->width;
745 if (metrics)
746 metrics->width = width;
747 return width;
750 static int
751 xfont_draw (s, from, to, x, y, with_background)
752 struct glyph_string *s;
753 int from, to, x, y, with_background;
755 XFontStruct *xfont = ((struct xfont_info *) s->font)->xfont;
756 int len = to - from;
757 GC gc = s->gc;
758 int i;
760 if (s->gc != s->face->gc)
762 BLOCK_INPUT;
763 XSetFont (s->display, gc, xfont->fid);
764 UNBLOCK_INPUT;
767 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
769 char *str;
770 USE_SAFE_ALLOCA;
772 SAFE_ALLOCA (str, char *, len);
773 for (i = 0; i < len ; i++)
774 str[i] = XCHAR2B_BYTE2 (s->char2b + from + i);
775 BLOCK_INPUT;
776 if (with_background > 0)
778 if (s->padding_p)
779 for (i = 0; i < len; i++)
780 XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
781 gc, x + i, y, str + i, 1);
782 else
783 XDrawImageString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
784 gc, x, y, str, len);
786 else
788 if (s->padding_p)
789 for (i = 0; i < len; i++)
790 XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
791 gc, x + i, y, str + i, 1);
792 else
793 XDrawString (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
794 gc, x, y, str, len);
796 UNBLOCK_INPUT;
797 SAFE_FREE ();
798 return s->nchars;
801 BLOCK_INPUT;
802 if (with_background > 0)
804 if (s->padding_p)
805 for (i = 0; i < len; i++)
806 XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
807 gc, x + i, y, s->char2b + from + i, 1);
808 else
809 XDrawImageString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
810 gc, x, y, s->char2b + from, len);
812 else
814 if (s->padding_p)
815 for (i = 0; i < len; i++)
816 XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
817 gc, x + i, y, s->char2b + from + i, 1);
818 else
819 XDrawString16 (FRAME_X_DISPLAY (s->f), FRAME_X_WINDOW (s->f),
820 gc, x, y, s->char2b + from, len);
822 UNBLOCK_INPUT;
824 return len;
827 static int
828 xfont_check (f, font)
829 FRAME_PTR f;
830 struct font *font;
832 struct xfont_info *xfont = (struct xfont_info *) font;
834 return (FRAME_X_DISPLAY (f) == xfont->display ? 0 : -1);
838 void
839 syms_of_xfont ()
841 xfont_driver.type = Qx;
842 register_font_driver (&xfont_driver, NULL);
845 /* arch-tag: 23c5f366-a5ee-44b7-a3b7-90d6da7fd749
846 (do not change this comment) */