diff options
| author | Kenichi Handa | 2008-05-14 01:41:52 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2008-05-14 01:41:52 +0000 |
| commit | 2dee4c0b8dd17f9864d95c868ac362aa04572522 (patch) | |
| tree | a71b209b75bcaad3b2008c5ca3c9efcd82dd3bb3 /src | |
| parent | 4039e20cf488e5995cc34236be2459e685c03824 (diff) | |
| download | emacs-2dee4c0b8dd17f9864d95c868ac362aa04572522.tar.gz emacs-2dee4c0b8dd17f9864d95c868ac362aa04572522.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xfaces.c | 2731 |
1 files changed, 375 insertions, 2356 deletions
diff --git a/src/xfaces.c b/src/xfaces.c index 087dc86297a..37b8913913c 100644 --- a/src/xfaces.c +++ b/src/xfaces.c | |||
| @@ -56,15 +56,17 @@ Boston, MA 02110-1301, USA. */ | |||
| 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 | ||
| @@ -72,7 +74,11 @@ Boston, MA 02110-1301, USA. */ | |||
| 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 |
| @@ -206,10 +212,6 @@ Boston, MA 02110-1301, USA. */ | |||
| 206 | #include "frame.h" | 212 | #include "frame.h" |
| 207 | #include "termhooks.h" | 213 | #include "termhooks.h" |
| 208 | 214 | ||
| 209 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 210 | #include "fontset.h" | ||
| 211 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 212 | |||
| 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 |
| @@ -251,7 +253,8 @@ Boston, MA 02110-1301, USA. */ | |||
| 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 | ||
| @@ -314,6 +317,11 @@ 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; |
| 316 | 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; | ||
| 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; |
| @@ -491,7 +499,6 @@ 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 *)); |
| @@ -516,7 +523,7 @@ static int try_alternative_families P_ ((struct frame *f, Lisp_Object, | |||
| 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 *)); |
| @@ -531,48 +538,24 @@ 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)); |
| @@ -980,14 +963,11 @@ clear_face_cache (clear_fonts_p) | |||
| 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 |
| @@ -1029,70 +1009,6 @@ Optional THOROUGHLY non-nil means try to free unused fonts, too. */) | |||
| 1029 | return Qnil; | 1009 | return Qnil; |
| 1030 | } | 1010 | } |
| 1031 | 1011 | ||
| 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 | |||
| 1096 | 1012 | ||
| 1097 | /*********************************************************************** | 1013 | /*********************************************************************** |
| 1098 | X Pixmaps | 1014 | X Pixmaps |
| @@ -1222,64 +1138,6 @@ load_pixmap (f, name, w_ptr, h_ptr) | |||
| 1222 | 1138 | ||
| 1223 | 1139 | ||
| 1224 | /*********************************************************************** | 1140 | /*********************************************************************** |
| 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 | } | ||
| 1277 | |||
| 1278 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 1279 | |||
| 1280 | |||
| 1281 | |||
| 1282 | /*********************************************************************** | ||
| 1283 | X Colors | 1141 | X Colors |
| 1284 | ***********************************************************************/ | 1142 | ***********************************************************************/ |
| 1285 | 1143 | ||
| @@ -1920,33 +1778,6 @@ static struct table_entry swidth_table[] = | |||
| 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 | ||
| @@ -1965,425 +1796,9 @@ static int font_sort_order[4] = { | |||
| 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 | 1801 | ||
| 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 | |||
| 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 |
| @@ -2402,586 +1817,42 @@ font_rescale_ratio (name) | |||
| 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; | ||
| 2418 | int numeric_p; | ||
| 2419 | { | ||
| 2420 | int i = 0; | ||
| 2421 | int success_p; | ||
| 2422 | double rescale_ratio; | ||
| 2423 | |||
| 2424 | if (numeric_p) | ||
| 2425 | /* This must be done before splitting the font name. */ | ||
| 2426 | rescale_ratio = font_rescale_ratio (font->name); | ||
| 2427 | |||
| 2428 | if (*font->name == '-') | ||
| 2429 | { | ||
| 2430 | char *p = xstrlwr (font->name) + 1; | ||
| 2431 | |||
| 2432 | while (i < XLFD_LAST) | ||
| 2433 | { | ||
| 2434 | font->fields[i] = p; | ||
| 2435 | ++i; | ||
| 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 | { | 1825 | { |
| 1826 | Lisp_Object font1 = *(Lisp_Object *) v1; | ||
| 1827 | Lisp_Object font2 = *(Lisp_Object *) v2; | ||
| 2504 | int i; | 1828 | int i; |
| 2505 | int size = 100; | 1829 | |
| 2506 | char *font_name = (char *) xmalloc (size); | 1830 | for (i = 0; i < FONT_SIZE_INDEX; i++) |
| 2507 | int total_length = 0; | ||
| 2508 | |||
| 2509 | for (i = 0; i < XLFD_LAST; ++i) | ||
| 2510 | { | 1831 | { |
| 2511 | /* Add 1 because of the leading `-'. */ | 1832 | enum font_property_index idx = font_props_for_sorting[i]; |
| 2512 | int len = strlen (font->fields[i]) + 1; | 1833 | Lisp_Object val1 = AREF (font1, idx), val2 = AREF (font2, idx); |
| 1834 | int result; | ||
| 2513 | 1835 | ||
| 2514 | /* Reallocate font_name if necessary. Add 1 for the final | 1836 | if (idx <= FONT_REGISTRY_INDEX) |
| 2515 | NUL-byte. */ | ||
| 2516 | if (total_length + len + 1 >= size) | ||
| 2517 | { | 1837 | { |
| 2518 | int new_size = max (2 * size, size + len + 1); | 1838 | if (STRINGP (val1)) |
| 2519 | int sz = new_size * sizeof *font_name; | 1839 | result = STRINGP (val2) ? strcmp (SDATA (val1), SDATA (val2)) : -1; |
| 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 | } | ||
| 2649 | 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 | { | ||
| 2666 | Lisp_Object entry = XCAR (list); | ||
| 2667 | if (CONSP (entry) | ||
| 2668 | && STRINGP (XCAR (entry)) | ||
| 2669 | && strcmp (SDATA (XCAR (entry)), pattern) == 0) | ||
| 2670 | break; | ||
| 2671 | list = XCDR (list); | ||
| 2672 | } | ||
| 2673 | |||
| 2674 | if (CONSP (list)) | ||
| 2675 | { | ||
| 2676 | Lisp_Object patterns = XCAR (list); | ||
| 2677 | Lisp_Object name; | ||
| 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 | } | 1842 | } |
| 2722 | registry = XCDR (pattern); | ||
| 2723 | if (NILP (registry)) | ||
| 2724 | registry_str = "*"; | ||
| 2725 | else | 1843 | else |
| 2726 | { | 1844 | { |
| 2727 | CHECK_STRING (registry); | 1845 | if (INTEGERP (val1)) |
| 2728 | registry_str = (char *) SDATA (registry); | 1846 | result = INTEGERP (val2) ? XINT (val1) - XINT (val2) : -1; |
| 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 | 1847 | else |
| 2874 | strcat (pattern_str, "*-*"); | 1848 | result = INTEGERP (val2) ? 1 : 0; |
| 2875 | } | 1849 | } |
| 1850 | if (result) | ||
| 1851 | return result; | ||
| 2876 | } | 1852 | } |
| 2877 | else | 1853 | return 0; |
| 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 | } | 1854 | } |
| 2983 | 1855 | ||
| 2984 | |||
| 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. |
| @@ -3002,41 +1873,66 @@ the face font sort order. */) | |||
| 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 | ||
| @@ -3051,28 +1947,7 @@ 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 | ||
| @@ -3100,30 +1975,27 @@ the WIDTH times as wide as FACE on FRAME. */) | |||
| 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 | ||
| @@ -3141,19 +2013,31 @@ the WIDTH times as wide as FACE on FRAME. */) | |||
| 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); |
| @@ -3186,7 +2070,6 @@ the WIDTH times as wide as FACE on FRAME. */) | |||
| 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 |
| @@ -3212,9 +2095,6 @@ check_lface_attrs (attrs) | |||
| 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]) |
| @@ -3265,11 +2145,7 @@ check_lface_attrs (attrs) | |||
| 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 |
| @@ -3478,8 +2354,7 @@ lface_fully_specified_p (attrs) | |||
| 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 |
| @@ -3494,144 +2369,19 @@ lface_fully_specified_p (attrs) | |||
| 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 |
| @@ -3639,8 +2389,8 @@ set_lface_from_font_and_fontset (f, lface, font_object, fontset, force_p) | |||
| 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 | { |
| @@ -3662,42 +2412,31 @@ set_lface_from_font_and_fontset (f, lface, font_object, fontset, force_p) | |||
| 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); | ||
| 3693 | LFACE_SWIDTH (lface) = ! NILP (val) ? val : width; | ||
| 3694 | } | 2435 | } |
| 3695 | 2436 | ||
| 3696 | LFACE_FONT (lface) = make_unibyte_string (font->font.full_name, | 2437 | LFACE_FONT (lface) = font_object; |
| 3697 | strlen (font->font.full_name)); | 2438 | return 1; |
| 3698 | LFACE_FONTSET (lface) = fontset_name (fontset); | ||
| 3699 | } | 2439 | } |
| 3700 | #endif /* USE_FONT_BACKEND */ | ||
| 3701 | 2440 | ||
| 3702 | #endif /* HAVE_WINDOW_SYSTEM */ | 2441 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 3703 | 2442 | ||
| @@ -3777,28 +2516,42 @@ merge_face_vectors (f, from, to, named_merge_points) | |||
| 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 | } |
| 3801 | 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); | ||
| 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; |
| @@ -3914,7 +2667,10 @@ merge_face_ref (f, face_ref, to, err_msgs, named_merge_points) | |||
| 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 | } |
| @@ -3924,23 +2680,30 @@ merge_face_ref (f, face_ref, to, err_msgs, named_merge_points) | |||
| 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 | } |
| @@ -4017,9 +2780,11 @@ merge_face_ref (f, face_ref, to, err_msgs, named_merge_points) | |||
| 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 | } |
| @@ -4250,10 +3015,9 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 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); |
| @@ -4308,7 +3072,7 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 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 | { |
| @@ -4329,31 +3093,31 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 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 | { |
| @@ -4516,84 +3280,70 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 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); | 3303 | { |
| 4550 | LFACE_FONTSET (lface) = tmp; | 3304 | int fontset = fs_query_fontset (value, 0); |
| 3305 | |||
| 3306 | if (fontset >= 0) | ||
| 3307 | value = fontset_ascii (fontset); | ||
| 3308 | else | ||
| 3309 | value = font_spec_from_name (value); | ||
| 3310 | } | ||
| 3311 | else | ||
| 3312 | signal_error ("Invalid font or font-spec", value); | ||
| 4551 | } | 3313 | } |
| 3314 | if (EQ (frame, Qt)) | ||
| 3315 | f = XFRAME (selected_frame); | ||
| 4552 | else | 3316 | else |
| 3317 | f = XFRAME (frame); | ||
| 3318 | if (! FONT_OBJECT_P (value)) | ||
| 4553 | { | 3319 | { |
| 4554 | int fontset; | 3320 | Lisp_Object *attrs = XVECTOR (lface)->contents; |
| 4555 | Lisp_Object font_object; | 3321 | Lisp_Object font_object; |
| 4556 | 3322 | ||
| 4557 | if (! NILP (tmp)) | 3323 | font_object = font_load_for_lface (f, attrs, value); |
| 4558 | { | ||
| 4559 | fontset = fs_query_fontset (tmp, 0); | ||
| 4560 | value = fontset_ascii (fontset); | ||
| 4561 | } | ||
| 4562 | else | ||
| 4563 | { | ||
| 4564 | fontset = FRAME_FONTSET (f); | ||
| 4565 | } | ||
| 4566 | font_object = font_open_by_name (f, SDATA (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)) | ||
| 4585 | signal_error ("Invalid fontset name", value); | ||
| 4586 | |||
| 4587 | if (EQ (attr, QCfont)) | ||
| 4588 | { | ||
| 4589 | if (!set_lface_from_font_name (f, lface, value, 1, 1)) | ||
| 4590 | signal_error ("Invalid font or fontset name", value); | ||
| 4591 | } | ||
| 4592 | else | ||
| 4593 | LFACE_FONTSET (lface) = value; | ||
| 4594 | } | ||
| 4595 | 3341 | ||
| 4596 | font_attr_p = 1; | 3342 | old_value = LFACE_FONTSET (lface); |
| 3343 | tmp = Fquery_fontset (value, Qnil); | ||
| 3344 | if (NILP (tmp)) | ||
| 3345 | signal_error ("Invalid fontset name", value); | ||
| 3346 | LFACE_FONTSET (lface) = value = tmp; | ||
| 4597 | } | 3347 | } |
| 4598 | #endif /* HAVE_WINDOW_SYSTEM */ | 3348 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 4599 | } | 3349 | } |
| @@ -4615,24 +3365,25 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 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 |
| @@ -4641,9 +3392,7 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 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; |
| @@ -4662,7 +3411,7 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 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 |
| @@ -4749,11 +3498,8 @@ FRAME 0 means change the face on all frames, and change the default | |||
| 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) |
| @@ -4763,43 +3509,17 @@ set_font_frame_param (frame, lface) | |||
| 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; | ||
| 4768 | 3513 | ||
| 4769 | if (STRINGP (LFACE_FONT (lface))) | 3514 | if (FONT_SPEC_P (font)) |
| 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 | } | ||
| 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 | } | 3520 | } |
| 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 | ||
| @@ -5031,14 +3751,14 @@ x_update_menu_appearance (f) | |||
| 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; |
| @@ -5051,22 +3771,26 @@ x_update_menu_appearance (f) | |||
| 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) |
| @@ -5198,35 +3922,7 @@ Value is nil if ATTR doesn't have a discrete set of valid values. */) | |||
| 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)); |
| @@ -5322,12 +4018,11 @@ return the font name used for CHARACTER. */) | |||
| 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 | ||
| @@ -5490,7 +4185,7 @@ lface_hash (v) | |||
| 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 |
| @@ -5503,14 +4198,9 @@ lface_same_font_attributes_p (lface1, lface2) | |||
| 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]) |
| @@ -5559,10 +4249,8 @@ free_realized_face (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; |
| @@ -5600,25 +4288,6 @@ prepare_face_for_display (f, face) | |||
| 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 |
| @@ -5630,10 +4299,8 @@ prepare_face_for_display (f, face) | |||
| 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 */ |
| @@ -5739,10 +4406,8 @@ clear_face_gcs (c) | |||
| 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; |
| @@ -6029,16 +4694,15 @@ lookup_face (f, attr) | |||
| 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); |
| @@ -6056,58 +4720,16 @@ lookup_non_ascii_face (f, font_id, base_face) | |||
| 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)) |
| 6061 | } | 4725 | && lface_equal_p (face->lface, base_face->lface)) |
| 6062 | |||
| 6063 | /* If not found, realize a new face. */ | ||
| 6064 | if (face == NULL) | ||
| 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; | ||
| 6072 | } | ||
| 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; | 4726 | return face->id; |
| 6099 | } | 4727 | } |
| 6100 | 4728 | ||
| 6101 | /* If not found, realize a new face. */ | 4729 | /* If not found, realize a new face. */ |
| 6102 | face = realize_non_ascii_face (f, -1, base_face); | 4730 | face = realize_non_ascii_face (f, font_object, 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; | 4731 | return face->id; |
| 6108 | } | 4732 | } |
| 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 |
| @@ -6363,12 +4985,12 @@ x_supports_face_attributes_p (f, attrs, def_face) | |||
| 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 | ||
| @@ -6383,6 +5005,21 @@ x_supports_face_attributes_p (f, attrs, def_face) | |||
| 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. */ |
| @@ -6443,24 +5080,24 @@ tty_supports_face_attributes_p (f, attrs, def_face) | |||
| 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 | ||
| @@ -6713,10 +5350,7 @@ Value is 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 | } |
| @@ -6758,494 +5392,10 @@ be found. Value is ALIST. */) | |||
| 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 | 5398 | ||
| 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 | |||
| 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. */ |
| @@ -7262,107 +5412,6 @@ face_fontset (attrs) | |||
| 7262 | return fs_query_fontset (name, 0); | 5412 | return fs_query_fontset (name, 0); |
| 7263 | } | 5413 | } |
| 7264 | 5414 | ||
| 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 | } | ||
| 7365 | |||
| 7366 | #endif /* HAVE_WINDOW_SYSTEM */ | 5415 | #endif /* HAVE_WINDOW_SYSTEM */ |
| 7367 | 5416 | ||
| 7368 | 5417 | ||
| @@ -7431,7 +5480,6 @@ realize_default_face (f) | |||
| 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. */ |
| @@ -7443,31 +5491,14 @@ realize_default_face (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 */ |
| @@ -7481,7 +5512,6 @@ realize_default_face (f) | |||
| 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))) |
| @@ -7552,7 +5582,7 @@ realize_default_face (f) | |||
| 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 */ |
| @@ -7642,45 +5672,32 @@ realize_face (cache, attrs, former_face_id) | |||
| 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); |
| @@ -7723,14 +5740,7 @@ realize_x_face (cache, attrs) | |||
| 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 | { |
| @@ -7750,18 +5760,26 @@ realize_x_face (cache, attrs) | |||
| 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]); |
| 7756 | else | 5766 | if (FONT_OBJECT_P (attrs[LFACE_FONT_INDEX])) |
| 7757 | #endif /* USE_FONT_BACKEND */ | 5767 | { |
| 7758 | load_face_font (f, face); | 5768 | face->font = XFONT_OBJECT (attrs[LFACE_FONT_INDEX]); |
| 7759 | if (face->font) | 5769 | face->fontset = make_fontset_for_ascii_face (f, fontset, face); |
| 7760 | face->fontset = make_fontset_for_ascii_face (f, fontset, face); | 5770 | } |
| 7761 | else | 5771 | else |
| 7762 | face->fontset = -1; | 5772 | { |
| 5773 | face->font = NULL; | ||
| 5774 | face->fontset = -1; | ||
| 5775 | } | ||
| 7763 | } | 5776 | } |
| 7764 | 5777 | ||
| 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; | ||
| 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); |
| @@ -7997,17 +6015,18 @@ realize_tty_face (cache, attrs) | |||
| 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; |
| @@ -8466,13 +6485,13 @@ dump_realized_face (face) | |||
| 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, |