This source file includes following definitions.
- haikufont_apply_registry
- haikufont_get_fallback_entity
- haikufont_get_cache
- haikufont_weight_to_lisp
- haikufont_lisp_to_weight
- haikufont_slant_to_lisp
- haikufont_lisp_to_slant
- haikufont_width_to_lisp
- haikufont_lisp_to_width
- haikufont_maybe_handle_special_family
- haikufont_pattern_to_entity
- haikufont_pattern_from_object
- haikufont_spec_or_entity_to_pattern
- haikufont_done_with_query_pattern
- haikufont_match
- haikufont_list
- haiku_bulk_encode
- haikufont_encode_char
- haikufont_open
- haikufont_close
- haikufont_prepare_face
- haikufont_glyph_extents
- haikufont_text_extents
- haikufont_shape
- haikufont_draw
- haikufont_list_family
- haikufont_filter_properties
- haikufont_should_quit_popup
- DEFUN
- DEFUN
- haiku_handle_font_change_event
- syms_of_haikufont_for_pdumper
- syms_of_haikufont
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <config.h>
21
22 #include "lisp.h"
23 #include "dispextern.h"
24 #include "composite.h"
25 #include "blockinput.h"
26 #include "charset.h"
27 #include "frame.h"
28 #include "window.h"
29 #include "fontset.h"
30 #include "haikuterm.h"
31 #include "character.h"
32 #include "coding.h"
33 #include "font.h"
34 #include "termchar.h"
35 #include "pdumper.h"
36 #include "haiku_support.h"
37
38 #include <math.h>
39 #include <stdlib.h>
40
41 static Lisp_Object font_cache;
42
43 #define METRICS_NCOLS_PER_ROW (128)
44
45 enum metrics_status
46 {
47 METRICS_INVALID = -1,
48 };
49
50 #define METRICS_STATUS(metrics) ((metrics)->ascent + (metrics)->descent)
51 #define METRICS_SET_STATUS(metrics, status) \
52 ((metrics)->ascent = 0, (metrics)->descent = (status))
53
54 static struct
55 {
56
57 const char *name;
58
59 int uniquifier[6];
60
61 const char *lang;
62 } em_charset_table[] =
63 { { "iso8859-1", { 0x00A0, 0x00A1, 0x00B4, 0x00BC, 0x00D0 } },
64 { "iso8859-2", { 0x00A0, 0x010E }},
65 { "iso8859-3", { 0x00A0, 0x0108 }},
66 { "iso8859-4", { 0x00A0, 0x00AF, 0x0128, 0x0156, 0x02C7 }},
67 { "iso8859-5", { 0x00A0, 0x0401 }},
68 { "iso8859-6", { 0x00A0, 0x060C }},
69 { "iso8859-7", { 0x00A0, 0x0384 }},
70 { "iso8859-8", { 0x00A0, 0x05D0 }},
71 { "iso8859-9", { 0x00A0, 0x00A1, 0x00BC, 0x011E }},
72 { "iso8859-10", { 0x00A0, 0x00D0, 0x0128, 0x2015 }},
73 { "iso8859-11", { 0x00A0, 0x0E01 }},
74 { "iso8859-13", { 0x00A0, 0x201C }},
75 { "iso8859-14", { 0x00A0, 0x0174 }},
76 { "iso8859-15", { 0x00A0, 0x00A1, 0x00D0, 0x0152 }},
77 { "iso8859-16", { 0x00A0, 0x0218}},
78 { "gb2312.1980-0", { 0x4E13 }, "zh-cn"},
79 { "big5-0", { 0x9C21 }, "zh-tw" },
80 { "jisx0208.1983-0", { 0x4E55 }, "ja"},
81 { "ksc5601.1985-0", { 0xAC00 }, "ko"},
82 { "cns11643.1992-1", { 0xFE32 }, "zh-tw"},
83 { "cns11643.1992-2", { 0x4E33, 0x7934 }},
84 { "cns11643.1992-3", { 0x201A9 }},
85 { "cns11643.1992-4", { 0x20057 }},
86 { "cns11643.1992-5", { 0x20000 }},
87 { "cns11643.1992-6", { 0x20003 }},
88 { "cns11643.1992-7", { 0x20055 }},
89 { "gbk-0", { 0x4E06 }, "zh-cn"},
90 { "jisx0212.1990-0", { 0x4E44 }},
91 { "jisx0213.2000-1", { 0xFA10 }, "ja"},
92 { "jisx0213.2000-2", { 0xFA49 }},
93 { "jisx0213.2004-1", { 0x20B9F }},
94 { "viscii1.1-1", { 0x1EA0, 0x1EAE, 0x1ED2 }, "vi"},
95 { "tis620.2529-1", { 0x0E01 }, "th"},
96 { "microsoft-cp1251", { 0x0401, 0x0490 }, "ru"},
97 { "koi8-r", { 0x0401, 0x2219 }, "ru"},
98 { "mulelao-1", { 0x0E81 }, "lo"},
99 { "unicode-sip", { 0x20000 }},
100 { "mulearabic-0", { 0x628 }},
101 { "mulearabic-1", { 0x628 }},
102 { "mulearabic-2", { 0x628 }},
103 { NULL }
104 };
105
106 static void
107 haikufont_apply_registry (struct haiku_font_pattern *pattern,
108 Lisp_Object registry)
109 {
110 char *str = SSDATA (SYMBOL_NAME (registry));
111 USE_SAFE_ALLOCA;
112 char *re = SAFE_ALLOCA (SBYTES (SYMBOL_NAME (registry)) * 2 + 1);
113 int i, j;
114
115 for (i = j = 0; i < SBYTES (SYMBOL_NAME (registry)); i++, j++)
116 {
117 if (str[i] == '.')
118 re[j++] = '\\';
119 else if (str[i] == '*')
120 re[j++] = '.';
121 re[j] = str[i];
122 if (re[j] == '?')
123 re[j] = '.';
124 }
125 re[j] = '\0';
126 AUTO_STRING_WITH_LEN (regexp, re, j);
127 for (i = 0; em_charset_table[i].name; i++)
128 if (fast_c_string_match_ignore_case
129 (regexp, em_charset_table[i].name,
130 strlen (em_charset_table[i].name)) >= 0)
131 break;
132 SAFE_FREE ();
133 if (!em_charset_table[i].name)
134 return;
135 int *uniquifier = em_charset_table[i].uniquifier;
136 int l;
137
138 for (l = 0; uniquifier[l]; ++l);
139
140 int *a = xmalloc (l * sizeof *a);
141 for (l = 0; uniquifier[l]; ++l)
142 a[l] = uniquifier[l];
143
144 if (pattern->specified & FSPEC_WANTED)
145 {
146 int old_l = l;
147 l += pattern->want_chars_len;
148 a = xrealloc (a, l * sizeof *a);
149 memcpy (&a[old_l], pattern->wanted_chars, (l - old_l) * sizeof *a);
150 xfree (pattern->wanted_chars);
151 }
152
153 pattern->specified |= FSPEC_WANTED;
154 pattern->want_chars_len = l;
155 pattern->wanted_chars = a;
156
157 if (em_charset_table[i].lang)
158 {
159 if (!strncmp (em_charset_table[i].lang, "zh", 2))
160 {
161 pattern->specified |= FSPEC_LANGUAGE;
162 pattern->language = LANGUAGE_CN;
163 }
164 else if (!strncmp (em_charset_table[i].lang, "ko", 2))
165 {
166 pattern->specified |= FSPEC_LANGUAGE;
167 pattern->language = LANGUAGE_KO;
168 }
169 else if (!strncmp (em_charset_table[i].lang, "ja", 2))
170 {
171 pattern->specified |= FSPEC_LANGUAGE;
172 pattern->language = LANGUAGE_JP;
173 }
174 }
175
176 return;
177 }
178
179 static Lisp_Object
180 haikufont_get_fallback_entity (void)
181 {
182 Lisp_Object ent = font_make_entity ();
183 ASET (ent, FONT_TYPE_INDEX, Qhaiku);
184 ASET (ent, FONT_FOUNDRY_INDEX, Qhaiku);
185 ASET (ent, FONT_FAMILY_INDEX, Qnil);
186 ASET (ent, FONT_ADSTYLE_INDEX, Qnil);
187 ASET (ent, FONT_REGISTRY_INDEX, Qiso10646_1);
188 ASET (ent, FONT_SIZE_INDEX, make_fixnum (0));
189 ASET (ent, FONT_AVGWIDTH_INDEX, make_fixnum (0));
190 ASET (ent, FONT_SPACING_INDEX, make_fixnum (FONT_SPACING_MONO));
191 FONT_SET_STYLE (ent, FONT_WIDTH_INDEX, Qnil);
192 FONT_SET_STYLE (ent, FONT_WEIGHT_INDEX, Qnil);
193 FONT_SET_STYLE (ent, FONT_SLANT_INDEX, Qnil);
194
195 return ent;
196 }
197
198 static Lisp_Object
199 haikufont_get_cache (struct frame *frame)
200 {
201 return font_cache;
202 }
203
204 static Lisp_Object
205 haikufont_weight_to_lisp (int weight)
206 {
207 switch (weight)
208 {
209 case HAIKU_THIN:
210 return Qthin;
211 case HAIKU_EXTRALIGHT:
212 return Qextra_light;
213 case HAIKU_LIGHT:
214 return Qlight;
215 case HAIKU_SEMI_LIGHT:
216 return Qsemi_light;
217 case HAIKU_REGULAR:
218 return Qnormal;
219 case HAIKU_SEMI_BOLD:
220 return Qsemi_bold;
221 case HAIKU_BOLD:
222 return Qbold;
223 case HAIKU_EXTRA_BOLD:
224 return Qextra_bold;
225 case HAIKU_BOOK:
226 return Qbook;
227 case HAIKU_HEAVY:
228 return Qheavy;
229 case HAIKU_ULTRA_HEAVY:
230 return Qultra_heavy;
231 case HAIKU_BLACK:
232 return Qblack;
233 case HAIKU_MEDIUM:
234 return Qmedium;
235 }
236 emacs_abort ();
237 }
238
239 static int
240 haikufont_lisp_to_weight (Lisp_Object weight)
241 {
242 if (EQ (weight, Qthin))
243 return HAIKU_THIN;
244 if (EQ (weight, Qultra_light))
245 return HAIKU_EXTRALIGHT;
246 if (EQ (weight, Qextra_light))
247 return HAIKU_EXTRALIGHT;
248 if (EQ (weight, Qlight))
249 return HAIKU_LIGHT;
250 if (EQ (weight, Qsemi_light))
251 return HAIKU_SEMI_LIGHT;
252 if (EQ (weight, Qnormal) || EQ (weight, Qregular))
253 return HAIKU_REGULAR;
254 if (EQ (weight, Qsemi_bold))
255 return HAIKU_SEMI_BOLD;
256 if (EQ (weight, Qbold))
257 return HAIKU_BOLD;
258 if (EQ (weight, Qextra_bold))
259 return HAIKU_EXTRA_BOLD;
260 if (EQ (weight, Qultra_bold))
261 return HAIKU_EXTRA_BOLD;
262 if (EQ (weight, Qbook))
263 return HAIKU_BOOK;
264 if (EQ (weight, Qheavy))
265 return HAIKU_HEAVY;
266 if (EQ (weight, Qultra_heavy))
267 return HAIKU_ULTRA_HEAVY;
268 if (EQ (weight, Qblack))
269 return HAIKU_BLACK;
270 if (EQ (weight, Qmedium))
271 return HAIKU_MEDIUM;
272
273 return HAIKU_REGULAR;
274 }
275
276 static Lisp_Object
277 haikufont_slant_to_lisp (enum haiku_font_slant slant)
278 {
279 switch (slant)
280 {
281 case NO_SLANT:
282 emacs_abort ();
283 case SLANT_ITALIC:
284 return Qitalic;
285 case SLANT_REGULAR:
286 return Qnormal;
287 case SLANT_OBLIQUE:
288 return Qoblique;
289 }
290 emacs_abort ();
291 }
292
293 static enum haiku_font_slant
294 haikufont_lisp_to_slant (Lisp_Object slant)
295 {
296 if (EQ (slant, Qitalic)
297 || EQ (slant, Qreverse_italic))
298 return SLANT_ITALIC;
299 if (EQ (slant, Qoblique)
300 || EQ (slant, Qreverse_oblique))
301 return SLANT_OBLIQUE;
302 if (EQ (slant, Qnormal) || EQ (slant, Qregular))
303 return SLANT_REGULAR;
304
305 return SLANT_REGULAR;
306 }
307
308 static Lisp_Object
309 haikufont_width_to_lisp (enum haiku_font_width width)
310 {
311 switch (width)
312 {
313 case NO_WIDTH:
314 emacs_abort ();
315 case ULTRA_CONDENSED:
316 return Qultra_condensed;
317 case EXTRA_CONDENSED:
318 return Qextra_condensed;
319 case CONDENSED:
320 return Qcondensed;
321 case SEMI_CONDENSED:
322 return Qsemi_condensed;
323 case NORMAL_WIDTH:
324 return Qnormal;
325 case SEMI_EXPANDED:
326 return Qsemi_expanded;
327 case EXPANDED:
328 return Qexpanded;
329 case EXTRA_EXPANDED:
330 return Qextra_expanded;
331 case ULTRA_EXPANDED:
332 return Qultra_expanded;
333 }
334
335 emacs_abort ();
336 }
337
338 static enum haiku_font_width
339 haikufont_lisp_to_width (Lisp_Object lisp)
340 {
341 if (EQ (lisp, Qultra_condensed))
342 return ULTRA_CONDENSED;
343 if (EQ (lisp, Qextra_condensed))
344 return EXTRA_CONDENSED;
345 if (EQ (lisp, Qcondensed))
346 return CONDENSED;
347 if (EQ (lisp, Qsemi_condensed))
348 return SEMI_CONDENSED;
349 if (EQ (lisp, Qnormal) || EQ (lisp, Qregular))
350 return NORMAL_WIDTH;
351 if (EQ (lisp, Qexpanded))
352 return EXPANDED;
353 if (EQ (lisp, Qextra_expanded))
354 return EXTRA_EXPANDED;
355 if (EQ (lisp, Qultra_expanded))
356 return ULTRA_EXPANDED;
357
358 return NORMAL_WIDTH;
359 }
360
361 static int
362 haikufont_maybe_handle_special_family (Lisp_Object family,
363 struct haiku_font_pattern *ptn)
364 {
365 CHECK_SYMBOL (family);
366
367 if (EQ (family, Qmonospace) || EQ (family, Qfixed) ||
368 EQ (family, Qdefault))
369 {
370 BFont_populate_fixed_family (ptn);
371 return 1;
372 }
373 else if (EQ (family, QSans_Serif))
374 {
375 BFont_populate_plain_family (ptn);
376 return 1;
377 }
378 return 0;
379 }
380
381 static Lisp_Object
382 haikufont_pattern_to_entity (struct haiku_font_pattern *ptn)
383 {
384 Lisp_Object entity, extras;
385
386 entity = font_make_entity ();
387 extras = Qnil;
388
389 ASET (entity, FONT_TYPE_INDEX, Qhaiku);
390 ASET (entity, FONT_FOUNDRY_INDEX, Qhaiku);
391 ASET (entity, FONT_FAMILY_INDEX, Qdefault);
392 ASET (entity, FONT_ADSTYLE_INDEX, Qnil);
393 ASET (entity, FONT_REGISTRY_INDEX, Qiso10646_1);
394 ASET (entity, FONT_SIZE_INDEX, make_fixnum (0));
395 ASET (entity, FONT_AVGWIDTH_INDEX, make_fixnum (0));
396 ASET (entity, FONT_SPACING_INDEX, make_fixnum (FONT_SPACING_MONO));
397
398
399
400
401 if (ptn->specified & FSPEC_INDICES)
402 extras = Fcons (Fcons (QCindices,
403 Fcons (make_fixnum (ptn->family_index),
404 make_fixnum (ptn->style_index))),
405 extras);
406
407 if (ptn->specified & FSPEC_ANTIALIAS)
408 extras = Fcons (Fcons (QCantialias,
409 ptn->use_antialiasing ? Qt : Qnil),
410 extras);
411
412 ASET (entity, FONT_EXTRA_INDEX, extras);
413
414 FONT_SET_STYLE (entity, FONT_WIDTH_INDEX, Qnormal);
415 FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX, Qnormal);
416 FONT_SET_STYLE (entity, FONT_SLANT_INDEX, Qnormal);
417
418 if (ptn->specified & FSPEC_FAMILY)
419 ASET (entity, FONT_FAMILY_INDEX, intern (ptn->family));
420 else
421 ASET (entity, FONT_FAMILY_INDEX, Qdefault);
422
423 if (ptn->specified & FSPEC_STYLE)
424 ASET (entity, FONT_ADSTYLE_INDEX, intern (ptn->style));
425 else
426 {
427 if (ptn->specified & FSPEC_WEIGHT)
428 FONT_SET_STYLE (entity, FONT_WEIGHT_INDEX,
429 haikufont_weight_to_lisp (ptn->weight));
430 if (ptn->specified & FSPEC_SLANT)
431 FONT_SET_STYLE (entity, FONT_SLANT_INDEX,
432 haikufont_slant_to_lisp (ptn->slant));
433 if (ptn->specified & FSPEC_WIDTH)
434 FONT_SET_STYLE (entity, FONT_WIDTH_INDEX,
435 haikufont_width_to_lisp (ptn->width));
436 }
437
438 if (ptn->specified & FSPEC_SPACING)
439 ASET (entity, FONT_SPACING_INDEX,
440 make_fixnum (ptn->mono_spacing_p
441 ? FONT_SPACING_MONO
442 : FONT_SPACING_PROPORTIONAL));
443
444 return entity;
445 }
446
447 static void
448 haikufont_pattern_from_object (struct haiku_font_pattern *pattern,
449 Lisp_Object font_object)
450 {
451 Lisp_Object val;
452
453 pattern->specified = 0;
454
455 val = AREF (font_object, FONT_FAMILY_INDEX);
456 if (!NILP (val))
457 {
458 pattern->specified |= FSPEC_FAMILY;
459 strncpy ((char *) &pattern->family,
460 SSDATA (SYMBOL_NAME (val)),
461 sizeof pattern->family - 1);
462 pattern->family[sizeof pattern->family - 1] = '\0';
463 }
464
465 val = AREF (font_object, FONT_ADSTYLE_INDEX);
466 if (!NILP (val))
467 {
468 pattern->specified |= FSPEC_STYLE;
469 strncpy ((char *) &pattern->style,
470 SSDATA (SYMBOL_NAME (val)),
471 sizeof pattern->style - 1);
472 pattern->style[sizeof pattern->style - 1] = '\0';
473 }
474
475 val = FONT_WEIGHT_FOR_FACE (font_object);
476 if (!NILP (val) && !EQ (val, Qunspecified))
477 {
478 pattern->specified |= FSPEC_WEIGHT;
479 pattern->weight = haikufont_lisp_to_weight (val);
480 }
481
482 val = FONT_SLANT_FOR_FACE (font_object);
483 if (!NILP (val) && !EQ (val, Qunspecified))
484 {
485 pattern->specified |= FSPEC_SLANT;
486 pattern->slant = haikufont_lisp_to_slant (val);
487 }
488
489 val = FONT_WIDTH_FOR_FACE (font_object);
490 if (!NILP (val) && !EQ (val, Qunspecified))
491 {
492 pattern->specified |= FSPEC_WIDTH;
493 pattern->width = haikufont_lisp_to_width (val);
494 }
495
496 val = assq_no_quit (QCantialias,
497 AREF (font_object, FONT_EXTRA_INDEX));
498 if (CONSP (val))
499 {
500 pattern->specified |= FSPEC_ANTIALIAS;
501 pattern->use_antialiasing = !NILP (XCDR (val));
502 }
503 }
504
505 static void
506 haikufont_spec_or_entity_to_pattern (Lisp_Object ent, int list_p,
507 struct haiku_font_pattern *ptn)
508 {
509 Lisp_Object tem;
510 ptn->specified = 0;
511
512 tem = AREF (ent, FONT_ADSTYLE_INDEX);
513 if (!NILP (tem))
514 {
515 ptn->specified |= FSPEC_STYLE;
516 strncpy ((char *) &ptn->style,
517 SSDATA (SYMBOL_NAME (tem)),
518 sizeof ptn->style - 1);
519 ptn->style[sizeof ptn->style - 1] = '\0';
520 }
521
522 tem = FONT_SLANT_SYMBOLIC (ent);
523 if (!NILP (tem) && !EQ (tem, Qunspecified))
524 {
525 ptn->specified |= FSPEC_SLANT;
526 ptn->slant = haikufont_lisp_to_slant (tem);
527 }
528
529 tem = FONT_WEIGHT_SYMBOLIC (ent);
530 if (!NILP (tem) && !EQ (tem, Qunspecified))
531 {
532 ptn->specified |= FSPEC_WEIGHT;
533 ptn->weight = haikufont_lisp_to_weight (tem);
534 }
535
536 tem = FONT_WIDTH_SYMBOLIC (ent);
537 if (!NILP (tem) && !EQ (tem, Qunspecified))
538 {
539 ptn->specified |= FSPEC_WIDTH;
540 ptn->width = haikufont_lisp_to_width (tem);
541 }
542
543 tem = AREF (ent, FONT_SPACING_INDEX);
544 if (!NILP (tem) && !EQ (tem, Qunspecified))
545 {
546 ptn->specified |= FSPEC_SPACING;
547 ptn->mono_spacing_p = XFIXNUM (tem) != FONT_SPACING_PROPORTIONAL;
548 }
549
550 tem = AREF (ent, FONT_FAMILY_INDEX);
551 if (!NILP (tem) && !EQ (tem, Qunspecified)
552 && (list_p
553 && !haikufont_maybe_handle_special_family (tem, ptn)))
554 {
555 ptn->specified |= FSPEC_FAMILY;
556 strncpy ((char *) &ptn->family,
557 SSDATA (SYMBOL_NAME (tem)),
558 sizeof ptn->family - 1);
559 ptn->family[sizeof ptn->family - 1] = '\0';
560 }
561
562 tem = assq_no_quit (QCscript, AREF (ent, FONT_EXTRA_INDEX));
563 if (!NILP (tem))
564 {
565 tem = assq_no_quit (XCDR (tem), Vscript_representative_chars);
566
567 if (CONSP (tem) && VECTORP (XCDR (tem)))
568 {
569 tem = XCDR (tem);
570
571 int count = 0;
572
573 for (int j = 0; j < ASIZE (tem); ++j)
574 if (TYPE_RANGED_FIXNUMP (uint32_t, AREF (tem, j)))
575 ++count;
576
577 if (count)
578 {
579 ptn->specified |= FSPEC_NEED_ONE_OF;
580 ptn->need_one_of_len = count;
581 ptn->need_one_of = xmalloc (count * sizeof *ptn->need_one_of);
582 count = 0;
583 for (int j = 0; j < ASIZE (tem); ++j)
584 if (TYPE_RANGED_FIXNUMP (uint32_t, AREF (tem, j)))
585 {
586 ptn->need_one_of[j] = XFIXNAT (AREF (tem, j));
587 ++count;
588 }
589 }
590 }
591 else if (CONSP (tem) && CONSP (XCDR (tem)))
592 {
593 int count = 0;
594
595 for (Lisp_Object it = XCDR (tem); CONSP (it); it = XCDR (it))
596 if (TYPE_RANGED_FIXNUMP (uint32_t, XCAR (it)))
597 ++count;
598
599 if (count)
600 {
601 ptn->specified |= FSPEC_WANTED;
602 ptn->want_chars_len = count;
603 ptn->wanted_chars = xmalloc (count * sizeof *ptn->wanted_chars);
604 count = 0;
605
606 for (tem = XCDR (tem); CONSP (tem); tem = XCDR (tem))
607 if (TYPE_RANGED_FIXNUMP (uint32_t, XCAR (tem)))
608 {
609 ptn->wanted_chars[count] = XFIXNAT (XCAR (tem));
610 ++count;
611 }
612 }
613 }
614 }
615
616 tem = assq_no_quit (QClang, AREF (ent, FONT_EXTRA_INDEX));
617 if (CONSP (tem))
618 {
619 tem = XCDR (tem);
620 if (EQ (tem, Qzh))
621 {
622 ptn->specified |= FSPEC_LANGUAGE;
623 ptn->language = LANGUAGE_CN;
624 }
625 else if (EQ (tem, Qko))
626 {
627 ptn->specified |= FSPEC_LANGUAGE;
628 ptn->language = LANGUAGE_KO;
629 }
630 else if (EQ (tem, Qjp))
631 {
632 ptn->specified |= FSPEC_LANGUAGE;
633 ptn->language = LANGUAGE_JP;
634 }
635 }
636
637 tem = assq_no_quit (QCantialias, AREF (ent, FONT_EXTRA_INDEX));
638 if (CONSP (tem))
639 {
640 ptn->specified |= FSPEC_ANTIALIAS;
641 ptn->use_antialiasing = !NILP (XCDR (tem));
642 }
643
644 tem = AREF (ent, FONT_REGISTRY_INDEX);
645 if (SYMBOLP (tem))
646 haikufont_apply_registry (ptn, tem);
647 }
648
649 static void
650 haikufont_done_with_query_pattern (struct haiku_font_pattern *ptn)
651 {
652 if (ptn->specified & FSPEC_WANTED)
653 xfree (ptn->wanted_chars);
654
655 if (ptn->specified & FSPEC_NEED_ONE_OF)
656 xfree (ptn->need_one_of);
657 }
658
659 static Lisp_Object
660 haikufont_match (struct frame *f, Lisp_Object font_spec)
661 {
662 block_input ();
663 Lisp_Object tem = Qnil;
664 struct haiku_font_pattern ptn;
665 haikufont_spec_or_entity_to_pattern (font_spec, 0, &ptn);
666 ptn.specified &= ~FSPEC_FAMILY;
667 struct haiku_font_pattern *found = BFont_find (&ptn);
668 haikufont_done_with_query_pattern (&ptn);
669 if (found)
670 {
671 tem = haikufont_pattern_to_entity (found);
672 haiku_font_pattern_free (found);
673 }
674 unblock_input ();
675 return !NILP (tem) ? tem : haikufont_get_fallback_entity ();
676 }
677
678 static Lisp_Object
679 haikufont_list (struct frame *f, Lisp_Object font_spec)
680 {
681 Lisp_Object lst, tem;
682 struct haiku_font_pattern ptn, *found, *pt;
683
684 lst = Qnil;
685
686 block_input ();
687
688
689
690 tem = assq_no_quit (QCotf, AREF (font_spec, FONT_EXTRA_INDEX));
691
692 if (CONSP (tem) && !NILP (XCDR (tem)))
693 {
694 unblock_input ();
695 return Qnil;
696 }
697
698 haikufont_spec_or_entity_to_pattern (font_spec, 1, &ptn);
699 found = BFont_find (&ptn);
700 haikufont_done_with_query_pattern (&ptn);
701 if (found)
702 {
703 for (pt = found; pt; pt = pt->next)
704 lst = Fcons (haikufont_pattern_to_entity (pt), lst);
705 haiku_font_pattern_free (found);
706 }
707 unblock_input ();
708 return lst;
709 }
710
711 static void
712 haiku_bulk_encode (struct haikufont_info *font_info, int block)
713 {
714 unsigned short *unichars = xmalloc (0x101 * sizeof (*unichars));
715 unsigned int i, idx;
716
717 block_input ();
718
719 font_info->glyphs[block] = unichars;
720 if (!unichars)
721 emacs_abort ();
722
723 for (idx = block << 8, i = 0; i < 0x100; idx++, i++)
724 unichars[i] = idx;
725 unichars[0x100] = 0;
726
727
728
729 if (!BFont_have_char_block (font_info->be_font,
730 unichars[0], unichars[0xff]))
731 {
732 for (int i = 0; i < 0x100; ++i)
733 if (!BFont_have_char_p (font_info->be_font, unichars[i]))
734 unichars[i] = 0xFFFF;
735 }
736
737 unblock_input ();
738 }
739
740 static unsigned int
741 haikufont_encode_char (struct font *font, int c)
742 {
743 struct haikufont_info *font_info = (struct haikufont_info *) font;
744 unsigned char high = (c & 0xff00) >> 8, low = c & 0x00ff;
745 unsigned short g;
746
747 if (c > 0xFFFF)
748 return FONT_INVALID_CODE;
749
750 if (!font_info->glyphs[high])
751 haiku_bulk_encode (font_info, high);
752 g = font_info->glyphs[high][low];
753 return g == 0xFFFF ? FONT_INVALID_CODE : g;
754 }
755
756 static Lisp_Object
757 haikufont_open (struct frame *f, Lisp_Object font_entity, int pixel_size)
758 {
759 struct haikufont_info *font_info;
760 struct haiku_font_pattern ptn;
761 struct font *font;
762 void *be_font;
763 Lisp_Object font_object, extra, indices, antialias;
764 int px_size, min_width, max_width;
765 int avg_width, height, space_width, ascent;
766 int descent, underline_pos, underline_thickness;
767
768 if (XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX)) != 0)
769 pixel_size = XFIXNUM (AREF (font_entity, FONT_SIZE_INDEX));
770 else if (pixel_size == 0)
771 {
772
773
774
775
776
777 if (FRAME_FONT (f))
778 pixel_size = FRAME_FONT (f)->pixel_size;
779 else
780 pixel_size = 12;
781 }
782
783 extra = AREF (font_entity, FONT_EXTRA_INDEX);
784
785 indices = assq_no_quit (QCindices, extra);
786 antialias = assq_no_quit (QCantialias, extra);
787
788 if (CONSP (indices))
789 indices = XCDR (indices);
790
791
792
793
794 if (CONSP (indices) && FIXNUMP (XCAR (indices))
795 && FIXNUMP (XCDR (indices)))
796 {
797 block_input ();
798 be_font = be_open_font_at_index (XFIXNUM (XCAR (indices)),
799 XFIXNUM (XCDR (indices)),
800 pixel_size);
801 unblock_input ();
802
803 if (!be_font)
804 return Qnil;
805 }
806 else
807 {
808 block_input ();
809 haikufont_spec_or_entity_to_pattern (font_entity, 1, &ptn);
810
811 if (BFont_open_pattern (&ptn, &be_font, pixel_size))
812 {
813 haikufont_done_with_query_pattern (&ptn);
814 unblock_input ();
815 return Qnil;
816 }
817
818 haikufont_done_with_query_pattern (&ptn);
819 unblock_input ();
820 }
821
822 block_input ();
823
824 font_object = font_make_object (VECSIZE (struct haikufont_info),
825 font_entity, pixel_size);
826
827 ASET (font_object, FONT_TYPE_INDEX, Qhaiku);
828 font_info = (struct haikufont_info *) XFONT_OBJECT (font_object);
829 font = (struct font *) font_info;
830
831 if (!font)
832 {
833 unblock_input ();
834 return Qnil;
835 }
836
837 font_info->be_font = be_font;
838 font_info->glyphs = xzalloc (0x100 * sizeof *font_info->glyphs);
839
840 if (CONSP (antialias))
841 be_set_font_antialiasing (be_font, !NILP (XCDR (antialias)));
842
843 font->pixel_size = 0;
844 font->driver = &haikufont_driver;
845 font->encoding_charset = -1;
846 font->repertory_charset = -1;
847 font->default_ascent = 0;
848 font->vertical_centering = 0;
849 font->baseline_offset = 0;
850 font->relative_compose = 0;
851
852 font_info->metrics = NULL;
853 font_info->metrics_nrows = 0;
854
855 BFont_metrics (be_font, &px_size, &min_width,
856 &max_width, &avg_width, &height,
857 &space_width, &ascent, &descent,
858 &underline_pos, &underline_thickness);
859
860 font->pixel_size = px_size;
861 font->min_width = min_width;
862 font->max_width = max_width;
863 font->average_width = avg_width;
864 font->height = height;
865 font->space_width = space_width;
866 font->ascent = ascent;
867 font->descent = descent;
868 font->default_ascent = ascent;
869 font->underline_position = underline_pos;
870 font->underline_thickness = underline_thickness;
871
872 font->vertical_centering = 0;
873 font->baseline_offset = 0;
874 font->relative_compose = 0;
875
876 font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil);
877
878 unblock_input ();
879 return font_object;
880 }
881
882 static void
883 haikufont_close (struct font *font)
884 {
885 struct haikufont_info *info = (struct haikufont_info *) font;
886 int i;
887
888 if (font_data_structures_may_be_ill_formed ())
889 return;
890
891 block_input ();
892 if (info && info->be_font)
893 BFont_close (info->be_font);
894
895 for (i = 0; i < info->metrics_nrows; i++)
896 {
897 if (info->metrics[i])
898 xfree (info->metrics[i]);
899 }
900
901 if (info->metrics)
902 xfree (info->metrics);
903
904 for (i = 0; i < 0x100; ++i)
905 {
906 if (info->glyphs[i])
907 xfree (info->glyphs[i]);
908 }
909
910 xfree (info->glyphs);
911 unblock_input ();
912 }
913
914 static void
915 haikufont_prepare_face (struct frame *f, struct face *face)
916 {
917
918 }
919
920 static void
921 haikufont_glyph_extents (struct font *font, unsigned code,
922 struct font_metrics *metrics)
923 {
924 struct haikufont_info *info = (struct haikufont_info *) font;
925
926 struct font_metrics *cache;
927 int row, col;
928
929 row = code / METRICS_NCOLS_PER_ROW;
930 col = code % METRICS_NCOLS_PER_ROW;
931 if (row >= info->metrics_nrows)
932 {
933 info->metrics =
934 xrealloc (info->metrics,
935 sizeof (struct font_metrics *) * (row + 1));
936 memset (info->metrics + info->metrics_nrows, 0,
937 (sizeof (struct font_metrics *)
938 * (row + 1 - info->metrics_nrows)));
939 info->metrics_nrows = row + 1;
940 }
941
942 if (info->metrics[row] == NULL)
943 {
944 struct font_metrics *new;
945 int i;
946
947 new = xmalloc (sizeof (struct font_metrics) * METRICS_NCOLS_PER_ROW);
948 for (i = 0; i < METRICS_NCOLS_PER_ROW; i++)
949 METRICS_SET_STATUS (new + i, METRICS_INVALID);
950 info->metrics[row] = new;
951 }
952 cache = info->metrics[row] + col;
953
954 if (METRICS_STATUS (cache) == METRICS_INVALID)
955 {
956 unsigned char utf8[MAX_MULTIBYTE_LENGTH];
957 memset (utf8, 0, MAX_MULTIBYTE_LENGTH);
958 CHAR_STRING (code, utf8);
959 int advance, lb, rb;
960 BFont_char_bounds (info->be_font, (const char *) utf8, &advance, &lb, &rb);
961
962 cache->lbearing = lb;
963 cache->rbearing = rb;
964 cache->width = advance;
965 cache->ascent = font->ascent;
966 cache->descent = font->descent;
967 }
968
969 if (metrics)
970 *metrics = *cache;
971 }
972
973 static void
974 haikufont_text_extents (struct font *font, const unsigned int *code,
975 int nglyphs, struct font_metrics *metrics)
976 {
977 int totalwidth = 0;
978 memset (metrics, 0, sizeof (struct font_metrics));
979
980 block_input ();
981 for (int i = 0; i < nglyphs; i++)
982 {
983 struct font_metrics m;
984 haikufont_glyph_extents (font, code[i], &m);
985 if (metrics)
986 {
987 if (totalwidth + m.lbearing < metrics->lbearing)
988 metrics->lbearing = totalwidth + m.lbearing;
989 if (totalwidth + m.rbearing > metrics->rbearing)
990 metrics->rbearing = totalwidth + m.rbearing;
991 if (m.ascent > metrics->ascent)
992 metrics->ascent = m.ascent;
993 if (m.descent > metrics->descent)
994 metrics->descent = m.descent;
995 }
996 totalwidth += m.width;
997 }
998
999 unblock_input ();
1000
1001 if (metrics)
1002 metrics->width = totalwidth;
1003 }
1004
1005 static Lisp_Object
1006 haikufont_shape (Lisp_Object lgstring, Lisp_Object direction)
1007 {
1008 struct haikufont_info *font =
1009 (struct haikufont_info *) CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
1010 int *advance, *lb, *rb;
1011 ptrdiff_t glyph_len, len, i, b_len;
1012 Lisp_Object tem;
1013 char *b;
1014 uint32_t *mb_buf;
1015
1016 glyph_len = LGSTRING_GLYPH_LEN (lgstring);
1017 for (i = 0; i < glyph_len; ++i)
1018 {
1019 tem = LGSTRING_GLYPH (lgstring, i);
1020
1021 if (NILP (tem))
1022 break;
1023 }
1024
1025 len = i;
1026
1027 if (INT_MAX / 2 < len)
1028 memory_full (SIZE_MAX);
1029
1030 block_input ();
1031
1032 b_len = 0;
1033 b = xmalloc (b_len);
1034 mb_buf = alloca (len * sizeof *mb_buf);
1035
1036 for (i = b_len; i < len; ++i)
1037 {
1038 uint32_t c = LGLYPH_CHAR (LGSTRING_GLYPH (lgstring, i));
1039 mb_buf[i] = c;
1040 unsigned char mb[MAX_MULTIBYTE_LENGTH];
1041 int slen = CHAR_STRING (c, mb);
1042
1043 b = xrealloc (b, b_len = (b_len + slen));
1044 if (len == 1)
1045 b[b_len - slen] = mb[0];
1046 else
1047 memcpy (b + b_len - slen, mb, slen);
1048 }
1049
1050 advance = alloca (len * sizeof *advance);
1051 lb = alloca (len * sizeof *lb);
1052 rb = alloca (len * sizeof *rb);
1053
1054 eassert (font->be_font);
1055 BFont_nchar_bounds (font->be_font, b, advance, lb, rb, len);
1056 xfree (b);
1057
1058 for (i = 0; i < len; ++i)
1059 {
1060 tem = LGSTRING_GLYPH (lgstring, i);
1061 if (NILP (tem))
1062 {
1063 tem = LGLYPH_NEW ();
1064 LGSTRING_SET_GLYPH (lgstring, i, tem);
1065 }
1066
1067 LGLYPH_SET_FROM (tem, i);
1068 LGLYPH_SET_TO (tem, i);
1069 LGLYPH_SET_CHAR (tem, mb_buf[i]);
1070 LGLYPH_SET_CODE (tem, mb_buf[i]);
1071
1072 LGLYPH_SET_WIDTH (tem, advance[i]);
1073 LGLYPH_SET_LBEARING (tem, lb[i]);
1074 LGLYPH_SET_RBEARING (tem, rb[i]);
1075 LGLYPH_SET_ASCENT (tem, font->font.ascent);
1076 LGLYPH_SET_DESCENT (tem, font->font.descent);
1077 }
1078
1079 unblock_input ();
1080
1081 return make_fixnum (len);
1082 }
1083
1084 static int
1085 haikufont_draw (struct glyph_string *s, int from, int to,
1086 int x, int y, bool with_background)
1087 {
1088 struct frame *f = s->f;
1089 struct face *face = s->face;
1090 struct font_info *info = (struct font_info *) s->font;
1091 unsigned char mb[MAX_MULTIBYTE_LENGTH];
1092 void *view = FRAME_HAIKU_VIEW (f);
1093 unsigned long foreground, background;
1094
1095 block_input ();
1096 prepare_face_for_display (s->f, face);
1097
1098 if (s->hl != DRAW_CURSOR)
1099 {
1100 foreground = s->face->foreground;
1101 background = s->face->background;
1102 }
1103 else
1104 haiku_merge_cursor_foreground (s, &foreground, &background);
1105
1106
1107
1108 if (with_background)
1109 {
1110 int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font);
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121 if (s->first_glyph->type == GLYPHLESS_GLYPH
1122 && (s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE
1123 || s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM))
1124 height = ascent =
1125 s->first_glyph->slice.glyphless.lower_yoff
1126 - s->first_glyph->slice.glyphless.upper_yoff;
1127
1128 haiku_draw_background_rect (s, s->face, x, y - ascent,
1129 s->width, height);
1130 }
1131
1132 BView_SetHighColor (view, foreground);
1133 BView_MovePenTo (view, x, y);
1134 BView_SetFont (view, ((struct haikufont_info *) info)->be_font);
1135
1136 if (from == to)
1137 {
1138 int len = CHAR_STRING (s->char2b[from], mb);
1139 BView_DrawString (view, (char *) mb, len);
1140 }
1141 else
1142 {
1143 ptrdiff_t b_len = 0;
1144 char *b = alloca ((to - from + 1) * MAX_MULTIBYTE_LENGTH);
1145
1146 for (int idx = from; idx < to; ++idx)
1147 {
1148 int len = CHAR_STRING (s->char2b[idx], mb);
1149 b_len += len;
1150
1151 if (len == 1)
1152 b[b_len - len] = mb[0];
1153 else
1154 memcpy (b + b_len - len, mb, len);
1155 }
1156
1157 BView_DrawString (view, b, b_len);
1158 }
1159
1160 unblock_input ();
1161 return 1;
1162 }
1163
1164 static Lisp_Object
1165 haikufont_list_family (struct frame *f)
1166 {
1167 Lisp_Object list = Qnil;
1168 size_t length;
1169 ptrdiff_t idx;
1170 haiku_font_family_or_style *styles;
1171
1172 block_input ();
1173 styles = be_list_font_families (&length);
1174 unblock_input ();
1175
1176 if (!styles)
1177 return list;
1178
1179 block_input ();
1180 for (idx = 0; idx < length; ++idx)
1181 {
1182 if (styles[idx][0])
1183 list = Fcons (intern ((char *) &styles[idx]), list);
1184 }
1185
1186 free (styles);
1187 unblock_input ();
1188
1189 return list;
1190 }
1191
1192
1193
1194 static const char *const haikufont_booleans[] =
1195 {
1196 ":antialias",
1197 NULL,
1198 };
1199
1200
1201 static const char *const haikufont_non_booleans[1];
1202
1203 static void
1204 haikufont_filter_properties (Lisp_Object font, Lisp_Object alist)
1205 {
1206 font_filter_properties (font, alist, haikufont_booleans,
1207 haikufont_non_booleans);
1208 }
1209
1210 struct font_driver const haikufont_driver =
1211 {
1212 .type = LISPSYM_INITIALLY (Qhaiku),
1213 .case_sensitive = true,
1214 .get_cache = haikufont_get_cache,
1215 .list = haikufont_list,
1216 .match = haikufont_match,
1217 .draw = haikufont_draw,
1218 .open_font = haikufont_open,
1219 .close_font = haikufont_close,
1220 .prepare_face = haikufont_prepare_face,
1221 .encode_char = haikufont_encode_char,
1222 .text_extents = haikufont_text_extents,
1223 .shape = haikufont_shape,
1224 .list_family = haikufont_list_family,
1225 .filter_properties = haikufont_filter_properties,
1226 };
1227
1228 static bool
1229 haikufont_should_quit_popup (void)
1230 {
1231 return !NILP (Vquit_flag);
1232 }
1233
1234 DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0,
1235 doc:
1236
1237
1238
1239
1240
1241 )
1242 (Lisp_Object frame, Lisp_Object exclude_proportional)
1243 {
1244 struct frame *f;
1245 struct font *font;
1246 Lisp_Object font_object;
1247 haiku_font_family_or_style family, style;
1248 int rc, size, initial_family, initial_style, initial_size;
1249 struct haiku_font_pattern pattern;
1250 Lisp_Object lfamily, lweight, lslant, lwidth, ladstyle, lsize;
1251 bool disable_antialiasing, initial_antialias;
1252
1253 f = decode_window_system_frame (frame);
1254
1255 if (popup_activated_p)
1256 error ("Trying to use a menu from within a menu-entry");
1257
1258 initial_style = -1;
1259 initial_family = -1;
1260 initial_size = -1;
1261 initial_antialias = true;
1262
1263 font = FRAME_FONT (f);
1264
1265 if (font)
1266 {
1267 XSETFONT (font_object, font);
1268
1269 haikufont_pattern_from_object (&pattern, font_object);
1270 be_find_font_indices (&pattern, &initial_family,
1271 &initial_style);
1272 haikufont_done_with_query_pattern (&pattern);
1273
1274 initial_size = font->pixel_size;
1275
1276
1277
1278 if (pattern.specified & FSPEC_ANTIALIAS)
1279 initial_antialias = pattern.use_antialiasing;
1280 }
1281
1282 popup_activated_p++;
1283 unrequest_sigio ();
1284 rc = be_select_font (process_pending_signals,
1285 haikufont_should_quit_popup,
1286 &family, &style, &size,
1287 !NILP (exclude_proportional),
1288 initial_family, initial_style,
1289 initial_size, initial_antialias,
1290 &disable_antialiasing);
1291 request_sigio ();
1292 popup_activated_p--;
1293
1294 if (!rc)
1295 quit ();
1296
1297 be_font_style_to_flags (style, &pattern);
1298
1299 lfamily = build_string_from_utf8 (family);
1300 lweight = (pattern.specified & FSPEC_WEIGHT
1301 ? haikufont_weight_to_lisp (pattern.weight) : Qnil);
1302 lslant = (pattern.specified & FSPEC_SLANT
1303 ? haikufont_slant_to_lisp (pattern.slant) : Qnil);
1304 lwidth = (pattern.specified & FSPEC_WIDTH
1305 ? haikufont_width_to_lisp (pattern.width) : Qnil);
1306 ladstyle = (pattern.specified & FSPEC_STYLE
1307 ? intern (pattern.style) : Qnil);
1308 lsize = (size >= 0 ? make_fixnum (size) : Qnil);
1309
1310 if (disable_antialiasing)
1311 return CALLN (Ffont_spec, QCfamily, lfamily,
1312 QCweight, lweight, QCslant, lslant,
1313 QCwidth, lwidth, QCadstyle, ladstyle,
1314 QCsize, lsize, QCantialias, Qnil);
1315
1316 return CALLN (Ffont_spec, QCfamily, lfamily,
1317 QCweight, lweight, QCslant, lslant,
1318 QCwidth, lwidth, QCadstyle, ladstyle,
1319 QCsize, lsize);
1320 }
1321
1322 DEFUN ("font-get-system-normal-font", Ffont_get_system_normal_font,
1323 Sfont_get_system_normal_font, 0, 0, 0,
1324 doc: )
1325 (void)
1326 {
1327 Lisp_Object value;
1328 const char *name, *style;
1329 struct haiku_font_pattern pattern;
1330 Lisp_Object lfamily, lweight, lslant, lwidth, ladstyle;
1331 int size;
1332
1333 if (!be_lock_font_defaults ())
1334 return Qnil;
1335
1336 name = be_get_font_default (DEFAULT_FAMILY);
1337 style = be_get_font_default (DEFAULT_STYLE);
1338 size = be_get_font_size (DEFAULT_FAMILY);
1339
1340 be_font_style_to_flags (style, &pattern);
1341
1342 lfamily = build_string_from_utf8 (name);
1343 lweight = (pattern.specified & FSPEC_WEIGHT
1344 ? haikufont_weight_to_lisp (pattern.weight) : Qnil);
1345 lslant = (pattern.specified & FSPEC_SLANT
1346 ? haikufont_slant_to_lisp (pattern.slant) : Qnil);
1347 lwidth = (pattern.specified & FSPEC_WIDTH
1348 ? haikufont_width_to_lisp (pattern.width) : Qnil);
1349 ladstyle = (pattern.specified & FSPEC_STYLE
1350 ? intern (pattern.style) : Qnil);
1351
1352 value = CALLN (Ffont_spec, QCfamily, lfamily,
1353 QCweight, lweight, QCslant, lslant,
1354 QCwidth, lwidth, QCadstyle, ladstyle,
1355 QCsize, make_fixnum (size));
1356 be_unlock_font_defaults ();
1357
1358 return value;
1359 }
1360
1361 DEFUN ("font-get-system-font", Ffont_get_system_font,
1362 Sfont_get_system_font, 0, 0, 0,
1363 doc: )
1364 (void)
1365 {
1366 Lisp_Object value;
1367 const char *name, *style;
1368 struct haiku_font_pattern pattern;
1369 Lisp_Object lfamily, lweight, lslant, lwidth, ladstyle;
1370 int size;
1371
1372 if (!be_lock_font_defaults ())
1373 return Qnil;
1374
1375 name = be_get_font_default (FIXED_FAMILY);
1376 style = be_get_font_default (FIXED_STYLE);
1377 size = be_get_font_size (FIXED_FAMILY);
1378
1379 be_font_style_to_flags (style, &pattern);
1380
1381 lfamily = build_string_from_utf8 (name);
1382 lweight = (pattern.specified & FSPEC_WEIGHT
1383 ? haikufont_weight_to_lisp (pattern.weight) : Qnil);
1384 lslant = (pattern.specified & FSPEC_SLANT
1385 ? haikufont_slant_to_lisp (pattern.slant) : Qnil);
1386 lwidth = (pattern.specified & FSPEC_WIDTH
1387 ? haikufont_width_to_lisp (pattern.width) : Qnil);
1388 ladstyle = (pattern.specified & FSPEC_STYLE
1389 ? intern (pattern.style) : Qnil);
1390
1391 value = CALLN (Ffont_spec, QCfamily, lfamily,
1392 QCweight, lweight, QCslant, lslant,
1393 QCwidth, lwidth, QCadstyle, ladstyle,
1394 QCsize, make_fixnum (size));
1395 be_unlock_font_defaults ();
1396
1397 return value;
1398 }
1399
1400 void
1401 haiku_handle_font_change_event (struct haiku_font_change_event *event,
1402 struct input_event *ie)
1403 {
1404 ie->kind = CONFIG_CHANGED_EVENT;
1405
1406
1407 ie->frame_or_window = XCAR (x_display_list->name_list_element);
1408
1409
1410 ie->arg = (event->what == FIXED_FAMILY
1411 ? Qmonospace_font_name : Qfont_name);
1412 }
1413
1414 static void
1415 syms_of_haikufont_for_pdumper (void)
1416 {
1417 register_font_driver (&haikufont_driver, NULL);
1418 }
1419
1420 void
1421 syms_of_haikufont (void)
1422 {
1423 DEFSYM (QSans_Serif, "Sans Serif");
1424 DEFSYM (Qfontsize, "fontsize");
1425 DEFSYM (Qfixed, "fixed");
1426 DEFSYM (Qplain, "plain");
1427 DEFSYM (Qultra_light, "ultra-light");
1428 DEFSYM (Qthin, "thin");
1429 DEFSYM (Qreverse_italic, "reverse-italic");
1430 DEFSYM (Qreverse_oblique, "reverse-oblique");
1431 DEFSYM (Qmonospace, "monospace");
1432 DEFSYM (Qultra_condensed, "ultra-condensed");
1433 DEFSYM (Qextra_condensed, "extra-condensed");
1434 DEFSYM (Qcondensed, "condensed");
1435 DEFSYM (Qsemi_condensed, "semi-condensed");
1436 DEFSYM (Qsemi_expanded, "semi-expanded");
1437 DEFSYM (Qexpanded, "expanded");
1438 DEFSYM (Qextra_expanded, "extra-expanded");
1439 DEFSYM (Qultra_expanded, "ultra-expanded");
1440 DEFSYM (Qregular, "regular");
1441 DEFSYM (Qzh, "zh");
1442 DEFSYM (Qko, "ko");
1443 DEFSYM (Qjp, "jp");
1444
1445 DEFSYM (QCindices, ":indices");
1446
1447 DEFSYM (Qmonospace_font_name, "monospace-font-name");
1448 DEFSYM (Qfont_name, "font-name");
1449 DEFSYM (Qdynamic_setting, "dynamic-setting");
1450
1451 DEFVAR_BOOL ("font-use-system-font", use_system_font,
1452 doc: );
1453 use_system_font = false;
1454
1455 #ifdef USE_BE_CAIRO
1456 Fput (Qhaiku, Qfont_driver_superseded_by, Qftcr);
1457 #endif
1458 pdumper_do_now_and_after_load (syms_of_haikufont_for_pdumper);
1459
1460 font_cache = list (Qnil);
1461 staticpro (&font_cache);
1462
1463 defsubr (&Sx_select_font);
1464 defsubr (&Sfont_get_system_normal_font);
1465 defsubr (&Sfont_get_system_font);
1466
1467 be_init_font_data ();
1468
1469
1470
1471 Fprovide (Qdynamic_setting, Qnil);
1472 }