diff options
| author | Jan Djärv | 2010-01-06 20:38:39 +0100 |
|---|---|---|
| committer | Jan Djärv | 2010-01-06 20:38:39 +0100 |
| commit | d0cf45b70247fc1f4cfc6d74c1b5f6d4ca75f0fc (patch) | |
| tree | ddbd3b141e6e402e77d48f601a9befdbccad8536 /src | |
| parent | ea2b370da2766fed12db4e7c0f33ddce12f9d0b4 (diff) | |
| download | emacs-d0cf45b70247fc1f4cfc6d74c1b5f6d4ca75f0fc.tar.gz emacs-d0cf45b70247fc1f4cfc6d74c1b5f6d4ca75f0fc.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 14 | ||||
| -rw-r--r-- | src/font.c | 23 | ||||
| -rw-r--r-- | src/font.h | 8 | ||||
| -rw-r--r-- | src/xftfont.c | 143 |
4 files changed, 136 insertions, 52 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 131abcb9f96..84b147418cb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,5 +1,19 @@ | |||
| 1 | 2010-01-06 Jan Djärv <jan.h.d@swipnet.se> | 1 | 2010-01-06 Jan Djärv <jan.h.d@swipnet.se> |
| 2 | 2 | ||
| 3 | * font.c (font_open_entity): Enable chache and call cached_font_ok | ||
| 4 | for the driver if defined. | ||
| 5 | (QCuser_spec): New symbol. | ||
| 6 | (font_spec_from_name): Save name as user-spec. | ||
| 7 | (font_load_for_lface): Keep user-spec instead of name. | ||
| 8 | (font_open_by_name): Save name as user-spec. | ||
| 9 | (syms_of_font): Initialize QCuser_spec. | ||
| 10 | |||
| 11 | * xftfont.c (xftfont_open): Call xftfont_add_rendering_parameters. | ||
| 12 | (xftfont_add_rendering_parameters, xftfont_cached_font_ok): New. | ||
| 13 | (syms_of_xftfont): Initialize xftfont_driver.cached_font_ok. | ||
| 14 | |||
| 15 | * font.h (struct font_driver): Add cached_font_ok. | ||
| 16 | |||
| 3 | * xterm.c (x_clear_frame): Queue draw for scroll bars. | 17 | * xterm.c (x_clear_frame): Queue draw for scroll bars. |
| 4 | 18 | ||
| 5 | 2010-01-05 Jan Djärv <jan.h.d@swipnet.se> | 19 | 2010-01-05 Jan Djärv <jan.h.d@swipnet.se> |
diff --git a/src/font.c b/src/font.c index ec4cb874b52..2141fe651c3 100644 --- a/src/font.c +++ b/src/font.c | |||
| @@ -2991,16 +2991,6 @@ font_open_entity (f, entity, pixel_size) | |||
| 2991 | else if (CONSP (Vface_font_rescale_alist)) | 2991 | else if (CONSP (Vface_font_rescale_alist)) |
| 2992 | scaled_pixel_size = pixel_size * font_rescale_ratio (entity); | 2992 | scaled_pixel_size = pixel_size * font_rescale_ratio (entity); |
| 2993 | 2993 | ||
| 2994 | #if 0 | ||
| 2995 | /* This doesn't work if you have changed hinting or any other parameter. | ||
| 2996 | We need to make a new object in every case to be sure. */ | ||
| 2997 | for (objlist = AREF (entity, FONT_OBJLIST_INDEX); CONSP (objlist); | ||
| 2998 | objlist = XCDR (objlist)) | ||
| 2999 | if (! NILP (AREF (XCAR (objlist), FONT_TYPE_INDEX)) | ||
| 3000 | && XFONT_OBJECT (XCAR (objlist))->pixel_size == pixel_size) | ||
| 3001 | return XCAR (objlist); | ||
| 3002 | #endif | ||
| 3003 | |||
| 3004 | val = AREF (entity, FONT_TYPE_INDEX); | 2994 | val = AREF (entity, FONT_TYPE_INDEX); |
| 3005 | for (driver_list = f->font_driver_list; | 2995 | for (driver_list = f->font_driver_list; |
| 3006 | driver_list && ! EQ (driver_list->driver->type, val); | 2996 | driver_list && ! EQ (driver_list->driver->type, val); |
| @@ -3008,6 +2998,19 @@ font_open_entity (f, entity, pixel_size) | |||
| 3008 | if (! driver_list) | 2998 | if (! driver_list) |
| 3009 | return Qnil; | 2999 | return Qnil; |
| 3010 | 3000 | ||
| 3001 | for (objlist = AREF (entity, FONT_OBJLIST_INDEX); CONSP (objlist); | ||
| 3002 | objlist = XCDR (objlist)) | ||
| 3003 | { | ||
| 3004 | Lisp_Object fn = XCAR (objlist); | ||
| 3005 | if (! NILP (AREF (fn, FONT_TYPE_INDEX)) | ||
| 3006 | && XFONT_OBJECT (fn)->pixel_size == pixel_size) | ||
| 3007 | { | ||
| 3008 | if (driver_list->driver->cached_font_ok == NULL | ||
| 3009 | || driver_list->driver->cached_font_ok (f, fn, entity)) | ||
| 3010 | return fn; | ||
| 3011 | } | ||
| 3012 | } | ||
| 3013 | |||
| 3011 | font_object = driver_list->driver->open (f, entity, scaled_pixel_size); | 3014 | font_object = driver_list->driver->open (f, entity, scaled_pixel_size); |
| 3012 | if (!NILP (font_object)) | 3015 | if (!NILP (font_object)) |
| 3013 | ASET (font_object, FONT_SIZE_INDEX, make_number (pixel_size)); | 3016 | ASET (font_object, FONT_SIZE_INDEX, make_number (pixel_size)); |
diff --git a/src/font.h b/src/font.h index 1a09df2558c..798676d546e 100644 --- a/src/font.h +++ b/src/font.h | |||
| @@ -689,6 +689,14 @@ struct font_driver | |||
| 689 | int c, unsigned variations[256])); | 689 | int c, unsigned variations[256])); |
| 690 | 690 | ||
| 691 | void (*filter_properties) P_ ((Lisp_Object font, Lisp_Object properties)); | 691 | void (*filter_properties) P_ ((Lisp_Object font, Lisp_Object properties)); |
| 692 | |||
| 693 | /* Optional. | ||
| 694 | |||
| 695 | Return non-zero if FONT_OBJECT can be used as a (cached) font | ||
| 696 | for ENTITY on frame F. */ | ||
| 697 | int (*cached_font_ok) P_ ((struct frame *f, | ||
| 698 | Lisp_Object font_object, | ||
| 699 | Lisp_Object entity)); | ||
| 692 | }; | 700 | }; |
| 693 | 701 | ||
| 694 | 702 | ||
diff --git a/src/xftfont.c b/src/xftfont.c index 82701ce0afe..26294ff16a6 100644 --- a/src/xftfont.c +++ b/src/xftfont.c | |||
| @@ -237,6 +237,56 @@ xftfont_fix_match (pat, match) | |||
| 237 | } | 237 | } |
| 238 | } | 238 | } |
| 239 | 239 | ||
| 240 | static void | ||
| 241 | xftfont_add_rendering_parameters (pat, entity) | ||
| 242 | FcPattern *pat; | ||
| 243 | Lisp_Object entity; | ||
| 244 | { | ||
| 245 | Lisp_Object tail; | ||
| 246 | int ival; | ||
| 247 | |||
| 248 | for (tail = AREF (entity, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail)) | ||
| 249 | { | ||
| 250 | Lisp_Object key = XCAR (XCAR (tail)); | ||
| 251 | Lisp_Object val = XCDR (XCAR (tail)); | ||
| 252 | |||
| 253 | if (EQ (key, QCantialias)) | ||
| 254 | FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue); | ||
| 255 | else if (EQ (key, QChinting)) | ||
| 256 | FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue); | ||
| 257 | else if (EQ (key, QCautohint)) | ||
| 258 | FcPatternAddBool (pat, FC_AUTOHINT, NILP (val) ? FcFalse : FcTrue); | ||
| 259 | else if (EQ (key, QChintstyle)) | ||
| 260 | { | ||
| 261 | if (INTEGERP (val)) | ||
| 262 | FcPatternAddInteger (pat, FC_HINT_STYLE, XINT (val)); | ||
| 263 | else if (SYMBOLP (val) | ||
| 264 | && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival)) | ||
| 265 | FcPatternAddInteger (pat, FC_HINT_STYLE, ival); | ||
| 266 | } | ||
| 267 | else if (EQ (key, QCrgba)) | ||
| 268 | { | ||
| 269 | if (INTEGERP (val)) | ||
| 270 | FcPatternAddInteger (pat, FC_RGBA, XINT (val)); | ||
| 271 | else if (SYMBOLP (val) | ||
| 272 | && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival)) | ||
| 273 | FcPatternAddInteger (pat, FC_RGBA, ival); | ||
| 274 | } | ||
| 275 | else if (EQ (key, QClcdfilter)) | ||
| 276 | { | ||
| 277 | if (INTEGERP (val)) | ||
| 278 | FcPatternAddInteger (pat, FC_LCD_FILTER, ival = XINT (val)); | ||
| 279 | else if (SYMBOLP (val) | ||
| 280 | && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival)) | ||
| 281 | FcPatternAddInteger (pat, FC_LCD_FILTER, ival); | ||
| 282 | } | ||
| 283 | #ifdef FC_EMBOLDEN | ||
| 284 | else if (EQ (key, QCembolden)) | ||
| 285 | FcPatternAddBool (pat, FC_EMBOLDEN, NILP (val) ? FcFalse : FcTrue); | ||
| 286 | #endif | ||
| 287 | } | ||
| 288 | } | ||
| 289 | |||
| 240 | static Lisp_Object | 290 | static Lisp_Object |
| 241 | xftfont_open (f, entity, pixel_size) | 291 | xftfont_open (f, entity, pixel_size) |
| 242 | FRAME_PTR f; | 292 | FRAME_PTR f; |
| @@ -245,7 +295,7 @@ xftfont_open (f, entity, pixel_size) | |||
| 245 | { | 295 | { |
| 246 | FcResult result; | 296 | FcResult result; |
| 247 | Display *display = FRAME_X_DISPLAY (f); | 297 | Display *display = FRAME_X_DISPLAY (f); |
| 248 | Lisp_Object val, filename, index, tail, font_object; | 298 | Lisp_Object val, filename, index, font_object; |
| 249 | FcPattern *pat = NULL, *match; | 299 | FcPattern *pat = NULL, *match; |
| 250 | struct xftfont_info *xftfont_info = NULL; | 300 | struct xftfont_info *xftfont_info = NULL; |
| 251 | struct font *font; | 301 | struct font *font; |
| @@ -253,7 +303,7 @@ xftfont_open (f, entity, pixel_size) | |||
| 253 | XftFont *xftfont = NULL; | 303 | XftFont *xftfont = NULL; |
| 254 | int spacing; | 304 | int spacing; |
| 255 | char name[256]; | 305 | char name[256]; |
| 256 | int len, i, ival; | 306 | int len, i; |
| 257 | XGlyphInfo extents; | 307 | XGlyphInfo extents; |
| 258 | FT_Face ft_face; | 308 | FT_Face ft_face; |
| 259 | FcMatrix *matrix; | 309 | FcMatrix *matrix; |
| @@ -297,46 +347,7 @@ xftfont_open (f, entity, pixel_size) | |||
| 297 | over 10x20-ISO8859-1.pcf.gz). */ | 347 | over 10x20-ISO8859-1.pcf.gz). */ |
| 298 | FcPatternAddCharSet (pat, FC_CHARSET, ftfont_get_fc_charset (entity)); | 348 | FcPatternAddCharSet (pat, FC_CHARSET, ftfont_get_fc_charset (entity)); |
| 299 | 349 | ||
| 300 | for (tail = AREF (entity, FONT_EXTRA_INDEX); CONSP (tail); tail = XCDR (tail)) | 350 | xftfont_add_rendering_parameters (pat, entity); |
| 301 | { | ||
| 302 | Lisp_Object key, val; | ||
| 303 | |||
| 304 | key = XCAR (XCAR (tail)), val = XCDR (XCAR (tail)); | ||
| 305 | if (EQ (key, QCantialias)) | ||
| 306 | FcPatternAddBool (pat, FC_ANTIALIAS, NILP (val) ? FcFalse : FcTrue); | ||
| 307 | else if (EQ (key, QChinting)) | ||
| 308 | FcPatternAddBool (pat, FC_HINTING, NILP (val) ? FcFalse : FcTrue); | ||
| 309 | else if (EQ (key, QCautohint)) | ||
| 310 | FcPatternAddBool (pat, FC_AUTOHINT, NILP (val) ? FcFalse : FcTrue); | ||
| 311 | else if (EQ (key, QChintstyle)) | ||
| 312 | { | ||
| 313 | if (INTEGERP (val)) | ||
| 314 | FcPatternAddInteger (pat, FC_HINT_STYLE, XINT (val)); | ||
| 315 | else if (SYMBOLP (val) | ||
| 316 | && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival)) | ||
| 317 | FcPatternAddInteger (pat, FC_HINT_STYLE, ival); | ||
| 318 | } | ||
| 319 | else if (EQ (key, QCrgba)) | ||
| 320 | { | ||
| 321 | if (INTEGERP (val)) | ||
| 322 | FcPatternAddInteger (pat, FC_RGBA, XINT (val)); | ||
| 323 | else if (SYMBOLP (val) | ||
| 324 | && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival)) | ||
| 325 | FcPatternAddInteger (pat, FC_RGBA, ival); | ||
| 326 | } | ||
| 327 | else if (EQ (key, QClcdfilter)) | ||
| 328 | { | ||
| 329 | if (INTEGERP (val)) | ||
| 330 | FcPatternAddInteger (pat, FC_LCD_FILTER, ival = XINT (val)); | ||
| 331 | else if (SYMBOLP (val) | ||
| 332 | && FcNameConstant (SDATA (SYMBOL_NAME (val)), &ival)) | ||
| 333 | FcPatternAddInteger (pat, FC_LCD_FILTER, ival); | ||
| 334 | } | ||
| 335 | #ifdef FC_EMBOLDEN | ||
| 336 | else if (EQ (key, QCembolden)) | ||
| 337 | FcPatternAddBool (pat, FC_EMBOLDEN, NILP (val) ? FcFalse : FcTrue); | ||
| 338 | #endif | ||
| 339 | } | ||
| 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)); |
| @@ -712,6 +723,53 @@ xftfont_end_for_frame (f) | |||
| 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 | { |
| @@ -737,6 +795,7 @@ syms_of_xftfont () | |||
| 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 | } |