17052
|
1 /* Fontset handler.
|
28223
|
2 Copyright (C) 1995, 1997, 2000 Electrotechnical Laboratory, JAPAN.
|
18341
|
3 Licensed to the Free Software Foundation.
|
17052
|
4
|
17071
|
5 This file is part of GNU Emacs.
|
|
6
|
|
7 GNU Emacs is free software; you can redistribute it and/or modify
|
|
8 it under the terms of the GNU General Public License as published by
|
|
9 the Free Software Foundation; either version 2, or (at your option)
|
|
10 any later version.
|
17052
|
11
|
17071
|
12 GNU Emacs is distributed in the hope that it will be useful,
|
|
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15 GNU General Public License for more details.
|
17052
|
16
|
17071
|
17 You should have received a copy of the GNU General Public License
|
|
18 along with GNU Emacs; see the file COPYING. If not, write to
|
|
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
20 Boston, MA 02111-1307, USA. */
|
17052
|
21
|
28223
|
22 /* #define FONTSET_DEBUG */
|
|
23
|
17052
|
24 #include <config.h>
|
28223
|
25
|
|
26 #ifdef FONTSET_DEBUG
|
|
27 #include <stdio.h>
|
|
28 #endif
|
|
29
|
17052
|
30 #include "lisp.h"
|
28963
|
31 #include "buffer.h"
|
17052
|
32 #include "charset.h"
|
|
33 #include "ccl.h"
|
31102
|
34 #include "keyboard.h"
|
23517
|
35 #include "frame.h"
|
28223
|
36 #include "dispextern.h"
|
17052
|
37 #include "fontset.h"
|
28223
|
38 #include "window.h"
|
52654
|
39 #ifdef HAVE_X_WINDOWS
|
|
40 #include "xterm.h"
|
|
41 #endif
|
|
42 #ifdef WINDOWSNT
|
|
43 #include "w32term.h"
|
|
44 #endif
|
|
45 #ifdef MAC_OS
|
|
46 #include "macterm.h"
|
|
47 #endif
|
28223
|
48
|
|
49 #ifdef FONTSET_DEBUG
|
|
50 #undef xassert
|
|
51 #define xassert(X) do {if (!(X)) abort ();} while (0)
|
|
52 #undef INLINE
|
|
53 #define INLINE
|
|
54 #endif
|
|
55
|
|
56
|
|
57 /* FONTSET
|
|
58
|
|
59 A fontset is a collection of font related information to give
|
|
60 similar appearance (style, size, etc) of characters. There are two
|
|
61 kinds of fontsets; base and realized. A base fontset is created by
|
|
62 new-fontset from Emacs Lisp explicitly. A realized fontset is
|
|
63 created implicitly when a face is realized for ASCII characters. A
|
|
64 face is also realized for multibyte characters based on an ASCII
|
|
65 face. All of the multibyte faces based on the same ASCII face
|
|
66 share the same realized fontset.
|
41987
|
67
|
28223
|
68 A fontset object is implemented by a char-table.
|
|
69
|
|
70 An element of a base fontset is:
|
|
71 (INDEX . FONTNAME) or
|
|
72 (INDEX . (FOUNDRY . REGISTRY ))
|
|
73 FONTNAME is a font name pattern for the corresponding character.
|
41987
|
74 FOUNDRY and REGISTRY are respectively foundry and registry fields of
|
28223
|
75 a font name for the corresponding character. INDEX specifies for
|
|
76 which character (or generic character) the element is defined. It
|
|
77 may be different from an index to access this element. For
|
|
78 instance, if a fontset defines some font for all characters of
|
|
79 charset `japanese-jisx0208', INDEX is the generic character of this
|
|
80 charset. REGISTRY is the
|
|
81
|
|
82 An element of a realized fontset is FACE-ID which is a face to use
|
41987
|
83 for displaying the corresponding character.
|
28223
|
84
|
41987
|
85 All single byte characters (ASCII and 8bit-unibyte) share the same
|
29767
|
86 element in a fontset. The element is stored in the first element
|
|
87 of the fontset.
|
28223
|
88
|
|
89 To access or set each element, use macros FONTSET_REF and
|
|
90 FONTSET_SET respectively for efficiency.
|
|
91
|
|
92 A fontset has 3 extra slots.
|
17052
|
93
|
28223
|
94 The 1st slot is an ID number of the fontset.
|
|
95
|
|
96 The 2nd slot is a name of the fontset. This is nil for a realized
|
|
97 face.
|
|
98
|
|
99 The 3rd slot is a frame that the fontset belongs to. This is nil
|
|
100 for a default face.
|
|
101
|
|
102 A parent of a base fontset is nil. A parent of a realized fontset
|
|
103 is a base fontset.
|
|
104
|
30398
|
105 All fontsets are recorded in Vfontset_table.
|
28223
|
106
|
|
107
|
|
108 DEFAULT FONTSET
|
|
109
|
|
110 There's a special fontset named `default fontset' which defines a
|
30398
|
111 default fontname pattern. When a base fontset doesn't specify a
|
|
112 font for a specific character, the corresponding value in the
|
|
113 default fontset is used. The format is the same as a base fontset.
|
28223
|
114
|
30398
|
115 The parent of a realized fontset created for such a face that has
|
|
116 no fontset is the default fontset.
|
28223
|
117
|
|
118
|
|
119 These structures are hidden from the other codes than this file.
|
|
120 The other codes handle fontsets only by their ID numbers. They
|
|
121 usually use variable name `fontset' for IDs. But, in this file, we
|
41987
|
122 always use variable name `id' for IDs, and name `fontset' for the
|
28223
|
123 actual fontset objects.
|
|
124
|
|
125 */
|
|
126
|
|
127 /********** VARIABLES and FUNCTION PROTOTYPES **********/
|
|
128
|
|
129 extern Lisp_Object Qfont;
|
|
130 Lisp_Object Qfontset;
|
|
131
|
|
132 /* Vector containing all fontsets. */
|
|
133 static Lisp_Object Vfontset_table;
|
|
134
|
41987
|
135 /* Next possibly free fontset ID. Usually this keeps the minimum
|
28223
|
136 fontset ID not yet used. */
|
|
137 static int next_fontset_id;
|
|
138
|
|
139 /* The default fontset. This gives default FAMILY and REGISTRY of
|
|
140 font for each characters. */
|
|
141 static Lisp_Object Vdefault_fontset;
|
|
142
|
53353
|
143 /* Alist of font specifications. It override the font specification
|
|
144 in the default fontset. */
|
|
145 static Lisp_Object Voverriding_fontspec_alist;
|
|
146
|
17052
|
147 Lisp_Object Vfont_encoding_alist;
|
17112
|
148 Lisp_Object Vuse_default_ascent;
|
19282
|
149 Lisp_Object Vignore_relative_composition;
|
19450
|
150 Lisp_Object Valternate_fontname_alist;
|
17730
|
151 Lisp_Object Vfontset_alias_alist;
|
26858
|
152 Lisp_Object Vvertical_centering_font_regexp;
|
17052
|
153
|
28223
|
154 /* The following six are declarations of callback functions depending
|
|
155 on window system. See the comments in src/fontset.h for more
|
|
156 detail. */
|
17052
|
157
|
|
158 /* Return a pointer to struct font_info of font FONT_IDX of frame F. */
|
20315
|
159 struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
|
17052
|
160
|
41987
|
161 /* Return a list of font names which matches PATTERN. See the documentation
|
|
162 of `x-list-fonts' for more details. */
|
23517
|
163 Lisp_Object (*list_fonts_func) P_ ((struct frame *f,
|
|
164 Lisp_Object pattern,
|
|
165 int size,
|
|
166 int maxnames));
|
17052
|
167
|
|
168 /* Load a font named NAME for frame F and return a pointer to the
|
|
169 information of the loaded font. If loading is failed, return 0. */
|
20315
|
170 struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
|
17052
|
171
|
|
172 /* Return a pointer to struct font_info of a font named NAME for frame F. */
|
20315
|
173 struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
|
17052
|
174
|
|
175 /* Additional function for setting fontset or changing fontset
|
|
176 contents of frame F. */
|
20315
|
177 void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
|
|
178 Lisp_Object oldval));
|
17052
|
179
|
21553
|
180 /* To find a CCL program, fs_load_font calls this function.
|
|
181 The argument is a pointer to the struct font_info.
|
41987
|
182 This function set the member `encoder' of the structure. */
|
21553
|
183 void (*find_ccl_program_func) P_ ((struct font_info *));
|
|
184
|
17052
|
185 /* Check if any window system is used now. */
|
20315
|
186 void (*check_window_system_func) P_ ((void));
|
17052
|
187
|
28223
|
188
|
|
189 /* Prototype declarations for static functions. */
|
|
190 static Lisp_Object fontset_ref P_ ((Lisp_Object, int));
|
53353
|
191 static Lisp_Object lookup_overriding_fontspec P_ ((Lisp_Object, int));
|
28223
|
192 static void fontset_set P_ ((Lisp_Object, int, Lisp_Object));
|
|
193 static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
|
|
194 static int fontset_id_valid_p P_ ((int));
|
|
195 static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
|
35658
|
196 static Lisp_Object font_family_registry P_ ((Lisp_Object, int));
|
54995
|
197 static Lisp_Object regularize_fontname P_ ((Lisp_Object));
|
28223
|
198
|
|
199
|
|
200 /********** MACROS AND FUNCTIONS TO HANDLE FONTSET **********/
|
|
201
|
|
202 /* Return the fontset with ID. No check of ID's validness. */
|
|
203 #define FONTSET_FROM_ID(id) AREF (Vfontset_table, id)
|
|
204
|
30398
|
205 /* Macros to access special values of FONTSET. */
|
28223
|
206 #define FONTSET_ID(fontset) XCHAR_TABLE (fontset)->extras[0]
|
|
207 #define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1]
|
|
208 #define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[2]
|
29767
|
209 #define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->contents[0]
|
28223
|
210 #define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->parent
|
|
211
|
|
212 #define BASE_FONTSET_P(fontset) NILP (FONTSET_BASE(fontset))
|
|
213
|
|
214
|
|
215 /* Return the element of FONTSET (char-table) at index C (character). */
|
|
216
|
|
217 #define FONTSET_REF(fontset, c) fontset_ref (fontset, c)
|
|
218
|
30398
|
219 static Lisp_Object
|
28223
|
220 fontset_ref (fontset, c)
|
|
221 Lisp_Object fontset;
|
|
222 int c;
|
|
223 {
|
|
224 int charset, c1, c2;
|
|
225 Lisp_Object elt, defalt;
|
|
226
|
|
227 if (SINGLE_BYTE_CHAR_P (c))
|
|
228 return FONTSET_ASCII (fontset);
|
|
229
|
29011
|
230 SPLIT_CHAR (c, charset, c1, c2);
|
28223
|
231 elt = XCHAR_TABLE (fontset)->contents[charset + 128];
|
|
232 if (!SUB_CHAR_TABLE_P (elt))
|
|
233 return elt;
|
|
234 defalt = XCHAR_TABLE (elt)->defalt;
|
|
235 if (c1 < 32
|
|
236 || (elt = XCHAR_TABLE (elt)->contents[c1],
|
|
237 NILP (elt)))
|
|
238 return defalt;
|
|
239 if (!SUB_CHAR_TABLE_P (elt))
|
|
240 return elt;
|
|
241 defalt = XCHAR_TABLE (elt)->defalt;
|
|
242 if (c2 < 32
|
|
243 || (elt = XCHAR_TABLE (elt)->contents[c2],
|
|
244 NILP (elt)))
|
|
245 return defalt;
|
|
246 return elt;
|
|
247 }
|
|
248
|
|
249
|
53353
|
250 static Lisp_Object
|
|
251 lookup_overriding_fontspec (frame, c)
|
|
252 Lisp_Object frame;
|
|
253 int c;
|
|
254 {
|
|
255 Lisp_Object tail;
|
|
256
|
|
257 for (tail = Voverriding_fontspec_alist; CONSP (tail); tail = XCDR (tail))
|
|
258 {
|
|
259 Lisp_Object val, target, elt;
|
|
260
|
|
261 val = XCAR (tail);
|
|
262 target = XCAR (val);
|
|
263 val = XCDR (val);
|
|
264 /* Now VAL is (NO-FRAME-LIST OK-FRAME-LIST CHAR FONTNAME). */
|
|
265 if (NILP (Fmemq (frame, XCAR (val)))
|
|
266 && (CHAR_TABLE_P (target)
|
|
267 ? ! NILP (CHAR_TABLE_REF (target, c))
|
|
268 : XINT (target) == CHAR_CHARSET (c)))
|
|
269 {
|
|
270 val = XCDR (val);
|
|
271 elt = XCDR (val);
|
|
272 if (NILP (Fmemq (frame, XCAR (val))))
|
|
273 {
|
|
274 if (! face_font_available_p (XFRAME (frame), XCDR (elt)))
|
|
275 {
|
|
276 val = XCDR (XCAR (tail));
|
|
277 XSETCAR (val, Fcons (frame, XCAR (val)));
|
|
278 continue;
|
|
279 }
|
|
280 XSETCAR (val, Fcons (frame, XCAR (val)));
|
|
281 }
|
|
282 if (NILP (XCAR (elt)))
|
|
283 XSETCAR (elt, make_number (c));
|
|
284 return elt;
|
|
285 }
|
|
286 }
|
|
287 return Qnil;
|
|
288 }
|
|
289
|
28223
|
290 #define FONTSET_REF_VIA_BASE(fontset, c) fontset_ref_via_base (fontset, &c)
|
|
291
|
30398
|
292 static Lisp_Object
|
28223
|
293 fontset_ref_via_base (fontset, c)
|
|
294 Lisp_Object fontset;
|
|
295 int *c;
|
|
296 {
|
|
297 int charset, c1, c2;
|
|
298 Lisp_Object elt;
|
|
299
|
|
300 if (SINGLE_BYTE_CHAR_P (*c))
|
|
301 return FONTSET_ASCII (fontset);
|
|
302
|
53353
|
303 elt = Qnil;
|
|
304 if (! EQ (FONTSET_BASE (fontset), Vdefault_fontset))
|
|
305 elt = FONTSET_REF (FONTSET_BASE (fontset), *c);
|
|
306 if (NILP (elt))
|
|
307 elt = lookup_overriding_fontspec (FONTSET_FRAME (fontset), *c);
|
53524
|
308 if (NILP (elt))
|
29767
|
309 elt = FONTSET_REF (Vdefault_fontset, *c);
|
28223
|
310 if (NILP (elt))
|
|
311 return Qnil;
|
|
312
|
|
313 *c = XINT (XCAR (elt));
|
29011
|
314 SPLIT_CHAR (*c, charset, c1, c2);
|
28223
|
315 elt = XCHAR_TABLE (fontset)->contents[charset + 128];
|
|
316 if (c1 < 32)
|
|
317 return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
|
|
318 if (!SUB_CHAR_TABLE_P (elt))
|
|
319 return Qnil;
|
|
320 elt = XCHAR_TABLE (elt)->contents[c1];
|
|
321 if (c2 < 32)
|
|
322 return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
|
|
323 if (!SUB_CHAR_TABLE_P (elt))
|
|
324 return Qnil;
|
|
325 elt = XCHAR_TABLE (elt)->contents[c2];
|
|
326 return elt;
|
|
327 }
|
|
328
|
|
329
|
30398
|
330 /* Store into the element of FONTSET at index C the value NEWELT. */
|
28223
|
331 #define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt)
|
|
332
|
|
333 static void
|
|
334 fontset_set (fontset, c, newelt)
|
|
335 Lisp_Object fontset;
|
|
336 int c;
|
|
337 Lisp_Object newelt;
|
17052
|
338 {
|
28223
|
339 int charset, code[3];
|
34975
|
340 Lisp_Object *elt;
|
|
341 int i;
|
28223
|
342
|
|
343 if (SINGLE_BYTE_CHAR_P (c))
|
|
344 {
|
|
345 FONTSET_ASCII (fontset) = newelt;
|
|
346 return;
|
|
347 }
|
|
348
|
29011
|
349 SPLIT_CHAR (c, charset, code[0], code[1]);
|
28223
|
350 code[2] = 0; /* anchor */
|
|
351 elt = &XCHAR_TABLE (fontset)->contents[charset + 128];
|
|
352 for (i = 0; code[i] > 0; i++)
|
|
353 {
|
|
354 if (!SUB_CHAR_TABLE_P (*elt))
|
|
355 *elt = make_sub_char_table (*elt);
|
|
356 elt = &XCHAR_TABLE (*elt)->contents[code[i]];
|
|
357 }
|
|
358 if (SUB_CHAR_TABLE_P (*elt))
|
|
359 XCHAR_TABLE (*elt)->defalt = newelt;
|
|
360 else
|
|
361 *elt = newelt;
|
|
362 }
|
|
363
|
|
364
|
|
365 /* Return a newly created fontset with NAME. If BASE is nil, make a
|
|
366 base fontset. Otherwise make a realized fontset whose parent is
|
|
367 BASE. */
|
|
368
|
|
369 static Lisp_Object
|
|
370 make_fontset (frame, name, base)
|
|
371 Lisp_Object frame, name, base;
|
|
372 {
|
34975
|
373 Lisp_Object fontset;
|
28223
|
374 int size = ASIZE (Vfontset_table);
|
|
375 int id = next_fontset_id;
|
|
376
|
|
377 /* Find a free slot in Vfontset_table. Usually, next_fontset_id is
|
|
378 the next available fontset ID. So it is expected that this loop
|
|
379 terminates quickly. In addition, as the last element of
|
41987
|
380 Vfontset_table is always nil, we don't have to check the range of
|
28223
|
381 id. */
|
|
382 while (!NILP (AREF (Vfontset_table, id))) id++;
|
|
383
|
|
384 if (id + 1 == size)
|
|
385 {
|
|
386 Lisp_Object tem;
|
41987
|
387 int i;
|
28223
|
388
|
|
389 tem = Fmake_vector (make_number (size + 8), Qnil);
|
|
390 for (i = 0; i < size; i++)
|
|
391 AREF (tem, i) = AREF (Vfontset_table, i);
|
|
392 Vfontset_table = tem;
|
|
393 }
|
|
394
|
29767
|
395 fontset = Fmake_char_table (Qfontset, Qnil);
|
28223
|
396
|
|
397 FONTSET_ID (fontset) = make_number (id);
|
|
398 FONTSET_NAME (fontset) = name;
|
|
399 FONTSET_FRAME (fontset) = frame;
|
|
400 FONTSET_BASE (fontset) = base;
|
17052
|
401
|
28223
|
402 AREF (Vfontset_table, id) = fontset;
|
|
403 next_fontset_id = id + 1;
|
|
404 return fontset;
|
|
405 }
|
|
406
|
|
407
|
|
408 /* Return 1 if ID is a valid fontset id, else return 0. */
|
|
409
|
|
410 static INLINE int
|
|
411 fontset_id_valid_p (id)
|
|
412 int id;
|
|
413 {
|
|
414 return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
|
|
415 }
|
|
416
|
|
417
|
35658
|
418 /* Extract `family' and `registry' string from FONTNAME and a cons of
|
|
419 them. Actually, `family' may also contain `foundry', `registry'
|
|
420 may also contain `encoding' of FONTNAME. But, if FONTNAME doesn't
|
|
421 conform to XLFD nor explicitely specifies the other fields
|
|
422 (i.e. not using wildcard `*'), return FONTNAME. If FORCE is
|
|
423 nonzero, specifications of the other fields are ignored, and return
|
|
424 a cons as far as FONTNAME conform to XLFD. */
|
28223
|
425
|
|
426 static Lisp_Object
|
35658
|
427 font_family_registry (fontname, force)
|
28223
|
428 Lisp_Object fontname;
|
35658
|
429 int force;
|
28223
|
430 {
|
|
431 Lisp_Object family, registry;
|
46466
|
432 const char *p = SDATA (fontname);
|
|
433 const char *sep[15];
|
28223
|
434 int i = 0;
|
41987
|
435
|
35658
|
436 while (*p && i < 15)
|
|
437 if (*p++ == '-')
|
|
438 {
|
|
439 if (!force && i >= 2 && i <= 11 && *p != '*' && p[1] != '-')
|
|
440 return fontname;
|
|
441 sep[i++] = p;
|
|
442 }
|
28223
|
443 if (i != 14)
|
|
444 return fontname;
|
17052
|
445
|
28223
|
446 family = make_unibyte_string (sep[0], sep[2] - 1 - sep[0]);
|
|
447 registry = make_unibyte_string (sep[12], p - sep[12]);
|
|
448 return Fcons (family, registry);
|
17052
|
449 }
|
|
450
|
28223
|
451
|
41987
|
452 /********** INTERFACES TO xfaces.c and dispextern.h **********/
|
28223
|
453
|
|
454 /* Return name of the fontset with ID. */
|
|
455
|
|
456 Lisp_Object
|
|
457 fontset_name (id)
|
|
458 int id;
|
|
459 {
|
|
460 Lisp_Object fontset;
|
|
461 fontset = FONTSET_FROM_ID (id);
|
|
462 return FONTSET_NAME (fontset);
|
|
463 }
|
|
464
|
|
465
|
|
466 /* Return ASCII font name of the fontset with ID. */
|
|
467
|
|
468 Lisp_Object
|
|
469 fontset_ascii (id)
|
|
470 int id;
|
|
471 {
|
|
472 Lisp_Object fontset, elt;
|
|
473 fontset= FONTSET_FROM_ID (id);
|
|
474 elt = FONTSET_ASCII (fontset);
|
|
475 return XCDR (elt);
|
|
476 }
|
|
477
|
|
478
|
|
479 /* Free fontset of FACE. Called from free_realized_face. */
|
|
480
|
17052
|
481 void
|
28223
|
482 free_face_fontset (f, face)
|
|
483 FRAME_PTR f;
|
|
484 struct face *face;
|
17052
|
485 {
|
28223
|
486 if (fontset_id_valid_p (face->fontset))
|
17052
|
487 {
|
28223
|
488 AREF (Vfontset_table, face->fontset) = Qnil;
|
|
489 if (face->fontset < next_fontset_id)
|
|
490 next_fontset_id = face->fontset;
|
|
491 }
|
|
492 }
|
|
493
|
|
494
|
|
495 /* Return 1 iff FACE is suitable for displaying character C.
|
|
496 Otherwise return 0. Called from the macro FACE_SUITABLE_FOR_CHAR_P
|
|
497 when C is not a single byte character.. */
|
|
498
|
|
499 int
|
|
500 face_suitable_for_char_p (face, c)
|
|
501 struct face *face;
|
|
502 int c;
|
|
503 {
|
|
504 Lisp_Object fontset, elt;
|
|
505
|
|
506 if (SINGLE_BYTE_CHAR_P (c))
|
|
507 return (face == face->ascii_face);
|
|
508
|
|
509 xassert (fontset_id_valid_p (face->fontset));
|
|
510 fontset = FONTSET_FROM_ID (face->fontset);
|
|
511 xassert (!BASE_FONTSET_P (fontset));
|
17052
|
512
|
28223
|
513 elt = FONTSET_REF_VIA_BASE (fontset, c);
|
|
514 return (!NILP (elt) && face->id == XFASTINT (elt));
|
|
515 }
|
|
516
|
|
517
|
|
518 /* Return ID of face suitable for displaying character C on frame F.
|
|
519 The selection of face is done based on the fontset of FACE. FACE
|
|
520 should already have been realized for ASCII characters. Called
|
|
521 from the macro FACE_FOR_CHAR when C is not a single byte character. */
|
17052
|
522
|
28223
|
523 int
|
|
524 face_for_char (f, face, c)
|
|
525 FRAME_PTR f;
|
|
526 struct face *face;
|
|
527 int c;
|
|
528 {
|
|
529 Lisp_Object fontset, elt;
|
|
530 int face_id;
|
|
531
|
|
532 xassert (fontset_id_valid_p (face->fontset));
|
|
533 fontset = FONTSET_FROM_ID (face->fontset);
|
|
534 xassert (!BASE_FONTSET_P (fontset));
|
|
535
|
|
536 elt = FONTSET_REF_VIA_BASE (fontset, c);
|
|
537 if (!NILP (elt))
|
|
538 return XINT (elt);
|
|
539
|
|
540 /* No face is recorded for C in the fontset of FACE. Make a new
|
|
541 realized face for C that has the same fontset. */
|
|
542 face_id = lookup_face (f, face->lface, c, face);
|
41987
|
543
|
28223
|
544 /* Record the face ID in FONTSET at the same index as the
|
|
545 information in the base fontset. */
|
|
546 FONTSET_SET (fontset, c, make_number (face_id));
|
|
547 return face_id;
|
17052
|
548 }
|
|
549
|
28223
|
550
|
|
551 /* Make a realized fontset for ASCII face FACE on frame F from the
|
|
552 base fontset BASE_FONTSET_ID. If BASE_FONTSET_ID is -1, use the
|
|
553 default fontset as the base. Value is the id of the new fontset.
|
|
554 Called from realize_x_face. */
|
|
555
|
|
556 int
|
|
557 make_fontset_for_ascii_face (f, base_fontset_id)
|
|
558 FRAME_PTR f;
|
|
559 int base_fontset_id;
|
|
560 {
|
34975
|
561 Lisp_Object base_fontset, fontset, frame;
|
28223
|
562
|
|
563 XSETFRAME (frame, f);
|
|
564 if (base_fontset_id >= 0)
|
|
565 {
|
|
566 base_fontset = FONTSET_FROM_ID (base_fontset_id);
|
|
567 if (!BASE_FONTSET_P (base_fontset))
|
|
568 base_fontset = FONTSET_BASE (base_fontset);
|
|
569 xassert (BASE_FONTSET_P (base_fontset));
|
|
570 }
|
|
571 else
|
|
572 base_fontset = Vdefault_fontset;
|
|
573
|
|
574 fontset = make_fontset (frame, Qnil, base_fontset);
|
28511
|
575 return XINT (FONTSET_ID (fontset));
|
28223
|
576 }
|
|
577
|
|
578
|
|
579 /* Return the font name pattern for C that is recorded in the fontset
|
35658
|
580 with ID. If a font name pattern is specified (instead of a cons of
|
|
581 family and registry), check if a font can be opened by that pattern
|
|
582 to get the fullname. If a font is opened, return that name.
|
|
583 Otherwise, return nil. If ID is -1, or the fontset doesn't contain
|
28223
|
584 information about C, get the registry and encoding of C from the
|
|
585 default fontset. Called from choose_face_font. */
|
18346
|
586
|
28223
|
587 Lisp_Object
|
|
588 fontset_font_pattern (f, id, c)
|
|
589 FRAME_PTR f;
|
|
590 int id, c;
|
|
591 {
|
|
592 Lisp_Object fontset, elt;
|
|
593 struct font_info *fontp;
|
41987
|
594
|
28223
|
595 elt = Qnil;
|
|
596 if (fontset_id_valid_p (id))
|
|
597 {
|
|
598 fontset = FONTSET_FROM_ID (id);
|
|
599 xassert (!BASE_FONTSET_P (fontset));
|
|
600 fontset = FONTSET_BASE (fontset);
|
53622
|
601 if (! EQ (fontset, Vdefault_fontset))
|
|
602 elt = FONTSET_REF (fontset, c);
|
28223
|
603 }
|
29767
|
604 if (NILP (elt))
|
53353
|
605 {
|
|
606 Lisp_Object frame;
|
|
607
|
|
608 XSETFRAME (frame, f);
|
|
609 elt = lookup_overriding_fontspec (frame, c);
|
|
610 }
|
|
611 if (NILP (elt))
|
28223
|
612 elt = FONTSET_REF (Vdefault_fontset, c);
|
|
613
|
|
614 if (!CONSP (elt))
|
|
615 return Qnil;
|
|
616 if (CONSP (XCDR (elt)))
|
|
617 return XCDR (elt);
|
|
618
|
|
619 /* The fontset specifies only a font name pattern (not cons of
|
35658
|
620 family and registry). If a font can be opened by that pattern,
|
|
621 return the name of opened font. Otherwise return nil. The
|
|
622 exception is a font for single byte characters. In that case, we
|
|
623 return a cons of FAMILY and REGISTRY extracted from the opened
|
|
624 font name. */
|
28223
|
625 elt = XCDR (elt);
|
|
626 xassert (STRINGP (elt));
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
627 fontp = FS_LOAD_FONT (f, c, SDATA (elt), -1);
|
28223
|
628 if (!fontp)
|
|
629 return Qnil;
|
|
630
|
35658
|
631 return font_family_registry (build_string (fontp->full_name),
|
|
632 SINGLE_BYTE_CHAR_P (c));
|
28223
|
633 }
|
|
634
|
|
635
|
40028
|
636 #if defined(WINDOWSNT) && defined (_MSC_VER)
|
|
637 #pragma optimize("", off)
|
|
638 #endif
|
|
639
|
28223
|
640 /* Load a font named FONTNAME to display character C on frame F.
|
|
641 Return a pointer to the struct font_info of the loaded font. If
|
|
642 loading fails, return NULL. If FACE is non-zero and a fontset is
|
|
643 assigned to it, record FACE->id in the fontset for C. If FONTNAME
|
|
644 is NULL, the name is taken from the fontset of FACE or what
|
|
645 specified by ID. */
|
17052
|
646
|
|
647 struct font_info *
|
28223
|
648 fs_load_font (f, c, fontname, id, face)
|
17052
|
649 FRAME_PTR f;
|
28223
|
650 int c;
|
17052
|
651 char *fontname;
|
28223
|
652 int id;
|
|
653 struct face *face;
|
17052
|
654 {
|
28223
|
655 Lisp_Object fontset;
|
17052
|
656 Lisp_Object list, elt;
|
|
657 int size = 0;
|
|
658 struct font_info *fontp;
|
28223
|
659 int charset = CHAR_CHARSET (c);
|
17052
|
660
|
28223
|
661 if (face)
|
|
662 id = face->fontset;
|
|
663 if (id < 0)
|
|
664 fontset = Qnil;
|
|
665 else
|
|
666 fontset = FONTSET_FROM_ID (id);
|
|
667
|
|
668 if (!NILP (fontset)
|
|
669 && !BASE_FONTSET_P (fontset))
|
17052
|
670 {
|
28223
|
671 elt = FONTSET_REF_VIA_BASE (fontset, c);
|
|
672 if (!NILP (elt))
|
|
673 {
|
|
674 /* A suitable face for C is already recorded, which means
|
|
675 that a proper font is already loaded. */
|
|
676 int face_id = XINT (elt);
|
|
677
|
|
678 xassert (face_id == face->id);
|
|
679 face = FACE_FROM_ID (f, face_id);
|
|
680 return (*get_font_info_func) (f, face->font_info_id);
|
|
681 }
|
|
682
|
|
683 if (!fontname && charset == CHARSET_ASCII)
|
|
684 {
|
|
685 elt = FONTSET_ASCII (fontset);
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
686 fontname = SDATA (XCDR (elt));
|
28223
|
687 }
|
17052
|
688 }
|
|
689
|
|
690 if (!fontname)
|
|
691 /* No way to get fontname. */
|
|
692 return 0;
|
|
693
|
28223
|
694 fontp = (*load_font_func) (f, fontname, size);
|
|
695 if (!fontp)
|
|
696 return 0;
|
17052
|
697
|
28223
|
698 /* Fill in members (charset, vertical_centering, encoding, etc) of
|
|
699 font_info structure that are not set by (*load_font_func). */
|
17052
|
700 fontp->charset = charset;
|
|
701
|
26858
|
702 fontp->vertical_centering
|
|
703 = (STRINGP (Vvertical_centering_font_regexp)
|
41987
|
704 && (fast_c_string_match_ignore_case
|
26858
|
705 (Vvertical_centering_font_regexp, fontp->full_name) >= 0));
|
|
706
|
17999
|
707 if (fontp->encoding[1] != FONT_ENCODING_NOT_DECIDED)
|
17052
|
708 {
|
|
709 /* The font itself tells which code points to be used. Use this
|
|
710 encoding for all other charsets. */
|
|
711 int i;
|
|
712
|
|
713 fontp->encoding[0] = fontp->encoding[1];
|
17190
|
714 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
|
17052
|
715 fontp->encoding[i] = fontp->encoding[1];
|
|
716 }
|
|
717 else
|
|
718 {
|
28223
|
719 /* The font itself doesn't have information about encoding. */
|
17052
|
720 int i;
|
|
721
|
28766
|
722 fontname = fontp->full_name;
|
|
723 /* By default, encoding of ASCII chars is 0 (i.e. 0x00..0x7F),
|
|
724 others is 1 (i.e. 0x80..0xFF). */
|
|
725 fontp->encoding[0] = 0;
|
17190
|
726 for (i = MIN_CHARSET_OFFICIAL_DIMENSION1; i <= MAX_CHARSET; i++)
|
17052
|
727 fontp->encoding[i] = 1;
|
|
728 /* Then override them by a specification in Vfont_encoding_alist. */
|
26164
|
729 for (list = Vfont_encoding_alist; CONSP (list); list = XCDR (list))
|
17052
|
730 {
|
26164
|
731 elt = XCAR (list);
|
17052
|
732 if (CONSP (elt)
|
26164
|
733 && STRINGP (XCAR (elt)) && CONSP (XCDR (elt))
|
|
734 && (fast_c_string_match_ignore_case (XCAR (elt), fontname)
|
17052
|
735 >= 0))
|
|
736 {
|
|
737 Lisp_Object tmp;
|
|
738
|
26164
|
739 for (tmp = XCDR (elt); CONSP (tmp); tmp = XCDR (tmp))
|
|
740 if (CONSP (XCAR (tmp))
|
|
741 && ((i = get_charset_id (XCAR (XCAR (tmp))))
|
17052
|
742 >= 0)
|
26164
|
743 && INTEGERP (XCDR (XCAR (tmp)))
|
|
744 && XFASTINT (XCDR (XCAR (tmp))) < 4)
|
17052
|
745 fontp->encoding[i]
|
26164
|
746 = XFASTINT (XCDR (XCAR (tmp)));
|
17052
|
747 }
|
|
748 }
|
|
749 }
|
|
750
|
52729
|
751 if (! fontp->font_encoder && find_ccl_program_func)
|
21553
|
752 (*find_ccl_program_func) (fontp);
|
17052
|
753
|
28963
|
754 /* If we loaded a font for a face that has fontset, record the face
|
|
755 ID in the fontset for C. */
|
|
756 if (face
|
|
757 && !NILP (fontset)
|
|
758 && !BASE_FONTSET_P (fontset))
|
|
759 FONTSET_SET (fontset, c, make_number (face->id));
|
17052
|
760 return fontp;
|
|
761 }
|
|
762
|
40028
|
763 #if defined(WINDOWSNT) && defined (_MSC_VER)
|
|
764 #pragma optimize("", on)
|
|
765 #endif
|
|
766
|
28223
|
767
|
17052
|
768 /* Cache data used by fontset_pattern_regexp. The car part is a
|
|
769 pattern string containing at least one wild card, the cdr part is
|
|
770 the corresponding regular expression. */
|
|
771 static Lisp_Object Vcached_fontset_data;
|
|
772
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
773 #define CACHED_FONTSET_NAME (SDATA (XCAR (Vcached_fontset_data)))
|
26164
|
774 #define CACHED_FONTSET_REGEX (XCDR (Vcached_fontset_data))
|
17052
|
775
|
|
776 /* If fontset name PATTERN contains any wild card, return regular
|
|
777 expression corresponding to PATTERN. */
|
|
778
|
28223
|
779 static Lisp_Object
|
17052
|
780 fontset_pattern_regexp (pattern)
|
|
781 Lisp_Object pattern;
|
|
782 {
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
783 if (!index (SDATA (pattern), '*')
|
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
784 && !index (SDATA (pattern), '?'))
|
17052
|
785 /* PATTERN does not contain any wild cards. */
|
17730
|
786 return Qnil;
|
17052
|
787
|
|
788 if (!CONSP (Vcached_fontset_data)
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
789 || strcmp (SDATA (pattern), CACHED_FONTSET_NAME))
|
17052
|
790 {
|
|
791 /* We must at first update the cached data. */
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
792 char *regex = (char *) alloca (SCHARS (pattern) * 2 + 3);
|
17052
|
793 char *p0, *p1 = regex;
|
|
794
|
17730
|
795 /* Convert "*" to ".*", "?" to ".". */
|
|
796 *p1++ = '^';
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
797 for (p0 = (char *) SDATA (pattern); *p0; p0++)
|
17052
|
798 {
|
17730
|
799 if (*p0 == '*')
|
17052
|
800 {
|
17730
|
801 *p1++ = '.';
|
|
802 *p1++ = '*';
|
17052
|
803 }
|
17730
|
804 else if (*p0 == '?')
|
21127
|
805 *p1++ = '.';
|
17730
|
806 else
|
|
807 *p1++ = *p0;
|
17052
|
808 }
|
|
809 *p1++ = '$';
|
|
810 *p1++ = 0;
|
|
811
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
812 Vcached_fontset_data = Fcons (build_string (SDATA (pattern)),
|
17052
|
813 build_string (regex));
|
|
814 }
|
|
815
|
|
816 return CACHED_FONTSET_REGEX;
|
|
817 }
|
|
818
|
28223
|
819 /* Return ID of the base fontset named NAME. If there's no such
|
|
820 fontset, return -1. */
|
|
821
|
|
822 int
|
|
823 fs_query_fontset (name, regexpp)
|
|
824 Lisp_Object name;
|
|
825 int regexpp;
|
|
826 {
|
34975
|
827 Lisp_Object tem;
|
28223
|
828 int i;
|
|
829
|
|
830 name = Fdowncase (name);
|
|
831 if (!regexpp)
|
|
832 {
|
|
833 tem = Frassoc (name, Vfontset_alias_alist);
|
|
834 if (CONSP (tem) && STRINGP (XCAR (tem)))
|
|
835 name = XCAR (tem);
|
|
836 else
|
|
837 {
|
|
838 tem = fontset_pattern_regexp (name);
|
|
839 if (STRINGP (tem))
|
|
840 {
|
|
841 name = tem;
|
|
842 regexpp = 1;
|
|
843 }
|
|
844 }
|
|
845 }
|
|
846
|
|
847 for (i = 0; i < ASIZE (Vfontset_table); i++)
|
|
848 {
|
|
849 Lisp_Object fontset;
|
46466
|
850 const unsigned char *this_name;
|
28223
|
851
|
|
852 fontset = FONTSET_FROM_ID (i);
|
|
853 if (NILP (fontset)
|
|
854 || !BASE_FONTSET_P (fontset))
|
|
855 continue;
|
|
856
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
857 this_name = SDATA (FONTSET_NAME (fontset));
|
28223
|
858 if (regexpp
|
|
859 ? fast_c_string_match_ignore_case (name, this_name) >= 0
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
860 : !strcmp (SDATA (name), this_name))
|
28223
|
861 return i;
|
|
862 }
|
|
863 return -1;
|
|
864 }
|
|
865
|
|
866
|
21553
|
867 DEFUN ("query-fontset", Fquery_fontset, Squery_fontset, 1, 2, 0,
|
41001
|
868 doc: /* Return the name of a fontset that matches PATTERN.
|
|
869 The value is nil if there is no matching fontset.
|
|
870 PATTERN can contain `*' or `?' as a wildcard
|
|
871 just as X font name matching algorithm allows.
|
|
872 If REGEXPP is non-nil, PATTERN is a regular expression. */)
|
|
873 (pattern, regexpp)
|
21553
|
874 Lisp_Object pattern, regexpp;
|
17052
|
875 {
|
28223
|
876 Lisp_Object fontset;
|
|
877 int id;
|
17052
|
878
|
|
879 (*check_window_system_func) ();
|
|
880
|
40656
|
881 CHECK_STRING (pattern);
|
17052
|
882
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
883 if (SCHARS (pattern) == 0)
|
17052
|
884 return Qnil;
|
|
885
|
28223
|
886 id = fs_query_fontset (pattern, !NILP (regexpp));
|
|
887 if (id < 0)
|
|
888 return Qnil;
|
17052
|
889
|
28223
|
890 fontset = FONTSET_FROM_ID (id);
|
|
891 return FONTSET_NAME (fontset);
|
17052
|
892 }
|
|
893
|
28223
|
894 /* Return a list of base fontset names matching PATTERN on frame F.
|
|
895 If SIZE is not 0, it is the size (maximum bound width) of fontsets
|
41987
|
896 to be listed. */
|
17052
|
897
|
|
898 Lisp_Object
|
|
899 list_fontsets (f, pattern, size)
|
|
900 FRAME_PTR f;
|
|
901 Lisp_Object pattern;
|
|
902 int size;
|
|
903 {
|
34975
|
904 Lisp_Object frame, regexp, val;
|
28223
|
905 int id;
|
|
906
|
|
907 XSETFRAME (frame, f);
|
17052
|
908
|
|
909 regexp = fontset_pattern_regexp (pattern);
|
28223
|
910 val = Qnil;
|
17052
|
911
|
28223
|
912 for (id = 0; id < ASIZE (Vfontset_table); id++)
|
17052
|
913 {
|
28223
|
914 Lisp_Object fontset;
|
46466
|
915 const unsigned char *name;
|
17052
|
916
|
28223
|
917 fontset = FONTSET_FROM_ID (id);
|
|
918 if (NILP (fontset)
|
|
919 || !BASE_FONTSET_P (fontset)
|
|
920 || !EQ (frame, FONTSET_FRAME (fontset)))
|
|
921 continue;
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
922 name = SDATA (FONTSET_NAME (fontset));
|
17052
|
923
|
28223
|
924 if (!NILP (regexp)
|
|
925 ? (fast_c_string_match_ignore_case (regexp, name) < 0)
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
926 : strcmp (SDATA (pattern), name))
|
28223
|
927 continue;
|
|
928
|
|
929 if (size)
|
17052
|
930 {
|
28223
|
931 struct font_info *fontp;
|
|
932 fontp = FS_LOAD_FONT (f, 0, NULL, id);
|
|
933 if (!fontp || size != fontp->size)
|
|
934 continue;
|
17052
|
935 }
|
28223
|
936 val = Fcons (Fcopy_sequence (FONTSET_NAME (fontset)), val);
|
17052
|
937 }
|
|
938
|
|
939 return val;
|
|
940 }
|
|
941
|
|
942 DEFUN ("new-fontset", Fnew_fontset, Snew_fontset, 2, 2, 0,
|
41001
|
943 doc: /* Create a new fontset NAME that contains font information in FONTLIST.
|
|
944 FONTLIST is an alist of charsets vs corresponding font name patterns. */)
|
|
945 (name, fontlist)
|
17052
|
946 Lisp_Object name, fontlist;
|
|
947 {
|
28223
|
948 Lisp_Object fontset, elements, ascii_font;
|
|
949 Lisp_Object tem, tail, elt;
|
17052
|
950
|
|
951 (*check_window_system_func) ();
|
|
952
|
40656
|
953 CHECK_STRING (name);
|
|
954 CHECK_LIST (fontlist);
|
17052
|
955
|
28223
|
956 name = Fdowncase (name);
|
|
957 tem = Fquery_fontset (name, Qnil);
|
|
958 if (!NILP (tem))
|
24585
|
959 error ("Fontset `%s' matches the existing fontset `%s'",
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
960 SDATA (name), SDATA (tem));
|
17052
|
961
|
28223
|
962 /* Check the validity of FONTLIST while creating a template for
|
|
963 fontset elements. */
|
|
964 elements = ascii_font = Qnil;
|
26164
|
965 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
|
17052
|
966 {
|
28223
|
967 int c, charset;
|
17052
|
968
|
28223
|
969 tem = XCAR (tail);
|
17052
|
970 if (!CONSP (tem)
|
26164
|
971 || (charset = get_charset_id (XCAR (tem))) < 0
|
36370
|
972 || (!STRINGP (XCDR (tem)) && !CONSP (XCDR (tem))))
|
|
973 error ("Elements of fontlist must be a cons of charset and font name pattern");
|
28223
|
974
|
36370
|
975 tem = XCDR (tem);
|
|
976 if (STRINGP (tem))
|
|
977 tem = Fdowncase (tem);
|
|
978 else
|
|
979 tem = Fcons (Fdowncase (Fcar (tem)), Fdowncase (Fcdr (tem)));
|
28223
|
980 if (charset == CHARSET_ASCII)
|
|
981 ascii_font = tem;
|
|
982 else
|
|
983 {
|
|
984 c = MAKE_CHAR (charset, 0, 0);
|
|
985 elements = Fcons (Fcons (make_number (c), tem), elements);
|
|
986 }
|
17052
|
987 }
|
|
988
|
28223
|
989 if (NILP (ascii_font))
|
|
990 error ("No ASCII font in the fontlist");
|
17052
|
991
|
28223
|
992 fontset = make_fontset (Qnil, name, Qnil);
|
|
993 FONTSET_ASCII (fontset) = Fcons (make_number (0), ascii_font);
|
|
994 for (; CONSP (elements); elements = XCDR (elements))
|
|
995 {
|
|
996 elt = XCAR (elements);
|
36370
|
997 tem = XCDR (elt);
|
|
998 if (STRINGP (tem))
|
|
999 tem = font_family_registry (tem, 0);
|
|
1000 tem = Fcons (XCAR (elt), tem);
|
28223
|
1001 FONTSET_SET (fontset, XINT (XCAR (elt)), tem);
|
|
1002 }
|
17052
|
1003
|
|
1004 return Qnil;
|
|
1005 }
|
|
1006
|
28223
|
1007
|
|
1008 /* Clear all elements of FONTSET for multibyte characters. */
|
|
1009
|
|
1010 static void
|
|
1011 clear_fontset_elements (fontset)
|
|
1012 Lisp_Object fontset;
|
|
1013 {
|
|
1014 int i;
|
|
1015
|
|
1016 for (i = CHAR_TABLE_SINGLE_BYTE_SLOTS; i < CHAR_TABLE_ORDINARY_SLOTS; i++)
|
|
1017 XCHAR_TABLE (fontset)->contents[i] = Qnil;
|
|
1018 }
|
|
1019
|
|
1020
|
|
1021 /* Check validity of NAME as a fontset name and return the
|
|
1022 corresponding fontset. If not valid, signal an error.
|
49874
|
1023 If NAME is nil, return Vdefault_fontset. */
|
28223
|
1024
|
|
1025 static Lisp_Object
|
|
1026 check_fontset_name (name)
|
|
1027 Lisp_Object name;
|
|
1028 {
|
|
1029 int id;
|
|
1030
|
49874
|
1031 if (EQ (name, Qnil))
|
28223
|
1032 return Vdefault_fontset;
|
|
1033
|
40656
|
1034 CHECK_STRING (name);
|
28223
|
1035 id = fs_query_fontset (name, 0);
|
|
1036 if (id < 0)
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
1037 error ("Fontset `%s' does not exist", SDATA (name));
|
28223
|
1038 return FONTSET_FROM_ID (id);
|
|
1039 }
|
17052
|
1040
|
53353
|
1041 /* Downcase FONTNAME or car and cdr of FONTNAME. If FONTNAME is a
|
|
1042 string, maybe change FONTNAME to (FAMILY . REGISTRY). */
|
|
1043
|
|
1044 static Lisp_Object
|
54995
|
1045 regularize_fontname (Lisp_Object fontname)
|
53353
|
1046 {
|
|
1047 Lisp_Object family, registry;
|
|
1048
|
|
1049 if (STRINGP (fontname))
|
|
1050 return font_family_registry (Fdowncase (fontname), 0);
|
|
1051
|
|
1052 CHECK_CONS (fontname);
|
|
1053 family = XCAR (fontname);
|
|
1054 registry = XCDR (fontname);
|
|
1055 if (!NILP (family))
|
|
1056 {
|
|
1057 CHECK_STRING (family);
|
|
1058 family = Fdowncase (family);
|
|
1059 }
|
|
1060 if (!NILP (registry))
|
|
1061 {
|
|
1062 CHECK_STRING (registry);
|
|
1063 registry = Fdowncase (registry);
|
|
1064 }
|
|
1065 return Fcons (family, registry);
|
|
1066 }
|
|
1067
|
49884
|
1068 DEFUN ("set-fontset-font", Fset_fontset_font, Sset_fontset_font, 3, 4, 0,
|
41001
|
1069 doc: /* Modify fontset NAME to use FONTNAME for CHARACTER.
|
|
1070
|
49881
|
1071 If NAME is nil, modify the default fontset.
|
41001
|
1072 CHARACTER may be a cons; (FROM . TO), where FROM and TO are
|
|
1073 non-generic characters. In that case, use FONTNAME
|
|
1074 for all characters in the range FROM and TO (inclusive).
|
47277
|
1075 CHARACTER may be a charset. In that case, use FONTNAME
|
41001
|
1076 for all character in the charsets.
|
|
1077
|
|
1078 FONTNAME may be a cons; (FAMILY . REGISTRY), where FAMILY is a family
|
41987
|
1079 name of a font, REGISTRY is a registry name of a font. */)
|
41001
|
1080 (name, character, fontname, frame)
|
28676
|
1081 Lisp_Object name, character, fontname, frame;
|
17052
|
1082 {
|
28223
|
1083 Lisp_Object fontset, elt;
|
|
1084 Lisp_Object realized;
|
|
1085 int from, to;
|
|
1086 int id;
|
29233
|
1087 Lisp_Object family, registry;
|
28223
|
1088
|
|
1089 fontset = check_fontset_name (name);
|
17052
|
1090
|
28676
|
1091 if (CONSP (character))
|
28223
|
1092 {
|
|
1093 /* CH should be (FROM . TO) where FROM and TO are non-generic
|
|
1094 characters. */
|
40656
|
1095 CHECK_NUMBER_CAR (character);
|
|
1096 CHECK_NUMBER_CDR (character);
|
28676
|
1097 from = XINT (XCAR (character));
|
|
1098 to = XINT (XCDR (character));
|
28223
|
1099 if (!char_valid_p (from, 0) || !char_valid_p (to, 0))
|
53072
|
1100 error ("Character range should be by non-generic characters");
|
28223
|
1101 if (!NILP (name)
|
|
1102 && (SINGLE_BYTE_CHAR_P (from) || SINGLE_BYTE_CHAR_P (to)))
|
|
1103 error ("Can't change font for a single byte character");
|
|
1104 }
|
29501
|
1105 else if (SYMBOLP (character))
|
|
1106 {
|
|
1107 elt = Fget (character, Qcharset);
|
|
1108 if (!VECTORP (elt) || ASIZE (elt) < 1 || !NATNUMP (AREF (elt, 0)))
|
46440
|
1109 error ("Invalid charset: %s", SDATA (SYMBOL_NAME (character)));
|
29501
|
1110 from = MAKE_CHAR (XINT (AREF (elt, 0)), 0, 0);
|
|
1111 to = from;
|
|
1112 }
|
28223
|
1113 else
|
|
1114 {
|
40656
|
1115 CHECK_NUMBER (character);
|
28676
|
1116 from = XINT (character);
|
28223
|
1117 to = from;
|
|
1118 }
|
|
1119 if (!char_valid_p (from, 1))
|
|
1120 invalid_character (from);
|
|
1121 if (SINGLE_BYTE_CHAR_P (from))
|
|
1122 error ("Can't change font for a single byte character");
|
|
1123 if (from < to)
|
|
1124 {
|
|
1125 if (!char_valid_p (to, 1))
|
|
1126 invalid_character (to);
|
|
1127 if (SINGLE_BYTE_CHAR_P (to))
|
|
1128 error ("Can't change font for a single byte character");
|
|
1129 }
|
17052
|
1130
|
28223
|
1131 /* The arg FRAME is kept for backward compatibility. We only check
|
|
1132 the validity. */
|
17052
|
1133 if (!NILP (frame))
|
40656
|
1134 CHECK_LIVE_FRAME (frame);
|
17052
|
1135
|
54995
|
1136 elt = Fcons (make_number (from), regularize_fontname (fontname));
|
28223
|
1137 for (; from <= to; from++)
|
|
1138 FONTSET_SET (fontset, from, elt);
|
|
1139 Foptimize_char_table (fontset);
|
17052
|
1140
|
28223
|
1141 /* If there's a realized fontset REALIZED whose parent is FONTSET,
|
|
1142 clear all the elements of REALIZED and free all multibyte faces
|
|
1143 whose fontset is REALIZED. This way, the specified character(s)
|
|
1144 are surely redisplayed by a correct font. */
|
|
1145 for (id = 0; id < ASIZE (Vfontset_table); id++)
|
|
1146 {
|
|
1147 realized = AREF (Vfontset_table, id);
|
|
1148 if (!NILP (realized)
|
|
1149 && !BASE_FONTSET_P (realized)
|
|
1150 && EQ (FONTSET_BASE (realized), fontset))
|
17052
|
1151 {
|
28223
|
1152 FRAME_PTR f = XFRAME (FONTSET_FRAME (realized));
|
|
1153 clear_fontset_elements (realized);
|
|
1154 free_realized_multibyte_face (f, id);
|
17052
|
1155 }
|
28223
|
1156 }
|
17052
|
1157
|
|
1158 return Qnil;
|
|
1159 }
|
|
1160
|
|
1161 DEFUN ("font-info", Ffont_info, Sfont_info, 1, 2, 0,
|
41001
|
1162 doc: /* Return information about a font named NAME on frame FRAME.
|
|
1163 If FRAME is omitted or nil, use the selected frame.
|
|
1164 The returned value is a vector of OPENED-NAME, FULL-NAME, CHARSET, SIZE,
|
|
1165 HEIGHT, BASELINE-OFFSET, RELATIVE-COMPOSE, and DEFAULT-ASCENT,
|
|
1166 where
|
|
1167 OPENED-NAME is the name used for opening the font,
|
|
1168 FULL-NAME is the full name of the font,
|
|
1169 SIZE is the maximum bound width of the font,
|
|
1170 HEIGHT is the height of the font,
|
|
1171 BASELINE-OFFSET is the upward offset pixels from ASCII baseline,
|
|
1172 RELATIVE-COMPOSE and DEFAULT-ASCENT are the numbers controlling
|
|
1173 how to compose characters.
|
|
1174 If the named font is not yet loaded, return nil. */)
|
|
1175 (name, frame)
|
17052
|
1176 Lisp_Object name, frame;
|
|
1177 {
|
|
1178 FRAME_PTR f;
|
|
1179 struct font_info *fontp;
|
|
1180 Lisp_Object info;
|
|
1181
|
|
1182 (*check_window_system_func) ();
|
|
1183
|
40656
|
1184 CHECK_STRING (name);
|
28223
|
1185 name = Fdowncase (name);
|
17052
|
1186 if (NILP (frame))
|
25668
|
1187 frame = selected_frame;
|
40656
|
1188 CHECK_LIVE_FRAME (frame);
|
25668
|
1189 f = XFRAME (frame);
|
17052
|
1190
|
|
1191 if (!query_font_func)
|
|
1192 error ("Font query function is not supported");
|
|
1193
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
1194 fontp = (*query_font_func) (f, SDATA (name));
|
17052
|
1195 if (!fontp)
|
|
1196 return Qnil;
|
|
1197
|
28223
|
1198 info = Fmake_vector (make_number (7), Qnil);
|
17052
|
1199
|
|
1200 XVECTOR (info)->contents[0] = build_string (fontp->name);
|
|
1201 XVECTOR (info)->contents[1] = build_string (fontp->full_name);
|
28223
|
1202 XVECTOR (info)->contents[2] = make_number (fontp->size);
|
|
1203 XVECTOR (info)->contents[3] = make_number (fontp->height);
|
|
1204 XVECTOR (info)->contents[4] = make_number (fontp->baseline_offset);
|
|
1205 XVECTOR (info)->contents[5] = make_number (fontp->relative_compose);
|
|
1206 XVECTOR (info)->contents[6] = make_number (fontp->default_ascent);
|
17052
|
1207
|
|
1208 return info;
|
|
1209 }
|
|
1210
|
28963
|
1211
|
52654
|
1212 /* Return a cons (FONT-NAME . GLYPH-CODE).
|
|
1213 FONT-NAME is the font name for the character at POSITION in the current
|
28963
|
1214 buffer. This is computed from all the text properties and overlays
|
55094
|
1215 that apply to POSITION. POSTION may be nil, in which case,
|
|
1216 FONT-NAME is the font name for display the character CH with the
|
|
1217 default face.
|
|
1218
|
52654
|
1219 GLYPH-CODE is the glyph code in the font to use for the character.
|
|
1220
|
|
1221 If the 2nd optional arg CH is non-nil, it is a character to check
|
|
1222 the font instead of the character at POSITION.
|
|
1223
|
|
1224 It returns nil in the following cases:
|
28963
|
1225
|
|
1226 (1) The window system doesn't have a font for the character (thus
|
|
1227 it is displayed by an empty box).
|
|
1228
|
|
1229 (2) The character code is invalid.
|
|
1230
|
55094
|
1231 (3) If POSITION is not nil, and the current buffer is not displayed
|
|
1232 in any window.
|
28963
|
1233
|
|
1234 In addition, the returned font name may not take into account of
|
|
1235 such redisplay engine hooks as what used in jit-lock-mode if
|
|
1236 POSITION is currently not visible. */
|
|
1237
|
|
1238
|
52654
|
1239 DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0,
|
41001
|
1240 doc: /* For internal use only. */)
|
52654
|
1241 (position, ch)
|
|
1242 Lisp_Object position, ch;
|
28963
|
1243 {
|
|
1244 int pos, pos_byte, dummy;
|
|
1245 int face_id;
|
52654
|
1246 int c, code;
|
28963
|
1247 struct frame *f;
|
|
1248 struct face *face;
|
|
1249
|
55094
|
1250 if (NILP (position))
|
52654
|
1251 {
|
|
1252 CHECK_NATNUM (ch);
|
|
1253 c = XINT (ch);
|
55094
|
1254 f = XFRAME (selected_frame);
|
|
1255 face_id = DEFAULT_FACE_ID;
|
|
1256 }
|
|
1257 else
|
|
1258 {
|
|
1259 Lisp_Object window;
|
|
1260 struct window *w;
|
|
1261
|
|
1262 CHECK_NUMBER_COERCE_MARKER (position);
|
|
1263 pos = XINT (position);
|
|
1264 if (pos < BEGV || pos >= ZV)
|
|
1265 args_out_of_range_3 (position, make_number (BEGV), make_number (ZV));
|
|
1266 pos_byte = CHAR_TO_BYTE (pos);
|
|
1267 if (NILP (ch))
|
|
1268 c = FETCH_CHAR (pos_byte);
|
|
1269 else
|
|
1270 {
|
|
1271 CHECK_NATNUM (ch);
|
|
1272 c = XINT (ch);
|
|
1273 }
|
|
1274 window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
|
|
1275 if (NILP (window))
|
|
1276 return Qnil;
|
|
1277 w = XWINDOW (window);
|
|
1278 f = XFRAME (w->frame);
|
|
1279 face_id = face_at_buffer_position (w, pos, -1, -1, &dummy, pos + 100, 0);
|
52654
|
1280 }
|
28963
|
1281 if (! CHAR_VALID_P (c, 0))
|
|
1282 return Qnil;
|
|
1283 face_id = FACE_FOR_CHAR (f, FACE_FROM_ID (f, face_id), c);
|
|
1284 face = FACE_FROM_ID (f, face_id);
|
52654
|
1285 if (! face->font || ! face->font_name)
|
|
1286 return Qnil;
|
|
1287
|
|
1288 {
|
|
1289 struct font_info *fontp = (*get_font_info_func) (f, face->font_info_id);
|
|
1290 XChar2b char2b;
|
|
1291 int c1, c2, charset;
|
|
1292
|
|
1293 SPLIT_CHAR (c, charset, c1, c2);
|
|
1294 if (c2 > 0)
|
|
1295 STORE_XCHAR2B (&char2b, c1, c2);
|
|
1296 else
|
|
1297 STORE_XCHAR2B (&char2b, 0, c1);
|
|
1298 rif->encode_char (c, &char2b, fontp, NULL);
|
|
1299 code = (XCHAR2B_BYTE1 (&char2b) << 8) | XCHAR2B_BYTE2 (&char2b);
|
|
1300 }
|
|
1301 return Fcons (build_string (face->font_name), make_number (code));
|
28963
|
1302 }
|
|
1303
|
|
1304
|
|
1305 /* Called from Ffontset_info via map_char_table on each leaf of
|
49874
|
1306 fontset. ARG is a copy of the default fontset. The current leaf
|
|
1307 is indexed by CHARACTER and has value ELT. This function override
|
|
1308 the copy by ELT if ELT is not nil. */
|
|
1309
|
|
1310 static void
|
|
1311 override_font_info (fontset, character, elt)
|
|
1312 Lisp_Object fontset, character, elt;
|
|
1313 {
|
|
1314 if (! NILP (elt))
|
|
1315 Faset (fontset, character, elt);
|
|
1316 }
|
|
1317
|
|
1318 /* Called from Ffontset_info via map_char_table on each leaf of
|
28963
|
1319 fontset. ARG is a list (LAST FONT-INFO ...), where LAST is `(last
|
|
1320 ARG)' and FONT-INFOs have this form:
|
|
1321 (CHAR FONT-SPEC) or ((FROM . TO) FONT-SPEC)
|
|
1322 The current leaf is indexed by CHARACTER and has value ELT. This
|
|
1323 function add the information of the current leaf to ARG by
|
49874
|
1324 appending a new element or modifying the last element. */
|
28963
|
1325
|
|
1326 static void
|
|
1327 accumulate_font_info (arg, character, elt)
|
|
1328 Lisp_Object arg, character, elt;
|
|
1329 {
|
34975
|
1330 Lisp_Object last, last_char, last_elt;
|
28963
|
1331
|
29767
|
1332 if (!CONSP (elt) && !SINGLE_BYTE_CHAR_P (XINT (character)))
|
|
1333 elt = FONTSET_REF (Vdefault_fontset, XINT (character));
|
28963
|
1334 if (!CONSP (elt))
|
|
1335 return;
|
|
1336 last = XCAR (arg);
|
|
1337 last_char = XCAR (XCAR (last));
|
|
1338 last_elt = XCAR (XCDR (XCAR (last)));
|
|
1339 elt = XCDR (elt);
|
|
1340 if (!NILP (Fequal (elt, last_elt)))
|
|
1341 {
|
|
1342 int this_charset = CHAR_CHARSET (XINT (character));
|
|
1343
|
|
1344 if (CONSP (last_char)) /* LAST_CHAR == (FROM . TO) */
|
|
1345 {
|
|
1346 if (this_charset == CHAR_CHARSET (XINT (XCAR (last_char))))
|
|
1347 {
|
39973
579177964efa
Avoid (most) uses of XCAR/XCDR as lvalues, for flexibility in experimenting
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
1348 XSETCDR (last_char, character);
|
28963
|
1349 return;
|
|
1350 }
|
|
1351 }
|
29767
|
1352 else if (XINT (last_char) == XINT (character))
|
|
1353 return;
|
|
1354 else if (this_charset == CHAR_CHARSET (XINT (last_char)))
|
28963
|
1355 {
|
39973
579177964efa
Avoid (most) uses of XCAR/XCDR as lvalues, for flexibility in experimenting
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
1356 XSETCAR (XCAR (last), Fcons (last_char, character));
|
29767
|
1357 return;
|
28963
|
1358 }
|
|
1359 }
|
39973
579177964efa
Avoid (most) uses of XCAR/XCDR as lvalues, for flexibility in experimenting
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
1360 XSETCDR (last, Fcons (Fcons (character, Fcons (elt, Qnil)), Qnil));
|
579177964efa
Avoid (most) uses of XCAR/XCDR as lvalues, for flexibility in experimenting
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
1361 XSETCAR (arg, XCDR (last));
|
28963
|
1362 }
|
|
1363
|
|
1364
|
17052
|
1365 DEFUN ("fontset-info", Ffontset_info, Sfontset_info, 1, 2, 0,
|
41001
|
1366 doc: /* Return information about a fontset named NAME on frame FRAME.
|
49881
|
1367 If NAME is nil, return information about the default fontset.
|
41001
|
1368 The value is a vector:
|
|
1369 [ SIZE HEIGHT ((CHARSET-OR-RANGE FONT-SPEC OPENED ...) ...) ],
|
|
1370 where,
|
|
1371 SIZE is the maximum bound width of ASCII font in the fontset,
|
|
1372 HEIGHT is the maximum bound height of ASCII font in the fontset,
|
|
1373 CHARSET-OR-RANGE is a charset, a character (may be a generic character)
|
|
1374 or a cons of two characters specifying the range of characters.
|
|
1375 FONT-SPEC is a fontname pattern string or a cons (FAMILY . REGISTRY),
|
|
1376 where FAMILY is a `FAMILY' field of a XLFD font name,
|
41987
|
1377 REGISTRY is a `CHARSET_REGISTRY' field of a XLFD font name.
|
|
1378 FAMILY may contain a `FOUNDRY' field at the head.
|
41001
|
1379 REGISTRY may contain a `CHARSET_ENCODING' field at the tail.
|
|
1380 OPENEDs are names of fonts actually opened.
|
|
1381 If the ASCII font is not yet opened, SIZE and HEIGHT are 0.
|
|
1382 If FRAME is omitted, it defaults to the currently selected frame. */)
|
|
1383 (name, frame)
|
17052
|
1384 Lisp_Object name, frame;
|
|
1385 {
|
28963
|
1386 Lisp_Object fontset;
|
17052
|
1387 FRAME_PTR f;
|
28963
|
1388 Lisp_Object indices[3];
|
|
1389 Lisp_Object val, tail, elt;
|
|
1390 Lisp_Object *realized;
|
30124
|
1391 struct font_info *fontp = NULL;
|
28963
|
1392 int n_realized = 0;
|
17052
|
1393 int i;
|
41987
|
1394
|
17052
|
1395 (*check_window_system_func) ();
|
|
1396
|
28223
|
1397 fontset = check_fontset_name (name);
|
|
1398
|
17052
|
1399 if (NILP (frame))
|
25668
|
1400 frame = selected_frame;
|
40656
|
1401 CHECK_LIVE_FRAME (frame);
|
25668
|
1402 f = XFRAME (frame);
|
17052
|
1403
|
29767
|
1404 /* Recode realized fontsets whose base is FONTSET in the table
|
28963
|
1405 `realized'. */
|
|
1406 realized = (Lisp_Object *) alloca (sizeof (Lisp_Object)
|
|
1407 * ASIZE (Vfontset_table));
|
28223
|
1408 for (i = 0; i < ASIZE (Vfontset_table); i++)
|
|
1409 {
|
28963
|
1410 elt = FONTSET_FROM_ID (i);
|
|
1411 if (!NILP (elt)
|
|
1412 && EQ (FONTSET_BASE (elt), fontset))
|
|
1413 realized[n_realized++] = elt;
|
28223
|
1414 }
|
|
1415
|
49874
|
1416 if (! EQ (fontset, Vdefault_fontset))
|
|
1417 {
|
|
1418 /* Merge FONTSET onto the default fontset. */
|
|
1419 val = Fcopy_sequence (Vdefault_fontset);
|
51033
|
1420 map_char_table (override_font_info, Qnil, fontset, fontset, val, 0, indices);
|
49874
|
1421 fontset = val;
|
|
1422 }
|
|
1423
|
28963
|
1424 /* Accumulate information of the fontset in VAL. The format is
|
|
1425 (LAST FONT-INFO FONT-INFO ...), where FONT-INFO is (CHAR-OR-RANGE
|
|
1426 FONT-SPEC). See the comment for accumulate_font_info for the
|
|
1427 detail. */
|
|
1428 val = Fcons (Fcons (make_number (0),
|
|
1429 Fcons (XCDR (FONTSET_ASCII (fontset)), Qnil)),
|
|
1430 Qnil);
|
|
1431 val = Fcons (val, val);
|
51033
|
1432 map_char_table (accumulate_font_info, Qnil, fontset, fontset, val, 0, indices);
|
28963
|
1433 val = XCDR (val);
|
28223
|
1434
|
28963
|
1435 /* For each FONT-INFO, if CHAR_OR_RANGE (car part) is a generic
|
29767
|
1436 character for a charset, replace it with the charset symbol. If
|
28963
|
1437 fonts are opened for FONT-SPEC, append the names of the fonts to
|
|
1438 FONT-SPEC. */
|
|
1439 for (tail = val; CONSP (tail); tail = XCDR (tail))
|
28223
|
1440 {
|
28963
|
1441 int c;
|
|
1442 elt = XCAR (tail);
|
|
1443 if (INTEGERP (XCAR (elt)))
|
28223
|
1444 {
|
28963
|
1445 int charset, c1, c2;
|
|
1446 c = XINT (XCAR (elt));
|
|
1447 SPLIT_CHAR (c, charset, c1, c2);
|
|
1448 if (c1 == 0)
|
39973
579177964efa
Avoid (most) uses of XCAR/XCDR as lvalues, for flexibility in experimenting
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
1449 XSETCAR (elt, CHARSET_SYMBOL (charset));
|
28963
|
1450 }
|
|
1451 else
|
|
1452 c = XINT (XCAR (XCAR (elt)));
|
|
1453 for (i = 0; i < n_realized; i++)
|
|
1454 {
|
|
1455 Lisp_Object face_id, font;
|
28223
|
1456 struct face *face;
|
17052
|
1457
|
28963
|
1458 face_id = FONTSET_REF_VIA_BASE (realized[i], c);
|
|
1459 if (INTEGERP (face_id))
|
28223
|
1460 {
|
28963
|
1461 face = FACE_FROM_ID (f, XINT (face_id));
|
37744
|
1462 if (face && face->font && face->font_name)
|
28963
|
1463 {
|
|
1464 font = build_string (face->font_name);
|
|
1465 if (NILP (Fmember (font, XCDR (XCDR (elt)))))
|
39973
579177964efa
Avoid (most) uses of XCAR/XCDR as lvalues, for flexibility in experimenting
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
1466 XSETCDR (XCDR (elt), Fcons (font, XCDR (XCDR (elt))));
|
28963
|
1467 }
|
28223
|
1468 }
|
|
1469 }
|
|
1470 }
|
30124
|
1471
|
|
1472 elt = Fcdr (Fcdr (Fassq (CHARSET_SYMBOL (CHARSET_ASCII), val)));
|
|
1473 if (CONSP (elt))
|
|
1474 {
|
|
1475 elt = XCAR (elt);
|
46370
40db0673e6f0
Most uses of XSTRING combined with STRING_BYTES or indirection changed to
Ken Raeburn <raeburn@raeburn.org>
diff
changeset
|
1476 fontp = (*query_font_func) (f, SDATA (elt));
|
30124
|
1477 }
|
|
1478 val = Fmake_vector (make_number (3), val);
|
|
1479 AREF (val, 0) = fontp ? make_number (fontp->size) : make_number (0);
|
|
1480 AREF (val, 1) = fontp ? make_number (fontp->height) : make_number (0);
|
|
1481 return val;
|
17052
|
1482 }
|
|
1483
|
28223
|
1484 DEFUN ("fontset-font", Ffontset_font, Sfontset_font, 2, 2, 0,
|
41001
|
1485 doc: /* Return a font name pattern for character CH in fontset NAME.
|
49881
|
1486 If NAME is nil, find a font name pattern in the default fontset. */)
|
41001
|
1487 (name, ch)
|
28223
|
1488 Lisp_Object name, ch;
|
|
1489 {
|
34975
|
1490 int c;
|
28223
|
1491 Lisp_Object fontset, elt;
|
|
1492
|
|
1493 fontset = check_fontset_name (name);
|
|
1494
|
40656
|
1495 CHECK_NUMBER (ch);
|
28223
|
1496 c = XINT (ch);
|
|
1497 if (!char_valid_p (c, 1))
|
|
1498 invalid_character (c);
|
|
1499
|
|
1500 elt = FONTSET_REF (fontset, c);
|
|
1501 if (CONSP (elt))
|
|
1502 elt = XCDR (elt);
|
|
1503
|
|
1504 return elt;
|
|
1505 }
|
|
1506
|
|
1507 DEFUN ("fontset-list", Ffontset_list, Sfontset_list, 0, 0, 0,
|
41001
|
1508 doc: /* Return a list of all defined fontset names. */)
|
|
1509 ()
|
28223
|
1510 {
|
|
1511 Lisp_Object fontset, list;
|
|
1512 int i;
|
|
1513
|
|
1514 list = Qnil;
|
|
1515 for (i = 0; i < ASIZE (Vfontset_table); i++)
|
|
1516 {
|
|
1517 fontset = FONTSET_FROM_ID (i);
|
|
1518 if (!NILP (fontset)
|
|
1519 && BASE_FONTSET_P (fontset))
|
|
1520 list = Fcons (FONTSET_NAME (fontset), list);
|
|
1521 }
|
28963
|
1522
|
28223
|
1523 return list;
|
|
1524 }
|
|
1525
|
53353
|
1526 DEFUN ("set-overriding-fontspec-internal", Fset_overriding_fontspec_internal,
|
|
1527 Sset_overriding_fontspec_internal, 1, 1, 0,
|
|
1528 doc: /* Internal use only.
|
|
1529
|
|
1530 FONTLIST is an alist of TARGET vs FONTNAME, where TARGET is a charset
|
|
1531 or a char-table, FONTNAME have the same meanings as in
|
|
1532 `set-fontset-font'.
|
|
1533
|
|
1534 It overrides the font specifications for each TARGET in the default
|
|
1535 fontset by the corresponding FONTNAME.
|
|
1536
|
|
1537 If TARGET is a charset, targets are all characters in the charset. If
|
|
1538 TARGET is a char-table, targets are characters whose value is non-nil
|
|
1539 in the table.
|
|
1540
|
|
1541 It is intended that this function is called only from
|
|
1542 `set-language-environment'. */)
|
|
1543 (fontlist)
|
|
1544 Lisp_Object fontlist;
|
|
1545 {
|
|
1546 Lisp_Object tail;
|
|
1547
|
|
1548 fontlist = Fcopy_sequence (fontlist);
|
|
1549 /* Now FONTLIST is ((TARGET . FONTNAME) ...). Reform it to ((TARGET
|
|
1550 nil nil nil FONTSPEC) ...), where TARGET is a charset-id or a
|
|
1551 char-table. */
|
|
1552 for (tail = fontlist; CONSP (tail); tail = XCDR (tail))
|
|
1553 {
|
|
1554 Lisp_Object elt, target;
|
|
1555
|
|
1556 elt = XCAR (tail);
|
|
1557 target = Fcar (elt);
|
54995
|
1558 elt = Fcons (Qnil, regularize_fontname (Fcdr (elt)));
|
53353
|
1559 if (! CHAR_TABLE_P (target))
|
|
1560 {
|
|
1561 int charset, c;
|
|
1562
|
|
1563 CHECK_SYMBOL (target);
|
|
1564 charset = get_charset_id (target);
|
|
1565 if (charset < 0)
|
|
1566 error ("Invalid charset %s", SDATA (SYMBOL_NAME (target)));
|
|
1567 target = make_number (charset);
|
|
1568 c = MAKE_CHAR (charset, 0, 0);
|
|
1569 XSETCAR (elt, make_number (c));
|
|
1570 }
|
|
1571 elt = Fcons (target, Fcons (Qnil, Fcons (Qnil, elt)));
|
|
1572 XSETCAR (tail, elt);
|
|
1573 }
|
|
1574 Voverriding_fontspec_alist = fontlist;
|
|
1575 clear_face_cache (0);
|
|
1576 ++windows_or_buffers_changed;
|
|
1577 return Qnil;
|
|
1578 }
|
|
1579
|
21514
|
1580 void
|
17052
|
1581 syms_of_fontset ()
|
|
1582 {
|
|
1583 if (!load_font_func)
|
|
1584 /* Window system initializer should have set proper functions. */
|
|
1585 abort ();
|
|
1586
|
17112
|
1587 Qfontset = intern ("fontset");
|
17052
|
1588 staticpro (&Qfontset);
|
28223
|
1589 Fput (Qfontset, Qchar_table_extra_slots, make_number (3));
|
17052
|
1590
|
|
1591 Vcached_fontset_data = Qnil;
|
|
1592 staticpro (&Vcached_fontset_data);
|
|
1593
|
28223
|
1594 Vfontset_table = Fmake_vector (make_number (32), Qnil);
|
|
1595 staticpro (&Vfontset_table);
|
|
1596
|
|
1597 Vdefault_fontset = Fmake_char_table (Qfontset, Qnil);
|
|
1598 staticpro (&Vdefault_fontset);
|
28963
|
1599 FONTSET_ID (Vdefault_fontset) = make_number (0);
|
|
1600 FONTSET_NAME (Vdefault_fontset)
|
|
1601 = build_string ("-*-*-*-*-*-*-*-*-*-*-*-*-fontset-default");
|
44890
01b93e5e53a7
Patch for building Emacs on Mac OS X. April 26, 2002. See ChangeLog,
Andrew Choi <akochoi@shaw.ca>
diff
changeset
|
1602 #if defined (MAC_OS)
|
32752
|
1603 FONTSET_ASCII (Vdefault_fontset)
|
|
1604 = Fcons (make_number (0),
|
45848
|
1605 build_string ("-apple-monaco-medium-r-*--*-120-*-*-*-*-mac-roman"));
|
32790
131348208699
(syms_of_fontset) [WINDOWSNT]: Special case for ASCII font of default
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1606 #elif defined (WINDOWSNT)
|
131348208699
(syms_of_fontset) [WINDOWSNT]: Special case for ASCII font of default
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1607 FONTSET_ASCII (Vdefault_fontset)
|
131348208699
(syms_of_fontset) [WINDOWSNT]: Special case for ASCII font of default
Jason Rumney <jasonr@gnu.org>
diff
changeset
|
1608 = Fcons (make_number (0),
|
32978
|
1609 build_string ("-*-courier new-normal-r-*-*-*-100-*-*-*-*-iso8859-1"));
|
32752
|
1610 #else
|
28223
|
1611 FONTSET_ASCII (Vdefault_fontset)
|
29231
|
1612 = Fcons (make_number (0),
|
|
1613 build_string ("-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1"));
|
32752
|
1614 #endif
|
28963
|
1615 AREF (Vfontset_table, 0) = Vdefault_fontset;
|
|
1616 next_fontset_id = 1;
|
17052
|
1617
|
53353
|
1618 Voverriding_fontspec_alist = Qnil;
|
|
1619 staticpro (&Voverriding_fontspec_alist);
|
|
1620
|
17052
|
1621 DEFVAR_LISP ("font-encoding-alist", &Vfont_encoding_alist,
|
41001
|
1622 doc: /* Alist of fontname patterns vs corresponding encoding info.
|
|
1623 Each element looks like (REGEXP . ENCODING-INFO),
|
|
1624 where ENCODING-INFO is an alist of CHARSET vs ENCODING.
|
|
1625 ENCODING is one of the following integer values:
|
|
1626 0: code points 0x20..0x7F or 0x2020..0x7F7F are used,
|
|
1627 1: code points 0xA0..0xFF or 0xA0A0..0xFFFF are used,
|
|
1628 2: code points 0x20A0..0x7FFF are used,
|
|
1629 3: code points 0xA020..0xFF7F are used. */);
|
17052
|
1630 Vfont_encoding_alist = Qnil;
|
49286
|
1631 Vfont_encoding_alist
|
|
1632 = Fcons (Fcons (build_string ("JISX0201"),
|
|
1633 Fcons (Fcons (intern ("latin-jisx0201"), make_number (0)),
|
|
1634 Qnil)),
|
|
1635 Vfont_encoding_alist);
|
|
1636 Vfont_encoding_alist
|
|
1637 = Fcons (Fcons (build_string ("ISO8859-1"),
|
|
1638 Fcons (Fcons (intern ("ascii"), make_number (0)),
|
|
1639 Qnil)),
|
|
1640 Vfont_encoding_alist);
|
17052
|
1641
|
17112
|
1642 DEFVAR_LISP ("use-default-ascent", &Vuse_default_ascent,
|
41001
|
1643 doc: /* Char table of characters whose ascent values should be ignored.
|
|
1644 If an entry for a character is non-nil, the ascent value of the glyph
|
|
1645 is assumed to be what specified by _MULE_DEFAULT_ASCENT property of a font.
|
|
1646
|
|
1647 This affects how a composite character which contains
|
|
1648 such a character is displayed on screen. */);
|
19282
|
1649 Vuse_default_ascent = Qnil;
|
|
1650
|
|
1651 DEFVAR_LISP ("ignore-relative-composition", &Vignore_relative_composition,
|
41001
|
1652 doc: /* Char table of characters which is not composed relatively.
|
|
1653 If an entry for a character is non-nil, a composition sequence
|
|
1654 which contains that character is displayed so that
|
|
1655 the glyph of that character is put without considering
|
|
1656 an ascent and descent value of a previous character. */);
|
26858
|
1657 Vignore_relative_composition = Qnil;
|
17112
|
1658
|
19450
|
1659 DEFVAR_LISP ("alternate-fontname-alist", &Valternate_fontname_alist,
|
41001
|
1660 doc: /* Alist of fontname vs list of the alternate fontnames.
|
|
1661 When a specified font name is not found, the corresponding
|
|
1662 alternate fontnames (if any) are tried instead. */);
|
19450
|
1663 Valternate_fontname_alist = Qnil;
|
17193
|
1664
|
17730
|
1665 DEFVAR_LISP ("fontset-alias-alist", &Vfontset_alias_alist,
|
41001
|
1666 doc: /* Alist of fontset names vs the aliases. */);
|
28963
|
1667 Vfontset_alias_alist = Fcons (Fcons (FONTSET_NAME (Vdefault_fontset),
|
|
1668 build_string ("fontset-default")),
|
|
1669 Qnil);
|
17730
|
1670
|
26858
|
1671 DEFVAR_LISP ("vertical-centering-font-regexp",
|
|
1672 &Vvertical_centering_font_regexp,
|
41001
|
1673 doc: /* *Regexp matching font names that require vertical centering on display.
|
|
1674 When a character is displayed with such fonts, the character is displayed
|
41987
|
1675 at the vertical center of lines. */);
|
26858
|
1676 Vvertical_centering_font_regexp = Qnil;
|
|
1677
|
17052
|
1678 defsubr (&Squery_fontset);
|
|
1679 defsubr (&Snew_fontset);
|
|
1680 defsubr (&Sset_fontset_font);
|
|
1681 defsubr (&Sfont_info);
|
28963
|
1682 defsubr (&Sinternal_char_font);
|
17052
|
1683 defsubr (&Sfontset_info);
|
28223
|
1684 defsubr (&Sfontset_font);
|
|
1685 defsubr (&Sfontset_list);
|
53353
|
1686 defsubr (&Sset_overriding_fontspec_internal);
|
17052
|
1687 }
|
52401
|
1688
|
|
1689 /* arch-tag: ea861585-2f5f-4e5b-9849-d04a9c3a3537
|
|
1690 (do not change this comment) */
|