aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorYAMAMOTO Mitsuharu2019-05-23 10:30:59 +0900
committerYAMAMOTO Mitsuharu2019-05-23 10:30:59 +0900
commit03feb9376b54c489e24478954a11061e9b0d6db7 (patch)
tree3e20c6c3295c24d0d4053a68062bcc7e9c49a224 /src
parent72047556fa391016ab507c02c2f489c97b53f088 (diff)
downloademacs-03feb9376b54c489e24478954a11061e9b0d6db7.tar.gz
emacs-03feb9376b54c489e24478954a11061e9b0d6db7.zip
Make Cairo build obey hint-style font setting (Bug#35781)
* src/ftfont.h (ftfont_open2): Remove extern. (ftfont_fix_match, ftfont_add_rendering_parameters) (ftfont_entity_pattern): Add externs. (struct font_info): Remove member bitmap_strike_index. (struct font_info) [USE_CAIRO]: Remove member ft_size_draw. All uses removed. Add member bitmap_position_unit. * src/xftfont.c (xftfont_fix_match, xftfont_add_rendering_parameters): Move functions from here ... * src/ftfont.c (ftfont_fix_match, ftfont_add_rendering_parameters): ... to here. All uses changed. * src/xftfont.c (xftfont_open): Extract FcPattern creation from font entity from here ... * src/ftfont.c (ftfont_entity_pattern): ... to here. * src/xftfont.c (syms_of_xftfont): Move DEFSYMs for Fontconfig's rendering parameters from here ... * src/ftfont.c (syms_of_ftfont): ... to here. * src/ftfont.c (ftfont_open, ftfont_open2): Undo introduction of bitmap_strike_index. Merge functions into ftfont_open. * src/ftcrfont.c (ftcrfont_open): Align code with xftfont_open rather than ftfont_open. (ftcrfont_close): Likewise. (ftcrfont_has_char, ftcrfont_encode_char): (ftcrfont_otf_capability) [HAVE_LIBOTF]: (ftcrfont_variation_glyphs) [HAVE_OTF_GET_VARIATION_GLYPHS]: New functions. (ftcrfont_driver): Register them. (ftcrfont_get_bitmap, ftcrfont_anchor_point): (ftcrfont_shape) [HAVE_M17N_FLT && HAVE_LIBOTF]: Use bitmap_position_unit instead of bitmap_strike_index to screen bitmap fonts. (ftcrfont_get_bitmap, ftcrfont_anchor_point): (ftcrfont_otf_capability) [HAVE_LIBOTF]: (ftcrfont_shape) [HAVE_M17N_FLT && HAVE_LIBOTF]: (ftcrfont_variation_glyphs) [HAVE_OTF_GET_VARIATION_GLYPHS]: Temporarily assign ftcrfont_info->ft_size and call corresponding ftfont functions. (ftcrfont_draw): Don't flush cairo surface when exporting.
Diffstat (limited to 'src')
-rw-r--r--src/ftcrfont.c370
-rw-r--r--src/ftfont.c222
-rw-r--r--src/ftfont.h18
-rw-r--r--src/xftfont.c151
4 files changed, 433 insertions, 328 deletions
diff --git a/src/ftcrfont.c b/src/ftcrfont.c
index 2d5a7665578..9686cec0e8c 100644
--- a/src/ftcrfont.c
+++ b/src/ftcrfont.c
@@ -79,7 +79,6 @@ ftcrfont_glyph_extents (struct font *font,
79 cairo_glyph_t cr_glyph = {.index = glyph}; 79 cairo_glyph_t cr_glyph = {.index = glyph};
80 cairo_text_extents_t extents; 80 cairo_text_extents_t extents;
81 81
82 FT_Activate_Size (ftcrfont_info->ft_size_draw);
83 cairo_scaled_font_glyph_extents (ftcrfont_info->cr_scaled_font, 82 cairo_scaled_font_glyph_extents (ftcrfont_info->cr_scaled_font,
84 &cr_glyph, 1, &extents); 83 &cr_glyph, 1, &extents);
85 cache->lbearing = floor (extents.x_bearing); 84 cache->lbearing = floor (extents.x_bearing);
@@ -118,103 +117,159 @@ ftcrfont_match (struct frame *f, Lisp_Object spec)
118static Lisp_Object 117static Lisp_Object
119ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size) 118ftcrfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
120{ 119{
121 Lisp_Object font_object; 120 FcResult result;
122 121 Lisp_Object val, filename, font_object;
123 FT_UInt size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX)); 122 FcPattern *pat, *match;
123 struct font_info *ftcrfont_info;
124 struct font *font;
125 double size = 0;
126 cairo_font_face_t *font_face;
127 cairo_font_extents_t extents;
128 FT_Face ft_face;
129 FcMatrix *matrix;
130
131 val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
132 if (! CONSP (val))
133 return Qnil;
134 val = XCDR (val);
135 filename = XCAR (val);
136 size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX));
124 if (size == 0) 137 if (size == 0)
125 size = pixel_size; 138 size = pixel_size;
139
140 block_input ();
141
142 pat = ftfont_entity_pattern (entity, pixel_size);
143 FcConfigSubstitute (NULL, pat, FcMatchPattern);
144 FcDefaultSubstitute (pat);
145 match = FcFontMatch (NULL, pat, &result);
146 ftfont_fix_match (pat, match);
147
148 FcPatternDestroy (pat);
149 font_face = cairo_ft_font_face_create_for_pattern (match);
150 if (!font_face)
151 {
152 unblock_input ();
153 FcPatternDestroy (match);
154 return Qnil;
155 }
156 cairo_matrix_t font_matrix, ctm;
157 cairo_matrix_init_scale (&font_matrix, pixel_size, pixel_size);
158 cairo_matrix_init_identity (&ctm);
159 cairo_font_options_t *options = cairo_font_options_create ();
160 cairo_scaled_font_t *scaled_font
161 = cairo_scaled_font_create (font_face, &font_matrix, &ctm, options);
162 cairo_font_face_destroy (font_face);
163 cairo_font_options_destroy (options);
164 unblock_input ();
165
126 font_object = font_build_object (VECSIZE (struct font_info), 166 font_object = font_build_object (VECSIZE (struct font_info),
127 Qftcr, entity, size); 167 Qftcr, entity, size);
168 ASET (font_object, FONT_FILE_INDEX, filename);
169 font = XFONT_OBJECT (font_object);
170 font->pixel_size = size;
171 font->driver = &ftcrfont_driver;
172 font->encoding_charset = font->repertory_charset = -1;
173
174 ftcrfont_info = (struct font_info *) font;
175 ftcrfont_info->cr_scaled_font = scaled_font;
176
177 /* This means that there's no need of transformation. */
178 ftcrfont_info->matrix.xx = 0;
179 if (FcPatternGetMatrix (match, FC_MATRIX, 0, &matrix) == FcResultMatch)
180 {
181 ftcrfont_info->matrix.xx = 0x10000L * matrix->xx;
182 ftcrfont_info->matrix.yy = 0x10000L * matrix->yy;
183 ftcrfont_info->matrix.xy = 0x10000L * matrix->xy;
184 ftcrfont_info->matrix.yx = 0x10000L * matrix->yx;
185 }
186
187 ftcrfont_info->metrics = NULL;
188 ftcrfont_info->metrics_nrows = 0;
189
128 block_input (); 190 block_input ();
129 font_object = ftfont_open2 (f, entity, pixel_size, font_object); 191 cairo_glyph_t stack_glyph;
130 if (FONT_OBJECT_P (font_object)) 192 int n = 0;
193 font->min_width = font->average_width = font->space_width = 0;
194 for (char c = 32; c < 127; c++)
131 { 195 {
132 struct font *font = XFONT_OBJECT (font_object); 196 cairo_glyph_t *glyphs = &stack_glyph;
133 struct font_info *ftcrfont_info = (struct font_info *) font; 197 int num_glyphs = 1;
134 FT_Face ft_face = ftcrfont_info->ft_size->face; 198 cairo_status_t status =
135 199 cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font,
136 font->driver = &ftcrfont_driver; 200 0, 0, &c, 1, &glyphs, &num_glyphs,
137 FT_New_Size (ft_face, &ftcrfont_info->ft_size_draw); 201 NULL, NULL, NULL);
138 FT_Activate_Size (ftcrfont_info->ft_size_draw); 202
139 if (ftcrfont_info->bitmap_strike_index < 0) 203 if (status == CAIRO_STATUS_SUCCESS)
140 FT_Set_Pixel_Sizes (ft_face, 0, font->pixel_size);
141 else
142 FT_Select_Size (ft_face, ftcrfont_info->bitmap_strike_index);
143 cairo_font_face_t *font_face =
144 cairo_ft_font_face_create_for_ft_face (ft_face, 0);
145 cairo_matrix_t font_matrix, ctm;
146 cairo_matrix_init_scale (&font_matrix, pixel_size, pixel_size);
147 cairo_matrix_init_identity (&ctm);
148 cairo_font_options_t *options = cairo_font_options_create ();
149 ftcrfont_info->cr_scaled_font =
150 cairo_scaled_font_create (font_face, &font_matrix, &ctm, options);
151 cairo_font_face_destroy (font_face);
152 cairo_font_options_destroy (options);
153 ftcrfont_info->metrics = NULL;
154 ftcrfont_info->metrics_nrows = 0;
155 if (ftcrfont_info->bitmap_strike_index >= 0)
156 { 204 {
157 /* Several members of struct font/font_info set by 205 if (glyphs != &stack_glyph)
158 ftfont_open2 are bogus. Recalculate them with cairo 206 cairo_glyph_free (glyphs);
159 scaled font functions. */ 207 else if (stack_glyph.index)
160 cairo_font_extents_t extents;
161 cairo_scaled_font_extents (ftcrfont_info->cr_scaled_font, &extents);
162 font->ascent = lround (extents.ascent);
163 Lisp_Object val = assq_no_quit (QCminspace,
164 AREF (entity, FONT_EXTRA_INDEX));
165 if (!(CONSP (val) && NILP (XCDR (val))))
166 {
167 font->descent = lround (extents.descent);
168 font->height = font->ascent + font->descent;
169 }
170 else
171 { 208 {
172 font->height = lround (extents.height); 209 int this_width = ftcrfont_glyph_extents (font, stack_glyph.index,
173 font->descent = font->height - font->ascent; 210 NULL);
211
212 if (this_width > 0
213 && (! font->min_width
214 || font->min_width > this_width))
215 font->min_width = this_width;
216 if (c == 32)
217 font->space_width = this_width;
218 font->average_width += this_width;
219 n++;
174 } 220 }
221 }
222 }
223 if (n > 0)
224 font->average_width /= n;
175 225
176 cairo_glyph_t stack_glyph; 226 cairo_scaled_font_extents (ftcrfont_info->cr_scaled_font, &extents);
177 int n = 0; 227 font->ascent = lround (extents.ascent);
178 font->min_width = font->average_width = font->space_width = 0; 228 val = assq_no_quit (QCminspace, AREF (entity, FONT_EXTRA_INDEX));
179 for (char c = 32; c < 127; c++) 229 if (!(CONSP (val) && NILP (XCDR (val))))
180 { 230 {
181 cairo_glyph_t *glyphs = &stack_glyph; 231 font->descent = lround (extents.descent);
182 int num_glyphs = 1; 232 font->height = font->ascent + font->descent;
183 cairo_status_t status = 233 }
184 cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font, 234 else
185 0, 0, &c, 1, 235 {
186 &glyphs, &num_glyphs, 236 font->height = lround (extents.height);
187 NULL, NULL, NULL); 237 font->descent = font->height - font->ascent;
188 238 }
189 if (status == CAIRO_STATUS_SUCCESS)
190 {
191 if (glyphs != &stack_glyph)
192 cairo_glyph_free (glyphs);
193 else if (stack_glyph.index)
194 {
195 int this_width =
196 ftcrfont_glyph_extents (font, stack_glyph.index, NULL);
197
198 if (this_width > 0
199 && (! font->min_width
200 || font->min_width > this_width))
201 font->min_width = this_width;
202 if (c == 32)
203 font->space_width = this_width;
204 font->average_width += this_width;
205 n++;
206 }
207 }
208 }
209 if (n > 0)
210 font->average_width /= n;
211 239
212 font->underline_position = -1; 240 ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
213 font->underline_thickness = 0; 241 if (XFIXNUM (AREF (entity, FONT_SIZE_INDEX)) == 0)
214 } 242 {
243 int upEM = ft_face->units_per_EM;
244
245 font->underline_position = -ft_face->underline_position * size / upEM;
246 font->underline_thickness = ft_face->underline_thickness * size / upEM;
247 if (font->underline_thickness > 2)
248 font->underline_position -= font->underline_thickness / 2;
249 }
250 else
251 {
252 font->underline_position = -1;
253 font->underline_thickness = 0;
215 } 254 }
255#ifdef HAVE_LIBOTF
256 ftcrfont_info->maybe_otf = (ft_face->face_flags & FT_FACE_FLAG_SFNT) != 0;
257 ftcrfont_info->otf = NULL;
258#endif /* HAVE_LIBOTF */
259 if (ft_face->units_per_EM)
260 ftcrfont_info->bitmap_position_unit = 0;
261 else
262 ftcrfont_info->bitmap_position_unit = (extents.height
263 / ft_face->size->metrics.height);
264 cairo_ft_scaled_font_unlock_face (scaled_font);
265 ftcrfont_info->ft_size = NULL;
216 unblock_input (); 266 unblock_input ();
217 267
268 font->baseline_offset = 0;
269 font->relative_compose = 0;
270 font->default_ascent = 0;
271 font->vertical_centering = false;
272
218 return font_object; 273 return font_object;
219} 274}
220 275
@@ -225,19 +280,58 @@ ftcrfont_close (struct font *font)
225 return; 280 return;
226 281
227 struct font_info *ftcrfont_info = (struct font_info *) font; 282 struct font_info *ftcrfont_info = (struct font_info *) font;
228 int i;
229 283
230 block_input (); 284 block_input ();
231 for (i = 0; i < ftcrfont_info->metrics_nrows; i++) 285#ifdef HAVE_LIBOTF
286 if (ftcrfont_info->otf)
287 {
288 OTF_close (ftcrfont_info->otf);
289 ftcrfont_info->otf = NULL;
290 }
291#endif
292 for (int i = 0; i < ftcrfont_info->metrics_nrows; i++)
232 if (ftcrfont_info->metrics[i]) 293 if (ftcrfont_info->metrics[i])
233 xfree (ftcrfont_info->metrics[i]); 294 xfree (ftcrfont_info->metrics[i]);
234 if (ftcrfont_info->metrics) 295 if (ftcrfont_info->metrics)
235 xfree (ftcrfont_info->metrics); 296 xfree (ftcrfont_info->metrics);
236 FT_Done_Size (ftcrfont_info->ft_size_draw);
237 cairo_scaled_font_destroy (ftcrfont_info->cr_scaled_font); 297 cairo_scaled_font_destroy (ftcrfont_info->cr_scaled_font);
238 unblock_input (); 298 unblock_input ();
299}
300
301static int
302ftcrfont_has_char (Lisp_Object font, int c)
303{
304 if (FONT_ENTITY_P (font))
305 return ftfont_has_char (font, c);
239 306
240 ftfont_close (font); 307 return -1;
308}
309
310static unsigned
311ftcrfont_encode_char (struct font *font, int c)
312{
313 struct font_info *ftcrfont_info = (struct font_info *) font;
314 unsigned code = FONT_INVALID_CODE;
315 unsigned char utf8[MAX_MULTIBYTE_LENGTH];
316 unsigned char *p = utf8;
317 cairo_glyph_t stack_glyph;
318 cairo_glyph_t *glyphs = &stack_glyph;
319 int num_glyphs = 1;
320
321 CHAR_STRING_ADVANCE (c, p);
322 if (cairo_scaled_font_text_to_glyphs (ftcrfont_info->cr_scaled_font, 0, 0,
323 (char *) utf8, p - utf8,
324 &glyphs, &num_glyphs,
325 NULL, NULL, NULL)
326 == CAIRO_STATUS_SUCCESS)
327 {
328 if (glyphs != &stack_glyph)
329 cairo_glyph_free (glyphs);
330 else if (stack_glyph.index)
331 code = stack_glyph.index;
332 }
333
334 return code;
241} 335}
242 336
243static void 337static void
@@ -280,10 +374,18 @@ ftcrfont_get_bitmap (struct font *font, unsigned int code,
280{ 374{
281 struct font_info *ftcrfont_info = (struct font_info *) font; 375 struct font_info *ftcrfont_info = (struct font_info *) font;
282 376
283 if (ftcrfont_info->bitmap_strike_index < 0) 377 if (ftcrfont_info->bitmap_position_unit)
284 return ftfont_get_bitmap (font, code, bitmap, bits_per_pixel); 378 return -1;
285 379
286 return -1; 380 cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
381 FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
382
383 ftcrfont_info->ft_size = ft_face->size;
384 int result = ftfont_get_bitmap (font, code, bitmap, bits_per_pixel);
385 cairo_ft_scaled_font_unlock_face (scaled_font);
386 ftcrfont_info->ft_size = NULL;
387
388 return result;
287} 389}
288 390
289static int 391static int
@@ -292,25 +394,75 @@ ftcrfont_anchor_point (struct font *font, unsigned int code, int idx,
292{ 394{
293 struct font_info *ftcrfont_info = (struct font_info *) font; 395 struct font_info *ftcrfont_info = (struct font_info *) font;
294 396
295 if (ftcrfont_info->bitmap_strike_index < 0) 397 if (ftcrfont_info->bitmap_position_unit)
296 return ftfont_anchor_point (font, code, idx, x, y); 398 return -1;
297 399
298 return -1; 400 cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
401 FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
402
403 ftcrfont_info->ft_size = ft_face->size;
404 int result = ftfont_anchor_point (font, code, idx, x, y);
405 cairo_ft_scaled_font_unlock_face (scaled_font);
406 ftcrfont_info->ft_size = NULL;
407
408 return result;
299} 409}
300 410
411#ifdef HAVE_LIBOTF
301static Lisp_Object 412static Lisp_Object
302ftcrfont_shape (Lisp_Object lgstring) 413ftcrfont_otf_capability (struct font *font)
303{ 414{
415 struct font_info *ftcrfont_info = (struct font_info *) font;
416 cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
417 FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
418
419 ftcrfont_info->ft_size = ft_face->size;
420 Lisp_Object result = ftfont_otf_capability (font);
421 cairo_ft_scaled_font_unlock_face (scaled_font);
422 ftcrfont_info->ft_size = NULL;
423
424 return result;
425}
426#endif
427
304#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF 428#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
429static Lisp_Object
430ftcrfont_shape (Lisp_Object lgstring)
431{
305 struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring)); 432 struct font *font = CHECK_FONT_GET_OBJECT (LGSTRING_FONT (lgstring));
306 struct font_info *ftcrfont_info = (struct font_info *) font; 433 struct font_info *ftcrfont_info = (struct font_info *) font;
307 434
308 if (ftcrfont_info->bitmap_strike_index < 0) 435 if (ftcrfont_info->bitmap_position_unit)
309 return ftfont_shape (lgstring); 436 return make_fixnum (0);
437
438 cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
439 FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
440
441 ftcrfont_info->ft_size = ft_face->size;
442 Lisp_Object result = ftfont_shape (lgstring);
443 cairo_ft_scaled_font_unlock_face (scaled_font);
444 ftcrfont_info->ft_size = NULL;
445
446 return result;
447}
310#endif 448#endif
311 449
312 return make_fixnum (0); 450#ifdef HAVE_OTF_GET_VARIATION_GLYPHS
451static int
452ftcrfont_variation_glyphs (struct font *font, int c, unsigned variations[256])
453{
454 struct font_info *ftcrfont_info = (struct font_info *) font;
455 cairo_scaled_font_t *scaled_font = ftcrfont_info->cr_scaled_font;
456 FT_Face ft_face = cairo_ft_scaled_font_lock_face (scaled_font);
457
458 ftcrfont_info->ft_size = ft_face->size;
459 int result = ftfont_variation_glyphs (font, c, variations);
460 cairo_ft_scaled_font_unlock_face (scaled_font);
461 ftcrfont_info->ft_size = NULL;
462
463 return result;
313} 464}
465#endif /* HAVE_OTF_GET_VARIATION_GLYPHS */
314 466
315static int 467static int
316ftcrfont_draw (struct glyph_string *s, 468ftcrfont_draw (struct glyph_string *s,
@@ -321,8 +473,6 @@ ftcrfont_draw (struct glyph_string *s,
321 struct font_info *ftcrfont_info = (struct font_info *) s->font; 473 struct font_info *ftcrfont_info = (struct font_info *) s->font;
322 cairo_t *cr; 474 cairo_t *cr;
323 cairo_glyph_t *glyphs; 475 cairo_glyph_t *glyphs;
324 cairo_surface_t *surface;
325 cairo_surface_type_t surface_type;
326 int len = to - from; 476 int len = to - from;
327 int i; 477 int i;
328 478
@@ -351,17 +501,7 @@ ftcrfont_draw (struct glyph_string *s,
351 501
352 x_set_cr_source_with_gc_foreground (f, s->gc); 502 x_set_cr_source_with_gc_foreground (f, s->gc);
353 cairo_set_scaled_font (cr, ftcrfont_info->cr_scaled_font); 503 cairo_set_scaled_font (cr, ftcrfont_info->cr_scaled_font);
354
355 FT_Activate_Size (ftcrfont_info->ft_size_draw);
356 cairo_show_glyphs (cr, glyphs, len); 504 cairo_show_glyphs (cr, glyphs, len);
357 surface = cairo_get_target (cr);
358 /* XXX: It used to be necessary to flush when exporting. It might
359 be the case that this is no longer necessary. */
360 surface_type = cairo_surface_get_type (surface);
361 if (surface_type != CAIRO_SURFACE_TYPE_XLIB
362 && (surface_type != CAIRO_SURFACE_TYPE_IMAGE
363 || cairo_image_surface_get_format (surface) != CAIRO_FORMAT_ARGB32))
364 cairo_surface_flush (surface);
365 505
366 x_end_cr_clip (f); 506 x_end_cr_clip (f);
367 507
@@ -383,18 +523,20 @@ struct font_driver const ftcrfont_driver =
383 .list_family = ftfont_list_family, 523 .list_family = ftfont_list_family,
384 .open = ftcrfont_open, 524 .open = ftcrfont_open,
385 .close = ftcrfont_close, 525 .close = ftcrfont_close,
386 .has_char = ftfont_has_char, 526 .has_char = ftcrfont_has_char,
387 .encode_char = ftfont_encode_char, 527 .encode_char = ftcrfont_encode_char,
388 .text_extents = ftcrfont_text_extents, 528 .text_extents = ftcrfont_text_extents,
389 .draw = ftcrfont_draw, 529 .draw = ftcrfont_draw,
390 .get_bitmap = ftcrfont_get_bitmap, 530 .get_bitmap = ftcrfont_get_bitmap,
391 .anchor_point = ftcrfont_anchor_point, 531 .anchor_point = ftcrfont_anchor_point,
392#ifdef HAVE_LIBOTF 532#ifdef HAVE_LIBOTF
393 .otf_capability = ftfont_otf_capability, 533 .otf_capability = ftcrfont_otf_capability,
394#endif 534#endif
535#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
395 .shape = ftcrfont_shape, 536 .shape = ftcrfont_shape,
537#endif
396#ifdef HAVE_OTF_GET_VARIATION_GLYPHS 538#ifdef HAVE_OTF_GET_VARIATION_GLYPHS
397 .get_variation_glyphs = ftfont_variation_glyphs, 539 .get_variation_glyphs = ftcrfont_variation_glyphs,
398#endif 540#endif
399 .filter_properties = ftfont_filter_properties, 541 .filter_properties = ftfont_filter_properties,
400 .combining_capability = ftfont_combining_capability, 542 .combining_capability = ftfont_combining_capability,
diff --git a/src/ftfont.c b/src/ftfont.c
index f17bd9ab3f7..d8b510d7032 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -1079,12 +1079,159 @@ ftfont_list_family (struct frame *f)
1079 return list; 1079 return list;
1080} 1080}
1081 1081
1082void
1083ftfont_fix_match (FcPattern *pat, FcPattern *match)
1084{
1085 /* These values are not used for matching (except antialias), but for
1086 rendering, so make sure they are carried over to the match.
1087 We also put antialias here because most fonts are antialiased, so
1088 the match will have antialias true. */
1089
1090 FcBool b = FcTrue;
1091 int i;
1092 double dpi;
1093
1094 FcPatternGetBool (pat, FC_ANTIALIAS, 0, &b);
1095 if (! b)
1096 {
1097 FcPatternDel (match, FC_ANTIALIAS);
1098 FcPatternAddBool (match, FC_ANTIALIAS, FcFalse);
1099 }
1100 FcPatternGetBool (pat, FC_HINTING, 0, &b);
1101 if (! b)
1102 {
1103 FcPatternDel (match, FC_HINTING);
1104 FcPatternAddBool (match, FC_HINTING, FcFalse);
1105 }
1106#ifndef FC_HINT_STYLE
1107# define FC_HINT_STYLE "hintstyle"
1108#endif
1109 if (FcResultMatch == FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &i))
1110 {
1111 FcPatternDel (match, FC_HINT_STYLE);
1112 FcPatternAddInteger (match, FC_HINT_STYLE, i);
1113 }
1114#ifndef FC_LCD_FILTER
1115 /* Older fontconfig versions don't have FC_LCD_FILTER. */
1116#define FC_LCD_FILTER "lcdfilter"
1117#endif
1118 if (FcResultMatch == FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &i))
1119 {
1120 FcPatternDel (match, FC_LCD_FILTER);
1121 FcPatternAddInteger (match, FC_LCD_FILTER, i);
1122 }
1123 if (FcResultMatch == FcPatternGetInteger (pat, FC_RGBA, 0, &i))
1124 {
1125 FcPatternDel (match, FC_RGBA);
1126 FcPatternAddInteger (match, FC_RGBA, i);
1127 }
1128 if (FcResultMatch == FcPatternGetDouble (pat, FC_DPI, 0, &dpi))
1129 {
1130 FcPatternDel (match, FC_DPI);
1131 FcPatternAddDouble (match, FC_DPI, dpi);
1132 }
1133}
1134
1135void
1136ftfont_add_rendering_parameters (FcPattern *pat, Lisp_Object entity)
1137{
1138 Lisp_Object tail;
1139 int ival;
1140
1141 for (tail = AREF (entity, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
1142 {
1143 Lisp_Object key = XCAR (XCAR (tail));
1144 Lisp_Object val = XCDR (XCAR (tail));
1145
1146 if (EQ (key, QCantialias))
1147 FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue);
1148 else if (EQ (key, QChinting))
1149 FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue);
1150 else if (EQ (key, QCautohint))
1151 FcPatternAddBool (pat, FC_AUTOHINT, NILP (val) ? FcFalse : FcTrue);
1152 else if (EQ (key, QChintstyle))
1153 {
1154 if (FIXNUMP (val))
1155 FcPatternAddInteger (pat, FC_HINT_STYLE, XFIXNUM (val));
1156 else if (SYMBOLP (val)
1157 && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
1158 FcPatternAddInteger (pat, FC_HINT_STYLE, ival);
1159 }
1160 else if (EQ (key, QCrgba))
1161 {
1162 if (FIXNUMP (val))
1163 FcPatternAddInteger (pat, FC_RGBA, XFIXNUM (val));
1164 else if (SYMBOLP (val)
1165 && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
1166 FcPatternAddInteger (pat, FC_RGBA, ival);
1167 }
1168 else if (EQ (key, QClcdfilter))
1169 {
1170 if (FIXNUMP (val))
1171 FcPatternAddInteger (pat, FC_LCD_FILTER, ival = XFIXNUM (val));
1172 else if (SYMBOLP (val)
1173 && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
1174 FcPatternAddInteger (pat, FC_LCD_FILTER, ival);
1175 }
1176#ifdef FC_EMBOLDEN
1177 else if (EQ (key, QCembolden))
1178 FcPatternAddBool (pat, FC_EMBOLDEN, NILP (val) ? FcFalse : FcTrue);
1179#endif
1180 }
1181}
1182
1183FcPattern *
1184ftfont_entity_pattern (Lisp_Object entity, int pixel_size)
1185{
1186 Lisp_Object val, filename, idx;
1187 FcPattern *pat;
1188 int i;
1189
1190 val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
1191 eassert (CONSP (val));
1192 val = XCDR (val);
1193 filename = XCAR (val);
1194 idx = XCDR (val);
1195 pat = FcPatternCreate ();
1196 FcPatternAddInteger (pat, FC_WEIGHT, FONT_WEIGHT_NUMERIC (entity));
1197 i = FONT_SLANT_NUMERIC (entity) - 100;
1198 if (i < 0) i = 0;
1199 FcPatternAddInteger (pat, FC_SLANT, i);
1200 FcPatternAddInteger (pat, FC_WIDTH, FONT_WIDTH_NUMERIC (entity));
1201 FcPatternAddDouble (pat, FC_PIXEL_SIZE, pixel_size);
1202 val = AREF (entity, FONT_FAMILY_INDEX);
1203 if (! NILP (val))
1204 FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) SDATA (SYMBOL_NAME (val)));
1205 val = AREF (entity, FONT_FOUNDRY_INDEX);
1206 if (! NILP (val))
1207 FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) SDATA (SYMBOL_NAME (val)));
1208 val = AREF (entity, FONT_SPACING_INDEX);
1209 if (! NILP (val))
1210 FcPatternAddInteger (pat, FC_SPACING, XFIXNUM (val));
1211 val = AREF (entity, FONT_DPI_INDEX);
1212 if (! NILP (val))
1213 {
1214 double dbl = XFIXNUM (val);
1215
1216 FcPatternAddDouble (pat, FC_DPI, dbl);
1217 }
1218 val = AREF (entity, FONT_AVGWIDTH_INDEX);
1219 if (FIXNUMP (val) && XFIXNUM (val) == 0)
1220 FcPatternAddBool (pat, FC_SCALABLE, FcTrue);
1221 /* This is necessary to identify the exact font (e.g. 10x20.pcf.gz
1222 over 10x20-ISO8859-1.pcf.gz). */
1223 FcPatternAddCharSet (pat, FC_CHARSET, ftfont_get_fc_charset (entity));
1224
1225 ftfont_add_rendering_parameters (pat, entity);
1226
1227 FcPatternAddString (pat, FC_FILE, (FcChar8 *) SDATA (filename));
1228 FcPatternAddInteger (pat, FC_INDEX, XFIXNUM (idx));
1229
1230 return pat;
1231}
1082 1232
1083Lisp_Object 1233Lisp_Object
1084ftfont_open2 (struct frame *f, 1234ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
1085 Lisp_Object entity,
1086 int pixel_size,
1087 Lisp_Object font_object)
1088{ 1235{
1089 struct font_info *ftfont_info; 1236 struct font_info *ftfont_info;
1090 struct font *font; 1237 struct font *font;
@@ -1092,12 +1239,11 @@ ftfont_open2 (struct frame *f,
1092 FT_Face ft_face; 1239 FT_Face ft_face;
1093 FT_Size ft_size; 1240 FT_Size ft_size;
1094 FT_UInt size; 1241 FT_UInt size;
1095 Lisp_Object val, filename, idx, cache; 1242 Lisp_Object val, filename, idx, cache, font_object;
1096 bool scalable; 1243 bool scalable;
1097 int spacing; 1244 int spacing;
1098 int i; 1245 int i;
1099 double upEM; 1246 double upEM;
1100 FT_Int strike_index = -1;
1101 1247
1102 val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX)); 1248 val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX));
1103 if (! CONSP (val)) 1249 if (! CONSP (val))
@@ -1126,35 +1272,17 @@ ftfont_open2 (struct frame *f,
1126 size = pixel_size; 1272 size = pixel_size;
1127 if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0) 1273 if (FT_Set_Pixel_Sizes (ft_face, size, size) != 0)
1128 { 1274 {
1129 int min_distance = INT_MAX; 1275 if (cache_data->face_refcount == 0)
1130 bool magnify = true;
1131
1132 for (FT_Int i = 0; i < ft_face->num_fixed_sizes; i++)
1133 {
1134 int distance = ft_face->available_sizes[i].height - (int) size;
1135
1136 /* Prefer down-scaling to upscaling. */
1137 if (magnify == (distance < 0) ? abs (distance) <= min_distance
1138 : magnify)
1139 {
1140 magnify = distance < 0;
1141 min_distance = abs (distance);
1142 strike_index = i;
1143 }
1144 }
1145
1146 if (strike_index < 0 || FT_Select_Size (ft_face, strike_index) != 0)
1147 { 1276 {
1148 if (cache_data->face_refcount == 0) 1277 FT_Done_Face (ft_face);
1149 { 1278 cache_data->ft_face = NULL;
1150 FT_Done_Face (ft_face);
1151 cache_data->ft_face = NULL;
1152 }
1153 return Qnil;
1154 } 1279 }
1280 return Qnil;
1155 } 1281 }
1156 cache_data->face_refcount++; 1282 cache_data->face_refcount++;
1157 1283
1284 font_object = font_build_object (VECSIZE (struct font_info),
1285 Qfreetype, entity, size);
1158 ASET (font_object, FONT_FILE_INDEX, filename); 1286 ASET (font_object, FONT_FILE_INDEX, filename);
1159 font = XFONT_OBJECT (font_object); 1287 font = XFONT_OBJECT (font_object);
1160 ftfont_info = (struct font_info *) font; 1288 ftfont_info = (struct font_info *) font;
@@ -1164,7 +1292,6 @@ ftfont_open2 (struct frame *f,
1164 ftfont_info->maybe_otf = (ft_face->face_flags & FT_FACE_FLAG_SFNT) != 0; 1292 ftfont_info->maybe_otf = (ft_face->face_flags & FT_FACE_FLAG_SFNT) != 0;
1165 ftfont_info->otf = NULL; 1293 ftfont_info->otf = NULL;
1166#endif /* HAVE_LIBOTF */ 1294#endif /* HAVE_LIBOTF */
1167 ftfont_info->bitmap_strike_index = strike_index;
1168 /* This means that there's no need of transformation. */ 1295 /* This means that there's no need of transformation. */
1169 ftfont_info->matrix.xx = 0; 1296 ftfont_info->matrix.xx = 0;
1170 font->pixel_size = size; 1297 font->pixel_size = size;
@@ -1258,31 +1385,6 @@ ftfont_open2 (struct frame *f,
1258 return font_object; 1385 return font_object;
1259} 1386}
1260 1387
1261Lisp_Object
1262ftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
1263{
1264 Lisp_Object font_object;
1265 FT_UInt size;
1266 size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX));
1267 if (size == 0)
1268 size = pixel_size;
1269 font_object = font_build_object (VECSIZE (struct font_info),
1270 Qfreetype, entity, size);
1271 font_object = ftfont_open2 (f, entity, pixel_size, font_object);
1272 if (FONT_OBJECT_P (font_object))
1273 {
1274 struct font *font = XFONT_OBJECT (font_object);
1275 struct font_info *ftfont_info = (struct font_info *) font;
1276
1277 if (ftfont_info->bitmap_strike_index >= 0)
1278 {
1279 ftfont_close (font);
1280 font_object = Qnil;
1281 }
1282 }
1283 return font_object;
1284}
1285
1286void 1388void
1287ftfont_close (struct font *font) 1389ftfont_close (struct font *font)
1288{ 1390{
@@ -2789,6 +2891,14 @@ syms_of_ftfont (void)
2789 /* The boolean-valued font property key specifying the use of leading. */ 2891 /* The boolean-valued font property key specifying the use of leading. */
2790 DEFSYM (QCminspace, ":minspace"); 2892 DEFSYM (QCminspace, ":minspace");
2791 2893
2894 /* Fontconfig's rendering parameters. */
2895 DEFSYM (QChinting, ":hinting");
2896 DEFSYM (QCautohint, ":autohint");
2897 DEFSYM (QChintstyle, ":hintstyle");
2898 DEFSYM (QCrgba, ":rgba");
2899 DEFSYM (QCembolden, ":embolden");
2900 DEFSYM (QClcdfilter, ":lcdfilter");
2901
2792 staticpro (&freetype_font_cache); 2902 staticpro (&freetype_font_cache);
2793 freetype_font_cache = list1 (Qt); 2903 freetype_font_cache = list1 (Qt);
2794 2904
diff --git a/src/ftfont.h b/src/ftfont.h
index adbda49ff1c..7860469491f 100644
--- a/src/ftfont.h
+++ b/src/ftfont.h
@@ -37,10 +37,9 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
37#endif /* HAVE_LIBOTF */ 37#endif /* HAVE_LIBOTF */
38 38
39extern FcCharSet *ftfont_get_fc_charset (Lisp_Object); 39extern FcCharSet *ftfont_get_fc_charset (Lisp_Object);
40extern Lisp_Object ftfont_open2 (struct frame *f, 40extern void ftfont_fix_match (FcPattern *, FcPattern *);
41 Lisp_Object entity, 41extern void ftfont_add_rendering_parameters (FcPattern *, Lisp_Object);
42 int pixel_size, 42extern FcPattern *ftfont_entity_pattern (Lisp_Object, int);
43 Lisp_Object font_object);
44 43
45/* This struct is shared by the XFT, Freetype, and Cairo font 44/* This struct is shared by the XFT, Freetype, and Cairo font
46 backends. Members up to and including 'matrix' are common, the 45 backends. Members up to and including 'matrix' are common, the
@@ -54,17 +53,14 @@ struct font_info
54#endif /* HAVE_LIBOTF */ 53#endif /* HAVE_LIBOTF */
55 FT_Size ft_size; 54 FT_Size ft_size;
56 int index; 55 int index;
57 /* Index of the bitmap strike used as a fallback for
58 FT_Set_Pixel_Sizes failure. If the value is non-negative, then
59 ft_size is not of the requested size. Otherwise it is -1. */
60 FT_Int bitmap_strike_index;
61 FT_Matrix matrix; 56 FT_Matrix matrix;
62 57
63#ifdef USE_CAIRO 58#ifdef USE_CAIRO
64 cairo_scaled_font_t *cr_scaled_font; 59 cairo_scaled_font_t *cr_scaled_font;
65 /* To prevent cairo from cluttering the activated FT_Size maintained 60 /* Scale factor from the bitmap strike metrics in 1/64 pixels, used
66 in ftfont.c, we activate this special FT_Size before drawing. */ 61 as the hb_position_t value in HarfBuzz, to those in (scaled)
67 FT_Size ft_size_draw; 62 pixels. The value is 0 for scalable fonts. */
63 double bitmap_position_unit;
68 /* Font metrics cache. */ 64 /* Font metrics cache. */
69 struct font_metrics **metrics; 65 struct font_metrics **metrics;
70 short metrics_nrows; 66 short metrics_nrows;
diff --git a/src/xftfont.c b/src/xftfont.c
index 2edc51fe356..4f0a0d81d85 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -127,120 +127,18 @@ xftfont_match (struct frame *f, Lisp_Object spec)
127 127
128static FcChar8 ascii_printable[95]; 128static FcChar8 ascii_printable[95];
129 129
130static void
131xftfont_fix_match (FcPattern *pat, FcPattern *match)
132{
133 /* These values are not used for matching (except antialias), but for
134 rendering, so make sure they are carried over to the match.
135 We also put antialias here because most fonts are antialiased, so
136 the match will have antialias true. */
137
138 FcBool b = FcTrue;
139 int i;
140 double dpi;
141
142 FcPatternGetBool (pat, FC_ANTIALIAS, 0, &b);
143 if (! b)
144 {
145 FcPatternDel (match, FC_ANTIALIAS);
146 FcPatternAddBool (match, FC_ANTIALIAS, FcFalse);
147 }
148 FcPatternGetBool (pat, FC_HINTING, 0, &b);
149 if (! b)
150 {
151 FcPatternDel (match, FC_HINTING);
152 FcPatternAddBool (match, FC_HINTING, FcFalse);
153 }
154#ifndef FC_HINT_STYLE
155# define FC_HINT_STYLE "hintstyle"
156#endif
157 if (FcResultMatch == FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &i))
158 {
159 FcPatternDel (match, FC_HINT_STYLE);
160 FcPatternAddInteger (match, FC_HINT_STYLE, i);
161 }
162#ifndef FC_LCD_FILTER
163 /* Older fontconfig versions don't have FC_LCD_FILTER. */
164#define FC_LCD_FILTER "lcdfilter"
165#endif
166 if (FcResultMatch == FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &i))
167 {
168 FcPatternDel (match, FC_LCD_FILTER);
169 FcPatternAddInteger (match, FC_LCD_FILTER, i);
170 }
171 if (FcResultMatch == FcPatternGetInteger (pat, FC_RGBA, 0, &i))
172 {
173 FcPatternDel (match, FC_RGBA);
174 FcPatternAddInteger (match, FC_RGBA, i);
175 }
176 if (FcResultMatch == FcPatternGetDouble (pat, FC_DPI, 0, &dpi))
177 {
178 FcPatternDel (match, FC_DPI);
179 FcPatternAddDouble (match, FC_DPI, dpi);
180 }
181}
182
183static void
184xftfont_add_rendering_parameters (FcPattern *pat, Lisp_Object entity)
185{
186 Lisp_Object tail;
187 int ival;
188
189 for (tail = AREF (entity, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail))
190 {
191 Lisp_Object key = XCAR (XCAR (tail));
192 Lisp_Object val = XCDR (XCAR (tail));
193
194 if (EQ (key, QCantialias))
195 FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue);
196 else if (EQ (key, QChinting))
197 FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue);
198 else if (EQ (key, QCautohint))
199 FcPatternAddBool (pat, FC_AUTOHINT, NILP (val) ? FcFalse : FcTrue);
200 else if (EQ (key, QChintstyle))
201 {
202 if (FIXNUMP (val))
203 FcPatternAddInteger (pat, FC_HINT_STYLE, XFIXNUM (val));
204 else if (SYMBOLP (val)
205 && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
206 FcPatternAddInteger (pat, FC_HINT_STYLE, ival);
207 }
208 else if (EQ (key, QCrgba))
209 {
210 if (FIXNUMP (val))
211 FcPatternAddInteger (pat, FC_RGBA, XFIXNUM (val));
212 else if (SYMBOLP (val)
213 && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
214 FcPatternAddInteger (pat, FC_RGBA, ival);
215 }
216 else if (EQ (key, QClcdfilter))
217 {
218 if (FIXNUMP (val))
219 FcPatternAddInteger (pat, FC_LCD_FILTER, ival = XFIXNUM (val));
220 else if (SYMBOLP (val)
221 && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival))
222 FcPatternAddInteger (pat, FC_LCD_FILTER, ival);
223 }
224#ifdef FC_EMBOLDEN
225 else if (EQ (key, QCembolden))
226 FcPatternAddBool (pat, FC_EMBOLDEN, NILP (val) ? FcFalse : FcTrue);
227#endif
228 }
229}
230
231static Lisp_Object 130static Lisp_Object
232xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size) 131xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
233{ 132{
234 FcResult result; 133 FcResult result;
235 Display *display = FRAME_X_DISPLAY (f); 134 Display *display = FRAME_X_DISPLAY (f);
236 Lisp_Object val, filename, idx, font_object; 135 Lisp_Object val, filename, font_object;
237 FcPattern *pat = NULL, *match; 136 FcPattern *pat = NULL, *match;
238 struct font_info *xftfont_info = NULL; 137 struct font_info *xftfont_info = NULL;
239 struct font *font; 138 struct font *font;
240 double size = 0; 139 double size = 0;
241 XftFont *xftfont = NULL; 140 XftFont *xftfont = NULL;
242 int spacing; 141 int spacing;
243 int i;
244 XGlyphInfo extents; 142 XGlyphInfo extents;
245 FT_Face ft_face; 143 FT_Face ft_face;
246 FcMatrix *matrix; 144 FcMatrix *matrix;
@@ -250,52 +148,17 @@ xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
250 return Qnil; 148 return Qnil;
251 val = XCDR (val); 149 val = XCDR (val);
252 filename = XCAR (val); 150 filename = XCAR (val);
253 idx = XCDR (val);
254 size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX)); 151 size = XFIXNUM (AREF (entity, FONT_SIZE_INDEX));
255 if (size == 0) 152 if (size == 0)
256 size = pixel_size; 153 size = pixel_size;
257 pat = FcPatternCreate ();
258 FcPatternAddInteger (pat, FC_WEIGHT, FONT_WEIGHT_NUMERIC (entity));
259 i = FONT_SLANT_NUMERIC (entity) - 100;
260 if (i < 0) i = 0;
261 FcPatternAddInteger (pat, FC_SLANT, i);
262 FcPatternAddInteger (pat, FC_WIDTH, FONT_WIDTH_NUMERIC (entity));
263 FcPatternAddDouble (pat, FC_PIXEL_SIZE, pixel_size);
264 val = AREF (entity, FONT_FAMILY_INDEX);
265 if (! NILP (val))
266 FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) SDATA (SYMBOL_NAME (val)));
267 val = AREF (entity, FONT_FOUNDRY_INDEX);
268 if (! NILP (val))
269 FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) SDATA (SYMBOL_NAME (val)));
270 val = AREF (entity, FONT_SPACING_INDEX);
271 if (! NILP (val))
272 FcPatternAddInteger (pat, FC_SPACING, XFIXNUM (val));
273 val = AREF (entity, FONT_DPI_INDEX);
274 if (! NILP (val))
275 {
276 double dbl = XFIXNUM (val);
277
278 FcPatternAddDouble (pat, FC_DPI, dbl);
279 }
280 val = AREF (entity, FONT_AVGWIDTH_INDEX);
281 if (FIXNUMP (val) && XFIXNUM (val) == 0)
282 FcPatternAddBool (pat, FC_SCALABLE, FcTrue);
283 /* This is necessary to identify the exact font (e.g. 10x20.pcf.gz
284 over 10x20-ISO8859-1.pcf.gz). */
285 FcPatternAddCharSet (pat, FC_CHARSET, ftfont_get_fc_charset (entity));
286
287 xftfont_add_rendering_parameters (pat, entity);
288
289 FcPatternAddString (pat, FC_FILE, (FcChar8 *) SDATA (filename));
290 FcPatternAddInteger (pat, FC_INDEX, XFIXNUM (idx));
291
292 154
293 block_input (); 155 block_input ();
294 156
157 pat = ftfont_entity_pattern (entity, pixel_size);
295 /* Substitute in values from X resources and XftDefaultSet. */ 158 /* Substitute in values from X resources and XftDefaultSet. */
296 XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat); 159 XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat);
297 match = XftFontMatch (display, FRAME_X_SCREEN_NUMBER (f), pat, &result); 160 match = XftFontMatch (display, FRAME_X_SCREEN_NUMBER (f), pat, &result);
298 xftfont_fix_match (pat, match); 161 ftfont_fix_match (pat, match);
299 162
300 FcPatternDestroy (pat); 163 FcPatternDestroy (pat);
301 xftfont = XftFontOpenPattern (display, match); 164 xftfont = XftFontOpenPattern (display, match);
@@ -695,7 +558,7 @@ xftfont_cached_font_ok (struct frame *f, Lisp_Object font_object,
695 bool ok = false; 558 bool ok = false;
696 int i1, i2, r1, r2; 559 int i1, i2, r1, r2;
697 560
698 xftfont_add_rendering_parameters (pat, entity); 561 ftfont_add_rendering_parameters (pat, entity);
699 XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat); 562 XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat);
700 563
701 r1 = FcPatternGetBool (pat, FC_ANTIALIAS, 0, &b1); 564 r1 = FcPatternGetBool (pat, FC_ANTIALIAS, 0, &b1);
@@ -768,12 +631,6 @@ void
768syms_of_xftfont (void) 631syms_of_xftfont (void)
769{ 632{
770 DEFSYM (Qxft, "xft"); 633 DEFSYM (Qxft, "xft");
771 DEFSYM (QChinting, ":hinting");
772 DEFSYM (QCautohint, ":autohint");
773 DEFSYM (QChintstyle, ":hintstyle");
774 DEFSYM (QCrgba, ":rgba");
775 DEFSYM (QCembolden, ":embolden");
776 DEFSYM (QClcdfilter, ":lcdfilter");
777 634
778 DEFVAR_BOOL ("xft-font-ascent-descent-override", 635 DEFVAR_BOOL ("xft-font-ascent-descent-override",
779 xft_font_ascent_descent_override, 636 xft_font_ascent_descent_override,