diff options
| author | Kenichi Handa | 2002-07-26 04:06:25 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2002-07-26 04:06:25 +0000 |
| commit | 1d5d720059a440409157199b4ce9ce9e9105df41 (patch) | |
| tree | bc84393ddd6f5f1f0940d61b1a64fd49db135b6e /src | |
| parent | 153b4d7b751e341512229cfd529751b197f4ab77 (diff) | |
| download | emacs-1d5d720059a440409157199b4ce9ce9e9105df41.tar.gz emacs-1d5d720059a440409157199b4ce9ce9e9105df41.zip | |
(Qprepend, Qappend): New variables.
(FONTSET_CHARSET_ALIST, FONTSET_FACE_ALIST): These macros deleted.
(FONTSET_NOFONT_FACE, FONTSET_REPERTORY): New macros.
(FONTSET_REF): Optimize if FONTSET is Vdefault_fontset.
(FONTSET_REF_AND_RANGE, FONTSET_ADD): New macros.
(fontset_ref_and_range, fontset_add, reorder_font_vector)
(load_font_get_repertory): New functions.
(fontset_set): This function deleted.
(fontset_face): New arg FACE. Return face ID, not face.
Completely re-written to handle new fontset structure. Caller
changed.
(free_face_fontset): Use ASET istead of AREF (X) = Y.
(face_for_char): Don't call lookup_face.
(make_fontset_for_ascii_face): New arg FACE.
(fs_load_font): New arg CHARSET_ID. Don't check
Vfont_encoding_alist here.
(find_font_encoding): New function.
(list_fontsets): Use STRINGP, not ! NILP.
(accumulate_script_ranges): New function.
(Fset_fontset_font, Fnew_fontset, Ffontset_info): Completely
re-written to handle new fontset structure.
(Ffontset_font): Return a copy of element.
(syms_of_fontset): Define symbols Qprepend and Qappend. Fix
docstring of font-encoding-alist.
Diffstat (limited to 'src')
| -rw-r--r-- | src/fontset.c | 1155 |
1 files changed, 745 insertions, 410 deletions
diff --git a/src/fontset.c b/src/fontset.c index 05db03e100c..fb6600da254 100644 --- a/src/fontset.c +++ b/src/fontset.c | |||
| @@ -54,61 +54,105 @@ EXFUN (Fclear_face_cache, 1); | |||
| 54 | /* FONTSET | 54 | /* FONTSET |
| 55 | 55 | ||
| 56 | A fontset is a collection of font related information to give | 56 | A fontset is a collection of font related information to give |
| 57 | similar appearance (style, etc) of characters. There are two kinds | 57 | similar appearance (style, etc) of characters. A fontset has two |
| 58 | of fontsets; base and realized. A base fontset is created by | 58 | roles. One is to use for the frame parameter `font' as if it is an |
| 59 | `new-fontset' from Emacs Lisp explicitly. A realized fontset is | 59 | ASCII font. In that case, Emacs uses the font specified for |
| 60 | created implicitly when a face is realized for ASCII characters. A | 60 | `ascii' script for the frame's default font. |
| 61 | face is also realized for non-ASCII characters based on an ASCII | 61 | |
| 62 | face. All of non-ASCII faces based on the same ASCII face share | 62 | Another role, the more important one, is to provide information |
| 63 | the same realized fontset. | 63 | about which font to use for each non-ASCII character. |
| 64 | |||
| 65 | There are two kinds of fontsets; base and realized. A base fontset | ||
| 66 | is created by `new-fontset' from Emacs Lisp explicitly. A realized | ||
| 67 | fontset is created implicitly when a face is realized for ASCII | ||
| 68 | characters. A face is also realized for non-ASCII characters based | ||
| 69 | on an ASCII face. All of non-ASCII faces based on the same ASCII | ||
| 70 | face share the same realized fontset. | ||
| 64 | 71 | ||
| 65 | A fontset object is implemented by a char-table whose default value | 72 | A fontset object is implemented by a char-table whose default value |
| 66 | and parent are always nil. | 73 | and parent are always nil. |
| 67 | 74 | ||
| 68 | An element of a base fontset is a font specification of the form: | 75 | An element of a base fontset is a vector of FONT-DEFs which itself |
| 69 | [ FAMILY WEIGHT SLANT SWIDTH REGISTRY ] (vector of size 5) | 76 | is a vector [ FONT-SPEC ENCODING REPERTORY ]. |
| 77 | |||
| 78 | FONT-SPEC is: | ||
| 79 | [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ] | ||
| 70 | or | 80 | or |
| 71 | FONT-NAME (strig) | 81 | FONT-NAME |
| 82 | where FAMILY, WEIGHT, SLANT, SWIDTH, ADSTYLE, REGISTRY, and | ||
| 83 | FONT-NAME are strings. | ||
| 84 | |||
| 85 | ENCODING is a charset ID or a char-table that can convert | ||
| 86 | characters to glyph codes of the corresponding font. | ||
| 87 | |||
| 88 | REPERTORY is a charset ID or nil. If REPERTORY is a charset ID, | ||
| 89 | the repertory of the charset exactly matches with that of the font. | ||
| 90 | If REPERTORY is nil, we consult with the font itself to get the | ||
| 91 | repertory. | ||
| 92 | |||
| 93 | ENCODING and REPERTORY are extracted from the variable | ||
| 94 | Vfont_encoding_alist by using a font name generated form FONT-SPEC | ||
| 95 | (if it is a vector) or FONT-NAME as a key. | ||
| 96 | |||
| 97 | |||
| 98 | An element of a realized fontset is nil or t, or has this form: | ||
| 99 | |||
| 100 | ( CHARSET-PRIORITY-LIST-TICK . FONT-VECTOR ) | ||
| 101 | |||
| 102 | FONT-VECTOR is a vector whose elements have this form: | ||
| 103 | |||
| 104 | [ FACE-ID FONT-INDEX FONT-DEF ] | ||
| 72 | 105 | ||
| 73 | FAMILY and REGISTRY are strings. | 106 | FONT-VECTOR is automatically reordered by the current charset |
| 107 | priority list. | ||
| 74 | 108 | ||
| 75 | WEIGHT, SLANT, and SWIDTH must be symbols that set-face-attribute | 109 | The value nil means that we have not yet generated FONT-VECTOR from |
| 76 | accepts as attribute values for :weight, :slant, :swidth | 110 | the base of the fontset. |
| 77 | respectively. | ||
| 78 | 111 | ||
| 112 | The value t means that no font is available for the corresponding | ||
| 113 | range of characters. | ||
| 79 | 114 | ||
| 80 | A fontset has 7 extra slots. | ||
| 81 | 115 | ||
| 82 | The 1st slot is an ID number of the fontset. | 116 | A fontset has 5 extra slots. |
| 83 | 117 | ||
| 84 | The 2nd slot is a name of the fontset in a base fontset, and nil in | 118 | The 1st slot: the ID number of the fontset |
| 85 | a realized fontset. | ||
| 86 | 119 | ||
| 87 | The 3rd slot is nil in a base fontset, and a base fontset in a | 120 | The 2nd slot: |
| 88 | realized fontset. | 121 | base: the name of the fontset |
| 122 | realized: nil | ||
| 89 | 123 | ||
| 90 | The 4th slot is a frame that the fontset belongs to. This is nil | 124 | The 3rd slot: |
| 91 | in a base fontset. | 125 | base: nli |
| 126 | realized: the base fontset | ||
| 92 | 127 | ||
| 93 | The 5th slot is a cons of 0 and fontname for ASCII characters in a | 128 | The 4th slot: |
| 94 | base fontset, and nil in a realized face. | 129 | base: nil |
| 130 | realized: the frame that the fontset belongs to | ||
| 95 | 131 | ||
| 96 | The 6th slot is an alist of a charset vs. the corresponding font | 132 | The 5th slot: |
| 97 | specification. | 133 | base: the font name for ASCII characters |
| 134 | realized: nil | ||
| 98 | 135 | ||
| 99 | The 7th slot is an alist of a font specification vs. the | 136 | The 6th slot: |
| 100 | corresponding face ID. In a base fontset, the face IDs are all | 137 | base: nil |
| 101 | nil. | 138 | realized: the ID number of a face to use for characters that |
| 139 | has no font in a realized fontset. | ||
| 102 | 140 | ||
| 103 | All fontsets are recorded in Vfontset_table. | 141 | The 7th slot: |
| 142 | base: nil | ||
| 143 | realized: Alist of font index vs the corresponding repertory | ||
| 144 | char-table. | ||
| 145 | |||
| 146 | |||
| 147 | All fontsets are recorded in the vector Vfontset_table. | ||
| 104 | 148 | ||
| 105 | 149 | ||
| 106 | DEFAULT FONTSET | 150 | DEFAULT FONTSET |
| 107 | 151 | ||
| 108 | There's a special fontset named `default fontset' which defines the | 152 | There's a special base fontset named `default fontset' which |
| 109 | default font specifications. When a base fontset doesn't specify a | 153 | defines the default font specifications. When a base fontset |
| 110 | font for a specific character, the corresponding value in the | 154 | doesn't specify a font for a specific character, the corresponding |
| 111 | default fontset is used. The format is the same as a base fontset. | 155 | value in the default fontset is used. |
| 112 | 156 | ||
| 113 | The parent of a realized fontset created for such a face that has | 157 | The parent of a realized fontset created for such a face that has |
| 114 | no fontset is the default fontset. | 158 | no fontset is the default fontset. |
| @@ -118,7 +162,7 @@ EXFUN (Fclear_face_cache, 1); | |||
| 118 | The other codes handle fontsets only by their ID numbers. They | 162 | The other codes handle fontsets only by their ID numbers. They |
| 119 | usually use the variable name `fontset' for IDs. But, in this | 163 | usually use the variable name `fontset' for IDs. But, in this |
| 120 | file, we always use varialbe name `id' for IDs, and name `fontset' | 164 | file, we always use varialbe name `id' for IDs, and name `fontset' |
| 121 | for the actual fontset objects (i.e. char-table objects). | 165 | for an actual fontset object, i.e., char-table. |
| 122 | 166 | ||
| 123 | */ | 167 | */ |
| 124 | 168 | ||
| @@ -126,6 +170,7 @@ EXFUN (Fclear_face_cache, 1); | |||
| 126 | 170 | ||
| 127 | extern Lisp_Object Qfont; | 171 | extern Lisp_Object Qfont; |
| 128 | Lisp_Object Qfontset; | 172 | Lisp_Object Qfontset; |
| 173 | static Lisp_Object Qprepend, Qappend; | ||
| 129 | 174 | ||
| 130 | /* Vector containing all fontsets. */ | 175 | /* Vector containing all fontsets. */ |
| 131 | static Lisp_Object Vfontset_table; | 176 | static Lisp_Object Vfontset_table; |
| @@ -176,6 +221,9 @@ void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg, | |||
| 176 | This function set the member `encoder' of the structure. */ | 221 | This function set the member `encoder' of the structure. */ |
| 177 | void (*find_ccl_program_func) P_ ((struct font_info *)); | 222 | void (*find_ccl_program_func) P_ ((struct font_info *)); |
| 178 | 223 | ||
| 224 | Lisp_Object (*get_font_repertory_func) P_ ((struct frame *, | ||
| 225 | struct font_info *)); | ||
| 226 | |||
| 179 | /* Check if any window system is used now. */ | 227 | /* Check if any window system is used now. */ |
| 180 | void (*check_window_system_func) P_ ((void)); | 228 | void (*check_window_system_func) P_ ((void)); |
| 181 | 229 | ||
| @@ -184,6 +232,9 @@ void (*check_window_system_func) P_ ((void)); | |||
| 184 | static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); | 232 | static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object)); |
| 185 | static int fontset_id_valid_p P_ ((int)); | 233 | static int fontset_id_valid_p P_ ((int)); |
| 186 | static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object)); | 234 | static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object)); |
| 235 | static void accumulate_script_ranges P_ ((Lisp_Object, Lisp_Object, | ||
| 236 | Lisp_Object)); | ||
| 237 | |||
| 187 | 238 | ||
| 188 | 239 | ||
| 189 | /********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/ | 240 | /********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/ |
| @@ -203,13 +254,19 @@ static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object)); | |||
| 203 | /* Macros to access special values of (realized) FONTSET. */ | 254 | /* Macros to access special values of (realized) FONTSET. */ |
| 204 | #define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[2] | 255 | #define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[2] |
| 205 | #define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[3] | 256 | #define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[3] |
| 206 | #define FONTSET_CHARSET_ALIST(fontset) XCHAR_TABLE (fontset)->extras[5] | 257 | #define FONTSET_NOFONT_FACE(fontset) XCHAR_TABLE (fontset)->extras[5] |
| 207 | #define FONTSET_FACE_ALIST(fontset) XCHAR_TABLE (fontset)->extras[6] | 258 | #define FONTSET_REPERTORY(fontset) XCHAR_TABLE (fontset)->extras[6] |
| 208 | 259 | ||
| 209 | 260 | ||
| 210 | /* Return the element of FONTSET (char-table) at index C (character). */ | 261 | /* Return the element of FONTSET for the character C. If FONTSET is a |
| 262 | base fontset other then the default fontset and FONTSET doesn't | ||
| 263 | contain information for C, return the information in the default | ||
| 264 | fontset. */ | ||
| 211 | 265 | ||
| 212 | #define FONTSET_REF(fontset, c, etl) ((elt) = fontset_ref ((fontset), (c))) | 266 | #define FONTSET_REF(fontset, c) \ |
| 267 | (EQ (fontset, Vdefault_fontset) \ | ||
| 268 | ? CHAR_TABLE_REF (fontset, c) \ | ||
| 269 | : fontset_ref ((fontset), (c))) | ||
| 213 | 270 | ||
| 214 | static Lisp_Object | 271 | static Lisp_Object |
| 215 | fontset_ref (fontset, c) | 272 | fontset_ref (fontset, c) |
| @@ -218,105 +275,336 @@ fontset_ref (fontset, c) | |||
| 218 | { | 275 | { |
| 219 | Lisp_Object elt; | 276 | Lisp_Object elt; |
| 220 | 277 | ||
| 221 | while (1) | 278 | elt = CHAR_TABLE_REF (fontset, c); |
| 279 | if (NILP (elt) && ! EQ (fontset, Vdefault_fontset) | ||
| 280 | /* Don't check Vdefault_fontset for a realized fontset. */ | ||
| 281 | && NILP (FONTSET_BASE (fontset))) | ||
| 282 | elt = CHAR_TABLE_REF (Vdefault_fontset, c); | ||
| 283 | return elt; | ||
| 284 | } | ||
| 285 | |||
| 286 | |||
| 287 | /* Return the element of FONTSET for the character C, set FROM and TO | ||
| 288 | to the range of characters around C that have the same value as C. | ||
| 289 | If FONTSET is a base fontset other then the default fontset and | ||
| 290 | FONTSET doesn't contain information for C, return the information | ||
| 291 | in the default fontset. */ | ||
| 292 | |||
| 293 | #define FONTSET_REF_AND_RANGE(fontset, c, form, to) \ | ||
| 294 | (EQ (fontset, Vdefault_fontset) \ | ||
| 295 | ? char_table_ref_and_range (fontset, c, &from, &to) \ | ||
| 296 | : fontset_ref_and_range (fontset, c, &from, &to)) | ||
| 297 | |||
| 298 | static Lisp_Object | ||
| 299 | fontset_ref_and_range (fontset, c, from, to) | ||
| 300 | Lisp_Object fontset; | ||
| 301 | int c; | ||
| 302 | int *from, *to; | ||
| 303 | { | ||
| 304 | Lisp_Object elt; | ||
| 305 | |||
| 306 | elt = char_table_ref_and_range (fontset, c, from, to); | ||
| 307 | if (NILP (elt) && ! EQ (fontset, Vdefault_fontset) | ||
| 308 | /* Don't check Vdefault_fontset for a realized fontset. */ | ||
| 309 | && NILP (FONTSET_BASE (fontset))) | ||
| 222 | { | 310 | { |
| 223 | elt = CHAR_TABLE_REF (fontset, c); | 311 | int from1, to1; |
| 224 | if (NILP (elt) && ASCII_CHAR_P (c)) | ||
| 225 | elt = FONTSET_ASCII (fontset); | ||
| 226 | if (NILP (elt)) | ||
| 227 | { | ||
| 228 | Lisp_Object tail; | ||
| 229 | struct charset *charset; | ||
| 230 | 312 | ||
| 231 | for (tail = FONTSET_CHARSET_ALIST (fontset); | 313 | elt = char_table_ref_and_range (Vdefault_fontset, c, &from1, &to1); |
| 232 | CONSP (tail); tail = XCDR (tail)) | 314 | if (*from < from1) |
| 233 | { | 315 | *from = from1; |
| 234 | charset = CHARSET_FROM_ID (XINT (XCAR (XCAR (tail)))); | 316 | if (*to > to1) |
| 235 | if (ENCODE_CHAR (charset, c) != CHARSET_INVALID_CODE (charset)) | 317 | *to = to1; |
| 236 | { | ||
| 237 | elt = XCDR (XCAR (tail)); | ||
| 238 | break; | ||
| 239 | } | ||
| 240 | } | ||
| 241 | } | ||
| 242 | if (! NILP (elt) || EQ (fontset, Vdefault_fontset)) | ||
| 243 | break; | ||
| 244 | fontset = Vdefault_fontset; | ||
| 245 | } | 318 | } |
| 246 | return elt; | 319 | return elt; |
| 247 | } | 320 | } |
| 248 | 321 | ||
| 249 | 322 | ||
| 250 | /* Set the element of FONTSET at index IDX to the value ELT. IDX may | 323 | /* Set elements of FONTSET for characters in RANGE to the value ELT. |
| 251 | be a character or a charset. */ | 324 | RANGE is a cons (FROM . TO), where FROM and TO are character codes |
| 325 | specifying a range. */ | ||
| 326 | |||
| 327 | #define FONTSET_SET(fontset, range, elt) \ | ||
| 328 | Fset_char_table_range ((fontset), (range), (elt)) | ||
| 329 | |||
| 252 | 330 | ||
| 253 | #define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt) | 331 | /* Modify the elements of FONTSET for characters in RANGE by replacing |
| 332 | with ELT or adding ETL. RANGE is a cons (FROM . TO), where FROM | ||
| 333 | and TO are character codes specifying a range. If ADD is nil, | ||
| 334 | replace with ELT, if ADD is `prepend', prepend ELT, otherwise, | ||
| 335 | append ELT. */ | ||
| 336 | |||
| 337 | #define FONTSET_ADD(fontset, range, elt, add) \ | ||
| 338 | (NILP (add) \ | ||
| 339 | ? Fset_char_table_range ((fontset), (range), \ | ||
| 340 | Fmake_vector (make_number (1), (elt))) \ | ||
| 341 | : fontset_add ((fontset), (range), (elt), (add))) | ||
| 254 | 342 | ||
| 255 | static void | 343 | static void |
| 256 | fontset_set (fontset, idx, elt) | 344 | fontset_add (fontset, range, elt, add) |
| 257 | Lisp_Object fontset, idx, elt; | ||
| 258 | { | 345 | { |
| 259 | if (SYMBOLP (idx)) | 346 | int from, to, from1, to1; |
| 347 | Lisp_Object elt1; | ||
| 348 | |||
| 349 | from = XINT (XCAR (range)); | ||
| 350 | to = XINT (XCDR (range)); | ||
| 351 | do { | ||
| 352 | elt1 = char_table_ref_and_range (fontset, from, &from1, &to1); | ||
| 353 | if (NILP (elt1)) | ||
| 354 | elt1 = Fmake_vector (make_number (1), elt); | ||
| 355 | else | ||
| 356 | { | ||
| 357 | int i, i0 = 1, i1 = ASIZE (elt1) + 1; | ||
| 358 | Lisp_Object new; | ||
| 359 | |||
| 360 | new = Fmake_vector (i1, elt); | ||
| 361 | if (EQ (add, Qappend)) | ||
| 362 | i0--, i1--; | ||
| 363 | for (i = 0; i0 < i1; i++, i0++) | ||
| 364 | ASET (new, i0, AREF (elt1, i)); | ||
| 365 | elt1 = new; | ||
| 366 | } | ||
| 367 | char_table_set_range (fontset, from, to1, elt1); | ||
| 368 | from = to1 + 1; | ||
| 369 | } while (from < to); | ||
| 370 | } | ||
| 371 | |||
| 372 | |||
| 373 | /* Update FONTSET_ELEMENT which has this form: | ||
| 374 | ( CHARSET-PRIORITY-LIST-TICK . FONT-VECTOR). | ||
| 375 | Reorder FONT-VECTOR according to the current order of charset | ||
| 376 | (Vcharset_ordered_list), and update CHARSET-PRIORITY-LIST-TICK to | ||
| 377 | the latest value. */ | ||
| 378 | |||
| 379 | static void | ||
| 380 | reorder_font_vector (fontset_element) | ||
| 381 | Lisp_Object fontset_element; | ||
| 382 | { | ||
| 383 | Lisp_Object vec, list, *new_vec; | ||
| 384 | int size; | ||
| 385 | int *charset_id_table; | ||
| 386 | int i, idx; | ||
| 387 | |||
| 388 | XSETCAR (fontset_element, make_number (charset_ordered_list_tick)); | ||
| 389 | vec = XCDR (fontset_element); | ||
| 390 | size = ASIZE (vec); | ||
| 391 | if (size < 2) | ||
| 392 | /* No need of reordering VEC. */ | ||
| 393 | return; | ||
| 394 | charset_id_table = (int *) alloca (sizeof (int) * size); | ||
| 395 | new_vec = (Lisp_Object *) alloca (sizeof (Lisp_Object) * size); | ||
| 396 | /* At first, extract ENCODING (a chaset ID) from VEC. VEC has this | ||
| 397 | form: | ||
| 398 | [[FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ]] ...] */ | ||
| 399 | for (i = 0; i < size; i++) | ||
| 400 | charset_id_table[i] = XINT (AREF (AREF (AREF (vec, i), 2), 1)); | ||
| 401 | |||
| 402 | /* Then, store the elements of VEC in NEW_VEC in the correct | ||
| 403 | order. */ | ||
| 404 | idx = 0; | ||
| 405 | for (list = Vcharset_ordered_list; CONSP (list); list = XCDR (list)) | ||
| 260 | { | 406 | { |
| 261 | Lisp_Object id, slot, tail; | 407 | for (i = 0; i < size; i++) |
| 262 | 408 | if (charset_id_table[i] == XINT (XCAR (list))) | |
| 263 | id = CHARSET_SYMBOL_ID (idx); | 409 | new_vec[idx++] = AREF (vec, i); |
| 264 | if (XFASTINT (id) == charset_ascii) | 410 | if (idx == size) |
| 265 | Fset_char_table_range (fontset, | 411 | break; |
| 266 | Fcons (make_number (0), make_number (127)), | ||
| 267 | elt); | ||
| 268 | else | ||
| 269 | { | ||
| 270 | slot = Fassq (id, FONTSET_CHARSET_ALIST (fontset)); | ||
| 271 | if (CONSP (slot)) | ||
| 272 | XCDR (slot) = elt; | ||
| 273 | else if (CONSP (FONTSET_CHARSET_ALIST (fontset))) | ||
| 274 | { | ||
| 275 | for (tail = FONTSET_CHARSET_ALIST (fontset); | ||
| 276 | CONSP (XCDR (tail)); tail = XCDR (tail)); | ||
| 277 | XCDR (tail) = Fcons (Fcons (id, elt), Qnil); | ||
| 278 | } | ||
| 279 | else | ||
| 280 | FONTSET_CHARSET_ALIST (fontset) = Fcons (Fcons (id, elt), Qnil); | ||
| 281 | } | ||
| 282 | } | 412 | } |
| 283 | else | ||
| 284 | { | ||
| 285 | int from = XINT (XCAR (idx)); | ||
| 286 | int to = XINT (XCDR (idx)); | ||
| 287 | 413 | ||
| 288 | if (from == to) | 414 | /* At last, update VEC. */ |
| 289 | CHAR_TABLE_SET (fontset, from, elt); | 415 | for (i = 0; i < size; i++) |
| 290 | else | 416 | ASET (vec, i, new_vec[i]); |
| 291 | Fset_char_table_range (fontset, idx, elt); | 417 | } |
| 418 | |||
| 419 | |||
| 420 | /* Load a font matching the font related attributes in FACE->lface and | ||
| 421 | font pattern in FONT_DEF of FONTSET, and return an index of the | ||
| 422 | font. FONT_DEF has this form: | ||
| 423 | [ FONT-SPEC ENCODING REPERTORY ] | ||
| 424 | If REPERTORY is nil, generate a char-table representing the font | ||
| 425 | repertory by looking into the font itself. */ | ||
| 426 | |||
| 427 | static int | ||
| 428 | load_font_get_repertory (f, face, font_def, fontset) | ||
| 429 | FRAME_PTR f; | ||
| 430 | struct face *face; | ||
| 431 | Lisp_Object font_def; | ||
| 432 | Lisp_Object fontset; | ||
| 433 | { | ||
| 434 | char *font_name; | ||
| 435 | struct font_info *font_info; | ||
| 436 | |||
| 437 | font_name = choose_face_font (f, face->lface, AREF (font_def, 0)); | ||
| 438 | if (! (font_info = fs_load_font (f, font_name, XINT (AREF (font_def, 1))))) | ||
| 439 | return -1; | ||
| 440 | |||
| 441 | if (NILP (AREF (font_def, 2)) | ||
| 442 | && NILP (Fassq (make_number (font_info->font_idx), | ||
| 443 | FONTSET_REPERTORY (fontset)))) | ||
| 444 | { | ||
| 445 | /* We must look into the font to get the correct repertory as a | ||
| 446 | char-table. */ | ||
| 447 | Lisp_Object repertory; | ||
| 448 | |||
| 449 | repertory = (*get_font_repertory_func) (f, font_info); | ||
| 450 | FONTSET_REPERTORY (fontset) | ||
| 451 | = Fcons (Fcons (make_number (font_info->font_idx), repertory), | ||
| 452 | FONTSET_REPERTORY (fontset)); | ||
| 292 | } | 453 | } |
| 454 | |||
| 455 | return font_info->font_idx; | ||
| 293 | } | 456 | } |
| 294 | 457 | ||
| 295 | 458 | ||
| 296 | /* Return a face registerd in the realized fontset FONTSET for the | 459 | /* Return a face ID registerd in the realized fontset FONTSET for the |
| 297 | character C. Return -1 if a face ID is not yet set. */ | 460 | character C. If FACE is NULL, return -1 if a face is not yet |
| 461 | set. Otherwise, realize a proper face from FACE and return it. */ | ||
| 298 | 462 | ||
| 299 | static struct face * | 463 | static int |
| 300 | fontset_face (fontset, c) | 464 | fontset_face (fontset, c, face) |
| 301 | Lisp_Object fontset; | 465 | Lisp_Object fontset; |
| 302 | int c; | 466 | int c; |
| 467 | struct face *face; | ||
| 303 | { | 468 | { |
| 304 | Lisp_Object base, elt; | 469 | Lisp_Object elt, vec; |
| 305 | int id; | 470 | int i, from, to; |
| 306 | struct face *face; | 471 | int font_idx; |
| 472 | FRAME_PTR f = XFRAME (FONTSET_FRAME (fontset)); | ||
| 307 | 473 | ||
| 308 | base = FONTSET_BASE (fontset); | 474 | elt = CHAR_TABLE_REF (fontset, c); |
| 309 | FONTSET_REF (base, c, elt); | ||
| 310 | 475 | ||
| 476 | if (EQ (elt, Qt)) | ||
| 477 | goto font_not_found; | ||
| 311 | if (NILP (elt)) | 478 | if (NILP (elt)) |
| 312 | return NULL; | 479 | { |
| 480 | /* We have not yet decided a face for C. */ | ||
| 481 | Lisp_Object base_fontset, range; | ||
| 482 | |||
| 483 | if (! face) | ||
| 484 | return -1; | ||
| 485 | base_fontset = FONTSET_BASE (fontset); | ||
| 486 | elt = FONTSET_REF_AND_RANGE (base_fontset, c, from, to); | ||
| 487 | range = Fcons (make_number (from), make_number (to)); | ||
| 488 | if (NILP (elt)) | ||
| 489 | { | ||
| 490 | /* Record that we have no font for characters of this | ||
| 491 | range. */ | ||
| 492 | FONTSET_SET (fontset, range, Qt); | ||
| 493 | goto font_not_found; | ||
| 494 | } | ||
| 495 | elt = Fcopy_sequence (elt); | ||
| 496 | /* Now ELT is a vector of FONT-DEFs. We at first change it to | ||
| 497 | FONT-VECTOR, a vector of [ nil nil FONT-DEF ]. */ | ||
| 498 | for (i = 0; i < ASIZE (elt); i++) | ||
| 499 | { | ||
| 500 | Lisp_Object tmp; | ||
| 313 | 501 | ||
| 314 | elt = Fassoc (elt, FONTSET_FACE_ALIST (fontset)); | 502 | tmp = Fmake_vector (make_number (3), Qnil); |
| 315 | if (! CONSP (elt)) | 503 | ASET (tmp, 2, AREF (elt, i)); |
| 316 | return NULL; | 504 | ASET (elt, i, tmp); |
| 317 | id = XINT (XCDR (elt)); | 505 | } |
| 318 | face = FACE_FROM_ID (XFRAME (FONTSET_FRAME (fontset)), id); | 506 | /* Then store (-1 . FONT-VECTOR) in the fontset. -1 is to force |
| 319 | return face; | 507 | reordering of FONT-VECTOR. */ |
| 508 | elt = Fcons (make_number (-1), elt); | ||
| 509 | FONTSET_SET (fontset, range, elt); | ||
| 510 | } | ||
| 511 | |||
| 512 | if (XINT (XCAR (elt)) != charset_ordered_list_tick) | ||
| 513 | /* The priority of charsets is changed after we selected a face | ||
| 514 | for C last time. */ | ||
| 515 | reorder_font_vector (elt); | ||
| 516 | |||
| 517 | vec = XCDR (elt); | ||
| 518 | /* Find the first available font in the font vector VEC. */ | ||
| 519 | for (i = 0; i < ASIZE (vec); i++) | ||
| 520 | { | ||
| 521 | Lisp_Object font_def; | ||
| 522 | |||
| 523 | elt = AREF (vec, i); | ||
| 524 | /* ELT == [ FACE-ID FONT-INDEX [ FONT-SPEC ENCODING REPERTORY ] ] */ | ||
| 525 | font_def = AREF (elt, 2); | ||
| 526 | if (INTEGERP (AREF (elt, 1)) && XINT (AREF (elt, 1)) < 0) | ||
| 527 | /* We couldn't open this font last time. */ | ||
| 528 | continue; | ||
| 529 | |||
| 530 | if (!face && (NILP (AREF (elt, 1)) || NILP (AREF (elt, 0)))) | ||
| 531 | /* We have not yet opened the font, or we have not yet made a | ||
| 532 | realized face for the font. */ | ||
| 533 | return -1; | ||
| 534 | |||
| 535 | if (INTEGERP (AREF (font_def, 2))) | ||
| 536 | { | ||
| 537 | /* The repertory is specified by charset ID. */ | ||
| 538 | struct charset *charset | ||
| 539 | = CHARSET_FROM_ID (XINT (AREF (font_def, 2))); | ||
| 540 | |||
| 541 | if (! CHAR_CHARSET_P (c, charset)) | ||
| 542 | /* This fond can't display C. */ | ||
| 543 | continue; | ||
| 544 | } | ||
| 545 | else | ||
| 546 | { | ||
| 547 | Lisp_Object slot; | ||
| 548 | |||
| 549 | if (! INTEGERP (AREF (elt, 1))) | ||
| 550 | { | ||
| 551 | /* We have not yet opened a font matching this spec. | ||
| 552 | Open the best matching font now and register the | ||
| 553 | repertory. */ | ||
| 554 | font_idx = load_font_get_repertory (f, face, font_def, fontset); | ||
| 555 | ASET (elt, 1, make_number (font_idx)); | ||
| 556 | if (font_idx < 0) | ||
| 557 | /* This means that we couldn't find a font matching | ||
| 558 | FONT_DEF. */ | ||
| 559 | continue; | ||
| 560 | } | ||
| 561 | |||
| 562 | slot = Fassq (AREF (elt, 1), FONTSET_REPERTORY (fontset)); | ||
| 563 | if (! CONSP (slot)) | ||
| 564 | abort (); | ||
| 565 | if (NILP (CHAR_TABLE_REF (XCDR (slot), c))) | ||
| 566 | /* This fond can't display C. */ | ||
| 567 | continue; | ||
| 568 | } | ||
| 569 | |||
| 570 | /* Now we have decided to use this font spec to display C. */ | ||
| 571 | if (INTEGERP (AREF (elt, 1))) | ||
| 572 | font_idx = XINT (AREF (elt, 1)); | ||
| 573 | else | ||
| 574 | { | ||
| 575 | /* But not yet opened the best matching font. */ | ||
| 576 | font_idx = load_font_get_repertory (f, face, font_def, fontset); | ||
| 577 | ASET (elt, 1, make_number (font_idx)); | ||
| 578 | if (font_idx < 0) | ||
| 579 | continue; | ||
| 580 | } | ||
| 581 | |||
| 582 | /* Now we have the opened font. */ | ||
| 583 | if (NILP (AREF (elt, 0))) | ||
| 584 | { | ||
| 585 | /* But not yet made a realized face that uses this font. */ | ||
| 586 | int face_id = lookup_non_ascii_face (f, font_idx, face); | ||
| 587 | |||
| 588 | ASET (elt, 0, make_number (face_id)); | ||
| 589 | } | ||
| 590 | |||
| 591 | /* Ok, this face can display C. */ | ||
| 592 | return XINT (AREF (elt, 0)); | ||
| 593 | } | ||
| 594 | |||
| 595 | font_not_found: | ||
| 596 | /* We have tried all the fonts for C, but none of them can be opened | ||
| 597 | nor can display C. */ | ||
| 598 | if (NILP (FONTSET_NOFONT_FACE (fontset))) | ||
| 599 | { | ||
| 600 | int face_id; | ||
| 601 | |||
| 602 | if (! face) | ||
| 603 | return -1; | ||
| 604 | face_id = lookup_non_ascii_face (f, -1, face); | ||
| 605 | FONTSET_NOFONT_FACE (fontset) = make_number (face_id); | ||
| 606 | } | ||
| 607 | return XINT (FONTSET_NOFONT_FACE (fontset)); | ||
| 320 | } | 608 | } |
| 321 | 609 | ||
| 322 | 610 | ||
| @@ -341,6 +629,7 @@ make_fontset (frame, name, base) | |||
| 341 | 629 | ||
| 342 | if (id + 1 == size) | 630 | if (id + 1 == size) |
| 343 | { | 631 | { |
| 632 | /* We must grow Vfontset_table. */ | ||
| 344 | Lisp_Object tem; | 633 | Lisp_Object tem; |
| 345 | int i; | 634 | int i; |
| 346 | 635 | ||
| @@ -371,9 +660,9 @@ make_fontset (frame, name, base) | |||
| 371 | 660 | ||
| 372 | 661 | ||
| 373 | 662 | ||
| 374 | /********** INTERFACES TO xfaces.c and dispextern.h **********/ | 663 | /********** INTERFACES TO xfaces.c, xfns.c, and dispextern.h **********/ |
| 375 | 664 | ||
| 376 | /* Return name of the fontset with ID. */ | 665 | /* Return the name of the fontset who has ID. */ |
| 377 | 666 | ||
| 378 | Lisp_Object | 667 | Lisp_Object |
| 379 | fontset_name (id) | 668 | fontset_name (id) |
| @@ -386,16 +675,19 @@ fontset_name (id) | |||
| 386 | } | 675 | } |
| 387 | 676 | ||
| 388 | 677 | ||
| 389 | /* Return ASCII font name of the fontset with ID. */ | 678 | /* Return the ASCII font name of the fontset who has ID. */ |
| 390 | 679 | ||
| 391 | Lisp_Object | 680 | Lisp_Object |
| 392 | fontset_ascii (id) | 681 | fontset_ascii (id) |
| 393 | int id; | 682 | int id; |
| 394 | { | 683 | { |
| 395 | Lisp_Object fontset; | 684 | Lisp_Object fontset, elt; |
| 396 | 685 | ||
| 397 | fontset= FONTSET_FROM_ID (id); | 686 | fontset= FONTSET_FROM_ID (id); |
| 398 | return FONTSET_ASCII (fontset); | 687 | elt = FONTSET_ASCII (fontset); |
| 688 | /* It is assured that ELT is always a string (i.e. fontname | ||
| 689 | pattern). */ | ||
| 690 | return elt; | ||
| 399 | } | 691 | } |
| 400 | 692 | ||
| 401 | 693 | ||
| @@ -407,7 +699,7 @@ free_face_fontset (f, face) | |||
| 407 | FRAME_PTR f; | 699 | FRAME_PTR f; |
| 408 | struct face *face; | 700 | struct face *face; |
| 409 | { | 701 | { |
| 410 | AREF (Vfontset_table, face->fontset) = Qnil; | 702 | ASET (Vfontset_table, face->fontset, Qnil); |
| 411 | if (face->fontset < next_fontset_id) | 703 | if (face->fontset < next_fontset_id) |
| 412 | next_fontset_id = face->fontset; | 704 | next_fontset_id = face->fontset; |
| 413 | } | 705 | } |
| @@ -425,14 +717,13 @@ face_suitable_for_char_p (face, c) | |||
| 425 | Lisp_Object fontset; | 717 | Lisp_Object fontset; |
| 426 | 718 | ||
| 427 | fontset = FONTSET_FROM_ID (face->fontset); | 719 | fontset = FONTSET_FROM_ID (face->fontset); |
| 428 | return (face == fontset_face (fontset, c)); | 720 | return (face->id == fontset_face (fontset, c, NULL)); |
| 429 | } | 721 | } |
| 430 | 722 | ||
| 431 | 723 | ||
| 432 | /* Return ID of face suitable for displaying character C on frame F. | 724 | /* Return ID of face suitable for displaying character C on frame F. |
| 433 | The selection of face is done based on the fontset of FACE. FACE | 725 | FACE must be reazlied for ASCII characters in advance. Called from |
| 434 | must be reazlied for ASCII characters in advance. Called from the | 726 | the macro FACE_FOR_CHAR. */ |
| 435 | macro FACE_FOR_CHAR when C is not an ASCII character. */ | ||
| 436 | 727 | ||
| 437 | int | 728 | int |
| 438 | face_for_char (f, face, c) | 729 | face_for_char (f, face, c) |
| @@ -441,19 +732,17 @@ face_for_char (f, face, c) | |||
| 441 | int c; | 732 | int c; |
| 442 | { | 733 | { |
| 443 | Lisp_Object fontset; | 734 | Lisp_Object fontset; |
| 444 | struct face *new_face; | 735 | Lisp_Object elt, vec; |
| 736 | int font_idx; | ||
| 737 | int i; | ||
| 738 | |||
| 739 | if (ASCII_CHAR_P (c)) | ||
| 740 | return face->ascii_face->id; | ||
| 445 | 741 | ||
| 446 | xassert (fontset_id_valid_p (face->fontset)); | 742 | xassert (fontset_id_valid_p (face->fontset)); |
| 447 | fontset = FONTSET_FROM_ID (face->fontset); | 743 | fontset = FONTSET_FROM_ID (face->fontset); |
| 448 | xassert (!BASE_FONTSET_P (fontset)); | 744 | xassert (!BASE_FONTSET_P (fontset)); |
| 449 | 745 | return fontset_face (fontset, c, face); | |
| 450 | new_face = fontset_face (fontset, c); | ||
| 451 | if (new_face) | ||
| 452 | return new_face->id; | ||
| 453 | |||
| 454 | /* No face is recorded for C in the fontset of FACE. Make a new | ||
| 455 | realized face for C that has the same fontset. */ | ||
| 456 | return lookup_face (f, face->lface, c, face); | ||
| 457 | } | 746 | } |
| 458 | 747 | ||
| 459 | 748 | ||
| @@ -463,9 +752,10 @@ face_for_char (f, face, c) | |||
| 463 | Called from realize_x_face. */ | 752 | Called from realize_x_face. */ |
| 464 | 753 | ||
| 465 | int | 754 | int |
| 466 | make_fontset_for_ascii_face (f, base_fontset_id) | 755 | make_fontset_for_ascii_face (f, base_fontset_id, face) |
| 467 | FRAME_PTR f; | 756 | FRAME_PTR f; |
| 468 | int base_fontset_id; | 757 | int base_fontset_id; |
| 758 | struct face *face; | ||
| 469 | { | 759 | { |
| 470 | Lisp_Object base_fontset, fontset, frame; | 760 | Lisp_Object base_fontset, fontset, frame; |
| 471 | 761 | ||
| @@ -476,105 +766,69 @@ make_fontset_for_ascii_face (f, base_fontset_id) | |||
| 476 | if (!BASE_FONTSET_P (base_fontset)) | 766 | if (!BASE_FONTSET_P (base_fontset)) |
| 477 | base_fontset = FONTSET_BASE (base_fontset); | 767 | base_fontset = FONTSET_BASE (base_fontset); |
| 478 | xassert (BASE_FONTSET_P (base_fontset)); | 768 | xassert (BASE_FONTSET_P (base_fontset)); |
| 769 | if (! BASE_FONTSET_P (base_fontset)) | ||
| 770 | abort (); | ||
| 479 | } | 771 | } |
| 480 | else | 772 | else |
| 481 | base_fontset = Vdefault_fontset; | 773 | base_fontset = Vdefault_fontset; |
| 482 | 774 | ||
| 483 | fontset = make_fontset (frame, Qnil, base_fontset); | 775 | fontset = make_fontset (frame, Qnil, base_fontset); |
| 776 | { | ||
| 777 | Lisp_Object elt; | ||
| 778 | |||
| 779 | elt = FONTSET_REF (base_fontset, 0); | ||
| 780 | elt = Fmake_vector (make_number (3), AREF (elt, 0)); | ||
| 781 | ASET (elt, 0, make_number (face->id)); | ||
| 782 | ASET (elt, 1, make_number (face->font_info_id)); | ||
| 783 | elt = Fcons (make_number (charset_ordered_list_tick), | ||
| 784 | Fmake_vector (make_number (1), elt)); | ||
| 785 | char_table_set_range (fontset, 0, 127, elt); | ||
| 786 | } | ||
| 484 | return XINT (FONTSET_ID (fontset)); | 787 | return XINT (FONTSET_ID (fontset)); |
| 485 | } | 788 | } |
| 486 | 789 | ||
| 487 | 790 | ||
| 488 | /* Return FONT-SPEC recorded in the fontset of FACE for character C. | ||
| 489 | If FACE is null, or the fontset doesn't contain information about | ||
| 490 | C, get the font name pattern from the default fontset. Called from | ||
| 491 | choose_face_font. */ | ||
| 492 | |||
| 493 | Lisp_Object | ||
| 494 | fontset_font_pattern (f, face, c) | ||
| 495 | FRAME_PTR f; | ||
| 496 | struct face *face; | ||
| 497 | int c; | ||
| 498 | { | ||
| 499 | Lisp_Object fontset, base, elt; | ||
| 500 | int id = face ? face->fontset : -1; | ||
| 501 | |||
| 502 | if (id >= 0) | ||
| 503 | { | ||
| 504 | fontset = FONTSET_FROM_ID (id); | ||
| 505 | xassert (!BASE_FONTSET_P (fontset)); | ||
| 506 | base = FONTSET_BASE (fontset); | ||
| 507 | } | ||
| 508 | else | ||
| 509 | { | ||
| 510 | base = Vdefault_fontset; | ||
| 511 | } | ||
| 512 | |||
| 513 | FONTSET_REF (base, c, elt); | ||
| 514 | if (face && ! NILP (elt)) | ||
| 515 | { | ||
| 516 | Lisp_Object slot; | ||
| 517 | |||
| 518 | slot = Fassoc (elt, FONTSET_FACE_ALIST (fontset)); | ||
| 519 | if (CONSP (slot)) | ||
| 520 | XSETCDR (slot, make_number (face->id)); | ||
| 521 | FONTSET_FACE_ALIST (fontset) | ||
| 522 | = Fcons (Fcons (elt, make_number (face->id)), | ||
| 523 | FONTSET_FACE_ALIST (fontset)); | ||
| 524 | } | ||
| 525 | return elt; | ||
| 526 | } | ||
| 527 | |||
| 528 | |||
| 529 | #if defined(WINDOWSNT) && defined (_MSC_VER) | 791 | #if defined(WINDOWSNT) && defined (_MSC_VER) |
| 530 | #pragma optimize("", off) | 792 | #pragma optimize("", off) |
| 531 | #endif | 793 | #endif |
| 532 | 794 | ||
| 533 | /* Load a font named FONTNAME on frame F. Return a pointer to the | 795 | /* Load a font named FONTNAME on frame F. Return a pointer to the |
| 534 | struct font_info of the loaded font. If loading fails, return | 796 | struct font_info of the loaded font. If loading fails, return |
| 535 | NULL. */ | 797 | NULL. CHARSET_ID is an ID of charset to encode characters for this |
| 798 | font. */ | ||
| 536 | 799 | ||
| 537 | struct font_info * | 800 | struct font_info * |
| 538 | fs_load_font (f, fontname) | 801 | fs_load_font (f, fontname, charset_id) |
| 539 | FRAME_PTR f; | 802 | FRAME_PTR f; |
| 540 | char *fontname; | 803 | char *fontname; |
| 804 | int charset_id; | ||
| 541 | { | 805 | { |
| 542 | Lisp_Object tail, elt; | ||
| 543 | struct font_info *fontp; | 806 | struct font_info *fontp; |
| 544 | 807 | ||
| 545 | if (!fontname) | 808 | if (!fontname) |
| 546 | /* No way to get fontname. */ | 809 | /* No way to get fontname. */ |
| 547 | return 0; | 810 | return NULL; |
| 548 | 811 | ||
| 549 | fontp = (*load_font_func) (f, fontname, 0); | 812 | fontp = (*load_font_func) (f, fontname, 0); |
| 550 | if (!fontp) | 813 | if (!fontp) |
| 551 | return NULL; | 814 | return NULL; |
| 552 | 815 | ||
| 553 | fontname = fontp->full_name; | 816 | fontname = fontp->full_name; |
| 554 | /* Fill in members (charset, vertical_centering, encoding, etc) of | ||
| 555 | font_info structure that are not set by (*load_font_func). */ | ||
| 556 | for (tail = Vfont_encoding_alist; CONSP (tail); tail = XCDR (tail)) | ||
| 557 | { | ||
| 558 | elt = XCAR (tail); | ||
| 559 | if (STRINGP (XCAR (elt)) && CHARSETP (XCDR (elt)) | ||
| 560 | && fast_c_string_match_ignore_case (XCAR (elt), fontname) >= 0) | ||
| 561 | { | ||
| 562 | fontp->charset = XFASTINT (CHARSET_SYMBOL_ID (XCDR (elt))); | ||
| 563 | break; | ||
| 564 | } | ||
| 565 | } | ||
| 566 | if (! CONSP (tail)) | ||
| 567 | return NULL; | ||
| 568 | |||
| 569 | fontp->vertical_centering | ||
| 570 | = (STRINGP (Vvertical_centering_font_regexp) | ||
| 571 | && (fast_c_string_match_ignore_case | ||
| 572 | (Vvertical_centering_font_regexp, fontname) >= 0)); | ||
| 573 | 817 | ||
| 818 | fontp->charset = charset_id; | ||
| 819 | fontp->vertical_centering = 0; | ||
| 574 | fontp->font_encoder = NULL; | 820 | fontp->font_encoder = NULL; |
| 575 | 821 | ||
| 576 | if (find_ccl_program_func) | 822 | if (charset_id != charset_ascii) |
| 577 | (*find_ccl_program_func) (fontp); | 823 | { |
| 824 | fontp->vertical_centering | ||
| 825 | = (STRINGP (Vvertical_centering_font_regexp) | ||
| 826 | && (fast_c_string_match_ignore_case | ||
| 827 | (Vvertical_centering_font_regexp, fontname) >= 0)); | ||
| 828 | |||
| 829 | if (find_ccl_program_func) | ||
| 830 | (*find_ccl_program_func) (fontp); | ||
| 831 | } | ||
| 578 | 832 | ||
| 579 | return fontp; | 833 | return fontp; |
| 580 | } | 834 | } |
| @@ -584,6 +838,34 @@ fs_load_font (f, fontname) | |||
| 584 | #endif | 838 | #endif |
| 585 | 839 | ||
| 586 | 840 | ||
| 841 | /* Return ENCODING or a cons(ENCODING REPERTORY) of the font FONTNAME. | ||
| 842 | ENCODING is a charset symbol that specifies the encoding of the | ||
| 843 | font. REPERTORY is a charset symbol or nil. */ | ||
| 844 | |||
| 845 | |||
| 846 | static Lisp_Object | ||
| 847 | find_font_encoding (fontname) | ||
| 848 | char *fontname; | ||
| 849 | { | ||
| 850 | Lisp_Object tail, elt; | ||
| 851 | |||
| 852 | for (tail = Vfont_encoding_alist; CONSP (tail); tail = XCDR (tail)) | ||
| 853 | { | ||
| 854 | elt = XCAR (tail); | ||
| 855 | if (CONSP (elt) | ||
| 856 | && STRINGP (XCAR (elt)) | ||
| 857 | && fast_c_string_match_ignore_case (XCAR (elt), fontname) >= 0 | ||
| 858 | && (SYMBOLP (XCDR (elt)) | ||
| 859 | ? CHARSETP (XCDR (elt)) | ||
| 860 | : CONSP (XCDR (elt)) && CHARSETP (XCAR (XCDR (elt))))) | ||
| 861 | return (XCDR (elt)); | ||
| 862 | } | ||
| 863 | /* We don't know the encoding of this font. Let's assume Unicode | ||
| 864 | encoding. */ | ||
| 865 | return Qunicode; | ||
| 866 | } | ||
| 867 | |||
| 868 | |||
| 587 | /* Cache data used by fontset_pattern_regexp. The car part is a | 869 | /* Cache data used by fontset_pattern_regexp. The car part is a |
| 588 | pattern string containing at least one wild card, the cdr part is | 870 | pattern string containing at least one wild card, the cdr part is |
| 589 | the corresponding regular expression. */ | 871 | the corresponding regular expression. */ |
| @@ -738,7 +1020,7 @@ list_fontsets (f, pattern, size) | |||
| 738 | continue; | 1020 | continue; |
| 739 | name = XSTRING (FONTSET_NAME (fontset))->data; | 1021 | name = XSTRING (FONTSET_NAME (fontset))->data; |
| 740 | 1022 | ||
| 741 | if (!NILP (regexp) | 1023 | if (STRINGP (regexp) |
| 742 | ? (fast_c_string_match_ignore_case (regexp, name) < 0) | 1024 | ? (fast_c_string_match_ignore_case (regexp, name) < 0) |
| 743 | : strcmp (XSTRING (pattern)->data, name)) | 1025 | : strcmp (XSTRING (pattern)->data, name)) |
| 744 | continue; | 1026 | continue; |
| @@ -811,84 +1093,183 @@ check_fontset_name (name) | |||
| 811 | return FONTSET_FROM_ID (id); | 1093 | return FONTSET_FROM_ID (id); |
| 812 | } | 1094 | } |
| 813 | 1095 | ||
| 814 | DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0, | 1096 | static void |
| 815 | doc: /* Modify fontset NAME to use FONT-SPEC for characters of CHARSETS. | 1097 | accumulate_script_ranges (arg, range, val) |
| 1098 | Lisp_Object arg, range, val; | ||
| 1099 | { | ||
| 1100 | if (EQ (XCAR (arg), val)) | ||
| 1101 | { | ||
| 1102 | if (CONSP (range)) | ||
| 1103 | XSETCDR (arg, Fcons (Fcons (XCAR (range), XCDR (range)), XCDR (arg))); | ||
| 1104 | else | ||
| 1105 | XSETCDR (arg, Fcons (Fcons (range, range), XCDR (arg))); | ||
| 1106 | } | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | |||
| 1110 | DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 5, 0, | ||
| 1111 | doc: /* | ||
| 1112 | Modify fontset NAME to use FONT-SPEC for CHARACTER. | ||
| 1113 | |||
| 1114 | CHARACTER may be a cons; (FROM . TO), where FROM and TO are | ||
| 1115 | characters. In that case, use FONT-SPEC for all characters in the | ||
| 1116 | range FROM and TO (inclusive). | ||
| 816 | 1117 | ||
| 817 | CHARSET may be a cons; (FROM . TO), where FROM and TO are characters. | 1118 | CHARACTER may be a script name symbol. In that case, use FONT-SPEC |
| 818 | In that case, use FONT-SPEC for all characters in the range FROM and | 1119 | for all characters that belong to the script. |
| 819 | TO (inclusive). | ||
| 820 | 1120 | ||
| 821 | FONT-SPEC is be a vector; [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ] | 1121 | CHARACTER may be a charset who has :code-offset attribute and the |
| 1122 | attribute value is greater than the maximum Unicode character | ||
| 1123 | \(#x10FFFF). In that case, use FONT-SPEC for all characters in the | ||
| 1124 | charset. | ||
| 1125 | |||
| 1126 | FONT-SPEC is a vector; [ FAMILY WEIGHT SLANT ADSTYLE REGISTRY ]. | ||
| 1127 | See the documentation of `set-face-attribute' for the detail of | ||
| 1128 | these vector elements. | ||
| 822 | 1129 | ||
| 823 | FONT-SPEC may be a cons; (FAMILY . REGISTRY), where FAMILY is a family | 1130 | FONT-SPEC may be a cons; (FAMILY . REGISTRY). |
| 824 | name of a font, REGSITRY is a registry name of a font. | ||
| 825 | 1131 | ||
| 826 | FONT-SPEC may be a font name string. */) | 1132 | FONT-SPEC may be a font name string. |
| 827 | (name, charset, font_spec, frame) | 1133 | |
| 828 | Lisp_Object name, charset, font_spec, frame; | 1134 | Optional 4th argument FRAME, if non-nil, is a frame. This argument is |
| 1135 | kept for backward compatibility and has no meaning. | ||
| 1136 | |||
| 1137 | Optional 5th argument ADD, if non-nil, specifies how to add FONT-SPEC | ||
| 1138 | to the font specifications for RANGE previously set. If it is | ||
| 1139 | `prepend', FONT-SPEC is prepended. If it is `append', FONT-SPEC is | ||
| 1140 | appended. By default, FONT-SPEC overrides the previous settings. */) | ||
| 1141 | (name, character, font_spec, frame, add) | ||
| 1142 | Lisp_Object name, character, font_spec, frame, add; | ||
| 829 | { | 1143 | { |
| 830 | Lisp_Object fontset; | 1144 | Lisp_Object fontset; |
| 831 | Lisp_Object family, registry; | 1145 | int i; |
| 1146 | Lisp_Object font_def, registry; | ||
| 1147 | Lisp_Object val, encoding, repertory; | ||
| 1148 | Lisp_Object range_list; | ||
| 832 | 1149 | ||
| 833 | fontset = check_fontset_name (name); | 1150 | fontset = check_fontset_name (name); |
| 834 | 1151 | ||
| 1152 | /* The arg FRAME is kept for backward compatibility. We only check | ||
| 1153 | the validity. */ | ||
| 1154 | if (!NILP (frame)) | ||
| 1155 | CHECK_LIVE_FRAME (frame); | ||
| 1156 | |||
| 835 | if (VECTORP (font_spec)) | 1157 | if (VECTORP (font_spec)) |
| 836 | { | 1158 | { |
| 837 | int i; | 1159 | int j; |
| 838 | Lisp_Object val; | 1160 | |
| 1161 | if (ASIZE (font_spec) != 6) | ||
| 1162 | args_out_of_range (make_number (6), | ||
| 1163 | make_number (ASIZE (font_spec))); | ||
| 839 | 1164 | ||
| 840 | font_spec = Fcopy_sequence (font_spec); | 1165 | font_spec = Fcopy_sequence (font_spec); |
| 841 | for (i = 0; i < 5; i++) | 1166 | for (j = 0; j < 5; j++) |
| 842 | { | 1167 | if (! NILP (AREF (font_spec, j))) |
| 843 | val = Faref (font_spec, make_number (i)); | 1168 | { |
| 844 | if (! NILP (val)) | 1169 | CHECK_STRING (AREF (font_spec, j)); |
| 845 | { | 1170 | ASET (font_spec, j, Fdowncase (AREF (font_spec, j))); |
| 846 | CHECK_STRING (val); | 1171 | } |
| 847 | ASET (font_spec, i, Fdowncase (val)); | 1172 | /* REGISTRY should not be omitted. */ |
| 848 | } | 1173 | CHECK_STRING (AREF (font_spec, 5)); |
| 849 | } | 1174 | registry = Fdowncase (AREF (font_spec, 5)); |
| 850 | val = Faref (font_spec, make_number (5)); | 1175 | ASET (font_spec, 5, registry); |
| 851 | CHECK_STRING (val); | 1176 | |
| 852 | ASET (font_spec, 5, Fdowncase (val)); | ||
| 853 | } | 1177 | } |
| 854 | else if (STRINGP (font_spec)) | ||
| 855 | font_spec = Fdowncase (font_spec); | ||
| 856 | else if (CONSP (font_spec)) | 1178 | else if (CONSP (font_spec)) |
| 857 | { | 1179 | { |
| 858 | CHECK_CONS (font_spec); | 1180 | Lisp_Object family; |
| 1181 | |||
| 859 | family = XCAR (font_spec); | 1182 | family = XCAR (font_spec); |
| 860 | registry = XCDR (font_spec); | 1183 | registry = XCDR (font_spec); |
| 861 | font_spec = Fmake_vector (make_number (6), Qnil); | 1184 | |
| 862 | if (!NILP (family)) | 1185 | if (! NILP (family)) |
| 863 | { | 1186 | { |
| 864 | CHECK_STRING (family); | 1187 | CHECK_STRING (family); |
| 865 | ASET (font_spec, 0, Fdowncase (family)); | 1188 | family = Fdowncase (family); |
| 866 | } | 1189 | } |
| 867 | CHECK_STRING (registry); | 1190 | CHECK_STRING (registry); |
| 868 | ASET (font_spec, 5, Fdowncase (registry)); | 1191 | registry = Fdowncase (registry); |
| 1192 | font_spec = Fmake_vector (make_number (6), Qnil); | ||
| 1193 | ASET (font_spec, 0, family); | ||
| 1194 | ASET (font_spec, 5, registry); | ||
| 869 | } | 1195 | } |
| 870 | 1196 | else | |
| 871 | if (SYMBOLP (charset)) | ||
| 872 | { | 1197 | { |
| 873 | CHECK_CHARSET (charset); | 1198 | CHECK_STRING (font_spec); |
| 1199 | font_spec = Fdowncase (font_spec); | ||
| 1200 | registry = font_name_registry (font_spec); | ||
| 1201 | if (NILP (registry)) | ||
| 1202 | error ("No XLFD: %s", XSTRING (font_spec)->data); | ||
| 874 | } | 1203 | } |
| 1204 | |||
| 1205 | if (STRINGP (font_spec)) | ||
| 1206 | encoding = find_font_encoding ((char *) XSTRING (font_spec)->data); | ||
| 875 | else | 1207 | else |
| 1208 | encoding = find_font_encoding ((char *) XSTRING (registry)->data); | ||
| 1209 | if (SYMBOLP (encoding)) | ||
| 1210 | encoding = repertory = CHARSET_SYMBOL_ID (encoding); | ||
| 1211 | else | ||
| 1212 | { | ||
| 1213 | repertory = XCDR (encoding); | ||
| 1214 | encoding = CHARSET_SYMBOL_ID (XCAR (encoding)); | ||
| 1215 | } | ||
| 1216 | font_def = Fmake_vector (make_number (3), font_spec); | ||
| 1217 | ASET (font_def, 1, encoding); | ||
| 1218 | ASET (font_def, 2, repertory); | ||
| 1219 | |||
| 1220 | if (CHARACTERP (character)) | ||
| 1221 | range_list = Fcons (Fcons (character, character), Qnil); | ||
| 1222 | else if (CONSP (character)) | ||
| 876 | { | 1223 | { |
| 877 | Lisp_Object from, to; | 1224 | Lisp_Object from, to; |
| 878 | 1225 | ||
| 879 | /* CHARSET should be (FROM . TO). */ | 1226 | from = Fcar (character); |
| 880 | from = Fcar (charset); | 1227 | to = Fcdr (character); |
| 881 | to = Fcdr (charset); | ||
| 882 | CHECK_CHARACTER (from); | 1228 | CHECK_CHARACTER (from); |
| 883 | CHECK_CHARACTER (to); | 1229 | CHECK_CHARACTER (to); |
| 1230 | range_list = Fcons (character, Qnil); | ||
| 884 | } | 1231 | } |
| 1232 | else | ||
| 1233 | { | ||
| 1234 | Lisp_Object script_list; | ||
| 1235 | Lisp_Object val; | ||
| 885 | 1236 | ||
| 886 | /* The arg FRAME is kept for backward compatibility. We only check | 1237 | CHECK_SYMBOL (character); |
| 887 | the validity. */ | 1238 | range_list = Qnil; |
| 888 | if (!NILP (frame)) | 1239 | script_list = XCHAR_TABLE (Vchar_script_table)->extras[0]; |
| 889 | CHECK_LIVE_FRAME (frame); | 1240 | if (! NILP (Fmemq (character, script_list))) |
| 1241 | { | ||
| 1242 | val = Fcons (character, Qnil); | ||
| 1243 | map_char_table (accumulate_script_ranges, Qnil, Vchar_script_table, | ||
| 1244 | val, 0, NULL); | ||
| 1245 | range_list = XCDR (val); | ||
| 1246 | if (EQ (character, Qascii)) | ||
| 1247 | { | ||
| 1248 | if (! STRINGP (font_spec)) | ||
| 1249 | font_spec = generate_ascii_font_name (FONTSET_NAME (fontset), | ||
| 1250 | font_spec); | ||
| 1251 | FONTSET_ASCII (fontset) = font_spec; | ||
| 1252 | } | ||
| 1253 | } | ||
| 1254 | else if (CHARSETP (character)) | ||
| 1255 | { | ||
| 1256 | struct charset *charset; | ||
| 1257 | |||
| 1258 | CHECK_CHARSET_GET_CHARSET (character, charset); | ||
| 1259 | if (CHARSET_METHOD (charset) == CHARSET_METHOD_OFFSET) | ||
| 1260 | range_list | ||
| 1261 | = Fcons (Fcons (make_number (CHARSET_MIN_CHAR (charset)), | ||
| 1262 | make_number (CHARSET_MAX_CHAR (charset))), | ||
| 1263 | range_list); | ||
| 1264 | } | ||
| 890 | 1265 | ||
| 891 | FONTSET_SET (fontset, charset, font_spec); | 1266 | if (NILP (range_list)) |
| 1267 | error ("Invalid script or charset name: %s", | ||
| 1268 | XSYMBOL (character)->name->data); | ||
| 1269 | } | ||
| 1270 | |||
| 1271 | for (; CONSP (range_list); range_list = XCDR (range_list)) | ||
| 1272 | FONTSET_ADD (fontset, XCAR (range_list), font_def, add); | ||
| 892 | 1273 | ||
| 893 | /* Free all realized fontsets whose base is FONTSET. This way, the | 1274 | /* Free all realized fontsets whose base is FONTSET. This way, the |
| 894 | specified character(s) are surely redisplayed by a correct | 1275 | specified character(s) are surely redisplayed by a correct |
| @@ -902,51 +1283,50 @@ FONT-SPEC may be a font name string. */) | |||
| 902 | DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0, | 1283 | DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0, |
| 903 | doc: /* Create a new fontset NAME from font information in FONTLIST. | 1284 | doc: /* Create a new fontset NAME from font information in FONTLIST. |
| 904 | 1285 | ||
| 905 | FONTLIST is an alist of charsets vs corresponding font specifications. | 1286 | FONTLIST is an alist of scripts vs the corresponding font specification list. |
| 906 | Each element of FONTLIST has the form (CHARSET . FONT-SPEC), where | 1287 | Each element of FONTLIST has the form (SCRIPT FONT-SPEC ...), where |
| 907 | a character of CHARSET is displayed by a font that matches FONT-SPEC. | 1288 | a character of SCRIPT is displayed by a font that matches FONT-SPEC. |
| 908 | 1289 | ||
| 909 | FONT-SPEC is a vector [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ], where | 1290 | SCRIPT is a symbol that appears in the variable `script-alist'. |
| 910 | FAMILY is a string specifying the font family, | ||
| 911 | WEIGHT is a string specifying the weight of the font, | ||
| 912 | SLANT is a string specifying the slant of the font, | ||
| 913 | WIDTH is a string specifying the width of the font, | ||
| 914 | ADSTYLE is a string specifying the adstyle of the font, | ||
| 915 | REGISTRY is a string specifying the charset-registry of the font. | ||
| 916 | |||
| 917 | See also the documentation of `set-face-attribute' for the detail of | ||
| 918 | these vector elements. | ||
| 919 | 1291 | ||
| 920 | FONT-SPEC may be a font name (string). */) | 1292 | FONT-SPEC is a vector, a cons, or a string. See the documentation of |
| 1293 | `set-fontset-font' for the meaning. */) | ||
| 921 | (name, fontlist) | 1294 | (name, fontlist) |
| 922 | Lisp_Object name, fontlist; | 1295 | Lisp_Object name, fontlist; |
| 923 | { | 1296 | { |
| 924 | Lisp_Object fontset, ascii_font; | 1297 | Lisp_Object fontset; |
| 925 | Lisp_Object tem, tail; | 1298 | Lisp_Object val; |
| 1299 | int id; | ||
| 926 | 1300 | ||
| 927 | CHECK_STRING (name); | 1301 | CHECK_STRING (name); |
| 928 | CHECK_LIST (fontlist); | 1302 | CHECK_LIST (fontlist); |
| 929 | 1303 | ||
| 930 | name = Fdowncase (name); | 1304 | /* Check if an ASCII font is specified in FONTLIST. */ |
| 931 | tem = Fquery_fontset (name, Qnil); | 1305 | val = Fcar (Fcdr (Fassq (Qascii, fontlist))); |
| 932 | if (! NILP (tem)) | 1306 | if (NILP (val)) |
| 933 | free_realized_fontsets (tem); | ||
| 934 | |||
| 935 | fontset = make_fontset (Qnil, name, Qnil); | ||
| 936 | |||
| 937 | /* Check the validity of FONTLIST. */ | ||
| 938 | ascii_font = Fcdr (Fassq (Qascii, fontlist)); | ||
| 939 | if (NILP (ascii_font)) | ||
| 940 | error ("No ascii font specified"); | 1307 | error ("No ascii font specified"); |
| 941 | if (! STRINGP (ascii_font)) | ||
| 942 | ascii_font = generate_ascii_font (name, ascii_font); | ||
| 943 | 1308 | ||
| 944 | fontlist = Fcopy_sequence (fontlist); | 1309 | id = fs_query_fontset (name, 0); |
| 945 | for (tail = fontlist; ! NILP (tail); tail = Fcdr (tail)) | 1310 | if (id < 0) |
| 946 | Fset_fontset_font (name, Fcar (Fcar (tail)), Fcdr (Fcar (tail)), Qnil); | 1311 | fontset = make_fontset (Qnil, Fdowncase (name), Qnil); |
| 947 | 1312 | else | |
| 948 | FONTSET_ASCII (fontset) = ascii_font; | 1313 | { |
| 1314 | fontset = FONTSET_FROM_ID (id);; | ||
| 1315 | free_realized_fontsets (fontset); | ||
| 1316 | Fset_char_table_range (fontset, Qt, Qnil); | ||
| 1317 | } | ||
| 949 | 1318 | ||
| 1319 | for (; ! NILP (fontlist); fontlist = Fcdr (fontlist)) | ||
| 1320 | { | ||
| 1321 | Lisp_Object elt, script; | ||
| 1322 | |||
| 1323 | elt = Fcar (fontlist); | ||
| 1324 | script = Fcar (elt); | ||
| 1325 | elt = Fcdr (elt); | ||
| 1326 | Fset_fontset_font (name, script, Fcar (elt), Qnil, Qnil); | ||
| 1327 | for (elt = Fcdr (elt); ! NILP (elt); elt = Fcdr (elt)) | ||
| 1328 | Fset_fontset_font (name, script, XCAR (elt), Qnil, Qappend); | ||
| 1329 | } | ||
| 950 | return name; | 1330 | return name; |
| 951 | } | 1331 | } |
| 952 | 1332 | ||
| @@ -1051,171 +1431,109 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 1, 0, | |||
| 1051 | } | 1431 | } |
| 1052 | 1432 | ||
| 1053 | 1433 | ||
| 1054 | #if 0 /* unused */ | 1434 | DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0, |
| 1055 | /* Called from Ffontset_info via map_char_table on each leaf of | 1435 | doc: /* Return information about a fontset FONTSET on frame FRAME. |
| 1056 | fontset. ARG is a list (LAST FONT-INFO ...), where LAST is `(last | 1436 | The value is a char-table of which elements has this form. |
| 1057 | ARG)' and FONT-INFOs have this form: | ||
| 1058 | (CHAR FONT-SPEC) or ((FROM . TO) FONT-SPEC) | ||
| 1059 | The current leaf is indexed by CHARACTER and has value ELT. This | ||
| 1060 | function add the information of the current leaf to ARG by | ||
| 1061 | appending a new element or modifying the last element.. */ | ||
| 1062 | 1437 | ||
| 1063 | static void | 1438 | ((FONT-PATTERN OPENED-FONT ...) ...) |
| 1064 | accumulate_font_info (arg, character, elt) | ||
| 1065 | Lisp_Object arg, character, elt; | ||
| 1066 | { | ||
| 1067 | Lisp_Object last, last_char, last_elt; | ||
| 1068 | 1439 | ||
| 1069 | if (!CONSP (elt) && !SINGLE_BYTE_CHAR_P (XINT (character))) | 1440 | FONT-PATTERN is a vector: |
| 1070 | FONTSET_REF (Vdefault_fontset, XINT (character), elt); | ||
| 1071 | if (!CONSP (elt)) | ||
| 1072 | return; | ||
| 1073 | last = XCAR (arg); | ||
| 1074 | last_char = XCAR (XCAR (last)); | ||
| 1075 | last_elt = XCAR (XCDR (XCAR (last))); | ||
| 1076 | elt = XCDR (elt); | ||
| 1077 | if (!NILP (Fequal (elt, last_elt))) | ||
| 1078 | { | ||
| 1079 | struct charset *this_charset = CHAR_CHARSET (XINT (character)); | ||
| 1080 | 1441 | ||
| 1081 | if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */ | 1442 | [ FAMILY WEIGHT SLANT SWIDTH ADSTYLE REGISTRY ] |
| 1082 | { | ||
| 1083 | if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char)))) | ||
| 1084 | { | ||
| 1085 | XSETCDR (last_char, character); | ||
| 1086 | return; | ||
| 1087 | } | ||
| 1088 | } | ||
| 1089 | else if (XINT (last_char) == XINT (character)) | ||
| 1090 | return; | ||
| 1091 | else if (this_charset == CHAR_CHARSET (XINT (last_char))) | ||
| 1092 | { | ||
| 1093 | XSETCAR (XCAR (last), Fcons (last_char, character)); | ||
| 1094 | return; | ||
| 1095 | } | ||
| 1096 | } | ||
| 1097 | XSETCDR (last, Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil)); | ||
| 1098 | XSETCAR (arg, XCDR (last)); | ||
| 1099 | } | ||
| 1100 | #endif /* 0 */ | ||
| 1101 | 1443 | ||
| 1102 | DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0, | 1444 | or a string of font name pattern. |
| 1103 | doc: /* Return information about a fontset named NAME on frame FRAME. | 1445 | |
| 1104 | The value is a vector: | 1446 | OPENED-FONT is a name of a font actually opened. */) |
| 1105 | [ SIZE HEIGHT ((CHARSET-OR-RANGE FONT-SPEC OPENED ...) ...) ], | 1447 | (fontset, frame) |
| 1106 | where, | 1448 | Lisp_Object fontset, frame; |
| 1107 | SIZE is the maximum bound width of ASCII font in the fontset, | ||
| 1108 | HEIGHT is the maximum bound height of ASCII font in the fontset, | ||
| 1109 | CHARSET-OR-RANGE is a charset or a cons of two characters specifying | ||
| 1110 | the range of characters. | ||
| 1111 | FONT-SPEC is a fontname pattern string or a vector | ||
| 1112 | [ FAMILY WEIGHT SLANT WIDTH ADSTYLE REGISTRY ]. | ||
| 1113 | See the documentation of `new-fontset' for the meanings those elements. | ||
| 1114 | OPENEDs are names of fonts actually opened. | ||
| 1115 | If the ASCII font is not yet opened, SIZE and HEIGHT are 0. | ||
| 1116 | If FRAME is omitted, it defaults to the currently selected frame. */) | ||
| 1117 | (name, frame) | ||
| 1118 | Lisp_Object name, frame; | ||
| 1119 | { | 1449 | { |
| 1120 | Lisp_Object fontset; | ||
| 1121 | FRAME_PTR f; | 1450 | FRAME_PTR f; |
| 1122 | Lisp_Object val, tail, elt; | 1451 | Lisp_Object table, val, elt; |
| 1123 | Lisp_Object *realized; | 1452 | Lisp_Object *realized; |
| 1124 | struct font_info *fontp = NULL; | 1453 | struct font_info *fontp = NULL; |
| 1125 | int n_realized = 0; | 1454 | int n_realized = 0; |
| 1126 | int i; | 1455 | int c, i, j; |
| 1127 | 1456 | ||
| 1128 | (*check_window_system_func) (); | 1457 | (*check_window_system_func) (); |
| 1129 | 1458 | ||
| 1130 | fontset = check_fontset_name (name); | 1459 | fontset = check_fontset_name (fontset); |
| 1131 | 1460 | ||
| 1132 | if (NILP (frame)) | 1461 | if (NILP (frame)) |
| 1133 | frame = selected_frame; | 1462 | frame = selected_frame; |
| 1134 | CHECK_LIVE_FRAME (frame); | 1463 | CHECK_LIVE_FRAME (frame); |
| 1135 | f = XFRAME (frame); | 1464 | f = XFRAME (frame); |
| 1136 | 1465 | ||
| 1137 | /* Recode realized fontsets whose base is FONTSET in the table | 1466 | /* Recode fontsets realized on FRAME from the base fontset FONTSET |
| 1138 | `realized'. */ | 1467 | in the table `realized'. */ |
| 1139 | realized = (Lisp_Object *) alloca (sizeof (Lisp_Object) | 1468 | realized = (Lisp_Object *) alloca (sizeof (Lisp_Object) |
| 1140 | * ASIZE (Vfontset_table)); | 1469 | * ASIZE (Vfontset_table)); |
| 1141 | for (i = 0; i < ASIZE (Vfontset_table); i++) | 1470 | for (i = 0; i < ASIZE (Vfontset_table); i++) |
| 1142 | { | 1471 | { |
| 1143 | elt = FONTSET_FROM_ID (i); | 1472 | elt = FONTSET_FROM_ID (i); |
| 1144 | if (!NILP (elt) | 1473 | if (!NILP (elt) |
| 1145 | && EQ (FONTSET_BASE (elt), fontset)) | 1474 | && EQ (FONTSET_BASE (elt), fontset) |
| 1475 | && EQ (FONTSET_FRAME (elt), frame)) | ||
| 1146 | realized[n_realized++] = elt; | 1476 | realized[n_realized++] = elt; |
| 1147 | } | 1477 | } |
| 1148 | 1478 | ||
| 1149 | /* Accumulate information of the fontset in VAL. The format is | 1479 | |
| 1150 | (LAST FONT-INFO FONT-INFO ...), where FONT-INFO is (CHAR-OR-RANGE | 1480 | table = Fmake_char_table (Qnil, Qnil); |
| 1151 | FONT-SPEC). See the comment for accumulate_font_info for the | 1481 | /* Accumulate information of the fontset in TABLE. The format of |
| 1152 | detail. */ | 1482 | each element is ((FONT-SPEC OPENED-FONT ...) ...). */ |
| 1153 | val = Fcons (Fcons (Qascii, Fcons (FONTSET_ASCII (fontset), Qnil)), Qnil); | 1483 | for (c = 0; c <= MAX_CHAR; ) |
| 1154 | val = Fcons (val, val); | ||
| 1155 | for (i = 128; i <= MAX_CHAR; ) | ||
| 1156 | { | 1484 | { |
| 1157 | Lisp_Object elt; | ||
| 1158 | int from, to; | 1485 | int from, to; |
| 1159 | 1486 | ||
| 1160 | elt = char_table_ref_and_range (fontset, i, &from, &to); | 1487 | val = FONTSET_REF_AND_RANGE (fontset, c, from, to); |
| 1161 | if (! NILP (elt)) | 1488 | if (VECTORP (val)) |
| 1162 | { | 1489 | { |
| 1163 | elt = Fcons (Fcons (make_number (from), make_number (to)), | 1490 | Lisp_Object alist; |
| 1164 | Fcons (elt, Qnil)); | ||
| 1165 | XSETCDR (XCAR (val), Fcons (elt, Qnil)); | ||
| 1166 | XSETCAR (val, XCDR (XCAR (val))); | ||
| 1167 | } | ||
| 1168 | i = to + 1; | ||
| 1169 | } | ||
| 1170 | |||
| 1171 | for (tail = FONTSET_CHARSET_ALIST (fontset); | ||
| 1172 | CONSP (tail); tail = XCDR (tail)) | ||
| 1173 | { | ||
| 1174 | elt = XCAR (tail); | ||
| 1175 | elt = Fcons ((INTEGERP (XCAR (elt)) | ||
| 1176 | ? CHARSET_NAME (CHARSET_FROM_ID (XFASTINT (XCAR (elt)))) | ||
| 1177 | : XCAR (elt)), | ||
| 1178 | Fcons (XCDR (elt), Qnil)); | ||
| 1179 | XSETCDR (XCAR (val), Fcons (elt, Qnil)); | ||
| 1180 | XSETCAR (val, XCDR (XCAR (val))); | ||
| 1181 | } | ||
| 1182 | 1491 | ||
| 1183 | val = XCDR (val); | 1492 | /* At first, set ALIST to ((FONT-SPEC) ...). */ |
| 1184 | 1493 | for (alist = Qnil, i = 0; i < ASIZE (val); i++) | |
| 1185 | /* If fonts are opened for FONT-SPEC, append the names of the fonts to | 1494 | alist = Fcons (Fcons (AREF (AREF (val, i), 0), Qnil), alist); |
| 1186 | FONT-SPEC. */ | 1495 | alist = Fnreverse (alist); |
| 1187 | for (tail = val; CONSP (tail); tail = XCDR (tail)) | ||
| 1188 | { | ||
| 1189 | elt = XCAR (tail); | ||
| 1190 | for (i = 0; i < n_realized; i++) | ||
| 1191 | { | ||
| 1192 | Lisp_Object face_list, fontname; | ||
| 1193 | 1496 | ||
| 1194 | for (face_list = FONTSET_FACE_ALIST (realized[i]); | 1497 | /* Then store opend font names to cdr of each elements. */ |
| 1195 | CONSP (face_list); face_list = XCDR (face_list)) | 1498 | for (i = 0; i < n_realized; i++) |
| 1196 | { | 1499 | { |
| 1197 | int face_id = XINT (XCDR (XCAR (face_list))); | 1500 | val = FONTSET_REF (realized[i], c); |
| 1198 | struct face *face = FACE_FROM_ID (f, face_id); | 1501 | if (NILP (val)) |
| 1199 | 1502 | continue; | |
| 1200 | if (face->font && face->font_name) | 1503 | val = XCDR (val); |
| 1201 | { | 1504 | /* Now VAL is [[FACE-ID FONT-INDEX FONT-DEF] ...]. |
| 1202 | fontname = build_string (face->font_name); | 1505 | If a font of an element is already opened, |
| 1203 | if (NILP (Fmember (fontname, XCDR (XCDR (elt))))) | 1506 | FONT-INDEX of the element is integer. */ |
| 1204 | XSETCDR (XCDR (elt), Fcons (fontname, XCDR (XCDR (elt)))); | 1507 | for (j = 0; j < ASIZE (val); j++) |
| 1205 | } | 1508 | if (INTEGERP (AREF (AREF (val, j), 0))) |
| 1509 | { | ||
| 1510 | Lisp_Object font_idx; | ||
| 1511 | |||
| 1512 | font_idx = AREF (AREF (val, j), 1); | ||
| 1513 | elt = Fassq (AREF (AREF (AREF (val, j), 2), 0), alist); | ||
| 1514 | if (CONSP (elt) | ||
| 1515 | && NILP (Fmemq (font_idx, XCDR(elt)))) | ||
| 1516 | nconc2 (elt, Fcons (font_idx, Qnil)); | ||
| 1517 | } | ||
| 1206 | } | 1518 | } |
| 1519 | for (val = alist; CONSP (val); val = XCDR (val)) | ||
| 1520 | for (elt = XCDR (XCAR (val)); CONSP (elt); elt = XCDR (elt)) | ||
| 1521 | { | ||
| 1522 | struct font_info *font_info | ||
| 1523 | = (*get_font_info_func) (f, XINT (XCAR (elt))); | ||
| 1524 | XSETCAR (elt, build_string (font_info->full_name)); | ||
| 1525 | } | ||
| 1526 | |||
| 1527 | /* Store ALIST in TABLE for characters C..TO. */ | ||
| 1528 | char_table_set_range (table, c, to, alist); | ||
| 1207 | } | 1529 | } |
| 1530 | c = to + 1; | ||
| 1208 | } | 1531 | } |
| 1209 | 1532 | ||
| 1210 | elt = XCDR (XCDR (XCAR (val))); | 1533 | return table; |
| 1211 | if (CONSP (elt)) | ||
| 1212 | fontp = (*query_font_func) (f, XSTRING (XCAR (elt))->data); | ||
| 1213 | val = Fmake_vector (make_number (3), val); | ||
| 1214 | AREF (val, 0) = fontp ? make_number (fontp->size) : make_number (0); | ||
| 1215 | AREF (val, 1) = fontp ? make_number (fontp->height) : make_number (0); | ||
| 1216 | return val; | ||
| 1217 | } | 1534 | } |
| 1218 | 1535 | ||
| 1536 | |||
| 1219 | DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0, | 1537 | DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0, |
| 1220 | doc: /* Return a font name pattern for character CH in fontset NAME. | 1538 | doc: /* Return a font name pattern for character CH in fontset NAME. |
| 1221 | If NAME is t, find a font name pattern in the default fontset. */) | 1539 | If NAME is t, find a font name pattern in the default fontset. */) |
| @@ -1229,8 +1547,8 @@ If NAME is t, find a font name pattern in the default fontset. */) | |||
| 1229 | 1547 | ||
| 1230 | CHECK_CHARACTER (ch); | 1548 | CHECK_CHARACTER (ch); |
| 1231 | c = XINT (ch); | 1549 | c = XINT (ch); |
| 1232 | FONTSET_REF (fontset, c, elt); | 1550 | elt = FONTSET_REF (fontset, c); |
| 1233 | return elt; | 1551 | return Fcopy_sequence (elt); |
| 1234 | } | 1552 | } |
| 1235 | 1553 | ||
| 1236 | DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0, | 1554 | DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0, |
| @@ -1259,10 +1577,12 @@ syms_of_fontset () | |||
| 1259 | /* Window system initializer should have set proper functions. */ | 1577 | /* Window system initializer should have set proper functions. */ |
| 1260 | abort (); | 1578 | abort (); |
| 1261 | 1579 | ||
| 1262 | Qfontset = intern ("fontset"); | 1580 | DEFSYM (Qfontset, "fontset"); |
| 1263 | staticpro (&Qfontset); | ||
| 1264 | Fput (Qfontset, Qchar_table_extra_slots, make_number (7)); | 1581 | Fput (Qfontset, Qchar_table_extra_slots, make_number (7)); |
| 1265 | 1582 | ||
| 1583 | DEFSYM (Qprepend, "prepend"); | ||
| 1584 | DEFSYM (Qappend, "append"); | ||
| 1585 | |||
| 1266 | Vcached_fontset_data = Qnil; | 1586 | Vcached_fontset_data = Qnil; |
| 1267 | staticpro (&Vcached_fontset_data); | 1587 | staticpro (&Vcached_fontset_data); |
| 1268 | 1588 | ||
| @@ -1293,13 +1613,27 @@ syms_of_fontset () | |||
| 1293 | next_fontset_id = 1; | 1613 | next_fontset_id = 1; |
| 1294 | 1614 | ||
| 1295 | DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist, | 1615 | DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist, |
| 1296 | doc: /* Alist of fontname patterns vs corresponding encoding info. | 1616 | doc: /* |
| 1297 | Each element looks like (REGEXP . CHARSET), where CHARSET is an | 1617 | Alist of fontname patterns vs the corresponding encoding and repertory info. |
| 1298 | Emacs charset symbol. */); | 1618 | Each element looks like (REGEXP . (ENCODING . REPERTORY)), |
| 1619 | where ENCODING is a charset or a char-table, | ||
| 1620 | and REPERTORY is a charset, a char-table, or nil. | ||
| 1621 | |||
| 1622 | ENCODING is for converting a character to a glyph code of the font. | ||
| 1623 | If ENCODING is a charset, encoding a character by the charset gives | ||
| 1624 | the corresponding glyph code. If ENCODING is a char-table, looking up | ||
| 1625 | the table by a character gives the corresponding glyph code. | ||
| 1626 | |||
| 1627 | REPERTORY specifies a repertory of characters supported by the font. | ||
| 1628 | If REPERTORY is a charset, all characters beloging to the charset are | ||
| 1629 | supported. If REPERTORY is a char-table, all characters who have a | ||
| 1630 | non-nil value in the table are supported. It REPERTORY is nil, Emacs | ||
| 1631 | gets the repertory information by an opened font and ENCODING. */); | ||
| 1299 | Vfont_encoding_alist = Qnil; | 1632 | Vfont_encoding_alist = Qnil; |
| 1300 | 1633 | ||
| 1301 | DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent, | 1634 | DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent, |
| 1302 | doc: /* Char table of characters whose ascent values should be ignored. | 1635 | doc: /* |
| 1636 | Char table of characters whose ascent values should be ignored. | ||
| 1303 | If an entry for a character is non-nil, the ascent value of the glyph | 1637 | If an entry for a character is non-nil, the ascent value of the glyph |
| 1304 | is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font. | 1638 | is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font. |
| 1305 | 1639 | ||
| @@ -1308,7 +1642,8 @@ such a character is displayed on screen. */); | |||
| 1308 | Vuse_default_ascent = Qnil; | 1642 | Vuse_default_ascent = Qnil; |
| 1309 | 1643 | ||
| 1310 | DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition, | 1644 | DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition, |
| 1311 | doc: /* Char table of characters which is not composed relatively. | 1645 | doc: /* |
| 1646 | Char table of characters which is not composed relatively. | ||
| 1312 | If an entry for a character is non-nil, a composition sequence | 1647 | If an entry for a character is non-nil, a composition sequence |
| 1313 | which contains that character is displayed so that | 1648 | which contains that character is displayed so that |
| 1314 | the glyph of that character is put without considering | 1649 | the glyph of that character is put without considering |