diff options
| author | Kenichi Handa | 2007-12-18 11:40:00 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2007-12-18 11:40:00 +0000 |
| commit | ca4da08aaada9de39390f339aeba00411f8edcc2 (patch) | |
| tree | 9bec069baa0ad2ec7a4947646c96b1b801cbafe2 /src | |
| parent | a4c7190998680d4e29e60f5387aaf57a3245774e (diff) | |
| download | emacs-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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/font.c | 234 |
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 | |||
| 2136 | static void font_prepare_cache P_ ((FRAME_PTR, struct font_driver *)); | ||
| 2137 | static void font_finish_cache P_ ((FRAME_PTR, struct font_driver *)); | ||
| 2138 | static Lisp_Object font_get_cache P_ ((FRAME_PTR, struct font_driver *)); | ||
| 2139 | static void font_clear_cache P_ ((FRAME_PTR, Lisp_Object, | ||
| 2140 | struct font_driver *)); | ||
| 2141 | |||
| 2142 | static void | ||
| 2143 | font_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 | |||
| 2165 | static void | ||
| 2166 | font_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 | |||
| 2190 | static Lisp_Object | ||
| 2191 | font_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 | |||
| 2206 | static void | ||
| 2207 | font_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 | |||
| 2122 | static Lisp_Object scratch_font_spec, scratch_font_prefer; | 2252 | static 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 | ||
| 2767 | Lisp_Object | 2894 | Lisp_Object |
| 2768 | font_update_drivers (f, new_drivers) | 2895 | font_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 | ||