<rdar://problem/10071256> Retain retired custom fonts until the next style recalc
[WebKit-https.git] / Source / WebKit / efl / ewk / ewk_view_tiled.cpp
1 /*
2     Copyright (C) 2009-2010 Samsung Electronics
3     Copyright (C) 2009-2010 ProFUSION embedded systems
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public License
16     along with this library; see the file COPYING.LIB.  If not, write to
17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18     Boston, MA 02110-1301, USA.
19 */
20
21 #include "config.h"
22 #include "ewk_view.h"
23
24 #include "ewk_logging.h"
25 #include "ewk_private.h"
26
27 #include <Evas.h>
28 #include <eina_safety_checks.h>
29 #include <ewk_tiled_backing_store.h>
30
31 static Ewk_View_Smart_Class _parent_sc = EWK_VIEW_SMART_CLASS_INIT_NULL;
32
33 static Eina_Bool _ewk_view_tiled_render_cb(void *data, Ewk_Tile *t, const Eina_Rectangle *area)
34 {
35     Ewk_View_Private_Data *priv = (Ewk_View_Private_Data*)data;
36     Eina_Rectangle r = {area->x + t->x, area->y + t->y, area->w, area->h};
37
38     return ewk_view_paint_contents(priv, t->cairo, &r);
39 }
40
41 static void *_ewk_view_tiled_updates_process_pre(void *data, Evas_Object *o)
42 {
43     Ewk_View_Private_Data *priv = (Ewk_View_Private_Data*)data;
44     ewk_view_layout_if_needed_recursive(priv);
45     return 0;
46 }
47
48 static Evas_Object *_ewk_view_tiled_smart_backing_store_add(Ewk_View_Smart_Data *sd)
49 {
50     Evas_Object *bs = ewk_tiled_backing_store_add(sd->base.evas);
51     ewk_tiled_backing_store_render_cb_set
52         (bs, _ewk_view_tiled_render_cb, sd->_priv);
53     ewk_tiled_backing_store_updates_process_pre_set
54         (bs, _ewk_view_tiled_updates_process_pre, sd->_priv);
55     return bs;
56 }
57
58 static void
59 _ewk_view_tiled_contents_size_changed_cb(void *data, Evas_Object *o, void *event_info)
60 {
61     Evas_Coord *size = (Evas_Coord*)event_info;
62     Ewk_View_Smart_Data *sd = (Ewk_View_Smart_Data*)data;
63
64     ewk_tiled_backing_store_contents_resize
65         (sd->backing_store, size[0], size[1]);
66 }
67
68 static void _ewk_view_tiled_smart_add(Evas_Object *o)
69 {
70     Ewk_View_Smart_Data *sd;
71
72     _parent_sc.sc.add(o);
73
74     sd = (Ewk_View_Smart_Data*)evas_object_smart_data_get(o);
75     if (!sd)
76         return;
77
78     evas_object_smart_callback_add(
79         sd->main_frame, "contents,size,changed",
80         _ewk_view_tiled_contents_size_changed_cb, sd);
81     ewk_frame_paint_full_set(sd->main_frame, EINA_TRUE);
82 }
83
84 static Eina_Bool _ewk_view_tiled_smart_scrolls_process(Ewk_View_Smart_Data *sd)
85 {
86     const Ewk_Scroll_Request *sr;
87     const Ewk_Scroll_Request *sr_end;
88     size_t count;
89     Evas_Coord vw, vh;
90
91     ewk_frame_contents_size_get(sd->main_frame, &vw, &vh);
92
93     sr = ewk_view_scroll_requests_get(sd->_priv, &count);
94     sr_end = sr + count;
95     for (; sr < sr_end; sr++) {
96         if (sr->main_scroll)
97             ewk_tiled_backing_store_scroll_full_offset_add
98                 (sd->backing_store, sr->dx, sr->dy);
99         else {
100             Evas_Coord sx, sy, sw, sh;
101
102             sx = sr->x;
103             sy = sr->y;
104             sw = sr->w;
105             sh = sr->h;
106
107             if (abs(sr->dx) >= sw || abs(sr->dy) >= sh) {
108                 /* doubt webkit would be so     stupid... */
109                 DBG("full page scroll %+03d,%+03d. convert to repaint %d,%d + %dx%d",
110                     sr->dx, sr->dy, sx, sy, sw, sh);
111                 ewk_view_repaint_add(sd->_priv, sx, sy, sw, sh);
112                 continue;
113             }
114
115             if (sx + sw > vw)
116                 sw = vw - sx;
117             if (sy + sh > vh)
118                 sh = vh - sy;
119
120             if (sw < 0)
121                 sw = 0;
122             if (sh < 0)
123                 sh = 0;
124
125             if (!sw || !sh)
126                 continue;
127
128             sx -= abs(sr->dx);
129             sy -= abs(sr->dy);
130             sw += abs(sr->dx);
131             sh += abs(sr->dy);
132             ewk_view_repaint_add(sd->_priv, sx, sy, sw, sh);
133             INF("using repaint for inner frame scolling!");
134         }
135     }
136
137     return EINA_TRUE;
138 }
139
140 static Eina_Bool _ewk_view_tiled_smart_repaints_process(Ewk_View_Smart_Data *sd)
141 {
142     const Eina_Rectangle *pr, *pr_end;
143     size_t count;
144     int sx, sy;
145
146     ewk_frame_scroll_pos_get(sd->main_frame, &sx, &sy);
147
148     pr = ewk_view_repaints_get(sd->_priv, &count);
149     pr_end = pr + count;
150     for (; pr < pr_end; pr++) {
151         Eina_Rectangle r;
152         r.x = pr->x + sx;
153         r.y = pr->y + sy;
154         r.w = pr->w;
155         r.h = pr->h;
156         ewk_tiled_backing_store_update(sd->backing_store, &r);
157     }
158     ewk_tiled_backing_store_updates_process(sd->backing_store);
159
160     return EINA_TRUE;
161 }
162
163 static Eina_Bool _ewk_view_tiled_smart_contents_resize(Ewk_View_Smart_Data *sd, int w, int h)
164 {
165     ewk_tiled_backing_store_contents_resize(sd->backing_store, w, h);
166     return EINA_TRUE;
167 }
168
169 static Eina_Bool _ewk_view_tiled_smart_zoom_set(Ewk_View_Smart_Data *sd, float zoom, Evas_Coord cx, Evas_Coord cy)
170 {
171     Evas_Coord x, y, w, h;
172     Eina_Bool r;
173     r = ewk_tiled_backing_store_zoom_set(sd->backing_store,
174                                          &zoom, cx, cy, &x, &y);
175     if (!r)
176         return r;
177     ewk_tiled_backing_store_disabled_update_set(sd->backing_store, EINA_TRUE);
178     r = _parent_sc.zoom_set(sd, zoom, cx, cy);
179     ewk_frame_scroll_set(sd->main_frame, -x, -y);
180     ewk_frame_scroll_size_get(sd->main_frame, &w, &h);
181     ewk_tiled_backing_store_fix_offsets(sd->backing_store, w, h);
182     ewk_view_scrolls_process(sd);
183     evas_object_smart_calculate(sd->backing_store);
184     evas_object_smart_calculate(sd->self);
185     ewk_tiled_backing_store_disabled_update_set(sd->backing_store, EINA_FALSE);
186     return r;
187 }
188
189 static Eina_Bool _ewk_view_tiled_smart_zoom_weak_set(Ewk_View_Smart_Data *sd, float zoom, Evas_Coord cx, Evas_Coord cy)
190 {
191     return ewk_tiled_backing_store_zoom_weak_set(sd->backing_store, zoom, cx, cy);
192 }
193
194 static void _ewk_view_tiled_smart_zoom_weak_smooth_scale_set(Ewk_View_Smart_Data *sd, Eina_Bool smooth_scale)
195 {
196     ewk_tiled_backing_store_zoom_weak_smooth_scale_set(sd->backing_store, smooth_scale);
197 }
198
199 static void _ewk_view_tiled_smart_flush(Ewk_View_Smart_Data *sd)
200 {
201     ewk_tiled_backing_store_flush(sd->backing_store);
202     _parent_sc.flush(sd);
203 }
204
205 static Eina_Bool _ewk_view_tiled_smart_pre_render_region(Ewk_View_Smart_Data *sd, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, float zoom)
206 {
207     return ewk_tiled_backing_store_pre_render_region
208         (sd->backing_store, x, y, w, h, zoom);
209 }
210
211 static Eina_Bool _ewk_view_tiled_smart_pre_render_relative_radius(Ewk_View_Smart_Data *sd, unsigned int n, float zoom)
212 {
213     return ewk_tiled_backing_store_pre_render_relative_radius
214         (sd->backing_store, n, zoom);
215 }
216
217 static void _ewk_view_tiled_smart_pre_render_cancel(Ewk_View_Smart_Data *sd)
218 {
219     ewk_tiled_backing_store_pre_render_cancel(sd->backing_store);
220 }
221
222 static Eina_Bool _ewk_view_tiled_smart_disable_render(Ewk_View_Smart_Data *sd)
223 {
224     return ewk_tiled_backing_store_disable_render(sd->backing_store);
225 }
226
227 static Eina_Bool _ewk_view_tiled_smart_enable_render(Ewk_View_Smart_Data *sd)
228 {
229     return ewk_tiled_backing_store_enable_render(sd->backing_store);
230 }
231
232 Eina_Bool ewk_view_tiled_smart_set(Ewk_View_Smart_Class *api)
233 {
234     if (!ewk_view_base_smart_set(api))
235         return EINA_FALSE;
236
237     if (EINA_UNLIKELY(!_parent_sc.sc.add))
238         ewk_view_base_smart_set(&_parent_sc);
239
240     api->sc.add = _ewk_view_tiled_smart_add;
241
242     api->backing_store_add = _ewk_view_tiled_smart_backing_store_add;
243     api->scrolls_process = _ewk_view_tiled_smart_scrolls_process;
244     api->repaints_process = _ewk_view_tiled_smart_repaints_process;
245     api->contents_resize = _ewk_view_tiled_smart_contents_resize;
246     api->zoom_set = _ewk_view_tiled_smart_zoom_set;
247     api->zoom_weak_set = _ewk_view_tiled_smart_zoom_weak_set;
248     api->zoom_weak_smooth_scale_set = _ewk_view_tiled_smart_zoom_weak_smooth_scale_set;
249     api->flush = _ewk_view_tiled_smart_flush;
250     api->pre_render_region = _ewk_view_tiled_smart_pre_render_region;
251     api->pre_render_relative_radius = _ewk_view_tiled_smart_pre_render_relative_radius;
252     api->pre_render_cancel = _ewk_view_tiled_smart_pre_render_cancel;
253     api->disable_render = _ewk_view_tiled_smart_disable_render;
254     api->enable_render = _ewk_view_tiled_smart_enable_render;
255     return EINA_TRUE;
256 }
257
258 static inline Evas_Smart *_ewk_view_tiled_smart_class_new(void)
259 {
260     static Ewk_View_Smart_Class api = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("EWK_View_Tiled");
261     static Evas_Smart *smart = 0;
262
263     if (EINA_UNLIKELY(!smart)) {
264         ewk_view_tiled_smart_set(&api);
265         smart = evas_smart_class_new(&api.sc);
266     }
267
268     return smart;
269 }
270
271 Evas_Object *ewk_view_tiled_add(Evas *e)
272 {
273     return evas_object_smart_add(e, _ewk_view_tiled_smart_class_new());
274 }
275
276 Ewk_Tile_Unused_Cache *ewk_view_tiled_unused_cache_get(const Evas_Object *o)
277 {
278     Ewk_View_Smart_Data *sd = ewk_view_smart_data_get(o);
279     EINA_SAFETY_ON_NULL_RETURN_VAL(sd, 0);
280     return ewk_tiled_backing_store_tile_unused_cache_get(sd->backing_store);
281 }
282
283 void ewk_view_tiled_unused_cache_set(Evas_Object *o, Ewk_Tile_Unused_Cache *cache)
284 {
285     Ewk_View_Smart_Data *sd = ewk_view_smart_data_get(o);
286     EINA_SAFETY_ON_NULL_RETURN(sd);
287     ewk_tiled_backing_store_tile_unused_cache_set(sd->backing_store, cache);
288 }