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