Evas.Image: Add new classes Snapshot and Proxy

Efl.Canvas.Snapshot and Efl.Canvas.Proxy are specialized
classes previously implemented as features of Evas.Image.

Note: this half of the work, as I suffered from a bad
merge and rebase with my work branch on top of master.
This commit is contained in:
Jean-Philippe Andre 2016-03-14 19:10:54 +09:00
parent 0fc0db0020
commit 68beccd1a9
7 changed files with 386 additions and 1 deletions

View File

@ -41,6 +41,8 @@ evas_eolian_pub_files = \
lib/evas/canvas/efl_vg_gradient.eo \
lib/evas/canvas/efl_vg_gradient_radial.eo \
lib/evas/canvas/efl_vg_gradient_linear.eo \
lib/evas/canvas/efl_canvas_snapshot.eo \
lib/evas/canvas/efl_canvas_proxy.eo \
lib/evas/canvas/evas_filter.eo \
$(NULL)
@ -172,7 +174,9 @@ lib/evas/canvas/evas_stats.c \
lib/evas/canvas/evas_touch_point.c \
lib/evas/canvas/evas_map.c \
lib/evas/canvas/evas_gl.c \
lib/evas/canvas/evas_out.c
lib/evas/canvas/evas_out.c \
lib/evas/canvas/efl_canvas_proxy.c \
lib/evas/canvas/efl_canvas_snapshot.c
EXTRA_DIST += \
lib/evas/canvas/render2/evas_render2_th_main.c \

View File

@ -342,6 +342,9 @@ typedef void (Evas_Canvas3D_Surface_Func)(Evas_Real *out_x,
#include "canvas/evas_image.eo.h"
#include "canvas/efl_canvas_snapshot.eo.h"
#include "canvas/efl_canvas_proxy.eo.h"
/**
* @ingroup Evas_Object_VG
*

View File

@ -0,0 +1,117 @@
#include "evas_image_private.h"
#include "efl_canvas_proxy.eo.h"
#define MY_CLASS EFL_CANVAS_PROXY_CLASS
EOLIAN static Eina_Bool
_efl_canvas_proxy_source_set(Eo *eo_obj, void *pd EINA_UNUSED, Evas_Object *eo_src)
{
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS);
if (obj->delete_me && eo_src)
{
WRN("Setting deleted object %p as image source %p", eo_src, eo_obj);
return EINA_FALSE;
}
if (eo_src)
{
Evas_Object_Protected_Data *src = eo_data_scope_get(eo_src, EVAS_OBJECT_CLASS);
if (src->delete_me)
{
WRN("Setting object %p to deleted image source %p", eo_src, eo_obj);
return EINA_FALSE;
}
if (!src->layer)
{
CRI("No evas surface associated with source object (%p)", eo_src);
return EINA_FALSE;
}
if (!obj->layer)
{
CRI("No evas surface associated with destination object (%p)", eo_obj);
return EINA_FALSE;
}
if ((obj->layer && src->layer) &&
(obj->layer->evas != src->layer->evas))
{
CRI("Setting object %p from Evas (%p) from another Evas (%p)", eo_src, src->layer->evas, obj->layer->evas);
return EINA_FALSE;
}
if (eo_src == eo_obj)
{
CRI("Setting object %p as a source for itself", obj);
return EINA_FALSE;
}
}
if (o->cur->source == eo_src) return EINA_TRUE;
evas_object_async_block(obj);
_evas_object_image_cleanup(eo_obj, obj, o);
/* Kill the image if any */
if (o->cur->u.file || o->cur->key)
evas_object_image_file_set(eo_obj, NULL, NULL);
if (eo_src) _proxy_set(eo_obj, eo_src);
else _proxy_unset(eo_obj, obj, o);
return EINA_TRUE;
}
EOLIAN static Evas_Object *
_efl_canvas_proxy_source_get(Eo *eo_obj EINA_UNUSED, void *pd EINA_UNUSED)
{
Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS);
return o->cur->source;
}
EOLIAN static void
_efl_canvas_proxy_source_clip_set(Eo *eo_obj EINA_UNUSED, void *pd EINA_UNUSED, Eina_Bool source_clip)
{
Evas_Object_Protected_Data *src_obj;
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS);
source_clip = !!source_clip;
if (o->proxy_src_clip == source_clip) return;
evas_object_async_block(obj);
o->proxy_src_clip = source_clip;
if (!o->cur->source) return;
src_obj = eo_data_scope_get(o->cur->source, EVAS_OBJECT_CLASS);
evas_object_change(o->cur->source, src_obj);
}
EOLIAN static Eina_Bool
_efl_canvas_proxy_source_clip_get(Eo *eo_obj EINA_UNUSED, void *pd EINA_UNUSED)
{
Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS);
return o->proxy_src_clip;
}
EOLIAN static void
_efl_canvas_proxy_source_events_set(Eo *eo_obj EINA_UNUSED, void *pd EINA_UNUSED, Eina_Bool source_events)
{
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
Evas_Image_Data *o = eo_data_scope_get(eo_obj, EVAS_IMAGE_CLASS);
source_events = !!source_events;
if (obj->proxy->src_events == source_events) return;
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, obj->proxy, Evas_Object_Proxy_Data, proxy_write)
proxy_write->src_events = source_events;
EINA_COW_WRITE_END(evas_object_proxy_cow, obj->proxy, proxy_write);
if (!o->cur->source) return;
if ((obj->proxy->src_invisible) || (!source_events)) return;
//FIXME: Feed mouse events here.
}
EOLIAN static Eina_Bool
_efl_canvas_proxy_source_events_get(Eo *eo_obj, void *pd EINA_UNUSED)
{
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
return obj->proxy->src_events;
}
#include "efl_canvas_proxy.eo.c"

