• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2     Copyright (C) 2009-2010 ProFUSION embedded systems
3     Copyright (C) 2009-2010 Samsung Electronics
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_frame.h"
25 #include "ewk_logging.h"
26 
27 #include <Evas.h>
28 #include <eina_safety_checks.h>
29 #include <string.h>
30 
31 static Ewk_View_Smart_Class _parent_sc = EWK_VIEW_SMART_CLASS_INIT_NULL;
32 
_ewk_view_single_on_del(void * data,Evas * e,Evas_Object * o,void * event_info)33 static void _ewk_view_single_on_del(void *data, Evas *e, Evas_Object *o, void *event_info)
34 {
35     Evas_Object *clip = (Evas_Object*)data;
36     evas_object_del(clip);
37 }
38 
_ewk_view_single_smart_add(Evas_Object * o)39 static void _ewk_view_single_smart_add(Evas_Object *o)
40 {
41     Ewk_View_Smart_Data *sd;
42 
43     _parent_sc.sc.add(o);
44 
45     sd = (Ewk_View_Smart_Data *)evas_object_smart_data_get(o);
46 
47     Evas_Object *clip = evas_object_rectangle_add(sd->base.evas);
48     evas_object_clip_set(sd->backing_store, clip);
49     evas_object_smart_member_add(clip, o);
50     evas_object_show(clip);
51 
52     evas_object_event_callback_add
53         (sd->backing_store, EVAS_CALLBACK_DEL, _ewk_view_single_on_del, clip);
54 }
55 
_ewk_view_single_smart_backing_store_add(Ewk_View_Smart_Data * sd)56 static Evas_Object *_ewk_view_single_smart_backing_store_add(Ewk_View_Smart_Data *sd)
57 {
58     Evas_Object *bs = evas_object_image_add(sd->base.evas);
59     evas_object_image_alpha_set(bs, EINA_FALSE);
60     evas_object_image_smooth_scale_set(bs, sd->zoom_weak_smooth_scale);
61 
62     return bs;
63 }
64 
_ewk_view_single_smart_resize(Evas_Object * o,Evas_Coord w,Evas_Coord h)65 static void _ewk_view_single_smart_resize(Evas_Object *o, Evas_Coord w, Evas_Coord h)
66 {
67     Ewk_View_Smart_Data *sd = (Ewk_View_Smart_Data*)evas_object_smart_data_get(o);
68     _parent_sc.sc.resize(o, w, h);
69 
70     // these should be queued and processed in calculate as well!
71     evas_object_image_size_set(sd->backing_store, w, h);
72     if (sd->animated_zoom.zoom.current < 0.00001) {
73         Evas_Object *clip = evas_object_clip_get(sd->backing_store);
74         Evas_Coord x, y, cw, ch;
75         evas_object_image_fill_set(sd->backing_store, 0, 0, w, h);
76         evas_object_geometry_get(sd->backing_store, &x, &y, 0, 0);
77         evas_object_move(clip, x, y);
78         ewk_frame_contents_size_get(sd->main_frame, &cw, &ch);
79         if (w > cw)
80             w = cw;
81         if (h > ch)
82             h = ch;
83         evas_object_resize(clip, w, h);
84     }
85 }
86 
_ewk_view_4b_move_region_up(uint32_t * image,size_t rows,size_t x,size_t y,size_t w,size_t h,size_t rowsize)87 static inline void _ewk_view_4b_move_region_up(uint32_t *image, size_t rows, size_t x, size_t y, size_t w, size_t h, size_t rowsize)
88 {
89     uint32_t *src;
90     uint32_t *dst;
91 
92     dst = image + x + y * rowsize;
93     src = dst + rows * rowsize;
94     h -= rows;
95 
96     for (; h > 0; h--, dst += rowsize, src += rowsize)
97         memcpy(dst, src, w * 4);
98 }
99 
_ewk_view_4b_move_region_down(uint32_t * image,size_t rows,size_t x,size_t y,size_t w,size_t h,size_t rowsize)100 static inline void _ewk_view_4b_move_region_down(uint32_t *image, size_t rows, size_t x, size_t y, size_t w, size_t h, size_t rowsize)
101 {
102     uint32_t *src;
103     uint32_t *dst;
104 
105     h -= rows;
106     src = image + x + (y + h - 1) * rowsize;
107     dst = src + rows * rowsize;
108 
109     for (; h > 0; h--, dst -= rowsize, src -= rowsize)
110         memcpy(dst, src, w * 4);
111 }
112 
_ewk_view_4b_move_line_left(uint32_t * dst,const uint32_t * src,size_t count)113 static inline void _ewk_view_4b_move_line_left(uint32_t *dst, const uint32_t *src, size_t count)
114 {
115     uint32_t *dst_end = dst + count;
116     /* no memcpy() as it does not allow overlapping regions */
117     /* no memmove() as it will copy to a temporary buffer */
118     /* TODO: loop unrolling, copying up to quad-words would help */
119     for (; dst < dst_end; dst++, src++)
120         *dst = *src;
121 }
122 
_ewk_view_4b_move_line_right(uint32_t * dst,uint32_t * src,size_t count)123 static inline void _ewk_view_4b_move_line_right(uint32_t *dst, uint32_t *src, size_t count)
124 {
125     uint32_t *dst_end = dst - count;
126     /* no memcpy() as it does not allow overlapping regions */
127     /* no memmove() as it will copy to a temporary buffer */
128     /* TODO: loop unrolling, copying up to quad-words would help */
129     for (; dst > dst_end; dst--, src--)
130         *dst = *src;
131 }
132 
_ewk_view_4b_move_region_left(uint32_t * image,size_t cols,size_t x,size_t y,size_t w,size_t h,size_t rowsize)133 static inline void _ewk_view_4b_move_region_left(uint32_t *image, size_t cols, size_t x, size_t y, size_t w, size_t h, size_t rowsize)
134 {
135     uint32_t *src;
136     uint32_t *dst;
137 
138     dst = image + x + y * rowsize;
139     src = dst + cols;
140     w -= cols;
141 
142     for (; h > 0; h--, dst += rowsize, src += rowsize)
143         _ewk_view_4b_move_line_left(dst, src, w);
144 }
145 
_ewk_view_4b_move_region_right(uint32_t * image,size_t cols,size_t x,size_t y,size_t w,size_t h,size_t rowsize)146 static inline void _ewk_view_4b_move_region_right(uint32_t *image, size_t cols, size_t x, size_t y, size_t w, size_t h, size_t rowsize)
147 {
148     uint32_t *src;
149     uint32_t *dst;
150 
151     w -= cols;
152     src = image + (x + w - 1) + y * rowsize;
153     dst = src + cols;
154 
155     for (; h > 0; h--, dst += rowsize, src += rowsize)
156         _ewk_view_4b_move_line_right(dst, src, w);
157 }
158 
159 /* catch-all function, not as optimized as the others, but does the work. */
_ewk_view_4b_move_region(uint32_t * image,int dx,int dy,size_t x,size_t y,size_t w,size_t h,size_t rowsize)160 static inline void _ewk_view_4b_move_region(uint32_t *image, int dx, int dy, size_t x, size_t y, size_t w, size_t h, size_t rowsize)
161 {
162     uint32_t *src;
163     uint32_t *dst;
164 
165     if (dy < 0) {
166         h += dy;
167         dst = image + x + y * rowsize;
168         src = dst - dy * rowsize;
169         if (dx <= 0) {
170             w += dx;
171             src -= dx;
172             for (; h > 0; h--, dst += rowsize, src += rowsize)
173                 _ewk_view_4b_move_line_left(dst, src, w);
174         } else {
175             w -= dx;
176             src += w - 1;
177             dst += w + dx -1;
178             for (; h > 0; h--, dst += rowsize, src += rowsize)
179                 _ewk_view_4b_move_line_right(dst, src, w);
180         }
181     } else {
182         h -= dy;
183         src = image + x + (y + h - 1) * rowsize;
184         dst = src + dy * rowsize;
185         if (dx <= 0) {
186             w += dx;
187             src -= dx;
188             for (; h > 0; h--, dst -= rowsize, src -= rowsize)
189                 _ewk_view_4b_move_line_left(dst, src, w);
190         } else {
191             w -= dx;
192             src += w - 1;
193             dst += w + dx - 1;
194             for (; h > 0; h--, dst -= rowsize, src -= rowsize)
195                 _ewk_view_4b_move_line_right(dst, src, w);
196         }
197     }
198 }
199 
_ewk_view_single_scroll_process_single(Ewk_View_Smart_Data * sd,void * pixels,Evas_Coord ow,Evas_Coord oh,const Ewk_Scroll_Request * sr)200 static inline void _ewk_view_single_scroll_process_single(Ewk_View_Smart_Data *sd, void *pixels, Evas_Coord ow, Evas_Coord oh, const Ewk_Scroll_Request *sr)
201 {
202     Evas_Coord sx, sy, sw, sh;
203 
204     DBG("%d,%d + %d,%d %+03d,%+03d, store: %p %dx%d",
205         sr->x, sr->y, sr->w, sr->h, sr->dx, sr->dy, pixels, ow, oh);
206 
207     sx = sr->x;
208     sy = sr->y;
209     sw = sr->w;
210     sh = sr->h;
211 
212     if (abs(sr->dx) >= sw || abs(sr->dy) >= sh) {
213         /* doubt webkit would be so stupid... */
214         DBG("full page scroll %+03d,%+03d. convert to repaint %d,%d + %dx%d",
215             sr->dx, sr->dy, sx, sy, sw, sh);
216         ewk_view_repaint_add(sd->_priv, sx, sy, sw, sh);
217         return;
218     }
219 
220     if (sx < 0) {
221         sw += sx;
222         sx = 0;
223     }
224     if (sy < 0) {
225         sh += sy;
226         sy = 0;
227     }
228 
229     if (sx + sw > ow)
230         sw = ow - sx;
231     if (sy + sh > oh)
232         sh = oh - sy;
233 
234     if (sw < 0)
235         sw = 0;
236     if (sh < 0)
237         sh = 0;
238 
239     EINA_SAFETY_ON_TRUE_RETURN(!sw || !sh);
240     if (!sr->dx) {
241         if (sr->dy < 0) {
242             DBG("scroll up: %+03d,%+03d update=%d,%d+%dx%d, "
243                 "repaint=%d,%d+%dx%d",
244                 sr->dx, sr->dy, sx, sy, sw, sh + sr->dy,
245                 sx, sy + sh + sr->dy, sw, -sr->dy);
246 
247             _ewk_view_4b_move_region_up
248                 ((uint32_t*)pixels, -sr->dy, sx, sy, sw, sh, ow);
249             evas_object_image_data_update_add
250                 (sd->backing_store, sx, sy, sw, sh + sr->dy);
251 
252             ewk_view_repaint_add(sd->_priv, sx, sy + sh + sr->dy, sw, -sr->dy);
253         } else if (sr->dy > 0) {
254             DBG("scroll down: %+03d,%+03d update=%d,%d+%dx%d, "
255                 "repaint=%d,%d+%dx%d",
256                 sr->dx, sr->dy, sx, sy + sr->dy, sw, sh - sr->dy,
257                 sx, sy, sw, sr->dy);
258 
259             _ewk_view_4b_move_region_down
260                 ((uint32_t*)pixels, sr->dy, sx, sy, sw, sh, ow);
261             evas_object_image_data_update_add
262                 (sd->backing_store, sx, sy + sr->dy, sw, sh - sr->dy);
263 
264             ewk_view_repaint_add(sd->_priv, sx, sy, sw, sr->dy);
265         }
266     } else if (!sr->dy) {
267         if (sr->dx < 0) {
268             DBG("scroll left: %+03d,%+03d update=%d,%d+%dx%d, "
269                 "repaint=%d,%d+%dx%d",
270                 sr->dx, sr->dy, sx, sy, sw + sr->dx, sh,
271                 sx + sw + sr->dx, sy, -sr->dx, sh);
272 
273             _ewk_view_4b_move_region_left
274                 ((uint32_t*)pixels, -sr->dx, sx, sy, sw, sh, ow);
275             evas_object_image_data_update_add
276                 (sd->backing_store, sx, sy, sw + sr->dx, sh);
277 
278             ewk_view_repaint_add(sd->_priv, sx + sw + sr->dx, sy, -sr->dx, sh);
279         } else if (sr->dx > 0) {
280             DBG("scroll up: %+03d,%+03d update=%d,%d+%dx%d, "
281                 "repaint=%d,%d+%dx%d",
282                 sr->dx, sr->dy, sx + sr->dx, sy, sw - sr->dx, sh,
283                 sx, sy, sr->dx, sh);
284 
285             _ewk_view_4b_move_region_right
286                 ((uint32_t*)pixels, sr->dx, sx, sy, sw, sh, ow);
287             evas_object_image_data_update_add
288                 (sd->backing_store, sx + sr->dx, sy, sw - sr->dx, sh);
289 
290             ewk_view_repaint_add(sd->_priv, sx, sy, sr->dx, sh);
291         }
292     } else {
293         Evas_Coord mx, my, mw, mh, ax, ay, aw, ah, bx, by, bw, bh;
294 
295         if (sr->dx < 0) {
296             mx = sx;
297             mw = sw + sr->dx;
298             ax = mx + mw;
299             aw = -sr->dx;
300         } else {
301             ax = sx;
302             aw = sr->dx;
303             mx = ax + aw;
304             mw = sw - sr->dx;
305         }
306 
307         if (sr->dy < 0) {
308             my = sy;
309             mh = sh + sr->dy;
310             by = my + mh;
311             bh = -sr->dy;
312         } else {
313             by = sy;
314             bh = sr->dy;
315             my = by + bh;
316             mh = sh - sr->dy;
317         }
318 
319         ay = my;
320         ah = mh;
321         bx = sx;
322         bw = sw;
323 
324         DBG("scroll diagonal: %+03d,%+03d update=%d,%d+%dx%d, "
325             "repaints: h=%d,%d+%dx%d v=%d,%d+%dx%d",
326             sr->dx, sr->dy, mx, my, mw, mh, ax, ay, aw, ah, bx, by, bw, bh);
327 
328         _ewk_view_4b_move_region
329             ((uint32_t*)pixels, sr->dx, sr->dy, sx, sy, sw, sh, ow);
330 
331         evas_object_image_data_update_add(sd->backing_store, mx, my, mw, mh);
332         ewk_view_repaint_add(sd->_priv, ax, ay, aw, ah);
333         ewk_view_repaint_add(sd->_priv, bx, by, bw, bh);
334     }
335 }
336 
_ewk_view_single_smart_scrolls_process(Ewk_View_Smart_Data * sd)337 static Eina_Bool _ewk_view_single_smart_scrolls_process(Ewk_View_Smart_Data *sd)
338 {
339     const Ewk_Scroll_Request *sr;
340     const Ewk_Scroll_Request *sr_end;
341     Evas_Coord ow, oh;
342     size_t count;
343     void *pixels = evas_object_image_data_get(sd->backing_store, 1);
344     evas_object_image_size_get(sd->backing_store, &ow, &oh);
345 
346     sr = ewk_view_scroll_requests_get(sd->_priv, &count);
347     sr_end = sr + count;
348     for (; sr < sr_end; sr++)
349         _ewk_view_single_scroll_process_single(sd, pixels, ow, oh, sr);
350 
351     evas_object_image_data_set(sd->backing_store, pixels);
352 
353     return EINA_TRUE;
354 }
355 
_ewk_view_single_smart_repaints_process(Ewk_View_Smart_Data * sd)356 static Eina_Bool _ewk_view_single_smart_repaints_process(Ewk_View_Smart_Data *sd)
357 {
358     Ewk_View_Paint_Context *ctxt;
359     Evas_Coord ow, oh;
360     void *pixels;
361     Eina_Rectangle *r;
362     const Eina_Rectangle *pr;
363     const Eina_Rectangle *pr_end;
364     Eina_Tiler *tiler;
365     Eina_Iterator *itr;
366     cairo_status_t status;
367     cairo_surface_t *surface;
368     cairo_format_t format;
369     cairo_t *cairo;
370     size_t count;
371     Eina_Bool ret = EINA_TRUE;
372 
373     if (sd->animated_zoom.zoom.current < 0.00001) {
374         Evas_Object *clip = evas_object_clip_get(sd->backing_store);
375         Evas_Coord w, h, cw, ch;
376         // reset effects of zoom_weak_set()
377         evas_object_image_fill_set
378             (sd->backing_store, 0, 0, sd->view.w, sd->view.h);
379         evas_object_move(clip, sd->view.x, sd->view.y);
380 
381         w = sd->view.w;
382         h = sd->view.h;
383 
384         ewk_frame_contents_size_get(sd->main_frame, &cw, &ch);
385         if (w > cw)
386             w = cw;
387         if (h > ch)
388             h = ch;
389         evas_object_resize(clip, w, h);
390     }
391 
392     pixels = evas_object_image_data_get(sd->backing_store, 1);
393     evas_object_image_size_get(sd->backing_store, &ow, &oh);
394 
395     if (sd->bg_color.a < 255)
396         format = CAIRO_FORMAT_ARGB32;
397     else
398         format = CAIRO_FORMAT_RGB24;
399 
400     surface = cairo_image_surface_create_for_data
401         ((unsigned char*)pixels, format, ow, oh, ow * 4);
402     status = cairo_surface_status(surface);
403     if (status != CAIRO_STATUS_SUCCESS) {
404         ERR("could not create surface from data %dx%d: %s",
405             ow, oh, cairo_status_to_string(status));
406         ret = EINA_FALSE;
407         goto error_cairo_surface;
408     }
409     cairo = cairo_create(surface);
410     status = cairo_status(cairo);
411     if (status != CAIRO_STATUS_SUCCESS) {
412         ERR("could not create cairo from surface %dx%d: %s",
413             ow, oh, cairo_status_to_string(status));
414         ret = EINA_FALSE;
415         goto error_cairo;
416     }
417 
418     ctxt = ewk_view_paint_context_new(sd->_priv, cairo);
419     if (!ctxt) {
420         ERR("could not create paint context");
421         ret = EINA_FALSE;
422         goto error_paint_context;
423     }
424 
425     tiler = eina_tiler_new(ow, oh);
426     if (!tiler) {
427         ERR("could not create tiler %dx%d", ow, oh);
428         ret = EINA_FALSE;
429         goto error_tiler;
430     }
431 
432     pr = ewk_view_repaints_get(sd->_priv, &count);
433     pr_end = pr + count;
434     for (; pr < pr_end; pr++)
435         eina_tiler_rect_add(tiler, pr);
436 
437     itr = eina_tiler_iterator_new(tiler);
438     if (!itr) {
439         ERR("could not get iterator for tiler");
440         ret = EINA_FALSE;
441         goto error_iterator;
442     }
443 
444     int sx, sy;
445     ewk_frame_scroll_pos_get(sd->main_frame, &sx, &sy);
446 
447     EINA_ITERATOR_FOREACH(itr, r) {
448         Eina_Rectangle scrolled_rect = {
449             r->x + sx, r->y + sy,
450             r->w, r->h
451         };
452 
453         ewk_view_paint_context_save(ctxt);
454 
455         if ((sx) || (sy))
456             ewk_view_paint_context_translate(ctxt, -sx, -sy);
457 
458         ewk_view_paint_context_clip(ctxt, &scrolled_rect);
459         ewk_view_paint_context_paint_contents(ctxt, &scrolled_rect);
460 
461         ewk_view_paint_context_restore(ctxt);
462         evas_object_image_data_update_add
463             (sd->backing_store, r->x, r->y, r->w, r->h);
464     }
465     eina_iterator_free(itr);
466 
467 error_iterator:
468     eina_tiler_free(tiler);
469 error_tiler:
470     ewk_view_paint_context_free(ctxt);
471 error_paint_context:
472     cairo_destroy(cairo);
473 error_cairo:
474     cairo_surface_destroy(surface);
475 error_cairo_surface:
476     evas_object_image_data_set(sd->backing_store, pixels); /* dec refcount */
477 
478     return ret;
479 }
480 
_ewk_view_single_smart_zoom_weak_set(Ewk_View_Smart_Data * sd,float zoom,Evas_Coord cx,Evas_Coord cy)481 static Eina_Bool _ewk_view_single_smart_zoom_weak_set(Ewk_View_Smart_Data *sd, float zoom, Evas_Coord cx, Evas_Coord cy)
482 {
483     // TODO: review
484     float scale = zoom / sd->animated_zoom.zoom.start;
485     Evas_Coord w = sd->view.w * scale;
486     Evas_Coord h = sd->view.h * scale;
487     Evas_Coord dx, dy, cw, ch;
488     Evas_Object *clip = evas_object_clip_get(sd->backing_store);
489 
490     ewk_frame_contents_size_get(sd->main_frame, &cw, &ch);
491     if (sd->view.w > 0 && sd->view.h > 0) {
492         dx = (w * (sd->view.w - cx)) / sd->view.w;
493         dy = (h * (sd->view.h - cy)) / sd->view.h;
494     } else {
495         dx = 0;
496         dy = 0;
497     }
498 
499     evas_object_image_fill_set(sd->backing_store, cx + dx, cy + dy, w, h);
500 
501     if (sd->view.w > 0 && sd->view.h > 0) {
502         dx = ((sd->view.w - w) * cx) / sd->view.w;
503         dy = ((sd->view.h - h) * cy) / sd->view.h;
504     } else {
505         dx = 0;
506         dy = 0;
507     }
508     evas_object_move(clip, sd->view.x + dx, sd->view.y + dy);
509 
510     if (cw < sd->view.w)
511         w = cw * scale;
512     if (ch < sd->view.h)
513         h = ch * scale;
514     evas_object_resize(clip, w, h);
515     return EINA_TRUE;
516 }
517 
_ewk_view_single_smart_zoom_weak_smooth_scale_set(Ewk_View_Smart_Data * sd,Eina_Bool smooth_scale)518 static void _ewk_view_single_smart_zoom_weak_smooth_scale_set(Ewk_View_Smart_Data *sd, Eina_Bool smooth_scale)
519 {
520     evas_object_image_smooth_scale_set(sd->backing_store, smooth_scale);
521 }
522 
_ewk_view_single_smart_bg_color_set(Ewk_View_Smart_Data * sd,unsigned char r,unsigned char g,unsigned char b,unsigned char a)523 static void _ewk_view_single_smart_bg_color_set(Ewk_View_Smart_Data *sd, unsigned char r, unsigned char g, unsigned char b, unsigned char a)
524 {
525     evas_object_image_alpha_set(sd->backing_store, a < 255);
526 }
527 
528 /**
529  * Sets the smart class api using single backing store, enabling view
530  * to be inherited.
531  *
532  * @param api class definition to be set, all members with the
533  *        exception of Evas_Smart_Class->data may be overridden. Must
534  *        @b not be @c NULL.
535  *
536  * @note Evas_Smart_Class->data is used to implement type checking and
537  *       is not supposed to be changed/overridden. If you need extra
538  *       data for your smart class to work, just extend
539  *       Ewk_View_Smart_Class instead.
540  *
541  * @return @c EINA_TRUE on success, @c EINA_FALSE on failure (probably
542  *         version mismatch).
543  *
544  * @see ewk_view_base_smart_set()
545  */
ewk_view_single_smart_set(Ewk_View_Smart_Class * api)546 Eina_Bool ewk_view_single_smart_set(Ewk_View_Smart_Class *api)
547 {
548     if (!ewk_view_base_smart_set(api))
549         return EINA_FALSE;
550 
551     if (EINA_UNLIKELY(!_parent_sc.sc.add))
552         ewk_view_base_smart_set(&_parent_sc);
553 
554     api->sc.add = _ewk_view_single_smart_add;
555     api->sc.resize = _ewk_view_single_smart_resize;
556 
557     api->backing_store_add = _ewk_view_single_smart_backing_store_add;
558     api->scrolls_process = _ewk_view_single_smart_scrolls_process;
559     api->repaints_process = _ewk_view_single_smart_repaints_process;
560     api->zoom_weak_set = _ewk_view_single_smart_zoom_weak_set;
561     api->zoom_weak_smooth_scale_set = _ewk_view_single_smart_zoom_weak_smooth_scale_set;
562     api->bg_color_set = _ewk_view_single_smart_bg_color_set;
563 
564     return EINA_TRUE;
565 }
566 
_ewk_view_single_smart_class_new(void)567 static inline Evas_Smart *_ewk_view_single_smart_class_new(void)
568 {
569     static Ewk_View_Smart_Class api = EWK_VIEW_SMART_CLASS_INIT_NAME_VERSION("Ewk_View_Single");
570     static Evas_Smart *smart = 0;
571 
572     if (EINA_UNLIKELY(!smart)) {
573         ewk_view_single_smart_set(&api);
574         smart = evas_smart_class_new(&api.sc);
575     }
576 
577     return smart;
578 }
579 
580 /**
581  * Creates a new EFL WebKit View object.
582  *
583  * View objects are the recommended way to deal with EFL WebKit as it
584  * abstracts the complex pieces of the process.
585  *
586  * Each view is composed by a set of frames. The set has at least one
587  * frame, called 'main_frame'. See ewk_view_frame_main_get() and
588  * ewk_view_frame_focused_get().
589  *
590  * @param e canvas where to create the view object.
591  *
592  * @return view object or @c NULL if errors.
593  *
594  * @see ewk_view_uri_set()
595  */
ewk_view_single_add(Evas * e)596 Evas_Object *ewk_view_single_add(Evas *e)
597 {
598     return evas_object_smart_add(e, _ewk_view_single_smart_class_new());
599 }
600