comparison src/faces.c @ 3659:98af8a976fc3

[xemacs-hg @ 2006-11-05 22:31:31 by aidan] Support specifying fonts for particular character sets in Mule; support translation to ISO 10646-1 for Mule character sets without an otherwise matching font; move to a vector of X11-charset-X11-registry instead of a regex for the charset-registry property.
author aidan
date Sun, 05 Nov 2006 22:31:46 +0000
parents ad2f4ae9895b
children 3ef0aaf3dc34
comparison
equal deleted inserted replaced
3658:0db1aaedbbef 3659:98af8a976fc3
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);
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 }
1069 ensure_face_cachel_contains_charset (struct face_cachel *cachel, 1082 ensure_face_cachel_contains_charset (struct face_cachel *cachel,
1070 Lisp_Object domain, Lisp_Object charset) 1083 Lisp_Object domain, Lisp_Object charset)
1071 { 1084 {
1072 Lisp_Object new_val; 1085 Lisp_Object new_val;
1073 Lisp_Object face = cachel->face; 1086 Lisp_Object face = cachel->face;
1074 int bound = 1; 1087 int bound = 1, final_stage = 0;
1075 int offs = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE; 1088 int offs = XCHARSET_LEADING_BYTE (charset) - MIN_LEADING_BYTE;
1076 1089
1077 if (!UNBOUNDP (cachel->font[offs]) 1090 if (!UNBOUNDP (cachel->font[offs]) &&
1078 && cachel->font_updated[offs]) 1091 bit_vector_bit(FACE_CACHEL_FONT_UPDATED (cachel), offs))
1079 return cachel->font[offs]; 1092 return cachel->font[offs];
1080 1093
1081 if (UNBOUNDP (face)) 1094 if (UNBOUNDP (face))
1082 { 1095 {
1083 /* a merged face. */ 1096 /* a merged face. */
1084 int i; 1097 int i;
1085 struct window *w = XWINDOW (domain); 1098 struct window *w = XWINDOW (domain);
1086 1099
1087 new_val = Qunbound; 1100 new_val = Qunbound;
1088 cachel->font_specified[offs] = 0; 1101 set_bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED(cachel), offs, 0);
1102
1089 for (i = 0; i < cachel->nfaces; i++) 1103 for (i = 0; i < cachel->nfaces; i++)
1090 { 1104 {
1091 struct face_cachel *oth; 1105 struct face_cachel *oth;
1092 1106
1093 oth = Dynarr_atp (w->face_cachels, 1107 oth = Dynarr_atp (w->face_cachels,
1094 FACE_CACHEL_FINDEX_UNSAFE (cachel, i)); 1108 FACE_CACHEL_FINDEX_UNSAFE (cachel, i));
1095 /* Tout le monde aime la recursion */ 1109 /* Tout le monde aime la recursion */
1096 ensure_face_cachel_contains_charset (oth, domain, charset); 1110 ensure_face_cachel_contains_charset (oth, domain, charset);
1097 1111
1098 if (oth->font_specified[offs]) 1112 if (bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED(oth), offs))
1099 { 1113 {
1100 new_val = oth->font[offs]; 1114 new_val = oth->font[offs];
1101 cachel->font_specified[offs] = 1; 1115 set_bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED(cachel), offs, 1);
1116 set_bit_vector_bit
1117 (FACE_CACHEL_FONT_FINAL_STAGE(cachel), offs,
1118 bit_vector_bit(FACE_CACHEL_FONT_FINAL_STAGE(oth), offs));
1102 break; 1119 break;
1103 } 1120 }
1104 } 1121 }
1105 1122
1106 if (!cachel->font_specified[offs]) 1123 if (!bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED(cachel), offs))
1107 /* need to do the default face. */ 1124 /* need to do the default face. */
1108 { 1125 {
1109 struct face_cachel *oth = 1126 struct face_cachel *oth =
1110 Dynarr_atp (w->face_cachels, DEFAULT_INDEX); 1127 Dynarr_atp (w->face_cachels, DEFAULT_INDEX);
1111 ensure_face_cachel_contains_charset (oth, domain, charset); 1128 ensure_face_cachel_contains_charset (oth, domain, charset);
1112 1129
1113 new_val = oth->font[offs]; 1130 new_val = oth->font[offs];
1114 } 1131 }
1115 1132
1116 if (!UNBOUNDP (cachel->font[offs]) && !EQ (cachel->font[offs], new_val)) 1133 if (!UNBOUNDP (cachel->font[offs]) &&
1134 !EQ (cachel->font[offs], new_val))
1117 cachel->dirty = 1; 1135 cachel->dirty = 1;
1118 cachel->font_updated[offs] = 1; 1136 set_bit_vector_bit(FACE_CACHEL_FONT_UPDATED(cachel), offs, 1);
1119 cachel->font[offs] = new_val; 1137 cachel->font[offs] = new_val;
1138 DEBUG_FACES("just recursed on the unbound face, returning "
1139 "something %s\n", UNBOUNDP(new_val) ? "not bound"
1140 : "bound");
1120 return new_val; 1141 return new_val;
1121 } 1142 }
1122 1143
1123 new_val = face_property_matching_instance (face, Qfont, charset, domain, 1144 do {
1124 /* #### look into error flag */ 1145
1125 ERROR_ME_DEBUG_WARN, 1, Qzero); 1146 /* Lookup the face, specifying the initial stage and that fallbacks
1126 if (UNBOUNDP (new_val)) 1147 shouldn't happen. */
1127 { 1148 new_val = face_property_matching_instance (face, Qfont, charset, domain,
1128 bound = 0; 1149 /* ERROR_ME_DEBUG_WARN is
1129 new_val = face_property_matching_instance (face, Qfont, 1150 fine here. */
1130 charset, domain, 1151 ERROR_ME_DEBUG_WARN, 1, Qzero,
1131 /* #### look into error 1152 initial);
1132 flag */ 1153 DEBUG_FACES("just called f_p_m_i on face %s, charset %s, initial, "
1133 ERROR_ME_DEBUG_WARN, 0, 1154 "result was something %s\n",
1134 Qzero); 1155 XSTRING_DATA(XSYMBOL_NAME(XFACE(cachel->face)->name)),
1135 } 1156 XSTRING_DATA(XSYMBOL_NAME(XCHARSET_NAME(charset))),
1157 UNBOUNDP(new_val) ? "not bound" : "bound");
1158
1159 if (!UNBOUNDP (new_val)) break;
1160
1161 bound = 0;
1162 /* Lookup the face again, this time allowing the fallback. If this
1163 succeeds, it'll give a font intended for the script in question,
1164 which is preferable to translating to ISO10646-1 and using the
1165 fixed-with fallback. */
1166 new_val = face_property_matching_instance (face, Qfont,
1167 charset, domain,
1168 ERROR_ME_DEBUG_WARN, 0,
1169 Qzero,
1170 initial);
1171
1172 DEBUG_FACES("just called f_p_m_i on face %s, charset %s, initial, "
1173 "allow fallback, result was something %s\n",
1174 XSTRING_DATA(XSYMBOL_NAME(XFACE(cachel->face)->name)),
1175 XSTRING_DATA(XSYMBOL_NAME(XCHARSET_NAME(charset))),
1176 UNBOUNDP(new_val) ? "not bound" : "bound");
1177
1178 if (!UNBOUNDP(new_val))
1179 {
1180 break;
1181 }
1182
1183 bound = 1;
1184 /* Try the face itself with the final-stage specifiers. */
1185 new_val = face_property_matching_instance (face, Qfont,
1186 charset, domain,
1187 ERROR_ME_DEBUG_WARN, 1,
1188 Qzero,
1189 final);
1190
1191 DEBUG_FACES("just called f_p_m_i on face %s, charset %s, final, "
1192 "result was something %s\n",
1193 XSTRING_DATA(XSYMBOL_NAME(XFACE(cachel->face)->name)),
1194 XSTRING_DATA(XSYMBOL_NAME(XCHARSET_NAME(charset))),
1195 UNBOUNDP(new_val) ? "not bound" : "bound");
1196 /* Tell X11 redisplay that it should translate to iso10646-1. */
1197 if (!UNBOUNDP(new_val))
1198 {
1199 final_stage = 1;
1200 break;
1201 }
1202
1203 bound = 0;
1204
1205 /* Lookup the face again, this time both allowing the fallback and
1206 allowing its final stage to be used. */
1207 new_val = face_property_matching_instance (face, Qfont,
1208 charset, domain,
1209 ERROR_ME_DEBUG_WARN, 0,
1210 Qzero,
1211 final);
1212
1213 DEBUG_FACES("just called f_p_m_i on face %s, charset %s, initial, "
1214 "allow fallback, result was something %s\n",
1215 XSTRING_DATA(XSYMBOL_NAME(XFACE(cachel->face)->name)),
1216 XSTRING_DATA(XSYMBOL_NAME(XCHARSET_NAME(charset))),
1217 UNBOUNDP(new_val) ? "not bound" : "bound");
1218 if (!UNBOUNDP(new_val))
1219 {
1220 /* Tell X11 redisplay that it should translate to iso10646-1. */
1221 final_stage = 1;
1222 break;
1223 }
1224 } while (0);
1225
1136 if (!UNBOUNDP (cachel->font[offs]) && !EQ (new_val, cachel->font[offs])) 1226 if (!UNBOUNDP (cachel->font[offs]) && !EQ (new_val, cachel->font[offs]))
1137 cachel->dirty = 1; 1227 cachel->dirty = 1;
1138 cachel->font_updated[offs] = 1; 1228
1229 set_bit_vector_bit(FACE_CACHEL_FONT_UPDATED(cachel), offs, 1);
1230 set_bit_vector_bit(FACE_CACHEL_FONT_FINAL_STAGE(cachel), offs,
1231 final_stage);
1232 set_bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED(cachel), offs,
1233 (bound || EQ (face, Vdefault_face)));
1139 cachel->font[offs] = new_val; 1234 cachel->font[offs] = new_val;
1140 cachel->font_specified[offs] = (bound || EQ (face, Vdefault_face));
1141 return new_val; 1235 return new_val;
1142 } 1236 }
1143 1237
1144 /* Ensure that the given cachel contains updated fonts for all 1238 /* Ensure that the given cachel contains updated fonts for all
1145 the charsets specified. */ 1239 the charsets specified. */
1370 1464
1371 static void 1465 static void
1372 merge_face_cachel_data (struct window *w, face_index findex, 1466 merge_face_cachel_data (struct window *w, face_index findex,
1373 struct face_cachel *cachel) 1467 struct face_cachel *cachel)
1374 { 1468 {
1469 int offs;
1470
1375 #define FINDEX_FIELD(field) \ 1471 #define FINDEX_FIELD(field) \
1376 Dynarr_atp (w->face_cachels, findex)->field 1472 Dynarr_atp (w->face_cachels, findex)->field
1377 1473
1378 #define FROB(field) \ 1474 #define FROB(field) \
1379 do { \ 1475 do { \
1393 FROB (strikethru); 1489 FROB (strikethru);
1394 FROB (highlight); 1490 FROB (highlight);
1395 FROB (dim); 1491 FROB (dim);
1396 FROB (reverse); 1492 FROB (reverse);
1397 FROB (blinking); 1493 FROB (blinking);
1398 /* And do ASCII, of course. */ 1494
1399 { 1495 for (offs = 0; offs < NUM_LEADING_BYTES; ++offs)
1400 int offs = LEADING_BYTE_ASCII - MIN_LEADING_BYTE; 1496 {
1401 1497 if (!(bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED(cachel), offs))
1402 if (!cachel->font_specified[offs] && FINDEX_FIELD (font_specified[offs])) 1498 && bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED
1403 { 1499 (Dynarr_atp(w->face_cachels, findex)), offs))
1404 cachel->font[offs] = FINDEX_FIELD (font[offs]); 1500 {
1405 cachel->font_specified[offs] = 1; 1501 cachel->font[offs] = FINDEX_FIELD (font[offs]);
1406 cachel->dirty = 1; 1502 set_bit_vector_bit(FACE_CACHEL_FONT_SPECIFIED(cachel), offs, 1);
1407 } 1503 /* Also propagate whether we're translating to Unicode for the
1408 } 1504 given face. */
1409 1505 set_bit_vector_bit(FACE_CACHEL_FONT_FINAL_STAGE(cachel), offs,
1506 bit_vector_bit(FACE_CACHEL_FONT_FINAL_STAGE
1507 (Dynarr_atp(w->face_cachels,
1508 findex)), offs));
1509 cachel->dirty = 1;
1510 }
1511 }
1410 #undef FROB 1512 #undef FROB
1411 #undef FINDEX_FIELD 1513 #undef FINDEX_FIELD
1412 1514
1413 cachel->updated = 1; 1515 cachel->updated = 1;
1414 } 1516 }
1431 for (i = 0; i < NUM_LEADING_BYTES; i++) 1533 for (i = 0; i < NUM_LEADING_BYTES; i++)
1432 cachel->font[i] = Qunbound; 1534 cachel->font[i] = Qunbound;
1433 } 1535 }
1434 cachel->display_table = Qunbound; 1536 cachel->display_table = Qunbound;
1435 cachel->background_pixmap = Qunbound; 1537 cachel->background_pixmap = Qunbound;
1538 FACE_CACHEL_FONT_SPECIFIED (cachel)->size = sizeof(cachel->font_specified);
1539 FACE_CACHEL_FONT_UPDATED (cachel)->size = sizeof(cachel->font_updated);
1436 } 1540 }
1437 1541
1438 /* Retrieve the index to a cachel for window W that corresponds to 1542 /* Retrieve the index to a cachel for window W that corresponds to
1439 the specified face. If necessary, add a new element to the 1543 the specified face. If necessary, add a new element to the
1440 cache. */ 1544 cache. */
1503 int elt; 1607 int elt;
1504 1608
1505 for (elt = 0; elt < Dynarr_length (w->face_cachels); elt++) 1609 for (elt = 0; elt < Dynarr_length (w->face_cachels); elt++)
1506 { 1610 {
1507 struct face_cachel *cachel = Dynarr_atp (w->face_cachels, elt); 1611 struct face_cachel *cachel = Dynarr_atp (w->face_cachels, elt);
1508 int i;
1509 1612
1510 cachel->updated = 0; 1613 cachel->updated = 0;
1511 for (i = 0; i < NUM_LEADING_BYTES; i++) 1614 memset(FACE_CACHEL_FONT_UPDATED(cachel)->bits, 0,
1512 cachel->font_updated[i] = 0; 1615 BIT_VECTOR_LONG_STORAGE (NUM_LEADING_BYTES));
1513 } 1616 }
1514 } 1617 }
1515 1618
1516 #ifdef MEMORY_USAGE_STATS 1619 #ifdef MEMORY_USAGE_STATS
1517 1620
1894 UNGCPRO; 1997 UNGCPRO;
1895 1998
1896 return new_name; 1999 return new_name;
1897 } 2000 }
1898 2001
2002 #ifdef MULE
2003
2004 Lisp_Object Qone_dimensional, Qtwo_dimensional;
2005
2006 DEFUN ("specifier-tag-one-dimensional-p",
2007 Fspecifier_tag_one_dimensional_p,
2008 2, 2, 0, /*
2009 Return non-nil if (charset-dimension CHARSET) is 1.
2010
2011 Used by the X11 platform font code; see `define-specifier-tag'. You
2012 shouldn't ever need to call this yourself.
2013 */
2014 (charset, UNUSED(stage)))
2015 {
2016 CHECK_CHARSET(charset);
2017 return (1 == XCHARSET_DIMENSION(charset)) ? Qt : Qnil;
2018 }
2019
2020 DEFUN ("specifier-tag-two-dimensional-p",
2021 Fspecifier_tag_two_dimensional_p,
2022 2, 2, 0, /*
2023 Return non-nil if (charset-dimension CHARSET) is 2.
2024
2025 Used by the X11 platform font code; see `define-specifier-tag'. You
2026 shouldn't ever need to call this yourself.
2027 */
2028 (charset, UNUSED(stage)))
2029 {
2030 CHECK_CHARSET(charset);
2031 return (2 == XCHARSET_DIMENSION(charset)) ? Qt : Qnil;
2032 }
2033
2034 DEFUN ("specifier-tag-final-stage-p",
2035 Fspecifier_tag_final_stage_p,
2036 2, 2, 0, /*
2037 Return non-nil if STAGE is 'final.
2038
2039 Used by the X11 platform font code for giving fallbacks; see
2040 `define-specifier-tag'. You shouldn't ever need to call this.
2041 */
2042 (UNUSED(charset), stage))
2043 {
2044 return EQ(stage, Qfinal) ? Qt : Qnil;
2045 }
2046
2047 DEFUN ("specifier-tag-initial-stage-p",
2048 Fspecifier_tag_initial_stage_p,
2049 2, 2, 0, /*
2050 Return non-nil if STAGE is 'initial.
2051
2052 Used by the X11 platform font code for giving fallbacks; see
2053 `define-specifier-tag'. You shouldn't ever need to call this.
2054 */
2055 (UNUSED(charset), stage))
2056 {
2057 return EQ(stage, Qinitial) ? Qt : Qnil;
2058 }
2059
2060 DEFUN ("specifier-tag-encode-as-utf-8-p",
2061 Fspecifier_tag_encode_as_utf_8_p,
2062 2, 2, 0, /*
2063 Return t if and only if (charset-property CHARSET 'encode-as-utf-8)).
2064
2065 Used by the X11 platform font code; see `define-specifier-tag'. You
2066 shouldn't ever need to call this.
2067 */
2068 (charset, UNUSED(stage)))
2069 {
2070 /* Used to check that the stage was initial too. */
2071 CHECK_CHARSET(charset);
2072 return XCHARSET_ENCODE_AS_UTF_8(charset) ? Qt : Qnil;
2073 }
2074
2075 #endif /* MULE */
2076
1899 2077
1900 void 2078 void
1901 syms_of_faces (void) 2079 syms_of_faces (void)
1902 { 2080 {
1903 INIT_LRECORD_IMPLEMENTATION (face); 2081 INIT_LRECORD_IMPLEMENTATION (face);
1914 DEFSUBR (Fface_name); 2092 DEFSUBR (Fface_name);
1915 DEFSUBR (Fbuilt_in_face_specifiers); 2093 DEFSUBR (Fbuilt_in_face_specifiers);
1916 DEFSUBR (Fface_list); 2094 DEFSUBR (Fface_list);
1917 DEFSUBR (Fmake_face); 2095 DEFSUBR (Fmake_face);
1918 DEFSUBR (Fcopy_face); 2096 DEFSUBR (Fcopy_face);
2097
2098 #ifdef MULE
2099 DEFSYMBOL (Qone_dimensional);
2100 DEFSYMBOL (Qtwo_dimensional);
2101 /* I would much prefer these were in Lisp. */
2102 DEFSUBR (Fspecifier_tag_one_dimensional_p);
2103 DEFSUBR (Fspecifier_tag_two_dimensional_p);
2104 DEFSUBR (Fspecifier_tag_initial_stage_p);
2105 DEFSUBR (Fspecifier_tag_final_stage_p);
2106 DEFSUBR (Fspecifier_tag_encode_as_utf_8_p);
2107 #endif /* MULE */
1919 2108
1920 DEFSYMBOL (Qfacep); 2109 DEFSYMBOL (Qfacep);
1921 DEFSYMBOL (Qforeground); 2110 DEFSYMBOL (Qforeground);
1922 DEFSYMBOL (Qbackground); 2111 DEFSYMBOL (Qbackground);
1923 /* Qfont defined in general.c */ 2112 /* Qfont defined in general.c */
1977 Vright_margin_face = Qnil; 2166 Vright_margin_face = Qnil;
1978 staticpro (&Vtext_cursor_face); 2167 staticpro (&Vtext_cursor_face);
1979 Vtext_cursor_face = Qnil; 2168 Vtext_cursor_face = Qnil;
1980 staticpro (&Vpointer_face); 2169 staticpro (&Vpointer_face);
1981 Vpointer_face = Qnil; 2170 Vpointer_face = Qnil;
2171
2172 #ifdef DEBUG_XEMACS
2173 DEFVAR_INT ("debug-x-faces", &debug_x_faces /*
2174 If non-zero, display debug information about X faces
2175 */ );
2176 debug_x_faces = 0;
2177 #endif
1982 2178
1983 { 2179 {
1984 Lisp_Object syms[20]; 2180 Lisp_Object syms[20];
1985 int n = 0; 2181 int n = 0;
1986 2182
2044 { 2240 {
2045 Lisp_Object inst_list = Qnil; 2241 Lisp_Object inst_list = Qnil;
2046 2242
2047 #if defined (HAVE_X_WINDOWS) || defined (HAVE_GTK) 2243 #if defined (HAVE_X_WINDOWS) || defined (HAVE_GTK)
2048 2244
2245 #ifdef HAVE_GTK
2246 Lisp_Object device_symbol = Qgtk;
2247 #else
2248 Lisp_Object device_symbol = Qx;
2249 #endif
2250
2251 #ifdef MULE
2252
2049 const Ascbyte *fonts[] = 2253 const Ascbyte *fonts[] =
2050 { 2254 {
2051 #ifdef USE_XFT 2255 #ifdef USE_XFT
2052 /************** Xft fonts *************/ 2256 /************** Xft fonts *************/
2053 2257
2054 /* Note that fontconfig can search for several font families in one 2258 /* Note that fontconfig can search for several font families in one
2055 call. We should use this facility. */ 2259 call. We should use this facility. */
2056 "monospace-12", /* Western #### add encoding info? */ 2260 "Monospace-12",
2057 /* do we need to worry about non-Latin characters for monospace? 2261 /* do we need to worry about non-Latin characters for monospace?
2058 No, at least in Debian's implementation of Xft. 2262 No, at least in Debian's implementation of Xft.
2059 We should recommend that "gothic" and "mincho" aliases be created? */ 2263 We should recommend that "gothic" and "mincho" aliases be created? */
2060 "Sazanami Mincho-12", /* Japanese #### add encoding info? */ 2264 "Sazanami Mincho-12",
2265 /* Japanese #### add encoding info? */
2061 /* Arphic for Chinese? */ 2266 /* Arphic for Chinese? */
2062 /* Korean */ 2267 /* Korean */
2063 #else 2268 #else
2064 2269 /* The default Japanese fonts installed with XFree86 4.0 use this
2065 /************** ISO-8859 fonts *************/ 2270 point size, and the -misc-fixed fonts (which look really bad with
2066 2271 Han characters) don't. We need to prefer the former. */
2067 "-*-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-*", 2272 "-*-*-medium-r-*-*-*-150-*-*-c-*-*-*",
2068 /* under USE_XFT, we always succeed, so let's not waste the effort */ 2273 /* And the Chinese ones, maddeningly, use this one. (But on 4.0, while
2069 "-*-fixed-medium-r-*-*-*-120-*-*-*-*-iso8859-*", 2274 XListFonts returns them, XLoadQueryFont on the fully-specified XLFD
2070 "-*-courier-*-r-*-*-*-120-*-*-*-*-iso8859-*", 2275 corresponding to one of them fails!) */
2071 "-*-fixed-*-r-*-*-*-120-*-*-*-*-iso8859-*", 2276 "-*-*-medium-r-*-*-*-160-*-*-c-*-*-*",
2072 /* Next try for any "medium" charcell or monospaced iso8859 font. */ 2277 "-*-*-medium-r-*-*-*-170-*-*-c-*-*-*",
2073 "-*-*-medium-r-*-*-*-120-*-*-m-*-iso8859-*",
2074 "-*-*-medium-r-*-*-*-120-*-*-c-*-iso8859-*",
2075 /* Next try for any charcell or monospaced iso8859 font. */
2076 "-*-*-*-r-*-*-*-120-*-*-m-*-iso8859-*",
2077 "-*-*-*-r-*-*-*-120-*-*-c-*-iso8859-*",
2078
2079 /* Repeat, any size */
2080 "-*-courier-medium-r-*-*-*-*-*-*-*-*-iso8859-*",
2081 "-*-fixed-medium-r-*-*-*-*-*-*-*-*-iso8859-*",
2082 "-*-courier-*-r-*-*-*-*-*-*-*-*-iso8859-*",
2083 "-*-fixed-*-r-*-*-*-*-*-*-*-*-iso8859-*",
2084 /* Next try for any "medium" charcell or monospaced iso8859 font. */
2085 "-*-*-medium-r-*-*-*-*-*-*-m-*-iso8859-*",
2086 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-*",
2087 /* Next try for any charcell or monospaced iso8859 font. */
2088 "-*-*-*-r-*-*-*-*-*-*-m-*-iso8859-*",
2089 "-*-*-*-r-*-*-*-*-*-*-c-*-iso8859-*",
2090
2091 /* Non-proportional fonts -- last resort. */
2092 "-*-*-*-r-*-*-*-120-*-*-*-*-iso8859-*",
2093 "-*-*-*-r-*-*-*-*-*-*-*-*-iso8859-*",
2094 "-*-*-*-*-*-*-*-*-*-*-*-*-iso8859-*",
2095
2096 /************* Japanese fonts ************/
2097
2098 /* Following 3 fonts proposed by Teruhiko.Kurosaka@Japan.eng.sun */
2099 "-sun-gothic-medium-r-normal--14-120-75-75-c-60-jisx0201.1976-0",
2100 "-sun-gothic-medium-r-normal--14-120-75-75-c-120-jisx0208.1983-0",
2101 "-wadalab-gothic-medium-r-normal--14-120-75-75-c-120-jisx0212.1990-0",
2102
2103 /* Other Japanese fonts */
2104 "-*-fixed-medium-r-*--*-jisx0201.1976-*",
2105 "-*-fixed-medium-r-*--*-jisx0208.1983-*",
2106 "-*-fixed-medium-r-*--*-jisx0212*-*",
2107 "-*-*-*-r-*--*-jisx0201.1976-*",
2108 "-*-*-*-r-*--*-jisx0208.1983-*",
2109 "-*-*-*-r-*--*-jisx0212*-*",
2110
2111 /************* Chinese fonts ************/
2112
2113 "-*-*-medium-r-*--*-gb2312.1980-*",
2114 "-*-fixed-medium-r-*--*-cns11643*-*",
2115
2116 "-*-fixed-medium-r-*--*-big5*-*,"
2117 "-*-fixed-medium-r-*--*-sisheng_cwnn-0",
2118
2119 /************* Korean fonts *************/
2120
2121 "-*-mincho-medium-r-*--*-ksc5601.1987-*",
2122
2123 /************* Thai fonts **************/
2124
2125 "-*-fixed-medium-r-*--*-tis620.2529-1",
2126
2127 /************* Other fonts (nonstandard) *************/
2128
2129 "-*-fixed-medium-r-*--*-viscii1.1-1",
2130 "-*-fixed-medium-r-*--*-mulearabic-*",
2131 "-*-fixed-medium-r-*--*-muleipa-*",
2132 "-*-fixed-medium-r-*--*-ethio-*",
2133
2134 /************* Unicode fonts **************/
2135
2136 /* #### We don't yet support Unicode fonts, but doing so would not be
2137 hard because all the machinery has already been added for Windows
2138 support. We need to do this:
2139
2140 (1) Add "stage 2" support in find_charset_font()/etc.; this finds
2141 an appropriate Unicode font after all the charset-specific fonts
2142 have been checked. This should look at the per-char font info and
2143 check whether we have support for some of the chars in the
2144 charset. (#### Bogus, but that's the way it currently works)
2145
2146 sjt sez: With Xft/fontconfig that information is available as a
2147 language support property. The character set (actually a bit
2148 vector) is also available. So what we need to do is to map charset
2149 -> language (Mule redesign Phase 1) and eventually use language
2150 information in the buffer, then map to charsets (Phase 2) at font
2151 instantiation time.
2152
2153 (2) Record in the font instance a flag indicating when we're
2154 dealing with a Unicode font.
2155
2156 (3) Notice this flag in separate_textual_runs() and translate the
2157 text into Unicode if so.
2158 */
2159
2160 "-*-courier-medium-r-*-*-*-120-*-*-*-*-iso10646-1",
2161 "-*-fixed-medium-r-*-*-*-120-*-*-*-*-iso10646-1",
2162 "-*-courier-*-r-*-*-*-120-*-*-*-*-iso10646-1",
2163 "-*-fixed-*-r-*-*-*-120-*-*-*-*-iso10646-1",
2164 /* Next try for any "medium" charcell or monospaced iso8859 font. */
2165 "-*-*-medium-r-*-*-*-120-*-*-m-*-iso10646-1",
2166 "-*-*-medium-r-*-*-*-120-*-*-c-*-iso10646-1",
2167 /* Next try for any charcell or monospaced iso8859 font. */
2168 "-*-*-*-r-*-*-*-120-*-*-m-*-iso10646-1",
2169 "-*-*-*-r-*-*-*-120-*-*-c-*-iso10646-1",
2170
2171 /* Repeat, any size */
2172 "-*-courier-medium-r-*-*-*-*-*-*-*-*-iso10646-1",
2173 "-*-fixed-medium-r-*-*-*-*-*-*-*-*-iso10646-1",
2174 "-*-courier-*-r-*-*-*-*-*-*-*-*-iso10646-1",
2175 "-*-fixed-*-r-*-*-*-*-*-*-*-*-iso10646-1",
2176 /* Next try for any "medium" charcell or monospaced iso8859 font. */
2177 "-*-*-medium-r-*-*-*-*-*-*-m-*-iso10646-1",
2178 "-*-*-medium-r-*-*-*-*-*-*-c-*-iso10646-1",
2179 /* Next try for any charcell or monospaced iso8859 font. */
2180 "-*-*-*-r-*-*-*-*-*-*-m-*-iso10646-1",
2181 "-*-*-*-r-*-*-*-*-*-*-c-*-iso10646-1",
2182
2183 /* Non-proportional fonts -- last resort. */
2184 "-*-*-*-r-*-*-*-120-*-*-*-*-iso10646-1",
2185 "-*-*-*-r-*-*-*-*-*-*-*-*-iso10646-1",
2186 "-*-*-*-*-*-*-*-*-*-*-*-*-iso10646-1",
2187
2188 /*********** Last resort ***********/
2189
2190 /* Boy, we sure are losing now. Try the above, but in any encoding. */
2191 "-*-*-medium-r-*-*-*-120-*-*-m-*-*-*",
2192 "-*-*-medium-r-*-*-*-120-*-*-c-*-*-*",
2193 "-*-*-*-r-*-*-*-120-*-*-m-*-*-*",
2194 "-*-*-*-r-*-*-*-120-*-*-c-*-*-*",
2195 /* Hello? Please? */
2196 "-*-*-*-r-*-*-*-120-*-*-*-*-*-*",
2197 "-*-*-*-*-*-*-*-120-*-*-*-*-*-*",
2198 "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
2199 "*"
2200 #endif 2278 #endif
2201 }; 2279 };
2202 const Ascbyte **fontptr; 2280 const Ascbyte **fontptr;
2203 2281
2204 #ifdef HAVE_X_WINDOWS 2282 /* Define some specifier tags for classes of character sets. Combining
2283 these allows for distinct fallback fonts for distinct dimensions of
2284 character sets and stages. */
2285
2286 define_specifier_tag(Qtwo_dimensional, Qnil,
2287 intern ("specifier-tag-two-dimensional-p"));
2288
2289 define_specifier_tag(Qone_dimensional, Qnil,
2290 intern ("specifier-tag-one-dimensional-p"));
2291
2292 define_specifier_tag(Qinitial, Qnil,
2293 intern ("specifier-tag-initial-stage-p"));
2294
2295 define_specifier_tag(Qfinal, Qnil,
2296 intern ("specifier-tag-final-stage-p"));
2297
2298 define_specifier_tag (Qencode_as_utf_8, Qnil,
2299 intern("specifier-tag-encode-as-utf-8-p"));
2300
2301 #endif /* MULE */
2302
2303 inst_list =
2304 Fcons
2305 (Fcons
2306 (list1 (device_symbol),
2307 build_string ("*")),
2308 inst_list);
2309
2310 #ifdef MULE
2311
2312 /* For Han characters and Ethiopic, we want the misc-fixed font used to
2313 be distinct from that for alphabetic scripts, because the font
2314 specified below is distractingly ugly when used for Han characters
2315 (this is slightly less so) and because its coverage isn't up to
2316 handling them (well, chiefly, it's not up to handling Ethiopic--we do
2317 have charset-specific fallbacks for the East Asian charsets.) */
2318 inst_list =
2319 Fcons
2320 (Fcons
2321 (list3(device_symbol, Qtwo_dimensional, Qfinal),
2322 build_string
2323 ("-misc-fixed-medium-r-normal--15-140-75-75-c-90-iso10646-1")),
2324 inst_list);
2325
2326 /* Use Markus Kuhn's version of misc-fixed as the font for the font for
2327 when a given charset's registries can't be found and redisplay for
2328 that charset falls back to iso10646-1. */
2329
2330 inst_list =
2331 Fcons
2332 (Fcons
2333 (list3(device_symbol, Qone_dimensional, Qfinal),
2334 build_string
2335 ("-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1")),
2336 inst_list);
2337
2205 for (fontptr = fonts + countof(fonts) - 1; fontptr >= fonts; fontptr--) 2338 for (fontptr = fonts + countof(fonts) - 1; fontptr >= fonts; fontptr--)
2206 inst_list = Fcons (Fcons (list1 (Qx), build_string (*fontptr)), 2339 inst_list = Fcons (Fcons (list3 (device_symbol,
2340 Qtwo_dimensional, Qinitial),
2341 build_string (*fontptr)),
2207 inst_list); 2342 inst_list);
2208 #endif /* HAVE_X_WINDOWS */ 2343
2209 2344 /* We need to set the font for the JIT-ucs-charsets separately from the
2210 #ifdef HAVE_GTK 2345 final stage, since otherwise it picks up the two-dimensional
2211 for (fontptr = fonts + countof(fonts) - 1; fontptr >= fonts; fontptr--) 2346 specification (see specifier-tag-two-dimensional-initial-stage-p
2212 inst_list = Fcons (Fcons (list1 (Qgtk), build_string (*fontptr)), 2347 above). They also use Markus Kuhn's ISO 10646-1 fixed fonts for
2213 inst_list); 2348 redisplay. */
2214 #endif /* HAVE_GTK */ 2349
2350 inst_list =
2351 Fcons
2352 (Fcons
2353 (list3(device_symbol, Qencode_as_utf_8, Qinitial),
2354 build_string
2355 ("-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1")),
2356 inst_list);
2357
2358 #endif /* MULE */
2359
2360 /* Needed to make sure that charsets with non-specified fonts don't
2361 use bold and oblique first if medium and regular are available. */
2362 inst_list =
2363 Fcons
2364 (Fcons
2365 (list1 (device_symbol),
2366 build_string ("-*-*-medium-r-*-*-*-120-*-*-c-*-*-*")),
2367 inst_list);
2368
2369 /* With a Cygwin XFree86 install, this returns the best (clearest,
2370 most readable) font I can find when scaling of bitmap fonts is
2371 turned on, as it is by default. (WHO IN THE NAME OF CHRIST THOUGHT
2372 THAT WAS A GOOD IDEA?!?!) The other fonts that used to be specified
2373 here gave horrendous results. */
2374
2375 inst_list =
2376 Fcons
2377 (Fcons
2378 (list1 (device_symbol),
2379 build_string ("-*-lucidatypewriter-medium-r-*-*-*-120-*-*-*-*-*-*")),
2380 inst_list);
2381
2215 #endif /* HAVE_X_WINDOWS || HAVE_GTK */ 2382 #endif /* HAVE_X_WINDOWS || HAVE_GTK */
2216 2383
2217 #ifdef HAVE_TTY 2384 #ifdef HAVE_TTY
2218 inst_list = Fcons (Fcons (list1 (Qtty), build_string ("normal")), 2385 inst_list = Fcons (Fcons (list1 (Qtty), build_string ("normal")),
2219 inst_list); 2386 inst_list);