View File

@ -0,0 +1,77 @@
class Efl.Canvas.Proxy (Evas.Image, Efl.Gfx.Base, Efl.Image, Efl.Gfx.Buffer, Efl.Gfx.Fill, Efl.Gfx.View, Efl.Gfx.Filter)
{
[[Low-level proxy image object.
A proxy is a special kind of image containing the pixels from a source
object attached to it. It can be used to apply some sort of image
transformation to any object (eg. filters, map or zoom).
]]
legacy_prefix: null;
data: null;
methods {
@property source {
[[The source object for this proxy.
The proxy object will mirror the rendering contents of a given
source object in its drawing region, without affecting that
source in any way. The source must be another valid @Evas.Object.
Other effects may be applied to the proxy, such as a map (see
@Evas.Object.map) to create a reflection of the original object
(for example).
Any existing source object will be removed after this call.
Note: This property should be set as soon as creating a proxy
object, otherwise the proxy will do nothing.
Warning: You cannot set a proxy as another proxy's source.
]]
set {
return: bool; [[Returns $true in case of success.]]
}
get {}
values {
src: Evas.Object * @nonull; [[Source object to use for the proxy.]]
}
}
@property source_clip {
[[Clip this proxy object with the source object's clipper.
Use this if you want to overlay an existing object with its proxy,
and apply some sort of transformation on it.
$true means both objects will share the same clip.
@since 1.8
]]
set {}
get {}
values {
source_clip: bool; [[Whether $obj is clipped by the source
clipper ($true) or not ($false).]]
}
}
@property source_events {
[[Defines whether the events on this object are repeated to the source.
If $source is $true, it will make events on $obj to also be
repeated for the source object (see @.source.set). Even the
$obj and source geometries are different, the event position
will be transformed to the source object's space.
If $source is $false, events occurring on $obj will be
processed only on it.
@since 1.8
]]
set {}
get {}
values {
source: bool; [[Whether this object should pass events ($true) or not
($false) to its source.]]
}
}
}
implements {
}
}

View File

@ -0,0 +1,25 @@
#include "evas_image_private.h"
#include "efl_canvas_snapshot.eo.h"
#define MY_CLASS EFL_CANVAS_SNAPSHOT_CLASS
EOLIAN static Eo *
_efl_canvas_snapshot_eo_base_constructor(Eo *eo_obj, void *pd EINA_UNUSED)
{
Evas_Object_Protected_Data *obj;
eo_obj = eo_constructor(eo_super(eo_obj, MY_CLASS));
if (!eo_obj) return NULL;
efl_gfx_fill_filled_set(eo_obj, EINA_TRUE);
evas_obj_pass_events_set(eo_obj, EINA_TRUE);
obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
EINA_COW_STATE_WRITE_BEGIN(obj, sw, cur)
sw->snapshot = EINA_TRUE;
EINA_COW_STATE_WRITE_END(obj, sw, cur);
return eo_obj;
}
#include "efl_canvas_snapshot.eo.c"

View File

@ -0,0 +1,14 @@
class Efl.Canvas.Snapshot (Evas.Image, Efl.Gfx.Base, Efl.Image, Efl.Gfx.Buffer, Efl.Gfx.Fill, Efl.Gfx.View, Efl.Gfx.Filter)
{
[[Low-level snapshot image object.
A snapshot is a special kind of image containing the pixels from
all the objects below it. This allows applications to save screenshots
of all or part of their UI, or apply filters to parts of the UI.
]]
legacy_prefix: null;
data: null;
implements {
Eo.Base.constructor;
}
}

