1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28: #include <config.h>
29:
30: #ifdef FONTSET_DEBUG
31: #include <stdio.h>
32: #endif
33:
34: #include "lisp.h"
35: #include "buffer.h"
36: #include "charset.h"
37: #include "ccl.h"
38: #include "keyboard.h"
39: #include "frame.h"
40: #include "dispextern.h"
41: #include "fontset.h"
42: #include "window.h"
43: #ifdef HAVE_X_WINDOWS
44: #include "xterm.h"
45: #endif
46: #ifdef WINDOWSNT
47: #include "w32term.h"
48: #endif
49: #ifdef MAC_OS
50: #include "macterm.h"
51: #endif
52:
53: #ifdef FONTSET_DEBUG
54: #undef xassert
55: #define xassert(X) do {if (!(X)) abort ();} while (0)
56: #undef INLINE
57: #define INLINE
58: #endif
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133: extern Lisp_Object Qfont;
134: Lisp_Object Qfontset;
135:
136:
137: static Lisp_Object Vfontset_table;
138:
139:
140:
141: static int next_fontset_id;
142:
143:
144:
145: static Lisp_Object Vdefault_fontset;
146:
147:
148:
149: static Lisp_Object Voverriding_fontspec_alist;
150:
151: Lisp_Object Vfont_encoding_alist;
152: Lisp_Object Vuse_default_ascent;
153: Lisp_Object Vignore_relative_composition;
154: Lisp_Object Valternate_fontname_alist;
155: Lisp_Object Vfontset_alias_alist;
156: Lisp_Object Vvertical_centering_font_regexp;
157:
158:
159:
160:
161:
162:
163: struct font_info *(*get_font_info_func) P_ ((FRAME_PTR f, int font_idx));
164:
165:
166:
167: Lisp_Object (*list_fonts_func) P_ ((struct frame *f,
168: Lisp_Object pattern,
169: int size,
170: int maxnames));
171:
172:
173:
174: struct font_info *(*load_font_func) P_ ((FRAME_PTR f, char *name, int));
175:
176:
177: struct font_info *(*query_font_func) P_ ((FRAME_PTR f, char *name));
178:
179:
180:
181: void (*set_frame_fontset_func) P_ ((FRAME_PTR f, Lisp_Object arg,
182: Lisp_Object oldval));
183:
184:
185:
186:
187: void (*find_ccl_program_func) P_ ((struct font_info *));
188:
189:
190: void (*check_window_system_func) P_ ((void));
191:
192:
193:
194: static Lisp_Object fontset_ref P_ ((Lisp_Object, int));
195: static Lisp_Object lookup_overriding_fontspec P_ ((Lisp_Object, int));
196: static void fontset_set P_ ((Lisp_Object, int, Lisp_Object));
197: static Lisp_Object make_fontset P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
198: static int fontset_id_valid_p P_ ((int));
199: static Lisp_Object fontset_pattern_regexp P_ ((Lisp_Object));
200: static Lisp_Object font_family_registry P_ ((Lisp_Object, int));
201: static Lisp_Object regularize_fontname P_ ((Lisp_Object));
202:
203: ^L
204:
205:
206:
207: #define FONTSET_FROM_ID(id) AREF (Vfontset_table, id)
208:
209:
210: #define FONTSET_ID(fontset) XCHAR_TABLE (fontset)->extras[0]
211: #define FONTSET_NAME(fontset) XCHAR_TABLE (fontset)->extras[1]
212: #define FONTSET_FRAME(fontset) XCHAR_TABLE (fontset)->extras[2]
213: #define FONTSET_ASCII(fontset) XCHAR_TABLE (fontset)->contents[0]
214: #define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->parent
215:
216: #define BASE_FONTSET_P(fontset) NILP (FONTSET_BASE(fontset))
217:
218:
219:
220:
221: #define FONTSET_REF(fontset, c) fontset_ref (fontset, c)
222:
223: static Lisp_Object
224: fontset_ref (fontset, c)
225: Lisp_Object fontset;
226: int c;
227: {
228: int charset, c1, c2;
229: Lisp_Object elt, defalt;
230:
231: if (SINGLE_BYTE_CHAR_P (c))
232: return FONTSET_ASCII (fontset);
233:
234: SPLIT_CHAR (c, charset, c1, c2);
235: elt = XCHAR_TABLE (fontset)->contents[charset + 128];
236: if (!SUB_CHAR_TABLE_P (elt))
237: return elt;
238: defalt = XCHAR_TABLE (elt)->defalt;
239: if (c1 < 32
240: || (elt = XCHAR_TABLE (elt)->contents[c1],
241: NILP (elt)))
242: return defalt;
243: if (!SUB_CHAR_TABLE_P (elt))
244: return elt;
245: defalt = XCHAR_TABLE (elt)->defalt;
246: if (c2 < 32
247: || (elt = XCHAR_TABLE (elt)->contents[c2],
248: NILP (elt)))
249: return defalt;
250: return elt;
251: }
252:
253:
254: static Lisp_Object
255: lookup_overriding_fontspec (frame, c)
256: Lisp_Object frame;
257: int c;
258: {
259: Lisp_Object tail;
260:
261: for (tail = Voverriding_fontspec_alist; CONSP (tail); tail = XCDR (tail))
262: {
263: Lisp_Object val, target, elt;
264:
265: val = XCAR (tail);
266: target = XCAR (val);
267: val = XCDR (val);
268:
269: if (NILP (Fmemq (frame, XCAR (val)))
270: && (CHAR_TABLE_P (target)
271: ? ! NILP (CHAR_TABLE_REF (target, c))
272: : XINT (target) == CHAR_CHARSET (c)))
273: {
274: val = XCDR (val);
275: elt = XCDR (val);
276: if (NILP (Fmemq (frame, XCAR (val))))
277: {
278: if (! face_font_available_p (XFRAME (frame), XCDR (elt)))
279: {
280: val = XCDR (XCAR (tail));
281: XSETCAR (val, Fcons (frame, XCAR (val)));
282: continue;
283: }
284: XSETCAR (val, Fcons (frame, XCAR (val)));
285: }
286: if (NILP (XCAR (elt)))
287: XSETCAR (elt, make_number (c));
288: return elt;
289: }
290: }
291: return Qnil;
292: }
293:
294: #define FONTSET_REF_VIA_BASE(fontset, c) fontset_ref_via_base (fontset, &c)
295:
296: static Lisp_Object
297: fontset_ref_via_base (fontset, c)
298: Lisp_Object fontset;
299: int *c;
300: {
301: int charset, c1, c2;
302: Lisp_Object elt;
303:
304: if (SINGLE_BYTE_CHAR_P (*c))
305: return FONTSET_ASCII (fontset);
306:
307: elt = Qnil;
308: if (! EQ (FONTSET_BASE (fontset), Vdefault_fontset))
309: elt = FONTSET_REF (FONTSET_BASE (fontset), *c);
310: if (NILP (elt))
311: elt = lookup_overriding_fontspec (FONTSET_FRAME (fontset), *c);
312: if (NILP (elt))
313: elt = FONTSET_REF (Vdefault_fontset, *c);
314: if (NILP (elt))
315: return Qnil;
316:
317: *c = XINT (XCAR (elt));
318: SPLIT_CHAR (*c, charset, c1, c2);
319: elt = XCHAR_TABLE (fontset)->contents[charset + 128];
320: if (c1 < 32)
321: return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
322: if (!SUB_CHAR_TABLE_P (elt))
323: return Qnil;
324: elt = XCHAR_TABLE (elt)->contents[c1];
325: if (c2 < 32)
326: return (SUB_CHAR_TABLE_P (elt) ? XCHAR_TABLE (elt)->defalt : elt);
327: if (!SUB_CHAR_TABLE_P (elt))
328: return Qnil;
329: elt = XCHAR_TABLE (elt)->contents[c2];
330: return elt;
331: }
332:
333:
334:
335: #define FONTSET_SET(fontset, c, newelt) fontset_set(fontset, c, newelt)
336:
337: static void
338: fontset_set (fontset, c, newelt)
339: Lisp_Object fontset;
340: int c;
341: Lisp_Object newelt;
342: {
343: int charset, code[3];
344: Lisp_Object *elt;
345: int i;
346:
347: if (SINGLE_BYTE_CHAR_P (c))
348: {
349: FONTSET_ASCII (fontset) = newelt;
350: return;
351: }
352:
353: SPLIT_CHAR (c, charset, code[0], code[1]);
354: code[2] = 0;
355: elt = &XCHAR_TABLE (fontset)->contents[charset + 128];
356: for (i = 0; code[i] > 0; i++)
357: {
358: if (!SUB_CHAR_TABLE_P (*elt))
359: {
360: Lisp_Object val = *elt;
361: *elt = make_sub_char_table (Qnil);
362: XCHAR_TABLE (*elt)->defalt = val;
363: }
364: elt = &XCHAR_TABLE (*elt)->contents[code[i]];
365: }
366: if (SUB_CHAR_TABLE_P (*elt))
367: XCHAR_TABLE (*elt)->defalt = newelt;
368: else
369: *elt = newelt;
370: }
371:
372:
373:
374:
375:
376:
377: static Lisp_Object
378: make_fontset (frame, name, base)
379: Lisp_Object frame, name, base;
380: {
381: Lisp_Object fontset;
382: int size = ASIZE (Vfontset_table);
383: int id = next_fontset_id;
384:
385:
386:
387:
388:
389:
390: while (!NILP (AREF (Vfontset_table, id))) id++;
391:
392: if (id + 1 == size)
393: {
394: Lisp_Object tem;
395: int i;
396:
397: tem = Fmake_vector (make_number (size + 8), Qnil);
398: for (i = 0; i < size; i++)
399: AREF (tem, i) = AREF (Vfontset_table, i);
400: Vfontset_table = tem;
401: }
402:
403: fontset = Fmake_char_table (Qfontset, Qnil);
404:
405: FONTSET_ID (fontset) = make_number (id);
406: FONTSET_NAME (fontset) = name;
407: FONTSET_FRAME (fontset) = frame;
408: FONTSET_BASE (fontset) = base;
409:
410: AREF (Vfontset_table, id) = fontset;
411: next_fontset_id = id + 1;
412: return fontset;
413: }
414:
415:
416:
417:
418: static INLINE int
419: fontset_id_valid_p (id)
420: int id;
421: {
422: return (id >= 0 && id < ASIZE (Vfontset_table) - 1);
423: }
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434: static Lisp_Object
435: font_family_registry (fontname, force)
436: Lisp_Object fontname;
437: int force;
438: {
439: Lisp_Object family, registry;
440: const char *p = SDATA (fontname);
441: const char *sep[15];
442: int i = 0;
443:
444: while (*p && i < 15)
445: if (*p++ == '-')
446: {
447: if (!force && i >= 2 && i <= 11 && *p != '*' && p[1] != '-')
448: return fontname;
449: sep[i++] = p;
450: }
451: if (i != 14)
452: return fontname;
453:
454: family = make_unibyte_string (sep[0], sep[2] - 1 - sep[0]);
455: registry = make_unibyte_string (sep[12], p - sep[12]);
456: return Fcons (family, registry);
457: }
458:
459: ^L
460:
461:
462:
463:
464: Lisp_Object
465: fontset_name (id)
466: int id;
467: {
468: Lisp_Object fontset;
469: fontset = FONTSET_FROM_ID (id);
470: return FONTSET_NAME (fontset);
471: }
472:
473:
474:
475:
476: Lisp_Object
477: fontset_ascii (id)
478: int id;
479: {
480: Lisp_Object fontset, elt;
481: fontset= FONTSET_FROM_ID (id);
482: elt = FONTSET_ASCII (fontset);
483: return XCDR (elt);
484: }
485:
486:
487:
488:
489: void
490: free_face_fontset (f, face)
491: FRAME_PTR f;
492: struct face *face;
493: {
494: if (fontset_id_valid_p (face->fontset))
495: {
496: AREF (Vfontset_table, face->fontset) = Qnil;
497: if (face->fontset < next_fontset_id)
498: next_fontset_id = face->fontset;
499: }
500: }
501:
502:
503:
504:
505:
506:
507: int
508: face_suitable_for_char_p (face, c)
509: struct face *face;
510: int c;
511: {
512: Lisp_Object fontset, elt;
513:
514: if (SINGLE_BYTE_CHAR_P (c))
515: return (face == face->ascii_face);
516:
517: xassert (fontset_id_valid_p (face->fontset));
518: fontset = FONTSET_FROM_ID (face->fontset);
519: xassert (!BASE_FONTSET_P (fontset));
520:
521: elt = FONTSET_REF_VIA_BASE (fontset, c);
522: return (!NILP (elt) && face->id == XFASTINT (elt));
523: }
524:
525:
526:
527:
528:
529:
530:
531: int
532: face_for_char (f, face, c)
533: FRAME_PTR f;
534: struct face *face;
535: int c;
536: {
537: Lisp_Object fontset, elt;
538: int face_id;
539:
540: xassert (fontset_id_valid_p (face->fontset));
541: fontset = FONTSET_FROM_ID (face->fontset);
542: xassert (!BASE_FONTSET_P (fontset));
543:
544: elt = FONTSET_REF_VIA_BASE (fontset, c);
545: if (!NILP (elt))
546: return XINT (elt);
547:
548:
549:
550: face_id = lookup_face (f, face->lface, c, face);
551:
552:
553:
554: FONTSET_SET (fontset, c, make_number (face_id));
555: return face_id;
556: }
557:
558:
559:
560:
561:
562:
563:
564: int
565: make_fontset_for_ascii_face (f, base_fontset_id)
566: FRAME_PTR f;
567: int base_fontset_id;
568: {
569: Lisp_Object base_fontset, fontset, frame;
570:
571: XSETFRAME (frame, f);
572: if (base_fontset_id >= 0)
573: {
574: base_fontset = FONTSET_FROM_ID (base_fontset_id);
575: if (!BASE_FONTSET_P (base_fontset))
576: base_fontset = FONTSET_BASE (base_fontset);
577: xassert (BASE_FONTSET_P (base_fontset));
578: }
579: else
580: base_fontset = Vdefault_fontset;
581:
582: fontset = make_fontset (frame, Qnil, base_fontset);
583: return XINT (FONTSET_ID (fontset));
584: }
585:
586:
587:
588:
589:
590:
591:
592:
593:
594:
595: Lisp_Object