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/>. */
28 #include "dispextern.h"
31 #include "blockinput.h"
32 #include "character.h"
39 /* X core font driver. */
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. */
58 xfont_get_pcm (xfont
, 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
;
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
94 D = max_char_or_byte2 - min_char_or_byte2 + 1
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
));
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
;
118 || (pcm
->width
== 0 && (pcm
->rbearing
- pcm
->lbearing
) == 0))
122 /* Find a CCL program for a font specified by FONTP, and set the member
123 `encoder' of the structure. */
126 xfont_find_ccl_program (font
)
129 Lisp_Object list
, elt
;
132 for (list
= Vfont_ccl_encoder_alist
; CONSP (list
); list
= XCDR (list
))
136 && STRINGP (XCAR (elt
))
137 && ((fast_string_match_ignore_case (XCAR (elt
),
138 font
->props
[FONT_NAME_INDEX
])
140 || (fast_string_match_ignore_case (XCAR (elt
),
141 font
->props
[FONT_FULLNAME_INDEX
])
148 struct ccl_program
*ccl
149 = (struct ccl_program
*) xmalloc (sizeof (struct ccl_program
));
151 if (setup_ccl_program (ccl
, XCDR (elt
)) < 0)
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
=
175 0, /* case insensitive */
189 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
193 extern Lisp_Object QCname
;
199 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
201 return (dpyinfo
->name_list_element
);
204 extern Lisp_Object Vface_alternative_font_registry_alist
;
207 compare_font_names (const void *name1
, const void *name2
)
209 return xstrcasecmp (*(const unsigned char **) name1
,
210 *(const unsigned char **) name2
);
213 static Lisp_Object xfont_list_pattern
P_ ((Lisp_Object
, Display
*, char *));
216 xfont_list_pattern (frame
, display
, pattern
)
221 Lisp_Object list
= Qnil
;
222 int i
, limit
, num_fonts
;
226 x_catch_errors (display
);
228 for (limit
= 512; ; limit
*= 2)
230 names
= XListFonts (display
, pattern
, limit
, &num_fonts
);
231 if (x_had_errors_p (display
))
233 /* This error is perhaps due to insufficient memory on X
234 server. Let's just ignore it. */
235 x_clear_errors (display
);
239 if (num_fonts
< limit
)
241 XFreeFontNames (names
);
246 char **indices
= alloca (sizeof (char *) * num_fonts
);
248 for (i
= 0; i
< num_fonts
; i
++)
249 indices
[i
] = names
[i
];
250 qsort (indices
, num_fonts
, sizeof (char *), compare_font_names
);
252 for (i
= 0; i
< num_fonts
; i
++)
257 if (i
> 0 && xstrcasecmp (indices
[i
- 1], indices
[i
]) == 0)
260 entity
= font_make_entity ();
261 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
263 result
= font_parse_xlfd (indices
[i
], entity
);
266 /* This may be an alias name. Try to get the full XLFD name
267 from XA_FONT property of the font. */
268 XFontStruct
*font
= XLoadQueryFont (display
, indices
[i
]);
273 if (XGetFontProperty (font
, XA_FONT
, &value
))
275 char *name
= (char *) XGetAtomName (display
, (Atom
) value
);
276 int len
= strlen (name
);
278 /* If DXPC (a Differential X Protocol Compressor)
279 Ver.3.7 is running, XGetAtomName will return null
280 string. We must avoid such a name. */
282 result
= font_parse_xlfd (name
, entity
);
285 XFreeFont (display
, font
);
289 /* Avoid auto-scaled fonts. */
290 && (XINT (AREF (entity
, FONT_DPI_INDEX
)) == 0
291 || XINT (AREF (entity
, FONT_AVGWIDTH_INDEX
)) > 0))
292 list
= Fcons (entity
, list
);
294 XFreeFontNames (names
);
300 font_add_log ("xfont-list", build_string (pattern
), list
);
305 xfont_list (frame
, spec
)
306 Lisp_Object frame
, spec
;
308 FRAME_PTR f
= XFRAME (frame
);
309 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
310 Lisp_Object registry
, list
, val
, extra
;
314 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
317 val
= assq_no_quit (QCotf
, extra
);
320 val
= assq_no_quit (QCscript
, extra
);
323 val
= assq_no_quit (QClang
, extra
);
328 registry
= AREF (spec
, FONT_REGISTRY_INDEX
);
329 len
= font_unparse_xlfd (spec
, 0, name
, 256);
330 ASET (spec
, FONT_REGISTRY_INDEX
, registry
);
333 list
= xfont_list_pattern (frame
, display
, name
);
334 if (NILP (list
) && NILP (registry
))
337 char *r
= name
+ len
- 9; /* 9 == strlen (iso8859-1) */
339 if (r
- name
+ 10 < 256) /* 10 == strlen (iso10646-1) */
341 strcpy (r
, "iso10646-1");
342 list
= xfont_list_pattern (frame
, display
, name
);
345 if (NILP (list
) && ! NILP (registry
))
347 /* Try alternate registries. */
350 if ((alter
= Fassoc (SYMBOL_NAME (registry
),
351 Vface_alternative_font_registry_alist
),
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
);
371 val
= assq_no_quit (QCname
, AREF (spec
, FONT_EXTRA_INDEX
));
372 if (CONSP (val
) && STRINGP (XCDR (val
)))
373 list
= xfont_list_pattern (frame
, display
, (char *) SDATA (XCDR (val
)));
380 xfont_match (frame
, spec
)
381 Lisp_Object frame
, spec
;
383 FRAME_PTR f
= XFRAME (frame
);
384 Display
*display
= FRAME_X_DISPLAY_INFO (f
)->display
;
385 Lisp_Object extra
, val
, entity
;
386 char buf
[256], *name
;
390 extra
= AREF (spec
, FONT_EXTRA_INDEX
);
391 val
= assq_no_quit (QCname
, extra
);
392 if (! CONSP (val
) || ! STRINGP (XCDR (val
)))
394 if (font_unparse_xlfd (spec
, 0, buf
, 256) < 0)
399 name
= (char *) SDATA (XCDR (val
));
403 xfont
= XLoadQueryFont (display
, name
);
406 if (XGetFontProperty (xfont
, XA_FONT
, &value
))
410 name
= (char *) XGetAtomName (display
, (Atom
) value
);
413 /* If DXPC (a Differential X Protocol Compressor)
414 Ver.3.7 is running, XGetAtomName will return null
415 string. We must avoid such a name. */
418 entity
= font_make_entity ();
419 ASET (entity
, FONT_TYPE_INDEX
, Qx
);
420 if (font_parse_xlfd (name
, entity
) < 0)
425 XFreeFont (display
, xfont
);
429 font_add_log ("xfont-match", spec
, entity
);
434 xfont_list_family (frame
)
437 FRAME_PTR f
= XFRAME (frame
);
438 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
446 x_catch_errors (dpyinfo
->display
);
447 names
= XListFonts (dpyinfo
->display
, "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
449 if (x_had_errors_p (dpyinfo
->display
))
451 /* This error is perhaps due to insufficient memory on X server.
452 Let's just ignore it. */
453 x_clear_errors (dpyinfo
->display
);
458 for (i
= 0, last_len
= 0; i
< num_fonts
; i
++)
460 char *p0
= names
[i
], *p1
;
463 p0
++; /* skip the leading '-' */
464 while (*p0
&& *p0
!= '-') p0
++; /* skip foundry */
468 while (*p1
&& *p1
!= '-') p1
++; /* find the end of family */
469 if (! *p1
|| p1
== p0
)
471 if (last_len
== p1
- p0
472 && bcmp (last_family
, p0
, last_len
) == 0)
476 family
= make_unibyte_string (p0
, last_len
);
477 if (NILP (Fassoc_string (family
, list
, Qt
)))
478 list
= Fcons (family
, list
);
481 XFreeFontNames (names
);
488 extern Lisp_Object QCavgwidth
;
491 xfont_open (f
, entity
, pixel_size
)
496 Display_Info
*dpyinfo
= FRAME_X_DISPLAY_INFO (f
);
497 Display
*display
= dpyinfo
->display
;
501 Lisp_Object registry
;
502 struct charset
*encoding
, *repertory
;
503 Lisp_Object font_object
, fullname
;
508 /* At first, check if we know how to encode characters for this
510 registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
511 if (font_registry_charsets (registry
, &encoding
, &repertory
) < 0)
514 if (XINT (AREF (entity
, FONT_SIZE_INDEX
)) != 0)
515 pixel_size
= XINT (AREF (entity
, FONT_SIZE_INDEX
));
516 else if (pixel_size
== 0)
519 pixel_size
= FRAME_FONT (f
)->pixel_size
;
523 len
= font_unparse_xlfd (entity
, pixel_size
, name
, 256);
528 x_catch_errors (display
);
529 xfont
= XLoadQueryFont (display
, name
);
530 if (x_had_errors_p (display
))
532 /* This error is perhaps due to insufficient memory on X server.
533 Let's just ignore it. */
534 x_clear_errors (display
);
538 /* Try to get the full name of FONT. */
539 if (xfont
&& XGetFontProperty (xfont
, XA_FONT
, &value
))
544 p0
= p
= (char *) XGetAtomName (FRAME_X_DISPLAY (f
), (Atom
) value
);;
545 /* Count the number of dashes in the "full name".
546 If it is too few, this isn't really the font's full name,
548 In X11R4, the fonts did not come with their canonical names
558 fullname
= Fdowncase (make_unibyte_string (p0
, p
- p0
));
567 font_object
= font_make_object (VECSIZE (struct xfont_info
));
568 ASET (font_object
, FONT_TYPE_INDEX
, Qx
);
569 if (STRINGP (fullname
))
570 font_parse_xlfd ((char *) SDATA (fullname
), font_object
);
571 for (i
= 1; i
< FONT_ENTITY_MAX
; i
++)
572 ASET (font_object
, i
, AREF (entity
, i
));
573 ASET (font_object
, FONT_SIZE_INDEX
, make_number (pixel_size
));
574 if (STRINGP (fullname
))
575 ASET (font_object
, FONT_NAME_INDEX
, fullname
);
577 ASET (font_object
, FONT_NAME_INDEX
, make_unibyte_string (name
, len
));
578 ASET (font_object
, FONT_FULLNAME_INDEX
, fullname
);
579 ASET (font_object
, FONT_FILE_INDEX
, Qnil
);
580 ASET (font_object
, FONT_FORMAT_INDEX
, Qx
);
581 font
= XFONT_OBJECT (font_object
);
582 ((struct xfont_info
*) font
)->xfont
= xfont
;
583 ((struct xfont_info
*) font
)->display
= FRAME_X_DISPLAY (f
);
584 font
->pixel_size
= pixel_size
;
585 font
->driver
= &xfont_driver
;
586 font
->encoding_charset
= encoding
->id
;
587 font
->repertory_charset
= repertory
? repertory
->id
: -1;
588 font
->ascent
= xfont
->ascent
;
589 font
->descent
= xfont
->descent
;
590 font
->height
= font
->ascent
+ font
->descent
;
591 font
->min_width
= xfont
->min_bounds
.width
;
592 if (xfont
->min_bounds
.width
== xfont
->max_bounds
.width
)
594 /* Fixed width font. */
595 font
->average_width
= font
->space_width
= xfont
->min_bounds
.width
;
603 char2b
.byte1
= 0x00, char2b
.byte2
= 0x20;
604 pcm
= xfont_get_pcm (xfont
, &char2b
);
606 font
->space_width
= pcm
->width
;
608 font
->space_width
= 0;
610 val
= Ffont_get (font_object
, QCavgwidth
);
612 font
->average_width
= XINT (val
);
613 if (font
->average_width
< 0)
614 font
->average_width
= - font
->average_width
;
615 if (font
->average_width
== 0
616 && encoding
->ascii_compatible_p
)
618 int width
= font
->space_width
, n
= pcm
!= NULL
;
620 for (char2b
.byte2
= 33; char2b
.byte2
<= 126; char2b
.byte2
++)
621 if ((pcm
= xfont_get_pcm (xfont
, &char2b
)) != NULL
)
622 width
+= pcm
->width
, n
++;
624 font
->average_width
= width
/ n
;
626 if (font
->average_width
== 0)
627 /* No easy way other than this to get a reasonable
630 = (xfont
->min_bounds
.width
+ xfont
->max_bounds
.width
) / 2;
634 font
->underline_thickness
635 = (XGetFontProperty (xfont
, XA_UNDERLINE_THICKNESS
, &value
)
637 font
->underline_position
638 = (XGetFontProperty (xfont
, XA_UNDERLINE_POSITION
, &value
)
639 ? (long) value
: -1);
640 font
->baseline_offset
641 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_BASELINE_OFFSET
, &value
)
643 font
->relative_compose
644 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_RELATIVE_COMPOSE
, &value
)
647 = (XGetFontProperty (xfont
, dpyinfo
->Xatom_MULE_DEFAULT_ASCENT
, &value
)
652 fullname
= AREF (font_object
, FONT_NAME_INDEX
);
653 font
->vertical_centering
654 = (STRINGP (Vvertical_centering_font_regexp
)
655 && (fast_string_match_ignore_case
656 (Vvertical_centering_font_regexp
, fullname
) >= 0));
662 xfont_close (f
, font
)
667 XFreeFont (FRAME_X_DISPLAY (f
), ((struct xfont_info
*) font
)->xfont
);
672 xfont_prepare_face (f
, face
)
677 XSetFont (FRAME_X_DISPLAY (f
), face
->gc
,
678 ((struct xfont_info
*) face
->font
)->xfont
->fid
);
685 xfont_has_char (entity
, c
)
689 Lisp_Object registry
= AREF (entity
, FONT_REGISTRY_INDEX
);
690 struct charset
*repertory
;
692 if (font_registry_charsets (registry
, NULL
, &repertory
) < 0)
696 return (ENCODE_CHAR (repertory
, c
) != CHARSET_INVALID_CODE (repertory
));
700 xfont_encode_char (font
, c
)
704 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
705 struct charset
*charset
;
709 charset
= CHARSET_FROM_ID (font
->encoding_charset
);
710 code
= ENCODE_CHAR (charset
, c
);
711 if (code
== CHARSET_INVALID_CODE (charset
))
712 return FONT_INVALID_CODE
;
713 if (font
->repertory_charset
>= 0)
715 charset
= CHARSET_FROM_ID (font
->repertory_charset
);
716 return (ENCODE_CHAR (charset
, c
) != CHARSET_INVALID_CODE (charset
)
717 ? code
: FONT_INVALID_CODE
);
719 char2b
.byte1
= code
>> 8;
720 char2b
.byte2
= code
& 0xFF;
721 return (xfont_get_pcm (xfont
, &char2b
) ? code
: FONT_INVALID_CODE
);
725 xfont_text_extents (font
, code
, nglyphs
, metrics
)
729 struct font_metrics
*metrics
;
731 XFontStruct
*xfont
= ((struct xfont_info
*) font
)->xfont
;
736 bzero (metrics
, sizeof (struct font_metrics
));
737 for (i
= 0, x
= 0; i
< nglyphs
; i
++)
740 static XCharStruct
*pcm
;
742 if (code
[i
] >= 0x10000)
744 char2b
.byte1
= code
[i
] >> 8, char2b
.byte2
= code
[i
] & 0xFF;
745 pcm
= xfont_get_pcm (xfont
, &char2b
);
748 if (metrics
->lbearing
> width
+ pcm
->lbearing
)
749 metrics
->lbearing
= width
+ pcm
->lbearing
;
750 if (metrics
->rbearing
< width
+ pcm
->rbearing
)
751 metrics
->rbearing
= width
+ pcm
->rbearing
;
752 if (metrics
->ascent
< pcm
->ascent
)
753 metrics
->ascent
= pcm
->ascent
;
754 if (metrics
->descent
< pcm
->descent
)
755 metrics
->descent
= pcm
->descent
;
759 metrics
->width
= width
;
764 xfont_draw (s
, from
, to
, x
, y
, with_background
)
765 struct glyph_string
*s
;
766 int from
, to
, x
, y
, with_background
;
768 XFontStruct
*xfont
= ((struct xfont_info
*) s
->font
)->xfont
;
773 if (s
->gc
!= s
->face
->gc
)
776 XSetFont (s
->display
, gc
, xfont
->fid
);
780 if (xfont
->min_byte1
== 0 && xfont
->max_byte1
== 0)
785 SAFE_ALLOCA (str
, char *, len
);
786 for (i
= 0; i
< len
; i
++)
787 str
[i
] = XCHAR2B_BYTE2 (s
->char2b
+ from
+ i
);
789 if (with_background
> 0)
792 for (i
= 0; i
< len
; i
++)
793 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
794 gc
, x
+ i
, y
, str
+ i
, 1);
796 XDrawImageString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
802 for (i
= 0; i
< len
; i
++)
803 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
804 gc
, x
+ i
, y
, str
+ i
, 1);
806 XDrawString (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
815 if (with_background
> 0)
818 for (i
= 0; i
< len
; i
++)
819 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
820 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
822 XDrawImageString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
823 gc
, x
, y
, s
->char2b
+ from
, len
);
828 for (i
= 0; i
< len
; i
++)
829 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
830 gc
, x
+ i
, y
, s
->char2b
+ from
+ i
, 1);
832 XDrawString16 (FRAME_X_DISPLAY (s
->f
), FRAME_X_WINDOW (s
->f
),
833 gc
, x
, y
, s
->char2b
+ from
, len
);
841 xfont_check (f
, font
)
845 struct xfont_info
*xfont
= (struct xfont_info
*) font
;
847 return (FRAME_X_DISPLAY (f
) == xfont
->display
? 0 : -1);
854 xfont_driver
.type
= Qx
;
855 register_font_driver (&xfont_driver
, NULL
);
858 /* arch-tag: 23c5f366-a5ee-44b7-a3b7-90d6da7fd749
859 (do not change this comment) */