aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenichi Handa2007-12-18 11:40:00 +0000
committerKenichi Handa2007-12-18 11:40:00 +0000
commitca4da08aaada9de39390f339aeba00411f8edcc2 (patch)
tree9bec069baa0ad2ec7a4947646c96b1b801cbafe2
parenta4c7190998680d4e29e60f5387aaf57a3245774e (diff)
downloademacs-ca4da08aaada9de39390f339aeba00411f8edcc2.tar.gz
emacs-ca4da08aaada9de39390f339aeba00411f8edcc2.zip
(font_prepare_cache, font_finish_cache, font_get_cache): New
functions. (font_clear_cache): New function. (font_list_entities): Use font_get_cache. (font_matching_entity): Likewise. (font_update_drivers): Call font_clear_cache when finishing a driver.
-rw-r--r--src/font.c234
1 files changed, 169 insertions, 65 deletions
diff --git a/src/font.c b/src/font.c
index 27c4c7411ed..3b07e3db59c 100644
--- a/src/font.c
+++ b/src/font.c
@@ -2119,6 +2119,136 @@ font_find_object (font)
2119 return Qnil; 2119 return Qnil;
2120} 2120}
2121 2121
2122
2123/* Font cache
2124
2125 Each font backend has the callback function get_cache, and it
2126 returns a cons cell of which cdr part can be freely used for
2127 caching fonts. The cons cell may be shared by multiple frames
2128 and/or multiple font drivers. So, we arrange the cdr part as this:
2129
2130 ((DRIVER-TYPE NUM-FRAMES FONT-CACHE-DATA ...) ...)
2131
2132 where DRIVER-TYPE is a symbol such as `x', `xft', etc., NUM-FRAMES
2133 is a number frames sharing this cache, and FONT-CACHE-DATA is a
2134 cons (FONT-SPEC FONT-ENTITY ...). */
2135
2136static void font_prepare_cache P_ ((FRAME_PTR, struct font_driver *));
2137static void font_finish_cache P_ ((FRAME_PTR, struct font_driver *));
2138static Lisp_Object font_get_cache P_ ((FRAME_PTR, struct font_driver *));
2139static void font_clear_cache P_ ((FRAME_PTR, Lisp_Object,
2140 struct font_driver *));
2141
2142static void
2143font_prepare_cache (f, driver)
2144 FRAME_PTR f;
2145 struct font_driver *driver;
2146{
2147 Lisp_Object cache, val;
2148
2149 cache = driver->get_cache (f);
2150 val = XCDR (cache);
2151 while (CONSP (val) && ! EQ (XCAR (XCAR (val)), driver->type))
2152 val = XCDR (val);
2153 if (NILP (val))
2154 {
2155 val = Fcons (driver->type, Fcons (make_number (1), Qnil));
2156 XSETCDR (cache, Fcons (val, XCDR (cache)));
2157 }
2158 else
2159 {
2160 val = XCDR (XCAR (val));
2161 XSETCAR (val, make_number (XINT (XCAR (val)) + 1));
2162 }
2163}
2164
2165static void
2166font_finish_cache (f, driver)
2167 FRAME_PTR f;
2168 struct font_driver *driver;
2169{
2170 Lisp_Object cache, val, tmp;
2171
2172
2173 cache = driver->get_cache (f);
2174 val = XCDR (cache);
2175 while (CONSP (val) && ! EQ (XCAR (XCAR (val)), driver->type))
2176 cache = val, val = XCDR (val);
2177 xassert (! NILP (val));
2178 tmp = XCDR (XCAR (val));
2179 if (XINT (XCAR (tmp)) == 0)
2180 {
2181 font_clear_cache (f, XCAR (val), driver);
2182 XSETCDR (cache, XCDR (val));
2183 }
2184 else
2185 {
2186 XSETCAR (tmp, make_number (XINT (XCAR (tmp)) - 1));
2187 }
2188}
2189
2190static Lisp_Object
2191font_get_cache (f, driver)
2192 FRAME_PTR f;
2193 struct font_driver *driver;
2194{
2195 Lisp_Object val = driver->get_cache (f);
2196 Lisp_Object type = driver->type;
2197
2198 xassert (CONSP (val));
2199 for (val = XCDR (val); ! EQ (XCAR (XCAR (val)), type); val = XCDR (val));
2200 xassert (CONSP (val));
2201 /* VAL = ((DRIVER-TYPE NUM-FRAMES FONT-CACHE-DATA ...) ...) */
2202 val = XCDR (XCAR (val));
2203 return val;
2204}
2205
2206static void
2207font_clear_cache (f, cache, driver)
2208 FRAME_PTR f;
2209 Lisp_Object cache;
2210 struct font_driver *driver;
2211{
2212 Lisp_Object tail, elt;
2213
2214 /* CACHE = (DRIVER-TYPE NUM-FRAMES FONT-CACHE-DATA ...) */
2215 for (tail = XCDR (XCDR (cache)); CONSP (tail); tail = XCDR (tail))
2216 {
2217 elt = XCAR (tail);
2218 if (CONSP (elt) && FONT_SPEC_P (XCAR (elt)))
2219 {
2220 Lisp_Object vec = XCDR (elt);
2221 int i;
2222
2223 for (i = 0; i < ASIZE (vec); i++)
2224 {
2225 Lisp_Object entity = AREF (vec, i);
2226
2227 if (EQ (driver->type, AREF (entity, FONT_TYPE_INDEX)))
2228 {
2229 Lisp_Object objlist = AREF (entity, FONT_OBJLIST_INDEX);
2230
2231 for (; CONSP (objlist); objlist = XCDR (objlist))
2232 {
2233 Lisp_Object val = XCAR (objlist);
2234 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
2235 struct font *font = p->pointer;
2236
2237 xassert (font && driver == font->driver);
2238 driver->close (f, font);
2239 p->pointer = NULL;
2240 p->integer = 0;
2241 }
2242 if (driver->free_entity)
2243 driver->free_entity (entity);
2244 }
2245 }
2246 }
2247 }
2248 XSETCDR (cache, Qnil);
2249}
2250
2251
2122static Lisp_Object scratch_font_spec, scratch_font_prefer; 2252static Lisp_Object scratch_font_spec, scratch_font_prefer;
2123 2253
2124 2254
@@ -2160,17 +2290,16 @@ font_list_entities (frame, spec)
2160 if (driver_list->on 2290 if (driver_list->on
2161 && (NILP (ftype) || EQ (driver_list->driver->type, ftype))) 2291 && (NILP (ftype) || EQ (driver_list->driver->type, ftype)))
2162 { 2292 {
2163 Lisp_Object cache = driver_list->driver->get_cache (frame); 2293 Lisp_Object cache = font_get_cache (f, driver_list->driver);
2164 Lisp_Object tail = alternate_familes; 2294 Lisp_Object tail = alternate_familes;
2165 Lisp_Object val;
2166 2295
2167 xassert (CONSP (cache));
2168 ASET (spec, FONT_TYPE_INDEX, driver_list->driver->type); 2296 ASET (spec, FONT_TYPE_INDEX, driver_list->driver->type);
2169 ASET (spec, FONT_FAMILY_INDEX, family); 2297 ASET (spec, FONT_FAMILY_INDEX, family);
2170 2298
2171 while (1) 2299 while (1)
2172 { 2300 {
2173 val = assoc_no_quit (spec, XCDR (cache)); 2301 Lisp_Object val = assoc_no_quit (spec, XCDR (cache));
2302
2174 if (CONSP (val)) 2303 if (CONSP (val))
2175 val = XCDR (val); 2304 val = XCDR (val);
2176 else 2305 else
@@ -2217,10 +2346,9 @@ font_matching_entity (frame, spec)
2217 if (driver_list->on 2346 if (driver_list->on
2218 && (NILP (ftype) || EQ (driver_list->driver->type, ftype))) 2347 && (NILP (ftype) || EQ (driver_list->driver->type, ftype)))
2219 { 2348 {
2220 Lisp_Object cache = driver_list->driver->get_cache (frame); 2349 Lisp_Object cache = font_get_cache (f, driver_list->driver);
2221 Lisp_Object key; 2350 Lisp_Object key;
2222 2351
2223 xassert (CONSP (cache));
2224 ASET (spec, FONT_TYPE_INDEX, driver_list->driver->type); 2352 ASET (spec, FONT_TYPE_INDEX, driver_list->driver->type);
2225 key = Fcons (spec, Qnil); 2353 key = Fcons (spec, Qnil);
2226 entity = assoc_no_quit (key, XCDR (cache)); 2354 entity = assoc_no_quit (key, XCDR (cache));
@@ -2756,13 +2884,12 @@ free_font_driver_list (f)
2756 2884
2757 2885
2758/* Make the frame F use font backends listed in NEW_DRIVERS (list of 2886/* Make the frame F use font backends listed in NEW_DRIVERS (list of
2759 symbols, e.g. xft, x). If NEW_DRIVERS is nil, make F use all 2887 symbols, e.g. xft, x). If NEW_DRIVERS is t, make F use all
2760 available font drivers. If no backend is available, dont't alter 2888 available font drivers. If NEW_DRIVERS is nil, finalize all drivers.
2761 F->font_driver_list.
2762 2889
2763 A caller must free all realized faces and clear all font caches if 2890 A caller must free all realized faces if any in advance. The
2764 any in advance. The return value is a list of font backends 2891 return value is a list of font backends actually made used on
2765 actually made used on F. */ 2892 F. */
2766 2893
2767Lisp_Object 2894Lisp_Object
2768font_update_drivers (f, new_drivers) 2895font_update_drivers (f, new_drivers)
@@ -2772,27 +2899,32 @@ font_update_drivers (f, new_drivers)
2772 Lisp_Object active_drivers = Qnil; 2899 Lisp_Object active_drivers = Qnil;
2773 struct font_driver_list *list; 2900 struct font_driver_list *list;
2774 2901
2775 /* At first, finialize all font drivers for F. */
2776 for (list = f->font_driver_list; list; list = list->next) 2902 for (list = f->font_driver_list; list; list = list->next)
2777 if (list->on) 2903 if (list->on)
2778 { 2904 {
2779 if (list->driver->end_for_frame) 2905 if (! EQ (new_drivers, Qt)
2780 list->driver->end_for_frame (f); 2906 && NILP (Fmemq (list->driver->type, new_drivers)))
2781 list->on = 0; 2907 {
2908 if (list->driver->end_for_frame)
2909 list->driver->end_for_frame (f);
2910 font_finish_cache (f, list->driver);
2911 list->on = 0;
2912 }
2782 } 2913 }
2783 2914 else
2784 /* Then start the requested drivers. */
2785 for (list = f->font_driver_list; list; list = list->next)
2786 if (NILP (new_drivers)
2787 || ! NILP (Fmemq (list->driver->type, new_drivers)))
2788 { 2915 {
2789 if (! list->driver->start_for_frame 2916 if (EQ (new_drivers, Qt)
2790 || list->driver->start_for_frame (f) == 0); 2917 || ! NILP (Fmemq (list->driver->type, new_drivers)))
2791 { 2918 {
2792 list->on = 1; 2919 if (! list->driver->start_for_frame
2793 active_drivers = nconc2 (active_drivers, 2920 || list->driver->start_for_frame (f) == 0)
2794 Fcons (list->driver->type, Qnil)); 2921 {
2795 } 2922 font_prepare_cache (f, list->driver);
2923 list->on = 1;
2924 active_drivers = nconc2 (active_drivers,
2925 Fcons (list->driver->type, Qnil));
2926 }
2927 }
2796 } 2928 }
2797 2929
2798 return active_drivers; 2930 return active_drivers;
@@ -3192,46 +3324,18 @@ DEFUN ("clear-font-cache", Fclear_font_cache, Sclear_font_cache, 0, 0, 0,
3192 for (; driver_list; driver_list = driver_list->next) 3324 for (; driver_list; driver_list = driver_list->next)
3193 if (driver_list->on) 3325 if (driver_list->on)
3194 { 3326 {
3195 Lisp_Object cache = driver_list->driver->get_cache (frame); 3327 Lisp_Object cache = driver_list->driver->get_cache (f);
3196 Lisp_Object tail, elt; 3328 Lisp_Object val;
3197 3329
3198 for (tail = XCDR (cache); CONSP (tail); tail = XCDR (tail)) 3330 val = XCDR (cache);
3331 while (! EQ (XCAR (val), driver_list->driver->type))
3332 val = XCDR (val);
3333 val = XCDR (XCAR (val));
3334 if (XINT (XCAR (val)) == 0)
3199 { 3335 {
3200 elt = XCAR (tail); 3336 font_clear_cache (f, XCAR (val), driver_list->driver);
3201 if (CONSP (elt) && FONT_SPEC_P (XCAR (elt))) 3337 XSETCDR (cache, XCDR (val));
3202 {
3203 Lisp_Object vec = XCDR (elt);
3204 int i;
3205
3206 for (i = 0; i < ASIZE (vec); i++)
3207 {
3208 Lisp_Object entity = AREF (vec, i);
3209
3210 if (EQ (driver_list->driver->type,
3211 AREF (entity, FONT_TYPE_INDEX)))
3212 {
3213 Lisp_Object objlist
3214 = AREF (entity, FONT_OBJLIST_INDEX);
3215
3216 for (; CONSP (objlist); objlist = XCDR (objlist))
3217 {
3218 Lisp_Object val = XCAR (objlist);
3219 struct Lisp_Save_Value *p = XSAVE_VALUE (val);
3220 struct font *font = p->pointer;
3221
3222 xassert (font && (driver_list->driver
3223 == font->driver));
3224 driver_list->driver->close (f, font);
3225 p->pointer = NULL;
3226 p->integer = 0;
3227 }
3228 if (driver_list->driver->free_entity)
3229 driver_list->driver->free_entity (entity);
3230 }
3231 }
3232 }
3233 } 3338 }
3234 XSETCDR (cache, Qnil);
3235 } 3339 }
3236 } 3340 }
3237 3341