This source file includes following definitions.
- ftcrfont_glyph_extents
- ftcrfont_list
- ftcrfont_match
- ftcrfont_open
- ftcrfont_close
- ftcrfont_has_char
- ftcrfont_encode_char
- ftcrfont_text_extents
- ftcrfont_get_bitmap
- ftcrfont_anchor_point
- ftcrfont_otf_capability
- ftcrfont_shape
- ftcrfont_variation_glyphs
- ftcrfont_draw
- ftcrfont_cached_font_ok
- ftcrhbfont_list
- ftcrhbfont_match
- ftcrhbfont_begin_hb_font
- ftcrhbfont_end_hb_font
- syms_of_ftcrfont
- ftcrfont_get_default_font_options
- syms_of_ftcrfont_for_pdumper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 #include <config.h>
21 #include <math.h>
22 #include <cairo-ft.h>
23
24 #include "lisp.h"
25 #ifdef HAVE_X_WINDOWS
26 #include "xterm.h"
27 #elif HAVE_HAIKU
28 #include "haikuterm.h"
29 #include "haiku_support.h"
30 #include "termchar.h"
31 #else
32 #include "pgtkterm.h"
33 #endif
34 #include "blockinput.h"
35 #include "charset.h"
36 #include "composite.h"
37 #include "font.h"
38 #include "ftfont.h"
39 #include "pdumper.h"
40 #ifdef HAVE_PGTK
41 #include "xsettings.h"
42 #endif
43
44 #ifdef USE_BE_CAIRO
45 #define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
46 #define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
47 #define BLUE_FROM_ULONG(color) ((color) & 0xff)
48 #endif
49
50 #define METRICS_NCOLS_PER_ROW (128)
51
52 enum metrics_status
53 {
54 METRICS_INVALID = -1,
55 };
56
57 #define METRICS_STATUS(metrics) ((metrics)->ascent + (metrics)->descent)
58 #define METRICS_SET_STATUS(metrics, status) \
59 ((metrics)->ascent = 0, (metrics)->descent = (status))
60
61 static int
62 ftcrfont_glyph_extents (struct font *font,
63 unsigned glyph,
64 struct font_metrics *metrics)
65 {
66 struct font_info *ftcrfont_info = (struct font_info *) font;
67 int row, col;
68 struct font_metrics *cache;
69
70 row = glyph / METRICS_NCOLS_PER_ROW;
71 col = glyph % METRICS_NCOLS_PER_ROW;
72 if (row >= ftcrfont_info->metrics_nrows)
73 {
74 ftcrfont_info->metrics =
75 xrealloc (ftcrfont_info->metrics,
76 sizeof (struct font_metrics *) * (row + 1));
77 memset (ftcrfont_info->metrics + ftcrfont_info->metrics_nrows, 0,
78 (sizeof (struct font_metrics *)
79 * (row + 1 - ftcrfont_info->metrics_nrows)));
80 ftcrfont_info->metrics_nrows = row + 1;
81 }
82 if (ftcrfont_info->metrics[row] == NULL)
83 {
84 struct font_metrics *new;
85 int i;
86
87 new = xmalloc (sizeof (struct font_metrics) * METRICS_NCOLS_PER_ROW);
88 for (i = 0; i < METRICS_NCOLS_PER_ROW; i++)
89 METRICS_SET_STATUS (new + i, METRICS_INVALID);
90 ftcrfont_info->metrics[row] = new;
91 }
92 cache = ftcrfont_info->metrics[row] + col;
93
94 if (METRICS_STATUS (cache) == METRICS_INVALID)
95 {
96 cairo_glyph_t cr_glyph = {.index = glyph};
97 cairo_text_extents_t extents;
98
99 cairo_scaled_font_glyph_extents (ftcrfont_info->cr_scaled_font,
100 &cr_glyph, 1, &extents);
101 cache->lbearing = floor (extents.x_bearing);
102 cache->rbearing = ceil (extents.width + extents.x_bearing);
103 cache->width = lround (extents.x_advance);
104
105
106
107
108
109 cache->ascent = ceil (- extents.y_bearing - 1.0 / 256);
110 cache->descent = ceil (extents.height + extents.y_bearing);
111 }
112
113 if (metrics)
114 *metrics = *cache;
115
116 return cache->width;
117 }
118
119 static Lisp_Object
120 ftcrfont_list (struct frame *f, Lisp_Object spec)
121 {
122 return ftfont_list2 (f, spec, Qftcr);
123 }
124
125 static Lisp_Object
126 ftcrfont_match (struct frame *f, Lisp_Object spec)
127 {
128 return ftfont_match2 (f, spec, Qftcr);
129 }
130
131 static Lisp_Object
132 ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
133 {
134 FcResult result;
135 Lisp_Object val, filename, font_object;
136 FcPattern *pat, *match;
137 struct font_info *ftcrfont_info;
138 struct font *font;
139 double size = 0;
140 cairo_font_face_t *font_face;
141 cairo_font_extents_t extents;
142 FT_Face ft_face;
143 FcMatrix *matrix;
144
145 val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
146 if (! CONSP (val))
147 return Qnil;
148 val = XCDR (val);
149 filename = XCAR (val);
150 size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX));
151 if (size == 0)
152 size = pixel_size;
153
154 block_input ();
155
156 pat = ftfont_entity_pattern (entity, pixel_size);
157 FcConfigSubstitute (NULL, pat, FcMatchPattern);
158 FcDefaultSubstitute (pat);
159 match = FcFontMatch (NULL, pat, &result);
160 ftfont_fix_match (pat, match);
161
162 FcPatternDestroy (pat);
163 font_face = cairo_ft_font_face_create_for_pattern (match);
164 if (!font_face
165 || cairo_font_face_status (font_face) != CAIRO_STATUS_SUCCESS)
166 {
167 unblock_input ();
168 FcPatternDestroy (match);
169 return Qnil;
170 }
171 cairo_matrix_t font_matrix, ctm;
172 cairo_matrix_init_scale (&font_matrix, pixel_size, pixel_size);
173 cairo_matrix_init_identity (&ctm);
174
175 #ifdef HAVE_PGTK
176 cairo_font_options_t *options = xsettings_get_font_options ();
177 #else
178 cairo_font_options_t *options = cairo_font_options_create ();
179 #endif
180 #ifdef USE_BE_CAIRO
181 if (be_use_subpixel_antialiasing ())
182 cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_SUBPIXEL);
183 #endif
184 cairo_scaled_font_t *scaled_font
185 = cairo_scaled_font_create (font_face, &font_matrix, &ctm, options);
186 cairo_font_face_destroy (font_face);
187 cairo_font_options_destroy (options);
188 unblock_input ();
189 if (!scaled_font
190 || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS)
191 {
192 FcPatternDestroy (match);
193 return Qnil;
194 }
195 ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
196 if (!ft_face)
197 {
198 FcPatternDestroy (match);
199 return Qnil;
200 }
201
202 font_object = font_build_object (VECSIZE (struct font_info),
203 AREF (entity, FONT_TYPE_INDEX),
204 entity, size);
205 ASET (font_object, FONT_FILE_INDEX, filename);
206 font = XFONT_OBJECT (font_object);
207 font->pixel_size = size;
208 #ifdef HAVE_HARFBUZZ
209 if (EQ (AREF (font_object, FONT_TYPE_INDEX), Qftcrhb))
210 font->driver = &ftcrhbfont_driver;
211 else
212 #endif
213 font->driver = &ftcrfont_driver;
214 font->encoding_charset = font->repertory_charset = -1;
215
216 ftcrfont_info = (struct font_info *) font;
217 ftcrfont_info->cr_scaled_font = scaled_font;
218
219
220 ftcrfont_info->matrix.xx = 0;
221 if (FcPatternGetMatrix (match, FC_MATRIX, 0, &matrix) == FcResultMatch)
222 {
223 ftcrfont_info->matrix.xx = 0x10000L * matrix->xx;
224 ftcrfont_info->matrix.yy = 0x10000L * matrix->yy;
225 ftcrfont_info->matrix.xy = 0x10000L * matrix->xy;
226 ftcrfont_info->matrix.yx = 0x10000L * matrix->yx;
227 }
228
229 ftcrfont_info->metrics = NULL;
230 ftcrfont_info->metrics_nrows = 0;
231
232 block_input ();
233 cairo_glyph_t stack_glyph;
234 font->min_width = font->max_width = 0;
235 font->average_width = font->space_width = 0;
236 int n = 0;
237 for (char c = 32; c < 127; c++)
238 {
239 cairo_glyph_t *glyphs = &stack_glyph;
240 int num_glyphs = 1;
241 cairo_status_t status =
242 cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font,
243 0, 0, &c, 1, &glyphs, &num_glyphs,
244 NULL, NULL, NULL);
245
246
247
248 if (status != CAIRO_STATUS_SUCCESS)
249 stack_glyph.index = 0;
250 else if (glyphs != &stack_glyph)
251 {
252 cairo_glyph_free (glyphs);
253 stack_glyph.index = 0;
254 }
255 int this_width = ftcrfont_glyph_extents (font, stack_glyph.index, NULL);
256 if (this_width > 0)
257 {
258 if (! font->min_width || font->min_width > this_width)
259 font->min_width = this_width;
260 if (this_width > font->max_width)
261 font->max_width = this_width;
262 if (c == 32)
263 font->space_width = this_width;
264 font->average_width += this_width;
265 n++;
266 }
267 }
268 if (n)
269 font->average_width /= n;
270
271 cairo_scaled_font_extents (ftcrfont_info->cr_scaled_font, &extents);
272 font->ascent = lround (extents.ascent);
273 val = assq_no_quit (QCminspace, AREF (entity, FONT_EXTRA_INDEX));
274 if (!(CONSP (val) && NILP (XCDR (val))))
275 {
276 font->descent = lround (extents.descent);
277 font->height = font->ascent + font->descent;
278 }
279 else
280 {
281 font->height = lround (extents.height);
282 font->descent = font->height - font->ascent;
283 }
284
285 if (XFIXNUM (AREF (entity, FONT_SIZE_INDEX)) == 0)
286 {
287 int upEM = ft_face->units_per_EM;
288
289 font->underline_position = -ft_face->underline_position * size / upEM;
290 font->underline_thickness = ft_face->underline_thickness * size / upEM;
291 if (font->underline_thickness > 2)
292 font->underline_position -= font->underline_thickness / 2;
293 }
294 else
295 {
296 font->underline_position = -1;
297 font->underline_thickness = 0;
298 }
299 #ifdef HAVE_LIBOTF
300 ftcrfont_info->maybe_otf = (ft_face->face_flags & FT_FACE_FLAG_SFNT) != 0;
301 ftcrfont_info->otf = NULL;
302 #endif
303 #ifdef HAVE_HARFBUZZ
304 ftcrfont_info->hb_font = NULL;
305 #endif
306 if (ft_face->units_per_EM)
307 ftcrfont_info->bitmap_position_unit = 0;
308 else
309 ftcrfont_info->bitmap_position_unit = (extents.height
310 / ft_face->size->metrics.height);
311 cairo_ft_scaled_font_unlock_face (scaled_font);
312 ftcrfont_info->ft_size = NULL;
313 unblock_input ();
314
315 font->baseline_offset = 0;
316 font->relative_compose = 0;
317 font->default_ascent = 0;
318 font->vertical_centering = false;
319 eassert (font->max_width < 512 * 1024 * 1024);
320
321 return font_object;
322 }
323
324 static void
325 ftcrfont_close (struct font *font)
326 {
327 if (font_data_structures_may_be_ill_formed ())
328 return;
329
330 struct font_info *ftcrfont_info = (struct font_info *) font;
331
332 block_input ();
333 #ifdef HAVE_LIBOTF
334 if (ftcrfont_info->otf)
335 {
336 OTF_close (ftcrfont_info->otf);
337 ftcrfont_info->otf = NULL;
338 }
339 #endif
340 #ifdef HAVE_HARFBUZZ
341 if (ftcrfont_info->hb_font)
342 {
343 hb_font_destroy (ftcrfont_info->hb_font);
344 ftcrfont_info->hb_font = NULL;
345 }
346 #endif
347 for (int i = 0; i < ftcrfont_info->metrics_nrows; i++)
348 if (ftcrfont_info->metrics[i])
349 xfree (ftcrfont_info->metrics[i]);
350 if (ftcrfont_info->metrics)
351 xfree (ftcrfont_info->metrics);
352 cairo_scaled_font_destroy (ftcrfont_info->cr_scaled_font);
353 unblock_input ();
354 }
355
356 static int
357 ftcrfont_has_char (Lisp_Object font, int c)
358 {
359 if (FONT_ENTITY_P (font))
360 return ftfont_has_char (font, c);
361
362 struct charset *cs = NULL;
363
364 if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qja)
365 && charset_jisx0208 >= 0)
366 cs = CHARSET_FROM_ID (charset_jisx0208);
367 else if (EQ (AREF (font, FONT_ADSTYLE_INDEX), Qko)
368 && charset_ksc5601 >= 0)
369 cs = CHARSET_FROM_ID (charset_ksc5601);
370 if (cs)
371 return (ENCODE_CHAR (cs, c) != CHARSET_INVALID_CODE (cs));
372
373 return -1;
374 }
375
376 static unsigned
377 ftcrfont_encode_char (struct font *font, int c)
378 {
379 struct font_info *ftcrfont_info = (struct font_info *) font;
380 unsigned code = FONT_INVALID_CODE;
381 unsigned char utf8[MAX_MULTIBYTE_LENGTH];
382 int utf8len = CHAR_STRING (c, utf8);
383 cairo_glyph_t stack_glyph;
384 cairo_glyph_t *glyphs = &stack_glyph;
385 int num_glyphs = 1;
386
387 if (cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font, 0, 0,
388 (char *) utf8, utf8len,
389 &glyphs, &num_glyphs,
390 NULL, NULL, NULL)
391 == CAIRO_STATUS_SUCCESS)
392 {
393 if (glyphs != &stack_glyph)
394 cairo_glyph_free (glyphs);
395 else if (stack_glyph.index)
396 code = stack_glyph.index;
397 }
398
399 return code;
400 }
401
402 static void
403 ftcrfont_text_extents (struct font *font,
404 const unsigned *code,
405 int nglyphs,
406 struct font_metrics *metrics)
407 {
408 int width, i;
409
410 block_input ();
411 width = ftcrfont_glyph_extents (font, code[0], metrics);
412 for (i = 1; i < nglyphs; i++)
413 {
414 struct font_metrics m;
415 int w = ftcrfont_glyph_extents (font, code[i], metrics ? &m : NULL);
416
417 if (metrics)
418 {
419 if (width + m.lbearing < metrics->lbearing)
420 metrics->lbearing = width + m.lbearing;
421 if (width + m.rbearing > metrics->rbearing)
422 metrics->rbearing = width + m.rbearing;
423 if (m.ascent > metrics->ascent)
424 metrics->ascent = m.ascent;
425 if (m.descent > metrics->descent)
426 metrics->descent = m.descent;
427 }
428 width += w;
429 }
430 unblock_input ();
431
432 if (metrics)
433 metrics->width = width;
434 }
435
436 static int
437 ftcrfont_get_bitmap (struct font *font, unsigned int code,
438 struct font_bitmap *bitmap, int bits_per_pixel)
439 {
440 struct font_info *ftcrfont_info = (struct font_info *) font;
441
442 if (ftcrfont_info->bitmap_position_unit)
443 return -1;
444
445 cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
446 FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
447
448 ftcrfont_info->ft_size = ft_face->size;
449 int result = ftfont_get_bitmap (font, code, bitmap, bits_per_pixel);
450 cairo_ft_scaled_font_unlock_face (scaled_font);
451 ftcrfont_info->ft_size = NULL;
452
453 return result;
454 }
455
456 static int
457 ftcrfont_anchor_point (struct font *font, unsigned int code, int idx,
458 int *x, int *y)
459 {
460 struct font_info *ftcrfont_info = (struct font_info *) font;
461
462 if (ftcrfont_info->bitmap_position_unit)
463 return -1;
464
465 cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
466 FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
467
468 ftcrfont_info->ft_size = ft_face->size;
469 int result = ftfont_anchor_point (font, code, idx, x, y);
470 cairo_ft_scaled_font_unlock_face (scaled_font);
471 ftcrfont_info->ft_size = NULL;
472
473 return result;
474 }
475
476 #ifdef HAVE_LIBOTF
477 static Lisp_Object
478 ftcrfont_otf_capability (struct font *font)
479 {
480 struct font_info *ftcrfont_info = (struct font_info *) font;
481 cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
482 FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
483
484 ftcrfont_info->ft_size = ft_face->size;
485 Lisp_Object result = ftfont_otf_capability (font);
486 cairo_ft_scaled_font_unlock_face (scaled_font);
487 ftcrfont_info->ft_size = NULL;
488
489 return result;
490 }
491 #endif
492
493 #if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
494 static Lisp_Object
495 ftcrfont_shape (Lisp_Object lgstring, Lisp_Object direction)
496 {
497 struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
498 struct font_info *ftcrfont_info = (struct font_info *) font;
499
500 if (ftcrfont_info->bitmap_position_unit)
501 return make_fixnum (0);
502
503 cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
504 FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
505
506 ftcrfont_info->ft_size = ft_face->size;
507 Lisp_Object result = ftfont_shape (lgstring, direction);
508 cairo_ft_scaled_font_unlock_face (scaled_font);
509 ftcrfont_info->ft_size = NULL;
510
511 return result;
512 }
513 #endif
514
515 #if defined HAVE_OTF_GET_VARIATION_GLYPHS || defined HAVE_FT_FACE_GETCHARVARIANTINDEX
516 static int
517 ftcrfont_variation_glyphs (struct font *font, int c, unsigned variations[256])
518 {
519 struct font_info *ftcrfont_info = (struct font_info *) font;
520 cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
521 FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
522
523 ftcrfont_info->ft_size = ft_face->size;
524 int result = ftfont_variation_glyphs (font, c, variations);
525 cairo_ft_scaled_font_unlock_face (scaled_font);
526 ftcrfont_info->ft_size = NULL;
527
528 return result;
529 }
530 #endif
531
532 static int
533 ftcrfont_draw (struct glyph_string *s,
534 int from, int to, int x, int y, bool with_background)
535 {
536 struct frame *f = s->f;
537 struct font_info *ftcrfont_info = (struct font_info *) s->font;
538 cairo_t *cr;
539 cairo_glyph_t *glyphs;
540 int len = to - from;
541 int i;
542 #ifdef USE_BE_CAIRO
543 unsigned long be_foreground, be_background;
544
545 if (s->hl != DRAW_CURSOR)
546 {
547 be_foreground = s->face->foreground;
548 be_background = s->face->background;
549 }
550 else
551 haiku_merge_cursor_foreground (s, &be_foreground,
552 &be_background);
553 #endif
554
555 block_input ();
556
557 #ifndef USE_BE_CAIRO
558 #ifdef HAVE_X_WINDOWS
559 cr = x_begin_cr_clip (f, s->gc);
560 #else
561 cr = pgtk_begin_cr_clip (f);
562 #endif
563 #else
564
565
566 EmacsWindow_begin_cr_critical_section (FRAME_HAIKU_WINDOW (f));
567 cr = haiku_begin_cr_clip (f, s);
568 if (!cr)
569 {
570 EmacsWindow_end_cr_critical_section (FRAME_HAIKU_WINDOW (f));
571 unblock_input ();
572 return 0;
573 }
574 BView_cr_dump_clipping (FRAME_HAIKU_DRAWABLE (f), cr);
575 #endif
576
577 if (with_background)
578 {
579 #ifndef USE_BE_CAIRO
580 #ifdef HAVE_X_WINDOWS
581 x_set_cr_source_with_gc_background (f, s->gc, s->hl != DRAW_CURSOR);
582 #else
583 pgtk_set_cr_source_with_color (f, s->xgcv.background,
584 s->hl != DRAW_CURSOR);
585 #endif
586 #else
587 uint32_t col = be_background;
588
589 cairo_set_source_rgb (cr, RED_FROM_ULONG (col) / 255.0,
590 GREEN_FROM_ULONG (col) / 255.0,
591 BLUE_FROM_ULONG (col) / 255.0);
592 #endif
593 cairo_rectangle (cr, x, y - FONT_BASE (s->font),
594 s->width, FONT_HEIGHT (s->font));
595 cairo_fill (cr);
596 }
597
598 glyphs = alloca (sizeof (cairo_glyph_t) * len);
599 for (i = 0; i < len; i++)
600 {
601 glyphs[i].index = s->char2b[from + i];
602 glyphs[i].x = x;
603 glyphs[i].y = y;
604 x += (s->padding_p ? 1 : ftcrfont_glyph_extents (s->font,
605 glyphs[i].index,
606 NULL));
607 }
608 #ifndef USE_BE_CAIRO
609 #ifdef HAVE_X_WINDOWS
610 x_set_cr_source_with_gc_foreground (f, s->gc, false);
611 #else
612 pgtk_set_cr_source_with_color (f, s->xgcv.foreground, false);
613 #endif
614 #else
615 uint32_t col = be_foreground;
616
617 cairo_set_source_rgb (cr, RED_FROM_ULONG (col) / 255.0,
618 GREEN_FROM_ULONG (col) / 255.0,
619 BLUE_FROM_ULONG (col) / 255.0);
620 #endif
621 cairo_set_scaled_font (cr, ftcrfont_info->cr_scaled_font);
622 cairo_show_glyphs (cr, glyphs, len);
623 #ifndef USE_BE_CAIRO
624 #ifdef HAVE_X_WINDOWS
625 x_end_cr_clip (f);
626 #else
627 pgtk_end_cr_clip (f);
628 #endif
629 #else
630 haiku_end_cr_clip (cr);
631 EmacsWindow_end_cr_critical_section (FRAME_HAIKU_WINDOW (f));
632 #endif
633 unblock_input ();
634
635 return len;
636 }
637
638 #ifdef HAVE_PGTK
639
640
641
642 static bool
643 ftcrfont_cached_font_ok (struct frame *f, Lisp_Object font_object,
644 Lisp_Object entity)
645 {
646 struct font_info *info = (struct font_info *) XFONT_OBJECT (font_object);
647
648 cairo_font_options_t *options = cairo_font_options_create ();
649 cairo_scaled_font_get_font_options (info->cr_scaled_font, options);
650 cairo_font_options_t *gsettings_options = xsettings_get_font_options ();
651
652 bool equal = cairo_font_options_equal (options, gsettings_options);
653 cairo_font_options_destroy (options);
654 cairo_font_options_destroy (gsettings_options);
655
656 return equal;
657 }
658 #endif
659
660 #ifdef HAVE_HARFBUZZ
661
662 static Lisp_Object
663 ftcrhbfont_list (struct frame *f, Lisp_Object spec)
664 {
665 return ftfont_list2 (f, spec, Qftcrhb);
666 }
667
668 static Lisp_Object
669 ftcrhbfont_match (struct frame *f, Lisp_Object spec)
670 {
671 return ftfont_match2 (f, spec, Qftcrhb);
672 }
673
674 static hb_font_t *
675 ftcrhbfont_begin_hb_font (struct font *font, double *position_unit)
676 {
677 struct font_info *ftcrfont_info = (struct font_info *) font;
678 cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
679 FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
680
681 ftcrfont_info->ft_size = ft_face->size;
682 hb_font_t *hb_font = fthbfont_begin_hb_font (font, position_unit);
683
684
685
686
687
688
689
690 if ((hb_version_atleast (5, 2, 0) || !hb_version_atleast (5, 0, 0))
691 && ftcrfont_info->bitmap_position_unit)
692 *position_unit = ftcrfont_info->bitmap_position_unit;
693
694 return hb_font;
695 }
696
697 static void
698 ftcrhbfont_end_hb_font (struct font *font, hb_font_t *hb_font)
699 {
700 struct font_info *ftcrfont_info = (struct font_info *) font;
701 cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
702
703 cairo_ft_scaled_font_unlock_face (scaled_font);
704 ftcrfont_info->ft_size = NULL;
705 }
706
707 #endif
708
709
710 static void syms_of_ftcrfont_for_pdumper (void);
711
712 struct font_driver const ftcrfont_driver =
713 {
714 .type = LISPSYM_INITIALLY (Qftcr),
715 .get_cache = ftfont_get_cache,
716 .list = ftcrfont_list,
717 .match = ftcrfont_match,
718 .list_family = ftfont_list_family,
719 .open_font = ftcrfont_open,
720 .close_font = ftcrfont_close,
721 .has_char = ftcrfont_has_char,
722 .encode_char = ftcrfont_encode_char,
723 .text_extents = ftcrfont_text_extents,
724 .draw = ftcrfont_draw,
725 .get_bitmap = ftcrfont_get_bitmap,
726 .anchor_point = ftcrfont_anchor_point,
727 #ifdef HAVE_LIBOTF
728 .otf_capability = ftcrfont_otf_capability,
729 #endif
730 #if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
731 .shape = ftcrfont_shape,
732 #endif
733 #if defined HAVE_OTF_GET_VARIATION_GLYPHS || defined HAVE_FT_FACE_GETCHARVARIANTINDEX
734 .get_variation_glyphs = ftcrfont_variation_glyphs,
735 #endif
736 .filter_properties = ftfont_filter_properties,
737 .combining_capability = ftfont_combining_capability,
738 #ifdef HAVE_PGTK
739 .cached_font_ok = ftcrfont_cached_font_ok,
740 #endif
741 };
742 #ifdef HAVE_HARFBUZZ
743 struct font_driver ftcrhbfont_driver;
744 #endif
745
746 void
747 syms_of_ftcrfont (void)
748 {
749 DEFSYM (Qftcr, "ftcr");
750 #ifdef HAVE_HARFBUZZ
751 DEFSYM (Qftcrhb, "ftcrhb");
752 Fput (Qftcr, Qfont_driver_superseded_by, Qftcrhb);
753 #endif
754 pdumper_do_now_and_after_load (syms_of_ftcrfont_for_pdumper);
755 }
756
757 #ifdef HAVE_X_WINDOWS
758
759
760
761
762 void
763 ftcrfont_get_default_font_options (struct x_display_info *dpyinfo,
764 cairo_font_options_t *options)
765 {
766 Pixmap drawable;
767 cairo_surface_t *surface;
768
769
770
771
772
773
774 drawable = XCreatePixmap (dpyinfo->display, dpyinfo->root_window,
775 1, 1, dpyinfo->n_planes);
776 surface = cairo_xlib_surface_create (dpyinfo->display, drawable,
777 dpyinfo->visual, 1, 1);
778
779 if (!surface)
780 {
781 XFreePixmap (dpyinfo->display, drawable);
782 return;
783 }
784
785 cairo_surface_get_font_options (surface, options);
786 XFreePixmap (dpyinfo->display, drawable);
787 cairo_surface_destroy (surface);
788 return;
789 }
790
791 #endif
792
793 static void
794 syms_of_ftcrfont_for_pdumper (void)
795 {
796 register_font_driver (&ftcrfont_driver, NULL);
797 #ifdef HAVE_HARFBUZZ
798 ftcrhbfont_driver = ftcrfont_driver;
799 ftcrhbfont_driver.type = Qftcrhb;
800 ftcrhbfont_driver.list = ftcrhbfont_list;
801 ftcrhbfont_driver.match = ftcrhbfont_match;
802 ftcrhbfont_driver.otf_capability = hbfont_otf_capability;
803 ftcrhbfont_driver.shape = hbfont_shape;
804 ftcrhbfont_driver.combining_capability = hbfont_combining_capability;
805 ftcrhbfont_driver.begin_hb_font = ftcrhbfont_begin_hb_font;
806 ftcrhbfont_driver.end_hb_font = ftcrhbfont_end_hb_font;
807 register_font_driver (&ftcrhbfont_driver, NULL);
808 #endif
809 }