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