Mercurial > hg > xemacs-beta
comparison src/faces.c @ 5118:e0db3c197671 ben-lisp-object
merge up to latest default branch, doesn't compile yet
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Sat, 26 Dec 2009 21:18:49 -0600 |
parents | 3742ea8250b5 32b358a240b0 |
children | d877c14318b3 |
comparison
equal
deleted
inserted
replaced
5117:3742ea8250b5 | 5118:e0db3c197671 |
---|---|
70 Lisp_Object Vtemporary_faces_cache; | 70 Lisp_Object Vtemporary_faces_cache; |
71 | 71 |
72 Lisp_Object Vbuilt_in_face_specifiers; | 72 Lisp_Object Vbuilt_in_face_specifiers; |
73 | 73 |
74 | 74 |
75 #ifdef DEBUG_XEMACS | |
76 Fixnum debug_x_faces; | |
77 #endif | |
78 | |
79 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) | |
80 | |
81 #ifdef DEBUG_XEMACS | |
82 # define DEBUG_FACES(FORMAT, ...) \ | |
83 do { if (debug_x_faces) stderr_out(FORMAT, __VA_ARGS__); } while (0) | |
84 #else /* DEBUG_XEMACS */ | |
85 # define DEBUG_FACES(format, ...) | |
86 #endif /* DEBUG_XEMACS */ | |
87 | |
88 #elif defined(__GNUC__) | |
89 | |
90 #ifdef DEBUG_XEMACS | |
91 # define DEBUG_FACES(format, args...) \ | |
92 do { if (debug_x_faces) stderr_out(format, args ); } while (0) | |
93 #else /* DEBUG_XEMACS */ | |
94 # define DEBUG_FACES(format, args...) | |
95 #endif /* DEBUG_XEMACS */ | |
96 | |
97 #else /* defined(__STDC_VERSION__) [...] */ | |
98 # define DEBUG_FACES (void) | |
99 #endif | |
75 | 100 |
76 static Lisp_Object | 101 static Lisp_Object |
77 mark_face (Lisp_Object obj) | 102 mark_face (Lisp_Object obj) |
78 { | 103 { |
79 Lisp_Face *face = XFACE (obj); | 104 Lisp_Face *face = XFACE (obj); |
276 { XD_LISP_OBJECT, offsetof (Lisp_Face, plist) }, | 301 { XD_LISP_OBJECT, offsetof (Lisp_Face, plist) }, |
277 { XD_LISP_OBJECT, offsetof (Lisp_Face, charsets_warned_about) }, | 302 { XD_LISP_OBJECT, offsetof (Lisp_Face, charsets_warned_about) }, |
278 { XD_END } | 303 { XD_END } |
279 }; | 304 }; |
280 | 305 |
281 DEFINE_LISP_OBJECT_WITH_PROPS ("face", face, | 306 DEFINE_DUMPABLE_LISP_OBJECT_WITH_PROPS ("face", face, |
282 mark_face, print_face, 0, face_equal, | 307 mark_face, print_face, 0, face_equal, |
283 face_hash, face_description, | 308 face_hash, face_description, |
284 face_getprop, | 309 face_getprop, |
285 face_putprop, face_remprop, | 310 face_putprop, face_remprop, |
286 face_plist, Lisp_Face); | 311 face_plist, Lisp_Face); |
552 | 577 |
553 Lisp_Object | 578 Lisp_Object |
554 face_property_matching_instance (Lisp_Object face, Lisp_Object property, | 579 face_property_matching_instance (Lisp_Object face, Lisp_Object property, |
555 Lisp_Object charset, Lisp_Object domain, | 580 Lisp_Object charset, Lisp_Object domain, |
556 Error_Behavior errb, int no_fallback, | 581 Error_Behavior errb, int no_fallback, |
557 Lisp_Object depth) | 582 Lisp_Object depth, |
583 enum font_specifier_matchspec_stages stage) | |
558 { | 584 { |
559 Lisp_Object retval; | 585 Lisp_Object retval; |
560 Lisp_Object matchspec = Qunbound; | 586 Lisp_Object matchspec = Qunbound; |
561 struct gcpro gcpro1; | 587 struct gcpro gcpro1; |
562 | 588 |
563 if (!NILP (charset)) | 589 if (!NILP (charset)) |
564 matchspec = noseeum_cons (charset, Qnil); | 590 matchspec = noseeum_cons (charset, |
591 stage == initial ? Qinitial : Qfinal); | |
592 | |
565 GCPRO1 (matchspec); | 593 GCPRO1 (matchspec); |
566 retval = specifier_instance_no_quit (Fget (face, property, Qnil), matchspec, | 594 retval = specifier_instance_no_quit (Fget (face, property, Qnil), matchspec, |
567 domain, errb, no_fallback, depth); | 595 domain, errb, no_fallback, depth); |
568 if (UNBOUNDP (retval)) | |
569 { | |
570 if (CONSP (matchspec)) | |
571 Fsetcdr (matchspec, Qt); | |
572 retval = specifier_instance_no_quit (Fget (face, property, Qnil), | |
573 matchspec, domain, errb, | |
574 no_fallback, depth); | |
575 } | |
576 UNGCPRO; | 596 UNGCPRO; |
577 if (CONSP (matchspec)) | 597 if (CONSP (matchspec)) |
578 free_cons (matchspec); | 598 free_cons (matchspec); |
579 | 599 |
580 if (UNBOUNDP (retval) && !no_fallback) | 600 if (UNBOUNDP (retval) && !no_fallback && final == stage) |
581 { | 601 { |
582 if (EQ (property, Qfont)) | 602 if (EQ (property, Qfont)) |
583 { | 603 { |
584 if (NILP (memq_no_quit (charset, | 604 if (NILP (memq_no_quit (charset, |
585 XFACE (face)->charsets_warned_about))) | 605 XFACE (face)->charsets_warned_about))) |
586 { | 606 { |
587 #ifdef MULE | |
588 if (!UNBOUNDP (charset)) | 607 if (!UNBOUNDP (charset)) |
589 warn_when_safe | 608 warn_when_safe |
590 (Qfont, Qnotice, | 609 (Qfont, Qnotice, |
591 "Unable to instantiate font for charset %s, face %s", | 610 "Unable to instantiate font for charset %s, face %s", |
592 XSTRING_DATA (symbol_name | 611 XSTRING_DATA (symbol_name |
593 (XSYMBOL (XCHARSET_NAME (charset)))), | 612 (XSYMBOL (XCHARSET_NAME (charset)))), |
594 XSTRING_DATA (symbol_name | 613 XSTRING_DATA (symbol_name |
595 (XSYMBOL (XFACE (face)->name)))); | 614 (XSYMBOL (XFACE (face)->name)))); |
596 else | |
597 #endif | |
598 warn_when_safe (Qfont, Qnotice, | |
599 "Unable to instantiate font for face %s", | |
600 XSTRING_DATA (symbol_name | |
601 (XSYMBOL (XFACE (face)->name)))); | |
602 XFACE (face)->charsets_warned_about = | 615 XFACE (face)->charsets_warned_about = |
603 Fcons (charset, XFACE (face)->charsets_warned_about); | 616 Fcons (charset, XFACE (face)->charsets_warned_about); |
604 } | 617 } |
605 retval = Vthe_null_font_instance; | 618 retval = Vthe_null_font_instance; |
606 } | 619 } |
688 return XFACE (Fget_face (face))->name; | 701 return XFACE (Fget_face (face))->name; |
689 } | 702 } |
690 | 703 |
691 DEFUN ("built-in-face-specifiers", Fbuilt_in_face_specifiers, 0, 0, 0, /* | 704 DEFUN ("built-in-face-specifiers", Fbuilt_in_face_specifiers, 0, 0, 0, /* |
692 Return a list of all built-in face specifier properties. | 705 Return a list of all built-in face specifier properties. |
693 Don't modify this list! | 706 |
707 This is a copy; there is no way to modify XEmacs' idea of the built-in face | |
708 specifier properties from Lisp. | |
694 */ | 709 */ |
695 ()) | 710 ()) |
696 { | 711 { |
697 return Vbuilt_in_face_specifiers; | 712 return Fcopy_list(Vbuilt_in_face_specifiers); |
698 } | 713 } |
699 | 714 |
700 /* These values are retrieved so often that we make a special | 715 /* These values are retrieved so often that we make a special |
701 function. | 716 function. |
702 */ | 717 */ |
704 void | 719 void |
705 default_face_font_info (Lisp_Object domain, int *ascent, int *descent, | 720 default_face_font_info (Lisp_Object domain, int *ascent, int *descent, |
706 int *height, int *width, int *proportional_p) | 721 int *height, int *width, int *proportional_p) |
707 { | 722 { |
708 Lisp_Object font_instance; | 723 Lisp_Object font_instance; |
724 struct face_cachel *cachel; | |
725 struct window *w = NULL; | |
709 | 726 |
710 if (noninteractive) | 727 if (noninteractive) |
711 { | 728 { |
712 if (ascent) | 729 if (ascent) |
713 *ascent = 1; | 730 *ascent = 1; |
714 if (descent) | 731 if (descent) |
715 *descent = 0; | 732 *descent = 0; |
716 if (height) | 733 if (height) |
717 *height = 1; | 734 *height = 1; |
718 if (width) | 735 if (width) |
719 *width = 1; | 736 *width = 1; |
720 if (proportional_p) | 737 if (proportional_p) |
721 *proportional_p = 0; | 738 *proportional_p = 0; |
722 return; | 739 return; |
723 } | 740 } |
724 | 741 |
725 /* We use ASCII here. This is probably reasonable because the | 742 /* We use ASCII here. This is reasonable because the people calling this |
726 people calling this function are using the resulting values to | 743 function are using the resulting values to come up with overall sizes |
727 come up with overall sizes for windows and frames. */ | 744 for windows and frames. |
728 if (WINDOWP (domain)) | 745 |
729 { | 746 It's possible for this function to get called when the face cachels |
730 struct face_cachel *cachel; | 747 have not been initialized--put a call to debug-print in |
731 struct window *w = XWINDOW (domain); | 748 init-locale-at-early-startup to see it happen. */ |
732 | 749 |
733 /* #### It's possible for this function to get called when the | 750 if (WINDOWP (domain) && (w = XWINDOW (domain)) && w->face_cachels) |
734 face cachels have not been initialized. I don't know why. */ | 751 { |
735 if (!Dynarr_length (w->face_cachels)) | 752 if (!Dynarr_length (w->face_cachels)) |
736 reset_face_cachels (w); | 753 reset_face_cachels (w); |
737 cachel = WINDOW_FACE_CACHEL (w, DEFAULT_INDEX); | 754 cachel = WINDOW_FACE_CACHEL (w, DEFAULT_INDEX); |
738 font_instance = FACE_CACHEL_FONT (cachel, Vcharset_ascii); | 755 font_instance = FACE_CACHEL_FONT (cachel, Vcharset_ascii); |
739 } | 756 } |
740 else | 757 else |
741 { | 758 { |
742 font_instance = FACE_FONT (Vdefault_face, domain, Vcharset_ascii); | 759 font_instance = FACE_FONT (Vdefault_face, domain, Vcharset_ascii); |
760 } | |
761 | |
762 if (UNBOUNDP (font_instance)) | |
763 { | |
764 return; | |
743 } | 765 } |
744 | 766 |
745 if (height) | 767 if (height) |
746 *height = XFONT_INSTANCE (font_instance)->height; | 768 *height = XFONT_INSTANCE (font_instance)->height; |
747 if (width) | 769 if (width) |
934 { | 956 { |
935 Lisp_Object tframe = wrap_frame (frm); | 957 Lisp_Object tframe = wrap_frame (frm); |
936 | 958 |
937 | 959 |
938 /* DO NOT change the selected frame here. If the debugger goes off | 960 /* DO NOT change the selected frame here. If the debugger goes off |
939 it will try and display on the frame being created, but it is not | 961 it will try and display on the frame being created, but it is not |
940 ready for that yet and a horrible death will occur. Any random | 962 ready for that yet and a horrible death will occur. Any random |
941 code depending on the selected-frame as an implicit arg should be | 963 code depending on the selected-frame as an implicit arg should be |
942 tracked down and shot. For the benefit of the one known, | 964 tracked down and shot. For the benefit of the one known, |
943 xpm-color-symbols, make-frame sets the variable | 965 xpm-color-symbols, make-frame sets the variable |
944 Vframe_being_created to the frame it is making and sets it to nil | 966 Vframe_being_created to the frame it is making and sets it to nil |
945 when done. Internal functions that this could trigger which are | 967 when done. Internal functions that this could trigger which are |
946 currently depending on selected-frame should use this instead. It | 968 currently depending on selected-frame should use this instead. It |
947 is not currently visible at the lisp level. */ | 969 is not currently visible at the lisp level. */ |
948 call_critical_lisp_code (XDEVICE (FRAME_DEVICE (frm)), | 970 call_critical_lisp_code (XDEVICE (FRAME_DEVICE (frm)), |
949 Qinit_frame_faces, tframe); | 971 Qinit_frame_faces, tframe); |
950 } | 972 } |
951 } | 973 } |
952 | 974 |
1058 mark_object (cachel->background_pixmap); | 1080 mark_object (cachel->background_pixmap); |
1059 } | 1081 } |
1060 } | 1082 } |
1061 | 1083 |
1062 /* ensure that the given cachel contains an updated font value for | 1084 /* ensure that the given cachel contains an updated font value for |
1063 the given charset. Return the updated font value. */ | 1085 the given charset. Return the updated font value (which can be |
1086 Qunbound, so this value must not be passed unchecked to Lisp). | |
1087 | |
1088 #### Xft: This function will need to be updated for new font model. */ | |
1064 | 1089 |
1065 Lisp_Object | 1090 Lisp_Object |
1066 ensure_face_cachel_contains_charset (struct face_cachel *cachel, | 1091 ensure_face_cachel_contains_charset (struct face_cachel *cachel, |
1067 Lisp_Object domain, Lisp_Object charset) | 1092 Lisp_Object domain, Lisp_Object charset) |
1068 { | 1093 { |
1069 Lisp_Object new_val; | 1094 Lisp_Object new_val; |
1070 Lisp_Object face = cachel->face; | 1095 Lisp_Object face = cachel->face; |
1071 int bound = 1; | 1096 int bound = 1, final_stage = 0; |
1072 int offs = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE; | 1097 int offs = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE; |
1073 | 1098 |
1074 if (!UNBOUNDP (cachel->font[offs]) | 1099 if (!UNBOUNDP (cachel->font[offs]) && |
1075 && cachel->font_updated[offs]) | 1100 bit_vector_bit(FACE_CACHEL_FONT_UPDATED (cachel), offs)) |
1076 return cachel->font[offs]; | 1101 return cachel->font[offs]; |
1077 | 1102 |
1078 if (UNBOUNDP (face)) | 1103 if (UNBOUNDP (face)) |
1079 { | 1104 { |
1080 /* a merged face. */ | 1105 /* a merged face. */ |
1081 int i; | 1106 int i; |
1082 struct window *w = XWINDOW (domain); | 1107 struct window *w = XWINDOW (domain); |
1083 | 1108 |
1084 new_val = Qunbound; | 1109 new_val = Qunbound; |
1085 cachel->font_specified[offs] = 0; | 1110 set_bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED(cachel), offs, 0); |
1111 | |
1086 for (i = 0; i < cachel->nfaces; i++) | 1112 for (i = 0; i < cachel->nfaces; i++) |
1087 { | 1113 { |
1088 struct face_cachel *oth; | 1114 struct face_cachel *oth; |
1089 | 1115 |
1090 oth = Dynarr_atp (w->face_cachels, | 1116 oth = Dynarr_atp (w->face_cachels, |
1091 FACE_CACHEL_FINDEX_UNSAFE (cachel, i)); | 1117 FACE_CACHEL_FINDEX_UNSAFE (cachel, i)); |
1092 /* Tout le monde aime la recursion */ | 1118 /* Tout le monde aime la recursion */ |
1093 ensure_face_cachel_contains_charset (oth, domain, charset); | 1119 ensure_face_cachel_contains_charset (oth, domain, charset); |
1094 | 1120 |
1095 if (oth->font_specified[offs]) | 1121 if (bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED(oth), offs)) |
1096 { | 1122 { |
1097 new_val = oth->font[offs]; | 1123 new_val = oth->font[offs]; |
1098 cachel->font_specified[offs] = 1; | 1124 set_bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED(cachel), offs, 1); |
1125 set_bit_vector_bit | |
1126 (FACE_CACHEL_FONT_FINAL_STAGE(cachel), offs, | |
1127 bit_vector_bit(FACE_CACHEL_FONT_FINAL_STAGE(oth), offs)); | |
1099 break; | 1128 break; |
1100 } | 1129 } |
1101 } | 1130 } |
1102 | 1131 |
1103 if (!cachel->font_specified[offs]) | 1132 if (!bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED(cachel), offs)) |
1104 /* need to do the default face. */ | 1133 /* need to do the default face. */ |
1105 { | 1134 { |
1106 struct face_cachel *oth = | 1135 struct face_cachel *oth = |
1107 Dynarr_atp (w->face_cachels, DEFAULT_INDEX); | 1136 Dynarr_atp (w->face_cachels, DEFAULT_INDEX); |
1108 ensure_face_cachel_contains_charset (oth, domain, charset); | 1137 ensure_face_cachel_contains_charset (oth, domain, charset); |
1109 | 1138 |
1110 new_val = oth->font[offs]; | 1139 new_val = oth->font[offs]; |
1111 } | 1140 } |
1112 | 1141 |
1113 if (!UNBOUNDP (cachel->font[offs]) && !EQ (cachel->font[offs], new_val)) | 1142 if (!UNBOUNDP (cachel->font[offs]) && |
1143 !EQ (cachel->font[offs], new_val)) | |
1114 cachel->dirty = 1; | 1144 cachel->dirty = 1; |
1115 cachel->font_updated[offs] = 1; | 1145 set_bit_vector_bit(FACE_CACHEL_FONT_UPDATED(cachel), offs, 1); |
1116 cachel->font[offs] = new_val; | 1146 cachel->font[offs] = new_val; |
1147 DEBUG_FACES("just recursed on the unbound face, returning " | |
1148 "something %s\n", UNBOUNDP(new_val) ? "not bound" | |
1149 : "bound"); | |
1117 return new_val; | 1150 return new_val; |
1118 } | 1151 } |
1119 | 1152 |
1120 new_val = face_property_matching_instance (face, Qfont, charset, domain, | 1153 do { |
1121 /* #### look into error flag */ | 1154 |
1122 ERROR_ME_DEBUG_WARN, 1, Qzero); | 1155 /* Lookup the face, specifying the initial stage and that fallbacks |
1123 if (UNBOUNDP (new_val)) | 1156 shouldn't happen. */ |
1124 { | 1157 new_val = face_property_matching_instance (face, Qfont, charset, domain, |
1125 bound = 0; | 1158 /* ERROR_ME_DEBUG_WARN is |
1126 new_val = face_property_matching_instance (face, Qfont, | 1159 fine here. */ |
1127 charset, domain, | 1160 ERROR_ME_DEBUG_WARN, 1, Qzero, |
1128 /* #### look into error | 1161 initial); |
1129 flag */ | 1162 DEBUG_FACES("just called f_p_m_i on face %s, charset %s, initial, " |
1130 ERROR_ME_DEBUG_WARN, 0, | 1163 "result was something %s\n", |
1131 Qzero); | 1164 XSTRING_DATA(XSYMBOL_NAME(XFACE(cachel->face)->name)), |
1132 } | 1165 XSTRING_DATA(XSYMBOL_NAME(XCHARSET_NAME(charset))), |
1166 UNBOUNDP(new_val) ? "not bound" : "bound"); | |
1167 | |
1168 if (!UNBOUNDP (new_val)) break; | |
1169 | |
1170 bound = 0; | |
1171 /* Lookup the face again, this time allowing the fallback. If this | |
1172 succeeds, it'll give a font intended for the script in question, | |
1173 which is preferable to translating to ISO10646-1 and using the | |
1174 fixed-width fallback. | |
1175 | |
1176 #### This is questionable. The problem is that unusual scripts | |
1177 will typically fallback to the hard-coded values as the user is | |
1178 unlikely to have specified them herself, a common complaint. */ | |
1179 new_val = face_property_matching_instance (face, Qfont, | |
1180 charset, domain, | |
1181 ERROR_ME_DEBUG_WARN, 0, | |
1182 Qzero, | |
1183 initial); | |
1184 | |
1185 DEBUG_FACES("just called f_p_m_i on face %s, charset %s, initial, " | |
1186 "allow fallback, result was something %s\n", | |
1187 XSTRING_DATA(XSYMBOL_NAME(XFACE(cachel->face)->name)), | |
1188 XSTRING_DATA(XSYMBOL_NAME(XCHARSET_NAME(charset))), | |
1189 UNBOUNDP(new_val) ? "not bound" : "bound"); | |
1190 | |
1191 if (!UNBOUNDP(new_val)) | |
1192 { | |
1193 break; | |
1194 } | |
1195 | |
1196 bound = 1; | |
1197 /* Try the face itself with the final-stage specifiers. */ | |
1198 new_val = face_property_matching_instance (face, Qfont, | |
1199 charset, domain, | |
1200 ERROR_ME_DEBUG_WARN, 1, | |
1201 Qzero, | |
1202 final); | |
1203 | |
1204 DEBUG_FACES("just called f_p_m_i on face %s, charset %s, final, " | |
1205 "result was something %s\n", | |
1206 XSTRING_DATA(XSYMBOL_NAME(XFACE(cachel->face)->name)), | |
1207 XSTRING_DATA(XSYMBOL_NAME(XCHARSET_NAME(charset))), | |
1208 UNBOUNDP(new_val) ? "not bound" : "bound"); | |
1209 /* Tell X11 redisplay that it should translate to iso10646-1. */ | |
1210 if (!UNBOUNDP(new_val)) | |
1211 { | |
1212 final_stage = 1; | |
1213 break; | |
1214 } | |
1215 | |
1216 bound = 0; | |
1217 | |
1218 /* Lookup the face again, this time both allowing the fallback and | |
1219 allowing its final stage to be used. */ | |
1220 new_val = face_property_matching_instance (face, Qfont, | |
1221 charset, domain, | |
1222 ERROR_ME_DEBUG_WARN, 0, | |
1223 Qzero, | |
1224 final); | |
1225 | |
1226 DEBUG_FACES("just called f_p_m_i on face %s, charset %s, initial, " | |
1227 "allow fallback, result was something %s\n", | |
1228 XSTRING_DATA(XSYMBOL_NAME(XFACE(cachel->face)->name)), | |
1229 XSTRING_DATA(XSYMBOL_NAME(XCHARSET_NAME(charset))), | |
1230 UNBOUNDP(new_val) ? "not bound" : "bound"); | |
1231 if (!UNBOUNDP(new_val)) | |
1232 { | |
1233 /* Tell X11 redisplay that it should translate to iso10646-1. */ | |
1234 final_stage = 1; | |
1235 break; | |
1236 } | |
1237 } while (0); | |
1238 | |
1133 if (!UNBOUNDP (cachel->font[offs]) && !EQ (new_val, cachel->font[offs])) | 1239 if (!UNBOUNDP (cachel->font[offs]) && !EQ (new_val, cachel->font[offs])) |
1134 cachel->dirty = 1; | 1240 cachel->dirty = 1; |
1135 cachel->font_updated[offs] = 1; | 1241 |
1242 set_bit_vector_bit(FACE_CACHEL_FONT_UPDATED(cachel), offs, 1); | |
1243 set_bit_vector_bit(FACE_CACHEL_FONT_FINAL_STAGE(cachel), offs, | |
1244 final_stage); | |
1245 set_bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED(cachel), offs, | |
1246 (bound || EQ (face, Vdefault_face))); | |
1136 cachel->font[offs] = new_val; | 1247 cachel->font[offs] = new_val; |
1137 cachel->font_specified[offs] = (bound || EQ (face, Vdefault_face)); | |
1138 return new_val; | 1248 return new_val; |
1139 } | 1249 } |
1140 | 1250 |
1141 /* Ensure that the given cachel contains updated fonts for all | 1251 /* Ensure that the given cachel contains updated fonts for all |
1142 the charsets specified. */ | 1252 the charsets specified. */ |
1245 domain = wrap_window (w); | 1355 domain = wrap_window (w); |
1246 update_face_cachel_data (&new_cachel, domain, face); | 1356 update_face_cachel_data (&new_cachel, domain, face); |
1247 Dynarr_add (w->face_cachels, new_cachel); | 1357 Dynarr_add (w->face_cachels, new_cachel); |
1248 | 1358 |
1249 /* The face's background pixmap have not yet been frobbed (see comment | 1359 /* The face's background pixmap have not yet been frobbed (see comment |
1250 int update_face_cachel_data), so we have to do it now */ | 1360 in update_face_cachel_data), so we have to do it now */ |
1251 if (must_finish_frobbing) | 1361 if (must_finish_frobbing) |
1252 { | 1362 { |
1253 int default_face = EQ (face, Vdefault_face); | 1363 int default_face = EQ (face, Vdefault_face); |
1254 struct face_cachel *cachel | 1364 struct face_cachel *cachel |
1255 = Dynarr_atp (w->face_cachels, Dynarr_length (w->face_cachels) - 1); | 1365 = Dynarr_atp (w->face_cachels, Dynarr_length (w->face_cachels) - 1); |
1273 { | 1383 { |
1274 int default_face = EQ (face, Vdefault_face); | 1384 int default_face = EQ (face, Vdefault_face); |
1275 cachel->face = face; | 1385 cachel->face = face; |
1276 | 1386 |
1277 /* We normally only set the _specified flags if the value was | 1387 /* We normally only set the _specified flags if the value was |
1278 actually bound. The exception is for the default face where | 1388 actually bound. The exception is for the default face where |
1279 we always set it since it is the ultimate fallback. */ | 1389 we always set it since it is the ultimate fallback. */ |
1280 | 1390 |
1281 FROB (foreground); | 1391 FROB (foreground); |
1282 FROB (background); | 1392 FROB (background); |
1283 FROB (display_table); | 1393 FROB (display_table); |
1284 | 1394 |
1286 the only one dealing with images. The problem we have here is that | 1396 the only one dealing with images. The problem we have here is that |
1287 frobbing the background pixmap might lead to image instantiation | 1397 frobbing the background pixmap might lead to image instantiation |
1288 which in turn might require that the cache we're building be up to | 1398 which in turn might require that the cache we're building be up to |
1289 date, hence a crash. Here's a typical scenario of this: | 1399 date, hence a crash. Here's a typical scenario of this: |
1290 | 1400 |
1291 - a new window is created and it's face cache elements are | 1401 - a new window is created and its face cache elements are |
1292 initialized through a call to reset_face_cachels[1]. At that point, | 1402 initialized through a call to reset_face_cachels[1]. At that point, |
1293 the cache for the default and modeline faces (normaly taken care of | 1403 the cache for the default and modeline faces (normaly taken care of |
1294 by redisplay itself) are null. | 1404 by redisplay itself) are null. |
1295 - the default face has a background pixmap which needs to be | 1405 - the default face has a background pixmap which needs to be |
1296 instantiated right here, as a consequence of cache initialization. | 1406 instantiated right here, as a consequence of cache initialization. |
1367 | 1477 |
1368 static void | 1478 static void |
1369 merge_face_cachel_data (struct window *w, face_index findex, | 1479 merge_face_cachel_data (struct window *w, face_index findex, |
1370 struct face_cachel *cachel) | 1480 struct face_cachel *cachel) |
1371 { | 1481 { |
1482 int offs; | |
1483 | |
1372 #define FINDEX_FIELD(field) \ | 1484 #define FINDEX_FIELD(field) \ |
1373 Dynarr_atp (w->face_cachels, findex)->field | 1485 Dynarr_atp (w->face_cachels, findex)->field |
1374 | 1486 |
1375 #define FROB(field) \ | 1487 #define FROB(field) \ |
1376 do { \ | 1488 do { \ |
1390 FROB (strikethru); | 1502 FROB (strikethru); |
1391 FROB (highlight); | 1503 FROB (highlight); |
1392 FROB (dim); | 1504 FROB (dim); |
1393 FROB (reverse); | 1505 FROB (reverse); |
1394 FROB (blinking); | 1506 FROB (blinking); |
1395 /* And do ASCII, of course. */ | 1507 |
1396 { | 1508 for (offs = 0; offs < NUM_LEADING_BYTES; ++offs) |
1397 int offs = LEADING_BYTE_ASCII - MIN_LEADING_BYTE; | 1509 { |
1398 | 1510 if (!(bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED(cachel), offs)) |
1399 if (!cachel->font_specified[offs] && FINDEX_FIELD (font_specified[offs])) | 1511 && bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED |
1400 { | 1512 (Dynarr_atp(w->face_cachels, findex)), offs)) |
1401 cachel->font[offs] = FINDEX_FIELD (font[offs]); | 1513 { |
1402 cachel->font_specified[offs] = 1; | 1514 cachel->font[offs] = FINDEX_FIELD (font[offs]); |
1403 cachel->dirty = 1; | 1515 set_bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED(cachel), offs, 1); |
1404 } | 1516 /* Also propagate whether we're translating to Unicode for the |
1405 } | 1517 given face. */ |
1406 | 1518 set_bit_vector_bit(FACE_CACHEL_FONT_FINAL_STAGE(cachel), offs, |
1519 bit_vector_bit(FACE_CACHEL_FONT_FINAL_STAGE | |
1520 (Dynarr_atp(w->face_cachels, | |
1521 findex)), offs)); | |
1522 cachel->dirty = 1; | |
1523 } | |
1524 } | |
1407 #undef FROB | 1525 #undef FROB |
1408 #undef FINDEX_FIELD | 1526 #undef FINDEX_FIELD |
1409 | 1527 |
1410 cachel->updated = 1; | 1528 cachel->updated = 1; |
1411 } | 1529 } |
1412 | 1530 |
1413 /* Initialize a cachel. */ | 1531 /* Initialize a cachel. */ |
1532 /* #### Xft: this function will need to be changed for new font model. */ | |
1414 | 1533 |
1415 void | 1534 void |
1416 reset_face_cachel (struct face_cachel *cachel) | 1535 reset_face_cachel (struct face_cachel *cachel) |
1417 { | 1536 { |
1418 xzero (*cachel); | 1537 xzero (*cachel); |
1427 for (i = 0; i < NUM_LEADING_BYTES; i++) | 1546 for (i = 0; i < NUM_LEADING_BYTES; i++) |
1428 cachel->font[i] = Qunbound; | 1547 cachel->font[i] = Qunbound; |
1429 } | 1548 } |
1430 cachel->display_table = Qunbound; | 1549 cachel->display_table = Qunbound; |
1431 cachel->background_pixmap = Qunbound; | 1550 cachel->background_pixmap = Qunbound; |
1551 FACE_CACHEL_FONT_SPECIFIED (cachel)->size = sizeof(cachel->font_specified); | |
1552 FACE_CACHEL_FONT_UPDATED (cachel)->size = sizeof(cachel->font_updated); | |
1432 } | 1553 } |
1433 | 1554 |
1434 /* Retrieve the index to a cachel for window W that corresponds to | 1555 /* Retrieve the index to a cachel for window W that corresponds to |
1435 the specified face. If necessary, add a new element to the | 1556 the specified face. If necessary, add a new element to the |
1436 cache. */ | 1557 cache. */ |
1467 { | 1588 { |
1468 /* #### Not initialized in batch mode for the stream device. */ | 1589 /* #### Not initialized in batch mode for the stream device. */ |
1469 if (w->face_cachels) | 1590 if (w->face_cachels) |
1470 { | 1591 { |
1471 int i; | 1592 int i; |
1593 face_index fi; | |
1472 | 1594 |
1473 for (i = 0; i < Dynarr_length (w->face_cachels); i++) | 1595 for (i = 0; i < Dynarr_length (w->face_cachels); i++) |
1474 { | 1596 { |
1475 struct face_cachel *cachel = Dynarr_atp (w->face_cachels, i); | 1597 struct face_cachel *cachel = Dynarr_atp (w->face_cachels, i); |
1476 if (cachel->merged_faces) | 1598 if (cachel->merged_faces) |
1477 Dynarr_free (cachel->merged_faces); | 1599 Dynarr_free (cachel->merged_faces); |
1478 } | 1600 } |
1479 Dynarr_reset (w->face_cachels); | 1601 Dynarr_reset (w->face_cachels); |
1480 get_builtin_face_cache_index (w, Vdefault_face); | 1602 /* #### NOTE: be careful with the order ! |
1481 get_builtin_face_cache_index (w, Vmodeline_face); | 1603 The cpp macros DEFAULT_INDEX and MODELINE_INDEX defined in |
1604 redisplay.h depend on the code below. Please make sure to assert the | |
1605 correct values if you ever add new built-in faces here. | |
1606 -- dvl */ | |
1607 fi = get_builtin_face_cache_index (w, Vdefault_face); | |
1608 assert (noninteractive || fi == DEFAULT_INDEX); | |
1609 fi = get_builtin_face_cache_index (w, Vmodeline_face); | |
1610 assert (noninteractive || fi == MODELINE_INDEX); | |
1482 XFRAME (w->frame)->window_face_cache_reset = 1; | 1611 XFRAME (w->frame)->window_face_cache_reset = 1; |
1483 } | 1612 } |
1484 } | 1613 } |
1485 | 1614 |
1486 void | 1615 void |
1490 | 1619 |
1491 for (elt = 0; elt < Dynarr_length (w->face_cachels); elt++) | 1620 for (elt = 0; elt < Dynarr_length (w->face_cachels); elt++) |
1492 Dynarr_atp (w->face_cachels, elt)->dirty = 0; | 1621 Dynarr_atp (w->face_cachels, elt)->dirty = 0; |
1493 } | 1622 } |
1494 | 1623 |
1624 /* #### Xft: this function will need to be changed for new font model. */ | |
1495 void | 1625 void |
1496 mark_face_cachels_as_not_updated (struct window *w) | 1626 mark_face_cachels_as_not_updated (struct window *w) |
1497 { | 1627 { |
1498 int elt; | 1628 int elt; |
1499 | 1629 |
1500 for (elt = 0; elt < Dynarr_length (w->face_cachels); elt++) | 1630 for (elt = 0; elt < Dynarr_length (w->face_cachels); elt++) |
1501 { | 1631 { |
1502 struct face_cachel *cachel = Dynarr_atp (w->face_cachels, elt); | 1632 struct face_cachel *cachel = Dynarr_atp (w->face_cachels, elt); |
1503 int i; | |
1504 | 1633 |
1505 cachel->updated = 0; | 1634 cachel->updated = 0; |
1506 for (i = 0; i < NUM_LEADING_BYTES; i++) | 1635 memset(FACE_CACHEL_FONT_UPDATED(cachel)->bits, 0, |
1507 cachel->font_updated[i] = 0; | 1636 BIT_VECTOR_LONG_STORAGE (NUM_LEADING_BYTES)); |
1508 } | 1637 } |
1509 } | 1638 } |
1510 | 1639 |
1511 #ifdef MEMORY_USAGE_STATS | 1640 #ifdef MEMORY_USAGE_STATS |
1512 | 1641 |
1684 } | 1813 } |
1685 return findex; | 1814 return findex; |
1686 } | 1815 } |
1687 } | 1816 } |
1688 | 1817 |
1818 /* Return a cache index for window W from merging the faces in FACE_LIST. | |
1819 COUNT is the number of faces in the list. | |
1820 | |
1821 The default face should not be included in the list, as it is always | |
1822 implicitly merged into the cachel. | |
1823 | |
1824 WARNING: this interface may change. */ | |
1825 | |
1826 face_index | |
1827 merge_face_list_to_cache_index (struct window *w, | |
1828 Lisp_Object *face_list, int count) | |
1829 { | |
1830 int i; | |
1831 face_index findex = 0; | |
1832 struct face_cachel cachel; | |
1833 | |
1834 reset_face_cachel (&cachel); | |
1835 | |
1836 for (i = 0; i < count; i++) | |
1837 { | |
1838 Lisp_Object face = face_list[i]; | |
1839 | |
1840 if (!NILP (face)) | |
1841 { | |
1842 CHECK_FACE(face); /* #### presumably unnecessary */ | |
1843 findex = get_builtin_face_cache_index (w, face); | |
1844 merge_face_cachel_data (w, findex, &cachel); | |
1845 } | |
1846 } | |
1847 | |
1848 /* Now finally merge in the default face. */ | |
1849 findex = get_builtin_face_cache_index (w, Vdefault_face); | |
1850 merge_face_cachel_data (w, findex, &cachel); | |
1851 | |
1852 return get_merged_face_cache_index (w, &cachel); | |
1853 } | |
1854 | |
1689 | 1855 |
1690 /***************************************************************************** | 1856 /***************************************************************************** |
1691 interface functions | 1857 interface functions |
1692 ****************************************************************************/ | 1858 ****************************************************************************/ |
1693 | 1859 |
1694 static void | 1860 static void |
1695 update_EmacsFrame (Lisp_Object frame, Lisp_Object name) | 1861 update_EmacsFrame (Lisp_Object frame, Lisp_Object name) |
1696 { | 1862 { |
1697 struct frame *frm = XFRAME (frame); | 1863 struct frame *frm = XFRAME (frame); |
1864 | |
1865 if (!FRAME_LIVE_P(frm)) | |
1866 return; | |
1698 | 1867 |
1699 if (EQ (name, Qfont)) | 1868 if (EQ (name, Qfont)) |
1700 MARK_FRAME_SIZE_SLIPPED (frm); | 1869 MARK_FRAME_SIZE_SLIPPED (frm); |
1701 | 1870 |
1702 MAYBE_FRAMEMETH (frm, update_frame_external_traits, (frm, name)); | 1871 MAYBE_FRAMEMETH (frm, update_frame_external_traits, (frm, name)); |
1830 fold = XFACE (old_face); | 1999 fold = XFACE (old_face); |
1831 fnew = XFACE (new_face); | 2000 fnew = XFACE (new_face); |
1832 | 2001 |
1833 #define COPY_PROPERTY(property) \ | 2002 #define COPY_PROPERTY(property) \ |
1834 Fcopy_specifier (fold->property, fnew->property, \ | 2003 Fcopy_specifier (fold->property, fnew->property, \ |
1835 locale, tag_set, exact_p, how_to_add); | 2004 locale, tag_set, exact_p, how_to_add); |
1836 | 2005 |
1837 COPY_PROPERTY (foreground); | 2006 COPY_PROPERTY (foreground); |
1838 COPY_PROPERTY (background); | 2007 COPY_PROPERTY (background); |
1839 COPY_PROPERTY (font); | 2008 COPY_PROPERTY (font); |
1840 COPY_PROPERTY (display_table); | 2009 COPY_PROPERTY (display_table); |
1852 UNGCPRO; | 2021 UNGCPRO; |
1853 | 2022 |
1854 return new_name; | 2023 return new_name; |
1855 } | 2024 } |
1856 | 2025 |
2026 #ifdef MULE | |
2027 | |
2028 Lisp_Object Qone_dimensional, Qtwo_dimensional, Qx_coverage_instantiator; | |
2029 | |
2030 DEFUN ("specifier-tag-one-dimensional-p", | |
2031 Fspecifier_tag_one_dimensional_p, | |
2032 2, 2, 0, /* | |
2033 Return non-nil if (charset-dimension CHARSET) is 1. | |
2034 | |
2035 Used by the X11 platform font code; see `define-specifier-tag'. You | |
2036 shouldn't ever need to call this yourself. | |
2037 */ | |
2038 (charset, UNUSED(stage))) | |
2039 { | |
2040 CHECK_CHARSET(charset); | |
2041 return (1 == XCHARSET_DIMENSION(charset)) ? Qt : Qnil; | |
2042 } | |
2043 | |
2044 DEFUN ("specifier-tag-two-dimensional-p", | |
2045 Fspecifier_tag_two_dimensional_p, | |
2046 2, 2, 0, /* | |
2047 Return non-nil if (charset-dimension CHARSET) is 2. | |
2048 | |
2049 Used by the X11 platform font code; see `define-specifier-tag'. You | |
2050 shouldn't ever need to call this yourself. | |
2051 */ | |
2052 (charset, UNUSED(stage))) | |
2053 { | |
2054 CHECK_CHARSET(charset); | |
2055 return (2 == XCHARSET_DIMENSION(charset)) ? Qt : Qnil; | |
2056 } | |
2057 | |
2058 DEFUN ("specifier-tag-final-stage-p", | |
2059 Fspecifier_tag_final_stage_p, | |
2060 2, 2, 0, /* | |
2061 Return non-nil if STAGE is 'final. | |
2062 | |
2063 Used by the X11 platform font code for giving fallbacks; see | |
2064 `define-specifier-tag'. You shouldn't ever need to call this. | |
2065 */ | |
2066 (UNUSED(charset), stage)) | |
2067 { | |
2068 return EQ(stage, Qfinal) ? Qt : Qnil; | |
2069 } | |
2070 | |
2071 DEFUN ("specifier-tag-initial-stage-p", | |
2072 Fspecifier_tag_initial_stage_p, | |
2073 2, 2, 0, /* | |
2074 Return non-nil if STAGE is 'initial. | |
2075 | |
2076 Used by the X11 platform font code for giving fallbacks; see | |
2077 `define-specifier-tag'. You shouldn't ever need to call this. | |
2078 */ | |
2079 (UNUSED(charset), stage)) | |
2080 { | |
2081 return EQ(stage, Qinitial) ? Qt : Qnil; | |
2082 } | |
2083 | |
2084 DEFUN ("specifier-tag-encode-as-utf-8-p", | |
2085 Fspecifier_tag_encode_as_utf_8_p, | |
2086 2, 2, 0, /* | |
2087 Return t if and only if (charset-property CHARSET 'encode-as-utf-8)). | |
2088 | |
2089 Used by the X11 platform font code; see `define-specifier-tag'. You | |
2090 shouldn't ever need to call this. | |
2091 */ | |
2092 (charset, UNUSED(stage))) | |
2093 { | |
2094 /* Used to check that the stage was initial too. */ | |
2095 CHECK_CHARSET(charset); | |
2096 return XCHARSET_ENCODE_AS_UTF_8(charset) ? Qt : Qnil; | |
2097 } | |
2098 | |
2099 #endif /* MULE */ | |
2100 | |
1857 | 2101 |
1858 void | 2102 void |
1859 syms_of_faces (void) | 2103 syms_of_faces (void) |
1860 { | 2104 { |
1861 INIT_LISP_OBJECT (face); | 2105 INIT_LISP_OBJECT (face); |
1872 DEFSUBR (Fface_name); | 2116 DEFSUBR (Fface_name); |
1873 DEFSUBR (Fbuilt_in_face_specifiers); | 2117 DEFSUBR (Fbuilt_in_face_specifiers); |
1874 DEFSUBR (Fface_list); | 2118 DEFSUBR (Fface_list); |
1875 DEFSUBR (Fmake_face); | 2119 DEFSUBR (Fmake_face); |
1876 DEFSUBR (Fcopy_face); | 2120 DEFSUBR (Fcopy_face); |
2121 | |
2122 #ifdef MULE | |
2123 DEFSYMBOL (Qone_dimensional); | |
2124 DEFSYMBOL (Qtwo_dimensional); | |
2125 DEFSYMBOL (Qx_coverage_instantiator); | |
2126 | |
2127 /* I would much prefer these were in Lisp. */ | |
2128 DEFSUBR (Fspecifier_tag_one_dimensional_p); | |
2129 DEFSUBR (Fspecifier_tag_two_dimensional_p); | |
2130 DEFSUBR (Fspecifier_tag_initial_stage_p); | |
2131 DEFSUBR (Fspecifier_tag_final_stage_p); | |
2132 DEFSUBR (Fspecifier_tag_encode_as_utf_8_p); | |
2133 #endif /* MULE */ | |
1877 | 2134 |
1878 DEFSYMBOL (Qfacep); | 2135 DEFSYMBOL (Qfacep); |
1879 DEFSYMBOL (Qforeground); | 2136 DEFSYMBOL (Qforeground); |
1880 DEFSYMBOL (Qbackground); | 2137 DEFSYMBOL (Qbackground); |
1881 /* Qfont defined in general.c */ | 2138 /* Qfont defined in general.c */ |
1935 Vright_margin_face = Qnil; | 2192 Vright_margin_face = Qnil; |
1936 staticpro (&Vtext_cursor_face); | 2193 staticpro (&Vtext_cursor_face); |
1937 Vtext_cursor_face = Qnil; | 2194 Vtext_cursor_face = Qnil; |
1938 staticpro (&Vpointer_face); | 2195 staticpro (&Vpointer_face); |
1939 Vpointer_face = Qnil; | 2196 Vpointer_face = Qnil; |
2197 | |
2198 #ifdef DEBUG_XEMACS | |
2199 DEFVAR_INT ("debug-x-faces", &debug_x_faces /* | |
2200 If non-zero, display debug information about X faces | |
2201 */ ); | |
2202 debug_x_faces = 0; | |
2203 #endif | |
1940 | 2204 |
1941 { | 2205 { |
1942 Lisp_Object syms[20]; | 2206 Lisp_Object syms[20]; |
1943 int n = 0; | 2207 int n = 0; |
1944 | 2208 |
1995 #endif | 2259 #endif |
1996 set_specifier_fallback (Fget (Vdefault_face, Qforeground, Qnil), fg_fb); | 2260 set_specifier_fallback (Fget (Vdefault_face, Qforeground, Qnil), fg_fb); |
1997 set_specifier_fallback (Fget (Vdefault_face, Qbackground, Qnil), bg_fb); | 2261 set_specifier_fallback (Fget (Vdefault_face, Qbackground, Qnil), bg_fb); |
1998 } | 2262 } |
1999 | 2263 |
2000 /* #### We may want to have different fallback values if NeXTstep | |
2001 support is compiled in. */ | |
2002 { | 2264 { |
2003 Lisp_Object inst_list = Qnil; | 2265 Lisp_Object inst_list = Qnil; |
2004 | 2266 |
2005 #if defined (HAVE_X_WINDOWS) || defined (HAVE_GTK) | 2267 #if defined (HAVE_X_WINDOWS) || defined (HAVE_GTK) |
2006 | 2268 |
2269 #ifdef HAVE_GTK | |
2270 Lisp_Object device_symbol = Qgtk; | |
2271 #else | |
2272 Lisp_Object device_symbol = Qx; | |
2273 #endif | |
2274 | |
2275 const Ascbyte **fontptr; | |
2276 | |
2007 const Ascbyte *fonts[] = | 2277 const Ascbyte *fonts[] = |
2008 { | 2278 { |
2009 /************** ISO-8859 fonts *************/ | 2279 #ifdef USE_XFT |
2010 | 2280 /************** Xft fonts *************/ |
2011 "-*-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-*", | 2281 |
2012 "-*-fixed-medium-r-*-*-*-120-*-*-*-*-iso8859-*", | 2282 /* Note that fontconfig can search for several font families in one |
2013 "-*-courier-*-r-*-*-*-120-*-*-*-*-iso8859-*", | 2283 call. We should use this facility. */ |
2014 "-*-fixed-*-r-*-*-*-120-*-*-*-*-iso8859-*", | 2284 "Monospace-12", |
2015 /* Next try for any "medium" charcell or monospaced iso8859 font. */ | 2285 /* do we need to worry about non-Latin characters for monospace? |
2016 "-*-*-medium-r-*-*-*-120-*-*-m-*-iso8859-*", | 2286 No, at least in Debian's implementation of Xft. |
2017 "-*-*-medium-r-*-*-*-120-*-*-c-*-iso8859-*", | 2287 We should recommend that "gothic" and "mincho" aliases be created? */ |
2018 /* Next try for any charcell or monospaced iso8859 font. */ | 2288 "Sazanami Mincho-12", |
2019 "-*-*-*-r-*-*-*-120-*-*-m-*-iso8859-*", | 2289 /* Japanese #### add encoding info? */ |
2020 "-*-*-*-r-*-*-*-120-*-*-c-*-iso8859-*", | 2290 /* Arphic for Chinese? */ |
2021 | 2291 /* Korean */ |
2022 /* Repeat, any size */ | 2292 #else |
2023 "-*-courier-medium-r-*-*-*-*-*-*-*-*-iso8859-*", | 2293 /* The default Japanese fonts installed with XFree86 4.0 use this |
2024 "-*-fixed-medium-r-*-*-*-*-*-*-*-*-iso8859-*", | 2294 point size, and the -misc-fixed fonts (which look really bad with |
2025 "-*-courier-*-r-*-*-*-*-*-*-*-*-iso8859-*", | 2295 Han characters) don't. We need to prefer the former. */ |
2026 "-*-fixed-*-r-*-*-*-*-*-*-*-*-iso8859-*", | 2296 "-*-*-medium-r-*-*-*-150-*-*-c-*-*-*", |
2027 /* Next try for any "medium" charcell or monospaced iso8859 font. */ | 2297 /* And the Chinese ones, maddeningly, use this one. (But on 4.0, while |
2028 "-*-*-medium-r-*-*-*-*-*-*-m-*-iso8859-*", | 2298 XListFonts returns them, XLoadQueryFont on the fully-specified XLFD |
2029 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-*", | 2299 corresponding to one of them fails!) */ |
2030 /* Next try for any charcell or monospaced iso8859 font. */ | 2300 "-*-*-medium-r-*-*-*-160-*-*-c-*-*-*", |
2031 "-*-*-*-r-*-*-*-*-*-*-m-*-iso8859-*", | 2301 "-*-*-medium-r-*-*-*-170-*-*-c-*-*-*", |
2032 "-*-*-*-r-*-*-*-*-*-*-c-*-iso8859-*", | 2302 #endif |
2033 | |
2034 /* Non-proportional fonts -- last resort. */ | |
2035 "-*-*-*-r-*-*-*-120-*-*-*-*-iso8859-*", | |
2036 "-*-*-*-r-*-*-*-*-*-*-*-*-iso8859-*", | |
2037 "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-*", | |
2038 | |
2039 /************* Japanese fonts ************/ | |
2040 | |
2041 /* Following 3 fonts proposed by Teruhiko.Kurosaka@Japan.eng.sun */ | |
2042 "-sun-gothic-medium-r-normal--14-120-75-75-c-60-jisx0201.1976-0", | |
2043 "-sun-gothic-medium-r-normal--14-120-75-75-c-120-jisx0208.1983-0", | |
2044 "-wadalab-gothic-medium-r-normal--14-120-75-75-c-120-jisx0212.1990-0", | |
2045 | |
2046 /* Other Japanese fonts */ | |
2047 "-*-fixed-medium-r-*--*-jisx0201.1976-*", | |
2048 "-*-fixed-medium-r-*--*-jisx0208.1983-*", | |
2049 "-*-fixed-medium-r-*--*-jisx0212*-*", | |
2050 "-*-*-*-r-*--*-jisx0201.1976-*", | |
2051 "-*-*-*-r-*--*-jisx0208.1983-*", | |
2052 "-*-*-*-r-*--*-jisx0212*-*", | |
2053 | |
2054 /************* Chinese fonts ************/ | |
2055 | |
2056 "-*-*-medium-r-*--*-gb2312.1980-*", | |
2057 "-*-fixed-medium-r-*--*-cns11643*-*", | |
2058 | |
2059 "-*-fixed-medium-r-*--*-big5*-*," | |
2060 "-*-fixed-medium-r-*--*-sisheng_cwnn-0", | |
2061 | |
2062 /************* Korean fonts *************/ | |
2063 | |
2064 "-*-mincho-medium-r-*--*-ksc5601.1987-*", | |
2065 | |
2066 /************* Thai fonts **************/ | |
2067 | |
2068 "-*-fixed-medium-r-*--*-tis620.2529-1", | |
2069 | |
2070 /************* Other fonts (nonstandard) *************/ | |
2071 | |
2072 "-*-fixed-medium-r-*--*-viscii1.1-1", | |
2073 "-*-fixed-medium-r-*--*-mulearabic-*", | |
2074 "-*-fixed-medium-r-*--*-muleipa-*", | |
2075 "-*-fixed-medium-r-*--*-ethio-*", | |
2076 | |
2077 /************* Unicode fonts **************/ | |
2078 | |
2079 /* #### We don't yet support Unicode fonts, but doing so would not be | |
2080 hard because all the machinery has already been added for Windows | |
2081 support. We need to do this: | |
2082 | |
2083 (1) Add "stage 2" support in find_charset_font()/etc.; this finds | |
2084 an appropriate Unicode font after all the charset-specific fonts | |
2085 have been checked. This should look at the per-char font info and | |
2086 check whether we have support for some of the chars in the | |
2087 charset. (#### Bogus, but that's the way it currently works) | |
2088 | |
2089 (2) Record in the font instance a flag indicating when we're | |
2090 dealing with a Unicode font. | |
2091 | |
2092 (3) Notice this flag in separate_textual_runs() and translate the | |
2093 text into Unicode if so. | |
2094 */ | |
2095 | |
2096 "-*-courier-medium-r-*-*-*-120-*-*-*-*-iso10646-1", | |
2097 "-*-fixed-medium-r-*-*-*-120-*-*-*-*-iso10646-1", | |
2098 "-*-courier-*-r-*-*-*-120-*-*-*-*-iso10646-1", | |
2099 "-*-fixed-*-r-*-*-*-120-*-*-*-*-iso10646-1", | |
2100 /* Next try for any "medium" charcell or monospaced iso8859 font. */ | |
2101 "-*-*-medium-r-*-*-*-120-*-*-m-*-iso10646-1", | |
2102 "-*-*-medium-r-*-*-*-120-*-*-c-*-iso10646-1", | |
2103 /* Next try for any charcell or monospaced iso8859 font. */ | |
2104 "-*-*-*-r-*-*-*-120-*-*-m-*-iso10646-1", | |
2105 "-*-*-*-r-*-*-*-120-*-*-c-*-iso10646-1", | |
2106 | |
2107 /* Repeat, any size */ | |
2108 "-*-courier-medium-r-*-*-*-*-*-*-*-*-iso10646-1", | |
2109 "-*-fixed-medium-r-*-*-*-*-*-*-*-*-iso10646-1", | |
2110 "-*-courier-*-r-*-*-*-*-*-*-*-*-iso10646-1", | |
2111 "-*-fixed-*-r-*-*-*-*-*-*-*-*-iso10646-1", | |
2112 /* Next try for any "medium" charcell or monospaced iso8859 font. */ | |
2113 "-*-*-medium-r-*-*-*-*-*-*-m-*-iso10646-1", | |
2114 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso10646-1", | |
2115 /* Next try for any charcell or monospaced iso8859 font. */ | |
2116 "-*-*-*-r-*-*-*-*-*-*-m-*-iso10646-1", | |
2117 "-*-*-*-r-*-*-*-*-*-*-c-*-iso10646-1", | |
2118 | |
2119 /* Non-proportional fonts -- last resort. */ | |
2120 "-*-*-*-r-*-*-*-120-*-*-*-*-iso10646-1", | |
2121 "-*-*-*-r-*-*-*-*-*-*-*-*-iso10646-1", | |
2122 "-*-*-*-*-*-*-*-*-*-*-*-*-iso10646-1", | |
2123 | |
2124 /*********** Last resort ***********/ | |
2125 | |
2126 /* Boy, we sure are losing now. Try the above, but in any encoding. */ | |
2127 "-*-*-medium-r-*-*-*-120-*-*-m-*-*-*", | |
2128 "-*-*-medium-r-*-*-*-120-*-*-c-*-*-*", | |
2129 "-*-*-*-r-*-*-*-120-*-*-m-*-*-*", | |
2130 "-*-*-*-r-*-*-*-120-*-*-c-*-*-*", | |
2131 /* Hello? Please? */ | |
2132 "-*-*-*-r-*-*-*-120-*-*-*-*-*-*", | |
2133 "-*-*-*-*-*-*-*-120-*-*-*-*-*-*", | |
2134 "-*-*-*-*-*-*-*-*-*-*-*-*-*-*", | |
2135 "*" | |
2136 }; | 2303 }; |
2137 const Ascbyte **fontptr; | 2304 |
2138 | 2305 #ifdef MULE |
2139 #ifdef HAVE_X_WINDOWS | 2306 |
2307 /* Define some specifier tags for classes of character sets. Combining | |
2308 these allows for distinct fallback fonts for distinct dimensions of | |
2309 character sets and stages. */ | |
2310 | |
2311 define_specifier_tag(Qtwo_dimensional, Qnil, | |
2312 intern ("specifier-tag-two-dimensional-p")); | |
2313 | |
2314 define_specifier_tag(Qone_dimensional, Qnil, | |
2315 intern ("specifier-tag-one-dimensional-p")); | |
2316 | |
2317 define_specifier_tag(Qinitial, Qnil, | |
2318 intern ("specifier-tag-initial-stage-p")); | |
2319 | |
2320 define_specifier_tag(Qfinal, Qnil, | |
2321 intern ("specifier-tag-final-stage-p")); | |
2322 | |
2323 define_specifier_tag (Qencode_as_utf_8, Qnil, | |
2324 intern("specifier-tag-encode-as-utf-8-p")); | |
2325 | |
2326 /* This tag is used to group those instantiators made available in the | |
2327 fallback for the sake of coverage of obscure characters, notably | |
2328 Markus Kuhn's misc-fixed fonts. They will be copied from the fallback | |
2329 when the default face is determined from X resources at startup. */ | |
2330 define_specifier_tag (Qx_coverage_instantiator, Qnil, Qnil); | |
2331 | |
2332 #endif /* MULE */ | |
2333 | |
2334 #ifdef USE_XFT | |
2140 for (fontptr = fonts + countof(fonts) - 1; fontptr >= fonts; fontptr--) | 2335 for (fontptr = fonts + countof(fonts) - 1; fontptr >= fonts; fontptr--) |
2141 inst_list = Fcons (Fcons (list1 (Qx), build_string (*fontptr)), | 2336 inst_list = Fcons (Fcons (list1 (device_symbol), |
2337 build_string (*fontptr)), | |
2142 inst_list); | 2338 inst_list); |
2143 #endif /* HAVE_X_WINDOWS */ | 2339 |
2144 | 2340 #else /* !USE_XFT */ |
2145 #ifdef HAVE_GTK | 2341 inst_list = |
2342 Fcons | |
2343 (Fcons | |
2344 (list1 (device_symbol), | |
2345 /* grrr. This really does need to be "*", not an XLFD. | |
2346 An unspecified XLFD won't pick up stuff like 10x20. */ | |
2347 build_string ("*")), | |
2348 inst_list); | |
2349 #ifdef MULE | |
2350 | |
2351 /* For Han characters and Ethiopic, we want the misc-fixed font used to | |
2352 be distinct from that for alphabetic scripts, because the font | |
2353 specified below is distractingly ugly when used for Han characters | |
2354 (this is slightly less so) and because its coverage isn't up to | |
2355 handling them (well, chiefly, it's not up to handling Ethiopic--we do | |
2356 have charset-specific fallbacks for the East Asian charsets.) */ | |
2357 inst_list = | |
2358 Fcons | |
2359 (Fcons | |
2360 (list4(device_symbol, Qtwo_dimensional, Qfinal, Qx_coverage_instantiator), | |
2361 build_string | |
2362 ("-misc-fixed-medium-r-normal--15-140-75-75-c-90-iso10646-1")), | |
2363 inst_list); | |
2364 | |
2365 /* Use Markus Kuhn's version of misc-fixed as the font for the font for | |
2366 when a given charset's registries can't be found and redisplay for | |
2367 that charset falls back to iso10646-1. */ | |
2368 | |
2369 inst_list = | |
2370 Fcons | |
2371 (Fcons | |
2372 (list4(device_symbol, Qone_dimensional, Qfinal, Qx_coverage_instantiator), | |
2373 build_string | |
2374 ("-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1")), | |
2375 inst_list); | |
2376 | |
2146 for (fontptr = fonts + countof(fonts) - 1; fontptr >= fonts; fontptr--) | 2377 for (fontptr = fonts + countof(fonts) - 1; fontptr >= fonts; fontptr--) |
2147 inst_list = Fcons (Fcons (list1 (Qgtk), build_string (*fontptr)), | 2378 inst_list = Fcons (Fcons (list3 (device_symbol, |
2379 Qtwo_dimensional, Qinitial), | |
2380 build_string (*fontptr)), | |
2148 inst_list); | 2381 inst_list); |
2149 #endif /* HAVE_GTK */ | 2382 |
2383 /* We need to set the font for the JIT-ucs-charsets separately from the | |
2384 final stage, since otherwise it picks up the two-dimensional | |
2385 specification (see specifier-tag-two-dimensional-initial-stage-p | |
2386 above). They also use Markus Kuhn's ISO 10646-1 fixed fonts for | |
2387 redisplay. */ | |
2388 | |
2389 inst_list = | |
2390 Fcons | |
2391 (Fcons | |
2392 (list4(device_symbol, Qencode_as_utf_8, Qinitial, Qx_coverage_instantiator), | |
2393 build_string | |
2394 ("-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1")), | |
2395 inst_list); | |
2396 | |
2397 #endif /* MULE */ | |
2398 | |
2399 /* Needed to make sure that charsets with non-specified fonts don't | |
2400 use bold and oblique first if medium and regular are available. */ | |
2401 inst_list = | |
2402 Fcons | |
2403 (Fcons | |
2404 (list1 (device_symbol), | |
2405 build_string ("-*-*-medium-r-*-*-*-120-*-*-c-*-*-*")), | |
2406 inst_list); | |
2407 | |
2408 /* With a Cygwin XFree86 install, this returns the best (clearest, | |
2409 most readable) font I can find when scaling of bitmap fonts is | |
2410 turned on, as it is by default. (WHO IN THE NAME OF CHRIST THOUGHT | |
2411 THAT WAS A GOOD IDEA?!?!) The other fonts that used to be specified | |
2412 here gave horrendous results. */ | |
2413 | |
2414 inst_list = | |
2415 Fcons | |
2416 (Fcons | |
2417 (list1 (device_symbol), | |
2418 build_string ("-*-lucidatypewriter-medium-r-*-*-*-120-*-*-*-*-*-*")), | |
2419 inst_list); | |
2420 | |
2421 #endif /* !USE_XFT */ | |
2422 | |
2150 #endif /* HAVE_X_WINDOWS || HAVE_GTK */ | 2423 #endif /* HAVE_X_WINDOWS || HAVE_GTK */ |
2151 | 2424 |
2152 #ifdef HAVE_TTY | 2425 #ifdef HAVE_TTY |
2153 inst_list = Fcons (Fcons (list1 (Qtty), build_string ("normal")), | 2426 inst_list = Fcons (Fcons (list1 (Qtty), build_string ("normal")), |
2154 inst_list); | 2427 inst_list); |
2155 #endif /* HAVE_TTY */ | 2428 #endif /* HAVE_TTY */ |
2156 | 2429 |
2157 #ifdef HAVE_MS_WINDOWS | 2430 #ifdef HAVE_MS_WINDOWS |
2158 { | 2431 { |
2159 const Ascbyte *mswfonts[] = | 2432 const Ascbyte *mswfonts[] = |
2160 { | 2433 { |
2161 "Courier New:Regular:10::", | 2434 "Courier New:Regular:10::", |
2162 "Courier:Regular:10::", | 2435 "Courier:Regular:10::", |
2163 ":Regular:10::" | 2436 ":Regular:10::" |
2164 }; | 2437 }; |
2165 const Ascbyte **mswfontptr; | 2438 const Ascbyte **mswfontptr; |
2166 | 2439 |
2167 for (mswfontptr = mswfonts + countof (mswfonts) - 1; | 2440 for (mswfontptr = mswfonts + countof (mswfonts) - 1; |
2168 mswfontptr >= mswfonts; mswfontptr--) | 2441 mswfontptr >= mswfonts; mswfontptr--) |
2169 { | 2442 { |
2170 /* display device */ | 2443 /* display device */ |
2171 inst_list = Fcons (Fcons (list1 (Qmswindows), | 2444 inst_list = Fcons (Fcons (list1 (Qmswindows), |
2172 build_string (*mswfontptr)), | 2445 build_string (*mswfontptr)), |
2173 inst_list); | 2446 inst_list); |
2174 /* printer device */ | 2447 /* printer device */ |
2175 inst_list = Fcons (Fcons (list1 (Qmsprinter), | 2448 inst_list = Fcons (Fcons (list1 (Qmsprinter), |
2176 build_string (*mswfontptr)), | 2449 build_string (*mswfontptr)), |
2177 inst_list); | 2450 inst_list); |
2178 } | 2451 } |
2179 /* Use Lucida Console rather than Courier New if it exists -- the | 2452 /* Use Lucida Console rather than Courier New if it exists -- the |
2180 line spacing is much less, so many more lines fit with the same | 2453 line spacing is much less, so many more lines fit with the same |
2181 size font. (And it's specifically designed for screens.) */ | 2454 size font. (And it's specifically designed for screens.) */ |
2182 inst_list = Fcons (Fcons (list1 (Qmswindows), | 2455 inst_list = Fcons (Fcons (list1 (Qmswindows), |
2183 build_string ("Lucida Console:Regular:10::")), | 2456 build_string ("Lucida Console:Regular:10::")), |
2184 inst_list); | 2457 inst_list); |
2185 } | 2458 } |
2186 #endif /* HAVE_MS_WINDOWS */ | 2459 #endif /* HAVE_MS_WINDOWS */ |
2210 /* Provide some last-resort fallbacks for gui-element face which | 2483 /* Provide some last-resort fallbacks for gui-element face which |
2211 mustn't default to default. */ | 2484 mustn't default to default. */ |
2212 { | 2485 { |
2213 Lisp_Object fg_fb = Qnil, bg_fb = Qnil; | 2486 Lisp_Object fg_fb = Qnil, bg_fb = Qnil; |
2214 | 2487 |
2488 /* #### gui-element face doesn't have a font property? | |
2489 But it gets referred to later! */ | |
2215 #ifdef HAVE_GTK | 2490 #ifdef HAVE_GTK |
2216 /* We need to put something in there, or error checking gets | 2491 /* We need to put something in there, or error checking gets |
2217 #%!@#ed up before the styles are set, which override the | 2492 #%!@#ed up before the styles are set, which override the |
2218 fallbacks. */ | 2493 fallbacks. */ |
2219 fg_fb = acons (list1 (Qgtk), build_string ("black"), fg_fb); | 2494 fg_fb = acons (list1 (Qgtk), build_string ("black"), fg_fb); |
2281 | 2556 |
2282 /* widget is another gui element */ | 2557 /* widget is another gui element */ |
2283 Vwidget_face = Fmake_face (Qwidget, | 2558 Vwidget_face = Fmake_face (Qwidget, |
2284 build_msg_string ("widget face"), | 2559 build_msg_string ("widget face"), |
2285 Qnil); | 2560 Qnil); |
2561 /* #### weird ... the gui-element face doesn't have its own font yet */ | |
2286 set_specifier_fallback (Fget (Vwidget_face, Qfont, Qunbound), | 2562 set_specifier_fallback (Fget (Vwidget_face, Qfont, Qunbound), |
2287 Fget (Vgui_element_face, Qfont, Qunbound)); | 2563 Fget (Vgui_element_face, Qfont, Qunbound)); |
2288 set_specifier_fallback (Fget (Vwidget_face, Qforeground, Qunbound), | 2564 set_specifier_fallback (Fget (Vwidget_face, Qforeground, Qunbound), |
2289 Fget (Vgui_element_face, Qforeground, Qunbound)); | 2565 Fget (Vgui_element_face, Qforeground, Qunbound)); |
2290 set_specifier_fallback (Fget (Vwidget_face, Qbackground, Qunbound), | 2566 set_specifier_fallback (Fget (Vwidget_face, Qbackground, Qunbound), |