diff options
| author | Kenichi Handa | 2002-03-01 02:07:40 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2002-03-01 02:07:40 +0000 |
| commit | 06f76f0d47e0590856743a811cc9f7b0a3c92559 (patch) | |
| tree | 4a695cb445bfdb842ad465b8e02250b5f45117a1 /src | |
| parent | 9617ce06760605c25322af89e5a706e8ff3faacb (diff) | |
| download | emacs-06f76f0d47e0590856743a811cc9f7b0a3c92559.tar.gz emacs-06f76f0d47e0590856743a811cc9f7b0a3c92559.zip | |
Mostly re-written.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fontset.c | 985 |
1 files changed, 421 insertions, 564 deletions
diff --git a/src/fontset.c b/src/fontset.c index 30bec52f024..842aad5d6cf 100644 --- a/src/fontset.c +++ b/src/fontset.c | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | /* Fontset handler. | 1 | /* Fontset handler. |
| 2 | Copyright (C) 1995, 1997, 2000 Electrotechnical Laboratory, JAPAN. | 2 | Copyright (C) 1995, 1997, 2000 Electrotechnical Laboratory, JAPAN. |
| 3 | Licensed to the Free Software Foundation. | 3 | Licensed to the Free Software Foundation. |
| 4 | Copyright (C) 2001, 2002 | ||
| 5 | National Institute of Advanced Industrial Science and Technology (AIST) | ||
| 6 | Registration Number H13PRO009 | ||
| 4 | 7 | ||
| 5 | This file is part of GNU Emacs. | 8 | This file is part of GNU Emacs. |
| 6 | 9 | ||
| @@ -28,7 +31,9 @@ Boston, MA 02111-1307, USA. */ | |||
| 28 | #endif | 31 | #endif |
| 29 | 32 | ||
| 30 | #include "lisp.h" | 33 | #include "lisp.h" |
| 34 | #include "blockinput.h" | ||
| 31 | #include "buffer.h" | 35 | #include "buffer.h" |
| 36 | #include "character.h" | ||
| 32 | #include "charset.h" | 37 | #include "charset.h" |
| 33 | #include "ccl.h" | 38 | #include "ccl.h" |
| 34 | #include "keyboard.h" | 39 | #include "keyboard.h" |
| @@ -48,58 +53,59 @@ Boston, MA 02111-1307, USA. */ | |||
| 48 | /* FONTSET | 53 | /* FONTSET |
| 49 | 54 | ||
| 50 | A fontset is a collection of font related information to give | 55 | A fontset is a collection of font related information to give |
| 51 | similar appearance (style, size, etc) of characters. There are two | 56 | similar appearance (style, etc) of characters. There are two kinds |
| 52 | kinds of fontsets; base and realized. A base fontset is created by | 57 | of fontsets; base and realized. A base fontset is created by |
| 53 | new-fontset from Emacs Lisp explicitly. A realized fontset is | 58 | `new-fontset' from Emacs Lisp explicitly. A realized fontset is |
| 54 | created implicitly when a face is realized for ASCII characters. A | 59 | created implicitly when a face is realized for ASCII characters. A |
| 55 | face is also realized for multibyte characters based on an ASCII | 60 | face is also realized for non-ASCII characters based on an ASCII |
| 56 | face. All of the multibyte faces based on the same ASCII face | 61 | face. All of non-ASCII faces based on the same ASCII face share |
| 57 | share the same realized fontset. | 62 | the same realized fontset. |
| 63 | |||
| 64 | A fontset object is implemented by a char-table whose default value | ||
| 65 | and parent are always nil. | ||
| 58 | 66 | ||
| 59 | A fontset object is implemented by a char-table. | 67 | An element of a base fontset is a font specification of the form: |
| 68 | [ FAMILY WEIGHT SLANT SWIDTH REGISTRY ] (vector of size 5) | ||
| 69 | or | ||
| 70 | FONT-NAME (strig) | ||
| 60 | 71 | ||
| 61 | An element of a base fontset is: | 72 | FAMILY and REGISTRY are strings. |
| 62 | (INDEX . FONTNAME) or | ||
| 63 | (INDEX . (FOUNDRY . REGISTRY )) | ||
| 64 | FONTNAME is a font name pattern for the corresponding character. | ||
| 65 | FOUNDRY and REGISTRY are respectively foundry and registry fields of | ||
| 66 | a font name for the corresponding character. INDEX specifies for | ||
| 67 | which character (or generic character) the element is defined. It | ||
| 68 | may be different from an index to access this element. For | ||
| 69 | instance, if a fontset defines some font for all characters of | ||
| 70 | charset `japanese-jisx0208', INDEX is the generic character of this | ||
| 71 | charset. REGISTRY is the | ||
| 72 | 73 | ||
| 73 | An element of a realized fontset is FACE-ID which is a face to use | 74 | WEIGHT, SLANT, and SWIDTH must be symbols that set-face-attribute |
| 74 | for displaying the corresponding character. | 75 | accepts as attribute values for :weight, :slant, :swidth |
| 76 | respectively. | ||
| 75 | 77 | ||
| 76 | All single byte characters (ASCII and 8bit-unibyte) share the same | ||
| 77 | element in a fontset. The element is stored in the first element | ||
| 78 | of the fontset. | ||
| 79 | 78 | ||
| 80 | To access or set each element, use macros FONTSET_REF and | 79 | A fontset has 7 extra slots. |
| 81 | FONTSET_SET respectively for efficiency. | ||
| 82 | |||
| 83 | A fontset has 3 extra slots. | ||
| 84 | 80 | ||
| 85 | The 1st slot is an ID number of the fontset. | 81 | The 1st slot is an ID number of the fontset. |
| 86 | 82 | ||
| 87 | The 2nd slot is a name of the fontset. This is nil for a realized | 83 | The 2nd slot is a name of the fontset in a base fontset, and nil in |
| 88 | face. | 84 | a realized fontset. |
| 85 | |||
| 86 | The 3rd slot is nil in a base fontset, and a base fontset in a | ||
| 87 | realized fontset. | ||
| 88 | |||
| 89 | The 4th slot is a frame that the fontset belongs to. This is nil | ||
| 90 | in a base fontset. | ||
| 91 | |||
| 92 | The 5th slot is a cons of 0 and fontname for ASCII characters in a | ||
| 93 | base fontset, and nil in a realized face. | ||
| 89 | 94 | ||
| 90 | The 3rd slot is a frame that the fontset belongs to. This is nil | 95 | The 6th slot is an alist of a charset vs. the corresponding font |
| 91 | for a default face. | 96 | specification. |
| 92 | 97 | ||
| 93 | A parent of a base fontset is nil. A parent of a realized fontset | 98 | The 7th slot is an alist of a font specification vs. the |
| 94 | is a base fontset. | 99 | corresponding face ID. In a base fontset, the face IDs are all |
| 100 | nil. | ||
| 95 | 101 | ||
| 96 | All fontsets are recorded in Vfontset_table. | 102 | All fontsets are recorded in Vfontset_table. |
| 97 | 103 | ||
| 98 | 104 | ||
| 99 | DEFAULT FONTSET | 105 | DEFAULT FONTSET |
| 100 | 106 | ||
| 101 | There's a special fontset named `default fontset' which defines a | 107 | There's a special fontset named `default fontset' which defines the |
| 102 | default fontname pattern. When a base fontset doesn't specify a | 108 | default font specifications. When a base fontset doesn't specify a |
| 103 | font for a specific character, the corresponding value in the | 109 | font for a specific character, the corresponding value in the |
| 104 | default fontset is used. The format is the same as a base fontset. | 110 | default fontset is used. The format is the same as a base fontset. |
| 105 | 111 | ||
| @@ -109,9 +115,9 @@ Boston, MA 02111-1307, USA. */ | |||
| 109 | 115 | ||
| 110 | These structures are hidden from the other codes than this file. | 116 | These structures are hidden from the other codes than this file. |
| 111 | The other codes handle fontsets only by their ID numbers. They | 117 | The other codes handle fontsets only by their ID numbers. They |
| 112 | usually use variable name `fontset' for IDs. But, in this file, we | 118 | usually use the variable name `fontset' for IDs. But, in this |
| 113 | always use variable name `id' for IDs, and name `fontset' for the | 119 | file, we always use varialbe name `id' for IDs, and name `fontset' |
| 114 | actual fontset objects. | 120 | for the actual fontset objects (i.e. char-table objects). |
| 115 | 121 | ||
| 116 | */ | 122 | */ |
| 117 | 123 | ||
| @@ -128,7 +134,7 @@ static Lisp_Object Vfontset_table; | |||
| 128 | static int next_fontset_id; | 134 | static int next_fontset_id; |
| 129 | 135 | ||
| 130 | /* The default fontset. This gives default FAMILY and REGISTRY of | 136 | /* The default fontset. This gives default FAMILY and REGISTRY of |
| 131 | font for each characters. */ | 137 | font for each character. */ |
| 132 | static Lisp_Object Vdefault_fontset; | 138 | static Lisp_Object Vdefault_fontset; |
| 133 | 139 | ||
| 134 | Lisp_Object Vfont_encoding_alist; | 140 | Lisp_Object Vfont_encoding_alist; |
| @@ -174,12 +180,9 @@ void (*check_window_system_func) P_ ((void)); | |||
| 174 | 180 | ||
| 175 | 181 | ||
| 176 | /* Prototype declarations for static functions. */ | 182 | /* Prototype declarations for static functions. */ |
| 177 | static Lisp_Object fontset_ref P_ ((Lisp_Object, int)); | ||
| 178 | static void fontset_set P_ ((Lisp_Object, int, Lisp_Object)); | ||
| 179 | static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); | 183 | static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); |
| 180 | static int fontset_id_valid_p P_ ((int)); | 184 | static int fontset_id_valid_p P_ ((int)); |
| 181 | static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object)); | 185 | static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object)); |
| 182 | static Lisp_Object font_family_registry P_ ((Lisp_Object, int)); | ||
| 183 | 186 | ||
| 184 | 187 | ||
| 185 | /********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/ | 188 | /********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/ |
| @@ -189,122 +192,135 @@ static Lisp_Object font_family_registry P_ ((Lisp_Object, int)); | |||
| 189 | 192 | ||
| 190 | /* Macros to access special values of FONTSET. */ | 193 | /* Macros to access special values of FONTSET. */ |
| 191 | #define FONTSET_ID(fontset) XCHAR_TABLE (fontset)->extras[0] | 194 | #define FONTSET_ID(fontset) XCHAR_TABLE (fontset)->extras[0] |
| 195 | |||
| 196 | /* Macros to access special values of (base) FONTSET. */ | ||
| 192 | #define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1] | 197 | #define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1] |
| 193 | #define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[2] | 198 | #define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->extras[4] |
| 194 | #define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->contents[0] | 199 | |
| 195 | #define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->parent | 200 | #define BASE_FONTSET_P(fontset) STRINGP (FONTSET_NAME (fontset)) |
| 196 | 201 | ||
| 197 | #define BASE_FONTSET_P(fontset) NILP (FONTSET_BASE(fontset)) | 202 | /* Macros to access special values of (realized) FONTSET. */ |
| 203 | #define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[2] | ||
| 204 | #define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[3] | ||
| 205 | #define FONTSET_CHARSET_ALIST(fontset) XCHAR_TABLE (fontset)->extras[5] | ||
| 206 | #define FONTSET_FACE_ALIST(fontset) XCHAR_TABLE (fontset)->extras[6] | ||
| 198 | 207 | ||
| 199 | 208 | ||
| 200 | /* Return the element of FONTSET (char-table) at index C (character). */ | 209 | /* Return the element of FONTSET (char-table) at index C (character). */ |
| 201 | 210 | ||
| 202 | #define FONTSET_REF(fontset, c) fontset_ref (fontset, c) | 211 | #define FONTSET_REF(fontset, c, etl) ((elt) = fontset_ref ((fontset), (c))) |
| 203 | 212 | ||
| 204 | static Lisp_Object | 213 | static Lisp_Object |
| 205 | fontset_ref (fontset, c) | 214 | fontset_ref (fontset, c) |
| 206 | Lisp_Object fontset; | 215 | Lisp_Object fontset; |
| 207 | int c; | 216 | int c; |
| 208 | { | 217 | { |
| 209 | int charset, c1, c2; | 218 | Lisp_Object elt; |
| 210 | Lisp_Object elt, defalt; | 219 | |
| 211 | 220 | while (1) | |
| 212 | if (SINGLE_BYTE_CHAR_P (c)) | 221 | { |
| 213 | return FONTSET_ASCII (fontset); | 222 | elt = CHAR_TABLE_REF (fontset, c); |
| 214 | 223 | if (NILP (elt) && ASCII_CHAR_P (c)) | |
| 215 | SPLIT_CHAR (c, charset, c1, c2); | 224 | elt = FONTSET_ASCII (fontset); |
| 216 | elt = XCHAR_TABLE (fontset)->contents[charset + 128]; | 225 | if (NILP (elt)) |
| 217 | if (!SUB_CHAR_TABLE_P (elt)) | 226 | { |
| 218 | return elt; | 227 | Lisp_Object tail; |
| 219 | defalt = XCHAR_TABLE (elt)->defalt; | 228 | struct charset *charset; |
| 220 | if (c1 < 32 | 229 | |
| 221 | || (elt = XCHAR_TABLE (elt)->contents[c1], | 230 | for (tail = FONTSET_CHARSET_ALIST (fontset); |
| 222 | NILP (elt))) | 231 | CONSP (tail); tail = XCDR (tail)) |
| 223 | return defalt; | 232 | { |
| 224 | if (!SUB_CHAR_TABLE_P (elt)) | 233 | charset = CHARSET_FROM_ID (XCAR (XCAR (tail))); |
| 225 | return elt; | 234 | if (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset)) |
| 226 | defalt = XCHAR_TABLE (elt)->defalt; | 235 | { |
| 227 | if (c2 < 32 | 236 | elt = XCDR (XCAR (tail)); |
| 228 | || (elt = XCHAR_TABLE (elt)->contents[c2], | 237 | break; |
| 229 | NILP (elt))) | 238 | } |
| 230 | return defalt; | 239 | } |
| 240 | } | ||
| 241 | if (! NILP (elt) || EQ (fontset, Vdefault_fontset)) | ||
| 242 | break; | ||
| 243 | fontset = Vdefault_fontset; | ||
| 244 | } | ||
| 231 | return elt; | 245 | return elt; |
| 232 | } | 246 | } |
| 233 | 247 | ||
| 234 | 248 | ||
| 235 | #define FONTSET_REF_VIA_BASE(fontset, c) fontset_ref_via_base (fontset, &c) | 249 | /* Set the element of FONTSET at index IDX to the value ELT. IDX may |
| 236 | 250 | be a character or a charset. */ | |
| 237 | static Lisp_Object | ||
| 238 | fontset_ref_via_base (fontset, c) | ||
| 239 | Lisp_Object fontset; | ||
| 240 | int *c; | ||
| 241 | { | ||
| 242 | int charset, c1, c2; | ||
| 243 | Lisp_Object elt; | ||
| 244 | 251 | ||
| 245 | if (SINGLE_BYTE_CHAR_P (*c)) | 252 | #define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt) |
| 246 | return FONTSET_ASCII (fontset); | ||
| 247 | 253 | ||
| 248 | elt = FONTSET_REF (FONTSET_BASE (fontset), *c); | 254 | static void |
| 249 | if (NILP (elt) && ! EQ (fontset, Vdefault_fontset)) | 255 | fontset_set (fontset, idx, elt) |
| 250 | elt = FONTSET_REF (Vdefault_fontset, *c); | 256 | Lisp_Object fontset, idx, elt; |
| 251 | if (NILP (elt)) | 257 | { |
| 252 | return Qnil; | 258 | if (SYMBOLP (idx)) |
| 259 | { | ||
| 260 | Lisp_Object id, slot, tail; | ||
| 261 | |||
| 262 | id = make_number (CHARSET_SYMBOL_ID (idx)); | ||
| 263 | if (id == charset_ascii) | ||
| 264 | Fset_char_table_range (fontset, | ||
| 265 | Fcons (make_number (0), make_number (127)), | ||
| 266 | elt); | ||
| 267 | else | ||
| 268 | { | ||
| 269 | slot = Fassq (id, FONTSET_CHARSET_ALIST (fontset)); | ||
| 270 | if (CONSP (slot)) | ||
| 271 | XCDR (slot) = elt; | ||
| 272 | else if (CONSP (FONTSET_CHARSET_ALIST (fontset))) | ||
| 273 | { | ||
| 274 | for (tail = FONTSET_CHARSET_ALIST (fontset); | ||
| 275 | CONSP (XCDR (tail)); tail = XCDR (tail)); | ||
| 276 | XCDR (tail) = Fcons (Fcons (id, elt), Qnil); | ||
| 277 | } | ||
| 278 | else | ||
| 279 | FONTSET_CHARSET_ALIST (fontset) = Fcons (Fcons (id, elt), Qnil); | ||
| 280 | } | ||
| 281 | } | ||
| 282 | else | ||
| 283 | { | ||
| 284 | int from = XINT (XCAR (idx)); | ||
| 285 | int to = XINT (XCDR (idx)); | ||
| 253 | 286 | ||
| 254 | *c = XINT (XCAR (elt)); | 287 | if (from == to) |
| 255 | SPLIT_CHAR (*c, charset, c1, c2); | 288 | CHAR_TABLE_SET (fontset, from, elt); |
| 256 | elt = XCHAR_TABLE (fontset)->contents[charset + 128]; | 289 | else |
| 257 | if (c1 < 32) | 290 | Fset_char_table_range (fontset, idx, elt); |
| 258 | return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt); | 291 | } |
| 259 | if (!SUB_CHAR_TABLE_P (elt)) | ||
| 260 | return Qnil; | ||
| 261 | elt = XCHAR_TABLE (elt)->contents[c1]; | ||
| 262 | if (c2 < 32) | ||
| 263 | return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt); | ||
| 264 | if (!SUB_CHAR_TABLE_P (elt)) | ||
| 265 | return Qnil; | ||
| 266 | elt = XCHAR_TABLE (elt)->contents[c2]; | ||
| 267 | return elt; | ||
| 268 | } | 292 | } |
| 269 | 293 | ||
| 270 | 294 | ||
| 271 | /* Store into the element of FONTSET at index C the value NEWELT. */ | 295 | /* Return a face registerd in the realized fontset FONTSET for the |
| 272 | #define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt) | 296 | character C. Return -1 if a face ID is not yet set. */ |
| 273 | 297 | ||
| 274 | static void | 298 | static struct face * |
| 275 | fontset_set (fontset, c, newelt) | 299 | fontset_face (fontset, c) |
| 276 | Lisp_Object fontset; | 300 | Lisp_Object fontset; |
| 277 | int c; | 301 | int c; |
| 278 | Lisp_Object newelt; | ||
| 279 | { | 302 | { |
| 280 | int charset, code[3]; | 303 | Lisp_Object base, elt; |
| 281 | Lisp_Object *elt; | 304 | int id; |
| 282 | int i; | 305 | struct face *face; |
| 283 | 306 | ||
| 284 | if (SINGLE_BYTE_CHAR_P (c)) | 307 | base = FONTSET_BASE (fontset); |
| 285 | { | 308 | FONTSET_REF (base, c, elt); |
| 286 | FONTSET_ASCII (fontset) = newelt; | ||
| 287 | return; | ||
| 288 | } | ||
| 289 | 309 | ||
| 290 | SPLIT_CHAR (c, charset, code[0], code[1]); | 310 | if (NILP (elt)) |
| 291 | code[2] = 0; /* anchor */ | 311 | return NULL; |
| 292 | elt = &XCHAR_TABLE (fontset)->contents[charset + 128]; | 312 | |
| 293 | for (i = 0; code[i] > 0; i++) | 313 | elt = Fassoc (elt, FONTSET_FACE_ALIST (fontset)); |
| 294 | { | 314 | if (! CONSP (elt)) |
| 295 | if (!SUB_CHAR_TABLE_P (*elt)) | 315 | return NULL; |
| 296 | *elt = make_sub_char_table (*elt); | 316 | id = XINT (XCDR (elt)); |
| 297 | elt = &XCHAR_TABLE (*elt)->contents[code[i]]; | 317 | face = FACE_FROM_ID (XFRAME (FONTSET_FRAME (fontset)), id); |
| 298 | } | 318 | return face; |
| 299 | if (SUB_CHAR_TABLE_P (*elt)) | ||
| 300 | XCHAR_TABLE (*elt)->defalt = newelt; | ||
| 301 | else | ||
| 302 | *elt = newelt; | ||
| 303 | } | 319 | } |
| 304 | 320 | ||
| 305 | 321 | ||
| 306 | /* Return a newly created fontset with NAME. If BASE is nil, make a | 322 | /* Return a newly created fontset with NAME. If BASE is nil, make a |
| 307 | base fontset. Otherwise make a realized fontset whose parent is | 323 | base fontset. Otherwise make a realized fontset whose base is |
| 308 | BASE. */ | 324 | BASE. */ |
| 309 | 325 | ||
| 310 | static Lisp_Object | 326 | static Lisp_Object |
| @@ -327,7 +343,7 @@ make_fontset (frame, name, base) | |||
| 327 | Lisp_Object tem; | 343 | Lisp_Object tem; |
| 328 | int i; | 344 | int i; |
| 329 | 345 | ||
| 330 | tem = Fmake_vector (make_number (size + 8), Qnil); | 346 | tem = Fmake_vector (make_number (size + 32), Qnil); |
| 331 | for (i = 0; i < size; i++) | 347 | for (i = 0; i < size; i++) |
| 332 | AREF (tem, i) = AREF (Vfontset_table, i); | 348 | AREF (tem, i) = AREF (Vfontset_table, i); |
| 333 | Vfontset_table = tem; | 349 | Vfontset_table = tem; |
| @@ -336,59 +352,23 @@ make_fontset (frame, name, base) | |||
| 336 | fontset = Fmake_char_table (Qfontset, Qnil); | 352 | fontset = Fmake_char_table (Qfontset, Qnil); |
| 337 | 353 | ||
| 338 | FONTSET_ID (fontset) = make_number (id); | 354 | FONTSET_ID (fontset) = make_number (id); |
| 339 | FONTSET_NAME (fontset) = name; | 355 | if (NILP (base)) |
| 340 | FONTSET_FRAME (fontset) = frame; | 356 | { |
| 341 | FONTSET_BASE (fontset) = base; | 357 | FONTSET_NAME (fontset) = name; |
| 358 | } | ||
| 359 | else | ||
| 360 | { | ||
| 361 | FONTSET_NAME (fontset) = Qnil; | ||
| 362 | FONTSET_FRAME (fontset) = frame; | ||
| 363 | FONTSET_BASE (fontset) = base; | ||
| 364 | } | ||
| 342 | 365 | ||
| 343 | AREF (Vfontset_table, id) = fontset; | 366 | ASET (Vfontset_table, id, fontset); |
| 344 | next_fontset_id = id + 1; | 367 | next_fontset_id = id + 1; |
| 345 | return fontset; | 368 | return fontset; |
| 346 | } | 369 | } |
| 347 | 370 | ||
| 348 | 371 | ||
| 349 | /* Return 1 if ID is a valid fontset id, else return 0. */ | ||
| 350 | |||
| 351 | static INLINE int | ||
| 352 | fontset_id_valid_p (id) | ||
| 353 | int id; | ||
| 354 | { | ||
| 355 | return (id >= 0 && id < ASIZE (Vfontset_table) - 1); | ||
| 356 | } | ||
| 357 | |||
| 358 | |||
| 359 | /* Extract `family' and `registry' string from FONTNAME and a cons of | ||
| 360 | them. Actually, `family' may also contain `foundry', `registry' | ||
| 361 | may also contain `encoding' of FONTNAME. But, if FONTNAME doesn't | ||
| 362 | conform to XLFD nor explicitely specifies the other fields | ||
| 363 | (i.e. not using wildcard `*'), return FONTNAME. If FORCE is | ||
| 364 | nonzero, specifications of the other fields are ignored, and return | ||
| 365 | a cons as far as FONTNAME conform to XLFD. */ | ||
| 366 | |||
| 367 | static Lisp_Object | ||
| 368 | font_family_registry (fontname, force) | ||
| 369 | Lisp_Object fontname; | ||
| 370 | int force; | ||
| 371 | { | ||
| 372 | Lisp_Object family, registry; | ||
| 373 | char *p = XSTRING (fontname)->data; | ||
| 374 | char *sep[15]; | ||
| 375 | int i = 0; | ||
| 376 | |||
| 377 | while (*p && i < 15) | ||
| 378 | if (*p++ == '-') | ||
| 379 | { | ||
| 380 | if (!force && i >= 2 && i <= 11 && *p != '*' && p[1] != '-') | ||
| 381 | return fontname; | ||
| 382 | sep[i++] = p; | ||
| 383 | } | ||
| 384 | if (i != 14) | ||
| 385 | return fontname; | ||
| 386 | |||
| 387 | family = make_unibyte_string (sep[0], sep[2] - 1 - sep[0]); | ||
| 388 | registry = make_unibyte_string (sep[12], p - sep[12]); | ||
| 389 | return Fcons (family, registry); | ||
| 390 | } | ||
| 391 | |||
| 392 | 372 | ||
| 393 | /********** INTERFACES TO xfaces.c and dispextern.h **********/ | 373 | /********** INTERFACES TO xfaces.c and dispextern.h **********/ |
| 394 | 374 | ||
| @@ -399,6 +379,7 @@ fontset_name (id) | |||
| 399 | int id; | 379 | int id; |
| 400 | { | 380 | { |
| 401 | Lisp_Object fontset; | 381 | Lisp_Object fontset; |
| 382 | |||
| 402 | fontset = FONTSET_FROM_ID (id); | 383 | fontset = FONTSET_FROM_ID (id); |
| 403 | return FONTSET_NAME (fontset); | 384 | return FONTSET_NAME (fontset); |
| 404 | } | 385 | } |
| @@ -410,56 +391,47 @@ Lisp_Object | |||
| 410 | fontset_ascii (id) | 391 | fontset_ascii (id) |
| 411 | int id; | 392 | int id; |
| 412 | { | 393 | { |
| 413 | Lisp_Object fontset, elt; | 394 | Lisp_Object fontset; |
| 395 | |||
| 414 | fontset= FONTSET_FROM_ID (id); | 396 | fontset= FONTSET_FROM_ID (id); |
| 415 | elt = FONTSET_ASCII (fontset); | 397 | return FONTSET_ASCII (fontset); |
| 416 | return XCDR (elt); | ||
| 417 | } | 398 | } |
| 418 | 399 | ||
| 419 | 400 | ||
| 420 | /* Free fontset of FACE. Called from free_realized_face. */ | 401 | /* Free fontset of FACE defined on frame F. Called from |
| 402 | free_realized_face. */ | ||
| 421 | 403 | ||
| 422 | void | 404 | void |
| 423 | free_face_fontset (f, face) | 405 | free_face_fontset (f, face) |
| 424 | FRAME_PTR f; | 406 | FRAME_PTR f; |
| 425 | struct face *face; | 407 | struct face *face; |
| 426 | { | 408 | { |
| 427 | if (fontset_id_valid_p (face->fontset)) | 409 | AREF (Vfontset_table, face->fontset) = Qnil; |
| 428 | { | 410 | if (face->fontset < next_fontset_id) |
| 429 | AREF (Vfontset_table, face->fontset) = Qnil; | 411 | next_fontset_id = face->fontset; |
| 430 | if (face->fontset < next_fontset_id) | ||
| 431 | next_fontset_id = face->fontset; | ||
| 432 | } | ||
| 433 | } | 412 | } |
| 434 | 413 | ||
| 435 | 414 | ||
| 436 | /* Return 1 iff FACE is suitable for displaying character C. | 415 | /* Return 1 iff FACE is suitable for displaying character C. |
| 437 | Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P | 416 | Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P |
| 438 | when C is not a single byte character.. */ | 417 | when C is not an ASCII character. */ |
| 439 | 418 | ||
| 440 | int | 419 | int |
| 441 | face_suitable_for_char_p (face, c) | 420 | face_suitable_for_char_p (face, c) |
| 442 | struct face *face; | 421 | struct face *face; |
| 443 | int c; | 422 | int c; |
| 444 | { | 423 | { |
| 445 | Lisp_Object fontset, elt; | 424 | Lisp_Object fontset; |
| 446 | |||
| 447 | if (SINGLE_BYTE_CHAR_P (c)) | ||
| 448 | return (face == face->ascii_face); | ||
| 449 | 425 | ||
| 450 | xassert (fontset_id_valid_p (face->fontset)); | ||
| 451 | fontset = FONTSET_FROM_ID (face->fontset); | 426 | fontset = FONTSET_FROM_ID (face->fontset); |
| 452 | xassert (!BASE_FONTSET_P (fontset)); | 427 | return (face == fontset_face (fontset, c)); |
| 453 | |||
| 454 | elt = FONTSET_REF_VIA_BASE (fontset, c); | ||
| 455 | return (!NILP (elt) && face->id == XFASTINT (elt)); | ||
| 456 | } | 428 | } |
| 457 | 429 | ||
| 458 | 430 | ||
| 459 | /* Return ID of face suitable for displaying character C on frame F. | 431 | /* Return ID of face suitable for displaying character C on frame F. |
| 460 | The selection of face is done based on the fontset of FACE. FACE | 432 | The selection of face is done based on the fontset of FACE. FACE |
| 461 | should already have been realized for ASCII characters. Called | 433 | must be reazlied for ASCII characters in advance. Called from the |
| 462 | from the macro FACE_FOR_CHAR when C is not a single byte character. */ | 434 | macro FACE_FOR_CHAR when C is not an ASCII character. */ |
| 463 | 435 | ||
| 464 | int | 436 | int |
| 465 | face_for_char (f, face, c) | 437 | face_for_char (f, face, c) |
| @@ -468,24 +440,19 @@ face_for_char (f, face, c) | |||
| 468 | int c; | 440 | int c; |
| 469 | { | 441 | { |
| 470 | Lisp_Object fontset, elt; | 442 | Lisp_Object fontset, elt; |
| 471 | int face_id; | 443 | struct face *new_face; |
| 472 | 444 | ||
| 473 | xassert (fontset_id_valid_p (face->fontset)); | 445 | xassert (fontset_id_valid_p (face->fontset)); |
| 474 | fontset = FONTSET_FROM_ID (face->fontset); | 446 | fontset = FONTSET_FROM_ID (face->fontset); |
| 475 | xassert (!BASE_FONTSET_P (fontset)); | 447 | xassert (!BASE_FONTSET_P (fontset)); |
| 476 | 448 | ||
| 477 | elt = FONTSET_REF_VIA_BASE (fontset, c); | 449 | new_face = fontset_face (fontset, c); |
| 478 | if (!NILP (elt)) | 450 | if (new_face) |
| 479 | return XINT (elt); | 451 | return new_face->id; |
| 480 | 452 | ||
| 481 | /* No face is recorded for C in the fontset of FACE. Make a new | 453 | /* No face is recorded for C in the fontset of FACE. Make a new |
| 482 | realized face for C that has the same fontset. */ | 454 | realized face for C that has the same fontset. */ |
| 483 | face_id = lookup_face (f, face->lface, c, face); | 455 | return lookup_face (f, face->lface, c, face); |
| 484 | |||
| 485 | /* Record the face ID in FONTSET at the same index as the | ||
| 486 | information in the base fontset. */ | ||
| 487 | FONTSET_SET (fontset, c, make_number (face_id)); | ||
| 488 | return face_id; | ||
| 489 | } | 456 | } |
| 490 | 457 | ||
| 491 | 458 | ||
| @@ -517,52 +484,44 @@ make_fontset_for_ascii_face (f, base_fontset_id) | |||
| 517 | } | 484 | } |
| 518 | 485 | ||
| 519 | 486 | ||
| 520 | /* Return the font name pattern for C that is recorded in the fontset | 487 | /* Return FONT-SPEC recorded in the fontset of FACE for character C. |
| 521 | with ID. If a font name pattern is specified (instead of a cons of | 488 | If FACE is null, or the fontset doesn't contain information about |
| 522 | family and registry), check if a font can be opened by that pattern | 489 | C, get the font name pattern from the default fontset. Called from |
| 523 | to get the fullname. If a font is opened, return that name. | 490 | choose_face_font. */ |
| 524 | Otherwise, return nil. If ID is -1, or the fontset doesn't contain | ||
| 525 | information about C, get the registry and encoding of C from the | ||
| 526 | default fontset. Called from choose_face_font. */ | ||
| 527 | 491 | ||
| 528 | Lisp_Object | 492 | Lisp_Object |
| 529 | fontset_font_pattern (f, id, c) | 493 | fontset_font_pattern (f, face, c) |
| 530 | FRAME_PTR f; | 494 | FRAME_PTR f; |
| 531 | int id, c; | 495 | struct face *face; |
| 496 | int c; | ||
| 532 | { | 497 | { |
| 533 | Lisp_Object fontset, elt; | 498 | Lisp_Object fontset, base, elt; |
| 534 | struct font_info *fontp; | 499 | int id = face ? face->fontset : -1; |
| 535 | 500 | ||
| 536 | elt = Qnil; | 501 | if (id >= 0) |
| 537 | if (fontset_id_valid_p (id)) | ||
| 538 | { | 502 | { |
| 539 | fontset = FONTSET_FROM_ID (id); | 503 | fontset = FONTSET_FROM_ID (id); |
| 540 | xassert (!BASE_FONTSET_P (fontset)); | 504 | xassert (!BASE_FONTSET_P (fontset)); |
| 541 | fontset = FONTSET_BASE (fontset); | 505 | base = FONTSET_BASE (fontset); |
| 542 | elt = FONTSET_REF (fontset, c); | 506 | } |
| 507 | else | ||
| 508 | { | ||
| 509 | base = Vdefault_fontset; | ||
| 543 | } | 510 | } |
| 544 | if (NILP (elt)) | ||
| 545 | elt = FONTSET_REF (Vdefault_fontset, c); | ||
| 546 | |||
| 547 | if (!CONSP (elt)) | ||
| 548 | return Qnil; | ||
| 549 | if (CONSP (XCDR (elt))) | ||
| 550 | return XCDR (elt); | ||
| 551 | |||
| 552 | /* The fontset specifies only a font name pattern (not cons of | ||
| 553 | family and registry). If a font can be opened by that pattern, | ||
| 554 | return the name of opened font. Otherwise return nil. The | ||
| 555 | exception is a font for single byte characters. In that case, we | ||
| 556 | return a cons of FAMILY and REGISTRY extracted from the opened | ||
| 557 | font name. */ | ||
| 558 | elt = XCDR (elt); | ||
| 559 | xassert (STRINGP (elt)); | ||
| 560 | fontp = FS_LOAD_FONT (f, c, XSTRING (elt)->data, -1); | ||
| 561 | if (!fontp) | ||
| 562 | return Qnil; | ||
| 563 | 511 | ||
| 564 | return font_family_registry (build_string (fontp->full_name), | 512 | FONTSET_REF (base, c, elt); |
| 565 | SINGLE_BYTE_CHAR_P (c)); | 513 | if (face && ! NILP (elt)) |
| 514 | { | ||
| 515 | Lisp_Object slot; | ||
| 516 | |||
| 517 | slot = Fassoc (elt, FONTSET_FACE_ALIST (fontset)); | ||
| 518 | if (CONSP (slot)) | ||
| 519 | XSETCDR (slot, make_number (face->id)); | ||
| 520 | FONTSET_FACE_ALIST (fontset) | ||
| 521 | = Fcons (Fcons (elt, make_number (face->id)), | ||
| 522 | FONTSET_FACE_ALIST (fontset)); | ||
| 523 | } | ||
| 524 | return elt; | ||
| 566 | } | 525 | } |
| 567 | 526 | ||
| 568 | 527 | ||
| @@ -570,128 +529,51 @@ fontset_font_pattern (f, id, c) | |||
| 570 | #pragma optimize("", off) | 529 | #pragma optimize("", off) |
| 571 | #endif | 530 | #endif |
| 572 | 531 | ||
| 573 | /* Load a font named FONTNAME to display character C on frame F. | 532 | /* Load a font named FONTNAME on frame F. Return a pointer to the |
| 574 | Return a pointer to the struct font_info of the loaded font. If | 533 | struct font_info of the loaded font. If loading fails, return |
| 575 | loading fails, return NULL. If FACE is non-zero and a fontset is | 534 | NULL. */ |
| 576 | assigned to it, record FACE->id in the fontset for C. If FONTNAME | ||
| 577 | is NULL, the name is taken from the fontset of FACE or what | ||
| 578 | specified by ID. */ | ||
| 579 | 535 | ||
| 580 | struct font_info * | 536 | struct font_info * |
| 581 | fs_load_font (f, c, fontname, id, face) | 537 | fs_load_font (f, fontname) |
| 582 | FRAME_PTR f; | 538 | FRAME_PTR f; |
| 583 | int c; | ||
| 584 | char *fontname; | 539 | char *fontname; |
| 585 | int id; | ||
| 586 | struct face *face; | ||
| 587 | { | 540 | { |
| 588 | Lisp_Object fontset; | 541 | Lisp_Object tail, elt; |
| 589 | Lisp_Object list, elt; | ||
| 590 | int size = 0; | ||
| 591 | struct font_info *fontp; | 542 | struct font_info *fontp; |
| 592 | int charset = CHAR_CHARSET (c); | ||
| 593 | |||
| 594 | if (face) | ||
| 595 | id = face->fontset; | ||
| 596 | if (id < 0) | ||
| 597 | fontset = Qnil; | ||
| 598 | else | ||
| 599 | fontset = FONTSET_FROM_ID (id); | ||
| 600 | |||
| 601 | if (!NILP (fontset) | ||
| 602 | && !BASE_FONTSET_P (fontset)) | ||
| 603 | { | ||
| 604 | elt = FONTSET_REF_VIA_BASE (fontset, c); | ||
| 605 | if (!NILP (elt)) | ||
| 606 | { | ||
| 607 | /* A suitable face for C is already recorded, which means | ||
| 608 | that a proper font is already loaded. */ | ||
| 609 | int face_id = XINT (elt); | ||
| 610 | |||
| 611 | xassert (face_id == face->id); | ||
| 612 | face = FACE_FROM_ID (f, face_id); | ||
| 613 | return (*get_font_info_func) (f, face->font_info_id); | ||
| 614 | } | ||
| 615 | |||
| 616 | if (!fontname && charset == CHARSET_ASCII) | ||
| 617 | { | ||
| 618 | elt = FONTSET_ASCII (fontset); | ||
| 619 | fontname = XSTRING (XCDR (elt))->data; | ||
| 620 | } | ||
| 621 | } | ||
| 622 | 543 | ||
| 623 | if (!fontname) | 544 | if (!fontname) |
| 624 | /* No way to get fontname. */ | 545 | /* No way to get fontname. */ |
| 625 | return 0; | 546 | return 0; |
| 626 | 547 | ||
| 627 | fontp = (*load_font_func) (f, fontname, size); | 548 | fontp = (*load_font_func) (f, fontname, 0); |
| 628 | if (!fontp) | 549 | if (!fontp) |
| 629 | return 0; | 550 | return NULL; |
| 630 | 551 | ||
| 631 | /* Fill in members (charset, vertical_centering, encoding, etc) of | 552 | /* Fill in members (charset, vertical_centering, encoding, etc) of |
| 632 | font_info structure that are not set by (*load_font_func). */ | 553 | font_info structure that are not set by (*load_font_func). */ |
| 633 | fontp->charset = charset; | 554 | for (tail = Vfont_encoding_alist; CONSP (tail); tail = XCDR (tail)) |
| 555 | { | ||
| 556 | elt = XCAR (tail); | ||
| 557 | if (STRINGP (XCAR (elt)) && CHARSETP (XCDR (elt)) | ||
| 558 | && fast_c_string_match_ignore_case (XCAR (elt), fontname) >= 0) | ||
| 559 | { | ||
| 560 | fontp->charset = CHARSET_SYMBOL_ID (XCDR (elt)); | ||
| 561 | break; | ||
| 562 | } | ||
| 563 | } | ||
| 564 | if (! CONSP (tail)) | ||
| 565 | return NULL; | ||
| 634 | 566 | ||
| 635 | fontp->vertical_centering | 567 | fontp->vertical_centering |
| 636 | = (STRINGP (Vvertical_centering_font_regexp) | 568 | = (STRINGP (Vvertical_centering_font_regexp) |
| 637 | && (fast_c_string_match_ignore_case | 569 | && (fast_c_string_match_ignore_case |
| 638 | (Vvertical_centering_font_regexp, fontp->full_name) >= 0)); | 570 | (Vvertical_centering_font_regexp, fontp->full_name) >= 0)); |
| 639 | 571 | ||
| 640 | if (fontp->encoding[1] != FONT_ENCODING_NOT_DECIDED) | 572 | fontp->font_encoder = NULL; |
| 641 | { | ||
| 642 | /* The font itself tells which code points to be used. Use this | ||
| 643 | encoding for all other charsets. */ | ||
| 644 | int i; | ||
| 645 | |||
| 646 | fontp->encoding[0] = fontp->encoding[1]; | ||
| 647 | for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++) | ||
| 648 | fontp->encoding[i] = fontp->encoding[1]; | ||
| 649 | } | ||
| 650 | else | ||
| 651 | { | ||
| 652 | /* The font itself doesn't have information about encoding. */ | ||
| 653 | int i; | ||
| 654 | |||
| 655 | fontname = fontp->full_name; | ||
| 656 | /* By default, encoding of ASCII chars is 0 (i.e. 0x00..0x7F), | ||
| 657 | others is 1 (i.e. 0x80..0xFF). */ | ||
| 658 | fontp->encoding[0] = 0; | ||
| 659 | for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++) | ||
| 660 | fontp->encoding[i] = 1; | ||
| 661 | /* Then override them by a specification in Vfont_encoding_alist. */ | ||
| 662 | for (list = Vfont_encoding_alist; CONSP (list); list = XCDR (list)) | ||
| 663 | { | ||
| 664 | elt = XCAR (list); | ||
| 665 | if (CONSP (elt) | ||
| 666 | && STRINGP (XCAR (elt)) && CONSP (XCDR (elt)) | ||
| 667 | && (fast_c_string_match_ignore_case (XCAR (elt), fontname) | ||
| 668 | >= 0)) | ||
| 669 | { | ||
| 670 | Lisp_Object tmp; | ||
| 671 | |||
| 672 | for (tmp = XCDR (elt); CONSP (tmp); tmp = XCDR (tmp)) | ||
| 673 | if (CONSP (XCAR (tmp)) | ||
| 674 | && ((i = get_charset_id (XCAR (XCAR (tmp)))) | ||
| 675 | >= 0) | ||
| 676 | && INTEGERP (XCDR (XCAR (tmp))) | ||
| 677 | && XFASTINT (XCDR (XCAR (tmp))) < 4) | ||
| 678 | fontp->encoding[i] | ||
| 679 | = XFASTINT (XCDR (XCAR (tmp))); | ||
| 680 | } | ||
| 681 | } | ||
| 682 | } | ||
| 683 | |||
| 684 | fontp->font_encoder = (struct ccl_program *) 0; | ||
| 685 | 573 | ||
| 686 | if (find_ccl_program_func) | 574 | if (find_ccl_program_func) |
| 687 | (*find_ccl_program_func) (fontp); | 575 | (*find_ccl_program_func) (fontp); |
| 688 | 576 | ||
| 689 | /* If we loaded a font for a face that has fontset, record the face | ||
| 690 | ID in the fontset for C. */ | ||
| 691 | if (face | ||
| 692 | && !NILP (fontset) | ||
| 693 | && !BASE_FONTSET_P (fontset)) | ||
| 694 | FONTSET_SET (fontset, c, make_number (face->id)); | ||
| 695 | return fontp; | 577 | return fontp; |
| 696 | } | 578 | } |
| 697 | 579 | ||
| @@ -826,9 +708,7 @@ If REGEXPP is non-nil, PATTERN is a regular expression. */) | |||
| 826 | return FONTSET_NAME (fontset); | 708 | return FONTSET_NAME (fontset); |
| 827 | } | 709 | } |
| 828 | 710 | ||
| 829 | /* Return a list of base fontset names matching PATTERN on frame F. | 711 | /* Return a list of base fontset names matching PATTERN on frame F. */ |
| 830 | If SIZE is not 0, it is the size (maximum bound width) of fontsets | ||
| 831 | to be listed. */ | ||
| 832 | 712 | ||
| 833 | Lisp_Object | 713 | Lisp_Object |
| 834 | list_fontsets (f, pattern, size) | 714 | list_fontsets (f, pattern, size) |
| @@ -861,95 +741,43 @@ list_fontsets (f, pattern, size) | |||
| 861 | : strcmp (XSTRING (pattern)->data, name)) | 741 | : strcmp (XSTRING (pattern)->data, name)) |
| 862 | continue; | 742 | continue; |
| 863 | 743 | ||
| 864 | if (size) | ||
| 865 | { | ||
| 866 | struct font_info *fontp; | ||
| 867 | fontp = FS_LOAD_FONT (f, 0, NULL, id); | ||
| 868 | if (!fontp || size != fontp->size) | ||
| 869 | continue; | ||
| 870 | } | ||
| 871 | val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val); | 744 | val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val); |
| 872 | } | 745 | } |
| 873 | 746 | ||
| 874 | return val; | 747 | return val; |
| 875 | } | 748 | } |
| 876 | 749 | ||
| 877 | DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0, | ||
| 878 | doc: /* Create a new fontset NAME that contains font information in FONTLIST. | ||
| 879 | FONTLIST is an alist of charsets vs corresponding font name patterns. */) | ||
| 880 | (name, fontlist) | ||
| 881 | Lisp_Object name, fontlist; | ||
| 882 | { | ||
| 883 | Lisp_Object fontset, elements, ascii_font; | ||
| 884 | Lisp_Object tem, tail, elt; | ||
| 885 | 750 | ||
| 886 | (*check_window_system_func) (); | 751 | /* Free all realized fontsets whose base fontset is BASE. */ |
| 887 | 752 | ||
| 888 | CHECK_STRING (name); | 753 | static void |
| 889 | CHECK_LIST (fontlist); | 754 | free_realized_fontsets (base) |
| 755 | Lisp_Object base; | ||
| 756 | { | ||
| 757 | int id; | ||
| 890 | 758 | ||
| 891 | name = Fdowncase (name); | 759 | BLOCK_INPUT; |
| 892 | tem = Fquery_fontset (name, Qnil); | 760 | for (id = 0; id < ASIZE (Vfontset_table); id++) |
| 893 | if (!NILP (tem)) | ||
| 894 | error ("Fontset `%s' matches the existing fontset `%s'", | ||
| 895 | XSTRING (name)->data, XSTRING (tem)->data); | ||
| 896 | |||
| 897 | /* Check the validity of FONTLIST while creating a template for | ||
| 898 | fontset elements. */ | ||
| 899 | elements = ascii_font = Qnil; | ||
| 900 | for (tail = fontlist; CONSP (tail); tail = XCDR (tail)) | ||
| 901 | { | 761 | { |
| 902 | int c, charset; | 762 | Lisp_Object this = AREF (Vfontset_table, id); |
| 903 | 763 | ||
| 904 | tem = XCAR (tail); | 764 | if (EQ (FONTSET_BASE (this), base)) |
| 905 | if (!CONSP (tem) | ||
| 906 | || (charset = get_charset_id (XCAR (tem))) < 0 | ||
| 907 | || (!STRINGP (XCDR (tem)) && !CONSP (XCDR (tem)))) | ||
| 908 | error ("Elements of fontlist must be a cons of charset and font name pattern"); | ||
| 909 | |||
| 910 | tem = XCDR (tem); | ||
| 911 | if (STRINGP (tem)) | ||
| 912 | tem = Fdowncase (tem); | ||
| 913 | else | ||
| 914 | tem = Fcons (Fdowncase (Fcar (tem)), Fdowncase (Fcdr (tem))); | ||
| 915 | if (charset == CHARSET_ASCII) | ||
| 916 | ascii_font = tem; | ||
| 917 | else | ||
| 918 | { | 765 | { |
| 919 | c = MAKE_CHAR (charset, 0, 0); | 766 | Lisp_Object tail; |
| 920 | elements = Fcons (Fcons (make_number (c), tem), elements); | ||
| 921 | } | ||
| 922 | } | ||
| 923 | |||
| 924 | if (NILP (ascii_font)) | ||
| 925 | error ("No ASCII font in the fontlist"); | ||
| 926 | 767 | ||
| 927 | fontset = make_fontset (Qnil, name, Qnil); | 768 | for (tail = FONTSET_FACE_ALIST (this); CONSP (tail); |
| 928 | FONTSET_ASCII (fontset) = Fcons (make_number (0), ascii_font); | 769 | tail = XCDR (tail)) |
| 929 | for (; CONSP (elements); elements = XCDR (elements)) | 770 | { |
| 930 | { | 771 | FRAME_PTR f = XFRAME (FONTSET_FRAME (this)); |
| 931 | elt = XCAR (elements); | 772 | int face_id = XINT (XCDR (XCAR (tail))); |
| 932 | tem = XCDR (elt); | 773 | struct face *face = FACE_FROM_ID (f, face_id); |
| 933 | if (STRINGP (tem)) | 774 | |
| 934 | tem = font_family_registry (tem, 0); | 775 | /* Face THIS itself is also freed by the following call. */ |
| 935 | tem = Fcons (XCAR (elt), tem); | 776 | free_realized_face (f, face); |
| 936 | FONTSET_SET (fontset, XINT (XCAR (elt)), tem); | 777 | } |
| 778 | } | ||
| 937 | } | 779 | } |
| 938 | 780 | UNBLOCK_INPUT; | |
| 939 | return Qnil; | ||
| 940 | } | ||
| 941 | |||
| 942 | |||
| 943 | /* Clear all elements of FONTSET for multibyte characters. */ | ||
| 944 | |||
| 945 | static void | ||
| 946 | clear_fontset_elements (fontset) | ||
| 947 | Lisp_Object fontset; | ||
| 948 | { | ||
| 949 | int i; | ||
| 950 | |||
| 951 | for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++) | ||
| 952 | XCHAR_TABLE (fontset)->contents[i] = Qnil; | ||
| 953 | } | 781 | } |
| 954 | 782 | ||
| 955 | 783 | ||
| @@ -974,88 +802,76 @@ check_fontset_name (name) | |||
| 974 | } | 802 | } |
| 975 | 803 | ||
| 976 | DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0, | 804 | DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0, |
| 977 | doc: /* Modify fontset NAME to use FONTNAME for CHARACTER. | 805 | doc: /* Modify fontset NAME to use FONT-SPEC for characters of CHARSETS. |
| 978 | 806 | ||
| 979 | CHARACTER may be a cons; (FROM . TO), where FROM and TO are | 807 | CHARSET may be a cons; (FROM . TO), where FROM and TO are characters. |
| 980 | non-generic characters. In that case, use FONTNAME | 808 | In that case, use FONT-SPEC for all characters in the range FROM and |
| 981 | for all characters in the range FROM and TO (inclusive). | 809 | TO (inclusive). |
| 982 | CHARACTER may be a charset. In that case, use FONTNAME | 810 | |
| 983 | for all character in the charsets. | 811 | FONT-SPEC is be a vector; [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ] |
| 984 | 812 | ||
| 985 | FONTNAME may be a cons; (FAMILY . REGISTRY), where FAMILY is a family | 813 | FONT-SPEC may be a cons; (FAMILY . REGISTRY), where FAMILY is a family |
| 986 | name of a font, REGISTRY is a registry name of a font. */) | 814 | name of a font, REGSITRY is a registry name of a font. |
| 987 | (name, character, fontname, frame) | 815 | |
| 988 | Lisp_Object name, character, fontname, frame; | 816 | FONT-SPEC may be a font name string. */) |
| 817 | (name, charset, font_spec, frame) | ||
| 818 | Lisp_Object name, charset, font_spec, frame; | ||
| 989 | { | 819 | { |
| 990 | Lisp_Object fontset, elt; | 820 | Lisp_Object fontset; |
| 991 | Lisp_Object realized; | ||
| 992 | int from, to; | ||
| 993 | int id; | ||
| 994 | Lisp_Object family, registry; | 821 | Lisp_Object family, registry; |
| 822 | int charset_id; | ||
| 995 | 823 | ||
| 996 | fontset = check_fontset_name (name); | 824 | fontset = check_fontset_name (name); |
| 997 | 825 | ||
| 998 | if (CONSP (character)) | 826 | if (VECTORP (font_spec)) |
| 999 | { | ||
| 1000 | /* CH should be (FROM . TO) where FROM and TO are non-generic | ||
| 1001 | characters. */ | ||
| 1002 | CHECK_NUMBER_CAR (character); | ||
| 1003 | CHECK_NUMBER_CDR (character); | ||
| 1004 | from = XINT (XCAR (character)); | ||
| 1005 | to = XINT (XCDR (character)); | ||
| 1006 | if (!char_valid_p (from, 0) || !char_valid_p (to, 0)) | ||
| 1007 | error ("Character range should be by non-generic characters."); | ||
| 1008 | if (!NILP (name) | ||
| 1009 | && (SINGLE_BYTE_CHAR_P (from) || SINGLE_BYTE_CHAR_P (to))) | ||
| 1010 | error ("Can't change font for a single byte character"); | ||
| 1011 | } | ||
| 1012 | else if (SYMBOLP (character)) | ||
| 1013 | { | 827 | { |
| 1014 | elt = Fget (character, Qcharset); | 828 | int i; |
| 1015 | if (!VECTORP (elt) || ASIZE (elt) < 1 || !NATNUMP (AREF (elt, 0))) | 829 | Lisp_Object val; |
| 1016 | error ("Invalid charset: %s", (XSYMBOL (character)->name)->data); | 830 | |
| 1017 | from = MAKE_CHAR (XINT (AREF (elt, 0)), 0, 0); | 831 | font_spec = Fcopy_sequence (font_spec); |
| 1018 | to = from; | 832 | for (i = 0; i < 5; i++) |
| 1019 | } | 833 | { |
| 1020 | else | 834 | val = Faref (font_spec, make_number (i)); |
| 1021 | { | 835 | if (! NILP (val)) |
| 1022 | CHECK_NUMBER (character); | 836 | { |
| 1023 | from = XINT (character); | 837 | CHECK_STRING (val); |
| 1024 | to = from; | 838 | ASET (font_spec, i, Fdowncase (val)); |
| 839 | } | ||
| 840 | } | ||
| 841 | val = Faref (font_spec, make_number (5)); | ||
| 842 | CHECK_STRING (val); | ||
| 843 | ASET (font_spec, 5, Fdowncase (val)); | ||
| 1025 | } | 844 | } |
| 1026 | if (!char_valid_p (from, 1)) | 845 | else if (STRINGP (font_spec)) |
| 1027 | invalid_character (from); | 846 | font_spec = Fdowncase (font_spec); |
| 1028 | if (SINGLE_BYTE_CHAR_P (from)) | 847 | else if (CONSP (font_spec)) |
| 1029 | error ("Can't change font for a single byte character"); | ||
| 1030 | if (from < to) | ||
| 1031 | { | 848 | { |
| 1032 | if (!char_valid_p (to, 1)) | 849 | CHECK_CONS (font_spec); |
| 1033 | invalid_character (to); | 850 | family = XCAR (font_spec); |
| 1034 | if (SINGLE_BYTE_CHAR_P (to)) | 851 | registry = XCDR (font_spec); |
| 1035 | error ("Can't change font for a single byte character"); | 852 | font_spec = Fmake_vector (make_number (6), Qnil); |
| 853 | if (!NILP (family)) | ||
| 854 | { | ||
| 855 | CHECK_STRING (family); | ||
| 856 | ASET (font_spec, 0, Fdowncase (family)); | ||
| 857 | } | ||
| 858 | CHECK_STRING (registry); | ||
| 859 | ASET (font_spec, 5, Fdowncase (registry)); | ||
| 1036 | } | 860 | } |
| 1037 | 861 | ||
| 1038 | if (STRINGP (fontname)) | 862 | if (SYMBOLP (charset)) |
| 1039 | { | 863 | { |
| 1040 | fontname = Fdowncase (fontname); | 864 | CHECK_CHARSET (charset); |
| 1041 | elt = Fcons (make_number (from), font_family_registry (fontname, 0)); | ||
| 1042 | } | 865 | } |
| 1043 | else | 866 | else |
| 1044 | { | 867 | { |
| 1045 | CHECK_CONS (fontname); | 868 | Lisp_Object from, to; |
| 1046 | family = XCAR (fontname); | 869 | |
| 1047 | registry = XCDR (fontname); | 870 | /* CHARSET should be (FROM . TO). */ |
| 1048 | if (!NILP (family)) | 871 | from = Fcar (charset); |
| 1049 | { | 872 | to = Fcdr (charset); |
| 1050 | CHECK_STRING (family); | 873 | CHECK_CHARACTER (from); |
| 1051 | family = Fdowncase (family); | 874 | CHECK_CHARACTER (to); |
| 1052 | } | ||
| 1053 | if (!NILP (registry)) | ||
| 1054 | { | ||
| 1055 | CHECK_STRING (registry); | ||
| 1056 | registry = Fdowncase (registry); | ||
| 1057 | } | ||
| 1058 | elt = Fcons (make_number (from), Fcons (family, registry)); | ||
| 1059 | } | 875 | } |
| 1060 | 876 | ||
| 1061 | /* The arg FRAME is kept for backward compatibility. We only check | 877 | /* The arg FRAME is kept for backward compatibility. We only check |
| @@ -1063,30 +879,69 @@ name of a font, REGISTRY is a registry name of a font. */) | |||
| 1063 | if (!NILP (frame)) | 879 | if (!NILP (frame)) |
| 1064 | CHECK_LIVE_FRAME (frame); | 880 | CHECK_LIVE_FRAME (frame); |
| 1065 | 881 | ||
| 1066 | for (; from <= to; from++) | 882 | FONTSET_SET (fontset, charset, font_spec); |
| 1067 | FONTSET_SET (fontset, from, elt); | ||
| 1068 | Foptimize_char_table (fontset); | ||
| 1069 | 883 | ||
| 1070 | /* If there's a realized fontset REALIZED whose parent is FONTSET, | 884 | /* Free all realized fontsets whose base is FONTSET. This way, the |
| 1071 | clear all the elements of REALIZED and free all multibyte faces | 885 | specified character(s) are surely redisplayed by a correct |
| 1072 | whose fontset is REALIZED. This way, the specified character(s) | 886 | font. */ |
| 1073 | are surely redisplayed by a correct font. */ | 887 | free_realized_fontsets (fontset); |
| 1074 | for (id = 0; id < ASIZE (Vfontset_table); id++) | ||
| 1075 | { | ||
| 1076 | realized = AREF (Vfontset_table, id); | ||
| 1077 | if (!NILP (realized) | ||
| 1078 | && !BASE_FONTSET_P (realized) | ||
| 1079 | && EQ (FONTSET_BASE (realized), fontset)) | ||
| 1080 | { | ||
| 1081 | FRAME_PTR f = XFRAME (FONTSET_FRAME (realized)); | ||
| 1082 | clear_fontset_elements (realized); | ||
| 1083 | free_realized_multibyte_face (f, id); | ||
| 1084 | } | ||
| 1085 | } | ||
| 1086 | 888 | ||
| 1087 | return Qnil; | 889 | return Qnil; |
| 1088 | } | 890 | } |
| 1089 | 891 | ||
| 892 | |||
| 893 | DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0, | ||
| 894 | doc: /* Create a new fontset NAME from font information in FONTLIST. | ||
| 895 | |||
| 896 | FONTLIST is an alist of charsets vs corresponding font specifications. | ||
| 897 | Each element of FONTLIST has the form (CHARSET . FONT-SPEC), where | ||
| 898 | a character of CHARSET is displayed by a font that matches FONT-SPEC. | ||
| 899 | |||
| 900 | FONT-SPEC is a vector [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ], where | ||
| 901 | FAMILY is a string specifying the font family, | ||
| 902 | WEIGHT is a string specifying the weight of the font, | ||
| 903 | SLANT is a string specifying the slant of the font, | ||
| 904 | WIDTH is a string specifying the width of the font, | ||
| 905 | ADSTYLE is a string specifying the adstyle of the font, | ||
| 906 | REGISTRY is a string specifying the charset-registry of the font. | ||
| 907 | |||
| 908 | See also the documentation of `set-face-attribute' for the detail of | ||
| 909 | these vector elements. | ||
| 910 | |||
| 911 | FONT-SPEC may be a font name (string). */) | ||
| 912 | (name, fontlist) | ||
| 913 | Lisp_Object name, fontlist; | ||
| 914 | { | ||
| 915 | Lisp_Object fontset, ascii_font; | ||
| 916 | Lisp_Object tem, tail; | ||
| 917 | |||
| 918 | CHECK_STRING (name); | ||
| 919 | CHECK_LIST (fontlist); | ||
| 920 | |||
| 921 | name = Fdowncase (name); | ||
| 922 | tem = Fquery_fontset (name, Qnil); | ||
| 923 | if (! NILP (tem)) | ||
| 924 | free_realized_fontsets (tem); | ||
| 925 | |||
| 926 | fontset = make_fontset (Qnil, name, Qnil); | ||
| 927 | |||
| 928 | /* Check the validity of FONTLIST. */ | ||
| 929 | ascii_font = Fcdr (Fassq (Qascii, fontlist)); | ||
| 930 | if (NILP (ascii_font)) | ||
| 931 | error ("No ascii font specified"); | ||
| 932 | if (! STRINGP (ascii_font)) | ||
| 933 | ascii_font = generate_ascii_font (name, ascii_font); | ||
| 934 | |||
| 935 | fontlist = Fcopy_sequence (fontlist); | ||
| 936 | for (tail = fontlist; ! NILP (tail); tail = Fcdr (tail)) | ||
| 937 | Fset_fontset_font (name, Fcar (Fcar (tail)), Fcdr (Fcar (tail)), Qnil); | ||
| 938 | |||
| 939 | FONTSET_ASCII (fontset) = ascii_font; | ||
| 940 | |||
| 941 | return name; | ||
| 942 | } | ||
| 943 | |||
| 944 | |||
| 1090 | DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0, | 945 | DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0, |
| 1091 | doc: /* Return information about a font named NAME on frame FRAME. | 946 | doc: /* Return information about a font named NAME on frame FRAME. |
| 1092 | If FRAME is omitted or nil, use the selected frame. | 947 | If FRAME is omitted or nil, use the selected frame. |
| @@ -1173,8 +1028,6 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 1, 0, | |||
| 1173 | args_out_of_range_3 (position, make_number (BEGV), make_number (ZV)); | 1028 | args_out_of_range_3 (position, make_number (BEGV), make_number (ZV)); |
| 1174 | pos_byte = CHAR_TO_BYTE (pos); | 1029 | pos_byte = CHAR_TO_BYTE (pos); |
| 1175 | c = FETCH_CHAR (pos_byte); | 1030 | c = FETCH_CHAR (pos_byte); |
| 1176 | if (! CHAR_VALID_P (c, 0)) | ||
| 1177 | return Qnil; | ||
| 1178 | window = Fget_buffer_window (Fcurrent_buffer (), Qnil); | 1031 | window = Fget_buffer_window (Fcurrent_buffer (), Qnil); |
| 1179 | if (NILP (window)) | 1032 | if (NILP (window)) |
| 1180 | return Qnil; | 1033 | return Qnil; |
| @@ -1204,7 +1057,7 @@ accumulate_font_info (arg, character, elt) | |||
| 1204 | Lisp_Object last, last_char, last_elt; | 1057 | Lisp_Object last, last_char, last_elt; |
| 1205 | 1058 | ||
| 1206 | if (!CONSP (elt) && !SINGLE_BYTE_CHAR_P (XINT (character))) | 1059 | if (!CONSP (elt) && !SINGLE_BYTE_CHAR_P (XINT (character))) |
| 1207 | elt = FONTSET_REF (Vdefault_fontset, XINT (character)); | 1060 | FONTSET_REF (Vdefault_fontset, XINT (character), elt); |
| 1208 | if (!CONSP (elt)) | 1061 | if (!CONSP (elt)) |
| 1209 | return; | 1062 | return; |
| 1210 | last = XCAR (arg); | 1063 | last = XCAR (arg); |
| @@ -1213,7 +1066,7 @@ accumulate_font_info (arg, character, elt) | |||
| 1213 | elt = XCDR (elt); | 1066 | elt = XCDR (elt); |
| 1214 | if (!NILP (Fequal (elt, last_elt))) | 1067 | if (!NILP (Fequal (elt, last_elt))) |
| 1215 | { | 1068 | { |
| 1216 | int this_charset = CHAR_CHARSET (XINT (character)); | 1069 | struct charset *this_charset = CHAR_CHARSET (XINT (character)); |
| 1217 | 1070 | ||
| 1218 | if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */ | 1071 | if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */ |
| 1219 | { | 1072 | { |
| @@ -1243,13 +1096,11 @@ The value is a vector: | |||
| 1243 | where, | 1096 | where, |
| 1244 | SIZE is the maximum bound width of ASCII font in the fontset, | 1097 | SIZE is the maximum bound width of ASCII font in the fontset, |
| 1245 | HEIGHT is the maximum bound height of ASCII font in the fontset, | 1098 | HEIGHT is the maximum bound height of ASCII font in the fontset, |
| 1246 | CHARSET-OR-RANGE is a charset, a character (may be a generic character) | 1099 | CHARSET-OR-RANGE is a charset or a cons of two characters specifying |
| 1247 | or a cons of two characters specifying the range of characters. | 1100 | the range of characters. |
| 1248 | FONT-SPEC is a fontname pattern string or a cons (FAMILY . REGISTRY), | 1101 | FONT-SPEC is a fontname pattern string or a vector |
| 1249 | where FAMILY is a `FAMILY' field of a XLFD font name, | 1102 | [ FAMILY WEIGHT SLANT ADSTYLE REGISTRY ]. |
| 1250 | REGISTRY is a `CHARSET_REGISTRY' field of a XLFD font name. | 1103 | See the documentation of `new-fontset' for the meanings those elements. |
| 1251 | FAMILY may contain a `FOUNDRY' field at the head. | ||
| 1252 | REGISTRY may contain a `CHARSET_ENCODING' field at the tail. | ||
| 1253 | OPENEDs are names of fonts actually opened. | 1104 | OPENEDs are names of fonts actually opened. |
| 1254 | If the ASCII font is not yet opened, SIZE and HEIGHT are 0. | 1105 | If the ASCII font is not yet opened, SIZE and HEIGHT are 0. |
| 1255 | If FRAME is omitted, it defaults to the currently selected frame. */) | 1106 | If FRAME is omitted, it defaults to the currently selected frame. */) |
| @@ -1258,7 +1109,6 @@ If FRAME is omitted, it defaults to the currently selected frame. */) | |||
| 1258 | { | 1109 | { |
| 1259 | Lisp_Object fontset; | 1110 | Lisp_Object fontset; |
| 1260 | FRAME_PTR f; | 1111 | FRAME_PTR f; |
| 1261 | Lisp_Object indices[3]; | ||
| 1262 | Lisp_Object val, tail, elt; | 1112 | Lisp_Object val, tail, elt; |
| 1263 | Lisp_Object *realized; | 1113 | Lisp_Object *realized; |
| 1264 | struct font_info *fontp = NULL; | 1114 | struct font_info *fontp = NULL; |
| @@ -1290,56 +1140,67 @@ If FRAME is omitted, it defaults to the currently selected frame. */) | |||
| 1290 | (LAST FONT-INFO FONT-INFO ...), where FONT-INFO is (CHAR-OR-RANGE | 1140 | (LAST FONT-INFO FONT-INFO ...), where FONT-INFO is (CHAR-OR-RANGE |
| 1291 | FONT-SPEC). See the comment for accumulate_font_info for the | 1141 | FONT-SPEC). See the comment for accumulate_font_info for the |
| 1292 | detail. */ | 1142 | detail. */ |
| 1293 | val = Fcons (Fcons (make_number (0), | 1143 | val = Fcons (Fcons (Qascii, Fcons (FONTSET_ASCII (fontset), Qnil)), Qnil); |
| 1294 | Fcons (XCDR (FONTSET_ASCII (fontset)), Qnil)), | ||
| 1295 | Qnil); | ||
| 1296 | val = Fcons (val, val); | 1144 | val = Fcons (val, val); |
| 1297 | map_char_table (accumulate_font_info, Qnil, fontset, val, 0, indices); | 1145 | for (i = 128; i <= MAX_CHAR; ) |
| 1146 | { | ||
| 1147 | Lisp_Object elt; | ||
| 1148 | int from, to; | ||
| 1149 | |||
| 1150 | elt = char_table_ref_and_range (fontset, i, &from, &to); | ||
| 1151 | if (! NILP (elt)) | ||
| 1152 | { | ||
| 1153 | elt = Fcons (Fcons (make_number (from), make_number (to)), | ||
| 1154 | Fcons (elt, Qnil)); | ||
| 1155 | XSETCDR (XCAR (val), Fcons (elt, Qnil)); | ||
| 1156 | XSETCAR (val, XCDR (XCAR (val))); | ||
| 1157 | } | ||
| 1158 | i = to + 1; | ||
| 1159 | } | ||
| 1160 | |||
| 1161 | for (tail = FONTSET_CHARSET_ALIST (fontset); | ||
| 1162 | CONSP (tail); tail = XCDR (tail)) | ||
| 1163 | { | ||
| 1164 | elt = XCAR (tail); | ||
| 1165 | elt = Fcons (XCAR (elt), Fcons (XCDR (elt), Qnil)); | ||
| 1166 | XSETCDR (XCAR (val), Fcons (elt, Qnil)); | ||
| 1167 | XSETCAR (val, XCDR (XCAR (val))); | ||
| 1168 | } | ||
| 1169 | |||
| 1298 | val = XCDR (val); | 1170 | val = XCDR (val); |
| 1299 | 1171 | ||
| 1300 | /* For each FONT-INFO, if CHAR_OR_RANGE (car part) is a generic | 1172 | /* If fonts are opened for FONT-SPEC, append the names of the fonts to |
| 1301 | character for a charset, replace it with the charset symbol. If | ||
| 1302 | fonts are opened for FONT-SPEC, append the names of the fonts to | ||
| 1303 | FONT-SPEC. */ | 1173 | FONT-SPEC. */ |
| 1304 | for (tail = val; CONSP (tail); tail = XCDR (tail)) | 1174 | for (tail = val; CONSP (tail); tail = XCDR (tail)) |
| 1305 | { | 1175 | { |
| 1306 | int c; | 1176 | int c; |
| 1177 | |||
| 1307 | elt = XCAR (tail); | 1178 | elt = XCAR (tail); |
| 1308 | if (INTEGERP (XCAR (elt))) | ||
| 1309 | { | ||
| 1310 | int charset, c1, c2; | ||
| 1311 | c = XINT (XCAR (elt)); | ||
| 1312 | SPLIT_CHAR (c, charset, c1, c2); | ||
| 1313 | if (c1 == 0) | ||
| 1314 | XSETCAR (elt, CHARSET_SYMBOL (charset)); | ||
| 1315 | } | ||
| 1316 | else | ||
| 1317 | c = XINT (XCAR (XCAR (elt))); | ||
| 1318 | for (i = 0; i < n_realized; i++) | 1179 | for (i = 0; i < n_realized; i++) |
| 1319 | { | 1180 | { |
| 1320 | Lisp_Object face_id, font; | 1181 | int face_id; |
| 1321 | struct face *face; | 1182 | struct face *face; |
| 1183 | Lisp_Object face_list, fontname; | ||
| 1322 | 1184 | ||
| 1323 | face_id = FONTSET_REF_VIA_BASE (realized[i], c); | 1185 | for (face_list = FONTSET_FACE_ALIST (realized[i]); |
| 1324 | if (INTEGERP (face_id)) | 1186 | CONSP (face_list); face_list = XCDR (face_list)) |
| 1325 | { | 1187 | { |
| 1326 | face = FACE_FROM_ID (f, XINT (face_id)); | 1188 | int face_id = XINT (XCDR (XCAR (face_list))); |
| 1327 | if (face && face->font && face->font_name) | 1189 | struct face *face = FACE_FROM_ID (f, face_id); |
| 1190 | |||
| 1191 | if (face->font && face->font_name) | ||
| 1328 | { | 1192 | { |
| 1329 | font = build_string (face->font_name); | 1193 | fontname = build_string (face->font_name); |
| 1330 | if (NILP (Fmember (font, XCDR (XCDR (elt))))) | 1194 | if (NILP (Fmember (fontname, XCDR (XCDR (elt))))) |
| 1331 | XSETCDR (XCDR (elt), Fcons (font, XCDR (XCDR (elt)))); | 1195 | XSETCDR (XCDR (elt), Fcons (fontname, XCDR (XCDR (elt)))); |
| 1332 | } | 1196 | } |
| 1333 | } | 1197 | } |
| 1334 | } | 1198 | } |
| 1335 | } | 1199 | } |
| 1336 | 1200 | ||
| 1337 | elt = Fcdr (Fcdr (Fassq (CHARSET_SYMBOL (CHARSET_ASCII), val))); | 1201 | elt = XCDR (XCDR (XCAR (val))); |
| 1338 | if (CONSP (elt)) | 1202 | if (CONSP (elt)) |
| 1339 | { | 1203 | fontp = (*query_font_func) (f, XSTRING (XCAR (elt))->data); |
| 1340 | elt = XCAR (elt); | ||
| 1341 | fontp = (*query_font_func) (f, XSTRING (elt)->data); | ||
| 1342 | } | ||
| 1343 | val = Fmake_vector (make_number (3), val); | 1204 | val = Fmake_vector (make_number (3), val); |
| 1344 | AREF (val, 0) = fontp ? make_number (fontp->size) : make_number (0); | 1205 | AREF (val, 0) = fontp ? make_number (fontp->size) : make_number (0); |
| 1345 | AREF (val, 1) = fontp ? make_number (fontp->height) : make_number (0); | 1206 | AREF (val, 1) = fontp ? make_number (fontp->height) : make_number (0); |
| @@ -1357,15 +1218,9 @@ If NAME is t, find a font name pattern in the default fontset. */) | |||
| 1357 | 1218 | ||
| 1358 | fontset = check_fontset_name (name); | 1219 | fontset = check_fontset_name (name); |
| 1359 | 1220 | ||
| 1360 | CHECK_NUMBER (ch); | 1221 | CHECK_CHARACTER (ch); |
| 1361 | c = XINT (ch); | 1222 | c = XINT (ch); |
| 1362 | if (!char_valid_p (c, 1)) | 1223 | FONTSET_REF (fontset, c, elt); |
| 1363 | invalid_character (c); | ||
| 1364 | |||
| 1365 | elt = FONTSET_REF (fontset, c); | ||
| 1366 | if (CONSP (elt)) | ||
| 1367 | elt = XCDR (elt); | ||
| 1368 | |||
| 1369 | return elt; | 1224 | return elt; |
| 1370 | } | 1225 | } |
| 1371 | 1226 | ||
| @@ -1397,7 +1252,7 @@ syms_of_fontset () | |||
| 1397 | 1252 | ||
| 1398 | Qfontset = intern ("fontset"); | 1253 | Qfontset = intern ("fontset"); |
| 1399 | staticpro (&Qfontset); | 1254 | staticpro (&Qfontset); |
| 1400 | Fput (Qfontset, Qchar_table_extra_slots, make_number (3)); | 1255 | Fput (Qfontset, Qchar_table_extra_slots, make_number (7)); |
| 1401 | 1256 | ||
| 1402 | Vcached_fontset_data = Qnil; | 1257 | Vcached_fontset_data = Qnil; |
| 1403 | staticpro (&Vcached_fontset_data); | 1258 | staticpro (&Vcached_fontset_data); |
| @@ -1410,19 +1265,21 @@ syms_of_fontset () | |||
| 1410 | FONTSET_ID (Vdefault_fontset) = make_number (0); | 1265 | FONTSET_ID (Vdefault_fontset) = make_number (0); |
| 1411 | FONTSET_NAME (Vdefault_fontset) | 1266 | FONTSET_NAME (Vdefault_fontset) |
| 1412 | = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default"); | 1267 | = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default"); |
| 1268 | { | ||
| 1269 | Lisp_Object default_ascii_font; | ||
| 1270 | |||
| 1413 | #if defined (macintosh) | 1271 | #if defined (macintosh) |
| 1414 | FONTSET_ASCII (Vdefault_fontset) | 1272 | default_ascii_font |
| 1415 | = Fcons (make_number (0), | 1273 | = build_string ("-apple-monaco-medium-r-*--*-120-*-*-*-*-mac-roman"); |
| 1416 | build_string ("-apple-monaco-medium-r-*--*-120-*-*-*-*-mac-roman")); | ||
| 1417 | #elif defined (WINDOWSNT) | 1274 | #elif defined (WINDOWSNT) |
| 1418 | FONTSET_ASCII (Vdefault_fontset) | 1275 | default_ascii_font |
| 1419 | = Fcons (make_number (0), | 1276 | = build_string ("-*-courier new-normal-r-*-*-*-100-*-*-*-*-iso8859-1"); |
| 1420 | build_string ("-*-courier new-normal-r-*-*-*-100-*-*-*-*-iso8859-1")); | ||
| 1421 | #else | 1277 | #else |
| 1422 | FONTSET_ASCII (Vdefault_fontset) | 1278 | default_ascii_font |
| 1423 | = Fcons (make_number (0), | 1279 | = build_string ("-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1"); |
| 1424 | build_string ("-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1")); | ||
| 1425 | #endif | 1280 | #endif |
| 1281 | FONTSET_ASCII (Vdefault_fontset) = default_ascii_font; | ||
| 1282 | } | ||
| 1426 | AREF (Vfontset_table, 0) = Vdefault_fontset; | 1283 | AREF (Vfontset_table, 0) = Vdefault_fontset; |
| 1427 | next_fontset_id = 1; | 1284 | next_fontset_id = 1; |
| 1428 | 1285 | ||