This source file includes following definitions.
- xfont_get_pcm
- xfont_get_cache
- compare_font_names
- xfont_decode_coding_xlfd
- xfont_encode_coding_xlfd
- xfont_chars_supported
- xfont_supported_scripts
- xfont_list_pattern
- xfont_list
- xfont_match
- xfont_list_family
- xfont_open
- xfont_close
- xfont_prepare_face
- xfont_has_char
- xfont_encode_char
- xfont_text_extents
- xfont_draw
- xfont_check
- syms_of_xfont
- syms_of_xfont_for_pdumper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <config.h>
23 #include <stdlib.h>
24 #include <X11/Xlib.h>
25
26 #include "lisp.h"
27 #include "xterm.h"
28 #include "frame.h"
29 #include "blockinput.h"
30 #include "character.h"
31 #include "charset.h"
32 #include "font.h"
33 #include "pdumper.h"
34
35
36
37
38 struct xfont_info
39 {
40 struct font font;
41 Display *display;
42 XFontStruct *xfont;
43 unsigned x_display_id;
44 };
45
46
47
48 static XCharStruct *xfont_get_pcm (XFontStruct *, unsigned char2b);
49
50
51
52
53 static XCharStruct *
54 xfont_get_pcm (XFontStruct *xfont, unsigned char2b)
55 {
56
57 XCharStruct *pcm = NULL;
58 const unsigned char byte1 = char2b >> 8;
59 const unsigned char byte2 = char2b & 0xFF;
60
61 eassert (xfont);
62
63 if (xfont->per_char != NULL)
64 {
65 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
66 {
67
68
69
70
71
72
73 if (byte1 == 0
74 && byte2 >= xfont->min_char_or_byte2
75 && byte2 <= xfont->max_char_or_byte2)
76 pcm = xfont->per_char + byte2 - xfont->min_char_or_byte2;
77 }
78 else
79 {
80
81
82
83
84
85
86
87
88
89
90
91
92
93 if (byte1 >= xfont->min_byte1
94 && byte1 <= xfont->max_byte1
95 && byte2 >= xfont->min_char_or_byte2
96 && byte2 <= xfont->max_char_or_byte2)
97 pcm = (xfont->per_char
98 + ((xfont->max_char_or_byte2 - xfont->min_char_or_byte2 + 1)
99 * (byte1 - xfont->min_byte1))
100 + (byte2 - xfont->min_char_or_byte2));
101 }
102 }
103 else
104 {
105
106
107
108 if (byte2 >= xfont->min_char_or_byte2
109 && byte2 <= xfont->max_char_or_byte2)
110 pcm = &xfont->max_bounds;
111 }
112
113 return ((pcm == NULL
114 || (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0))
115 ? NULL : pcm);
116 }
117
118 Lisp_Object
119 xfont_get_cache (struct frame *f)
120 {
121 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
122
123 return (dpyinfo->name_list_element);
124 }
125
126 static int
127 compare_font_names (const void *name1, const void *name2)
128 {
129 char *const *n1 = name1;
130 char *const *n2 = name2;
131 return xstrcasecmp (*n1, *n2);
132 }
133
134
135
136
137
138
139 static ptrdiff_t
140 xfont_decode_coding_xlfd (char *xlfd, int len, char *output)
141 {
142 char *p0 = xlfd, *p1 = output;
143 int c;
144
145 while (*p0)
146 {
147 c = *(unsigned char *) p0++;
148 p1 += CHAR_STRING (c, (unsigned char *) p1);
149 if (--len == 0)
150 break;
151 }
152 *p1 = 0;
153 return (p1 - output);
154 }
155
156
157
158
159
160 static int
161 xfont_encode_coding_xlfd (char *xlfd)
162 {
163 const unsigned char *p0 = (unsigned char *) xlfd;
164 unsigned char *p1 = (unsigned char *) xlfd;
165 int len = 0;
166
167 while (*p0)
168 {
169 int c = string_char_advance (&p0);
170
171 if (c >= 0x100)
172 return -1;
173 *p1++ = c;
174 len++;
175 }
176 *p1 = 0;
177 return len;
178 }
179
180
181
182
183
184
185 static bool
186 xfont_chars_supported (Lisp_Object chars, XFontStruct *xfont,
187 struct charset *encoding, struct charset *repertory)
188 {
189 struct charset *charset = repertory ? repertory : encoding;
190
191 if (CONSP (chars))
192 {
193 for (; CONSP (chars); chars = XCDR (chars))
194 {
195 int c = XFIXNUM (XCAR (chars));
196 unsigned code = ENCODE_CHAR (charset, c);
197
198 if (code == CHARSET_INVALID_CODE (charset))
199 break;
200 if (! xfont)
201 continue;
202 if (code >= 0x10000)
203 break;
204 if (! xfont_get_pcm (xfont, code))
205 break;
206 }
207 return (NILP (chars));
208 }
209 else if (VECTORP (chars))
210 {
211 ptrdiff_t i;
212
213 for (i = ASIZE (chars) - 1; i >= 0; i--)
214 {
215 int c = XFIXNUM (AREF (chars, i));
216 unsigned code = ENCODE_CHAR (charset, c);
217
218 if (code == CHARSET_INVALID_CODE (charset))
219 continue;
220 if (! xfont)
221 break;
222 if (code >= 0x10000)
223 continue;
224 if (xfont_get_pcm (xfont, code))
225 break;
226 }
227 return (i >= 0);
228 }
229 return false;
230 }
231
232
233
234
235
236
237
238
239 static Lisp_Object xfont_scripts_cache;
240
241
242 static Lisp_Object xfont_scratch_props;
243
244
245
246
247
248 static Lisp_Object
249 xfont_supported_scripts (Display *display, char *fontname, Lisp_Object props,
250 struct charset *encoding)
251 {
252 Lisp_Object scripts;
253
254
255 if (EQ (AREF (props, 2), Qja))
256 return list2 (Qkana, Qhan);
257 if (EQ (AREF (props, 2), Qko))
258 return list1 (Qhangul);
259 scripts = Fgethash (props, xfont_scripts_cache, Qt);
260 if (EQ (scripts, Qt))
261 {
262 XFontStruct *xfont;
263 Lisp_Object val;
264
265 scripts = Qnil;
266 xfont = XLoadQueryFont (display, fontname);
267 if (xfont)
268 {
269 if (xfont->per_char)
270 {
271 for (val = Vscript_representative_chars; CONSP (val);
272 val = XCDR (val))
273 if (CONSP (XCAR (val)) && SYMBOLP (XCAR (XCAR (val))))
274 {
275 Lisp_Object script = XCAR (XCAR (val));
276 Lisp_Object chars = XCDR (XCAR (val));
277
278 if (xfont_chars_supported (chars, xfont, encoding, NULL))
279 scripts = Fcons (script, scripts);
280 }
281 }
282 XFreeFont (display, xfont);
283 }
284 if (EQ (AREF (props, 3), Qiso10646_1)
285 && NILP (Fmemq (Qlatin, scripts)))
286 scripts = Fcons (Qlatin, scripts);
287 Fputhash (Fcopy_sequence (props), scripts, xfont_scripts_cache);
288 }
289 return scripts;
290 }
291
292 static Lisp_Object
293 xfont_list_pattern (Display *display, const char *pattern,
294 Lisp_Object registry, Lisp_Object script)
295 {
296 Lisp_Object list = Qnil;
297 Lisp_Object chars = Qnil;
298 struct charset *encoding = NULL, *repertory = NULL;
299 int i, limit, num_fonts;
300 char **names;
301
302 char buf[512];
303
304 if (! NILP (registry)
305 && font_registry_charsets (registry, &encoding, &repertory) < 0)
306
307 return Qnil;
308 if (! NILP (script))
309 {
310 chars = assq_no_quit (script, Vscript_representative_chars);
311 if (NILP (chars))
312
313 return Qnil;
314 chars = XCDR (chars);
315 if (repertory)
316 {
317 if (! xfont_chars_supported (chars, NULL, encoding, repertory))
318 return Qnil;
319 script = Qnil;
320 }
321 }
322
323 block_input ();
324 x_catch_errors (display);
325
326 for (limit = 512; ; limit *= 2)
327 {
328 names = XListFonts (display, pattern, limit, &num_fonts);
329 if (x_had_errors_p (display))
330 {
331
332
333 x_clear_errors (display);
334 num_fonts = 0;
335 break;
336 }
337 if (num_fonts < limit)
338 break;
339 XFreeFontNames (names);
340 }
341
342 if (num_fonts > 0)
343 {
344 char **indices = alloca (sizeof (char *) * num_fonts);
345 Lisp_Object *props = XVECTOR (xfont_scratch_props)->contents;
346 Lisp_Object scripts = Qnil, entity = Qnil;
347
348 for (i = 0; i < ASIZE (xfont_scratch_props); i++)
349 ASET (xfont_scratch_props, i, Qnil);
350 for (i = 0; i < num_fonts; i++)
351 indices[i] = names[i];
352 qsort (indices, num_fonts, sizeof (char *), compare_font_names);
353
354
355
356
357 bool skipped_some_scalable_fonts = false;
358 for (int i_pass = 0;
359 (i_pass == 0
360 || (i_pass == 1 && NILP (list) && skipped_some_scalable_fonts));
361 i_pass++)
362 for (i = 0; i < num_fonts; i++)
363 {
364 ptrdiff_t len;
365
366 if (i > 0 && xstrcasecmp (indices[i - 1], indices[i]) == 0)
367 continue;
368 if (NILP (entity))
369 entity = font_make_entity ();
370 len = xfont_decode_coding_xlfd (indices[i], -1, buf);
371 if (font_parse_xlfd (buf, len, entity) < 0)
372 continue;
373 ASET (entity, FONT_TYPE_INDEX, Qx);
374
375 if (FIXNUMP (AREF (entity, FONT_DPI_INDEX))
376 && FIXNUMP (AREF (entity, FONT_AVGWIDTH_INDEX))
377 && XFIXNUM (AREF (entity, FONT_DPI_INDEX)) != 0
378 && XFIXNUM (AREF (entity, FONT_AVGWIDTH_INDEX)) == 0)
379 continue;
380
381 if (NILP (Vscalable_fonts_allowed))
382 {
383 int size = 0;
384
385 if (FIXNUMP (AREF (entity, FONT_SIZE_INDEX)))
386 size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX));
387 else if (FLOATP (AREF (entity, FONT_SIZE_INDEX)))
388 size = XFLOAT_DATA (AREF (entity, FONT_SIZE_INDEX));
389 if (size == 0 && i_pass == 0)
390 {
391 skipped_some_scalable_fonts = true;
392 continue;
393 }
394 }
395 else if (CONSP (Vscalable_fonts_allowed))
396 {
397 Lisp_Object tail;
398
399 for (tail = Vscalable_fonts_allowed; CONSP (tail);
400 tail = XCDR (tail))
401 {
402 Lisp_Object elt = XCAR (tail);
403 if (STRINGP (elt)
404 && (fast_c_string_match_ignore_case (elt, indices[i],
405 len)
406 >= 0))
407 break;
408 }
409 if (! CONSP (tail))
410 continue;
411 }
412
413
414 if (NILP (AREF (entity, FONT_REGISTRY_INDEX)))
415 continue;
416
417
418 if (! EQ (registry, AREF (entity, FONT_REGISTRY_INDEX)))
419 {
420 registry = AREF (entity, FONT_REGISTRY_INDEX);
421 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
422 encoding = NULL;
423 }
424 if (! encoding)
425
426 continue;
427 if (repertory)
428 {
429 if (NILP (script)
430 || xfont_chars_supported (chars, NULL, encoding, repertory))
431 list = Fcons (entity, list), entity = Qnil;
432 continue;
433 }
434 if (memcmp (props, aref_addr (entity, FONT_FOUNDRY_INDEX),
435 word_size * 7)
436 || ! EQ (AREF (entity, FONT_SPACING_INDEX), props[7]))
437 {
438 vcopy (xfont_scratch_props, 0,
439 aref_addr (entity, FONT_FOUNDRY_INDEX), 7);
440 ASET (xfont_scratch_props, 7, AREF (entity, FONT_SPACING_INDEX));
441 scripts = xfont_supported_scripts (display, indices[i],
442 xfont_scratch_props,
443 encoding);
444 }
445 if (NILP (script)
446 || ! NILP (Fmemq (script, scripts)))
447 list = Fcons (entity, list), entity = Qnil;
448 }
449 XFreeFontNames (names);
450 }
451
452 x_uncatch_errors ();
453 unblock_input ();
454
455 FONT_ADD_LOG ("xfont-list", build_string (pattern), list);
456 return list;
457 }
458
459 static Lisp_Object
460 xfont_list (struct frame *f, Lisp_Object spec)
461 {
462 Display *display = FRAME_DISPLAY_INFO (f)->display;
463 Lisp_Object registry, list, val, extra, script;
464 int len;
465
466 char name[512];
467
468 extra = AREF (spec, FONT_EXTRA_INDEX);
469 if (CONSP (extra))
470 {
471 val = assq_no_quit (QCotf, extra);
472 if (! NILP (val))
473 return Qnil;
474 val = assq_no_quit (QClang, extra);
475 if (! NILP (val))
476 return Qnil;
477 }
478
479 registry = AREF (spec, FONT_REGISTRY_INDEX);
480 len = font_unparse_xlfd (spec, 0, name, 512);
481 if (len < 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
482 return Qnil;
483
484 val = assq_no_quit (QCscript, extra);
485 script = CDR (val);
486 list = xfont_list_pattern (display, name, registry, script);
487 if (NILP (list) && NILP (registry))
488 {
489
490 char *r = name + len - 9;
491
492 if (r - name + 10 < 256)
493 {
494 strcpy (r, "iso10646-1");
495 list = xfont_list_pattern (display, name, Qiso10646_1, script);
496 }
497 }
498 if (NILP (list) && ! NILP (registry))
499 {
500
501 Lisp_Object alter;
502
503 if ((alter = Fassoc (SYMBOL_NAME (registry),
504 Vface_alternative_font_registry_alist,
505 Qnil),
506 CONSP (alter)))
507 {
508
509 char *r = name + len - SBYTES (SYMBOL_NAME (registry));
510
511 for (alter = XCDR (alter); CONSP (alter); alter = XCDR (alter))
512 if (STRINGP (XCAR (alter))
513 && ((r - name) + SBYTES (XCAR (alter))) < 256)
514 {
515 lispstpcpy (r, XCAR (alter));
516 list = xfont_list_pattern (display, name, registry, script);
517 if (! NILP (list))
518 break;
519 }
520 }
521 }
522 if (NILP (list))
523 {
524
525 val = assq_no_quit (QCname, AREF (spec, FONT_EXTRA_INDEX));
526 if (CONSP (val) && STRINGP (XCDR (val)) && SBYTES (XCDR (val)) < 512)
527 {
528 memcpy (name, SDATA (XCDR (val)), SBYTES (XCDR (val)) + 1);
529 if (xfont_encode_coding_xlfd (name) < 0)
530 return Qnil;
531 list = xfont_list_pattern (display, name, registry, script);
532 }
533 }
534
535 return list;
536 }
537
538 static Lisp_Object
539 xfont_match (struct frame *f, Lisp_Object spec)
540 {
541 Display *display = FRAME_DISPLAY_INFO (f)->display;
542 Lisp_Object extra, val, entity;
543 char name[512];
544 XFontStruct *xfont;
545 unsigned long value;
546
547 extra = AREF (spec, FONT_EXTRA_INDEX);
548 val = assq_no_quit (QCname, extra);
549 if (! CONSP (val) || ! STRINGP (XCDR (val)))
550 {
551 if (font_unparse_xlfd (spec, 0, name, 512) < 0)
552 return Qnil;
553 }
554 else if (SBYTES (XCDR (val)) < 512)
555 memcpy (name, SDATA (XCDR (val)), SBYTES (XCDR (val)) + 1);
556 else
557 return Qnil;
558 if (xfont_encode_coding_xlfd (name) < 0)
559 return Qnil;
560
561 block_input ();
562 entity = Qnil;
563 xfont = XLoadQueryFont (display, name);
564 if (xfont)
565 {
566 if (XGetFontProperty (xfont, XA_FONT, &value))
567 {
568 char *s = XGetAtomName (display, (Atom) value);
569
570
571
572
573 if (*s)
574 {
575 ptrdiff_t len;
576 entity = font_make_entity ();
577 ASET (entity, FONT_TYPE_INDEX, Qx);
578 len = xfont_decode_coding_xlfd (s, -1, name);
579 if (font_parse_xlfd (name, len, entity) < 0)
580 entity = Qnil;
581 }
582 XFree (s);
583 }
584 XFreeFont (display, xfont);
585 }
586 unblock_input ();
587
588 FONT_ADD_LOG ("xfont-match", spec, entity);
589 return entity;
590 }
591
592 static Lisp_Object
593 xfont_list_family (struct frame *f)
594 {
595 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
596 char **names;
597 int num_fonts, i;
598 Lisp_Object list;
599 char const *last_family;
600 #if defined GCC_LINT || defined lint
601 last_family = "";
602 #endif
603 int last_len;
604
605 block_input ();
606 x_catch_errors (dpyinfo->display);
607 names = XListFonts (dpyinfo->display, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
608 0x8000, &num_fonts);
609 if (x_had_errors_p (dpyinfo->display))
610 {
611
612
613 x_clear_errors (dpyinfo->display);
614 num_fonts = 0;
615 }
616
617 list = Qnil;
618 for (i = 0, last_len = 0; i < num_fonts; i++)
619 {
620 char *p0 = names[i], *p1, buf[512];
621 Lisp_Object family;
622 int decoded_len;
623
624 p0++;
625 while (*p0 && *p0 != '-') p0++;
626 if (! *p0)
627 continue;
628 p1 = ++p0;
629 while (*p1 && *p1 != '-') p1++;
630 if (! *p1 || p1 == p0)
631 continue;
632 if (last_len == p1 - p0
633 && memcmp (last_family, p0, last_len) == 0)
634 continue;
635 last_len = p1 - p0;
636 last_family = p0;
637
638 decoded_len = xfont_decode_coding_xlfd (p0, last_len, buf);
639 family = font_intern_prop (p0, decoded_len, 1);
640 if (NILP (assq_no_quit (family, list)))
641 list = Fcons (family, list);
642 }
643
644 XFreeFontNames (names);
645 x_uncatch_errors ();
646 unblock_input ();
647
648 return list;
649 }
650
651 static Lisp_Object
652 xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
653 {
654 Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
655 Display *display = dpyinfo->display;
656 char name[512];
657 int len;
658 unsigned long value;
659 Lisp_Object registry;
660 struct charset *encoding, *repertory;
661 Lisp_Object font_object, fullname;
662 struct font *font;
663 XFontStruct *xfont;
664
665
666
667 registry = AREF (entity, FONT_REGISTRY_INDEX);
668 if (font_registry_charsets (registry, &encoding, &repertory) < 0)
669 {
670 FONT_ADD_LOG (" x:unknown registry", registry, Qnil);
671 return Qnil;
672 }
673
674 if (XFIXNUM (AREF (entity, FONT_SIZE_INDEX)) != 0)
675 pixel_size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX));
676 else if (pixel_size == 0)
677 {
678 if (FRAME_FONT (f))
679 pixel_size = FRAME_FONT (f)->pixel_size;
680 else
681 pixel_size = 14;
682 }
683 len = font_unparse_xlfd (entity, pixel_size, name, 512);
684 if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
685 {
686 FONT_ADD_LOG (" x:unparse failed", entity, Qnil);
687 return Qnil;
688 }
689
690 block_input ();
691 x_catch_errors (display);
692 xfont = XLoadQueryFont (display, name);
693 if (x_had_errors_p (display))
694 {
695
696
697 x_clear_errors (display);
698 xfont = NULL;
699 }
700 else if (! xfont)
701 {
702
703
704
705
706
707
708
709
710 Lisp_Object temp;
711
712 temp = copy_font_spec (entity);
713 ASET (temp, FONT_DPI_INDEX, Qnil);
714 len = font_unparse_xlfd (temp, pixel_size, name, 512);
715 if (len <= 0 || (len = xfont_encode_coding_xlfd (name)) < 0)
716 {
717 FONT_ADD_LOG (" x:unparse failed", temp, Qnil);
718 return Qnil;
719 }
720 xfont = XLoadQueryFont (display, name);
721 if (x_had_errors_p (display))
722 {
723
724
725 x_clear_errors (display);
726 xfont = NULL;
727 }
728 }
729 fullname = Qnil;
730
731 if (xfont && XGetFontProperty (xfont, XA_FONT, &value))
732 {
733 char *p0, *p;
734 int dashes = 0;
735
736 p0 = p = XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);
737
738
739
740
741
742 while (*p)
743 {
744 if (*p == '-')
745 dashes++;
746 p++;
747 }
748
749 if (dashes >= 13)
750 {
751 len = xfont_decode_coding_xlfd (p0, -1, name);
752 fullname = Fdowncase (make_string (name, len));
753 }
754 XFree (p0);
755 }
756 x_uncatch_errors ();
757 unblock_input ();
758
759 if (! xfont)
760 {
761 FONT_ADD_LOG (" x:open failed", build_string (name), Qnil);
762 return Qnil;
763 }
764
765 font_object = font_make_object (VECSIZE (struct xfont_info),
766 entity, pixel_size);
767 ASET (font_object, FONT_TYPE_INDEX, Qx);
768 if (STRINGP (fullname))
769 {
770 font_parse_xlfd (SSDATA (fullname), SBYTES (fullname), font_object);
771 ASET (font_object, FONT_NAME_INDEX, fullname);
772 }
773 else
774 {
775 char buf[512];
776
777 len = xfont_decode_coding_xlfd (name, -1, buf);
778 ASET (font_object, FONT_NAME_INDEX, make_string (buf, len));
779 }
780 ASET (font_object, FONT_FULLNAME_INDEX, fullname);
781 font = XFONT_OBJECT (font_object);
782 ((struct xfont_info *) font)->xfont = xfont;
783 ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f);
784 ((struct xfont_info *) font)->x_display_id = FRAME_DISPLAY_INFO (f)->x_id;
785 font->pixel_size = pixel_size;
786 font->driver = &xfont_driver;
787 font->encoding_charset = encoding->id;
788 font->repertory_charset = repertory ? repertory->id : -1;
789 font->ascent = xfont->ascent;
790 font->descent = xfont->descent;
791 font->height = font->ascent + font->descent;
792 font->min_width = xfont->min_bounds.width;
793 font->max_width = xfont->max_bounds.width;
794 if (xfont->min_bounds.width == xfont->max_bounds.width)
795 {
796
797 font->average_width = font->space_width = xfont->min_bounds.width;
798 }
799 else
800 {
801 XCharStruct *pcm;
802 Lisp_Object val;
803
804 pcm = xfont_get_pcm (xfont, 0x20);
805 if (pcm)
806 font->space_width = pcm->width;
807 else
808 font->space_width = 0;
809
810 val = Ffont_get (font_object, QCavgwidth);
811 if (FIXNUMP (val))
812 font->average_width = XFIXNUM (val) / 10;
813 if (font->average_width < 0)
814 font->average_width = - font->average_width;
815 else
816 {
817 if (font->average_width == 0
818 && encoding->ascii_compatible_p)
819 {
820 int width = font->space_width, n = pcm != NULL;
821
822 for (unsigned char2b = 33; char2b <= 126; ++char2b)
823 if ((pcm = xfont_get_pcm (xfont, char2b)) != NULL)
824 width += pcm->width, n++;
825 if (n > 0)
826 font->average_width = width / n;
827 }
828 if (font->average_width == 0)
829
830
831 font->average_width
832 = (xfont->min_bounds.width + xfont->max_bounds.width) / 2;
833 }
834 }
835
836 block_input ();
837 font->underline_thickness
838 = (XGetFontProperty (xfont, XA_UNDERLINE_THICKNESS, &value)
839 ? (long) value : 0);
840 font->underline_position
841 = (XGetFontProperty (xfont, XA_UNDERLINE_POSITION, &value)
842 ? (long) value : -1);
843 font->baseline_offset
844 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_BASELINE_OFFSET, &value)
845 ? (long) value : 0);
846 font->relative_compose
847 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_RELATIVE_COMPOSE, &value)
848 ? (long) value : 0);
849 font->default_ascent
850 = (XGetFontProperty (xfont, dpyinfo->Xatom_MULE_DEFAULT_ASCENT, &value)
851 ? (long) value : 0);
852 unblock_input ();
853
854 if (NILP (fullname))
855 fullname = AREF (font_object, FONT_NAME_INDEX);
856 font->vertical_centering
857 = (STRINGP (Vvertical_centering_font_regexp)
858 && (fast_string_match_ignore_case
859 (Vvertical_centering_font_regexp, fullname) >= 0));
860
861 return font_object;
862 }
863
864 static void
865 xfont_close (struct font *font)
866 {
867 struct x_display_info *xdi;
868 struct xfont_info *xfi = (struct xfont_info *) font;
869
870
871
872
873
874
875
876
877
878 if (xfi->xfont
879 && ((xdi = x_display_info_for_display (xfi->display))
880 && xfi->x_display_id == xdi->x_id))
881 {
882 block_input ();
883 XFreeFont (xfi->display, xfi->xfont);
884 unblock_input ();
885 xfi->xfont = NULL;
886 }
887 }
888
889 static void
890 xfont_prepare_face (struct frame *f, struct face *face)
891 {
892 block_input ();
893 XSetFont (FRAME_X_DISPLAY (f), face->gc,
894 ((struct xfont_info *) face->font)->xfont->fid);
895 unblock_input ();
896 }
897
898 static int
899 xfont_has_char (Lisp_Object font, int c)
900 {
901 Lisp_Object registry = AREF (font, FONT_REGISTRY_INDEX);
902 struct charset *encoding;
903 struct charset *repertory = NULL;
904
905 if (EQ (registry, Qiso10646_1))
906 {
907 encoding = CHARSET_FROM_ID (charset_unicode);
908
909
910 if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qja)
911 && charset_jisx0208 >= 0)
912 repertory = CHARSET_FROM_ID (charset_jisx0208);
913 else if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qko)
914 && charset_ksc5601 >= 0)
915 repertory = CHARSET_FROM_ID (charset_ksc5601);
916 }
917 else if (font_registry_charsets (registry, &encoding, &repertory) < 0)
918
919 return 0;
920 if (ASCII_CHAR_P (c) && encoding->ascii_compatible_p)
921 return 1;
922 if (! repertory)
923 return -1;
924 return (ENCODE_CHAR (repertory, c) != CHARSET_INVALID_CODE (repertory));
925 }
926
927 static unsigned
928 xfont_encode_char (struct font *font, int c)
929 {
930 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
931 struct charset *charset;
932 unsigned code;
933
934 charset = CHARSET_FROM_ID (font->encoding_charset);
935 code = ENCODE_CHAR (charset, c);
936 if (code == CHARSET_INVALID_CODE (charset))
937 return FONT_INVALID_CODE;
938 if (font->repertory_charset >= 0)
939 {
940 charset = CHARSET_FROM_ID (font->repertory_charset);
941 return (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset)
942 ? code : FONT_INVALID_CODE);
943 }
944 return (xfont_get_pcm (xfont, code) ? code : FONT_INVALID_CODE);
945 }
946
947 static void
948 xfont_text_extents (struct font *font, const unsigned int *code,
949 int nglyphs, struct font_metrics *metrics)
950 {
951 XFontStruct *xfont = ((struct xfont_info *) font)->xfont;
952 int i, width = 0;
953 bool first;
954
955 for (i = 0, first = true; i < nglyphs; i++)
956 {
957 static XCharStruct *pcm;
958
959 if (code[i] >= 0x10000)
960 continue;
961 pcm = xfont_get_pcm (xfont, code[i]);
962 if (! pcm)
963 continue;
964 if (first)
965 {
966 metrics->lbearing = pcm->lbearing;
967 metrics->rbearing = pcm->rbearing;
968 metrics->ascent = pcm->ascent;
969 metrics->descent = pcm->descent;
970 first = false;
971 }
972 else
973 {
974 if (metrics->lbearing > width + pcm->lbearing)
975 metrics->lbearing = width + pcm->lbearing;
976 if (metrics->rbearing < width + pcm->rbearing)
977 metrics->rbearing = width + pcm->rbearing;
978 if (metrics->ascent < pcm->ascent)
979 metrics->ascent = pcm->ascent;
980 if (metrics->descent < pcm->descent)
981 metrics->descent = pcm->descent;
982 }
983 width += pcm->width;
984 }
985
986 metrics->width = width;
987 }
988
989 static int
990 xfont_draw (struct glyph_string *s, int from, int to, int x, int y,
991 bool with_background)
992 {
993 XFontStruct *xfont = ((struct xfont_info *) s->font)->xfont;
994 Display *display = FRAME_X_DISPLAY (s->f);
995 int len = to - from;
996 GC gc = s->gc;
997 int i;
998
999 if (s->gc != s->face->gc)
1000 {
1001 block_input ();
1002 XSetFont (display, gc, xfont->fid);
1003 unblock_input ();
1004 }
1005
1006 #if defined HAVE_XRENDER && (RENDER_MAJOR > 0 || (RENDER_MINOR >= 2))
1007 if (with_background
1008 && FRAME_DISPLAY_INFO (s->f)->alpha_bits
1009 && FRAME_CHECK_XR_VERSION (s->f, 0, 2))
1010 {
1011 x_xr_ensure_picture (s->f);
1012
1013 if (FRAME_X_PICTURE (s->f) != None)
1014 {
1015 XRenderColor xc;
1016 int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font);
1017
1018 x_xr_apply_ext_clip (s->f, gc);
1019 x_xrender_color_from_gc_background (s->f, gc, &xc,
1020 s->hl != DRAW_CURSOR);
1021 XRenderFillRectangle (FRAME_X_DISPLAY (s->f),
1022 PictOpSrc, FRAME_X_PICTURE (s->f),
1023 &xc, x, y - ascent, s->width, height);
1024 x_xr_reset_ext_clip (s->f);
1025 x_mark_frame_dirty (s->f);
1026
1027 with_background = false;
1028 }
1029 }
1030 #endif
1031
1032 if (xfont->min_byte1 == 0 && xfont->max_byte1 == 0)
1033 {
1034 USE_SAFE_ALLOCA;
1035 char *str = SAFE_ALLOCA (len);
1036 for (i = 0; i < len ; i++)
1037 str[i] = s->char2b[from + i] & 0xFF;
1038 block_input ();
1039 if (with_background)
1040 {
1041 if (s->padding_p)
1042 for (i = 0; i < len; i++)
1043 XDrawImageString (display, FRAME_X_DRAWABLE (s->f),
1044 gc, x + i, y, str + i, 1);
1045 else
1046 XDrawImageString (display, FRAME_X_DRAWABLE (s->f),
1047 gc, x, y, str, len);
1048 }
1049 else
1050 {
1051 if (s->padding_p)
1052 for (i = 0; i < len; i++)
1053 XDrawString (display, FRAME_X_DRAWABLE (s->f),
1054 gc, x + i, y, str + i, 1);
1055 else
1056 XDrawString (display, FRAME_X_DRAWABLE (s->f),
1057 gc, x, y, str, len);
1058 }
1059 unblock_input ();
1060 SAFE_FREE ();
1061 return s->nchars;
1062 }
1063
1064 block_input ();
1065 if (with_background)
1066 {
1067 if (s->padding_p)
1068 for (i = 0; i < len; i++)
1069 {
1070 const unsigned code = s->char2b[from + i];
1071 const XChar2b char2b = { .byte1 = code >> 8,
1072 .byte2 = code & 0xFF };
1073 XDrawImageString16 (display, FRAME_X_DRAWABLE (s->f),
1074 gc, x + i, y, &char2b, 1);
1075 }
1076 else
1077 {
1078 USE_SAFE_ALLOCA;
1079 const unsigned *code = s->char2b + from;
1080 XChar2b *char2b;
1081 SAFE_NALLOCA (char2b, 1, len);
1082 for (int i = 0; i < len; ++i)
1083 char2b[i] = (XChar2b) { .byte1 = code[i] >> 8,
1084 .byte2 = code[i] & 0xFF };
1085 XDrawImageString16 (display, FRAME_X_DRAWABLE (s->f),
1086 gc, x, y, char2b, len);
1087 SAFE_FREE ();
1088 }
1089 }
1090 else
1091 {
1092 if (s->padding_p)
1093 for (i = 0; i < len; i++)
1094 {
1095 const unsigned code = s->char2b[from + i];
1096 const XChar2b char2b = { .byte1 = code >> 8,
1097 .byte2 = code & 0xFF };
1098 XDrawString16 (display, FRAME_X_DRAWABLE (s->f),
1099 gc, x + i, y, &char2b, 1);
1100 }
1101 else
1102 {
1103 USE_SAFE_ALLOCA;
1104 const unsigned *code = s->char2b + from;
1105 XChar2b *char2b;
1106 SAFE_NALLOCA (char2b, 1, len);
1107 for (int i = 0; i < len; ++i)
1108 char2b[i] = (XChar2b) { .byte1 = code[i] >> 8,
1109 .byte2 = code[i] & 0xFF };
1110 XDrawString16 (display, FRAME_X_DRAWABLE (s->f),
1111 gc, x, y, char2b, len);
1112 SAFE_FREE ();
1113 }
1114 }
1115 unblock_input ();
1116
1117 return len;
1118 }
1119
1120 static int
1121 xfont_check (struct frame *f, struct font *font)
1122 {
1123 struct xfont_info *xfont = (struct xfont_info *) font;
1124
1125 return (FRAME_X_DISPLAY (f) == xfont->display ? 0 : -1);
1126 }
1127
1128
1129 static void syms_of_xfont_for_pdumper (void);
1130
1131 struct font_driver const xfont_driver =
1132 {
1133 .type = LISPSYM_INITIALLY (Qx),
1134 .get_cache = xfont_get_cache,
1135 .list = xfont_list,
1136 .match = xfont_match,
1137 .list_family = xfont_list_family,
1138 .open_font = xfont_open,
1139 .close_font = xfont_close,
1140 .prepare_face = xfont_prepare_face,
1141 .has_char = xfont_has_char,
1142 .encode_char = xfont_encode_char,
1143 .text_extents = xfont_text_extents,
1144 .draw = xfont_draw,
1145 .check = xfont_check,
1146 };
1147
1148 void
1149 syms_of_xfont (void)
1150 {
1151 staticpro (&xfont_scripts_cache);
1152 xfont_scripts_cache = CALLN (Fmake_hash_table, QCtest, Qequal);
1153 staticpro (&xfont_scratch_props);
1154 xfont_scratch_props = make_nil_vector (8);
1155 pdumper_do_now_and_after_load (syms_of_xfont_for_pdumper);
1156
1157 DEFSYM (Qkana, "kana");
1158 DEFSYM (Qhan, "han");
1159 DEFSYM (Qhangul, "hangul");
1160 }
1161
1162 static void
1163 syms_of_xfont_for_pdumper (void)
1164 {
1165 register_font_driver (&xfont_driver, NULL);
1166 }