diff options
| author | Kenichi Handa | 2000-05-17 23:30:30 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2000-05-17 23:30:30 +0000 |
| commit | 1ff005e1ed4bc9847924b466ca030007060ad05d (patch) | |
| tree | 26ac91aa3200c4830fc9e9b7dc5d360614d08944 /src | |
| parent | a3b210c4ab25a0b725085e2a1c42f588ad72482e (diff) | |
| download | emacs-1ff005e1ed4bc9847924b466ca030007060ad05d.tar.gz emacs-1ff005e1ed4bc9847924b466ca030007060ad05d.zip | |
Include "buffer.h".
(fs_load_font): If the face has fontset, record the face ID in
that fontset.
(Finternal_char_font): New function.
(accumulate_font_info): New function.
(Ffontset_info): Rewritten for the new fontset implementation.
(syms_of_fontset): Register Vdefault_fontset in the first element
of Vfontset_table. Include Vdefault_fontset in
Vfontset_alias_alist. Declare `internal-char-font' as a Lisp
function.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fontset.c | 256 |
1 files changed, 182 insertions, 74 deletions
diff --git a/src/fontset.c b/src/fontset.c index aa92cf931c8..ed15c70e44d 100644 --- a/src/fontset.c +++ b/src/fontset.c | |||
| @@ -28,6 +28,7 @@ Boston, MA 02111-1307, USA. */ | |||
| 28 | #endif | 28 | #endif |
| 29 | 29 | ||
| 30 | #include "lisp.h" | 30 | #include "lisp.h" |
| 31 | #include "buffer.h" | ||
| 31 | #include "charset.h" | 32 | #include "charset.h" |
| 32 | #include "ccl.h" | 33 | #include "ccl.h" |
| 33 | #include "frame.h" | 34 | #include "frame.h" |
| @@ -75,8 +76,8 @@ Boston, MA 02111-1307, USA. */ | |||
| 75 | element in a fontset. The element is stored in `defalt' slot of | 76 | element in a fontset. The element is stored in `defalt' slot of |
| 76 | the fontset. And this slot is never used as a default value of | 77 | the fontset. And this slot is never used as a default value of |
| 77 | multibyte characters. That means that the first 256 elements of a | 78 | multibyte characters. That means that the first 256 elements of a |
| 78 | fontset set is always nil (as this is not efficient, we may | 79 | fontset are always nil (as this is not efficient, we may implement |
| 79 | implement a fontset in a different way in the future). | 80 | a fontset in a different way in the future). |
| 80 | 81 | ||
| 81 | To access or set each element, use macros FONTSET_REF and | 82 | To access or set each element, use macros FONTSET_REF and |
| 82 | FONTSET_SET respectively for efficiency. | 83 | FONTSET_SET respectively for efficiency. |
| @@ -251,7 +252,6 @@ fontset_ref_via_base (fontset, c) | |||
| 251 | { | 252 | { |
| 252 | int charset, c1, c2; | 253 | int charset, c1, c2; |
| 253 | Lisp_Object elt; | 254 | Lisp_Object elt; |
| 254 | int i; | ||
| 255 | 255 | ||
| 256 | if (SINGLE_BYTE_CHAR_P (*c)) | 256 | if (SINGLE_BYTE_CHAR_P (*c)) |
| 257 | return FONTSET_ASCII (fontset); | 257 | return FONTSET_ASCII (fontset); |
| @@ -689,6 +689,12 @@ fs_load_font (f, c, fontname, id, face) | |||
| 689 | if (find_ccl_program_func) | 689 | if (find_ccl_program_func) |
| 690 | (*find_ccl_program_func) (fontp); | 690 | (*find_ccl_program_func) (fontp); |
| 691 | 691 | ||
| 692 | /* If we loaded a font for a face that has fontset, record the face | ||
| 693 | ID in the fontset for C. */ | ||
| 694 | if (face | ||
| 695 | && !NILP (fontset) | ||
| 696 | && !BASE_FONTSET_P (fontset)) | ||
| 697 | FONTSET_SET (fontset, c, make_number (face->id)); | ||
| 692 | return fontp; | 698 | return fontp; |
| 693 | } | 699 | } |
| 694 | 700 | ||
| @@ -1123,23 +1129,128 @@ If the named font is not yet loaded, return nil.") | |||
| 1123 | return info; | 1129 | return info; |
| 1124 | } | 1130 | } |
| 1125 | 1131 | ||
| 1132 | |||
| 1133 | /* Return the font name for the character at POSITION in the current | ||
| 1134 | buffer. This is computed from all the text properties and overlays | ||
| 1135 | that apply to POSITION. It returns nil in the following cases: | ||
| 1136 | |||
| 1137 | (1) The window system doesn't have a font for the character (thus | ||
| 1138 | it is displayed by an empty box). | ||
| 1139 | |||
| 1140 | (2) The character code is invalid. | ||
| 1141 | |||
| 1142 | (3) The current buffer is not displayed in any window. | ||
| 1143 | |||
| 1144 | In addition, the returned font name may not take into account of | ||
| 1145 | such redisplay engine hooks as what used in jit-lock-mode if | ||
| 1146 | POSITION is currently not visible. */ | ||
| 1147 | |||
| 1148 | |||
| 1149 | DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 1, 0, | ||
| 1150 | "For internal use only.") | ||
| 1151 | (position) | ||
| 1152 | Lisp_Object position; | ||
| 1153 | { | ||
| 1154 | int pos, pos_byte, dummy; | ||
| 1155 | int face_id; | ||
| 1156 | int c; | ||
| 1157 | Lisp_Object window; | ||
| 1158 | struct window *w; | ||
| 1159 | struct frame *f; | ||
| 1160 | struct face *face; | ||
| 1161 | |||
| 1162 | CHECK_NUMBER_COERCE_MARKER (position, 0); | ||
| 1163 | pos = XINT (position); | ||
| 1164 | if (pos < BEGV || pos >= ZV) | ||
| 1165 | args_out_of_range_3 (position, make_number (BEGV), make_number (ZV)); | ||
| 1166 | pos_byte = CHAR_TO_BYTE (pos); | ||
| 1167 | c = FETCH_CHAR (pos_byte); | ||
| 1168 | if (! CHAR_VALID_P (c, 0)) | ||
| 1169 | return Qnil; | ||
| 1170 | window = Fget_buffer_window (Fcurrent_buffer (), Qt); | ||
| 1171 | if (NILP (window)) | ||
| 1172 | return Qnil; | ||
| 1173 | w = XWINDOW (window); | ||
| 1174 | f = XFRAME (w->frame); | ||
| 1175 | face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0); | ||
| 1176 | face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c); | ||
| 1177 | face = FACE_FROM_ID (f, face_id); | ||
| 1178 | return (face->font && face->font_name | ||
| 1179 | ? build_string (face->font_name) | ||
| 1180 | : Qnil); | ||
| 1181 | } | ||
| 1182 | |||
| 1183 | |||
| 1184 | /* Called from Ffontset_info via map_char_table on each leaf of | ||
| 1185 | fontset. ARG is a list (LAST FONT-INFO ...), where LAST is `(last | ||
| 1186 | ARG)' and FONT-INFOs have this form: | ||
| 1187 | (CHAR FONT-SPEC) or ((FROM . TO) FONT-SPEC) | ||
| 1188 | The current leaf is indexed by CHARACTER and has value ELT. This | ||
| 1189 | function add the information of the current leaf to ARG by | ||
| 1190 | appending a new element or modifying the last element.. */ | ||
| 1191 | |||
| 1192 | static void | ||
| 1193 | accumulate_font_info (arg, character, elt) | ||
| 1194 | Lisp_Object arg, character, elt; | ||
| 1195 | { | ||
| 1196 | Lisp_Object last, last_char, last_elt, tmp; | ||
| 1197 | |||
| 1198 | if (!CONSP (elt)) | ||
| 1199 | return; | ||
| 1200 | last = XCAR (arg); | ||
| 1201 | last_char = XCAR (XCAR (last)); | ||
| 1202 | last_elt = XCAR (XCDR (XCAR (last))); | ||
| 1203 | elt = XCDR (elt); | ||
| 1204 | if (!NILP (Fequal (elt, last_elt))) | ||
| 1205 | { | ||
| 1206 | int this_charset = CHAR_CHARSET (XINT (character)); | ||
| 1207 | |||
| 1208 | if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */ | ||
| 1209 | { | ||
| 1210 | if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char)))) | ||
| 1211 | { | ||
| 1212 | XCDR (last_char) = character; | ||
| 1213 | return; | ||
| 1214 | } | ||
| 1215 | } | ||
| 1216 | else | ||
| 1217 | { | ||
| 1218 | if (this_charset == CHAR_CHARSET (XINT (last_char))) | ||
| 1219 | { | ||
| 1220 | XCAR (XCAR (last)) = Fcons (last_char, character); | ||
| 1221 | return; | ||
| 1222 | } | ||
| 1223 | } | ||
| 1224 | } | ||
| 1225 | XCDR (last) = Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil); | ||
| 1226 | XCAR (arg) = XCDR (last); | ||
| 1227 | } | ||
| 1228 | |||
| 1229 | |||
| 1126 | DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0, | 1230 | DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0, |
| 1127 | "Return information about a fontset named NAME on frame FRAME.\n\ | 1231 | "Return information about a fontset named NAME on frame FRAME.\n\ |
| 1128 | If FRAME is omitted or nil, use the selected frame.\n\ | 1232 | The value is a list:\n\ |
| 1129 | The returned value is a vector of SIZE, HEIGHT, and FONT-LIST,\n\ | 1233 | \(FONTSET-NAME (CHARSET-OR-RANGE FONT-SPEC OPENED ...) ...),\n\ |
| 1130 | where\n\ | 1234 | where,\n\ |
| 1131 | SIZE is the maximum bound width of ASCII font of the fontset,\n\ | 1235 | FONTSET-NAME is a full name of the fontset.\n\ |
| 1132 | HEIGHT is the height of the ASCII font in the fontset, and\n\ | 1236 | CHARSET-OR-RANGE is a charset, a character (may be a generic character)\n\ |
| 1133 | FONT-LIST is an alist of the format:\n\ | 1237 | or a cons of two characters specifying the range of characters.\n\ |
| 1134 | (CHARSET REQUESTED-FONT-NAME LOADED-FONT-NAME).\n\ | 1238 | FONT-SPEC is a fontname pattern string or a cons (FAMILY . REGISTRY),\n\ |
| 1135 | LOADED-FONT-NAME t means the font is not yet loaded, nil means the\n\ | 1239 | where FAMILY is a `FAMILY' field of a XLFD font name,\n\ |
| 1136 | loading failed.") | 1240 | REGISTRY is a `CHARSET_REGISTRY' field of a XLDF font name.\n\ |
| 1241 | FAMILY may contain a `FOUNDARY' field at the head.\n\ | ||
| 1242 | REGISTRY may contain a `CHARSET_ENCODING' field at the tail.\n\ | ||
| 1243 | OPENEDs are names of fonts actually opened.\n\ | ||
| 1244 | If FRAME is omitted, it defaults to the currently selected frame.") | ||
| 1137 | (name, frame) | 1245 | (name, frame) |
| 1138 | Lisp_Object name, frame; | 1246 | Lisp_Object name, frame; |
| 1139 | { | 1247 | { |
| 1248 | Lisp_Object fontset; | ||
| 1140 | FRAME_PTR f; | 1249 | FRAME_PTR f; |
| 1141 | Lisp_Object fontset, realized; | 1250 | Lisp_Object indices[3]; |
| 1142 | Lisp_Object info, val, loaded, requested; | 1251 | Lisp_Object val, tail, elt; |
| 1252 | Lisp_Object *realized; | ||
| 1253 | int n_realized = 0; | ||
| 1143 | int i; | 1254 | int i; |
| 1144 | 1255 | ||
| 1145 | (*check_window_system_func) (); | 1256 | (*check_window_system_func) (); |
| @@ -1151,77 +1262,66 @@ loading failed.") | |||
| 1151 | CHECK_LIVE_FRAME (frame, 1); | 1262 | CHECK_LIVE_FRAME (frame, 1); |
| 1152 | f = XFRAME (frame); | 1263 | f = XFRAME (frame); |
| 1153 | 1264 | ||
| 1154 | info = Fmake_vector (make_number (3), Qnil); | 1265 | /* Recodeq realized fontsets whose base is FONTSET in the table |
| 1155 | 1266 | `realized'. */ | |
| 1267 | realized = (Lisp_Object *) alloca (sizeof (Lisp_Object) | ||
| 1268 | * ASIZE (Vfontset_table)); | ||
| 1156 | for (i = 0; i < ASIZE (Vfontset_table); i++) | 1269 | for (i = 0; i < ASIZE (Vfontset_table); i++) |
| 1157 | { | 1270 | { |
| 1158 | realized = FONTSET_FROM_ID (i); | 1271 | elt = FONTSET_FROM_ID (i); |
| 1159 | if (!NILP (realized) | 1272 | if (!NILP (elt) |
| 1160 | && EQ (FONTSET_FRAME (realized), frame) | 1273 | && EQ (FONTSET_BASE (elt), fontset)) |
| 1161 | && EQ (FONTSET_BASE (realized), fontset) | 1274 | realized[n_realized++] = elt; |
| 1162 | && INTEGERP (FONTSET_ASCII (realized))) | ||
| 1163 | break; | ||
| 1164 | } | 1275 | } |
| 1165 | 1276 | ||
| 1166 | if (NILP (realized)) | 1277 | /* Accumulate information of the fontset in VAL. The format is |
| 1167 | return Qnil; | 1278 | (LAST FONT-INFO FONT-INFO ...), where FONT-INFO is (CHAR-OR-RANGE |
| 1168 | 1279 | FONT-SPEC). See the comment for accumulate_font_info for the | |
| 1169 | XVECTOR (info)->contents[0] = Qnil; | 1280 | detail. */ |
| 1170 | XVECTOR (info)->contents[1] = Qnil; | 1281 | val = Fcons (Fcons (make_number (0), |
| 1171 | loaded = Qnil; | 1282 | Fcons (XCDR (FONTSET_ASCII (fontset)), Qnil)), |
| 1172 | |||
| 1173 | val = Fcons (Fcons (CHARSET_SYMBOL (CHARSET_ASCII), | ||
| 1174 | Fcons (FONTSET_ASCII (fontset), | ||
| 1175 | Fcons (loaded, Qnil))), | ||
| 1176 | Qnil); | 1283 | Qnil); |
| 1177 | for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++) | 1284 | val = Fcons (val, val); |
| 1285 | map_char_table (accumulate_font_info, Qnil, fontset, val, 0, indices); | ||
| 1286 | val = XCDR (val); | ||
| 1287 | |||
| 1288 | /* For each FONT-INFO, if CHAR_OR_RANGE (car part) is a generic | ||
| 1289 | character for a charset, replace it wiht the charset symbol. If | ||
| 1290 | fonts are opened for FONT-SPEC, append the names of the fonts to | ||
| 1291 | FONT-SPEC. */ | ||
| 1292 | for (tail = val; CONSP (tail); tail = XCDR (tail)) | ||
| 1178 | { | 1293 | { |
| 1179 | Lisp_Object elt; | 1294 | int c; |
| 1180 | elt = XCHAR_TABLE (fontset)->contents[i + 128]; | 1295 | elt = XCAR (tail); |
| 1181 | 1296 | if (INTEGERP (XCAR (elt))) | |
| 1182 | if (VECTORP (elt)) | ||
| 1183 | { | 1297 | { |
| 1184 | int face_id; | 1298 | int charset, c1, c2; |
| 1299 | c = XINT (XCAR (elt)); | ||
| 1300 | SPLIT_CHAR (c, charset, c1, c2); | ||
| 1301 | if (c1 == 0) | ||
| 1302 | XCAR (elt) = CHARSET_SYMBOL (charset); | ||
| 1303 | } | ||
| 1304 | else | ||
| 1305 | c = XINT (XCAR (XCAR (elt))); | ||
| 1306 | for (i = 0; i < n_realized; i++) | ||
| 1307 | { | ||
| 1308 | Lisp_Object face_id, font; | ||
| 1185 | struct face *face; | 1309 | struct face *face; |
| 1186 | 1310 | ||
| 1187 | if (INTEGERP (AREF (elt, 2)) | 1311 | face_id = FONTSET_REF_VIA_BASE (realized[i], c); |
| 1188 | && (face_id = XINT (AREF (elt, 2)), | 1312 | if (INTEGERP (face_id)) |
| 1189 | face = FACE_FROM_ID (f, face_id))) | ||
| 1190 | { | ||
| 1191 | struct font_info *fontp; | ||
| 1192 | fontp = (*get_font_info_func) (f, face->font_info_id); | ||
| 1193 | requested = build_string (fontp->name); | ||
| 1194 | loaded = (fontp->full_name | ||
| 1195 | ? build_string (fontp->full_name) | ||
| 1196 | : Qnil); | ||
| 1197 | } | ||
| 1198 | else | ||
| 1199 | { | 1313 | { |
| 1200 | char *str; | 1314 | face = FACE_FROM_ID (f, XINT (face_id)); |
| 1201 | int family_len = 0, registry_len = 0; | 1315 | if (face->font && face->font_name) |
| 1202 | 1316 | { | |
| 1203 | if (STRINGP (AREF (elt, 0))) | 1317 | font = build_string (face->font_name); |
| 1204 | family_len = STRING_BYTES (XSTRING (AREF (elt, 0))); | 1318 | if (NILP (Fmember (font, XCDR (XCDR (elt))))) |
| 1205 | if (STRINGP (AREF (elt, 1))) | 1319 | XCDR (XCDR (elt)) = Fcons (font, XCDR (XCDR (elt))); |
| 1206 | registry_len = STRING_BYTES (XSTRING (AREF (elt, 1))); | 1320 | } |
| 1207 | str = (char *) alloca (1 + family_len + 3 + registry_len + 1); | ||
| 1208 | str[0] = '-'; | ||
| 1209 | str[1] = 0; | ||
| 1210 | if (family_len) | ||
| 1211 | strcat (str, XSTRING (AREF (elt, 0))->data); | ||
| 1212 | strcat (str, "-*-"); | ||
| 1213 | if (registry_len) | ||
| 1214 | strcat (str, XSTRING (AREF (elt, 1))->data); | ||
| 1215 | requested = build_string (str); | ||
| 1216 | loaded = Qnil; | ||
| 1217 | } | 1321 | } |
| 1218 | val = Fcons (Fcons (CHARSET_SYMBOL (i), | ||
| 1219 | Fcons (requested, Fcons (loaded, Qnil))), | ||
| 1220 | val); | ||
| 1221 | } | 1322 | } |
| 1222 | } | 1323 | } |
| 1223 | XVECTOR (info)->contents[2] = val; | 1324 | return Fcons (FONTSET_NAME (fontset), val); |
| 1224 | return info; | ||
| 1225 | } | 1325 | } |
| 1226 | 1326 | ||
| 1227 | DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0, | 1327 | DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0, |
| @@ -1263,6 +1363,7 @@ DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0, | |||
| 1263 | && BASE_FONTSET_P (fontset)) | 1363 | && BASE_FONTSET_P (fontset)) |
| 1264 | list = Fcons (FONTSET_NAME (fontset), list); | 1364 | list = Fcons (FONTSET_NAME (fontset), list); |
| 1265 | } | 1365 | } |
| 1366 | |||
| 1266 | return list; | 1367 | return list; |
| 1267 | } | 1368 | } |
| 1268 | 1369 | ||
| @@ -1284,12 +1385,16 @@ syms_of_fontset () | |||
| 1284 | 1385 | ||
| 1285 | Vfontset_table = Fmake_vector (make_number (32), Qnil); | 1386 | Vfontset_table = Fmake_vector (make_number (32), Qnil); |
| 1286 | staticpro (&Vfontset_table); | 1387 | staticpro (&Vfontset_table); |
| 1287 | next_fontset_id = 0; | ||
| 1288 | 1388 | ||
| 1289 | Vdefault_fontset = Fmake_char_table (Qfontset, Qnil); | 1389 | Vdefault_fontset = Fmake_char_table (Qfontset, Qnil); |
| 1290 | staticpro (&Vdefault_fontset); | 1390 | staticpro (&Vdefault_fontset); |
| 1391 | FONTSET_ID (Vdefault_fontset) = make_number (0); | ||
| 1392 | FONTSET_NAME (Vdefault_fontset) | ||
| 1393 | = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default"); | ||
| 1291 | FONTSET_ASCII (Vdefault_fontset) | 1394 | FONTSET_ASCII (Vdefault_fontset) |
| 1292 | = Fcons (make_number (0), Fcons (Qnil, build_string ("iso8859-1"))); | 1395 | = Fcons (make_number (0), Fcons (Qnil, build_string ("iso8859-1"))); |
| 1396 | AREF (Vfontset_table, 0) = Vdefault_fontset; | ||
| 1397 | next_fontset_id = 1; | ||
| 1293 | 1398 | ||
| 1294 | DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist, | 1399 | DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist, |
| 1295 | "Alist of fontname patterns vs corresponding encoding info.\n\ | 1400 | "Alist of fontname patterns vs corresponding encoding info.\n\ |
| @@ -1327,7 +1432,9 @@ alternate fontnames (if any) are tried instead."); | |||
| 1327 | 1432 | ||
| 1328 | DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist, | 1433 | DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist, |
| 1329 | "Alist of fontset names vs the aliases."); | 1434 | "Alist of fontset names vs the aliases."); |
| 1330 | Vfontset_alias_alist = Qnil; | 1435 | Vfontset_alias_alist = Fcons (Fcons (FONTSET_NAME (Vdefault_fontset), |
| 1436 | build_string ("fontset-default")), | ||
| 1437 | Qnil); | ||
| 1331 | 1438 | ||
| 1332 | DEFVAR_LISP ("highlight-wrong-size-font", &Vhighlight_wrong_size_font, | 1439 | DEFVAR_LISP ("highlight-wrong-size-font", &Vhighlight_wrong_size_font, |
| 1333 | "*Non-nil means highlight characters shown in wrong size fonts somehow.\n\ | 1440 | "*Non-nil means highlight characters shown in wrong size fonts somehow.\n\ |
| @@ -1358,6 +1465,7 @@ at the vertival center of lines."); | |||
| 1358 | defsubr (&Snew_fontset); | 1465 | defsubr (&Snew_fontset); |
| 1359 | defsubr (&Sset_fontset_font); | 1466 | defsubr (&Sset_fontset_font); |
| 1360 | defsubr (&Sfont_info); | 1467 | defsubr (&Sfont_info); |
| 1468 | defsubr (&Sinternal_char_font); | ||
| 1361 | defsubr (&Sfontset_info); | 1469 | defsubr (&Sfontset_info); |
| 1362 | defsubr (&Sfontset_font); | 1470 | defsubr (&Sfontset_font); |
| 1363 | defsubr (&Sfontset_list); | 1471 | defsubr (&Sfontset_list); |