Mercurial > emacs
comparison src/xftfont.c @ 106755:574dd89b7759
Fix slowdown and wrong font choosed by XSETTINGS changes. bug #5157.
* font.c (font_open_entity): Enable chache and call cached_font_ok
for the driver if defined.
(QCuser_spec): New symbol.
(font_spec_from_name): Save name as user-spec.
(font_load_for_lface): Keep user-spec instead of name.
(font_open_by_name): Save name as user-spec.
(syms_of_font): Initialize QCuser_spec.
* xftfont.c (xftfont_open): Call xftfont_add_rendering_parameters.
(xftfont_add_rendering_parameters, xftfont_cached_font_ok): New.
(syms_of_xftfont): Initialize xftfont_driver.cached_font_ok.
* font.h (struct font_driver): Add cached_font_ok.
* font-setting.el (font-setting-change-default-font): Use user-spec
instead of name.
author | Jan D. <jan.h.d@swipnet.se> |
---|---|
date | Wed, 06 Jan 2010 20:38:39 +0100 |
parents | 3d091f151696 |
children | 1d1d5d9bd884 |
comparison
equal
deleted
inserted
replaced
106754:b6846b19b0db | 106755:574dd89b7759 |
---|---|
235 FcPatternDel (match, FC_DPI); | 235 FcPatternDel (match, FC_DPI); |
236 FcPatternAddDouble (match, FC_DPI, dpi); | 236 FcPatternAddDouble (match, FC_DPI, dpi); |
237 } | 237 } |
238 } | 238 } |
239 | 239 |
240 static Lisp_Object | 240 static void |
241 xftfont_open (f, entity, pixel_size) | 241 xftfont_add_rendering_parameters (pat, entity) |
242 FRAME_PTR f; | 242 FcPattern *pat; |
243 Lisp_Object entity; | 243 Lisp_Object entity; |
244 int pixel_size; | 244 { |
245 { | 245 Lisp_Object tail; |
246 FcResult result; | 246 int ival; |
247 Display *display = FRAME_X_DISPLAY (f); | |
248 Lisp_Object val, filename, index, tail, font_object; | |
249 FcPattern *pat = NULL, *match; | |
250 struct xftfont_info *xftfont_info = NULL; | |
251 struct font *font; | |
252 double size = 0; | |
253 XftFont *xftfont = NULL; | |
254 int spacing; | |
255 char name[256]; | |
256 int len, i, ival; | |
257 XGlyphInfo extents; | |
258 FT_Face ft_face; | |
259 FcMatrix *matrix; | |
260 | |
261 val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX)); | |
262 if (! CONSP (val)) | |
263 return Qnil; | |
264 val = XCDR (val); | |
265 filename = XCAR (val); | |
266 index = XCDR (val); | |
267 size = XINT (AREF (entity, FONT_SIZE_INDEX)); | |
268 if (size == 0) | |
269 size = pixel_size; | |
270 pat = FcPatternCreate (); | |
271 FcPatternAddInteger (pat, FC_WEIGHT, FONT_WEIGHT_NUMERIC (entity)); | |
272 i = FONT_SLANT_NUMERIC (entity) - 100; | |
273 if (i < 0) i = 0; | |
274 FcPatternAddInteger (pat, FC_SLANT, i); | |
275 FcPatternAddInteger (pat, FC_WIDTH, FONT_WIDTH_NUMERIC (entity)); | |
276 FcPatternAddDouble (pat, FC_PIXEL_SIZE, pixel_size); | |
277 val = AREF (entity, FONT_FAMILY_INDEX); | |
278 if (! NILP (val)) | |
279 FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) SDATA (SYMBOL_NAME (val))); | |
280 val = AREF (entity, FONT_FOUNDRY_INDEX); | |
281 if (! NILP (val)) | |
282 FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) SDATA (SYMBOL_NAME (val))); | |
283 val = AREF (entity, FONT_SPACING_INDEX); | |
284 if (! NILP (val)) | |
285 FcPatternAddInteger (pat, FC_SPACING, XINT (val)); | |
286 val = AREF (entity, FONT_DPI_INDEX); | |
287 if (! NILP (val)) | |
288 { | |
289 double dbl = XINT (val); | |
290 | |
291 FcPatternAddDouble (pat, FC_DPI, dbl); | |
292 } | |
293 val = AREF (entity, FONT_AVGWIDTH_INDEX); | |
294 if (INTEGERP (val) && XINT (val) == 0) | |
295 FcPatternAddBool (pat, FC_SCALABLE, FcTrue); | |
296 /* This is necessary to identify the exact font (e.g. 10x20.pcf.gz | |
297 over 10x20-ISO8859-1.pcf.gz). */ | |
298 FcPatternAddCharSet (pat, FC_CHARSET, ftfont_get_fc_charset (entity)); | |
299 | 247 |
300 for (tail = AREF (entity, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail)) | 248 for (tail = AREF (entity, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail)) |
301 { | 249 { |
302 Lisp_Object key, val; | 250 Lisp_Object key = XCAR (XCAR (tail)); |
303 | 251 Lisp_Object val = XCDR (XCAR (tail)); |
304 key = XCAR (XCAR (tail)), val = XCDR (XCAR (tail)); | 252 |
305 if (EQ (key, QCantialias)) | 253 if (EQ (key, QCantialias)) |
306 FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue); | 254 FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue); |
307 else if (EQ (key, QChinting)) | 255 else if (EQ (key, QChinting)) |
308 FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue); | 256 FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue); |
309 else if (EQ (key, QCautohint)) | 257 else if (EQ (key, QCautohint)) |
335 #ifdef FC_EMBOLDEN | 283 #ifdef FC_EMBOLDEN |
336 else if (EQ (key, QCembolden)) | 284 else if (EQ (key, QCembolden)) |
337 FcPatternAddBool (pat, FC_EMBOLDEN, NILP (val) ? FcFalse : FcTrue); | 285 FcPatternAddBool (pat, FC_EMBOLDEN, NILP (val) ? FcFalse : FcTrue); |
338 #endif | 286 #endif |
339 } | 287 } |
288 } | |
289 | |
290 static Lisp_Object | |
291 xftfont_open (f, entity, pixel_size) | |
292 FRAME_PTR f; | |
293 Lisp_Object entity; | |
294 int pixel_size; | |
295 { | |
296 FcResult result; | |
297 Display *display = FRAME_X_DISPLAY (f); | |
298 Lisp_Object val, filename, index, font_object; | |
299 FcPattern *pat = NULL, *match; | |
300 struct xftfont_info *xftfont_info = NULL; | |
301 struct font *font; | |
302 double size = 0; | |
303 XftFont *xftfont = NULL; | |
304 int spacing; | |
305 char name[256]; | |
306 int len, i; | |
307 XGlyphInfo extents; | |
308 FT_Face ft_face; | |
309 FcMatrix *matrix; | |
310 | |
311 val = assq_no_quit (QCfont_entity, AREF (entity, FONT_EXTRA_INDEX)); | |
312 if (! CONSP (val)) | |
313 return Qnil; | |
314 val = XCDR (val); | |
315 filename = XCAR (val); | |
316 index = XCDR (val); | |
317 size = XINT (AREF (entity, FONT_SIZE_INDEX)); | |
318 if (size == 0) | |
319 size = pixel_size; | |
320 pat = FcPatternCreate (); | |
321 FcPatternAddInteger (pat, FC_WEIGHT, FONT_WEIGHT_NUMERIC (entity)); | |
322 i = FONT_SLANT_NUMERIC (entity) - 100; | |
323 if (i < 0) i = 0; | |
324 FcPatternAddInteger (pat, FC_SLANT, i); | |
325 FcPatternAddInteger (pat, FC_WIDTH, FONT_WIDTH_NUMERIC (entity)); | |
326 FcPatternAddDouble (pat, FC_PIXEL_SIZE, pixel_size); | |
327 val = AREF (entity, FONT_FAMILY_INDEX); | |
328 if (! NILP (val)) | |
329 FcPatternAddString (pat, FC_FAMILY, (FcChar8 *) SDATA (SYMBOL_NAME (val))); | |
330 val = AREF (entity, FONT_FOUNDRY_INDEX); | |
331 if (! NILP (val)) | |
332 FcPatternAddString (pat, FC_FOUNDRY, (FcChar8 *) SDATA (SYMBOL_NAME (val))); | |
333 val = AREF (entity, FONT_SPACING_INDEX); | |
334 if (! NILP (val)) | |
335 FcPatternAddInteger (pat, FC_SPACING, XINT (val)); | |
336 val = AREF (entity, FONT_DPI_INDEX); | |
337 if (! NILP (val)) | |
338 { | |
339 double dbl = XINT (val); | |
340 | |
341 FcPatternAddDouble (pat, FC_DPI, dbl); | |
342 } | |
343 val = AREF (entity, FONT_AVGWIDTH_INDEX); | |
344 if (INTEGERP (val) && XINT (val) == 0) | |
345 FcPatternAddBool (pat, FC_SCALABLE, FcTrue); | |
346 /* This is necessary to identify the exact font (e.g. 10x20.pcf.gz | |
347 over 10x20-ISO8859-1.pcf.gz). */ | |
348 FcPatternAddCharSet (pat, FC_CHARSET, ftfont_get_fc_charset (entity)); | |
349 | |
350 xftfont_add_rendering_parameters (pat, entity); | |
340 | 351 |
341 FcPatternAddString (pat, FC_FILE, (FcChar8 *) SDATA (filename)); | 352 FcPatternAddString (pat, FC_FILE, (FcChar8 *) SDATA (filename)); |
342 FcPatternAddInteger (pat, FC_INDEX, XINT (index)); | 353 FcPatternAddInteger (pat, FC_INDEX, XINT (index)); |
343 | 354 |
344 | 355 |
710 font_put_frame_data (f, &xftfont_driver, NULL); | 721 font_put_frame_data (f, &xftfont_driver, NULL); |
711 } | 722 } |
712 return 0; | 723 return 0; |
713 } | 724 } |
714 | 725 |
726 static int | |
727 xftfont_cached_font_ok (f, font_object, entity) | |
728 struct frame *f; | |
729 Lisp_Object font_object; | |
730 Lisp_Object entity; | |
731 | |
732 { | |
733 struct xftfont_info *info = (struct xftfont_info *) XFONT_OBJECT (font_object); | |
734 FcPattern *oldpat = info->xftfont->pattern; | |
735 Display *display = FRAME_X_DISPLAY (f); | |
736 FcPattern *pat = FcPatternCreate (); | |
737 FcBool b1, b2; | |
738 int ok = 0, i1, i2, r1, r2; | |
739 | |
740 xftfont_add_rendering_parameters (pat, entity); | |
741 XftDefaultSubstitute (display, FRAME_X_SCREEN_NUMBER (f), pat); | |
742 | |
743 r1 = FcPatternGetBool (pat, FC_ANTIALIAS, 0, &b1); | |
744 r2 = FcPatternGetBool (oldpat, FC_ANTIALIAS, 0, &b2); | |
745 if (r1 != r2 || b1 != b2) goto out; | |
746 r1 = FcPatternGetBool (pat, FC_HINTING, 0, &b1); | |
747 r2 = FcPatternGetBool (oldpat, FC_HINTING, 0, &b2); | |
748 if (r1 != r2 || b1 != b2) goto out; | |
749 r1 = FcPatternGetBool (pat, FC_AUTOHINT, 0, &b1); | |
750 r2 = FcPatternGetBool (oldpat, FC_AUTOHINT, 0, &b2); | |
751 if (r1 != r2 || b1 != b2) goto out; | |
752 #ifdef FC_EMBOLDEN | |
753 r1 = FcPatternGetBool (pat, FC_EMBOLDEN, 0, &b1); | |
754 r2 = FcPatternGetBool (oldpat, FC_EMBOLDEN, 0, &b2); | |
755 if (r1 != r2 || b1 != b2) goto out; | |
756 #endif | |
757 r1 = FcPatternGetInteger (pat, FC_HINT_STYLE, 0, &i1); | |
758 r2 = FcPatternGetInteger (oldpat, FC_HINT_STYLE, 0, &i2); | |
759 if (r1 != r2 || i1 != i2) goto out; | |
760 r1 = FcPatternGetInteger (pat, FC_LCD_FILTER, 0, &i1); | |
761 r2 = FcPatternGetInteger (oldpat, FC_LCD_FILTER, 0, &i2); | |
762 if (r1 != r2 || i1 != i2) goto out; | |
763 r1 = FcPatternGetInteger (pat, FC_RGBA, 0, &i1); | |
764 r2 = FcPatternGetInteger (oldpat, FC_RGBA, 0, &i2); | |
765 if (r1 != r2 || i1 != i2) goto out; | |
766 | |
767 ok = 1; | |
768 out: | |
769 FcPatternDestroy (pat); | |
770 return ok; | |
771 } | |
772 | |
715 void | 773 void |
716 syms_of_xftfont () | 774 syms_of_xftfont () |
717 { | 775 { |
718 DEFSYM (Qxft, "xft"); | 776 DEFSYM (Qxft, "xft"); |
719 DEFSYM (QChinting, ":hinting"); | 777 DEFSYM (QChinting, ":hinting"); |
735 xftfont_driver.has_char = xftfont_has_char; | 793 xftfont_driver.has_char = xftfont_has_char; |
736 xftfont_driver.encode_char = xftfont_encode_char; | 794 xftfont_driver.encode_char = xftfont_encode_char; |
737 xftfont_driver.text_extents = xftfont_text_extents; | 795 xftfont_driver.text_extents = xftfont_text_extents; |
738 xftfont_driver.draw = xftfont_draw; | 796 xftfont_driver.draw = xftfont_draw; |
739 xftfont_driver.end_for_frame = xftfont_end_for_frame; | 797 xftfont_driver.end_for_frame = xftfont_end_for_frame; |
798 xftfont_driver.cached_font_ok = xftfont_cached_font_ok; | |
740 | 799 |
741 register_font_driver (&xftfont_driver, NULL); | 800 register_font_driver (&xftfont_driver, NULL); |
742 } | 801 } |
743 | 802 |
744 /* arch-tag: 64ec61bf-7c8e-4fe6-b953-c6a85d5e1605 | 803 /* arch-tag: 64ec61bf-7c8e-4fe6-b953-c6a85d5e1605 |