Mercurial > emacs
comparison src/xfaces.c @ 94938:5752d7154afc
Throughout the file, delete all USE_FONT_BACKEND
conditionals. Don't check enable_font_backend. Delete all codes
used only when USE_FONT_BACKEND is not defined. Use
FONT_XXX_NAME_NUMERIC instead of face_numeric_xxx.
(QCfoundry, QCadstyle, QCregistry, QCspacing, QCsize, QCavgwidth)
(Qp): Extern them.
(clear_font_table, load_face_font, xlfd_lookup_field_contents):
Deleted.
(struct font_name): Deleted.
(xlfd_numeric_value, xlfd_symbolic_value): Deleted.
(compare_fonts_by_sort_order): New function.
(xlfd_numeric_slant, xlfd_symbolic_slant, xlfd_numeric_weight)
(xlfd_symbolic_weight, xlfd_numeric_swidth, xlfd_symbolic_swidth):
Deleted.
(Fx_family_fonts): Use font_list_entities, and sort fonts by
compare_fonts_by_sort_order.
(Fx_font_family_list): Call Ffont_family_list.
(face_numeric_value, face_numeric_weight, face_numeric_slant)
(face_numeric_swidth, face_symbolic_value, face_symbolic_weight)
(face_symbolic_slant, face_symbolic_swidth)
(split_font_name_into_vector, build_font_name_from_vector)
(xlfd_fixed_p, xlfd_point_size, pixel_point_size)
(font_rescale_ratio, split_font_name, build_font_name)
(free_font_names, sort_fonts, x_face_list_fonts)
(face_font_available_p, sorted_font_list, cmp_font_names)
(font_list_1, concat_font_list, font_list, remove_duplicates):
Deleted.
(Fx_list_fonts): Use Ffont_list.
(LFACE_AVGWIDTH): Deleted.
(check_lface_attrs): Don't check LFACE_AVGWIDTH. Check LFACE_FONT
by FONTP.
(lface_fully_specified_p): Don't check LFACE_AVGWIDTH.
(set_lface_from_font_name): Delete it.
(set_lface_from_font): Renamed from
set_lface_from_font_and_fontset. Caller changed. Don't set
LFACE_AVGWIDTH. Use FONT_XXX_FOR_FACE to get a symbol suitable
for face.
(merge_face_vectors): Copy font-spec if necessary. Clear
properties of the font-spec if necessary.
(merge_face_ref): Clear properties of the font-spec if necessary.
(Finternal_set_lisp_face_attribute): Likewise.
(set_font_frame_param): Use font_load_for_lface to load a
font-object, and call Fmodify_frame_parameters with it.
(x_update_menu_appearance): Don't check LFACE_AVGWIDTH. Get XLFD
font name by Ffont_xlfd_name.
(Finternal_lisp_face_attribute_values): Don't check QCweight,
QCslant, and QCwidth.
(Fface_font): Get a font name from font->props[FONT_NAME_INDEX].
(lface_same_font_attributes_p): Don't check LFACE_AVGWIDTH.
Compare fonts by EQ.
(lookup_non_ascii_face): Deleted.
(face_for_font): The 2nd argument changed.
(x_supports_face_attributes_p): Don't check LFACE_AVGWIDTH. Check
atomic font properties by case insensitive.
(realize_non_ascii_face): Set face->overstrike correctly.
(realize_x_face): Likewise. Check if LFACE_FONT is a font_object.
(dump_realized_face): Get font name from
font->props[FONT_NAME_INDEX]. Don't print font_info_id.
author | Kenichi Handa <handa@m17n.org> |
---|---|
date | Wed, 14 May 2008 01:41:52 +0000 |
parents | ce06567a933d |
children | 8971ddf55736 |
comparison
equal
deleted
inserted
replaced
94937:18a1217b0d5e | 94938:5752d7154afc |
---|---|
54 color. | 54 color. |
55 | 55 |
56 13. Whether or not a box should be drawn around characters, the box | 56 13. Whether or not a box should be drawn around characters, the box |
57 type, and, for simple boxes, in what color. | 57 type, and, for simple boxes, in what color. |
58 | 58 |
59 14. Font pattern, or nil. This is a special attribute. | 59 14. Font-spec, or nil. This is a special attribute. |
60 When this attribute is specified, the face uses a font opened by | 60 |
61 that pattern as is. In addition, all the other font-related | 61 A font-spec is a collection of font attributes (specs). |
62 attributes (1st thru 5th) are generated from the opened font name. | 62 |
63 When this attribute is specified, the face uses a font matching | |
64 with the specs as is except for what overwritten by the specs in | |
65 the fontset (see below). In addition, the other font-related | |
66 attributes (1st thru 5th) are updated from the spec. | |
67 | |
63 On the other hand, if one of the other font-related attributes are | 68 On the other hand, if one of the other font-related attributes are |
64 specified, this attribute is set to nil. In that case, the face | 69 specified, the correspoinding specs in this attribute is set to nil. |
65 doesn't inherit this attribute from the `default' face, and uses a | |
66 font determined by the other attributes (those may be inherited | |
67 from the `default' face). | |
68 | 70 |
69 15. A face name or list of face names from which to inherit attributes. | 71 15. A face name or list of face names from which to inherit attributes. |
70 | 72 |
71 16. A specified average font width, which is invisible from Lisp, | 73 16. A specified average font width, which is invisible from Lisp, |
72 and is used to ensure that a font specified on the command line, | 74 and is used to ensure that a font specified on the command line, |
73 for example, can be matched exactly. | 75 for example, can be matched exactly. |
74 | 76 |
75 17. A fontset name. | 77 17. A fontset name. This is another special attribute. |
78 | |
79 A fontset is a mappings from characters to font-specs, and the | |
80 specs overwrite the font-spec in the 14th attribute. | |
81 | |
76 | 82 |
77 Faces are frame-local by nature because Emacs allows to define the | 83 Faces are frame-local by nature because Emacs allows to define the |
78 same named face (face names are symbols) differently for different | 84 same named face (face names are symbols) differently for different |
79 frames. Each frame has an alist of face definitions for all named | 85 frames. Each frame has an alist of face definitions for all named |
80 faces. The value of a named face in such an alist is a Lisp vector | 86 faces. The value of a named face in such an alist is a Lisp vector |
203 #include "character.h" | 209 #include "character.h" |
204 #include "charset.h" | 210 #include "charset.h" |
205 #include "keyboard.h" | 211 #include "keyboard.h" |
206 #include "frame.h" | 212 #include "frame.h" |
207 #include "termhooks.h" | 213 #include "termhooks.h" |
208 | |
209 #ifdef HAVE_WINDOW_SYSTEM | |
210 #include "fontset.h" | |
211 #endif /* HAVE_WINDOW_SYSTEM */ | |
212 | 214 |
213 #ifdef HAVE_X_WINDOWS | 215 #ifdef HAVE_X_WINDOWS |
214 #include "xterm.h" | 216 #include "xterm.h" |
215 #ifdef USE_MOTIF | 217 #ifdef USE_MOTIF |
216 #include <Xm/Xm.h> | 218 #include <Xm/Xm.h> |
249 #include "intervals.h" | 251 #include "intervals.h" |
250 #include "termchar.h" | 252 #include "termchar.h" |
251 | 253 |
252 #ifdef HAVE_WINDOW_SYSTEM | 254 #ifdef HAVE_WINDOW_SYSTEM |
253 #include "font.h" | 255 #include "font.h" |
254 #endif /* HAVE_WINDOW_SYSTEM */ | 256 #include "fontset.h" |
257 #endif /* HAVE_WINDOW_SYSTEM */ | |
255 | 258 |
256 #ifdef HAVE_X_WINDOWS | 259 #ifdef HAVE_X_WINDOWS |
257 | 260 |
258 /* Compensate for a bug in Xos.h on some systems, on which it requires | 261 /* Compensate for a bug in Xos.h on some systems, on which it requires |
259 time.h. On some such systems, Xos.h tries to redefine struct | 262 time.h. On some such systems, Xos.h tries to redefine struct |
311 Lisp_Object QCinverse_video, QCforeground, QCbackground, QCstipple; | 314 Lisp_Object QCinverse_video, QCforeground, QCbackground, QCstipple; |
312 Lisp_Object QCwidth, QCfont, QCbold, QCitalic; | 315 Lisp_Object QCwidth, QCfont, QCbold, QCitalic; |
313 Lisp_Object QCreverse_video; | 316 Lisp_Object QCreverse_video; |
314 Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit; | 317 Lisp_Object QCoverline, QCstrike_through, QCbox, QCinherit; |
315 Lisp_Object QCfontset; | 318 Lisp_Object QCfontset; |
319 | |
320 /* Keywords symbols used for font properties. */ | |
321 extern Lisp_Object QCfoundry, QCadstyle, QCregistry; | |
322 extern Lisp_Object QCspacing, QCsize, QCavgwidth; | |
323 extern Lisp_Object Qp; | |
316 | 324 |
317 /* Symbols used for attribute values. */ | 325 /* Symbols used for attribute values. */ |
318 | 326 |
319 Lisp_Object Qnormal, Qbold, Qultra_light, Qextra_light, Qlight; | 327 Lisp_Object Qnormal, Qbold, Qultra_light, Qextra_light, Qlight; |
320 Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold; | 328 Lisp_Object Qsemi_light, Qsemi_bold, Qextra_bold, Qultra_bold; |
489 static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object)); | 497 static void set_font_frame_param P_ ((Lisp_Object, Lisp_Object)); |
490 static int better_font_p P_ ((int *, struct font_name *, struct font_name *, | 498 static int better_font_p P_ ((int *, struct font_name *, struct font_name *, |
491 int, int)); | 499 int, int)); |
492 static int x_face_list_fonts P_ ((struct frame *, char *, | 500 static int x_face_list_fonts P_ ((struct frame *, char *, |
493 struct font_name **, int, int)); | 501 struct font_name **, int, int)); |
494 static int font_scalable_p P_ ((struct font_name *)); | |
495 static int get_lface_attributes P_ ((struct frame *, Lisp_Object, Lisp_Object *, int)); | 502 static int get_lface_attributes P_ ((struct frame *, Lisp_Object, Lisp_Object *, int)); |
496 static int load_pixmap P_ ((struct frame *, Lisp_Object, unsigned *, unsigned *)); | 503 static int load_pixmap P_ ((struct frame *, Lisp_Object, unsigned *, unsigned *)); |
497 static unsigned char *xstrlwr P_ ((unsigned char *)); | 504 static unsigned char *xstrlwr P_ ((unsigned char *)); |
498 static struct frame *frame_or_selected_frame P_ ((Lisp_Object, int)); | 505 static struct frame *frame_or_selected_frame P_ ((Lisp_Object, int)); |
499 static void load_face_font P_ ((struct frame *, struct face *)); | 506 static void load_face_font P_ ((struct frame *, struct face *)); |
514 static int try_alternative_families P_ ((struct frame *f, Lisp_Object, | 521 static int try_alternative_families P_ ((struct frame *f, Lisp_Object, |
515 Lisp_Object, struct font_name **)); | 522 Lisp_Object, struct font_name **)); |
516 static int cmp_font_names P_ ((const void *, const void *)); | 523 static int cmp_font_names P_ ((const void *, const void *)); |
517 static struct face *realize_face P_ ((struct face_cache *, Lisp_Object *, | 524 static struct face *realize_face P_ ((struct face_cache *, Lisp_Object *, |
518 int)); | 525 int)); |
519 static struct face *realize_non_ascii_face P_ ((struct frame *, int, | 526 static struct face *realize_non_ascii_face P_ ((struct frame *, Lisp_Object, |
520 struct face *)); | 527 struct face *)); |
521 static struct face *realize_x_face P_ ((struct face_cache *, Lisp_Object *)); | 528 static struct face *realize_x_face P_ ((struct face_cache *, Lisp_Object *)); |
522 static struct face *realize_tty_face P_ ((struct face_cache *, Lisp_Object *)); | 529 static struct face *realize_tty_face P_ ((struct face_cache *, Lisp_Object *)); |
523 static int realize_basic_faces P_ ((struct frame *)); | 530 static int realize_basic_faces P_ ((struct frame *)); |
524 static int realize_default_face P_ ((struct frame *)); | 531 static int realize_default_face P_ ((struct frame *)); |
529 static unsigned lface_hash P_ ((Lisp_Object *)); | 536 static unsigned lface_hash P_ ((Lisp_Object *)); |
530 static int lface_same_font_attributes_p P_ ((Lisp_Object *, Lisp_Object *)); | 537 static int lface_same_font_attributes_p P_ ((Lisp_Object *, Lisp_Object *)); |
531 static struct face_cache *make_face_cache P_ ((struct frame *)); | 538 static struct face_cache *make_face_cache P_ ((struct frame *)); |
532 static void clear_face_gcs P_ ((struct face_cache *)); | 539 static void clear_face_gcs P_ ((struct face_cache *)); |
533 static void free_face_cache P_ ((struct face_cache *)); | 540 static void free_face_cache P_ ((struct face_cache *)); |
534 static int face_numeric_weight P_ ((Lisp_Object)); | |
535 static int face_numeric_slant P_ ((Lisp_Object)); | |
536 static int face_numeric_swidth P_ ((Lisp_Object)); | |
537 static int face_fontset P_ ((Lisp_Object *)); | 541 static int face_fontset P_ ((Lisp_Object *)); |
538 static void merge_face_vectors P_ ((struct frame *, Lisp_Object *, Lisp_Object*, | 542 static void merge_face_vectors P_ ((struct frame *, Lisp_Object *, Lisp_Object*, |
539 struct named_merge_point *)); | 543 struct named_merge_point *)); |
540 static int merge_face_ref P_ ((struct frame *, Lisp_Object, Lisp_Object *, | 544 static int merge_face_ref P_ ((struct frame *, Lisp_Object, Lisp_Object *, |
541 int, struct named_merge_point *)); | 545 int, struct named_merge_point *)); |
542 static int set_lface_from_font_name P_ ((struct frame *, Lisp_Object, | 546 static int set_lface_from_font P_ ((struct frame *, Lisp_Object, Lisp_Object, |
543 Lisp_Object, int, int)); | 547 int)); |
544 static void set_lface_from_font_and_fontset P_ ((struct frame *, Lisp_Object, | |
545 Lisp_Object, int, int)); | |
546 static Lisp_Object lface_from_face_name P_ ((struct frame *, Lisp_Object, int)); | 548 static Lisp_Object lface_from_face_name P_ ((struct frame *, Lisp_Object, int)); |
547 static struct face *make_realized_face P_ ((Lisp_Object *)); | 549 static struct face *make_realized_face P_ ((Lisp_Object *)); |
548 static char *best_matching_font P_ ((struct frame *, Lisp_Object *, | 550 static char *best_matching_font P_ ((struct frame *, Lisp_Object *, |
549 struct font_name *, int, int, int *)); | 551 struct font_name *, int, int, int *)); |
550 static void cache_face P_ ((struct face_cache *, struct face *, unsigned)); | 552 static void cache_face P_ ((struct face_cache *, struct face *, unsigned)); |
551 static void uncache_face P_ ((struct face_cache *, struct face *)); | 553 static void uncache_face P_ ((struct face_cache *, struct face *)); |
552 static int xlfd_numeric_slant P_ ((struct font_name *)); | |
553 static int xlfd_numeric_weight P_ ((struct font_name *)); | |
554 static int xlfd_numeric_swidth P_ ((struct font_name *)); | |
555 static Lisp_Object xlfd_symbolic_slant P_ ((struct font_name *)); | |
556 static Lisp_Object xlfd_symbolic_weight P_ ((struct font_name *)); | |
557 static Lisp_Object xlfd_symbolic_swidth P_ ((struct font_name *)); | |
558 static int xlfd_fixed_p P_ ((struct font_name *)); | |
559 static int xlfd_numeric_value P_ ((struct table_entry *, int, struct font_name *, | |
560 int, int)); | |
561 static Lisp_Object xlfd_symbolic_value P_ ((struct table_entry *, int, | |
562 struct font_name *, int, | |
563 Lisp_Object)); | |
564 static struct table_entry *xlfd_lookup_field_contents P_ ((struct table_entry *, int, | |
565 struct font_name *, int)); | |
566 | 554 |
567 #ifdef HAVE_WINDOW_SYSTEM | 555 #ifdef HAVE_WINDOW_SYSTEM |
568 | 556 |
569 static int split_font_name P_ ((struct frame *, struct font_name *, int)); | |
570 static int xlfd_point_size P_ ((struct frame *, struct font_name *)); | |
571 static void sort_fonts P_ ((struct frame *, struct font_name *, int, | |
572 int (*cmpfn) P_ ((const void *, const void *)))); | |
573 static GC x_create_gc P_ ((struct frame *, unsigned long, XGCValues *)); | 557 static GC x_create_gc P_ ((struct frame *, unsigned long, XGCValues *)); |
574 static void x_free_gc P_ ((struct frame *, GC)); | 558 static void x_free_gc P_ ((struct frame *, GC)); |
575 static void clear_font_table P_ ((struct x_display_info *)); | |
576 | 559 |
577 #ifdef WINDOWSNT | 560 #ifdef WINDOWSNT |
578 extern Lisp_Object w32_list_fonts P_ ((struct frame *, Lisp_Object, int, int)); | 561 extern Lisp_Object w32_list_fonts P_ ((struct frame *, Lisp_Object, int, int)); |
579 #endif /* WINDOWSNT */ | 562 #endif /* WINDOWSNT */ |
580 | 563 |
978 if (clear_fonts_p | 961 if (clear_fonts_p |
979 || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT) | 962 || ++clear_font_table_count == CLEAR_FONT_TABLE_COUNT) |
980 { | 963 { |
981 struct x_display_info *dpyinfo; | 964 struct x_display_info *dpyinfo; |
982 | 965 |
983 #ifdef USE_FONT_BACKEND | 966 #if 0 |
984 if (! enable_font_backend) | 967 /* Not yet implemented. */ |
985 #endif /* USE_FONT_BACKEND */ | 968 clear_font_cache (frame); |
986 /* Fonts are common for frames on one display, i.e. on | 969 #endif |
987 one X screen. */ | 970 |
988 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) | |
989 if (dpyinfo->n_fonts > CLEAR_FONT_TABLE_NFONTS) | |
990 clear_font_table (dpyinfo); | |
991 | 971 |
992 /* From time to time see if we can unload some fonts. This also | 972 /* From time to time see if we can unload some fonts. This also |
993 frees all realized faces on all frames. Fonts needed by | 973 frees all realized faces on all frames. Fonts needed by |
994 faces will be loaded again when faces are realized again. */ | 974 faces will be loaded again when faces are realized again. */ |
995 clear_font_table_count = 0; | 975 clear_font_table_count = 0; |
1026 clear_face_cache (!NILP (thoroughly)); | 1006 clear_face_cache (!NILP (thoroughly)); |
1027 ++face_change_count; | 1007 ++face_change_count; |
1028 ++windows_or_buffers_changed; | 1008 ++windows_or_buffers_changed; |
1029 return Qnil; | 1009 return Qnil; |
1030 } | 1010 } |
1031 | |
1032 | |
1033 | |
1034 #ifdef HAVE_WINDOW_SYSTEM | |
1035 | |
1036 | |
1037 /* Remove fonts from the font table of DPYINFO except for the default | |
1038 ASCII fonts of frames on that display. Called from clear_face_cache | |
1039 from time to time. */ | |
1040 | |
1041 static void | |
1042 clear_font_table (dpyinfo) | |
1043 struct x_display_info *dpyinfo; | |
1044 { | |
1045 int i; | |
1046 | |
1047 /* Free those fonts that are not used by frames on DPYINFO. */ | |
1048 for (i = 0; i < dpyinfo->n_fonts; ++i) | |
1049 { | |
1050 struct font_info *font_info = dpyinfo->font_table + i; | |
1051 Lisp_Object tail, frame; | |
1052 | |
1053 /* Check if slot is already free. */ | |
1054 if (font_info->name == NULL) | |
1055 continue; | |
1056 | |
1057 /* Don't free a default font of some frame. */ | |
1058 FOR_EACH_FRAME (tail, frame) | |
1059 { | |
1060 struct frame *f = XFRAME (frame); | |
1061 if (FRAME_WINDOW_P (f) | |
1062 && font_info->font == FRAME_FONT (f)) | |
1063 break; | |
1064 } | |
1065 | |
1066 if (!NILP (tail)) | |
1067 continue; | |
1068 | |
1069 /* Free names. */ | |
1070 if (font_info->full_name != font_info->name) | |
1071 xfree (font_info->full_name); | |
1072 xfree (font_info->name); | |
1073 | |
1074 /* Free the font. */ | |
1075 BLOCK_INPUT; | |
1076 #ifdef HAVE_X_WINDOWS | |
1077 XFreeFont (dpyinfo->display, font_info->font); | |
1078 #endif | |
1079 #ifdef WINDOWSNT | |
1080 w32_unload_font (dpyinfo, font_info->font); | |
1081 #endif | |
1082 #ifdef MAC_OS | |
1083 mac_unload_font (dpyinfo, font_info->font); | |
1084 #endif | |
1085 UNBLOCK_INPUT; | |
1086 | |
1087 /* Mark font table slot free. */ | |
1088 font_info->font = NULL; | |
1089 font_info->name = font_info->full_name = NULL; | |
1090 } | |
1091 } | |
1092 | |
1093 #endif /* HAVE_WINDOW_SYSTEM */ | |
1094 | |
1095 | 1011 |
1096 | 1012 |
1097 /*********************************************************************** | 1013 /*********************************************************************** |
1098 X Pixmaps | 1014 X Pixmaps |
1099 ***********************************************************************/ | 1015 ***********************************************************************/ |
1213 if (h_ptr) | 1129 if (h_ptr) |
1214 *h_ptr = x_bitmap_height (f, bitmap_id); | 1130 *h_ptr = x_bitmap_height (f, bitmap_id); |
1215 } | 1131 } |
1216 | 1132 |
1217 return bitmap_id; | 1133 return bitmap_id; |
1218 } | |
1219 | |
1220 #endif /* HAVE_WINDOW_SYSTEM */ | |
1221 | |
1222 | |
1223 | |
1224 /*********************************************************************** | |
1225 Fonts | |
1226 ***********************************************************************/ | |
1227 | |
1228 #ifdef HAVE_WINDOW_SYSTEM | |
1229 | |
1230 /* Load font of face FACE which is used on frame F to display ASCII | |
1231 characters. The name of the font to load is determined by lface. */ | |
1232 | |
1233 static void | |
1234 load_face_font (f, face) | |
1235 struct frame *f; | |
1236 struct face *face; | |
1237 { | |
1238 struct font_info *font_info = NULL; | |
1239 char *font_name; | |
1240 int needs_overstrike; | |
1241 | |
1242 #ifdef USE_FONT_BACKEND | |
1243 if (enable_font_backend) | |
1244 abort (); | |
1245 #endif /* USE_FONT_BACKEND */ | |
1246 face->font_info_id = -1; | |
1247 face->font = NULL; | |
1248 face->font_name = NULL; | |
1249 | |
1250 font_name = choose_face_font (f, face->lface, Qnil, &needs_overstrike); | |
1251 if (!font_name) | |
1252 return; | |
1253 | |
1254 BLOCK_INPUT; | |
1255 font_info = FS_LOAD_FONT (f, font_name); | |
1256 UNBLOCK_INPUT; | |
1257 | |
1258 if (font_info) | |
1259 { | |
1260 face->font_info_id = font_info->font_idx; | |
1261 face->font = font_info->font; | |
1262 face->font_name = font_info->full_name; | |
1263 face->overstrike = needs_overstrike; | |
1264 if (face->gc) | |
1265 { | |
1266 BLOCK_INPUT; | |
1267 x_free_gc (f, face->gc); | |
1268 face->gc = 0; | |
1269 UNBLOCK_INPUT; | |
1270 } | |
1271 } | |
1272 else | |
1273 add_to_log ("Unable to load font %s", | |
1274 build_string (font_name), Qnil); | |
1275 xfree (font_name); | |
1276 } | 1134 } |
1277 | 1135 |
1278 #endif /* HAVE_WINDOW_SYSTEM */ | 1136 #endif /* HAVE_WINDOW_SYSTEM */ |
1279 | 1137 |
1280 | 1138 |
1918 {"ultracondensed", XLFD_SWIDTH_ULTRA_CONDENSED, &Qultra_condensed}, | 1776 {"ultracondensed", XLFD_SWIDTH_ULTRA_CONDENSED, &Qultra_condensed}, |
1919 {"ultraexpanded", XLFD_SWIDTH_ULTRA_EXPANDED, &Qultra_expanded}, | 1777 {"ultraexpanded", XLFD_SWIDTH_ULTRA_EXPANDED, &Qultra_expanded}, |
1920 {"wide", XLFD_SWIDTH_EXTRA_EXPANDED, &Qextra_expanded} | 1778 {"wide", XLFD_SWIDTH_EXTRA_EXPANDED, &Qextra_expanded} |
1921 }; | 1779 }; |
1922 | 1780 |
1923 /* Structure used to hold the result of splitting font names in XLFD | |
1924 format into their fields. */ | |
1925 | |
1926 struct font_name | |
1927 { | |
1928 /* The original name which is modified destructively by | |
1929 split_font_name. The pointer is kept here to be able to free it | |
1930 if it was allocated from the heap. */ | |
1931 char *name; | |
1932 | |
1933 /* Font name fields. Each vector element points into `name' above. | |
1934 Fields are NUL-terminated. */ | |
1935 char *fields[XLFD_LAST]; | |
1936 | |
1937 /* Numeric values for those fields that interest us. See | |
1938 split_font_name for which these are. */ | |
1939 int numeric[XLFD_LAST]; | |
1940 | |
1941 /* If the original name matches one of Vface_font_rescale_alist, | |
1942 the value is the corresponding rescale ratio. Otherwise, the | |
1943 value is 1.0. */ | |
1944 double rescale_ratio; | |
1945 | |
1946 /* Lower value mean higher priority. */ | |
1947 int registry_priority; | |
1948 }; | |
1949 | |
1950 /* The frame in effect when sorting font names. Set temporarily in | 1781 /* The frame in effect when sorting font names. Set temporarily in |
1951 sort_fonts so that it is available in font comparison functions. */ | 1782 sort_fonts so that it is available in font comparison functions. */ |
1952 | 1783 |
1953 static struct frame *font_frame; | 1784 static struct frame *font_frame; |
1954 | 1785 |
1963 }; | 1794 }; |
1964 #else | 1795 #else |
1965 static int font_sort_order[4]; | 1796 static int font_sort_order[4]; |
1966 #endif | 1797 #endif |
1967 | 1798 |
1968 /* Look up FONT.fields[FIELD_INDEX] in TABLE which has DIM entries. | |
1969 TABLE must be sorted by TABLE[i]->name in ascending order. Value | |
1970 is a pointer to the matching table entry or null if no table entry | |
1971 matches. */ | |
1972 | |
1973 static struct table_entry * | |
1974 xlfd_lookup_field_contents (table, dim, font, field_index) | |
1975 struct table_entry *table; | |
1976 int dim; | |
1977 struct font_name *font; | |
1978 int field_index; | |
1979 { | |
1980 /* Function split_font_name converts fields to lower-case, so there | |
1981 is no need to use xstrlwr or xstricmp here. */ | |
1982 char *s = font->fields[field_index]; | |
1983 int low, mid, high, cmp; | |
1984 | |
1985 low = 0; | |
1986 high = dim - 1; | |
1987 | |
1988 while (low <= high) | |
1989 { | |
1990 mid = (low + high) / 2; | |
1991 cmp = strcmp (table[mid].name, s); | |
1992 | |
1993 if (cmp < 0) | |
1994 low = mid + 1; | |
1995 else if (cmp > 0) | |
1996 high = mid - 1; | |
1997 else | |
1998 return table + mid; | |
1999 } | |
2000 | |
2001 return NULL; | |
2002 } | |
2003 | |
2004 | |
2005 /* Return a numeric representation for font name field | |
2006 FONT.fields[FIELD_INDEX]. The field is looked up in TABLE which | |
2007 has DIM entries. Value is the numeric value found or DFLT if no | |
2008 table entry matches. This function is used to translate weight, | |
2009 slant, and swidth names of XLFD font names to numeric values. */ | |
2010 | |
2011 static INLINE int | |
2012 xlfd_numeric_value (table, dim, font, field_index, dflt) | |
2013 struct table_entry *table; | |
2014 int dim; | |
2015 struct font_name *font; | |
2016 int field_index; | |
2017 int dflt; | |
2018 { | |
2019 struct table_entry *p; | |
2020 p = xlfd_lookup_field_contents (table, dim, font, field_index); | |
2021 return p ? p->numeric : dflt; | |
2022 } | |
2023 | |
2024 | |
2025 /* Return a symbolic representation for font name field | |
2026 FONT.fields[FIELD_INDEX]. The field is looked up in TABLE which | |
2027 has DIM entries. Value is the symbolic value found or DFLT if no | |
2028 table entry matches. This function is used to translate weight, | |
2029 slant, and swidth names of XLFD font names to symbols. */ | |
2030 | |
2031 static INLINE Lisp_Object | |
2032 xlfd_symbolic_value (table, dim, font, field_index, dflt) | |
2033 struct table_entry *table; | |
2034 int dim; | |
2035 struct font_name *font; | |
2036 int field_index; | |
2037 Lisp_Object dflt; | |
2038 { | |
2039 struct table_entry *p; | |
2040 p = xlfd_lookup_field_contents (table, dim, font, field_index); | |
2041 return p ? *p->symbol : dflt; | |
2042 } | |
2043 | |
2044 | |
2045 /* Return a numeric value for the slant of the font given by FONT. */ | |
2046 | |
2047 static INLINE int | |
2048 xlfd_numeric_slant (font) | |
2049 struct font_name *font; | |
2050 { | |
2051 return xlfd_numeric_value (slant_table, DIM (slant_table), | |
2052 font, XLFD_SLANT, XLFD_SLANT_ROMAN); | |
2053 } | |
2054 | |
2055 | |
2056 /* Return a symbol representing the weight of the font given by FONT. */ | |
2057 | |
2058 static INLINE Lisp_Object | |
2059 xlfd_symbolic_slant (font) | |
2060 struct font_name *font; | |
2061 { | |
2062 return xlfd_symbolic_value (slant_table, DIM (slant_table), | |
2063 font, XLFD_SLANT, Qnormal); | |
2064 } | |
2065 | |
2066 | |
2067 /* Return a numeric value for the weight of the font given by FONT. */ | |
2068 | |
2069 static INLINE int | |
2070 xlfd_numeric_weight (font) | |
2071 struct font_name *font; | |
2072 { | |
2073 return xlfd_numeric_value (weight_table, DIM (weight_table), | |
2074 font, XLFD_WEIGHT, XLFD_WEIGHT_MEDIUM); | |
2075 } | |
2076 | |
2077 | |
2078 /* Return a symbol representing the slant of the font given by FONT. */ | |
2079 | |
2080 static INLINE Lisp_Object | |
2081 xlfd_symbolic_weight (font) | |
2082 struct font_name *font; | |
2083 { | |
2084 return xlfd_symbolic_value (weight_table, DIM (weight_table), | |
2085 font, XLFD_WEIGHT, Qnormal); | |
2086 } | |
2087 | |
2088 | |
2089 /* Return a numeric value for the swidth of the font whose XLFD font | |
2090 name fields are found in FONT. */ | |
2091 | |
2092 static INLINE int | |
2093 xlfd_numeric_swidth (font) | |
2094 struct font_name *font; | |
2095 { | |
2096 return xlfd_numeric_value (swidth_table, DIM (swidth_table), | |
2097 font, XLFD_SWIDTH, XLFD_SWIDTH_MEDIUM); | |
2098 } | |
2099 | |
2100 | |
2101 /* Return a symbolic value for the swidth of FONT. */ | |
2102 | |
2103 static INLINE Lisp_Object | |
2104 xlfd_symbolic_swidth (font) | |
2105 struct font_name *font; | |
2106 { | |
2107 return xlfd_symbolic_value (swidth_table, DIM (swidth_table), | |
2108 font, XLFD_SWIDTH, Qnormal); | |
2109 } | |
2110 | |
2111 | |
2112 /* Look up the entry of SYMBOL in the vector TABLE which has DIM | |
2113 entries. Value is a pointer to the matching table entry or null if | |
2114 no element of TABLE contains SYMBOL. */ | |
2115 | |
2116 static struct table_entry * | |
2117 face_value (table, dim, symbol) | |
2118 struct table_entry *table; | |
2119 int dim; | |
2120 Lisp_Object symbol; | |
2121 { | |
2122 int i; | |
2123 | |
2124 xassert (SYMBOLP (symbol)); | |
2125 | |
2126 for (i = 0; i < dim; ++i) | |
2127 if (EQ (*table[i].symbol, symbol)) | |
2128 break; | |
2129 | |
2130 return i < dim ? table + i : NULL; | |
2131 } | |
2132 | |
2133 | |
2134 /* Return a numeric value for SYMBOL in the vector TABLE which has DIM | |
2135 entries. Value is -1 if SYMBOL is not found in TABLE. */ | |
2136 | |
2137 static INLINE int | |
2138 face_numeric_value (table, dim, symbol) | |
2139 struct table_entry *table; | |
2140 size_t dim; | |
2141 Lisp_Object symbol; | |
2142 { | |
2143 struct table_entry *p = face_value (table, dim, symbol); | |
2144 return p ? p->numeric : -1; | |
2145 } | |
2146 | |
2147 | |
2148 /* Return a numeric value representing the weight specified by Lisp | |
2149 symbol WEIGHT. Value is one of the enumerators of enum | |
2150 xlfd_weight. */ | |
2151 | |
2152 static INLINE int | |
2153 face_numeric_weight (weight) | |
2154 Lisp_Object weight; | |
2155 { | |
2156 return face_numeric_value (weight_table, DIM (weight_table), weight); | |
2157 } | |
2158 | |
2159 | |
2160 /* Return a numeric value representing the slant specified by Lisp | |
2161 symbol SLANT. Value is one of the enumerators of enum xlfd_slant. */ | |
2162 | |
2163 static INLINE int | |
2164 face_numeric_slant (slant) | |
2165 Lisp_Object slant; | |
2166 { | |
2167 return face_numeric_value (slant_table, DIM (slant_table), slant); | |
2168 } | |
2169 | |
2170 | |
2171 /* Return a numeric value representing the swidth specified by Lisp | |
2172 symbol WIDTH. Value is one of the enumerators of enum xlfd_swidth. */ | |
2173 | |
2174 static int | |
2175 face_numeric_swidth (width) | |
2176 Lisp_Object width; | |
2177 { | |
2178 return face_numeric_value (swidth_table, DIM (swidth_table), width); | |
2179 } | |
2180 | 1799 |
2181 #ifdef HAVE_WINDOW_SYSTEM | 1800 #ifdef HAVE_WINDOW_SYSTEM |
2182 | |
2183 #ifdef USE_FONT_BACKEND | |
2184 static INLINE Lisp_Object | |
2185 face_symbolic_value (table, dim, font_prop) | |
2186 struct table_entry *table; | |
2187 int dim; | |
2188 Lisp_Object font_prop; | |
2189 { | |
2190 struct table_entry *p; | |
2191 char *s = SDATA (SYMBOL_NAME (font_prop)); | |
2192 int low, mid, high, cmp; | |
2193 | |
2194 low = 0; | |
2195 high = dim - 1; | |
2196 | |
2197 while (low <= high) | |
2198 { | |
2199 mid = (low + high) / 2; | |
2200 cmp = strcmp (table[mid].name, s); | |
2201 | |
2202 if (cmp < 0) | |
2203 low = mid + 1; | |
2204 else if (cmp > 0) | |
2205 high = mid - 1; | |
2206 else | |
2207 return *table[mid].symbol; | |
2208 } | |
2209 | |
2210 return Qnil; | |
2211 } | |
2212 | |
2213 static INLINE Lisp_Object | |
2214 face_symbolic_weight (weight) | |
2215 Lisp_Object weight; | |
2216 { | |
2217 return face_symbolic_value (weight_table, DIM (weight_table), weight); | |
2218 } | |
2219 | |
2220 static INLINE Lisp_Object | |
2221 face_symbolic_slant (slant) | |
2222 Lisp_Object slant; | |
2223 { | |
2224 return face_symbolic_value (slant_table, DIM (slant_table), slant); | |
2225 } | |
2226 | |
2227 static INLINE Lisp_Object | |
2228 face_symbolic_swidth (width) | |
2229 Lisp_Object width; | |
2230 { | |
2231 return face_symbolic_value (swidth_table, DIM (swidth_table), width); | |
2232 } | |
2233 #endif /* USE_FONT_BACKEND */ | |
2234 | |
2235 Lisp_Object | |
2236 split_font_name_into_vector (fontname) | |
2237 Lisp_Object fontname; | |
2238 { | |
2239 struct font_name font; | |
2240 Lisp_Object vec; | |
2241 int i; | |
2242 | |
2243 font.name = LSTRDUPA (fontname); | |
2244 if (! split_font_name (NULL, &font, 0)) | |
2245 return Qnil; | |
2246 vec = Fmake_vector (make_number (XLFD_LAST), Qnil); | |
2247 for (i = 0; i < XLFD_LAST; i++) | |
2248 if (font.fields[i][0] != '*') | |
2249 ASET (vec, i, build_string (font.fields[i])); | |
2250 return vec; | |
2251 } | |
2252 | |
2253 Lisp_Object | |
2254 build_font_name_from_vector (vec) | |
2255 Lisp_Object vec; | |
2256 { | |
2257 struct font_name font; | |
2258 Lisp_Object fontname; | |
2259 char *p; | |
2260 int i; | |
2261 | |
2262 for (i = 0; i < XLFD_LAST; i++) | |
2263 { | |
2264 font.fields[i] = (NILP (AREF (vec, i)) | |
2265 ? "*" : (char *) SDATA (AREF (vec, i))); | |
2266 if ((i == XLFD_FAMILY || i == XLFD_REGISTRY) | |
2267 && (p = strchr (font.fields[i], '-'))) | |
2268 { | |
2269 char *p1 = STRDUPA (font.fields[i]); | |
2270 | |
2271 p1[p - font.fields[i]] = '\0'; | |
2272 if (i == XLFD_FAMILY) | |
2273 { | |
2274 font.fields[XLFD_FOUNDRY] = p1; | |
2275 font.fields[XLFD_FAMILY] = p + 1; | |
2276 } | |
2277 else | |
2278 { | |
2279 font.fields[XLFD_REGISTRY] = p1; | |
2280 font.fields[XLFD_ENCODING] = p + 1; | |
2281 break; | |
2282 } | |
2283 } | |
2284 } | |
2285 | |
2286 p = build_font_name (&font); | |
2287 fontname = build_string (p); | |
2288 xfree (p); | |
2289 return fontname; | |
2290 } | |
2291 | |
2292 /* Return non-zero if FONT is the name of a fixed-pitch font. */ | |
2293 | |
2294 static INLINE int | |
2295 xlfd_fixed_p (font) | |
2296 struct font_name *font; | |
2297 { | |
2298 /* Function split_font_name converts fields to lower-case, so there | |
2299 is no need to use tolower here. */ | |
2300 return *font->fields[XLFD_SPACING] != 'p'; | |
2301 } | |
2302 | |
2303 | |
2304 /* Return the point size of FONT on frame F, measured in 1/10 pt. | |
2305 | |
2306 The actual height of the font when displayed on F depends on the | |
2307 resolution of both the font and frame. For example, a 10pt font | |
2308 designed for a 100dpi display will display larger than 10pt on a | |
2309 75dpi display. (It's not unusual to use fonts not designed for the | |
2310 display one is using. For example, some intlfonts are available in | |
2311 72dpi versions, only.) | |
2312 | |
2313 Value is the real point size of FONT on frame F, or 0 if it cannot | |
2314 be determined. | |
2315 | |
2316 By side effect, set FONT->numeric[XLFD_PIXEL_SIZE]. */ | |
2317 | |
2318 static INLINE int | |
2319 xlfd_point_size (f, font) | |
2320 struct frame *f; | |
2321 struct font_name *font; | |
2322 { | |
2323 double resy = FRAME_X_DISPLAY_INFO (f)->resy; | |
2324 char *pixel_field = font->fields[XLFD_PIXEL_SIZE]; | |
2325 double pixel; | |
2326 int real_pt; | |
2327 | |
2328 if (*pixel_field == '[') | |
2329 { | |
2330 /* The pixel size field is `[A B C D]' which specifies | |
2331 a transformation matrix. | |
2332 | |
2333 A B 0 | |
2334 C D 0 | |
2335 0 0 1 | |
2336 | |
2337 by which all glyphs of the font are transformed. The spec | |
2338 says that s scalar value N for the pixel size is equivalent | |
2339 to A = N * resx/resy, B = C = 0, D = N. */ | |
2340 char *start = pixel_field + 1, *end; | |
2341 double matrix[4]; | |
2342 int i; | |
2343 | |
2344 for (i = 0; i < 4; ++i) | |
2345 { | |
2346 matrix[i] = strtod (start, &end); | |
2347 start = end; | |
2348 } | |
2349 | |
2350 pixel = matrix[3]; | |
2351 } | |
2352 else | |
2353 pixel = atoi (pixel_field); | |
2354 | |
2355 font->numeric[XLFD_PIXEL_SIZE] = pixel; | |
2356 if (pixel == 0) | |
2357 real_pt = 0; | |
2358 else | |
2359 real_pt = PT_PER_INCH * 10.0 * pixel / resy + 0.5; | |
2360 | |
2361 return real_pt; | |
2362 } | |
2363 | |
2364 | |
2365 /* Return point size of PIXEL dots while considering Y-resultion (DPI) | |
2366 of frame F. This function is used to guess a point size of font | |
2367 when only the pixel height of the font is available. */ | |
2368 | |
2369 static INLINE int | |
2370 pixel_point_size (f, pixel) | |
2371 struct frame *f; | |
2372 int pixel; | |
2373 { | |
2374 double resy = FRAME_X_DISPLAY_INFO (f)->resy; | |
2375 double real_pt; | |
2376 int int_pt; | |
2377 | |
2378 /* As one inch is PT_PER_INCH points, PT_PER_INCH/RESY gives the | |
2379 point size of one dot. */ | |
2380 real_pt = pixel * PT_PER_INCH / resy; | |
2381 int_pt = real_pt + 0.5; | |
2382 | |
2383 return int_pt; | |
2384 } | |
2385 | |
2386 | 1801 |
2387 /* Return a rescaling ratio of a font of NAME. */ | 1802 /* Return a rescaling ratio of a font of NAME. */ |
2388 | 1803 |
2389 static double | 1804 static double |
2390 font_rescale_ratio (name) | 1805 font_rescale_ratio (name) |
2400 return XFLOAT_DATA (XCDR (elt)); | 1815 return XFLOAT_DATA (XCDR (elt)); |
2401 } | 1816 } |
2402 return 1.0; | 1817 return 1.0; |
2403 } | 1818 } |
2404 | 1819 |
2405 | 1820 static enum font_property_index font_props_for_sorting[FONT_SIZE_INDEX]; |
2406 /* Split XLFD font name FONT->name destructively into NUL-terminated, | |
2407 lower-case fields in FONT->fields. NUMERIC_P non-zero means | |
2408 compute numeric values for fields XLFD_POINT_SIZE, XLFD_SWIDTH, | |
2409 XLFD_RESY, XLFD_SLANT, and XLFD_WEIGHT in FONT->numeric. Value is | |
2410 zero if the font name doesn't have the format we expect. The | |
2411 expected format is a font name that starts with a `-' and has | |
2412 XLFD_LAST fields separated by `-'. */ | |
2413 | 1821 |
2414 static int | 1822 static int |
2415 split_font_name (f, font, numeric_p) | 1823 compare_fonts_by_sort_order (v1, v2) |
2416 struct frame *f; | 1824 const void *v1, *v2; |
2417 struct font_name *font; | 1825 { |
2418 int numeric_p; | 1826 Lisp_Object font1 = *(Lisp_Object *) v1; |
2419 { | 1827 Lisp_Object font2 = *(Lisp_Object *) v2; |
2420 int i = 0; | 1828 int i; |
2421 int success_p; | 1829 |
2422 double rescale_ratio; | 1830 for (i = 0; i < FONT_SIZE_INDEX; i++) |
2423 | 1831 { |
2424 if (numeric_p) | 1832 enum font_property_index idx = font_props_for_sorting[i]; |
2425 /* This must be done before splitting the font name. */ | 1833 Lisp_Object val1 = AREF (font1, idx), val2 = AREF (font2, idx); |
2426 rescale_ratio = font_rescale_ratio (font->name); | 1834 int result; |
2427 | 1835 |
2428 if (*font->name == '-') | 1836 if (idx <= FONT_REGISTRY_INDEX) |
2429 { | |
2430 char *p = xstrlwr (font->name) + 1; | |
2431 | |
2432 while (i < XLFD_LAST) | |
2433 { | 1837 { |
2434 font->fields[i] = p; | 1838 if (STRINGP (val1)) |
2435 ++i; | 1839 result = STRINGP (val2) ? strcmp (SDATA (val1), SDATA (val2)) : -1; |
2436 | |
2437 /* Pixel and point size may be of the form `[....]'. For | |
2438 BNF, see XLFD spec, chapter 4. Negative values are | |
2439 indicated by tilde characters which we replace with | |
2440 `-' characters, here. */ | |
2441 if (*p == '[' | |
2442 && (i - 1 == XLFD_PIXEL_SIZE | |
2443 || i - 1 == XLFD_POINT_SIZE)) | |
2444 { | |
2445 char *start, *end; | |
2446 int j; | |
2447 | |
2448 for (++p; *p && *p != ']'; ++p) | |
2449 if (*p == '~') | |
2450 *p = '-'; | |
2451 | |
2452 /* Check that the matrix contains 4 floating point | |
2453 numbers. */ | |
2454 for (j = 0, start = font->fields[i - 1] + 1; | |
2455 j < 4; | |
2456 ++j, start = end) | |
2457 if (strtod (start, &end) == 0 && start == end) | |
2458 break; | |
2459 | |
2460 if (j < 4) | |
2461 break; | |
2462 } | |
2463 | |
2464 while (*p && *p != '-') | |
2465 ++p; | |
2466 | |
2467 if (*p != '-') | |
2468 break; | |
2469 | |
2470 *p++ = 0; | |
2471 } | |
2472 } | |
2473 | |
2474 success_p = i == XLFD_LAST; | |
2475 | |
2476 /* If requested, and font name was in the expected format, | |
2477 compute numeric values for some fields. */ | |
2478 if (numeric_p && success_p) | |
2479 { | |
2480 font->numeric[XLFD_POINT_SIZE] = xlfd_point_size (f, font); | |
2481 font->numeric[XLFD_RESY] = atoi (font->fields[XLFD_RESY]); | |
2482 font->numeric[XLFD_SLANT] = xlfd_numeric_slant (font); | |
2483 font->numeric[XLFD_WEIGHT] = xlfd_numeric_weight (font); | |
2484 font->numeric[XLFD_SWIDTH] = xlfd_numeric_swidth (font); | |
2485 font->numeric[XLFD_AVGWIDTH] = atoi (font->fields[XLFD_AVGWIDTH]); | |
2486 font->rescale_ratio = rescale_ratio; | |
2487 } | |
2488 | |
2489 /* Initialize it to zero. It will be overridden by font_list while | |
2490 trying alternate registries. */ | |
2491 font->registry_priority = 0; | |
2492 | |
2493 return success_p; | |
2494 } | |
2495 | |
2496 | |
2497 /* Build an XLFD font name from font name fields in FONT. Value is a | |
2498 pointer to the font name, which is allocated via xmalloc. */ | |
2499 | |
2500 static char * | |
2501 build_font_name (font) | |
2502 struct font_name *font; | |
2503 { | |
2504 int i; | |
2505 int size = 100; | |
2506 char *font_name = (char *) xmalloc (size); | |
2507 int total_length = 0; | |
2508 | |
2509 for (i = 0; i < XLFD_LAST; ++i) | |
2510 { | |
2511 /* Add 1 because of the leading `-'. */ | |
2512 int len = strlen (font->fields[i]) + 1; | |
2513 | |
2514 /* Reallocate font_name if necessary. Add 1 for the final | |
2515 NUL-byte. */ | |
2516 if (total_length + len + 1 >= size) | |
2517 { | |
2518 int new_size = max (2 * size, size + len + 1); | |
2519 int sz = new_size * sizeof *font_name; | |
2520 font_name = (char *) xrealloc (font_name, sz); | |
2521 size = new_size; | |
2522 } | |
2523 | |
2524 font_name[total_length] = '-'; | |
2525 bcopy (font->fields[i], font_name + total_length + 1, len - 1); | |
2526 total_length += len; | |
2527 } | |
2528 | |
2529 font_name[total_length] = 0; | |
2530 return font_name; | |
2531 } | |
2532 | |
2533 | |
2534 /* Free an array FONTS of N font_name structures. This frees FONTS | |
2535 itself and all `name' fields in its elements. */ | |
2536 | |
2537 static INLINE void | |
2538 free_font_names (fonts, n) | |
2539 struct font_name *fonts; | |
2540 int n; | |
2541 { | |
2542 while (n) | |
2543 xfree (fonts[--n].name); | |
2544 xfree (fonts); | |
2545 } | |
2546 | |
2547 | |
2548 /* Sort vector FONTS of font_name structures which contains NFONTS | |
2549 elements using qsort and comparison function CMPFN. F is the frame | |
2550 on which the fonts will be used. The global variable font_frame | |
2551 is temporarily set to F to make it available in CMPFN. */ | |
2552 | |
2553 static INLINE void | |
2554 sort_fonts (f, fonts, nfonts, cmpfn) | |
2555 struct frame *f; | |
2556 struct font_name *fonts; | |
2557 int nfonts; | |
2558 int (*cmpfn) P_ ((const void *, const void *)); | |
2559 { | |
2560 font_frame = f; | |
2561 qsort (fonts, nfonts, sizeof *fonts, cmpfn); | |
2562 font_frame = NULL; | |
2563 } | |
2564 | |
2565 | |
2566 /* Get fonts matching PATTERN on frame F. If F is null, use the first | |
2567 display in x_display_list. FONTS is a pointer to a vector of | |
2568 NFONTS font_name structures. TRY_ALTERNATIVES_P non-zero means try | |
2569 alternative patterns from Valternate_fontname_alist if no fonts are | |
2570 found matching PATTERN. | |
2571 | |
2572 For all fonts found, set FONTS[i].name to the name of the font, | |
2573 allocated via xmalloc, and split font names into fields. Ignore | |
2574 fonts that we can't parse. Value is the number of fonts found. */ | |
2575 | |
2576 static int | |
2577 x_face_list_fonts (f, pattern, pfonts, nfonts, try_alternatives_p) | |
2578 struct frame *f; | |
2579 char *pattern; | |
2580 struct font_name **pfonts; | |
2581 int nfonts, try_alternatives_p; | |
2582 { | |
2583 int n, nignored; | |
2584 | |
2585 /* NTEMACS_TODO : currently this uses w32_list_fonts, but it may be | |
2586 better to do it the other way around. */ | |
2587 Lisp_Object lfonts; | |
2588 Lisp_Object lpattern, tem; | |
2589 struct font_name *fonts = 0; | |
2590 int num_fonts = nfonts; | |
2591 | |
2592 *pfonts = 0; | |
2593 lpattern = build_string (pattern); | |
2594 | |
2595 /* Get the list of fonts matching PATTERN. */ | |
2596 #ifdef WINDOWSNT | |
2597 BLOCK_INPUT; | |
2598 lfonts = w32_list_fonts (f, lpattern, 0, nfonts); | |
2599 UNBLOCK_INPUT; | |
2600 #else | |
2601 lfonts = x_list_fonts (f, lpattern, -1, nfonts); | |
2602 #endif | |
2603 | |
2604 if (nfonts < 0 && CONSP (lfonts)) | |
2605 num_fonts = XFASTINT (Flength (lfonts)); | |
2606 | |
2607 /* Make a copy of the font names we got from X, and | |
2608 split them into fields. */ | |
2609 n = nignored = 0; | |
2610 for (tem = lfonts; CONSP (tem) && n < num_fonts; tem = XCDR (tem)) | |
2611 { | |
2612 Lisp_Object elt, tail; | |
2613 const char *name = SDATA (XCAR (tem)); | |
2614 | |
2615 /* Ignore fonts matching a pattern from face-ignored-fonts. */ | |
2616 for (tail = Vface_ignored_fonts; CONSP (tail); tail = XCDR (tail)) | |
2617 { | |
2618 elt = XCAR (tail); | |
2619 if (STRINGP (elt) | |
2620 && fast_c_string_match_ignore_case (elt, name) >= 0) | |
2621 break; | |
2622 } | |
2623 if (!NILP (tail)) | |
2624 { | |
2625 ++nignored; | |
2626 continue; | |
2627 } | |
2628 | |
2629 if (! fonts) | |
2630 { | |
2631 *pfonts = (struct font_name *) xmalloc (num_fonts * sizeof **pfonts); | |
2632 fonts = *pfonts; | |
2633 } | |
2634 | |
2635 /* Make a copy of the font name. */ | |
2636 fonts[n].name = xstrdup (name); | |
2637 | |
2638 if (split_font_name (f, fonts + n, 1)) | |
2639 { | |
2640 if (font_scalable_p (fonts + n) | |
2641 && !may_use_scalable_font_p (name)) | |
2642 { | |
2643 ++nignored; | |
2644 xfree (fonts[n].name); | |
2645 } | |
2646 else | 1840 else |
2647 ++n; | 1841 result = STRINGP (val2) ? 1 : 0; |
2648 } | 1842 } |
2649 else | 1843 else |
2650 xfree (fonts[n].name); | |
2651 } | |
2652 | |
2653 /* If no fonts found, try patterns from Valternate_fontname_alist. */ | |
2654 if (n == 0 && try_alternatives_p) | |
2655 { | |
2656 Lisp_Object list = Valternate_fontname_alist; | |
2657 | |
2658 if (*pfonts) | |
2659 { | |
2660 xfree (*pfonts); | |
2661 *pfonts = 0; | |
2662 } | |
2663 | |
2664 while (CONSP (list)) | |
2665 { | 1844 { |
2666 Lisp_Object entry = XCAR (list); | 1845 if (INTEGERP (val1)) |
2667 if (CONSP (entry) | 1846 result = INTEGERP (val2) ? XINT (val1) - XINT (val2) : -1; |
2668 && STRINGP (XCAR (entry)) | 1847 else |
2669 && strcmp (SDATA (XCAR (entry)), pattern) == 0) | 1848 result = INTEGERP (val2) ? 1 : 0; |
2670 break; | |
2671 list = XCDR (list); | |
2672 } | 1849 } |
2673 | 1850 if (result) |
2674 if (CONSP (list)) | 1851 return result; |
2675 { | 1852 } |
2676 Lisp_Object patterns = XCAR (list); | 1853 return 0; |
2677 Lisp_Object name; | 1854 } |
2678 | |
2679 while (CONSP (patterns) | |
2680 /* If list is screwed up, give up. */ | |
2681 && (name = XCAR (patterns), | |
2682 STRINGP (name)) | |
2683 /* Ignore patterns equal to PATTERN because we tried that | |
2684 already with no success. */ | |
2685 && (strcmp (SDATA (name), pattern) == 0 | |
2686 || (n = x_face_list_fonts (f, SDATA (name), | |
2687 pfonts, nfonts, 0), | |
2688 n == 0))) | |
2689 patterns = XCDR (patterns); | |
2690 } | |
2691 } | |
2692 | |
2693 return n; | |
2694 } | |
2695 | |
2696 | |
2697 /* Check if a font matching pattern_offset_t on frame F is available | |
2698 or not. PATTERN may be a cons (FAMILY . REGISTRY), in which case, | |
2699 a font name pattern is generated from FAMILY and REGISTRY. */ | |
2700 | |
2701 int | |
2702 face_font_available_p (f, pattern) | |
2703 struct frame *f; | |
2704 Lisp_Object pattern; | |
2705 { | |
2706 Lisp_Object fonts; | |
2707 | |
2708 if (! STRINGP (pattern)) | |
2709 { | |
2710 Lisp_Object family, registry; | |
2711 char *family_str, *registry_str, *pattern_str; | |
2712 | |
2713 CHECK_CONS (pattern); | |
2714 family = XCAR (pattern); | |
2715 if (NILP (family)) | |
2716 family_str = "*"; | |
2717 else | |
2718 { | |
2719 CHECK_STRING (family); | |
2720 family_str = (char *) SDATA (family); | |
2721 } | |
2722 registry = XCDR (pattern); | |
2723 if (NILP (registry)) | |
2724 registry_str = "*"; | |
2725 else | |
2726 { | |
2727 CHECK_STRING (registry); | |
2728 registry_str = (char *) SDATA (registry); | |
2729 } | |
2730 | |
2731 pattern_str = (char *) alloca (strlen (family_str) | |
2732 + strlen (registry_str) | |
2733 + 10); | |
2734 strcpy (pattern_str, index (family_str, '-') ? "-" : "-*-"); | |
2735 strcat (pattern_str, family_str); | |
2736 strcat (pattern_str, "-*-"); | |
2737 strcat (pattern_str, registry_str); | |
2738 if (!index (registry_str, '-')) | |
2739 { | |
2740 if (registry_str[strlen (registry_str) - 1] == '*') | |
2741 strcat (pattern_str, "-*"); | |
2742 else | |
2743 strcat (pattern_str, "*-*"); | |
2744 } | |
2745 pattern = build_string (pattern_str); | |
2746 } | |
2747 | |
2748 /* Get the list of fonts matching PATTERN. */ | |
2749 #ifdef WINDOWSNT | |
2750 BLOCK_INPUT; | |
2751 fonts = w32_list_fonts (f, pattern, 0, 1); | |
2752 UNBLOCK_INPUT; | |
2753 #else | |
2754 fonts = x_list_fonts (f, pattern, -1, 1); | |
2755 #endif | |
2756 return XINT (Flength (fonts)); | |
2757 } | |
2758 | |
2759 | |
2760 /* Determine fonts matching PATTERN on frame F. Sort resulting fonts | |
2761 using comparison function CMPFN. Value is the number of fonts | |
2762 found. If value is non-zero, *FONTS is set to a vector of | |
2763 font_name structures allocated from the heap containing matching | |
2764 fonts. Each element of *FONTS contains a name member that is also | |
2765 allocated from the heap. Font names in these structures are split | |
2766 into fields. Use free_font_names to free such an array. */ | |
2767 | |
2768 static int | |
2769 sorted_font_list (f, pattern, cmpfn, fonts) | |
2770 struct frame *f; | |
2771 char *pattern; | |
2772 int (*cmpfn) P_ ((const void *, const void *)); | |
2773 struct font_name **fonts; | |
2774 { | |
2775 int nfonts; | |
2776 | |
2777 /* Get the list of fonts matching pattern. 100 should suffice. */ | |
2778 nfonts = DEFAULT_FONT_LIST_LIMIT; | |
2779 if (INTEGERP (Vfont_list_limit)) | |
2780 nfonts = XINT (Vfont_list_limit); | |
2781 | |
2782 *fonts = NULL; | |
2783 nfonts = x_face_list_fonts (f, pattern, fonts, nfonts, 1); | |
2784 | |
2785 /* Sort the resulting array and return it in *FONTS. If no | |
2786 fonts were found, make sure to set *FONTS to null. */ | |
2787 if (nfonts) | |
2788 sort_fonts (f, *fonts, nfonts, cmpfn); | |
2789 else if (*fonts) | |
2790 { | |
2791 xfree (*fonts); | |
2792 *fonts = NULL; | |
2793 } | |
2794 | |
2795 return nfonts; | |
2796 } | |
2797 | |
2798 | |
2799 /* Compare two font_name structures *A and *B. Value is analogous to | |
2800 strcmp. Sort order is given by the global variable | |
2801 font_sort_order. Font names are sorted so that, everything else | |
2802 being equal, fonts with a resolution closer to that of the frame on | |
2803 which they are used are listed first. The global variable | |
2804 font_frame is the frame on which we operate. */ | |
2805 | |
2806 static int | |
2807 cmp_font_names (a, b) | |
2808 const void *a, *b; | |
2809 { | |
2810 struct font_name *x = (struct font_name *) a; | |
2811 struct font_name *y = (struct font_name *) b; | |
2812 int cmp; | |
2813 | |
2814 /* All strings have been converted to lower-case by split_font_name, | |
2815 so we can use strcmp here. */ | |
2816 cmp = strcmp (x->fields[XLFD_FAMILY], y->fields[XLFD_FAMILY]); | |
2817 if (cmp == 0) | |
2818 { | |
2819 int i; | |
2820 | |
2821 for (i = 0; i < DIM (font_sort_order) && cmp == 0; ++i) | |
2822 { | |
2823 int j = font_sort_order[i]; | |
2824 cmp = x->numeric[j] - y->numeric[j]; | |
2825 } | |
2826 | |
2827 if (cmp == 0) | |
2828 { | |
2829 /* Everything else being equal, we prefer fonts with an | |
2830 y-resolution closer to that of the frame. */ | |
2831 int resy = FRAME_X_DISPLAY_INFO (font_frame)->resy; | |
2832 int x_resy = x->numeric[XLFD_RESY]; | |
2833 int y_resy = y->numeric[XLFD_RESY]; | |
2834 cmp = eabs (resy - x_resy) - eabs (resy - y_resy); | |
2835 } | |
2836 } | |
2837 | |
2838 return cmp; | |
2839 } | |
2840 | |
2841 | |
2842 /* Get a sorted list of fonts matching PATTERN on frame F. If PATTERN | |
2843 is nil, list fonts matching FAMILY and REGISTRY. FAMILY is a | |
2844 family name string or nil. REGISTRY is a registry name string. | |
2845 Set *FONTS to a vector of font_name structures allocated from the | |
2846 heap containing the fonts found. Value is the number of fonts | |
2847 found. */ | |
2848 | |
2849 static int | |
2850 font_list_1 (f, pattern, family, registry, fonts) | |
2851 struct frame *f; | |
2852 Lisp_Object pattern, family, registry; | |
2853 struct font_name **fonts; | |
2854 { | |
2855 char *pattern_str, *family_str, *registry_str; | |
2856 | |
2857 if (NILP (pattern)) | |
2858 { | |
2859 family_str = (NILP (family) ? "*" : (char *) SDATA (family)); | |
2860 registry_str = (NILP (registry) ? "*" : (char *) SDATA (registry)); | |
2861 | |
2862 pattern_str = (char *) alloca (strlen (family_str) | |
2863 + strlen (registry_str) | |
2864 + 10); | |
2865 strcpy (pattern_str, index (family_str, '-') ? "-" : "-*-"); | |
2866 strcat (pattern_str, family_str); | |
2867 strcat (pattern_str, "-*-"); | |
2868 strcat (pattern_str, registry_str); | |
2869 if (!index (registry_str, '-')) | |
2870 { | |
2871 if (registry_str[strlen (registry_str) - 1] == '*') | |
2872 strcat (pattern_str, "-*"); | |
2873 else | |
2874 strcat (pattern_str, "*-*"); | |
2875 } | |
2876 } | |
2877 else | |
2878 pattern_str = (char *) SDATA (pattern); | |
2879 | |
2880 return sorted_font_list (f, pattern_str, cmp_font_names, fonts); | |
2881 } | |
2882 | |
2883 | |
2884 /* Concatenate font list FONTS1 and FONTS2. FONTS1 and FONTS2 | |
2885 contains NFONTS1 fonts and NFONTS2 fonts respectively. Return a | |
2886 pointer to a newly allocated font list. FONTS1 and FONTS2 are | |
2887 freed. */ | |
2888 | |
2889 static struct font_name * | |
2890 concat_font_list (fonts1, nfonts1, fonts2, nfonts2) | |
2891 struct font_name *fonts1, *fonts2; | |
2892 int nfonts1, nfonts2; | |
2893 { | |
2894 int new_nfonts = nfonts1 + nfonts2; | |
2895 struct font_name *new_fonts; | |
2896 | |
2897 new_fonts = (struct font_name *) xmalloc (sizeof *new_fonts * new_nfonts); | |
2898 bcopy (fonts1, new_fonts, sizeof *new_fonts * nfonts1); | |
2899 bcopy (fonts2, new_fonts + nfonts1, sizeof *new_fonts * nfonts2); | |
2900 xfree (fonts1); | |
2901 xfree (fonts2); | |
2902 return new_fonts; | |
2903 } | |
2904 | |
2905 | |
2906 /* Get a sorted list of fonts of family FAMILY on frame F. | |
2907 | |
2908 If PATTERN is non-nil, list fonts matching that pattern. | |
2909 | |
2910 If REGISTRY is non-nil, it is a list of registry (and encoding) | |
2911 names. Return fonts with those registries and the alternative | |
2912 registries from Vface_alternative_font_registry_alist. | |
2913 | |
2914 If REGISTRY is nil return fonts of any registry. | |
2915 | |
2916 Set *FONTS to a vector of font_name structures allocated from the | |
2917 heap containing the fonts found. Value is the number of fonts | |
2918 found. */ | |
2919 | |
2920 static int | |
2921 font_list (f, pattern, family, registry, fonts) | |
2922 struct frame *f; | |
2923 Lisp_Object pattern, family, registry; | |
2924 struct font_name **fonts; | |
2925 { | |
2926 int nfonts; | |
2927 int reg_prio; | |
2928 int i; | |
2929 | |
2930 if (NILP (registry)) | |
2931 return font_list_1 (f, pattern, family, registry, fonts); | |
2932 | |
2933 for (reg_prio = 0, nfonts = 0; CONSP (registry); registry = XCDR (registry)) | |
2934 { | |
2935 Lisp_Object elt, alter; | |
2936 int nfonts2; | |
2937 struct font_name *fonts2; | |
2938 | |
2939 elt = XCAR (registry); | |
2940 alter = Fassoc (elt, Vface_alternative_font_registry_alist); | |
2941 if (NILP (alter)) | |
2942 alter = Fcons (elt, Qnil); | |
2943 for (; CONSP (alter); alter = XCDR (alter), reg_prio++) | |
2944 { | |
2945 nfonts2 = font_list_1 (f, pattern, family, XCAR (alter), &fonts2); | |
2946 if (nfonts2 > 0) | |
2947 { | |
2948 if (reg_prio > 0) | |
2949 for (i = 0; i < nfonts2; i++) | |
2950 fonts2[i].registry_priority = reg_prio; | |
2951 if (nfonts > 0) | |
2952 *fonts = concat_font_list (*fonts, nfonts, fonts2, nfonts2); | |
2953 else | |
2954 *fonts = fonts2; | |
2955 nfonts += nfonts2; | |
2956 } | |
2957 } | |
2958 } | |
2959 | |
2960 return nfonts; | |
2961 } | |
2962 | |
2963 | |
2964 /* Remove elements from LIST whose cars are `equal'. Called from | |
2965 x-family-fonts and x-font-family-list to remove duplicate font | |
2966 entries. */ | |
2967 | |
2968 static void | |
2969 remove_duplicates (list) | |
2970 Lisp_Object list; | |
2971 { | |
2972 Lisp_Object tail = list; | |
2973 | |
2974 while (!NILP (tail) && !NILP (XCDR (tail))) | |
2975 { | |
2976 Lisp_Object next = XCDR (tail); | |
2977 if (!NILP (Fequal (XCAR (next), XCAR (tail)))) | |
2978 XSETCDR (tail, XCDR (next)); | |
2979 else | |
2980 tail = XCDR (tail); | |
2981 } | |
2982 } | |
2983 | |
2984 | 1855 |
2985 DEFUN ("x-family-fonts", Fx_family_fonts, Sx_family_fonts, 0, 2, 0, | 1856 DEFUN ("x-family-fonts", Fx_family_fonts, Sx_family_fonts, 0, 2, 0, |
2986 doc: /* Return a list of available fonts of family FAMILY on FRAME. | 1857 doc: /* Return a list of available fonts of family FAMILY on FRAME. |
2987 If FAMILY is omitted or nil, list all families. | 1858 If FAMILY is omitted or nil, list all families. |
2988 Otherwise, FAMILY must be a string, possibly containing wildcards | 1859 Otherwise, FAMILY must be a string, possibly containing wildcards |
3000 the face font sort order. */) | 1871 the face font sort order. */) |
3001 (family, frame) | 1872 (family, frame) |
3002 Lisp_Object family, frame; | 1873 Lisp_Object family, frame; |
3003 { | 1874 { |
3004 struct frame *f = check_x_frame (frame); | 1875 struct frame *f = check_x_frame (frame); |
3005 struct font_name *fonts; | 1876 Lisp_Object font_spec = Qnil, vec; |
3006 int i, nfonts; | 1877 int i, nfonts; |
3007 Lisp_Object result; | 1878 Lisp_Object result; |
3008 struct gcpro gcpro1; | |
3009 | 1879 |
3010 if (!NILP (family)) | 1880 if (!NILP (family)) |
3011 CHECK_STRING (family); | 1881 { |
1882 CHECK_STRING (family); | |
1883 font_spec = Ffont_spec (0, NULL); | |
1884 Ffont_put (font_spec, QCfamily, family); | |
1885 } | |
1886 vec = font_list_entities (frame, font_spec); | |
1887 nfonts = ASIZE (vec); | |
1888 if (nfonts == 0) | |
1889 return Qnil; | |
1890 if (nfonts > 1) | |
1891 { | |
1892 for (i = 0; i < 4; i++) | |
1893 switch (font_sort_order[i]) | |
1894 { | |
1895 case XLFD_SWIDTH: | |
1896 font_props_for_sorting[i] = FONT_WIDTH_INDEX; break; | |
1897 case XLFD_POINT_SIZE: | |
1898 font_props_for_sorting[i] = FONT_SIZE_INDEX; break; | |
1899 case XLFD_WEIGHT: | |
1900 font_props_for_sorting[i] = FONT_WEIGHT_INDEX; break; | |
1901 default: | |
1902 font_props_for_sorting[i] = FONT_SLANT_INDEX; break; | |
1903 } | |
1904 font_props_for_sorting[i++] = FONT_FAMILY_INDEX; | |
1905 font_props_for_sorting[i++] = FONT_FOUNDRY_INDEX; | |
1906 font_props_for_sorting[i++] = FONT_ADSTYLE_INDEX; | |
1907 font_props_for_sorting[i++] = FONT_REGISTRY_INDEX; | |
1908 | |
1909 qsort (XVECTOR (vec)->contents, nfonts, sizeof (Lisp_Object), | |
1910 compare_fonts_by_sort_order); | |
1911 } | |
3012 | 1912 |
3013 result = Qnil; | 1913 result = Qnil; |
3014 GCPRO1 (result); | |
3015 nfonts = font_list (f, Qnil, family, Qnil, &fonts); | |
3016 for (i = nfonts - 1; i >= 0; --i) | 1914 for (i = nfonts - 1; i >= 0; --i) |
3017 { | 1915 { |
1916 Lisp_Object font = AREF (vec, i); | |
3018 Lisp_Object v = Fmake_vector (make_number (8), Qnil); | 1917 Lisp_Object v = Fmake_vector (make_number (8), Qnil); |
3019 char *tem; | 1918 int point; |
3020 | 1919 Lisp_Object spacing; |
3021 ASET (v, 0, build_string (fonts[i].fields[XLFD_FAMILY])); | 1920 |
3022 ASET (v, 1, xlfd_symbolic_swidth (fonts + i)); | 1921 ASET (v, 0, AREF (font, FONT_FAMILY_INDEX)); |
3023 ASET (v, 2, make_number (xlfd_point_size (f, fonts + i))); | 1922 ASET (v, 1, FONT_WIDTH_SYMBOLIC (font)); |
3024 ASET (v, 3, xlfd_symbolic_weight (fonts + i)); | 1923 point = PIXEL_TO_POINT (XINT (AREF (font, FONT_SIZE_INDEX)) * 10, |
3025 ASET (v, 4, xlfd_symbolic_slant (fonts + i)); | 1924 f->resy); |
3026 ASET (v, 5, xlfd_fixed_p (fonts + i) ? Qt : Qnil); | 1925 ASET (v, 2, make_number (point)); |
3027 tem = build_font_name (fonts + i); | 1926 ASET (v, 3, FONT_WEIGHT_SYMBOLIC (font)); |
3028 ASET (v, 6, build_string (tem)); | 1927 ASET (v, 4, FONT_SLANT_SYMBOLIC (font)); |
3029 sprintf (tem, "%s-%s", fonts[i].fields[XLFD_REGISTRY], | 1928 spacing = Ffont_get (font, QCspacing); |
3030 fonts[i].fields[XLFD_ENCODING]); | 1929 ASET (v, 5, (NILP (spacing) || EQ (spacing, Qp)) ? Qnil : Qt); |
3031 ASET (v, 7, build_string (tem)); | 1930 ASET (v, 6, AREF (font, FONT_NAME_INDEX)); |
3032 xfree (tem); | 1931 ASET (v, 7, AREF (font, FONT_REGISTRY_INDEX)); |
3033 | 1932 |
3034 result = Fcons (v, result); | 1933 result = Fcons (v, result); |
3035 } | 1934 } |
3036 | 1935 |
3037 remove_duplicates (result); | |
3038 free_font_names (fonts, nfonts); | |
3039 UNGCPRO; | |
3040 return result; | 1936 return result; |
3041 } | 1937 } |
3042 | 1938 |
3043 | 1939 |
3044 DEFUN ("x-font-family-list", Fx_font_family_list, Sx_font_family_list, | 1940 DEFUN ("x-font-family-list", Fx_font_family_list, Sx_font_family_list, |
3049 is a font family, and FIXED-P is non-nil if fonts of that family | 1945 is a font family, and FIXED-P is non-nil if fonts of that family |
3050 are fixed-pitch. */) | 1946 are fixed-pitch. */) |
3051 (frame) | 1947 (frame) |
3052 Lisp_Object frame; | 1948 Lisp_Object frame; |
3053 { | 1949 { |
3054 struct frame *f = check_x_frame (frame); | 1950 return Ffont_family_list (frame); |
3055 int nfonts, i; | |
3056 struct font_name *fonts; | |
3057 Lisp_Object result; | |
3058 struct gcpro gcpro1; | |
3059 int count = SPECPDL_INDEX (); | |
3060 | |
3061 /* Let's consider all fonts. */ | |
3062 specbind (intern ("font-list-limit"), make_number (-1)); | |
3063 nfonts = font_list (f, Qnil, Qnil, Qnil, &fonts); | |
3064 | |
3065 result = Qnil; | |
3066 GCPRO1 (result); | |
3067 for (i = nfonts - 1; i >= 0; --i) | |
3068 result = Fcons (Fcons (build_string (fonts[i].fields[XLFD_FAMILY]), | |
3069 xlfd_fixed_p (fonts + i) ? Qt : Qnil), | |
3070 result); | |
3071 | |
3072 remove_duplicates (result); | |
3073 free_font_names (fonts, nfonts); | |
3074 UNGCPRO; | |
3075 return unbind_to (count, result); | |
3076 } | 1951 } |
3077 | 1952 |
3078 | 1953 |
3079 DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 5, 0, | 1954 DEFUN ("x-list-fonts", Fx_list_fonts, Sx_list_fonts, 1, 5, 0, |
3080 doc: /* Return a list of the names of available fonts matching PATTERN. | 1955 doc: /* Return a list of the names of available fonts matching PATTERN. |
3098 the WIDTH times as wide as FACE on FRAME. */) | 1973 the WIDTH times as wide as FACE on FRAME. */) |
3099 (pattern, face, frame, maximum, width) | 1974 (pattern, face, frame, maximum, width) |
3100 Lisp_Object pattern, face, frame, maximum, width; | 1975 Lisp_Object pattern, face, frame, maximum, width; |
3101 { | 1976 { |
3102 struct frame *f; | 1977 struct frame *f; |
3103 int size; | 1978 int size, avgwidth; |
3104 int maxnames; | |
3105 | 1979 |
3106 check_x (); | 1980 check_x (); |
3107 CHECK_STRING (pattern); | 1981 CHECK_STRING (pattern); |
3108 | 1982 |
3109 if (NILP (maximum)) | 1983 if (! NILP (maximum)) |
3110 maxnames = -1; | 1984 CHECK_NATNUM (maximum); |
3111 else | |
3112 { | |
3113 CHECK_NATNUM (maximum); | |
3114 maxnames = XINT (maximum); | |
3115 } | |
3116 | 1985 |
3117 if (!NILP (width)) | 1986 if (!NILP (width)) |
3118 CHECK_NUMBER (width); | 1987 CHECK_NUMBER (width); |
3119 | 1988 |
3120 /* We can't simply call check_x_frame because this function may be | 1989 /* We can't simply call check_x_frame because this function may be |
3121 called before any frame is created. */ | 1990 called before any frame is created. */ |
1991 if (NILP (frame)) | |
1992 frame = selected_frame; | |
3122 f = frame_or_selected_frame (frame, 2); | 1993 f = frame_or_selected_frame (frame, 2); |
3123 if (!FRAME_WINDOW_P (f)) | 1994 if (! FRAME_WINDOW_P (f)) |
3124 { | 1995 { |
3125 /* Perhaps we have not yet created any frame. */ | 1996 /* Perhaps we have not yet created any frame. */ |
3126 f = NULL; | 1997 f = NULL; |
1998 frame = Qnil; | |
3127 face = Qnil; | 1999 face = Qnil; |
3128 } | 2000 } |
3129 | 2001 |
3130 /* Determine the width standard for comparison with the fonts we find. */ | 2002 /* Determine the width standard for comparison with the fonts we find. */ |
3131 | 2003 |
3139 struct face *face = (face_id < 0 | 2011 struct face *face = (face_id < 0 |
3140 ? NULL | 2012 ? NULL |
3141 : FACE_FROM_ID (f, face_id)); | 2013 : FACE_FROM_ID (f, face_id)); |
3142 | 2014 |
3143 if (face && face->font) | 2015 if (face && face->font) |
3144 size = FONT_WIDTH (face->font); | 2016 { |
2017 size = face->font->pixel_size; | |
2018 avgwidth = face->font->average_width; | |
2019 } | |
3145 else | 2020 else |
3146 size = FONT_WIDTH (FRAME_FONT (f)); /* FRAME_COLUMN_WIDTH (f) */ | 2021 { |
3147 | 2022 size = FRAME_FONT (f)->pixel_size; |
2023 avgwidth = FRAME_FONT (f)->average_width; | |
2024 } | |
3148 if (!NILP (width)) | 2025 if (!NILP (width)) |
3149 size *= XINT (width); | 2026 avgwidth *= XINT (width); |
3150 } | 2027 } |
3151 | 2028 |
3152 { | 2029 { |
2030 Lisp_Object font_spec; | |
3153 Lisp_Object args[2]; | 2031 Lisp_Object args[2]; |
3154 | 2032 |
3155 args[0] = x_list_fonts (f, pattern, size, maxnames); | 2033 font_spec = font_spec_from_name (pattern); |
3156 if (f == NULL) | 2034 if (size) |
2035 { | |
2036 Ffont_put (font_spec, QCsize, make_number (size)); | |
2037 Ffont_put (font_spec, QCavgwidth, make_number (avgwidth)); | |
2038 } | |
2039 args[0] = Flist_fonts (font_spec, frame, maximum, Qnil); | |
2040 if (NILP (frame)) | |
3157 /* We don't have to check fontsets. */ | 2041 /* We don't have to check fontsets. */ |
3158 return args[0]; | 2042 return args[0]; |
3159 args[1] = list_fontsets (f, pattern, size); | 2043 args[1] = list_fontsets (f, pattern, size); |
3160 return Fnconc (2, args); | 2044 return Fnconc (2, args); |
3161 } | 2045 } |
3184 #define LFACE_OVERLINE(LFACE) AREF ((LFACE), LFACE_OVERLINE_INDEX) | 2068 #define LFACE_OVERLINE(LFACE) AREF ((LFACE), LFACE_OVERLINE_INDEX) |
3185 #define LFACE_STRIKE_THROUGH(LFACE) AREF ((LFACE), LFACE_STRIKE_THROUGH_INDEX) | 2069 #define LFACE_STRIKE_THROUGH(LFACE) AREF ((LFACE), LFACE_STRIKE_THROUGH_INDEX) |
3186 #define LFACE_BOX(LFACE) AREF ((LFACE), LFACE_BOX_INDEX) | 2070 #define LFACE_BOX(LFACE) AREF ((LFACE), LFACE_BOX_INDEX) |
3187 #define LFACE_FONT(LFACE) AREF ((LFACE), LFACE_FONT_INDEX) | 2071 #define LFACE_FONT(LFACE) AREF ((LFACE), LFACE_FONT_INDEX) |
3188 #define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX) | 2072 #define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX) |
3189 #define LFACE_AVGWIDTH(LFACE) AREF ((LFACE), LFACE_AVGWIDTH_INDEX) | |
3190 #define LFACE_FONTSET(LFACE) AREF ((LFACE), LFACE_FONTSET_INDEX) | 2073 #define LFACE_FONTSET(LFACE) AREF ((LFACE), LFACE_FONTSET_INDEX) |
3191 | 2074 |
3192 /* Non-zero if LFACE is a Lisp face. A Lisp face is a vector of size | 2075 /* Non-zero if LFACE is a Lisp face. A Lisp face is a vector of size |
3193 LFACE_VECTOR_SIZE which has the symbol `face' in slot 0. */ | 2076 LFACE_VECTOR_SIZE which has the symbol `face' in slot 0. */ |
3194 | 2077 |
3210 || IGNORE_DEFFACE_P (attrs[LFACE_FAMILY_INDEX]) | 2093 || IGNORE_DEFFACE_P (attrs[LFACE_FAMILY_INDEX]) |
3211 || STRINGP (attrs[LFACE_FAMILY_INDEX])); | 2094 || STRINGP (attrs[LFACE_FAMILY_INDEX])); |
3212 xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX]) | 2095 xassert (UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX]) |
3213 || IGNORE_DEFFACE_P (attrs[LFACE_SWIDTH_INDEX]) | 2096 || IGNORE_DEFFACE_P (attrs[LFACE_SWIDTH_INDEX]) |
3214 || SYMBOLP (attrs[LFACE_SWIDTH_INDEX])); | 2097 || SYMBOLP (attrs[LFACE_SWIDTH_INDEX])); |
3215 xassert (UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX]) | |
3216 || IGNORE_DEFFACE_P (attrs[LFACE_AVGWIDTH_INDEX]) | |
3217 || INTEGERP (attrs[LFACE_AVGWIDTH_INDEX])); | |
3218 xassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX]) | 2098 xassert (UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX]) |
3219 || IGNORE_DEFFACE_P (attrs[LFACE_HEIGHT_INDEX]) | 2099 || IGNORE_DEFFACE_P (attrs[LFACE_HEIGHT_INDEX]) |
3220 || INTEGERP (attrs[LFACE_HEIGHT_INDEX]) | 2100 || INTEGERP (attrs[LFACE_HEIGHT_INDEX]) |
3221 || FLOATP (attrs[LFACE_HEIGHT_INDEX]) | 2101 || FLOATP (attrs[LFACE_HEIGHT_INDEX]) |
3222 || FUNCTIONP (attrs[LFACE_HEIGHT_INDEX])); | 2102 || FUNCTIONP (attrs[LFACE_HEIGHT_INDEX])); |
3263 || IGNORE_DEFFACE_P (attrs[LFACE_STIPPLE_INDEX]) | 2143 || IGNORE_DEFFACE_P (attrs[LFACE_STIPPLE_INDEX]) |
3264 || SYMBOLP (attrs[LFACE_STIPPLE_INDEX]) | 2144 || SYMBOLP (attrs[LFACE_STIPPLE_INDEX]) |
3265 || !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX]))); | 2145 || !NILP (Fbitmap_spec_p (attrs[LFACE_STIPPLE_INDEX]))); |
3266 xassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX]) | 2146 xassert (UNSPECIFIEDP (attrs[LFACE_FONT_INDEX]) |
3267 || IGNORE_DEFFACE_P (attrs[LFACE_FONT_INDEX]) | 2147 || IGNORE_DEFFACE_P (attrs[LFACE_FONT_INDEX]) |
3268 || NILP (attrs[LFACE_FONT_INDEX]) | 2148 || FONTP (attrs[LFACE_FONT_INDEX])); |
3269 #ifdef USE_FONT_BACKEND | |
3270 || FONT_OBJECT_P (attrs[LFACE_FONT_INDEX]) | |
3271 #endif /* USE_FONT_BACKEND */ | |
3272 || STRINGP (attrs[LFACE_FONT_INDEX])); | |
3273 xassert (UNSPECIFIEDP (attrs[LFACE_FONTSET_INDEX]) | 2149 xassert (UNSPECIFIEDP (attrs[LFACE_FONTSET_INDEX]) |
3274 || STRINGP (attrs[LFACE_FONTSET_INDEX])); | 2150 || STRINGP (attrs[LFACE_FONTSET_INDEX])); |
3275 #endif | 2151 #endif |
3276 } | 2152 } |
3277 | 2153 |
3476 Lisp_Object *attrs; | 2352 Lisp_Object *attrs; |
3477 { | 2353 { |
3478 int i; | 2354 int i; |
3479 | 2355 |
3480 for (i = 1; i < LFACE_VECTOR_SIZE; ++i) | 2356 for (i = 1; i < LFACE_VECTOR_SIZE; ++i) |
3481 if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX | 2357 if (i != LFACE_FONT_INDEX && i != LFACE_INHERIT_INDEX) |
3482 && i != LFACE_AVGWIDTH_INDEX && i != LFACE_FONTSET_INDEX) | |
3483 if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i])) | 2358 if ((UNSPECIFIEDP (attrs[i]) || IGNORE_DEFFACE_P (attrs[i])) |
3484 #ifdef MAC_OS | 2359 #ifdef MAC_OS |
3485 /* MAC_TODO: No stipple support on Mac OS yet, this index is | 2360 /* MAC_TODO: No stipple support on Mac OS yet, this index is |
3486 always unspecified. */ | 2361 always unspecified. */ |
3487 && i != LFACE_STIPPLE_INDEX | 2362 && i != LFACE_STIPPLE_INDEX |
3492 return i == LFACE_VECTOR_SIZE; | 2367 return i == LFACE_VECTOR_SIZE; |
3493 } | 2368 } |
3494 | 2369 |
3495 #ifdef HAVE_WINDOW_SYSTEM | 2370 #ifdef HAVE_WINDOW_SYSTEM |
3496 | 2371 |
3497 /* Set font-related attributes of Lisp face LFACE from the fullname of | 2372 /* Set font-related attributes of Lisp face LFACE from FONT-OBJECT. |
3498 the font opened by FONTNAME. If FORCE_P is zero, set only | 2373 If FORCE_P is zero, set only unspecified attributes of LFACE. The |
3499 unspecified attributes of LFACE. The exception is `font' | 2374 exception is `font' attribute. It is set to FONT_OBJECT regardless |
3500 attribute. It is set to FONTNAME as is regardless of FORCE_P. | 2375 of FORCE_P. */ |
3501 | |
3502 If FONTNAME is not available on frame F, | |
3503 return 0 if MAY_FAIL_P is non-zero, otherwise abort. | |
3504 If the fullname is not in a valid XLFD format, | |
3505 return 0 if MAY_FAIL_P is non-zero, otherwise set normal values | |
3506 in LFACE and return 1. | |
3507 Otherwise, return 1. */ | |
3508 | 2376 |
3509 static int | 2377 static int |
3510 set_lface_from_font_name (f, lface, fontname, force_p, may_fail_p) | 2378 set_lface_from_font (f, lface, font_object, force_p) |
3511 struct frame *f; | |
3512 Lisp_Object lface; | |
3513 Lisp_Object fontname; | |
3514 int force_p, may_fail_p; | |
3515 { | |
3516 struct font_name font; | |
3517 char *buffer; | |
3518 int pt; | |
3519 int have_xlfd_p; | |
3520 int fontset; | |
3521 char *font_name = SDATA (fontname); | |
3522 struct font_info *font_info; | |
3523 | |
3524 /* If FONTNAME is actually a fontset name, get ASCII font name of it. */ | |
3525 fontset = fs_query_fontset (fontname, 0); | |
3526 | |
3527 if (fontset > 0) | |
3528 font_name = SDATA (fontset_ascii (fontset)); | |
3529 else if (fontset == 0) | |
3530 { | |
3531 if (may_fail_p) | |
3532 return 0; | |
3533 abort (); | |
3534 } | |
3535 | |
3536 /* Check if FONT_NAME is surely available on the system. Usually | |
3537 FONT_NAME is already cached for the frame F and FS_LOAD_FONT | |
3538 returns quickly. But, even if FONT_NAME is not yet cached, | |
3539 caching it now is not futail because we anyway load the font | |
3540 later. */ | |
3541 BLOCK_INPUT; | |
3542 font_info = FS_LOAD_FONT (f, font_name); | |
3543 UNBLOCK_INPUT; | |
3544 | |
3545 if (!font_info) | |
3546 { | |
3547 if (may_fail_p) | |
3548 return 0; | |
3549 abort (); | |
3550 } | |
3551 | |
3552 font.name = STRDUPA (font_info->full_name); | |
3553 have_xlfd_p = split_font_name (f, &font, 1); | |
3554 | |
3555 /* Set attributes only if unspecified, otherwise face defaults for | |
3556 new frames would never take effect. If we couldn't get a font | |
3557 name conforming to XLFD, set normal values. */ | |
3558 | |
3559 if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface))) | |
3560 { | |
3561 Lisp_Object val; | |
3562 if (have_xlfd_p) | |
3563 { | |
3564 buffer = (char *) alloca (strlen (font.fields[XLFD_FAMILY]) | |
3565 + strlen (font.fields[XLFD_FOUNDRY]) | |
3566 + 2); | |
3567 sprintf (buffer, "%s-%s", font.fields[XLFD_FOUNDRY], | |
3568 font.fields[XLFD_FAMILY]); | |
3569 val = build_string (buffer); | |
3570 } | |
3571 else | |
3572 val = build_string ("*"); | |
3573 LFACE_FAMILY (lface) = val; | |
3574 } | |
3575 | |
3576 if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface))) | |
3577 { | |
3578 if (have_xlfd_p) | |
3579 pt = xlfd_point_size (f, &font); | |
3580 else | |
3581 pt = pixel_point_size (f, font_info->height * 10); | |
3582 xassert (pt > 0); | |
3583 LFACE_HEIGHT (lface) = make_number (pt); | |
3584 } | |
3585 | |
3586 if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface))) | |
3587 LFACE_SWIDTH (lface) | |
3588 = have_xlfd_p ? xlfd_symbolic_swidth (&font) : Qnormal; | |
3589 | |
3590 if (force_p || UNSPECIFIEDP (LFACE_AVGWIDTH (lface))) | |
3591 LFACE_AVGWIDTH (lface) | |
3592 = (have_xlfd_p | |
3593 ? make_number (font.numeric[XLFD_AVGWIDTH]) | |
3594 : Qunspecified); | |
3595 | |
3596 if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface))) | |
3597 LFACE_WEIGHT (lface) | |
3598 = have_xlfd_p ? xlfd_symbolic_weight (&font) : Qnormal; | |
3599 | |
3600 if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface))) | |
3601 LFACE_SLANT (lface) | |
3602 = have_xlfd_p ? xlfd_symbolic_slant (&font) : Qnormal; | |
3603 | |
3604 if (fontset > 0) | |
3605 { | |
3606 LFACE_FONT (lface) = build_string (font_info->full_name); | |
3607 LFACE_FONTSET (lface) = fontset_name (fontset); | |
3608 } | |
3609 else | |
3610 { | |
3611 LFACE_FONT (lface) = fontname; | |
3612 fontset | |
3613 = new_fontset_from_font_name (build_string (font_info->full_name)); | |
3614 LFACE_FONTSET (lface) = fontset_name (fontset); | |
3615 } | |
3616 return 1; | |
3617 } | |
3618 | |
3619 #ifdef USE_FONT_BACKEND | |
3620 /* Set font-related attributes of Lisp face LFACE from FONT-OBJECT and | |
3621 FONTSET. If FORCE_P is zero, set only unspecified attributes of | |
3622 LFACE. The exceptions are `font' and `fontset' attributes. They | |
3623 are set regardless of FORCE_P. */ | |
3624 | |
3625 static void | |
3626 set_lface_from_font_and_fontset (f, lface, font_object, fontset, force_p) | |
3627 struct frame *f; | 2379 struct frame *f; |
3628 Lisp_Object lface, font_object; | 2380 Lisp_Object lface, font_object; |
3629 int fontset; | |
3630 int force_p; | 2381 int force_p; |
3631 { | 2382 { |
3632 struct font *font = XSAVE_VALUE (font_object)->pointer; | |
3633 Lisp_Object entity = font->entity; | |
3634 Lisp_Object val; | 2383 Lisp_Object val; |
2384 struct font *font = XFONT_OBJECT (font_object); | |
3635 | 2385 |
3636 /* Set attributes only if unspecified, otherwise face defaults for | 2386 /* Set attributes only if unspecified, otherwise face defaults for |
3637 new frames would never take effect. If the font doesn't have a | 2387 new frames would never take effect. If the font doesn't have a |
3638 specific property, set a normal value for that. */ | 2388 specific property, set a normal value for that. */ |
3639 | 2389 |
3640 if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface))) | 2390 if (force_p || UNSPECIFIEDP (LFACE_FAMILY (lface))) |
3641 { | 2391 { |
3642 Lisp_Object foundry = AREF (entity, FONT_FOUNDRY_INDEX); | 2392 Lisp_Object foundry = AREF (font_object, FONT_FOUNDRY_INDEX); |
3643 Lisp_Object family = AREF (entity, FONT_FAMILY_INDEX); | 2393 Lisp_Object family = AREF (font_object, FONT_FAMILY_INDEX); |
3644 | 2394 |
3645 if (! NILP (foundry)) | 2395 if (! NILP (foundry)) |
3646 { | 2396 { |
3647 if (! NILP (family)) | 2397 if (! NILP (family)) |
3648 val = concat3 (SYMBOL_NAME (foundry), build_string ("-"), | 2398 val = concat3 (SYMBOL_NAME (foundry), build_string ("-"), |
3660 LFACE_FAMILY (lface) = val; | 2410 LFACE_FAMILY (lface) = val; |
3661 } | 2411 } |
3662 | 2412 |
3663 if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface))) | 2413 if (force_p || UNSPECIFIEDP (LFACE_HEIGHT (lface))) |
3664 { | 2414 { |
3665 int pt = pixel_point_size (f, font->pixel_size * 10); | 2415 int pt = PIXEL_TO_POINT (font->pixel_size * 10, f->resy); |
3666 | 2416 |
3667 xassert (pt > 0); | 2417 xassert (pt > 0); |
3668 LFACE_HEIGHT (lface) = make_number (pt); | 2418 LFACE_HEIGHT (lface) = make_number (pt); |
3669 } | 2419 } |
3670 | 2420 |
3671 if (force_p || UNSPECIFIEDP (LFACE_AVGWIDTH (lface))) | |
3672 LFACE_AVGWIDTH (lface) = make_number (font->font.average_width); | |
3673 | |
3674 if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface))) | 2421 if (force_p || UNSPECIFIEDP (LFACE_WEIGHT (lface))) |
3675 { | 2422 { |
3676 Lisp_Object weight = font_symbolic_weight (entity); | 2423 val = FONT_WEIGHT_FOR_FACE (font_object); |
3677 | 2424 LFACE_WEIGHT (lface) = ! NILP (val) ? val :Qnormal; |
3678 val = NILP (weight) ? Qnormal : face_symbolic_weight (weight); | |
3679 LFACE_WEIGHT (lface) = ! NILP (val) ? val : weight; | |
3680 } | 2425 } |
3681 if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface))) | 2426 if (force_p || UNSPECIFIEDP (LFACE_SLANT (lface))) |
3682 { | 2427 { |
3683 Lisp_Object slant = font_symbolic_slant (entity); | 2428 val = FONT_SLANT_FOR_FACE (font_object); |
3684 | 2429 LFACE_SLANT (lface) = ! NILP (val) ? val : Qnormal; |
3685 val = NILP (slant) ? Qnormal : face_symbolic_slant (slant); | |
3686 LFACE_SLANT (lface) = ! NILP (val) ? val : slant; | |
3687 } | 2430 } |
3688 if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface))) | 2431 if (force_p || UNSPECIFIEDP (LFACE_SWIDTH (lface))) |
3689 { | 2432 { |
3690 Lisp_Object width = font_symbolic_width (entity); | 2433 val = FONT_WIDTH_FOR_FACE (font_object); |
3691 | 2434 LFACE_SWIDTH (lface) = ! NILP (val) ? val : Qnormal; |
3692 val = NILP (width) ? Qnormal : face_symbolic_swidth (width); | 2435 } |
3693 LFACE_SWIDTH (lface) = ! NILP (val) ? val : width; | 2436 |
3694 } | 2437 LFACE_FONT (lface) = font_object; |
3695 | 2438 return 1; |
3696 LFACE_FONT (lface) = make_unibyte_string (font->font.full_name, | 2439 } |
3697 strlen (font->font.full_name)); | |
3698 LFACE_FONTSET (lface) = fontset_name (fontset); | |
3699 } | |
3700 #endif /* USE_FONT_BACKEND */ | |
3701 | 2440 |
3702 #endif /* HAVE_WINDOW_SYSTEM */ | 2441 #endif /* HAVE_WINDOW_SYSTEM */ |
3703 | 2442 |
3704 | 2443 |
3705 /* Merges the face height FROM with the face height TO, and returns the | 2444 /* Merges the face height FROM with the face height TO, and returns the |
3775 other code uses `unspecified' as a generic value for face attributes. */ | 2514 other code uses `unspecified' as a generic value for face attributes. */ |
3776 if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX]) | 2515 if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX]) |
3777 && !NILP (from[LFACE_INHERIT_INDEX])) | 2516 && !NILP (from[LFACE_INHERIT_INDEX])) |
3778 merge_face_ref (f, from[LFACE_INHERIT_INDEX], to, 0, named_merge_points); | 2517 merge_face_ref (f, from[LFACE_INHERIT_INDEX], to, 0, named_merge_points); |
3779 | 2518 |
3780 /* If TO specifies a :font attribute, and FROM specifies some | 2519 i = LFACE_FONT_INDEX; |
3781 font-related attribute, we need to clear TO's :font attribute | 2520 if (!UNSPECIFIEDP (from[i])) |
3782 (because it will be inconsistent with whatever FROM specifies, and | 2521 { |
3783 FROM takes precedence). */ | 2522 if (!UNSPECIFIEDP (to[i])) |
3784 if (!NILP (to[LFACE_FONT_INDEX]) | 2523 to[i] = Fmerge_font_spec (from[i], to[i]); |
3785 && (!UNSPECIFIEDP (from[LFACE_FAMILY_INDEX]) | 2524 else |
3786 || !UNSPECIFIEDP (from[LFACE_HEIGHT_INDEX]) | 2525 to[i] = Fcopy_font_spec (from[i]); |
3787 || !UNSPECIFIEDP (from[LFACE_WEIGHT_INDEX]) | 2526 ASET (to[i], FONT_SIZE_INDEX, Qnil); |
3788 || !UNSPECIFIEDP (from[LFACE_SLANT_INDEX]) | 2527 } |
3789 || !UNSPECIFIEDP (from[LFACE_SWIDTH_INDEX]) | |
3790 || !UNSPECIFIEDP (from[LFACE_AVGWIDTH_INDEX]))) | |
3791 to[LFACE_FONT_INDEX] = Qnil; | |
3792 | 2528 |
3793 for (i = 1; i < LFACE_VECTOR_SIZE; ++i) | 2529 for (i = 1; i < LFACE_VECTOR_SIZE; ++i) |
3794 if (!UNSPECIFIEDP (from[i])) | 2530 if (!UNSPECIFIEDP (from[i])) |
3795 { | 2531 { |
3796 if (i == LFACE_HEIGHT_INDEX && !INTEGERP (from[i])) | 2532 if (i == LFACE_HEIGHT_INDEX && !INTEGERP (from[i])) |
3797 to[i] = merge_face_heights (from[i], to[i], to[i]); | 2533 { |
3798 else | 2534 to[i] = merge_face_heights (from[i], to[i], to[i]); |
3799 to[i] = from[i]; | 2535 font_clear_prop (to, FONT_SIZE_INDEX); |
2536 } | |
2537 else if (i != LFACE_FONT_INDEX) | |
2538 { | |
2539 to[i] = from[i]; | |
2540 if (i >= LFACE_FAMILY_INDEX && i <=LFACE_SLANT_INDEX) | |
2541 font_clear_prop (to, | |
2542 (i == LFACE_FAMILY_INDEX ? FONT_FAMILY_INDEX | |
2543 : i == LFACE_SWIDTH_INDEX ? FONT_WIDTH_INDEX | |
2544 : i == LFACE_HEIGHT_INDEX ? FONT_SIZE_INDEX | |
2545 : i == LFACE_WEIGHT_INDEX ? FONT_WEIGHT_INDEX | |
2546 : FONT_SLANT_INDEX)); | |
2547 } | |
3800 } | 2548 } |
2549 | |
2550 /* If `font' attribute is specified, reflect the font properties in | |
2551 it to the other attributes. */ | |
2552 if (0 && !UNSPECIFIEDP (to[LFACE_FONT_INDEX])) | |
2553 font_update_lface (f, to); | |
3801 | 2554 |
3802 /* TO is always an absolute face, which should inherit from nothing. | 2555 /* TO is always an absolute face, which should inherit from nothing. |
3803 We blindly copy the :inherit attribute above and fix it up here. */ | 2556 We blindly copy the :inherit attribute above and fix it up here. */ |
3804 to[LFACE_INHERIT_INDEX] = Qnil; | 2557 to[LFACE_INHERIT_INDEX] = Qnil; |
3805 } | 2558 } |
3912 if (EQ (value, Qunspecified)) | 2665 if (EQ (value, Qunspecified)) |
3913 ; | 2666 ; |
3914 else if (EQ (keyword, QCfamily)) | 2667 else if (EQ (keyword, QCfamily)) |
3915 { | 2668 { |
3916 if (STRINGP (value)) | 2669 if (STRINGP (value)) |
3917 to[LFACE_FAMILY_INDEX] = value; | 2670 { |
2671 to[LFACE_FAMILY_INDEX] = value; | |
2672 font_clear_prop (to, FONT_FAMILY_INDEX); | |
2673 } | |
3918 else | 2674 else |
3919 err = 1; | 2675 err = 1; |
3920 } | 2676 } |
3921 else if (EQ (keyword, QCheight)) | 2677 else if (EQ (keyword, QCheight)) |
3922 { | 2678 { |
3923 Lisp_Object new_height = | 2679 Lisp_Object new_height = |
3924 merge_face_heights (value, to[LFACE_HEIGHT_INDEX], Qnil); | 2680 merge_face_heights (value, to[LFACE_HEIGHT_INDEX], Qnil); |
3925 | 2681 |
3926 if (! NILP (new_height)) | 2682 if (! NILP (new_height)) |
3927 to[LFACE_HEIGHT_INDEX] = new_height; | 2683 { |
2684 to[LFACE_HEIGHT_INDEX] = new_height; | |
2685 font_clear_prop (to, FONT_SIZE_INDEX); | |
2686 } | |
3928 else | 2687 else |
3929 err = 1; | 2688 err = 1; |
3930 } | 2689 } |
3931 else if (EQ (keyword, QCweight)) | 2690 else if (EQ (keyword, QCweight)) |
3932 { | 2691 { |
3933 if (SYMBOLP (value) | 2692 if (SYMBOLP (value) && FONT_WEIGHT_NAME_NUMERIC (value) >= 0) |
3934 && face_numeric_weight (value) >= 0) | 2693 { |
3935 to[LFACE_WEIGHT_INDEX] = value; | 2694 to[LFACE_WEIGHT_INDEX] = value; |
2695 font_clear_prop (to, FONT_WEIGHT_INDEX); | |
2696 } | |
3936 else | 2697 else |
3937 err = 1; | 2698 err = 1; |
3938 } | 2699 } |
3939 else if (EQ (keyword, QCslant)) | 2700 else if (EQ (keyword, QCslant)) |
3940 { | 2701 { |
3941 if (SYMBOLP (value) | 2702 if (SYMBOLP (value) && FONT_SLANT_NAME_NUMERIC (value) >= 0) |
3942 && face_numeric_slant (value) >= 0) | 2703 { |
3943 to[LFACE_SLANT_INDEX] = value; | 2704 to[LFACE_SLANT_INDEX] = value; |
2705 font_clear_prop (to, FONT_SLANT_INDEX); | |
2706 } | |
3944 else | 2707 else |
3945 err = 1; | 2708 err = 1; |
3946 } | 2709 } |
3947 else if (EQ (keyword, QCunderline)) | 2710 else if (EQ (keyword, QCunderline)) |
3948 { | 2711 { |
4015 err = 1; | 2778 err = 1; |
4016 #endif | 2779 #endif |
4017 } | 2780 } |
4018 else if (EQ (keyword, QCwidth)) | 2781 else if (EQ (keyword, QCwidth)) |
4019 { | 2782 { |
4020 if (SYMBOLP (value) | 2783 if (SYMBOLP (value) && FONT_WIDTH_NAME_NUMERIC (value) >= 0) |
4021 && face_numeric_swidth (value) >= 0) | 2784 { |
4022 to[LFACE_SWIDTH_INDEX] = value; | 2785 to[LFACE_SWIDTH_INDEX] = value; |
2786 font_clear_prop (to, FONT_WIDTH_INDEX); | |
2787 } | |
4023 else | 2788 else |
4024 err = 1; | 2789 err = 1; |
4025 } | 2790 } |
4026 else if (EQ (keyword, QCinherit)) | 2791 else if (EQ (keyword, QCinherit)) |
4027 { | 2792 { |
4248 (face, attr, value, frame) | 3013 (face, attr, value, frame) |
4249 Lisp_Object face, attr, value, frame; | 3014 Lisp_Object face, attr, value, frame; |
4250 { | 3015 { |
4251 Lisp_Object lface; | 3016 Lisp_Object lface; |
4252 Lisp_Object old_value = Qnil; | 3017 Lisp_Object old_value = Qnil; |
4253 /* Set 1 if ATTR is QCfont. */ | 3018 /* Set one of enum font_property_index (> 0) if ATTR is one of |
4254 int font_attr_p = 0; | 3019 font-related attributes other than QCfont and QCfontset. */ |
4255 /* Set 1 if ATTR is one of font-related attributes other than QCfont. */ | 3020 enum font_property_index prop_index = 0; |
4256 int font_related_attr_p = 0; | |
4257 | 3021 |
4258 CHECK_SYMBOL (face); | 3022 CHECK_SYMBOL (face); |
4259 CHECK_SYMBOL (attr); | 3023 CHECK_SYMBOL (attr); |
4260 | 3024 |
4261 face = resolve_face_name (face, 1); | 3025 face = resolve_face_name (face, 1); |
4306 if (SCHARS (value) == 0) | 3070 if (SCHARS (value) == 0) |
4307 signal_error ("Invalid face family", value); | 3071 signal_error ("Invalid face family", value); |
4308 } | 3072 } |
4309 old_value = LFACE_FAMILY (lface); | 3073 old_value = LFACE_FAMILY (lface); |
4310 LFACE_FAMILY (lface) = value; | 3074 LFACE_FAMILY (lface) = value; |
4311 font_related_attr_p = 1; | 3075 prop_index = FONT_FAMILY_INDEX; |
4312 } | 3076 } |
4313 else if (EQ (attr, QCheight)) | 3077 else if (EQ (attr, QCheight)) |
4314 { | 3078 { |
4315 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) | 3079 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) |
4316 { | 3080 { |
4327 signal_error ("Invalid face height", value); | 3091 signal_error ("Invalid face height", value); |
4328 } | 3092 } |
4329 | 3093 |
4330 old_value = LFACE_HEIGHT (lface); | 3094 old_value = LFACE_HEIGHT (lface); |
4331 LFACE_HEIGHT (lface) = value; | 3095 LFACE_HEIGHT (lface) = value; |
4332 font_related_attr_p = 1; | 3096 prop_index = FONT_SIZE_INDEX; |
4333 } | 3097 } |
4334 else if (EQ (attr, QCweight)) | 3098 else if (EQ (attr, QCweight)) |
4335 { | 3099 { |
4336 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) | 3100 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) |
4337 { | 3101 { |
4338 CHECK_SYMBOL (value); | 3102 CHECK_SYMBOL (value); |
4339 if (face_numeric_weight (value) < 0) | 3103 if (FONT_WEIGHT_NAME_NUMERIC (value) < 0) |
4340 signal_error ("Invalid face weight", value); | 3104 signal_error ("Invalid face weight", value); |
4341 } | 3105 } |
4342 old_value = LFACE_WEIGHT (lface); | 3106 old_value = LFACE_WEIGHT (lface); |
4343 LFACE_WEIGHT (lface) = value; | 3107 LFACE_WEIGHT (lface) = value; |
4344 font_related_attr_p = 1; | 3108 prop_index = FONT_WEIGHT_INDEX; |
4345 } | 3109 } |
4346 else if (EQ (attr, QCslant)) | 3110 else if (EQ (attr, QCslant)) |
4347 { | 3111 { |
4348 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) | 3112 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) |
4349 { | 3113 { |
4350 CHECK_SYMBOL (value); | 3114 CHECK_SYMBOL (value); |
4351 if (face_numeric_slant (value) < 0) | 3115 if (FONT_SLANT_NAME_NUMERIC (value) < 0) |
4352 signal_error ("Invalid face slant", value); | 3116 signal_error ("Invalid face slant", value); |
4353 } | 3117 } |
4354 old_value = LFACE_SLANT (lface); | 3118 old_value = LFACE_SLANT (lface); |
4355 LFACE_SLANT (lface) = value; | 3119 LFACE_SLANT (lface) = value; |
4356 font_related_attr_p = 1; | 3120 prop_index = FONT_SLANT_INDEX; |
4357 } | 3121 } |
4358 else if (EQ (attr, QCunderline)) | 3122 else if (EQ (attr, QCunderline)) |
4359 { | 3123 { |
4360 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) | 3124 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) |
4361 if ((SYMBOLP (value) | 3125 if ((SYMBOLP (value) |
4514 else if (EQ (attr, QCwidth)) | 3278 else if (EQ (attr, QCwidth)) |
4515 { | 3279 { |
4516 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) | 3280 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) |
4517 { | 3281 { |
4518 CHECK_SYMBOL (value); | 3282 CHECK_SYMBOL (value); |
4519 if (face_numeric_swidth (value) < 0) | 3283 if (FONT_WIDTH_NAME_NUMERIC (value) < 0) |
4520 signal_error ("Invalid face width", value); | 3284 signal_error ("Invalid face width", value); |
4521 } | 3285 } |
4522 old_value = LFACE_SWIDTH (lface); | 3286 old_value = LFACE_SWIDTH (lface); |
4523 LFACE_SWIDTH (lface) = value; | 3287 LFACE_SWIDTH (lface) = value; |
4524 font_related_attr_p = 1; | 3288 prop_index = FONT_WIDTH_INDEX; |
4525 } | 3289 } |
4526 else if (EQ (attr, QCfont) || EQ (attr, QCfontset)) | 3290 else if (EQ (attr, QCfont)) |
4527 { | 3291 { |
4528 #ifdef HAVE_WINDOW_SYSTEM | 3292 #ifdef HAVE_WINDOW_SYSTEM |
4529 if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame))) | 3293 if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame))) |
4530 { | 3294 { |
4531 /* Set font-related attributes of the Lisp face from an XLFD | 3295 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) |
4532 font name. */ | |
4533 struct frame *f; | |
4534 Lisp_Object tmp; | |
4535 | |
4536 if (EQ (frame, Qt)) | |
4537 f = SELECTED_FRAME (); | |
4538 else | |
4539 f = check_x_frame (frame); | |
4540 | |
4541 #ifdef USE_FONT_BACKEND | |
4542 if (enable_font_backend | |
4543 && !UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) | |
4544 { | 3296 { |
4545 tmp = Fquery_fontset (value, Qnil); | 3297 FRAME_PTR f; |
4546 if (EQ (attr, QCfontset)) | 3298 |
3299 old_value = LFACE_FONT (lface); | |
3300 if (! FONTP (value)) | |
4547 { | 3301 { |
4548 if (NILP (tmp)) | 3302 if (STRINGP (value)) |
4549 signal_error ("Invalid fontset name", value); | |
4550 LFACE_FONTSET (lface) = tmp; | |
4551 } | |
4552 else | |
4553 { | |
4554 int fontset; | |
4555 Lisp_Object font_object; | |
4556 | |
4557 if (! NILP (tmp)) | |
4558 { | 3303 { |
4559 fontset = fs_query_fontset (tmp, 0); | 3304 int fontset = fs_query_fontset (value, 0); |
4560 value = fontset_ascii (fontset); | 3305 |
3306 if (fontset >= 0) | |
3307 value = fontset_ascii (fontset); | |
3308 else | |
3309 value = font_spec_from_name (value); | |
4561 } | 3310 } |
4562 else | 3311 else |
4563 { | 3312 signal_error ("Invalid font or font-spec", value); |
4564 fontset = FRAME_FONTSET (f); | 3313 } |
4565 } | 3314 if (EQ (frame, Qt)) |
4566 font_object = font_open_by_name (f, SDATA (value)); | 3315 f = XFRAME (selected_frame); |
3316 else | |
3317 f = XFRAME (frame); | |
3318 if (! FONT_OBJECT_P (value)) | |
3319 { | |
3320 Lisp_Object *attrs = XVECTOR (lface)->contents; | |
3321 Lisp_Object font_object; | |
3322 | |
3323 font_object = font_load_for_lface (f, attrs, value); | |
4567 if (NILP (font_object)) | 3324 if (NILP (font_object)) |
4568 signal_error ("Invalid font", value); | 3325 signal_error ("Font not available", value); |
4569 set_lface_from_font_and_fontset (f, lface, font_object, | 3326 value = font_object; |
4570 fontset, 1); | |
4571 } | 3327 } |
3328 set_lface_from_font (f, lface, value, 1); | |
4572 } | 3329 } |
4573 else | 3330 else |
4574 #endif /* USE_FONT_BACKEND */ | 3331 LFACE_FONT (lface) = value; |
4575 if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) | 3332 } |
4576 { | 3333 #endif /* HAVE_WINDOW_SYSTEM */ |
4577 CHECK_STRING (value); | 3334 } |
4578 | 3335 else if (EQ (attr, QCfontset)) |
4579 /* VALUE may be a fontset name or an alias of fontset. In | 3336 { |
4580 such a case, use the base fontset name. */ | 3337 #ifdef HAVE_WINDOW_SYSTEM |
4581 tmp = Fquery_fontset (value, Qnil); | 3338 if (EQ (frame, Qt) || FRAME_WINDOW_P (XFRAME (frame))) |
4582 if (!NILP (tmp)) | 3339 { |
4583 value = tmp; | 3340 Lisp_Object tmp; |
4584 else if (EQ (attr, QCfontset)) | 3341 |
4585 signal_error ("Invalid fontset name", value); | 3342 old_value = LFACE_FONTSET (lface); |
4586 | 3343 tmp = Fquery_fontset (value, Qnil); |
4587 if (EQ (attr, QCfont)) | 3344 if (NILP (tmp)) |
4588 { | 3345 signal_error ("Invalid fontset name", value); |
4589 if (!set_lface_from_font_name (f, lface, value, 1, 1)) | 3346 LFACE_FONTSET (lface) = value = tmp; |
4590 signal_error ("Invalid font or fontset name", value); | |
4591 } | |
4592 else | |
4593 LFACE_FONTSET (lface) = value; | |
4594 } | |
4595 | |
4596 font_attr_p = 1; | |
4597 } | 3347 } |
4598 #endif /* HAVE_WINDOW_SYSTEM */ | 3348 #endif /* HAVE_WINDOW_SYSTEM */ |
4599 } | 3349 } |
4600 else if (EQ (attr, QCinherit)) | 3350 else if (EQ (attr, QCinherit)) |
4601 { | 3351 { |
4613 } | 3363 } |
4614 else if (EQ (attr, QCbold)) | 3364 else if (EQ (attr, QCbold)) |
4615 { | 3365 { |
4616 old_value = LFACE_WEIGHT (lface); | 3366 old_value = LFACE_WEIGHT (lface); |
4617 LFACE_WEIGHT (lface) = NILP (value) ? Qnormal : Qbold; | 3367 LFACE_WEIGHT (lface) = NILP (value) ? Qnormal : Qbold; |
4618 font_related_attr_p = 1; | 3368 prop_index = FONT_WEIGHT_INDEX; |
4619 } | 3369 } |
4620 else if (EQ (attr, QCitalic)) | 3370 else if (EQ (attr, QCitalic)) |
4621 { | 3371 { |
3372 attr = QCslant; | |
4622 old_value = LFACE_SLANT (lface); | 3373 old_value = LFACE_SLANT (lface); |
4623 LFACE_SLANT (lface) = NILP (value) ? Qnormal : Qitalic; | 3374 LFACE_SLANT (lface) = NILP (value) ? Qnormal : Qitalic; |
4624 font_related_attr_p = 1; | 3375 prop_index = FONT_SLANT_INDEX; |
4625 } | 3376 } |
4626 else | 3377 else |
4627 signal_error ("Invalid face attribute name", attr); | 3378 signal_error ("Invalid face attribute name", attr); |
4628 | 3379 |
4629 if (font_related_attr_p | 3380 if (prop_index) |
4630 && !UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) | 3381 /* If a font-related attribute other than QCfont and QCfontset is |
4631 /* If a font-related attribute other than QCfont is specified, the | 3382 specified, and if the original QCfont attribute has a font |
4632 original `font' attribute nor that of default face is useless | 3383 (font-spec or font-object), set the corresponding property in |
4633 to determine a new font. Thus, we set it to nil so that font | 3384 the font to nil so that the font selector doesn't think that |
4634 selection mechanism doesn't use it. */ | 3385 the attribute is mandatory. */ |
4635 LFACE_FONT (lface) = Qnil; | 3386 font_clear_prop (XVECTOR (lface)->contents, prop_index); |
4636 | 3387 |
4637 /* Changing a named face means that all realized faces depending on | 3388 /* Changing a named face means that all realized faces depending on |
4638 that face are invalid. Since we cannot tell which realized faces | 3389 that face are invalid. Since we cannot tell which realized faces |
4639 depend on the face, make sure they are all removed. This is done | 3390 depend on the face, make sure they are all removed. This is done |
4640 by incrementing face_change_count. The next call to | 3391 by incrementing face_change_count. The next call to |
4641 init_iterator will then free realized faces. */ | 3392 init_iterator will then free realized faces. */ |
4642 if (!EQ (frame, Qt) | 3393 if (!EQ (frame, Qt) |
4643 && NILP (Fget (face, Qface_no_inherit)) | 3394 && NILP (Fget (face, Qface_no_inherit)) |
4644 && (EQ (attr, QCfont) | 3395 && NILP (Fequal (old_value, value))) |
4645 || EQ (attr, QCfontset) | |
4646 || NILP (Fequal (old_value, value)))) | |
4647 { | 3396 { |
4648 ++face_change_count; | 3397 ++face_change_count; |
4649 ++windows_or_buffers_changed; | 3398 ++windows_or_buffers_changed; |
4650 } | 3399 } |
4651 | 3400 |
4660 { | 3409 { |
4661 #ifdef HAVE_WINDOW_SYSTEM | 3410 #ifdef HAVE_WINDOW_SYSTEM |
4662 /* Changed font-related attributes of the `default' face are | 3411 /* Changed font-related attributes of the `default' face are |
4663 reflected in changed `font' frame parameters. */ | 3412 reflected in changed `font' frame parameters. */ |
4664 if (FRAMEP (frame) | 3413 if (FRAMEP (frame) |
4665 && (font_related_attr_p || font_attr_p) | 3414 && (prop_index || EQ (attr, QCfont)) |
4666 && lface_fully_specified_p (XVECTOR (lface)->contents)) | 3415 && lface_fully_specified_p (XVECTOR (lface)->contents)) |
4667 set_font_frame_param (frame, lface); | 3416 set_font_frame_param (frame, lface); |
4668 else | 3417 else |
4669 #endif /* HAVE_WINDOW_SYSTEM */ | 3418 #endif /* HAVE_WINDOW_SYSTEM */ |
4670 | 3419 |
4747 } | 3496 } |
4748 | 3497 |
4749 | 3498 |
4750 #ifdef HAVE_WINDOW_SYSTEM | 3499 #ifdef HAVE_WINDOW_SYSTEM |
4751 | 3500 |
4752 /* Set the `font' frame parameter of FRAME determined from `default' | 3501 /* Set the `font' frame parameter of FRAME determined from the |
4753 face attributes LFACE. If a font name is explicitely | 3502 font-object set in `default' face attributes LFACE. */ |
4754 specfied in LFACE, use it as is. Otherwise, determine a font name | |
4755 from the other font-related atrributes of LFACE. In that case, if | |
4756 there's no matching font, signals an error. */ | |
4757 | 3503 |
4758 static void | 3504 static void |
4759 set_font_frame_param (frame, lface) | 3505 set_font_frame_param (frame, lface) |
4760 Lisp_Object frame, lface; | 3506 Lisp_Object frame, lface; |
4761 { | 3507 { |
4762 struct frame *f = XFRAME (frame); | 3508 struct frame *f = XFRAME (frame); |
4763 | 3509 |
4764 if (FRAME_WINDOW_P (f)) | 3510 if (FRAME_WINDOW_P (f)) |
4765 { | 3511 { |
4766 Lisp_Object font_name; | 3512 Lisp_Object font = LFACE_FONT (lface); |
4767 char *font; | 3513 |
4768 | 3514 if (FONT_SPEC_P (font)) |
4769 if (STRINGP (LFACE_FONT (lface))) | |
4770 font_name = LFACE_FONT (lface); | |
4771 #ifdef USE_FONT_BACKEND | |
4772 else if (enable_font_backend) | |
4773 { | 3515 { |
4774 /* We set FONT_NAME to a font-object. */ | 3516 font = font_load_for_lface (f, XVECTOR (lface)->contents, font); |
4775 if (FONT_OBJECT_P (LFACE_FONT (lface))) | 3517 if (NILP (font)) |
4776 font_name = LFACE_FONT (lface); | 3518 return; |
4777 else | 3519 LFACE_FONT (lface) = font; |
4778 { | |
4779 font_name = font_find_for_lface (f, &AREF (lface, 0), Qnil, -1); | |
4780 if (NILP (font_name)) | |
4781 error ("No font matches the specified attribute"); | |
4782 font_name = font_open_for_lface (f, font_name, &AREF (lface, 0), | |
4783 Qnil); | |
4784 if (NILP (font_name)) | |
4785 error ("No font matches the specified attribute"); | |
4786 } | |
4787 } | 3520 } |
4788 #endif | |
4789 else | |
4790 { | |
4791 /* Choose a font name that reflects LFACE's attributes and has | |
4792 the registry and encoding pattern specified in the default | |
4793 fontset (3rd arg: -1) for ASCII characters (4th arg: 0). */ | |
4794 font = choose_face_font (f, XVECTOR (lface)->contents, Qnil, NULL); | |
4795 if (!font) | |
4796 error ("No font matches the specified attribute"); | |
4797 font_name = build_string (font); | |
4798 xfree (font); | |
4799 } | |
4800 | |
4801 f->default_face_done_p = 0; | 3521 f->default_face_done_p = 0; |
4802 Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, font_name), Qnil)); | 3522 Fmodify_frame_parameters (frame, Fcons (Fcons (Qfont, font), Qnil)); |
4803 } | 3523 } |
4804 } | 3524 } |
4805 | 3525 |
4806 | 3526 |
4807 /* Update the corresponding face when frame parameter PARAM on frame F | 3527 /* Update the corresponding face when frame parameter PARAM on frame F |
5029 myname, SDATA (LFACE_BACKGROUND (lface))); | 3749 myname, SDATA (LFACE_BACKGROUND (lface))); |
5030 XrmPutLineResource (&rdb, line); | 3750 XrmPutLineResource (&rdb, line); |
5031 changed_p = 1; | 3751 changed_p = 1; |
5032 } | 3752 } |
5033 | 3753 |
5034 if (face->font_name | 3754 if (face->font |
5035 && (!UNSPECIFIEDP (LFACE_FAMILY (lface)) | 3755 && (!UNSPECIFIEDP (LFACE_FAMILY (lface)) |
5036 || !UNSPECIFIEDP (LFACE_SWIDTH (lface)) | 3756 || !UNSPECIFIEDP (LFACE_SWIDTH (lface)) |
5037 || !UNSPECIFIEDP (LFACE_AVGWIDTH (lface)) | |
5038 || !UNSPECIFIEDP (LFACE_WEIGHT (lface)) | 3757 || !UNSPECIFIEDP (LFACE_WEIGHT (lface)) |
5039 || !UNSPECIFIEDP (LFACE_SLANT (lface)) | 3758 || !UNSPECIFIEDP (LFACE_SLANT (lface)) |
5040 || !UNSPECIFIEDP (LFACE_HEIGHT (lface)))) | 3759 || !UNSPECIFIEDP (LFACE_HEIGHT (lface)))) |
5041 { | 3760 { |
3761 Lisp_Object xlfd = Ffont_xlfd_name (LFACE_FONT (lface)); | |
5042 #ifdef USE_MOTIF | 3762 #ifdef USE_MOTIF |
5043 const char *suffix = "List"; | 3763 const char *suffix = "List"; |
5044 Bool motif = True; | 3764 Bool motif = True; |
5045 #else | 3765 #else |
5046 #if defined HAVE_X_I18N | 3766 #if defined HAVE_X_I18N |
5049 #else | 3769 #else |
5050 const char *suffix = ""; | 3770 const char *suffix = ""; |
5051 #endif | 3771 #endif |
5052 Bool motif = False; | 3772 Bool motif = False; |
5053 #endif | 3773 #endif |
3774 | |
3775 if (! NILP (xlfd)) | |
3776 { | |
5054 #if defined HAVE_X_I18N | 3777 #if defined HAVE_X_I18N |
5055 extern char *xic_create_fontsetname | 3778 extern char *xic_create_fontsetname |
5056 P_ ((char *base_fontname, Bool motif)); | 3779 P_ ((char *base_fontname, Bool motif)); |
5057 char *fontsetname = xic_create_fontsetname (face->font_name, motif); | 3780 char *fontsetname = xic_create_fontsetname (SDATA (xlfd), motif); |
5058 #else | 3781 #else |
5059 char *fontsetname = face->font_name; | 3782 char *fontsetname = (char *) SDATA (xlfd); |
5060 #endif | 3783 #endif |
5061 sprintf (line, "%s.pane.menubar*font%s: %s", | 3784 sprintf (line, "%s.pane.menubar*font%s: %s", |
5062 myname, suffix, fontsetname); | 3785 myname, suffix, fontsetname); |
5063 XrmPutLineResource (&rdb, line); | 3786 XrmPutLineResource (&rdb, line); |
5064 sprintf (line, "%s.%s*font%s: %s", | 3787 sprintf (line, "%s.%s*font%s: %s", |
5065 myname, popup_path, suffix, fontsetname); | 3788 myname, popup_path, suffix, fontsetname); |
5066 XrmPutLineResource (&rdb, line); | 3789 XrmPutLineResource (&rdb, line); |
5067 changed_p = 1; | 3790 changed_p = 1; |
5068 if (fontsetname != face->font_name) | 3791 if (fontsetname != (char *) SDATA (xlfd)) |
5069 xfree (fontsetname); | 3792 xfree (fontsetname); |
3793 } | |
5070 } | 3794 } |
5071 | 3795 |
5072 if (changed_p && f->output_data.x->menubar_widget) | 3796 if (changed_p && f->output_data.x->menubar_widget) |
5073 free_frame_menubar (f); | 3797 free_frame_menubar (f); |
5074 } | 3798 } |
5196 { | 3920 { |
5197 Lisp_Object result = Qnil; | 3921 Lisp_Object result = Qnil; |
5198 | 3922 |
5199 CHECK_SYMBOL (attr); | 3923 CHECK_SYMBOL (attr); |
5200 | 3924 |
5201 if (EQ (attr, QCweight) | 3925 if (EQ (attr, QCunderline)) |
5202 || EQ (attr, QCslant) | |
5203 || EQ (attr, QCwidth)) | |
5204 { | |
5205 /* Extract permissible symbols from tables. */ | |
5206 struct table_entry *table; | |
5207 int i, dim; | |
5208 | |
5209 if (EQ (attr, QCweight)) | |
5210 table = weight_table, dim = DIM (weight_table); | |
5211 else if (EQ (attr, QCslant)) | |
5212 table = slant_table, dim = DIM (slant_table); | |
5213 else | |
5214 table = swidth_table, dim = DIM (swidth_table); | |
5215 | |
5216 for (i = 0; i < dim; ++i) | |
5217 { | |
5218 Lisp_Object symbol = *table[i].symbol; | |
5219 Lisp_Object tail = result; | |
5220 | |
5221 while (!NILP (tail) | |
5222 && !EQ (XCAR (tail), symbol)) | |
5223 tail = XCDR (tail); | |
5224 | |
5225 if (NILP (tail)) | |
5226 result = Fcons (symbol, result); | |
5227 } | |
5228 } | |
5229 else if (EQ (attr, QCunderline)) | |
5230 result = Fcons (Qt, Fcons (Qnil, Qnil)); | 3926 result = Fcons (Qt, Fcons (Qnil, Qnil)); |
5231 else if (EQ (attr, QCoverline)) | 3927 else if (EQ (attr, QCoverline)) |
5232 result = Fcons (Qt, Fcons (Qnil, Qnil)); | 3928 result = Fcons (Qt, Fcons (Qnil, Qnil)); |
5233 else if (EQ (attr, QCstrike_through)) | 3929 else if (EQ (attr, QCstrike_through)) |
5234 result = Fcons (Qt, Fcons (Qnil, Qnil)); | 3930 result = Fcons (Qt, Fcons (Qnil, Qnil)); |
5320 if (FRAME_WINDOW_P (f) && !NILP (character)) | 4016 if (FRAME_WINDOW_P (f) && !NILP (character)) |
5321 { | 4017 { |
5322 CHECK_CHARACTER (character); | 4018 CHECK_CHARACTER (character); |
5323 face_id = FACE_FOR_CHAR (f, face, XINT (character), -1, Qnil); | 4019 face_id = FACE_FOR_CHAR (f, face, XINT (character), -1, Qnil); |
5324 face = FACE_FROM_ID (f, face_id); | 4020 face = FACE_FROM_ID (f, face_id); |
5325 return (face->font && face->font_name | |
5326 ? build_string (face->font_name) | |
5327 : Qnil); | |
5328 } | 4021 } |
5329 #endif | 4022 #endif |
5330 return build_string (face->font_name); | 4023 return (face->font |
4024 ? face->font->props[FONT_NAME_INDEX] | |
4025 : Qnil); | |
5331 } | 4026 } |
5332 } | 4027 } |
5333 | 4028 |
5334 | 4029 |
5335 /* Compare face-attribute values v1 and v2 for equality. Value is non-zero if | 4030 /* Compare face-attribute values v1 and v2 for equality. Value is non-zero if |
5488 } | 4183 } |
5489 | 4184 |
5490 | 4185 |
5491 /* Return non-zero if LFACE1 and LFACE2 specify the same font (without | 4186 /* Return non-zero if LFACE1 and LFACE2 specify the same font (without |
5492 considering charsets/registries). They do if they specify the same | 4187 considering charsets/registries). They do if they specify the same |
5493 family, point size, weight, width, slant, font, and fontset. Both | 4188 family, point size, weight, width, slant, and font. Both |
5494 LFACE1 and LFACE2 must be fully-specified. */ | 4189 LFACE1 and LFACE2 must be fully-specified. */ |
5495 | 4190 |
5496 static INLINE int | 4191 static INLINE int |
5497 lface_same_font_attributes_p (lface1, lface2) | 4192 lface_same_font_attributes_p (lface1, lface2) |
5498 Lisp_Object *lface1, *lface2; | 4193 Lisp_Object *lface1, *lface2; |
5501 && lface_fully_specified_p (lface2)); | 4196 && lface_fully_specified_p (lface2)); |
5502 return (xstricmp (SDATA (lface1[LFACE_FAMILY_INDEX]), | 4197 return (xstricmp (SDATA (lface1[LFACE_FAMILY_INDEX]), |
5503 SDATA (lface2[LFACE_FAMILY_INDEX])) == 0 | 4198 SDATA (lface2[LFACE_FAMILY_INDEX])) == 0 |
5504 && EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX]) | 4199 && EQ (lface1[LFACE_HEIGHT_INDEX], lface2[LFACE_HEIGHT_INDEX]) |
5505 && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX]) | 4200 && EQ (lface1[LFACE_SWIDTH_INDEX], lface2[LFACE_SWIDTH_INDEX]) |
5506 && EQ (lface1[LFACE_AVGWIDTH_INDEX], lface2[LFACE_AVGWIDTH_INDEX]) | |
5507 && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX]) | 4201 && EQ (lface1[LFACE_WEIGHT_INDEX], lface2[LFACE_WEIGHT_INDEX]) |
5508 && EQ (lface1[LFACE_SLANT_INDEX], lface2[LFACE_SLANT_INDEX]) | 4202 && EQ (lface1[LFACE_SLANT_INDEX], lface2[LFACE_SLANT_INDEX]) |
5509 && (EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX]) | 4203 && EQ (lface1[LFACE_FONT_INDEX], lface2[LFACE_FONT_INDEX]) |
5510 || (STRINGP (lface1[LFACE_FONT_INDEX]) | |
5511 && STRINGP (lface2[LFACE_FONT_INDEX]) | |
5512 && ! xstricmp (SDATA (lface1[LFACE_FONT_INDEX]), | |
5513 SDATA (lface2[LFACE_FONT_INDEX])))) | |
5514 && (EQ (lface1[LFACE_FONTSET_INDEX], lface2[LFACE_FONTSET_INDEX]) | 4204 && (EQ (lface1[LFACE_FONTSET_INDEX], lface2[LFACE_FONTSET_INDEX]) |
5515 || (STRINGP (lface1[LFACE_FONTSET_INDEX]) | 4205 || (STRINGP (lface1[LFACE_FONTSET_INDEX]) |
5516 && STRINGP (lface2[LFACE_FONTSET_INDEX]) | 4206 && STRINGP (lface2[LFACE_FONTSET_INDEX]) |
5517 && ! xstricmp (SDATA (lface1[LFACE_FONTSET_INDEX]), | 4207 && ! xstricmp (SDATA (lface1[LFACE_FONTSET_INDEX]), |
5518 SDATA (lface2[LFACE_FONTSET_INDEX])))) | 4208 SDATA (lface2[LFACE_FONTSET_INDEX])))) |
5557 if (face->fontset >= 0 && face == face->ascii_face) | 4247 if (face->fontset >= 0 && face == face->ascii_face) |
5558 free_face_fontset (f, face); | 4248 free_face_fontset (f, face); |
5559 if (face->gc) | 4249 if (face->gc) |
5560 { | 4250 { |
5561 BLOCK_INPUT; | 4251 BLOCK_INPUT; |
5562 #ifdef USE_FONT_BACKEND | 4252 if (face->font) |
5563 if (enable_font_backend && face->font_info) | |
5564 font_done_for_face (f, face); | 4253 font_done_for_face (f, face); |
5565 #endif /* USE_FONT_BACKEND */ | |
5566 x_free_gc (f, face->gc); | 4254 x_free_gc (f, face->gc); |
5567 face->gc = 0; | 4255 face->gc = 0; |
5568 UNBLOCK_INPUT; | 4256 UNBLOCK_INPUT; |
5569 } | 4257 } |
5570 | 4258 |
5598 xgcv.foreground = face->foreground; | 4286 xgcv.foreground = face->foreground; |
5599 xgcv.background = face->background; | 4287 xgcv.background = face->background; |
5600 #ifdef HAVE_X_WINDOWS | 4288 #ifdef HAVE_X_WINDOWS |
5601 xgcv.graphics_exposures = False; | 4289 xgcv.graphics_exposures = False; |
5602 #endif | 4290 #endif |
5603 /* The font of FACE may be null if we couldn't load it. */ | |
5604 if (face->font) | |
5605 { | |
5606 #ifdef HAVE_X_WINDOWS | |
5607 #ifdef USE_FONT_BACKEND | |
5608 if (enable_font_backend) | |
5609 xgcv.font = FRAME_X_DISPLAY_INFO (f)->font->fid; | |
5610 else | |
5611 #endif | |
5612 xgcv.font = face->font->fid; | |
5613 #endif | |
5614 #ifdef WINDOWSNT | |
5615 xgcv.font = face->font; | |
5616 #endif | |
5617 #ifdef MAC_OS | |
5618 xgcv.font = face->font; | |
5619 #endif | |
5620 mask |= GCFont; | |
5621 } | |
5622 | 4291 |
5623 BLOCK_INPUT; | 4292 BLOCK_INPUT; |
5624 #ifdef HAVE_X_WINDOWS | 4293 #ifdef HAVE_X_WINDOWS |
5625 if (face->stipple) | 4294 if (face->stipple) |
5626 { | 4295 { |
5628 xgcv.stipple = x_bitmap_pixmap (f, face->stipple); | 4297 xgcv.stipple = x_bitmap_pixmap (f, face->stipple); |
5629 mask |= GCFillStyle | GCStipple; | 4298 mask |= GCFillStyle | GCStipple; |
5630 } | 4299 } |
5631 #endif | 4300 #endif |
5632 face->gc = x_create_gc (f, mask, &xgcv); | 4301 face->gc = x_create_gc (f, mask, &xgcv); |
5633 #ifdef USE_FONT_BACKEND | 4302 if (face->font) |
5634 if (enable_font_backend && face->font) | |
5635 font_prepare_for_face (f, face); | 4303 font_prepare_for_face (f, face); |
5636 #endif /* USE_FONT_BACKEND */ | |
5637 UNBLOCK_INPUT; | 4304 UNBLOCK_INPUT; |
5638 } | 4305 } |
5639 #endif /* HAVE_WINDOW_SYSTEM */ | 4306 #endif /* HAVE_WINDOW_SYSTEM */ |
5640 } | 4307 } |
5641 | 4308 |
5737 { | 4404 { |
5738 struct face *face = c->faces_by_id[i]; | 4405 struct face *face = c->faces_by_id[i]; |
5739 if (face && face->gc) | 4406 if (face && face->gc) |
5740 { | 4407 { |
5741 BLOCK_INPUT; | 4408 BLOCK_INPUT; |
5742 #ifdef USE_FONT_BACKEND | 4409 if (face->font) |
5743 if (enable_font_backend && face->font_info) | |
5744 font_done_for_face (c->f, face); | 4410 font_done_for_face (c->f, face); |
5745 #endif /* USE_FONT_BACKEND */ | |
5746 x_free_gc (c->f, face->gc); | 4411 x_free_gc (c->f, face->gc); |
5747 face->gc = 0; | 4412 face->gc = 0; |
5748 UNBLOCK_INPUT; | 4413 UNBLOCK_INPUT; |
5749 } | 4414 } |
5750 } | 4415 } |
6027 return face->id; | 4692 return face->id; |
6028 } | 4693 } |
6029 | 4694 |
6030 #ifdef HAVE_WINDOW_SYSTEM | 4695 #ifdef HAVE_WINDOW_SYSTEM |
6031 /* Look up a realized face that has the same attributes as BASE_FACE | 4696 /* Look up a realized face that has the same attributes as BASE_FACE |
6032 except for the font in the face cache of frame F. If FONT_ID is | 4697 except for the font in the face cache of frame F. If FONT-OBJECT |
6033 not negative, it is an ID number of an already opened font that is | 4698 is not nil, it is an already opened font. If FONT-OBJECT is nil, |
6034 used by the face. If FONT_ID is negative, the face has no font. | 4699 the face has no font. Value is the ID of the face found. If no |
6035 Value is the ID of the face found. If no suitable face is found, | 4700 suitable face is found, realize a new one. */ |
6036 realize a new one. */ | |
6037 | 4701 |
6038 int | 4702 int |
6039 lookup_non_ascii_face (f, font_id, base_face) | 4703 face_for_font (f, font_object, base_face) |
6040 struct frame *f; | 4704 struct frame *f; |
6041 int font_id; | 4705 Lisp_Object font_object; |
6042 struct face *base_face; | 4706 struct face *base_face; |
6043 { | 4707 { |
6044 struct face_cache *cache = FRAME_FACE_CACHE (f); | 4708 struct face_cache *cache = FRAME_FACE_CACHE (f); |
6045 unsigned hash; | 4709 unsigned hash; |
6046 int i; | 4710 int i; |
6054 for (face = cache->buckets[i]; face; face = face->next) | 4718 for (face = cache->buckets[i]; face; face = face->next) |
6055 { | 4719 { |
6056 if (face->ascii_face == face) | 4720 if (face->ascii_face == face) |
6057 continue; | 4721 continue; |
6058 if (face->ascii_face == base_face | 4722 if (face->ascii_face == base_face |
6059 && face->font_info_id == font_id) | 4723 && face->font == (NILP (font_object) ? NULL |
6060 break; | 4724 : XFONT_OBJECT (font_object)) |
4725 && lface_equal_p (face->lface, base_face->lface)) | |
4726 return face->id; | |
6061 } | 4727 } |
6062 | 4728 |
6063 /* If not found, realize a new face. */ | 4729 /* If not found, realize a new face. */ |
6064 if (face == NULL) | 4730 face = realize_non_ascii_face (f, font_object, base_face); |
6065 face = realize_non_ascii_face (f, font_id, base_face); | |
6066 | |
6067 #if GLYPH_DEBUG | |
6068 xassert (face == FACE_FROM_ID (f, face->id)); | |
6069 #endif /* GLYPH_DEBUG */ | |
6070 | |
6071 return face->id; | 4731 return face->id; |
6072 } | 4732 } |
6073 | |
6074 #ifdef USE_FONT_BACKEND | |
6075 int | |
6076 face_for_font (f, font, base_face) | |
6077 struct frame *f; | |
6078 struct font *font; | |
6079 struct face *base_face; | |
6080 { | |
6081 struct face_cache *cache = FRAME_FACE_CACHE (f); | |
6082 unsigned hash; | |
6083 int i; | |
6084 struct face *face; | |
6085 | |
6086 xassert (cache != NULL); | |
6087 base_face = base_face->ascii_face; | |
6088 hash = lface_hash (base_face->lface); | |
6089 i = hash % FACE_CACHE_BUCKETS_SIZE; | |
6090 | |
6091 for (face = cache->buckets[i]; face; face = face->next) | |
6092 { | |
6093 if (face->ascii_face == face) | |
6094 continue; | |
6095 if (face->ascii_face == base_face | |
6096 && face->font == font->font.font | |
6097 && face->font_info == (struct font_info *) font) | |
6098 return face->id; | |
6099 } | |
6100 | |
6101 /* If not found, realize a new face. */ | |
6102 face = realize_non_ascii_face (f, -1, base_face); | |
6103 face->font = font->font.font; | |
6104 face->font_info = (struct font_info *) font; | |
6105 face->font_info_id = 0; | |
6106 face->font_name = font->font.full_name; | |
6107 return face->id; | |
6108 } | |
6109 #endif /* USE_FONT_BACKEND */ | |
6110 | |
6111 #endif /* HAVE_WINDOW_SYSTEM */ | 4733 #endif /* HAVE_WINDOW_SYSTEM */ |
6112 | 4734 |
6113 /* Return the face id of the realized face for named face SYMBOL on | 4735 /* Return the face id of the realized face for named face SYMBOL on |
6114 frame F suitable for displaying ASCII characters. Value is -1 if | 4736 frame F suitable for displaying ASCII characters. Value is -1 if |
6115 the face couldn't be determined, which might happen if the default | 4737 the face couldn't be determined, which might happen if the default |
6361 "unsupported" on a window-system (because of missing fonts). */ | 4983 "unsupported" on a window-system (because of missing fonts). */ |
6362 if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX]) | 4984 if (!UNSPECIFIEDP (attrs[LFACE_FAMILY_INDEX]) |
6363 || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX]) | 4985 || !UNSPECIFIEDP (attrs[LFACE_HEIGHT_INDEX]) |
6364 || !UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX]) | 4986 || !UNSPECIFIEDP (attrs[LFACE_WEIGHT_INDEX]) |
6365 || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX]) | 4987 || !UNSPECIFIEDP (attrs[LFACE_SLANT_INDEX]) |
6366 || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX]) | 4988 || !UNSPECIFIEDP (attrs[LFACE_SWIDTH_INDEX])) |
6367 || !UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX])) | |
6368 { | 4989 { |
6369 int face_id; | 4990 int face_id; |
6370 struct face *face; | 4991 struct face *face; |
6371 Lisp_Object merged_attrs[LFACE_VECTOR_SIZE]; | 4992 Lisp_Object merged_attrs[LFACE_VECTOR_SIZE]; |
4993 int i; | |
6372 | 4994 |
6373 bcopy (def_attrs, merged_attrs, sizeof merged_attrs); | 4995 bcopy (def_attrs, merged_attrs, sizeof merged_attrs); |
6374 | 4996 |
6375 merge_face_vectors (f, attrs, merged_attrs, 0); | 4997 merge_face_vectors (f, attrs, merged_attrs, 0); |
6376 | 4998 |
6381 error ("Cannot make face"); | 5003 error ("Cannot make face"); |
6382 | 5004 |
6383 /* If the font is the same, then not supported. */ | 5005 /* If the font is the same, then not supported. */ |
6384 if (face->font == def_face->font) | 5006 if (face->font == def_face->font) |
6385 return 0; | 5007 return 0; |
5008 for (i = FONT_TYPE_INDEX; i <= FONT_SIZE_INDEX; i++) | |
5009 if (! EQ (face->font->props[i], def_face->font->props[i])) | |
5010 { | |
5011 Lisp_Object s1, s2; | |
5012 | |
5013 if (i < FONT_FOUNDRY_INDEX || i > FONT_REGISTRY_INDEX | |
5014 || face->font->driver->case_sensitive) | |
5015 return 1; | |
5016 s1 = SYMBOL_NAME (face->font->props[i]); | |
5017 s2 = SYMBOL_NAME (def_face->font->props[i]); | |
5018 if (! EQ (Fcompare_strings (s1, make_number (0), Qnil, | |
5019 s2, make_number (0), Qnil, Qt), Qt)) | |
5020 return 1; | |
5021 } | |
5022 return 0; | |
6386 } | 5023 } |
6387 | 5024 |
6388 /* Everything checks out, this face is supported. */ | 5025 /* Everything checks out, this face is supported. */ |
6389 return 1; | 5026 return 1; |
6390 } | 5027 } |
6441 | 5078 |
6442 | 5079 |
6443 /* Test for terminal `capabilities' (non-color character attributes). */ | 5080 /* Test for terminal `capabilities' (non-color character attributes). */ |
6444 | 5081 |
6445 /* font weight (bold/dim) */ | 5082 /* font weight (bold/dim) */ |
6446 weight = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]); | 5083 weight = FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]); |
6447 if (weight >= 0) | 5084 if (weight >= 0) |
6448 { | 5085 { |
6449 int def_weight = face_numeric_weight (def_attrs[LFACE_WEIGHT_INDEX]); | 5086 int def_weight = FONT_WEIGHT_NAME_NUMERIC (def_attrs[LFACE_WEIGHT_INDEX]); |
6450 | 5087 |
6451 if (weight > XLFD_WEIGHT_MEDIUM) | 5088 if (weight > 100) |
6452 { | 5089 { |
6453 if (def_weight > XLFD_WEIGHT_MEDIUM) | 5090 if (def_weight > 100) |
6454 return 0; /* same as default */ | 5091 return 0; /* same as default */ |
6455 test_caps = TTY_CAP_BOLD; | 5092 test_caps = TTY_CAP_BOLD; |
6456 } | 5093 } |
6457 else if (weight < XLFD_WEIGHT_MEDIUM) | 5094 else if (weight < 100) |
6458 { | 5095 { |
6459 if (def_weight < XLFD_WEIGHT_MEDIUM) | 5096 if (def_weight < 100) |
6460 return 0; /* same as default */ | 5097 return 0; /* same as default */ |
6461 test_caps = TTY_CAP_DIM; | 5098 test_caps = TTY_CAP_DIM; |
6462 } | 5099 } |
6463 else if (def_weight == XLFD_WEIGHT_MEDIUM) | 5100 else if (def_weight == 100) |
6464 return 0; /* same as default */ | 5101 return 0; /* same as default */ |
6465 } | 5102 } |
6466 | 5103 |
6467 /* underlining */ | 5104 /* underlining */ |
6468 val = attrs[LFACE_UNDERLINE_INDEX]; | 5105 val = attrs[LFACE_UNDERLINE_INDEX]; |
6711 { | 5348 { |
6712 bcopy (indices, font_sort_order, sizeof font_sort_order); | 5349 bcopy (indices, font_sort_order, sizeof font_sort_order); |
6713 free_all_realized_faces (Qnil); | 5350 free_all_realized_faces (Qnil); |
6714 } | 5351 } |
6715 | 5352 |
6716 #ifdef USE_FONT_BACKEND | 5353 font_update_sort_order (font_sort_order); |
6717 if (enable_font_backend) | |
6718 font_update_sort_order (font_sort_order); | |
6719 #endif /* USE_FONT_BACKEND */ | |
6720 | 5354 |
6721 return Qnil; | 5355 return Qnil; |
6722 } | 5356 } |
6723 | 5357 |
6724 | 5358 |
6756 } | 5390 } |
6757 | 5391 |
6758 | 5392 |
6759 #ifdef HAVE_WINDOW_SYSTEM | 5393 #ifdef HAVE_WINDOW_SYSTEM |
6760 | 5394 |
6761 /* Value is non-zero if FONT is the name of a scalable font. The | |
6762 X11R6 XLFD spec says that point size, pixel size, and average width | |
6763 are zero for scalable fonts. Intlfonts contain at least one | |
6764 scalable font ("*-muleindian-1") for which this isn't true, so we | |
6765 just test average width. */ | |
6766 | |
6767 static int | |
6768 font_scalable_p (font) | |
6769 struct font_name *font; | |
6770 { | |
6771 char *s = font->fields[XLFD_AVGWIDTH]; | |
6772 return (*s == '0' && *(s + 1) == '\0') | |
6773 #ifdef WINDOWSNT | |
6774 /* Windows implementation of XLFD is slightly broken for backward | |
6775 compatibility with previous broken versions, so test for | |
6776 wildcards as well as 0. */ | |
6777 || *s == '*' | |
6778 #endif | |
6779 ; | |
6780 } | |
6781 | |
6782 | |
6783 /* Ignore the difference of font point size less than this value. */ | 5395 /* Ignore the difference of font point size less than this value. */ |
6784 | 5396 |
6785 #define FONT_POINT_SIZE_QUANTUM 5 | 5397 #define FONT_POINT_SIZE_QUANTUM 5 |
6786 | |
6787 /* Value is non-zero if FONT1 is a better match for font attributes | |
6788 VALUES than FONT2. VALUES is an array of face attribute values in | |
6789 font sort order. COMPARE_PT_P zero means don't compare point | |
6790 sizes. AVGWIDTH, if not zero, is a specified font average width | |
6791 to compare with. */ | |
6792 | |
6793 static int | |
6794 better_font_p (values, font1, font2, compare_pt_p, avgwidth) | |
6795 int *values; | |
6796 struct font_name *font1, *font2; | |
6797 int compare_pt_p, avgwidth; | |
6798 { | |
6799 int i; | |
6800 | |
6801 /* Any font is better than no font. */ | |
6802 if (! font1) | |
6803 return 0; | |
6804 if (! font2) | |
6805 return 1; | |
6806 | |
6807 for (i = 0; i < DIM (font_sort_order); ++i) | |
6808 { | |
6809 int xlfd_idx = font_sort_order[i]; | |
6810 | |
6811 if (compare_pt_p || xlfd_idx != XLFD_POINT_SIZE) | |
6812 { | |
6813 int delta1, delta2; | |
6814 | |
6815 if (xlfd_idx == XLFD_POINT_SIZE) | |
6816 { | |
6817 delta1 = eabs (values[i] - (font1->numeric[xlfd_idx] | |
6818 / font1->rescale_ratio)); | |
6819 delta2 = eabs (values[i] - (font2->numeric[xlfd_idx] | |
6820 / font2->rescale_ratio)); | |
6821 if (eabs (delta1 - delta2) < FONT_POINT_SIZE_QUANTUM) | |
6822 continue; | |
6823 } | |
6824 else | |
6825 { | |
6826 delta1 = eabs (values[i] - font1->numeric[xlfd_idx]); | |
6827 delta2 = eabs (values[i] - font2->numeric[xlfd_idx]); | |
6828 } | |
6829 | |
6830 if (delta1 > delta2) | |
6831 return 0; | |
6832 else if (delta1 < delta2) | |
6833 return 1; | |
6834 else | |
6835 { | |
6836 /* The difference may be equal because, e.g., the face | |
6837 specifies `italic' but we have only `regular' and | |
6838 `oblique'. Prefer `oblique' in this case. */ | |
6839 if ((xlfd_idx == XLFD_WEIGHT || xlfd_idx == XLFD_SLANT) | |
6840 && font1->numeric[xlfd_idx] > values[i] | |
6841 && font2->numeric[xlfd_idx] < values[i]) | |
6842 return 1; | |
6843 } | |
6844 } | |
6845 } | |
6846 | |
6847 if (avgwidth) | |
6848 { | |
6849 int delta1 = eabs (avgwidth - font1->numeric[XLFD_AVGWIDTH]); | |
6850 int delta2 = eabs (avgwidth - font2->numeric[XLFD_AVGWIDTH]); | |
6851 if (delta1 > delta2) | |
6852 return 0; | |
6853 else if (delta1 < delta2) | |
6854 return 1; | |
6855 } | |
6856 | |
6857 if (! compare_pt_p) | |
6858 { | |
6859 /* We prefer a real scalable font; i.e. not what autoscaled. */ | |
6860 int auto_scaled_1 = (font1->numeric[XLFD_POINT_SIZE] == 0 | |
6861 && font1->numeric[XLFD_RESY] > 0); | |
6862 int auto_scaled_2 = (font2->numeric[XLFD_POINT_SIZE] == 0 | |
6863 && font2->numeric[XLFD_RESY] > 0); | |
6864 | |
6865 if (auto_scaled_1 != auto_scaled_2) | |
6866 return auto_scaled_2; | |
6867 } | |
6868 | |
6869 return font1->registry_priority < font2->registry_priority; | |
6870 } | |
6871 | |
6872 | |
6873 /* Value is non-zero if FONT is an exact match for face attributes in | |
6874 SPECIFIED. SPECIFIED is an array of face attribute values in font | |
6875 sort order. AVGWIDTH, if non-zero, is an average width to compare | |
6876 with. */ | |
6877 | |
6878 static int | |
6879 exact_face_match_p (specified, font, avgwidth) | |
6880 int *specified; | |
6881 struct font_name *font; | |
6882 int avgwidth; | |
6883 { | |
6884 int i; | |
6885 | |
6886 for (i = 0; i < DIM (font_sort_order); ++i) | |
6887 if (specified[i] != font->numeric[font_sort_order[i]]) | |
6888 break; | |
6889 | |
6890 return (i == DIM (font_sort_order) | |
6891 && (avgwidth <= 0 | |
6892 || avgwidth == font->numeric[XLFD_AVGWIDTH])); | |
6893 } | |
6894 | |
6895 | |
6896 /* Value is the name of a scaled font, generated from scalable font | |
6897 FONT on frame F. SPECIFIED_PT is the point-size to scale FONT to. | |
6898 Value is allocated from heap. */ | |
6899 | |
6900 static char * | |
6901 build_scalable_font_name (f, font, specified_pt) | |
6902 struct frame *f; | |
6903 struct font_name *font; | |
6904 int specified_pt; | |
6905 { | |
6906 char pixel_size[20]; | |
6907 int pixel_value; | |
6908 double resy = FRAME_X_DISPLAY_INFO (f)->resy; | |
6909 double pt; | |
6910 | |
6911 if (font->numeric[XLFD_PIXEL_SIZE] != 0 | |
6912 || font->numeric[XLFD_POINT_SIZE] != 0) | |
6913 /* This is a scalable font but is requested for a specific size. | |
6914 We should not change that size. */ | |
6915 return build_font_name (font); | |
6916 | |
6917 /* If scalable font is for a specific resolution, compute | |
6918 the point size we must specify from the resolution of | |
6919 the display and the specified resolution of the font. */ | |
6920 if (font->numeric[XLFD_RESY] != 0) | |
6921 { | |
6922 pt = resy / font->numeric[XLFD_RESY] * specified_pt + 0.5; | |
6923 pixel_value = font->numeric[XLFD_RESY] / (PT_PER_INCH * 10.0) * pt + 0.5; | |
6924 } | |
6925 else | |
6926 { | |
6927 pt = specified_pt; | |
6928 pixel_value = resy / (PT_PER_INCH * 10.0) * pt + 0.5; | |
6929 } | |
6930 /* We may need a font of the different size. */ | |
6931 pixel_value *= font->rescale_ratio; | |
6932 | |
6933 /* We should keep POINT_SIZE 0. Otherwise, X server can't open a | |
6934 font of the specified PIXEL_SIZE. */ | |
6935 #if 0 | |
6936 { /* Set point size of the font. */ | |
6937 char point_size[20]; | |
6938 sprintf (point_size, "%d", (int) pt); | |
6939 font->fields[XLFD_POINT_SIZE] = point_size; | |
6940 font->numeric[XLFD_POINT_SIZE] = pt; | |
6941 } | |
6942 #endif | |
6943 | |
6944 /* Set pixel size. */ | |
6945 sprintf (pixel_size, "%d", pixel_value); | |
6946 font->fields[XLFD_PIXEL_SIZE] = pixel_size; | |
6947 font->numeric[XLFD_PIXEL_SIZE] = pixel_value; | |
6948 | |
6949 /* If font doesn't specify its resolution, use the | |
6950 resolution of the display. */ | |
6951 if (font->numeric[XLFD_RESY] == 0) | |
6952 { | |
6953 char buffer[20]; | |
6954 sprintf (buffer, "%d", (int) resy); | |
6955 font->fields[XLFD_RESY] = buffer; | |
6956 font->numeric[XLFD_RESY] = resy; | |
6957 } | |
6958 | |
6959 if (strcmp (font->fields[XLFD_RESX], "0") == 0) | |
6960 { | |
6961 char buffer[20]; | |
6962 int resx = FRAME_X_DISPLAY_INFO (f)->resx; | |
6963 sprintf (buffer, "%d", resx); | |
6964 font->fields[XLFD_RESX] = buffer; | |
6965 font->numeric[XLFD_RESX] = resx; | |
6966 } | |
6967 | |
6968 return build_font_name (font); | |
6969 } | |
6970 | |
6971 | |
6972 /* Value is non-zero if we are allowed to use scalable font FONT. We | |
6973 can't run a Lisp function here since this function may be called | |
6974 with input blocked. */ | |
6975 | |
6976 static int | |
6977 may_use_scalable_font_p (font) | |
6978 const char *font; | |
6979 { | |
6980 if (EQ (Vscalable_fonts_allowed, Qt)) | |
6981 return 1; | |
6982 else if (CONSP (Vscalable_fonts_allowed)) | |
6983 { | |
6984 Lisp_Object tail, regexp; | |
6985 | |
6986 for (tail = Vscalable_fonts_allowed; CONSP (tail); tail = XCDR (tail)) | |
6987 { | |
6988 regexp = XCAR (tail); | |
6989 if (STRINGP (regexp) | |
6990 && fast_c_string_match_ignore_case (regexp, font) >= 0) | |
6991 return 1; | |
6992 } | |
6993 } | |
6994 | |
6995 return 0; | |
6996 } | |
6997 | |
6998 | |
6999 | |
7000 /* Return the name of the best matching font for face attributes ATTRS | |
7001 in the array of font_name structures FONTS which contains NFONTS | |
7002 elements. WIDTH_RATIO is a factor with which to multiply average | |
7003 widths if ATTRS specifies such a width. | |
7004 | |
7005 Value is a font name which is allocated from the heap. FONTS is | |
7006 freed by this function. | |
7007 | |
7008 If NEEDS_OVERSTRIKE is non-zero, a boolean is returned in it to | |
7009 indicate whether the resulting font should be drawn using overstrike | |
7010 to simulate bold-face. */ | |
7011 | |
7012 static char * | |
7013 best_matching_font (f, attrs, fonts, nfonts, width_ratio, needs_overstrike) | |
7014 struct frame *f; | |
7015 Lisp_Object *attrs; | |
7016 struct font_name *fonts; | |
7017 int nfonts; | |
7018 int width_ratio; | |
7019 int *needs_overstrike; | |
7020 { | |
7021 char *font_name; | |
7022 struct font_name *best; | |
7023 int i, pt = 0; | |
7024 int specified[5]; | |
7025 int exact_p, avgwidth; | |
7026 | |
7027 if (nfonts == 0) | |
7028 return NULL; | |
7029 | |
7030 /* Make specified font attributes available in `specified', | |
7031 indexed by sort order. */ | |
7032 for (i = 0; i < DIM (font_sort_order); ++i) | |
7033 { | |
7034 int xlfd_idx = font_sort_order[i]; | |
7035 | |
7036 if (xlfd_idx == XLFD_SWIDTH) | |
7037 specified[i] = face_numeric_swidth (attrs[LFACE_SWIDTH_INDEX]); | |
7038 else if (xlfd_idx == XLFD_POINT_SIZE) | |
7039 specified[i] = pt = XFASTINT (attrs[LFACE_HEIGHT_INDEX]); | |
7040 else if (xlfd_idx == XLFD_WEIGHT) | |
7041 specified[i] = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]); | |
7042 else if (xlfd_idx == XLFD_SLANT) | |
7043 specified[i] = face_numeric_slant (attrs[LFACE_SLANT_INDEX]); | |
7044 else | |
7045 abort (); | |
7046 } | |
7047 | |
7048 avgwidth = (UNSPECIFIEDP (attrs[LFACE_AVGWIDTH_INDEX]) | |
7049 ? 0 | |
7050 : XFASTINT (attrs[LFACE_AVGWIDTH_INDEX]) * width_ratio); | |
7051 | |
7052 exact_p = 0; | |
7053 | |
7054 if (needs_overstrike) | |
7055 *needs_overstrike = 0; | |
7056 | |
7057 best = NULL; | |
7058 | |
7059 /* Find the best match among the non-scalable fonts. */ | |
7060 for (i = 0; i < nfonts; ++i) | |
7061 if (!font_scalable_p (fonts + i) | |
7062 && better_font_p (specified, fonts + i, best, 1, avgwidth)) | |
7063 { | |
7064 best = fonts + i; | |
7065 | |
7066 exact_p = exact_face_match_p (specified, best, avgwidth); | |
7067 if (exact_p) | |
7068 break; | |
7069 } | |
7070 | |
7071 /* Unless we found an exact match among non-scalable fonts, see if | |
7072 we can find a better match among scalable fonts. */ | |
7073 if (!exact_p) | |
7074 { | |
7075 /* A scalable font is better if | |
7076 | |
7077 1. its weight, slant, swidth attributes are better, or. | |
7078 | |
7079 2. the best non-scalable font doesn't have the required | |
7080 point size, and the scalable fonts weight, slant, swidth | |
7081 isn't worse. */ | |
7082 | |
7083 int non_scalable_has_exact_height_p; | |
7084 | |
7085 if (best && best->numeric[XLFD_POINT_SIZE] == pt) | |
7086 non_scalable_has_exact_height_p = 1; | |
7087 else | |
7088 non_scalable_has_exact_height_p = 0; | |
7089 | |
7090 for (i = 0; i < nfonts; ++i) | |
7091 if (font_scalable_p (fonts + i)) | |
7092 { | |
7093 if (better_font_p (specified, fonts + i, best, 0, 0) | |
7094 || (!non_scalable_has_exact_height_p | |
7095 && !better_font_p (specified, best, fonts + i, 0, 0))) | |
7096 { | |
7097 non_scalable_has_exact_height_p = 1; | |
7098 best = fonts + i; | |
7099 } | |
7100 } | |
7101 } | |
7102 | |
7103 /* We should have found SOME font. */ | |
7104 if (best == NULL) | |
7105 abort (); | |
7106 | |
7107 if (! exact_p && needs_overstrike) | |
7108 { | |
7109 enum xlfd_weight want_weight = specified[XLFD_WEIGHT]; | |
7110 enum xlfd_weight got_weight = best->numeric[XLFD_WEIGHT]; | |
7111 | |
7112 if (want_weight > XLFD_WEIGHT_MEDIUM && want_weight > got_weight) | |
7113 { | |
7114 /* We want a bold font, but didn't get one; try to use | |
7115 overstriking instead to simulate bold-face. However, | |
7116 don't overstrike an already-bold font unless the | |
7117 desired weight grossly exceeds the available weight. */ | |
7118 if (got_weight > XLFD_WEIGHT_MEDIUM) | |
7119 *needs_overstrike = (want_weight - got_weight) > 2; | |
7120 else | |
7121 *needs_overstrike = 1; | |
7122 } | |
7123 } | |
7124 | |
7125 if (font_scalable_p (best)) | |
7126 font_name = build_scalable_font_name (f, best, pt); | |
7127 else | |
7128 font_name = build_font_name (best); | |
7129 | |
7130 /* Free font_name structures. */ | |
7131 free_font_names (fonts, nfonts); | |
7132 | |
7133 return font_name; | |
7134 } | |
7135 | |
7136 | |
7137 /* Get a list of matching fonts on frame F, considering FAMILY | |
7138 and alternative font families from Vface_alternative_font_registry_alist. | |
7139 | |
7140 FAMILY is the font family whose alternatives are considered. | |
7141 | |
7142 REGISTRY, if a string, specifies a font registry and encoding to | |
7143 match. A value of nil means include fonts of any registry and | |
7144 encoding. | |
7145 | |
7146 Return in *FONTS a pointer to a vector of font_name structures for | |
7147 the fonts matched. Value is the number of fonts found. */ | |
7148 | |
7149 static int | |
7150 try_alternative_families (f, family, registry, fonts) | |
7151 struct frame *f; | |
7152 Lisp_Object family, registry; | |
7153 struct font_name **fonts; | |
7154 { | |
7155 Lisp_Object alter; | |
7156 int nfonts = 0; | |
7157 | |
7158 nfonts = font_list (f, Qnil, family, registry, fonts); | |
7159 if (nfonts == 0) | |
7160 { | |
7161 /* Try alternative font families. */ | |
7162 alter = Fassoc (family, Vface_alternative_font_family_alist); | |
7163 if (CONSP (alter)) | |
7164 { | |
7165 for (alter = XCDR (alter); | |
7166 CONSP (alter) && nfonts == 0; | |
7167 alter = XCDR (alter)) | |
7168 { | |
7169 if (STRINGP (XCAR (alter))) | |
7170 nfonts = font_list (f, Qnil, XCAR (alter), registry, fonts); | |
7171 } | |
7172 } | |
7173 | |
7174 /* Try all scalable fonts before giving up. */ | |
7175 if (nfonts == 0 && ! EQ (Vscalable_fonts_allowed, Qt)) | |
7176 { | |
7177 int count = SPECPDL_INDEX (); | |
7178 specbind (Qscalable_fonts_allowed, Qt); | |
7179 nfonts = try_alternative_families (f, family, registry, fonts); | |
7180 unbind_to (count, Qnil); | |
7181 } | |
7182 } | |
7183 return nfonts; | |
7184 } | |
7185 | |
7186 | |
7187 /* Get a list of matching fonts on frame F. | |
7188 | |
7189 PATTERN, if a string, specifies a font name pattern to match while | |
7190 ignoring FAMILY and REGISTRY. | |
7191 | |
7192 FAMILY, if a list, specifies a list of font families to try. | |
7193 | |
7194 REGISTRY, if a list, specifies a list of font registries and | |
7195 encodinging to try. | |
7196 | |
7197 Return in *FONTS a pointer to a vector of font_name structures for | |
7198 the fonts matched. Value is the number of fonts found. */ | |
7199 | |
7200 static int | |
7201 try_font_list (f, pattern, family, registry, fonts) | |
7202 struct frame *f; | |
7203 Lisp_Object pattern, family, registry; | |
7204 struct font_name **fonts; | |
7205 { | |
7206 int nfonts = 0; | |
7207 | |
7208 if (STRINGP (pattern)) | |
7209 { | |
7210 nfonts = font_list (f, pattern, Qnil, Qnil, fonts); | |
7211 if (nfonts == 0 && ! EQ (Vscalable_fonts_allowed, Qt)) | |
7212 { | |
7213 int count = SPECPDL_INDEX (); | |
7214 specbind (Qscalable_fonts_allowed, Qt); | |
7215 nfonts = font_list (f, pattern, Qnil, Qnil, fonts); | |
7216 unbind_to (count, Qnil); | |
7217 } | |
7218 } | |
7219 else | |
7220 { | |
7221 Lisp_Object tail; | |
7222 | |
7223 if (NILP (family)) | |
7224 nfonts = font_list (f, Qnil, Qnil, registry, fonts); | |
7225 else | |
7226 for (tail = family; ! nfonts && CONSP (tail); tail = XCDR (tail)) | |
7227 nfonts = try_alternative_families (f, XCAR (tail), registry, fonts); | |
7228 | |
7229 /* Try font family of the default face or "fixed". */ | |
7230 if (nfonts == 0 && !NILP (family)) | |
7231 { | |
7232 struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); | |
7233 if (default_face) | |
7234 family = default_face->lface[LFACE_FAMILY_INDEX]; | |
7235 else | |
7236 family = build_string ("fixed"); | |
7237 nfonts = try_alternative_families (f, family, registry, fonts); | |
7238 } | |
7239 | |
7240 /* Try any family with the given registry. */ | |
7241 if (nfonts == 0 && !NILP (family)) | |
7242 nfonts = try_alternative_families (f, Qnil, registry, fonts); | |
7243 } | |
7244 | |
7245 return nfonts; | |
7246 } | |
7247 | |
7248 | 5398 |
7249 /* Return the fontset id of the base fontset name or alias name given | 5399 /* Return the fontset id of the base fontset name or alias name given |
7250 by the fontset attribute of ATTRS. Value is -1 if the fontset | 5400 by the fontset attribute of ATTRS. Value is -1 if the fontset |
7251 attribute of ATTRS doesn't name a fontset. */ | 5401 attribute of ATTRS doesn't name a fontset. */ |
7252 | 5402 |
7258 | 5408 |
7259 name = attrs[LFACE_FONTSET_INDEX]; | 5409 name = attrs[LFACE_FONTSET_INDEX]; |
7260 if (!STRINGP (name)) | 5410 if (!STRINGP (name)) |
7261 return -1; | 5411 return -1; |
7262 return fs_query_fontset (name, 0); | 5412 return fs_query_fontset (name, 0); |
7263 } | |
7264 | |
7265 | |
7266 /* Choose a name of font to use on frame F to display characters with | |
7267 Lisp face attributes specified by ATTRS. The font name is | |
7268 determined by the font-related attributes in ATTRS and FONT-SPEC | |
7269 (if specified). | |
7270 | |
7271 When we are choosing a font for ASCII characters, FONT-SPEC is | |
7272 always nil. Otherwise FONT-SPEC is an object created by | |
7273 `font-spec' or a string specifying a font name pattern. | |
7274 | |
7275 If NEEDS_OVERSTRIKE is not NULL, a boolean is returned in it to | |
7276 indicate whether the resulting font should be drawn using | |
7277 overstrike to simulate bold-face. | |
7278 | |
7279 Value is the font name which is allocated from the heap and must be | |
7280 freed by the caller. */ | |
7281 | |
7282 char * | |
7283 choose_face_font (f, attrs, font_spec, needs_overstrike) | |
7284 struct frame *f; | |
7285 Lisp_Object *attrs; | |
7286 Lisp_Object font_spec; | |
7287 int *needs_overstrike; | |
7288 { | |
7289 Lisp_Object pattern, family, adstyle, registry; | |
7290 char *font_name = NULL; | |
7291 struct font_name *fonts; | |
7292 int nfonts; | |
7293 | |
7294 if (needs_overstrike) | |
7295 *needs_overstrike = 0; | |
7296 | |
7297 /* If we are choosing an ASCII font and a font name is explicitly | |
7298 specified in ATTRS, return it. */ | |
7299 if (NILP (font_spec) && STRINGP (attrs[LFACE_FONT_INDEX])) | |
7300 return xstrdup (SDATA (attrs[LFACE_FONT_INDEX])); | |
7301 | |
7302 if (NILP (attrs[LFACE_FAMILY_INDEX])) | |
7303 family = Qnil; | |
7304 else | |
7305 family = Fcons (attrs[LFACE_FAMILY_INDEX], Qnil); | |
7306 | |
7307 /* Decide FAMILY, ADSTYLE, and REGISTRY from FONT_SPEC. But, | |
7308 ADSTYLE is not used in the font selector for the moment. */ | |
7309 if (VECTORP (font_spec)) | |
7310 { | |
7311 pattern = Qnil; | |
7312 if (! NILP (AREF (font_spec, FONT_FAMILY_INDEX))) | |
7313 family = Fcons (SYMBOL_NAME (AREF (font_spec, FONT_FAMILY_INDEX)), | |
7314 family); | |
7315 adstyle = AREF (font_spec, FONT_ADSTYLE_INDEX); | |
7316 registry = Fcons (SYMBOL_NAME (AREF (font_spec, FONT_REGISTRY_INDEX)), | |
7317 Qnil); | |
7318 } | |
7319 else if (STRINGP (font_spec)) | |
7320 { | |
7321 pattern = font_spec; | |
7322 family = Qnil; | |
7323 adstyle = Qnil; | |
7324 registry = Qnil; | |
7325 } | |
7326 else | |
7327 { | |
7328 /* We are choosing an ASCII font. By default, use the registry | |
7329 name "iso8859-1". But, if the registry name of the ASCII | |
7330 font specified in the fontset of ATTRS is not "iso8859-1" | |
7331 (e.g "iso10646-1"), use also that name with higher | |
7332 priority. */ | |
7333 int fontset = face_fontset (attrs); | |
7334 Lisp_Object ascii; | |
7335 int len; | |
7336 struct font_name font; | |
7337 | |
7338 pattern = Qnil; | |
7339 adstyle = Qnil; | |
7340 registry = Fcons (build_string ("iso8859-1"), Qnil); | |
7341 | |
7342 ascii = fontset_ascii (fontset); | |
7343 len = SBYTES (ascii); | |
7344 if (len < 9 | |
7345 || strcmp (SDATA (ascii) + len - 9, "iso8859-1")) | |
7346 { | |
7347 font.name = LSTRDUPA (ascii); | |
7348 /* Check if the name is in XLFD. */ | |
7349 if (split_font_name (f, &font, 0)) | |
7350 { | |
7351 font.fields[XLFD_ENCODING][-1] = '-'; | |
7352 registry = Fcons (build_string (font.fields[XLFD_REGISTRY]), | |
7353 registry); | |
7354 } | |
7355 } | |
7356 } | |
7357 | |
7358 /* Get a list of fonts matching that pattern and choose the | |
7359 best match for the specified face attributes from it. */ | |
7360 nfonts = try_font_list (f, pattern, family, registry, &fonts); | |
7361 font_name = best_matching_font (f, attrs, fonts, nfonts, NILP (font_spec), | |
7362 needs_overstrike); | |
7363 return font_name; | |
7364 } | 5413 } |
7365 | 5414 |
7366 #endif /* HAVE_WINDOW_SYSTEM */ | 5415 #endif /* HAVE_WINDOW_SYSTEM */ |
7367 | 5416 |
7368 | 5417 |
7429 struct frame *f; | 5478 struct frame *f; |
7430 { | 5479 { |
7431 struct face_cache *c = FRAME_FACE_CACHE (f); | 5480 struct face_cache *c = FRAME_FACE_CACHE (f); |
7432 Lisp_Object lface; | 5481 Lisp_Object lface; |
7433 Lisp_Object attrs[LFACE_VECTOR_SIZE]; | 5482 Lisp_Object attrs[LFACE_VECTOR_SIZE]; |
7434 Lisp_Object frame_font; | |
7435 struct face *face; | 5483 struct face *face; |
7436 | 5484 |
7437 /* If the `default' face is not yet known, create it. */ | 5485 /* If the `default' face is not yet known, create it. */ |
7438 lface = lface_from_face_name (f, Qdefault, 0); | 5486 lface = lface_from_face_name (f, Qdefault, 0); |
7439 if (NILP (lface)) | 5487 if (NILP (lface)) |
7441 Lisp_Object frame; | 5489 Lisp_Object frame; |
7442 XSETFRAME (frame, f); | 5490 XSETFRAME (frame, f); |
7443 lface = Finternal_make_lisp_face (Qdefault, frame); | 5491 lface = Finternal_make_lisp_face (Qdefault, frame); |
7444 } | 5492 } |
7445 | 5493 |
7446 | |
7447 #ifdef HAVE_WINDOW_SYSTEM | 5494 #ifdef HAVE_WINDOW_SYSTEM |
7448 if (FRAME_WINDOW_P (f)) | 5495 if (FRAME_WINDOW_P (f)) |
7449 { | 5496 { |
7450 #ifdef USE_FONT_BACKEND | 5497 Lisp_Object font_object; |
7451 if (enable_font_backend) | 5498 |
7452 { | 5499 XSETFONT (font_object, FRAME_FONT (f)); |
7453 frame_font = font_find_object (FRAME_FONT_OBJECT (f)); | 5500 set_lface_from_font (f, lface, font_object, f->default_face_done_p); |
7454 xassert (FONT_OBJECT_P (frame_font)); | 5501 LFACE_FONTSET (lface) = fontset_name (FRAME_FONTSET (f)); |
7455 set_lface_from_font_and_fontset (f, lface, frame_font, | |
7456 FRAME_FONTSET (f), | |
7457 f->default_face_done_p); | |
7458 } | |
7459 else | |
7460 { | |
7461 #endif /* USE_FONT_BACKEND */ | |
7462 /* Set frame_font to the value of the `font' frame parameter. */ | |
7463 frame_font = Fassq (Qfont, f->param_alist); | |
7464 xassert (CONSP (frame_font) && STRINGP (XCDR (frame_font))); | |
7465 frame_font = XCDR (frame_font); | |
7466 set_lface_from_font_name (f, lface, frame_font, | |
7467 f->default_face_done_p, 1); | |
7468 #ifdef USE_FONT_BACKEND | |
7469 } | |
7470 #endif /* USE_FONT_BACKEND */ | |
7471 f->default_face_done_p = 1; | 5502 f->default_face_done_p = 1; |
7472 } | 5503 } |
7473 #endif /* HAVE_WINDOW_SYSTEM */ | 5504 #endif /* HAVE_WINDOW_SYSTEM */ |
7474 | 5505 |
7475 if (!FRAME_WINDOW_P (f)) | 5506 if (!FRAME_WINDOW_P (f)) |
7479 LFACE_HEIGHT (lface) = make_number (1); | 5510 LFACE_HEIGHT (lface) = make_number (1); |
7480 if (UNSPECIFIEDP (LFACE_WEIGHT (lface))) | 5511 if (UNSPECIFIEDP (LFACE_WEIGHT (lface))) |
7481 LFACE_WEIGHT (lface) = Qnormal; | 5512 LFACE_WEIGHT (lface) = Qnormal; |
7482 if (UNSPECIFIEDP (LFACE_SLANT (lface))) | 5513 if (UNSPECIFIEDP (LFACE_SLANT (lface))) |
7483 LFACE_SLANT (lface) = Qnormal; | 5514 LFACE_SLANT (lface) = Qnormal; |
7484 LFACE_AVGWIDTH (lface) = Qunspecified; | |
7485 } | 5515 } |
7486 | 5516 |
7487 if (UNSPECIFIEDP (LFACE_UNDERLINE (lface))) | 5517 if (UNSPECIFIEDP (LFACE_UNDERLINE (lface))) |
7488 LFACE_UNDERLINE (lface) = Qnil; | 5518 LFACE_UNDERLINE (lface) = Qnil; |
7489 | 5519 |
7550 | 5580 |
7551 /* Otherwise, the font specified for the frame was not | 5581 /* Otherwise, the font specified for the frame was not |
7552 acceptable as a font for the default face (perhaps because | 5582 acceptable as a font for the default face (perhaps because |
7553 auto-scaled fonts are rejected), so we must adjust the frame | 5583 auto-scaled fonts are rejected), so we must adjust the frame |
7554 font. */ | 5584 font. */ |
7555 x_set_font (f, build_string (face->font_name), Qnil); | 5585 x_set_font (f, LFACE_FONT (lface), Qnil); |
7556 } | 5586 } |
7557 #endif /* HAVE_X_WINDOWS */ | 5587 #endif /* HAVE_X_WINDOWS */ |
7558 #endif /* HAVE_WINDOW_SYSTEM */ | 5588 #endif /* HAVE_WINDOW_SYSTEM */ |
7559 return 1; | 5589 return 1; |
7560 } | 5590 } |
7640 return face; | 5670 return face; |
7641 } | 5671 } |
7642 | 5672 |
7643 | 5673 |
7644 #ifdef HAVE_WINDOW_SYSTEM | 5674 #ifdef HAVE_WINDOW_SYSTEM |
7645 /* Realize the fully-specified face that has the same attributes as | 5675 /* Realize the fully-specified face that uses FONT-OBJECT and has the |
7646 BASE_FACE except for the font on frame F. If FONT_ID is not | 5676 same attributes as BASE_FACE except for the font on frame F. |
7647 negative, it is an ID number of an already opened font that should | 5677 FONT-OBJECT may be nil, in which case, realized a face of |
7648 be used by the face. If FONT_ID is negative, the face has no font, | 5678 no-font. */ |
7649 i.e., characters are displayed by empty boxes. */ | |
7650 | 5679 |
7651 static struct face * | 5680 static struct face * |
7652 realize_non_ascii_face (f, font_id, base_face) | 5681 realize_non_ascii_face (f, font_object, base_face) |
7653 struct frame *f; | 5682 struct frame *f; |
7654 int font_id; | 5683 Lisp_Object font_object; |
7655 struct face *base_face; | 5684 struct face *base_face; |
7656 { | 5685 { |
7657 struct face_cache *cache = FRAME_FACE_CACHE (f); | 5686 struct face_cache *cache = FRAME_FACE_CACHE (f); |
7658 struct face *face; | 5687 struct face *face; |
7659 struct font_info *font_info; | |
7660 | 5688 |
7661 face = (struct face *) xmalloc (sizeof *face); | 5689 face = (struct face *) xmalloc (sizeof *face); |
7662 *face = *base_face; | 5690 *face = *base_face; |
7663 face->gc = 0; | 5691 face->gc = 0; |
7664 #ifdef USE_FONT_BACKEND | |
7665 face->extra = NULL; | 5692 face->extra = NULL; |
7666 #endif /* USE_FONT_BACKEND */ | 5693 face->overstrike |
5694 = (! NILP (font_object) | |
5695 && FONT_WEIGHT_NAME_NUMERIC (face->lface[LFACE_WEIGHT_INDEX]) > 100 | |
5696 && FONT_WEIGHT_NUMERIC (font_object) <= 100); | |
7667 | 5697 |
7668 /* Don't try to free the colors copied bitwise from BASE_FACE. */ | 5698 /* Don't try to free the colors copied bitwise from BASE_FACE. */ |
7669 face->colors_copied_bitwise_p = 1; | 5699 face->colors_copied_bitwise_p = 1; |
7670 | 5700 face->font = NILP (font_object) ? NULL : XFONT_OBJECT (font_object); |
7671 face->font_info_id = font_id; | |
7672 if (font_id >= 0) | |
7673 { | |
7674 font_info = FONT_INFO_FROM_ID (f, font_id); | |
7675 face->font = font_info->font; | |
7676 face->font_name = font_info->full_name; | |
7677 } | |
7678 else | |
7679 { | |
7680 face->font = NULL; | |
7681 face->font_name = NULL; | |
7682 } | |
7683 | |
7684 face->gc = 0; | 5701 face->gc = 0; |
7685 | 5702 |
7686 cache_face (cache, face, face->hash); | 5703 cache_face (cache, face, face->hash); |
7687 | 5704 |
7688 return face; | 5705 return face; |
7721 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); | 5738 default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); |
7722 if (default_face | 5739 if (default_face |
7723 && lface_same_font_attributes_p (default_face->lface, attrs)) | 5740 && lface_same_font_attributes_p (default_face->lface, attrs)) |
7724 { | 5741 { |
7725 face->font = default_face->font; | 5742 face->font = default_face->font; |
7726 face->font_info_id = default_face->font_info_id; | 5743 face->fontset = make_fontset_for_ascii_face (f, -1, face); |
7727 #ifdef USE_FONT_BACKEND | |
7728 if (enable_font_backend) | |
7729 face->font_info = default_face->font_info; | |
7730 #endif /* USE_FONT_BACKEND */ | |
7731 face->font_name = default_face->font_name; | |
7732 face->fontset | |
7733 = make_fontset_for_ascii_face (f, default_face->fontset, face); | |
7734 } | 5744 } |
7735 else | 5745 else |
7736 { | 5746 { |
7737 /* If the face attribute ATTRS specifies a fontset, use it as | 5747 /* If the face attribute ATTRS specifies a fontset, use it as |
7738 the base of a new realized fontset. Otherwise, use the same | 5748 the base of a new realized fontset. Otherwise, use the same |
7748 already been realized. */ | 5758 already been realized. */ |
7749 if (fontset == -1) | 5759 if (fontset == -1) |
7750 fontset = default_face->fontset; | 5760 fontset = default_face->fontset; |
7751 if (fontset == -1) | 5761 if (fontset == -1) |
7752 abort (); | 5762 abort (); |
7753 #ifdef USE_FONT_BACKEND | 5763 if (! FONT_OBJECT_P (attrs[LFACE_FONT_INDEX])) |
7754 if (enable_font_backend) | 5764 attrs[LFACE_FONT_INDEX] |
7755 font_load_for_face (f, face); | 5765 = font_load_for_lface (f, attrs, attrs[LFACE_FONT_INDEX]); |
5766 if (FONT_OBJECT_P (attrs[LFACE_FONT_INDEX])) | |
5767 { | |
5768 face->font = XFONT_OBJECT (attrs[LFACE_FONT_INDEX]); | |
5769 face->fontset = make_fontset_for_ascii_face (f, fontset, face); | |
5770 } | |
7756 else | 5771 else |
7757 #endif /* USE_FONT_BACKEND */ | 5772 { |
7758 load_face_font (f, face); | 5773 face->font = NULL; |
7759 if (face->font) | 5774 face->fontset = -1; |
7760 face->fontset = make_fontset_for_ascii_face (f, fontset, face); | 5775 } |
7761 else | 5776 } |
7762 face->fontset = -1; | 5777 |
7763 } | 5778 if (face->font |
5779 && FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]) > 100 | |
5780 && FONT_WEIGHT_NUMERIC (attrs[LFACE_FONT_INDEX]) <= 100) | |
5781 face->overstrike = 1; | |
7764 | 5782 |
7765 /* Load colors, and set remaining attributes. */ | 5783 /* Load colors, and set remaining attributes. */ |
7766 | 5784 |
7767 load_face_colors (f, face, attrs); | 5785 load_face_colors (f, face, attrs); |
7768 | 5786 |
7995 /* Frame must be a termcap frame. */ | 6013 /* Frame must be a termcap frame. */ |
7996 xassert (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f)); | 6014 xassert (FRAME_TERMCAP_P (cache->f) || FRAME_MSDOS_P (cache->f)); |
7997 | 6015 |
7998 /* Allocate a new realized face. */ | 6016 /* Allocate a new realized face. */ |
7999 face = make_realized_face (attrs); | 6017 face = make_realized_face (attrs); |
6018 #if 0 | |
8000 face->font_name = FRAME_MSDOS_P (cache->f) ? "ms-dos" : "tty"; | 6019 face->font_name = FRAME_MSDOS_P (cache->f) ? "ms-dos" : "tty"; |
6020 #endif | |
8001 | 6021 |
8002 /* Map face attributes to TTY appearances. We map slant to | 6022 /* Map face attributes to TTY appearances. We map slant to |
8003 dimmed text because we want italic text to appear differently | 6023 dimmed text because we want italic text to appear differently |
8004 and because dimmed text is probably used infrequently. */ | 6024 and because dimmed text is probably used infrequently. */ |
8005 weight = face_numeric_weight (attrs[LFACE_WEIGHT_INDEX]); | 6025 weight = FONT_WEIGHT_NAME_NUMERIC (attrs[LFACE_WEIGHT_INDEX]); |
8006 slant = face_numeric_slant (attrs[LFACE_SLANT_INDEX]); | 6026 slant = FONT_SLANT_NAME_NUMERIC (attrs[LFACE_SLANT_INDEX]); |
8007 | 6027 if (weight > 100) |
8008 if (weight > XLFD_WEIGHT_MEDIUM) | |
8009 face->tty_bold_p = 1; | 6028 face->tty_bold_p = 1; |
8010 if (weight < XLFD_WEIGHT_MEDIUM || slant != XLFD_SLANT_ROMAN) | 6029 if (weight < 100 || slant != 100) |
8011 face->tty_dim_p = 1; | 6030 face->tty_dim_p = 1; |
8012 if (!NILP (attrs[LFACE_UNDERLINE_INDEX])) | 6031 if (!NILP (attrs[LFACE_UNDERLINE_INDEX])) |
8013 face->tty_underline_p = 1; | 6032 face->tty_underline_p = 1; |
8014 if (!NILP (attrs[LFACE_INVERSE_INDEX])) | 6033 if (!NILP (attrs[LFACE_INVERSE_INDEX])) |
8015 face->tty_reverse_p = 1; | 6034 face->tty_reverse_p = 1; |
8464 face->foreground, | 6483 face->foreground, |
8465 SDATA (face->lface[LFACE_FOREGROUND_INDEX])); | 6484 SDATA (face->lface[LFACE_FOREGROUND_INDEX])); |
8466 fprintf (stderr, "background: 0x%lx (%s)\n", | 6485 fprintf (stderr, "background: 0x%lx (%s)\n", |
8467 face->background, | 6486 face->background, |
8468 SDATA (face->lface[LFACE_BACKGROUND_INDEX])); | 6487 SDATA (face->lface[LFACE_BACKGROUND_INDEX])); |
8469 fprintf (stderr, "font_name: %s (%s)\n", | 6488 if (face->font) |
8470 face->font_name, | 6489 fprintf (stderr, "font_name: %s (%s)\n", |
8471 SDATA (face->lface[LFACE_FAMILY_INDEX])); | 6490 SDATA (face->font->props[FONT_NAME_INDEX]), |
6491 SDATA (face->lface[LFACE_FAMILY_INDEX])); | |
8472 #ifdef HAVE_X_WINDOWS | 6492 #ifdef HAVE_X_WINDOWS |
8473 fprintf (stderr, "font = %p\n", face->font); | 6493 fprintf (stderr, "font = %p\n", face->font); |
8474 #endif | 6494 #endif |
8475 fprintf (stderr, "font_info_id = %d\n", face->font_info_id); | |
8476 fprintf (stderr, "fontset: %d\n", face->fontset); | 6495 fprintf (stderr, "fontset: %d\n", face->fontset); |
8477 fprintf (stderr, "underline: %d (%s)\n", | 6496 fprintf (stderr, "underline: %d (%s)\n", |
8478 face->underline_p, | 6497 face->underline_p, |
8479 SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX]))); | 6498 SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX]))); |
8480 fprintf (stderr, "hash: %d\n", face->hash); | 6499 fprintf (stderr, "hash: %d\n", face->hash); |