View File

@ -0,0 +1,145 @@
#ifndef EVAS_IMAGE_PRIVATE_H
#define EVAS_IMAGE_PRIVATE_H
/* Those functions are shared between legacy evas_object_image.c and the
* new efl_canvas classes (image, snapshot, proxy, ...)
*/
#define EVAS_FILTER_PROTECTED
#define EVAS_OBJECT_PROTECTED
#include "evas_common_private.h"
#include <sys/types.h>
#include <unistd.h>
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif
#include <math.h>
#include "evas_private.h"
#ifdef EVAS_CSERVE2
#include "../cserve2/evas_cs2_private.h"
#endif
#include "../common/evas_convert_color.h"
#include "../common/evas_convert_colorspace.h"
#include "../common/evas_convert_yuv.h"
#include "evas_filter.eo.h"
#include "evas_filter.h"
/* private struct for rectangle object internal data */
typedef struct _Evas_Image_Data Evas_Image_Data;
typedef struct _Evas_Object_Image_Load_Opts Evas_Object_Image_Load_Opts;
typedef struct _Evas_Object_Image_Pixels Evas_Object_Image_Pixels;
typedef struct _Evas_Object_Image_State Evas_Object_Image_State;
struct _Evas_Object_Image_Load_Opts
{
unsigned char scale_down_by;
double dpi;
short w, h;
struct {
short x, y, w, h;
} region;
struct {
int src_x, src_y, src_w, src_h;
int dst_w, dst_h;
int smooth;
int scale_hint;
} scale_load;
Eina_Bool orientation : 1;
};
struct _Evas_Object_Image_Pixels
{
Eina_List *pixel_updates;
struct {
/* FIXME: no good match for eo */
Evas_Object_Image_Pixels_Get_Cb get_pixels;
void *get_pixels_data;
} func;
Evas_Video_Surface video;
unsigned int video_caps;
};
struct _Evas_Object_Image_State
{
Evas_Coord_Rectangle fill;
struct {
short w, h, stride;
} image;
struct {
double scale;
short l, r, t, b;
unsigned char fill;
} border;
Evas_Object *source;
Evas_Map *defmap;
Evas_Canvas3D_Scene *scene;
union {
const char *file;
Eina_File *f;
} u;
const char *key;
int frame;
Evas_Colorspace cspace;
Evas_Image_Orient orient;
Eina_Bool smooth_scale : 1;
Eina_Bool has_alpha :1;
Eina_Bool opaque_valid : 1;
Eina_Bool opaque : 1;
Eina_Bool mmaped_source : 1;
};
struct _Evas_Image_Data
{
const Evas_Object_Image_State *cur;
const Evas_Object_Image_State *prev;
const Evas_Object_Image_Load_Opts *load_opts;
const Evas_Object_Image_Pixels *pixels;
void *engine_data;
int pixels_checked_out;
int load_error;
Evas_Image_Scale_Hint scale_hint;
Evas_Image_Content_Hint content_hint;
Eina_Bool changed : 1;
Eina_Bool dirty_pixels : 1;
Eina_Bool filled : 1;
Eina_Bool filled_set : 1;
Eina_Bool proxyrendering : 1;
Eina_Bool preloading : 1;
Eina_Bool video_surface : 1;
Eina_Bool video_visible : 1;
Eina_Bool created : 1;
Eina_Bool proxyerror : 1;
Eina_Bool proxy_src_clip : 1;
Eina_Bool written : 1;
Eina_Bool direct_render : 1;
Eina_Bool has_filter : 1;
struct
{
Eina_Bool video_move : 1;
Eina_Bool video_resize : 1;
Eina_Bool video_show : 1;
Eina_Bool video_hide : 1;
} delayed;
Eina_Bool legacy_type : 1;
};
/* shared functions between legacy and new eo classes */
void _evas_object_image_cleanup(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Evas_Image_Data *o);
void _proxy_unset(Evas_Object *proxy, Evas_Object_Protected_Data *obj, Evas_Image_Data *o);
void _proxy_set(Evas_Object *proxy, Evas_Object *src);
void _proxy_error(Evas_Object *proxy, void *context, void *output, void *surface, int x, int y, Eina_Bool do_async);
#endif // EVAS_IMAGE_PRIVATE_H