forked from enlightenment/efl
Evas filters: EO-ify the filters API
This creates the new interface Efl.Gfx.Filter And the implementation is a mixin (evas_filter_mixin.c): Evas.Filter All the filter rendering code has now been moved to this new file. TODO: Merge image filtering.
This commit is contained in:
parent
a18107309d
commit
64fd278c62
|
@ -111,7 +111,7 @@ main(int argc, char **argv)
|
||||||
evas_object_color_set(o, 255, 255, 255, 255);
|
evas_object_color_set(o, 255, 255, 255, 255);
|
||||||
evas_object_show(o);
|
evas_object_show(o);
|
||||||
|
|
||||||
eo_do(o, evas_obj_text_filter_program_set(filter));
|
eo_do(o, efl_gfx_filter_program_set(filter));
|
||||||
|
|
||||||
ecore_evas_manual_render(wpd.ee);
|
ecore_evas_manual_render(wpd.ee);
|
||||||
evas_object_geometry_get(o, NULL, NULL, &w, &h);
|
evas_object_geometry_get(o, NULL, NULL, &w, &h);
|
||||||
|
|
|
@ -13,7 +13,9 @@ efl_eolian_files = \
|
||||||
lib/efl/interfaces/efl_gfx_gradient_base.eo \
|
lib/efl/interfaces/efl_gfx_gradient_base.eo \
|
||||||
lib/efl/interfaces/efl_gfx_gradient_linear.eo \
|
lib/efl/interfaces/efl_gfx_gradient_linear.eo \
|
||||||
lib/efl/interfaces/efl_gfx_gradient_radial.eo \
|
lib/efl/interfaces/efl_gfx_gradient_radial.eo \
|
||||||
lib/efl/interfaces/efl_model_base.eo
|
lib/efl/interfaces/efl_gfx_filter.eo \
|
||||||
|
lib/efl/interfaces/efl_model_base.eo \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
efl_eolian_files_h = $(efl_eolian_files:%.eo=%.eo.h)
|
efl_eolian_files_h = $(efl_eolian_files:%.eo=%.eo.h)
|
||||||
efl_eolian_files_c = $(efl_eolian_files:%.eo=%.eo.c)
|
efl_eolian_files_c = $(efl_eolian_files:%.eo=%.eo.c)
|
||||||
|
|
|
@ -40,7 +40,9 @@ evas_eolian_files = \
|
||||||
lib/evas/canvas/efl_vg_root_node.eo \
|
lib/evas/canvas/efl_vg_root_node.eo \
|
||||||
lib/evas/canvas/efl_vg_gradient.eo \
|
lib/evas/canvas/efl_vg_gradient.eo \
|
||||||
lib/evas/canvas/efl_vg_gradient_radial.eo \
|
lib/evas/canvas/efl_vg_gradient_radial.eo \
|
||||||
lib/evas/canvas/efl_vg_gradient_linear.eo
|
lib/evas/canvas/efl_vg_gradient_linear.eo \
|
||||||
|
lib/evas/canvas/evas_filter.eo \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
evas_eolian_type_files = \
|
evas_eolian_type_files = \
|
||||||
lib/evas/canvas/evas_types.eot
|
lib/evas/canvas/evas_types.eot
|
||||||
|
@ -520,7 +522,9 @@ lib/evas/common/evas_op_sub/op_sub_pixel_mask_i386.c
|
||||||
|
|
||||||
### Evas filters
|
### Evas filters
|
||||||
|
|
||||||
lib_evas_libevas_la_SOURCES += lib/evas/filters/evas_filter.c \
|
lib_evas_libevas_la_SOURCES += \
|
||||||
|
lib/evas/canvas/evas_filter_mixin.c \
|
||||||
|
lib/evas/filters/evas_filter.c \
|
||||||
lib/evas/filters/evas_filter_blend.c \
|
lib/evas/filters/evas_filter_blend.c \
|
||||||
lib/evas/filters/evas_filter_blur.c \
|
lib/evas/filters/evas_filter_blur.c \
|
||||||
lib/evas/filters/evas_filter_bump.c \
|
lib/evas/filters/evas_filter_bump.c \
|
||||||
|
|
|
@ -1603,7 +1603,7 @@ _edje_part_recalc_single_text(FLOAT_T sc EINA_UNUSED,
|
||||||
Edje_Part_Description_Text *chosen_desc,
|
Edje_Part_Description_Text *chosen_desc,
|
||||||
Edje_Calc_Params *params,
|
Edje_Calc_Params *params,
|
||||||
int *minw, int *minh,
|
int *minw, int *minh,
|
||||||
int *maxw, int *maxh, double pos)
|
int *maxw, int *maxh)
|
||||||
#define RECALC_SINGLE_TEXT_USING_APPLY 1
|
#define RECALC_SINGLE_TEXT_USING_APPLY 1
|
||||||
#if RECALC_SINGLE_TEXT_USING_APPLY
|
#if RECALC_SINGLE_TEXT_USING_APPLY
|
||||||
/*
|
/*
|
||||||
|
@ -1634,7 +1634,7 @@ _edje_part_recalc_single_text(FLOAT_T sc EINA_UNUSED,
|
||||||
free(sfont);
|
free(sfont);
|
||||||
params->type.text.size = size; /* XXX TODO used by further calcs, go inside recalc_apply? */
|
params->type.text.size = size; /* XXX TODO used by further calcs, go inside recalc_apply? */
|
||||||
|
|
||||||
_edje_text_recalc_apply(ed, ep, params, chosen_desc, EINA_TRUE, pos);
|
_edje_text_recalc_apply(ed, ep, params, chosen_desc, EINA_TRUE);
|
||||||
|
|
||||||
if ((!chosen_desc) ||
|
if ((!chosen_desc) ||
|
||||||
((!chosen_desc->text.min_x) && (!chosen_desc->text.min_y) &&
|
((!chosen_desc->text.min_x) && (!chosen_desc->text.min_y) &&
|
||||||
|
@ -2406,6 +2406,7 @@ _edje_part_recalc_single_map(Edje *ed,
|
||||||
static inline const char *
|
static inline const char *
|
||||||
_edje_filter_get(Edje *ed, Edje_Part_Description_Spec_Filter *filter)
|
_edje_filter_get(Edje *ed, Edje_Part_Description_Spec_Filter *filter)
|
||||||
{
|
{
|
||||||
|
if (!filter->code) return NULL;
|
||||||
if (EINA_UNLIKELY(!filter->checked_data))
|
if (EINA_UNLIKELY(!filter->checked_data))
|
||||||
{
|
{
|
||||||
Edje_String *st;
|
Edje_String *st;
|
||||||
|
@ -2433,7 +2434,6 @@ _edje_part_recalc_single_filter(Edje *ed,
|
||||||
const char *src1, *src2, *part, *code;
|
const char *src1, *src2, *part, *code;
|
||||||
Evas_Object *obj = ep->object;
|
Evas_Object *obj = ep->object;
|
||||||
Eina_List *li1, *li2;
|
Eina_List *li1, *li2;
|
||||||
Eina_Bool im = 0;
|
|
||||||
|
|
||||||
/* handle TEXT and IMAGE part types here */
|
/* handle TEXT and IMAGE part types here */
|
||||||
if (ep->part->type == EDJE_PART_TYPE_TEXT)
|
if (ep->part->type == EDJE_PART_TYPE_TEXT)
|
||||||
|
@ -2446,19 +2446,6 @@ _edje_part_recalc_single_filter(Edje *ed,
|
||||||
prev_sources = ep->typedata.text->filter.sources;
|
prev_sources = ep->typedata.text->filter.sources;
|
||||||
filter_sources = edt->text.filter.sources;
|
filter_sources = edt->text.filter.sources;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
// old form
|
|
||||||
if (ep->typedata.text->filter.code)
|
|
||||||
filter = &ep->typedata.text->filter;
|
|
||||||
else
|
|
||||||
filter = &chosen_edt->text.filter;
|
|
||||||
if (ep->typedata.text->filter.sources != chosen_edt->text.filter.sources)
|
|
||||||
{
|
|
||||||
prev_sources = ep->typedata.text->filter.sources;
|
|
||||||
filter_sources = chosen_edt->text.filter.sources;
|
|
||||||
//ep->typedata.text->filter.sources = chosen_edt->text.filter.sources;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else if (ep->part->type == EDJE_PART_TYPE_IMAGE)
|
else if (ep->part->type == EDJE_PART_TYPE_IMAGE)
|
||||||
{
|
{
|
||||||
|
@ -2470,7 +2457,6 @@ _edje_part_recalc_single_filter(Edje *ed,
|
||||||
prev_sources = edi->image.filter.sources;
|
prev_sources = edi->image.filter.sources;
|
||||||
filter_sources = chosen_edi->image.filter.sources;
|
filter_sources = chosen_edi->image.filter.sources;
|
||||||
}
|
}
|
||||||
im = 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2478,18 +2464,6 @@ _edje_part_recalc_single_filter(Edje *ed,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Implement proper EO interface/mixin and remove this ugly thing
|
|
||||||
#define efl_gfx_filter_program_set(...) do { \
|
|
||||||
if (!im) evas_obj_text_filter_program_set(__VA_ARGS__); \
|
|
||||||
else evas_obj_text_filter_program_set(__VA_ARGS__); } while (0)
|
|
||||||
#define efl_gfx_filter_source_set(...) do { \
|
|
||||||
if (!im) evas_obj_text_filter_source_set(__VA_ARGS__); \
|
|
||||||
else evas_obj_image_filter_source_set(__VA_ARGS__); } while (0)
|
|
||||||
#define efl_gfx_filter_state_set(...) do { \
|
|
||||||
if (!im) evas_obj_text_filter_state_set(__VA_ARGS__); \
|
|
||||||
/* else evas_obj_image_filter_state_set(__VA_ARGS__); */ } while (0)
|
|
||||||
// End of pure ugliness
|
|
||||||
|
|
||||||
/* common code below */
|
/* common code below */
|
||||||
code = _edje_filter_get(ed, filter);
|
code = _edje_filter_get(ed, filter);
|
||||||
if (!code)
|
if (!code)
|
||||||
|
@ -2724,7 +2698,7 @@ _edje_part_recalc_single(Edje *ed,
|
||||||
_edje_part_recalc_single_textblock(sc, ed, ep, (Edje_Part_Description_Text *)chosen_desc, params, &minw, &minh, &maxw, &maxh);
|
_edje_part_recalc_single_textblock(sc, ed, ep, (Edje_Part_Description_Text *)chosen_desc, params, &minw, &minh, &maxw, &maxh);
|
||||||
else if (ep->part->type == EDJE_PART_TYPE_TEXT)
|
else if (ep->part->type == EDJE_PART_TYPE_TEXT)
|
||||||
{
|
{
|
||||||
_edje_part_recalc_single_text(sc, ed, ep, (Edje_Part_Description_Text*) desc, (Edje_Part_Description_Text*) chosen_desc, params, &minw, &minh, &maxw, &maxh, pos);
|
_edje_part_recalc_single_text(sc, ed, ep, (Edje_Part_Description_Text*) desc, (Edje_Part_Description_Text*) chosen_desc, params, &minw, &minh, &maxw, &maxh);
|
||||||
_edje_part_recalc_single_filter(ed, ep, desc, chosen_desc, pos);
|
_edje_part_recalc_single_filter(ed, ep, desc, chosen_desc, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4522,7 +4496,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta
|
||||||
switch (ep->part->type)
|
switch (ep->part->type)
|
||||||
{
|
{
|
||||||
case EDJE_PART_TYPE_TEXT:
|
case EDJE_PART_TYPE_TEXT:
|
||||||
_edje_text_recalc_apply(ed, ep, pf, (Edje_Part_Description_Text*) chosen_desc, EINA_FALSE, pos);
|
_edje_text_recalc_apply(ed, ep, pf, (Edje_Part_Description_Text*) chosen_desc, EINA_FALSE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EDJE_PART_TYPE_PROXY:
|
case EDJE_PART_TYPE_PROXY:
|
||||||
|
|
|
@ -2293,7 +2293,7 @@ void _edje_text_recalc_apply(Edje *ed,
|
||||||
Edje_Real_Part *ep,
|
Edje_Real_Part *ep,
|
||||||
Edje_Calc_Params *params,
|
Edje_Calc_Params *params,
|
||||||
Edje_Part_Description_Text *chosen_desc,
|
Edje_Part_Description_Text *chosen_desc,
|
||||||
Eina_Bool calc_only, double state_val);
|
Eina_Bool calc_only);
|
||||||
Evas_Font_Size _edje_text_size_calc(Evas_Font_Size size, Edje_Text_Class *tc);
|
Evas_Font_Size _edje_text_size_calc(Evas_Font_Size size, Edje_Text_Class *tc);
|
||||||
const char * _edje_text_class_font_get(Edje *ed,
|
const char * _edje_text_class_font_get(Edje *ed,
|
||||||
Edje_Part_Description_Text *chosen_desc,
|
Edje_Part_Description_Text *chosen_desc,
|
||||||
|
|
|
@ -197,7 +197,7 @@ void
|
||||||
_edje_text_recalc_apply(Edje *ed, Edje_Real_Part *ep,
|
_edje_text_recalc_apply(Edje *ed, Edje_Real_Part *ep,
|
||||||
Edje_Calc_Params *params,
|
Edje_Calc_Params *params,
|
||||||
Edje_Part_Description_Text *chosen_desc,
|
Edje_Part_Description_Text *chosen_desc,
|
||||||
Eina_Bool calc_only, double state_val)
|
Eina_Bool calc_only)
|
||||||
{
|
{
|
||||||
const char *text = NULL;
|
const char *text = NULL;
|
||||||
const char *font;
|
const char *font;
|
||||||
|
|
|
@ -163,6 +163,7 @@ EAPI extern const Eo_Event_Description _EFL_GFX_PATH_CHANGED;
|
||||||
#include "interfaces/efl_gfx_gradient_base.eo.h"
|
#include "interfaces/efl_gfx_gradient_base.eo.h"
|
||||||
#include "interfaces/efl_gfx_gradient_linear.eo.h"
|
#include "interfaces/efl_gfx_gradient_linear.eo.h"
|
||||||
#include "interfaces/efl_gfx_gradient_radial.eo.h"
|
#include "interfaces/efl_gfx_gradient_radial.eo.h"
|
||||||
|
#include "interfaces/efl_gfx_filter.eo.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
interface Efl.Gfx.Filter
|
||||||
|
{
|
||||||
|
legacy_prefix: null;
|
||||||
|
/* @since 1.15 */
|
||||||
|
methods {
|
||||||
|
@property program {
|
||||||
|
set {
|
||||||
|
[[Set an evas filter program on this object.
|
||||||
|
|
||||||
|
Valid for Text and Image objects at the moment.
|
||||||
|
|
||||||
|
The argument passed to this function is a string
|
||||||
|
containing a valid Lua program based on the filters
|
||||||
|
API as described in the "Evas filters reference"
|
||||||
|
page.
|
||||||
|
|
||||||
|
Set to null to disable filtering.
|
||||||
|
]]
|
||||||
|
}
|
||||||
|
get {
|
||||||
|
[[Gets the code of the filter program set on this object.
|
||||||
|
May be null.
|
||||||
|
]]
|
||||||
|
}
|
||||||
|
values {
|
||||||
|
code: const(char)*; [[filter program source code]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@property state {
|
||||||
|
set {
|
||||||
|
[[Set the current state of the filter (for use from Edje).]]
|
||||||
|
}
|
||||||
|
values {
|
||||||
|
cur_state: const(char)*;
|
||||||
|
cur_val: double(0.0);
|
||||||
|
next_state: const(char)*;
|
||||||
|
next_val: double(0.0);
|
||||||
|
pos: double(0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@property padding {
|
||||||
|
get {
|
||||||
|
[[Gets the padding required to apply this filter.]]
|
||||||
|
}
|
||||||
|
values {
|
||||||
|
l: int;
|
||||||
|
r: int;
|
||||||
|
t: int;
|
||||||
|
b: int;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
source_set {
|
||||||
|
[[Bind an object to use as a mask or texture with Evas Filters.
|
||||||
|
|
||||||
|
This will create automatically a new RGBA buffer containing
|
||||||
|
the source object's pixels (as it is rendered).
|
||||||
|
]]
|
||||||
|
params {
|
||||||
|
@in name: const(char)*; [[buffer name as used in the program]]
|
||||||
|
@in source: Efl.Gfx.Base*; [[object to use as a proxy source]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
source_get @const {
|
||||||
|
[[Retrieve which object is attached to this filter given its
|
||||||
|
buffer name.
|
||||||
|
]]
|
||||||
|
params {
|
||||||
|
@in name: const(char)*; [[buffer name as used in the program]]
|
||||||
|
@out source: Efl.Gfx.Base*; [[object used as a proxy source]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,8 @@
|
||||||
#include "interfaces/efl_gfx_gradient_linear.eo.c"
|
#include "interfaces/efl_gfx_gradient_linear.eo.c"
|
||||||
#include "interfaces/efl_gfx_gradient_radial.eo.c"
|
#include "interfaces/efl_gfx_gradient_radial.eo.c"
|
||||||
|
|
||||||
|
#include "interfaces/efl_gfx_filter.eo.c"
|
||||||
|
|
||||||
EAPI const Eo_Event_Description _EFL_GFX_CHANGED =
|
EAPI const Eo_Event_Description _EFL_GFX_CHANGED =
|
||||||
EO_EVENT_DESCRIPTION("Graphics changed", "The visual representation of the object changed");
|
EO_EVENT_DESCRIPTION("Graphics changed", "The visual representation of the object changed");
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
mixin Evas.Filter (Efl.Gfx.Filter)
|
||||||
|
{
|
||||||
|
// Evas internal implementation
|
||||||
|
legacy_prefix: null;
|
||||||
|
methods {
|
||||||
|
@property changed {
|
||||||
|
set {
|
||||||
|
[[Marks this filter as changed.]]
|
||||||
|
}
|
||||||
|
values {
|
||||||
|
val: bool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@property invalid {
|
||||||
|
set {
|
||||||
|
[[Marks this filter as invalid.]]
|
||||||
|
}
|
||||||
|
values {
|
||||||
|
val: bool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
constructor {
|
||||||
|
[[Initialize the Evas.Filter mixin.
|
||||||
|
|
||||||
|
Should be called in a parent's class constructor.
|
||||||
|
]]
|
||||||
|
}
|
||||||
|
destructor {
|
||||||
|
[[Release all data held by this Evas.Filter.
|
||||||
|
|
||||||
|
This may include image buffers allocated by the Evas engine.
|
||||||
|
This should be called at the beginning of a parent's class destructor.
|
||||||
|
]]
|
||||||
|
}
|
||||||
|
input_render {
|
||||||
|
[[Called by Evas.Filter when the parent class must render the input.
|
||||||
|
;
|
||||||
|
]]
|
||||||
|
params {
|
||||||
|
filter: void*; [[Evas_Filter_Context]]
|
||||||
|
drawctx: void*;
|
||||||
|
l: int;
|
||||||
|
r: int;
|
||||||
|
t: int;
|
||||||
|
b: int;
|
||||||
|
do_async: bool;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dirty {
|
||||||
|
[[Called when the filter changes must trigger a redraw of the object.
|
||||||
|
|
||||||
|
Virtual, to be implemented in the parent class.
|
||||||
|
]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
implements {
|
||||||
|
Efl.Gfx.Filter.program.set;
|
||||||
|
Efl.Gfx.Filter.program.get;
|
||||||
|
Efl.Gfx.Filter.state.set;
|
||||||
|
Efl.Gfx.Filter.padding.get;
|
||||||
|
Efl.Gfx.Filter.source_set;
|
||||||
|
Efl.Gfx.Filter.source_get;
|
||||||
|
@virtual .input_render;
|
||||||
|
@virtual .dirty;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,512 @@
|
||||||
|
#include "evas_common_private.h"
|
||||||
|
#include "evas_private.h"
|
||||||
|
#include "../../lib/efl/interfaces/efl_gfx_filter.eo.h"
|
||||||
|
#include "evas_filter.eo.h"
|
||||||
|
#include "evas_filter.h"
|
||||||
|
|
||||||
|
#define MY_CLASS EVAS_FILTER_MIXIN
|
||||||
|
|
||||||
|
#define ENFN obj->layer->evas->engine.func
|
||||||
|
#define ENDT obj->layer->evas->engine.data.output
|
||||||
|
|
||||||
|
typedef struct _Evas_Filter_Data Evas_Filter_Data;
|
||||||
|
struct _Evas_Filter_Data
|
||||||
|
{
|
||||||
|
const Evas_Object_Filter_Data *data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
_filter_cb(Evas_Filter_Context *ctx, void *data, Eina_Bool success)
|
||||||
|
{
|
||||||
|
Eo *eo_obj = data;
|
||||||
|
|
||||||
|
// Destroy context as we won't reuse it.
|
||||||
|
evas_filter_context_destroy(ctx);
|
||||||
|
|
||||||
|
// Redraw text with normal styles in case of failure
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
|
||||||
|
|
||||||
|
ERR("Filter failed at runtime!");
|
||||||
|
eo_do(eo_obj,
|
||||||
|
evas_filter_invalid_set(EINA_TRUE);
|
||||||
|
evas_filter_dirty());
|
||||||
|
evas_object_change(eo_obj, obj);
|
||||||
|
evas_object_clip_dirty(eo_obj, obj);
|
||||||
|
evas_object_coords_recalc(eo_obj, obj);
|
||||||
|
evas_object_inform_call_resize(eo_obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_filter_source_hash_free_cb(void *data)
|
||||||
|
{
|
||||||
|
Evas_Filter_Proxy_Binding *pb = data;
|
||||||
|
Evas_Object_Protected_Data *proxy, *source;
|
||||||
|
Evas_Filter_Data *pd;
|
||||||
|
|
||||||
|
proxy = eo_data_scope_get(pb->eo_proxy, EVAS_OBJECT_CLASS);
|
||||||
|
source = eo_data_scope_get(pb->eo_source, EVAS_OBJECT_CLASS);
|
||||||
|
|
||||||
|
if (source)
|
||||||
|
{
|
||||||
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy,
|
||||||
|
Evas_Object_Proxy_Data, source_write)
|
||||||
|
source_write->proxies = eina_list_remove(source_write->proxies, pb->eo_proxy);
|
||||||
|
EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, source_write)
|
||||||
|
}
|
||||||
|
|
||||||
|
pd = eo_data_scope_get(pb->eo_proxy, MY_CLASS);
|
||||||
|
|
||||||
|
if (pd && proxy)
|
||||||
|
{
|
||||||
|
if (!eina_hash_population(pd->data->sources))
|
||||||
|
{
|
||||||
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, proxy->proxy,
|
||||||
|
Evas_Object_Proxy_Data, proxy_write)
|
||||||
|
proxy_write->is_proxy = EINA_FALSE;
|
||||||
|
EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, proxy_write)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eina_stringshare_del(pb->name);
|
||||||
|
free(pb);
|
||||||
|
}
|
||||||
|
|
||||||
|
Eina_Bool
|
||||||
|
evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj,
|
||||||
|
void *output, void *context, void *surface,
|
||||||
|
int x, int y, Eina_Bool do_async, Eina_Bool alpha)
|
||||||
|
{
|
||||||
|
Evas_Filter_Data *pd = eo_data_scope_get(eo_obj, MY_CLASS);
|
||||||
|
|
||||||
|
if (!pd->data->invalid && (pd->data->chain || pd->data->code))
|
||||||
|
{
|
||||||
|
int X, Y, W, H, l = 0, r = 0, t = 0, b = 0;
|
||||||
|
Evas_Filter_Context *filter;
|
||||||
|
void *drawctx;
|
||||||
|
Eina_Bool ok;
|
||||||
|
void *previous = pd->data->output;
|
||||||
|
Evas_Object_Filter_Data *fcow =
|
||||||
|
eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data));
|
||||||
|
|
||||||
|
/* NOTE: Filter rendering is now done ENTIRELY on CPU.
|
||||||
|
* So we rely on cache/cache2 to allocate a real image buffer,
|
||||||
|
* that we can draw to. The OpenGL texture will be created only
|
||||||
|
* after the rendering has been done, as we simply push the output
|
||||||
|
* image to GL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
W = obj->cur->geometry.w;
|
||||||
|
H = obj->cur->geometry.h;
|
||||||
|
X = obj->cur->geometry.x;
|
||||||
|
Y = obj->cur->geometry.y;
|
||||||
|
|
||||||
|
// Prepare color multiplier
|
||||||
|
ENFN->context_color_set(output, context,
|
||||||
|
obj->cur->cache.clip.r,
|
||||||
|
obj->cur->cache.clip.g,
|
||||||
|
obj->cur->cache.clip.b,
|
||||||
|
obj->cur->cache.clip.a);
|
||||||
|
if (obj->cur->clipper)
|
||||||
|
ENFN->context_multiplier_set(output, context,
|
||||||
|
obj->cur->clipper->cur->cache.clip.r,
|
||||||
|
obj->cur->clipper->cur->cache.clip.g,
|
||||||
|
obj->cur->clipper->cur->cache.clip.b,
|
||||||
|
obj->cur->clipper->cur->cache.clip.a);
|
||||||
|
else
|
||||||
|
ENFN->context_multiplier_unset(output, context);
|
||||||
|
|
||||||
|
if (!fcow->chain)
|
||||||
|
{
|
||||||
|
Evas_Filter_Program *pgm;
|
||||||
|
pgm = evas_filter_program_new(obj->name ? obj->name : obj->type, alpha);
|
||||||
|
evas_filter_program_source_set_all(pgm, fcow->sources);
|
||||||
|
evas_filter_program_state_set(pgm, eo_obj, obj,
|
||||||
|
fcow->state.cur.name, fcow->state.cur.value,
|
||||||
|
fcow->state.next.name, fcow->state.next.value,
|
||||||
|
fcow->state.pos);
|
||||||
|
if (!evas_filter_program_parse(pgm, fcow->code))
|
||||||
|
{
|
||||||
|
ERR("Filter program parsing failed");
|
||||||
|
evas_filter_program_del(pgm);
|
||||||
|
fcow->invalid = EINA_TRUE;
|
||||||
|
|
||||||
|
eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data),
|
||||||
|
fcow, EINA_TRUE);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
fcow->chain = pgm;
|
||||||
|
fcow->invalid = EINA_FALSE;
|
||||||
|
}
|
||||||
|
else if (previous && !fcow->changed)
|
||||||
|
{
|
||||||
|
Eina_Bool redraw;
|
||||||
|
|
||||||
|
redraw = evas_filter_program_state_set(fcow->chain, eo_obj, obj,
|
||||||
|
fcow->state.cur.name, fcow->state.cur.value,
|
||||||
|
fcow->state.next.name, fcow->state.next.value,
|
||||||
|
fcow->state.pos);
|
||||||
|
if (redraw)
|
||||||
|
DBG("Filter redraw by state change!");
|
||||||
|
|
||||||
|
// Scan proxies to find if any changed
|
||||||
|
if (!redraw && fcow->sources)
|
||||||
|
{
|
||||||
|
Evas_Filter_Proxy_Binding *pb;
|
||||||
|
Evas_Object_Protected_Data *source;
|
||||||
|
Eina_Iterator *iter;
|
||||||
|
|
||||||
|
iter = eina_hash_iterator_data_new(fcow->sources);
|
||||||
|
EINA_ITERATOR_FOREACH(iter, pb)
|
||||||
|
{
|
||||||
|
source = eo_data_scope_get(pb->eo_source, EVAS_OBJECT_CLASS);
|
||||||
|
if (source->changed)
|
||||||
|
{
|
||||||
|
redraw = EINA_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eina_iterator_free(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!redraw)
|
||||||
|
{
|
||||||
|
// Render this image only
|
||||||
|
ENFN->image_draw(ENDT, context,
|
||||||
|
surface, previous,
|
||||||
|
0, 0, W, H, // src
|
||||||
|
X + x, Y + y, W, H, // dst
|
||||||
|
EINA_FALSE, // smooth
|
||||||
|
do_async);
|
||||||
|
|
||||||
|
eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data),
|
||||||
|
fcow, EINA_TRUE);
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
evas_filter_program_state_set(fcow->chain, eo_obj, obj,
|
||||||
|
fcow->state.cur.name, fcow->state.cur.value,
|
||||||
|
fcow->state.next.name, fcow->state.next.value,
|
||||||
|
fcow->state.pos);
|
||||||
|
|
||||||
|
filter = evas_filter_context_new(obj->layer->evas, do_async);
|
||||||
|
|
||||||
|
// Run script
|
||||||
|
ok = evas_filter_context_program_use(filter, fcow->chain);
|
||||||
|
if (!filter || !ok)
|
||||||
|
{
|
||||||
|
ERR("Parsing failed?");
|
||||||
|
evas_filter_context_destroy(filter);
|
||||||
|
|
||||||
|
eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(pd->data),
|
||||||
|
fcow, EINA_TRUE);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proxies
|
||||||
|
evas_filter_context_proxy_render_all(filter, eo_obj, EINA_FALSE);
|
||||||
|
|
||||||
|
// Draw Context
|
||||||
|
drawctx = ENFN->context_new(ENDT);
|
||||||
|
ENFN->context_color_set(ENDT, drawctx, 255, 255, 255, 255);
|
||||||
|
|
||||||
|
// Allocate all buffers now
|
||||||
|
evas_filter_context_buffers_allocate_all(filter);
|
||||||
|
evas_filter_target_set(filter, context, surface, X + x, Y + y);
|
||||||
|
|
||||||
|
// Steal output and release previous
|
||||||
|
fcow->output = evas_filter_buffer_backing_steal(filter, EVAS_FILTER_BUFFER_OUTPUT_ID);
|
||||||
|
if (fcow->output != previous)
|
||||||
|
evas_filter_buffer_backing_release(filter, previous);
|
||||||
|
|
||||||
|
evas_filter_program_padding_get(fcow->chain, &l, &r, &t, &b);
|
||||||
|
eo_do(eo_obj, evas_filter_input_render(filter, drawctx, l, r, t, b, do_async));
|
||||||
|
#warning TODO: draw text into input buffer
|
||||||
|
#if 0
|
||||||
|
// Render text to input buffer
|
||||||
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(pd->items), it)
|
||||||
|
if ((pd->font) && (it->text_props.len > 0))
|
||||||
|
{
|
||||||
|
evas_filter_font_draw(filter, drawctx, EVAS_FILTER_BUFFER_INPUT_ID, pd->font,
|
||||||
|
sl + it->x,
|
||||||
|
st + (int) pd->max_ascent,
|
||||||
|
&it->text_props,
|
||||||
|
do_async);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ENFN->context_free(ENDT, drawctx);
|
||||||
|
|
||||||
|
// Add post-run callback and run filter
|
||||||
|
evas_filter_context_post_run_callback_set(filter, _filter_cb, eo_obj);
|
||||||
|
ok = evas_filter_run(filter);
|
||||||
|
fcow->changed = EINA_FALSE;
|
||||||
|
if (!ok) fcow->invalid = EINA_TRUE;
|
||||||
|
|
||||||
|
eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data **) &(pd->data), fcow, EINA_TRUE);
|
||||||
|
|
||||||
|
if (ok)
|
||||||
|
{
|
||||||
|
DBG("Effect rendering done.");
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ERR("Rendering failed.");
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN void
|
||||||
|
_evas_filter_efl_gfx_filter_program_set(Eo *eo_obj, Evas_Filter_Data *pd,
|
||||||
|
const char *code)
|
||||||
|
{
|
||||||
|
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
|
||||||
|
Evas_Filter_Program *pgm = NULL;
|
||||||
|
|
||||||
|
if (!pd) return;
|
||||||
|
if (pd->data->code == code) return;
|
||||||
|
if (pd->data->code && code && !strcmp(code, pd->data->code)) return;
|
||||||
|
|
||||||
|
evas_object_async_block(obj);
|
||||||
|
EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow)
|
||||||
|
{
|
||||||
|
// Parse filter program
|
||||||
|
evas_filter_program_del(fcow->chain);
|
||||||
|
if (code)
|
||||||
|
{
|
||||||
|
pgm = evas_filter_program_new("Evas_Text", EINA_TRUE);
|
||||||
|
evas_filter_program_source_set_all(pgm, fcow->sources);
|
||||||
|
evas_filter_program_state_set(pgm, eo_obj, obj,
|
||||||
|
fcow->state.cur.name, fcow->state.cur.value,
|
||||||
|
fcow->state.next.name, fcow->state.next.value,
|
||||||
|
fcow->state.pos);
|
||||||
|
if (!evas_filter_program_parse(pgm, code))
|
||||||
|
{
|
||||||
|
ERR("Parsing failed!");
|
||||||
|
evas_filter_program_del(pgm);
|
||||||
|
pgm = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fcow->chain = pgm;
|
||||||
|
fcow->changed = EINA_TRUE;
|
||||||
|
fcow->invalid = (pgm == NULL);
|
||||||
|
eina_stringshare_replace(&fcow->code, code);
|
||||||
|
}
|
||||||
|
EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
|
||||||
|
|
||||||
|
// Update object
|
||||||
|
eo_do(eo_obj, evas_filter_dirty());
|
||||||
|
evas_object_change(eo_obj, obj);
|
||||||
|
evas_object_clip_dirty(eo_obj, obj);
|
||||||
|
evas_object_coords_recalc(eo_obj, obj);
|
||||||
|
evas_object_inform_call_resize(eo_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN const char *
|
||||||
|
_evas_filter_efl_gfx_filter_program_get(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd)
|
||||||
|
{
|
||||||
|
return pd->data->code;
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN void
|
||||||
|
_evas_filter_efl_gfx_filter_source_set(Eo *eo_obj, Evas_Filter_Data *pd,
|
||||||
|
const char *name, Efl_Gfx_Base *eo_source)
|
||||||
|
{
|
||||||
|
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
|
||||||
|
Evas_Filter_Proxy_Binding *pb, *pb_old = NULL;
|
||||||
|
Evas_Object_Protected_Data *source = NULL;
|
||||||
|
Evas_Object_Filter_Data *fcow = NULL;
|
||||||
|
|
||||||
|
if (eo_source)
|
||||||
|
source = eo_data_scope_get(eo_source, EVAS_OBJECT_CLASS);
|
||||||
|
|
||||||
|
evas_object_async_block(obj);
|
||||||
|
if (!name)
|
||||||
|
{
|
||||||
|
if (!eo_source || !pd->data->sources) return;
|
||||||
|
if (eina_hash_del_by_data(pd->data->sources, eo_source))
|
||||||
|
goto update;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!source && !pd->data->sources)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (pd->data->sources)
|
||||||
|
{
|
||||||
|
pb_old = eina_hash_find(pd->data->sources, name);
|
||||||
|
if (pb_old && (pb_old->eo_source == eo_source)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fcow = eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&pd->data);
|
||||||
|
|
||||||
|
if (!fcow->sources)
|
||||||
|
fcow->sources = eina_hash_string_small_new(EINA_FREE_CB(_filter_source_hash_free_cb));
|
||||||
|
else if (pb_old)
|
||||||
|
eina_hash_del(fcow->sources, name, pb_old);
|
||||||
|
|
||||||
|
if (!source)
|
||||||
|
{
|
||||||
|
pb_old = eina_hash_find(fcow->sources, name);
|
||||||
|
if (!pb_old)
|
||||||
|
{
|
||||||
|
eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&pd->data, fcow, EINA_TRUE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
eina_hash_del_by_key(fcow->sources, name);
|
||||||
|
goto update;
|
||||||
|
}
|
||||||
|
|
||||||
|
pb = calloc(1, sizeof(*pb));
|
||||||
|
pb->eo_proxy = eo_obj;
|
||||||
|
pb->eo_source = eo_source;
|
||||||
|
pb->name = eina_stringshare_add(name);
|
||||||
|
|
||||||
|
if (!eina_list_data_find(source->proxy->proxies, eo_obj))
|
||||||
|
{
|
||||||
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy, Evas_Object_Proxy_Data, source_write)
|
||||||
|
source_write->proxies = eina_list_append(source_write->proxies, eo_obj);
|
||||||
|
EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, source_write)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!obj->proxy->is_proxy)
|
||||||
|
{
|
||||||
|
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, obj->proxy, Evas_Object_Proxy_Data, proxy_write)
|
||||||
|
proxy_write->is_proxy = EINA_TRUE;
|
||||||
|
EINA_COW_WRITE_END(evas_object_proxy_cow, obj->proxy, proxy_write)
|
||||||
|
}
|
||||||
|
|
||||||
|
eina_hash_add(fcow->sources, pb->name, pb);
|
||||||
|
evas_filter_program_source_set_all(fcow->chain, fcow->sources);
|
||||||
|
|
||||||
|
// Update object
|
||||||
|
update:
|
||||||
|
if (fcow)
|
||||||
|
{
|
||||||
|
fcow->changed = EINA_TRUE;
|
||||||
|
fcow->invalid = EINA_FALSE;
|
||||||
|
eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&pd->data, fcow, EINA_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
eo_do(eo_obj, evas_filter_dirty());
|
||||||
|
evas_object_change(eo_obj, obj);
|
||||||
|
evas_object_clip_dirty(eo_obj, obj);
|
||||||
|
evas_object_coords_recalc(eo_obj, obj);
|
||||||
|
evas_object_inform_call_resize(eo_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN void
|
||||||
|
_evas_filter_efl_gfx_filter_source_get(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd,
|
||||||
|
const char *name, Efl_Gfx_Base **source)
|
||||||
|
{
|
||||||
|
if (!source) return;
|
||||||
|
*source = eina_hash_find(pd->data->sources, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN void
|
||||||
|
_evas_filter_efl_gfx_filter_state_set(Eo *eo_obj, Evas_Filter_Data *pd,
|
||||||
|
const char *cur_state, double cur_val,
|
||||||
|
const char *next_state, double next_val,
|
||||||
|
double pos)
|
||||||
|
{
|
||||||
|
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
|
||||||
|
|
||||||
|
evas_object_async_block(obj);
|
||||||
|
if ((cur_state != pd->data->state.cur.name) || (cur_val != pd->data->state.cur.value) ||
|
||||||
|
(next_state != pd->data->state.next.name) || (next_val != pd->data->state.next.value) ||
|
||||||
|
(pos != pd->data->state.pos))
|
||||||
|
{
|
||||||
|
EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow)
|
||||||
|
{
|
||||||
|
fcow->changed = 1;
|
||||||
|
fcow->state.cur.name = cur_state;
|
||||||
|
fcow->state.cur.value = cur_val;
|
||||||
|
fcow->state.next.name = next_state;
|
||||||
|
fcow->state.next.value = next_val;
|
||||||
|
fcow->state.pos = pos;
|
||||||
|
|
||||||
|
if (pd->data->chain)
|
||||||
|
{
|
||||||
|
evas_filter_program_state_set(pd->data->chain, eo_obj, obj,
|
||||||
|
fcow->state.cur.name, fcow->state.cur.value,
|
||||||
|
fcow->state.next.name, fcow->state.next.value,
|
||||||
|
fcow->state.pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
|
||||||
|
|
||||||
|
// Mark as changed
|
||||||
|
eo_do(eo_obj, evas_filter_dirty());
|
||||||
|
evas_object_change(eo_obj, obj);
|
||||||
|
evas_object_clip_dirty(eo_obj, obj);
|
||||||
|
evas_object_coords_recalc(eo_obj, obj);
|
||||||
|
evas_object_inform_call_resize(eo_obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN void
|
||||||
|
_evas_filter_efl_gfx_filter_padding_get(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd,
|
||||||
|
int *l, int *r, int *t, int *b)
|
||||||
|
{
|
||||||
|
if (!pd->data->chain)
|
||||||
|
{
|
||||||
|
if (l) *l = 0;
|
||||||
|
if (r) *r = 0;
|
||||||
|
if (t) *t = 0;
|
||||||
|
if (b) *b = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
evas_filter_program_padding_get(pd->data->chain, l, r, t, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN void
|
||||||
|
_evas_filter_changed_set(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd, Eina_Bool val)
|
||||||
|
{
|
||||||
|
if ((evas_object_filter_cow_default != pd->data) && (pd->data->changed != val))
|
||||||
|
{
|
||||||
|
EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow)
|
||||||
|
fcow->changed = val;
|
||||||
|
EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN void
|
||||||
|
_evas_filter_invalid_set(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd, Eina_Bool val)
|
||||||
|
{
|
||||||
|
if (pd->data->invalid != val)
|
||||||
|
{
|
||||||
|
EINA_COW_WRITE_BEGIN(evas_object_filter_cow, pd->data, Evas_Object_Filter_Data, fcow)
|
||||||
|
fcow->invalid = val;
|
||||||
|
EINA_COW_WRITE_END(evas_object_filter_cow, pd->data, fcow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN void
|
||||||
|
_evas_filter_constructor(Eo *eo_obj EINA_UNUSED, Evas_Filter_Data *pd)
|
||||||
|
{
|
||||||
|
pd->data = eina_cow_alloc(evas_object_filter_cow);
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN void
|
||||||
|
_evas_filter_destructor(Eo *eo_obj, Evas_Filter_Data *pd)
|
||||||
|
{
|
||||||
|
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
|
||||||
|
|
||||||
|
if (!pd->data) return;
|
||||||
|
if (evas_object_filter_cow_default == pd->data) return;
|
||||||
|
|
||||||
|
if (pd->data->output)
|
||||||
|
ENFN->image_free(ENDT, pd->data->output);
|
||||||
|
eina_hash_free(pd->data->sources);
|
||||||
|
evas_filter_program_del(pd->data->chain);
|
||||||
|
eina_stringshare_del(pd->data->code);
|
||||||
|
eina_cow_free(evas_object_filter_cow, (const Eina_Cow_Data **) &pd->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "evas_filter.eo.c"
|
|
@ -718,7 +718,7 @@ _evas_object_eo_base_destructor(Eo *eo_obj, Evas_Object_Protected_Data *obj)
|
||||||
if (eo_isa(proxy, EVAS_IMAGE_CLASS))
|
if (eo_isa(proxy, EVAS_IMAGE_CLASS))
|
||||||
evas_object_image_source_unset(proxy);
|
evas_object_image_source_unset(proxy);
|
||||||
else if (eo_isa(proxy, EVAS_TEXT_CLASS))
|
else if (eo_isa(proxy, EVAS_TEXT_CLASS))
|
||||||
eo_do(proxy, evas_obj_text_filter_source_set(NULL, eo_obj));
|
eo_do(proxy, efl_gfx_filter_source_set(NULL, eo_obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Eina_Cow has no way to know if we are going to really change something
|
/* Eina_Cow has no way to know if we are going to really change something
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#include "evas_common_private.h" /* Includes evas_bidi_utils stuff. */
|
#include "evas_common_private.h" /* Includes evas_bidi_utils stuff. */
|
||||||
#include "evas_private.h"
|
#include "evas_private.h"
|
||||||
|
|
||||||
|
#include "../efl/interfaces/efl_gfx_filter.eo.h"
|
||||||
|
#include "evas_filter.eo.h"
|
||||||
#include "evas_filter.h"
|
#include "evas_filter.h"
|
||||||
|
|
||||||
#define MY_CLASS EVAS_TEXT_CLASS
|
#define MY_CLASS EVAS_TEXT_CLASS
|
||||||
|
@ -42,8 +45,6 @@ struct _Evas_Text_Data
|
||||||
|
|
||||||
Evas_Font_Size size;
|
Evas_Font_Size size;
|
||||||
Evas_Text_Style_Type style;
|
Evas_Text_Style_Type style;
|
||||||
|
|
||||||
const Evas_Object_Filter_Data* filter; // cow
|
|
||||||
} cur, prev;
|
} cur, prev;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -66,6 +67,7 @@ struct _Evas_Text_Data
|
||||||
|
|
||||||
Evas_BiDi_Direction bidi_dir : 2;
|
Evas_BiDi_Direction bidi_dir : 2;
|
||||||
char changed : 1;
|
char changed : 1;
|
||||||
|
char has_filter : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _Evas_Object_Text_Item
|
struct _Evas_Object_Text_Item
|
||||||
|
@ -368,13 +370,11 @@ evas_object_text_add(Evas *e)
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static Eo *
|
EOLIAN static Eo *
|
||||||
_evas_text_eo_base_constructor(Eo *eo_obj, Evas_Text_Data *o)
|
_evas_text_eo_base_constructor(Eo *eo_obj, Evas_Text_Data *o EINA_UNUSED)
|
||||||
{
|
{
|
||||||
eo_obj = eo_do_super_ret(eo_obj, MY_CLASS, eo_obj, eo_constructor());
|
eo_obj = eo_do_super_ret(eo_obj, MY_CLASS, eo_obj, eo_constructor());
|
||||||
evas_object_text_init(eo_obj);
|
evas_object_text_init(eo_obj);
|
||||||
|
|
||||||
o->cur.filter = eina_cow_alloc(evas_object_filter_cow);
|
|
||||||
|
|
||||||
return eo_obj;
|
return eo_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,22 +397,9 @@ _evas_text_efl_text_properties_font_source_set(Eo *eo_obj, Evas_Text_Data *o, co
|
||||||
EOLIAN static const char*
|
EOLIAN static const char*
|
||||||
_evas_text_efl_text_properties_font_source_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
|
_evas_text_efl_text_properties_font_source_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
|
||||||
{
|
{
|
||||||
|
|
||||||
return o->cur.source;
|
return o->cur.source;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
|
||||||
_evas_text_filter_changed_set(Evas_Text_Data *o, Eina_Bool val)
|
|
||||||
{
|
|
||||||
if ((evas_object_filter_cow_default != o->cur.filter)
|
|
||||||
&& (o->cur.filter->changed != val))
|
|
||||||
{
|
|
||||||
EINA_COW_WRITE_BEGIN(evas_object_filter_cow, o->cur.filter, Evas_Object_Filter_Data, fcow)
|
|
||||||
fcow->changed = val;
|
|
||||||
EINA_COW_WRITE_END(evas_object_filter_cow, o->cur.filter, fcow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EOLIAN static void
|
EOLIAN static void
|
||||||
_evas_text_efl_text_properties_font_set(Eo *eo_obj, Evas_Text_Data *o, const char *font, Evas_Font_Size size)
|
_evas_text_efl_text_properties_font_set(Eo *eo_obj, Evas_Text_Data *o, const char *font, Evas_Font_Size size)
|
||||||
{
|
{
|
||||||
|
@ -479,7 +466,8 @@ _evas_text_efl_text_properties_font_set(Eo *eo_obj, Evas_Text_Data *o, const cha
|
||||||
_evas_object_text_items_clear(o);
|
_evas_object_text_items_clear(o);
|
||||||
_evas_object_text_recalc(eo_obj, o->cur.text);
|
_evas_object_text_recalc(eo_obj, o->cur.text);
|
||||||
o->changed = 1;
|
o->changed = 1;
|
||||||
_evas_text_filter_changed_set(o, EINA_TRUE);
|
if (o->has_filter)
|
||||||
|
eo_do(eo_obj, evas_filter_changed_set(EINA_TRUE));
|
||||||
evas_object_change(eo_obj, obj);
|
evas_object_change(eo_obj, obj);
|
||||||
evas_object_clip_dirty(eo_obj, obj);
|
evas_object_clip_dirty(eo_obj, obj);
|
||||||
evas_object_coords_recalc(eo_obj, obj);
|
evas_object_coords_recalc(eo_obj, obj);
|
||||||
|
@ -665,6 +653,19 @@ _layout_text_item_trim(Evas_Object_Protected_Data *obj, Evas_Text_Data *o, Evas_
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_evas_object_text_pad_get(Evas_Object *eo_obj, Evas_Text_Data *o, int *l, int *r, int *t, int *b)
|
||||||
|
{
|
||||||
|
if (l) *l = 0;
|
||||||
|
if (r) *r = 0;
|
||||||
|
if (t) *t = 0;
|
||||||
|
if (b) *b = 0;
|
||||||
|
if (!o->has_filter)
|
||||||
|
evas_text_style_pad_get(o->cur.style, l, r, t, b);
|
||||||
|
else
|
||||||
|
eo_do(eo_obj, efl_gfx_filter_padding_get(l, r, t, b));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
* Populates o->items with the items of the text according to text
|
* Populates o->items with the items of the text according to text
|
||||||
|
@ -767,10 +768,7 @@ _evas_object_text_layout(Evas_Object *eo_obj, Evas_Text_Data *o, Eina_Unicode *t
|
||||||
}
|
}
|
||||||
o->last_computed.advance_without_ellipsis = advance;
|
o->last_computed.advance_without_ellipsis = advance;
|
||||||
|
|
||||||
if (!o->cur.filter || !o->cur.filter->chain)
|
_evas_object_text_pad_get(eo_obj, o, &l, &r, NULL, NULL);
|
||||||
evas_text_style_pad_get(o->cur.style, &l, &r, NULL, NULL);
|
|
||||||
else
|
|
||||||
evas_filter_program_padding_get(o->cur.filter->chain, &l, &r, NULL, NULL);
|
|
||||||
|
|
||||||
/* Handle ellipsis */
|
/* Handle ellipsis */
|
||||||
if (pos && (o->cur.ellipsis >= 0.0) && (advance + l + r > obj->cur->geometry.w) && (obj->cur->geometry.w > 0))
|
if (pos && (o->cur.ellipsis >= 0.0) && (advance + l + r > obj->cur->geometry.w) && (obj->cur->geometry.w > 0))
|
||||||
|
@ -950,7 +948,8 @@ _evas_text_ellipsis_set(Eo *eo_obj, Evas_Text_Data *o, double ellipsis)
|
||||||
evas_object_async_block(obj);
|
evas_object_async_block(obj);
|
||||||
o->cur.ellipsis = ellipsis;
|
o->cur.ellipsis = ellipsis;
|
||||||
o->changed = 1;
|
o->changed = 1;
|
||||||
_evas_text_filter_changed_set(o, EINA_TRUE);
|
if (o->has_filter)
|
||||||
|
eo_do(eo_obj, evas_filter_changed_set(EINA_TRUE));
|
||||||
evas_object_change(eo_obj, obj);
|
evas_object_change(eo_obj, obj);
|
||||||
evas_object_clip_dirty(eo_obj, obj);
|
evas_object_clip_dirty(eo_obj, obj);
|
||||||
}
|
}
|
||||||
|
@ -1008,7 +1007,8 @@ _evas_text_efl_text_text_set(Eo *eo_obj, Evas_Text_Data *o, const char *_text)
|
||||||
if (o->cur.text != text) free(text);
|
if (o->cur.text != text) free(text);
|
||||||
|
|
||||||
o->changed = 1;
|
o->changed = 1;
|
||||||
_evas_text_filter_changed_set(o, EINA_TRUE);
|
if (o->has_filter)
|
||||||
|
eo_do(eo_obj, evas_filter_changed_set(EINA_TRUE));
|
||||||
evas_object_change(eo_obj, obj);
|
evas_object_change(eo_obj, obj);
|
||||||
evas_object_clip_dirty(eo_obj, obj);
|
evas_object_clip_dirty(eo_obj, obj);
|
||||||
evas_object_coords_recalc(eo_obj, obj);
|
evas_object_coords_recalc(eo_obj, obj);
|
||||||
|
@ -1129,10 +1129,8 @@ _evas_text_char_pos_get(Eo *eo_obj, Evas_Text_Data *o, int pos, Evas_Coord *cx,
|
||||||
|
|
||||||
Eina_Bool int_ret = _evas_object_text_char_coords_get(eo_obj, o, (size_t) pos,
|
Eina_Bool int_ret = _evas_object_text_char_coords_get(eo_obj, o, (size_t) pos,
|
||||||
&x, &y, &w, &h);
|
&x, &y, &w, &h);
|
||||||
if (!o->cur.filter || !o->cur.filter->chain)
|
|
||||||
evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
|
_evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
|
||||||
else
|
|
||||||
evas_filter_program_padding_get(o->cur.filter->chain, &l, &r, &t, &b);
|
|
||||||
y += o->max_ascent - t;
|
y += o->max_ascent - t;
|
||||||
x -= l;
|
x -= l;
|
||||||
if (x < 0)
|
if (x < 0)
|
||||||
|
@ -1186,10 +1184,7 @@ _evas_text_char_coords_get(Eo *eo_obj, Evas_Text_Data *o, Evas_Coord x, Evas_Coo
|
||||||
|
|
||||||
int int_ret = _evas_object_text_char_at_coords(eo_obj, o, x, y - o->max_ascent,
|
int int_ret = _evas_object_text_char_at_coords(eo_obj, o, x, y - o->max_ascent,
|
||||||
&rx, &ry, &rw, &rh);
|
&rx, &ry, &rw, &rh);
|
||||||
if (!o->cur.filter || !o->cur.filter->chain)
|
_evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
|
||||||
evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
|
|
||||||
else
|
|
||||||
evas_filter_program_padding_get(o->cur.filter->chain, &l, &r, &t, &b);
|
|
||||||
ry += o->max_ascent - t;
|
ry += o->max_ascent - t;
|
||||||
rx -= l;
|
rx -= l;
|
||||||
if (rx < 0)
|
if (rx < 0)
|
||||||
|
@ -1226,9 +1221,11 @@ _evas_text_style_set(Eo *eo_obj, Evas_Text_Data *o, Evas_Text_Style_Type style)
|
||||||
if (o->cur.style == style) return;
|
if (o->cur.style == style) return;
|
||||||
evas_object_async_block(obj);
|
evas_object_async_block(obj);
|
||||||
|
|
||||||
evas_text_style_pad_get(o->cur.style, &pl, &pr, &pt, &pb);
|
_evas_object_text_pad_get(eo_obj, o, &pl, &pr, &pt, &pb);
|
||||||
|
//evas_text_style_pad_get(o->cur.style, &pl, &pr, &pt, &pb);
|
||||||
o->cur.style = style;
|
o->cur.style = style;
|
||||||
evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
|
_evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
|
||||||
|
//evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
|
||||||
|
|
||||||
if (o->items) w = obj->cur->geometry.w + (l - pl) + (r - pr);
|
if (o->items) w = obj->cur->geometry.w + (l - pl) + (r - pr);
|
||||||
h = obj->cur->geometry.h + (t - pt) + (b - pb);
|
h = obj->cur->geometry.h + (t - pt) + (b - pb);
|
||||||
|
@ -1345,18 +1342,9 @@ _evas_text_outline_color_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o, int *r,
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static void
|
EOLIAN static void
|
||||||
_evas_text_style_pad_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o, int *l, int *r, int *t, int *b)
|
_evas_text_style_pad_get(Eo *eo_obj, Evas_Text_Data *o, int *l, int *r, int *t, int *b)
|
||||||
{
|
{
|
||||||
int sl = 0, sr = 0, st = 0, sb = 0;
|
_evas_object_text_pad_get(eo_obj, o, l, r, t, b);
|
||||||
/* use temps to be certain we have initialized values */
|
|
||||||
if (!o->cur.filter || !o->cur.filter->chain)
|
|
||||||
evas_text_style_pad_get(o->cur.style, &sl, &sr, &st, &sb);
|
|
||||||
else
|
|
||||||
evas_filter_program_padding_get(o->cur.filter->chain, &sl, &sr, &st, &sb);
|
|
||||||
if (l) *l = sl;
|
|
||||||
if (r) *r = sr;
|
|
||||||
if (t) *t = st;
|
|
||||||
if (b) *b = sb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI int
|
EAPI int
|
||||||
|
@ -1539,6 +1527,8 @@ evas_object_text_init(Evas_Object *eo_obj)
|
||||||
#ifdef BIDI_SUPPORT
|
#ifdef BIDI_SUPPORT
|
||||||
o->bidi_par_props = evas_bidi_paragraph_props_new();
|
o->bidi_par_props = evas_bidi_paragraph_props_new();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
eo_do(eo_obj, evas_filter_constructor());
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static void
|
EOLIAN static void
|
||||||
|
@ -1554,24 +1544,8 @@ evas_object_text_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
|
||||||
{
|
{
|
||||||
Evas_Text_Data *o = eo_data_scope_get(eo_obj, MY_CLASS);
|
Evas_Text_Data *o = eo_data_scope_get(eo_obj, MY_CLASS);
|
||||||
|
|
||||||
/* free filter output */
|
|
||||||
if (evas_object_filter_cow_default != o->cur.filter)
|
|
||||||
{
|
|
||||||
EINA_COW_WRITE_BEGIN(evas_object_filter_cow, o->cur.filter, Evas_Object_Filter_Data, fcow)
|
|
||||||
if (fcow->output)
|
|
||||||
ENFN->image_free(ENDT, fcow->output);
|
|
||||||
eina_hash_free(fcow->sources);
|
|
||||||
evas_filter_program_del(fcow->chain);
|
|
||||||
eina_stringshare_del(fcow->code);
|
|
||||||
fcow->output = NULL;
|
|
||||||
fcow->chain = NULL;
|
|
||||||
fcow->sources = NULL;
|
|
||||||
fcow->code = NULL;
|
|
||||||
EINA_COW_WRITE_END(evas_object_filter_cow, o->cur.filter, fcow);
|
|
||||||
eina_cow_free(evas_object_filter_cow, (const Eina_Cow_Data **) &o->cur.filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free obj */
|
/* free obj */
|
||||||
|
eo_do(eo_obj, evas_filter_destructor());
|
||||||
_evas_object_text_items_clear(o);
|
_evas_object_text_items_clear(o);
|
||||||
if (o->cur.utf8_text) eina_stringshare_del(o->cur.utf8_text);
|
if (o->cur.utf8_text) eina_stringshare_del(o->cur.utf8_text);
|
||||||
if (o->cur.font) eina_stringshare_del(o->cur.font);
|
if (o->cur.font) eina_stringshare_del(o->cur.font);
|
||||||
|
@ -1605,34 +1579,34 @@ evas_font_draw_async_check(Evas_Object_Protected_Data *obj,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
/* ugly binding between evas_fitler_mixin.c and this object */
|
||||||
_filter_cb(Evas_Filter_Context *ctx, void *data, Eina_Bool success)
|
|
||||||
|
EOLIAN void
|
||||||
|
_evas_text_evas_filter_dirty(Eo *eo_obj, Evas_Text_Data *o)
|
||||||
{
|
{
|
||||||
Eo *eo_obj = data;
|
_evas_object_text_items_clear(o);
|
||||||
|
o->changed = 1;
|
||||||
|
_evas_object_text_recalc(eo_obj, o->cur.text);
|
||||||
|
}
|
||||||
|
|
||||||
// Destroy context as we won't reuse it.
|
EOLIAN void
|
||||||
evas_filter_context_destroy(ctx);
|
_evas_text_evas_filter_input_render(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o,
|
||||||
|
void *_filter, void *drawctx,
|
||||||
|
int l, int r, int t, int b, Eina_Bool do_async)
|
||||||
|
{
|
||||||
|
Evas_Filter_Context *filter = _filter;
|
||||||
|
Evas_Object_Text_Item *it;
|
||||||
|
(void) r; (void) b;
|
||||||
|
|
||||||
// Redraw text with normal styles in case of failure
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
|
||||||
if (!success)
|
if ((o->font) && (it->text_props.len > 0))
|
||||||
{
|
{
|
||||||
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
|
evas_filter_font_draw(filter, drawctx, EVAS_FILTER_BUFFER_INPUT_ID, o->font,
|
||||||
Evas_Text_Data *o = (Evas_Text_Data *) obj->private_data;
|
l + it->x,
|
||||||
|
t + (int) o->max_ascent,
|
||||||
ERR("Filter failed at runtime!");
|
&it->text_props,
|
||||||
EINA_COW_WRITE_BEGIN(evas_object_filter_cow, o->cur.filter, Evas_Object_Filter_Data, fcow)
|
do_async);
|
||||||
fcow->invalid = EINA_TRUE;
|
}
|
||||||
EINA_COW_WRITE_END(evas_object_filter_cow, o->cur.filter, fcow);
|
|
||||||
|
|
||||||
// Update object
|
|
||||||
_evas_object_text_items_clear(o);
|
|
||||||
o->changed = 1;
|
|
||||||
_evas_object_text_recalc(eo_obj, o->cur.text);
|
|
||||||
evas_object_change(eo_obj, obj);
|
|
||||||
evas_object_clip_dirty(eo_obj, obj);
|
|
||||||
evas_object_coords_recalc(eo_obj, obj);
|
|
||||||
evas_object_inform_call_resize(eo_obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1657,10 +1631,7 @@ evas_object_text_render(Evas_Object *eo_obj,
|
||||||
int shad_dst = 0, shad_sz = 0, dx = 0, dy = 0, haveshad = 0;
|
int shad_dst = 0, shad_sz = 0, dx = 0, dy = 0, haveshad = 0;
|
||||||
|
|
||||||
/* render object to surface with context, and offxet by x,y */
|
/* render object to surface with context, and offxet by x,y */
|
||||||
if (!o->cur.filter->chain)
|
_evas_object_text_pad_get(eo_obj, o, &sl, NULL, &st, NULL);
|
||||||
evas_text_style_pad_get(o->cur.style, &sl, NULL, &st, NULL);
|
|
||||||
else
|
|
||||||
evas_filter_program_padding_get(o->cur.filter->chain, &sl, NULL, &st, NULL);
|
|
||||||
ENFN->context_multiplier_unset(output, context);
|
ENFN->context_multiplier_unset(output, context);
|
||||||
ENFN->context_render_op_set(output, context, obj->cur->render_op);
|
ENFN->context_render_op_set(output, context, obj->cur->render_op);
|
||||||
/* FIXME: This clipping is just until we fix inset handling correctly. */
|
/* FIXME: This clipping is just until we fix inset handling correctly. */
|
||||||
|
@ -1737,190 +1708,12 @@ evas_object_text_render(Evas_Object *eo_obj,
|
||||||
&it->text_props, \
|
&it->text_props, \
|
||||||
do_async);
|
do_async);
|
||||||
|
|
||||||
/* FIXME/WARNING
|
if (o->has_filter)
|
||||||
* The code below is EXPERIMENTAL, and not to be considered usable or even
|
|
||||||
* remotely similar to its final form. You've been warned :)
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!o->cur.filter->invalid && (o->cur.filter->chain || o->cur.filter->code))
|
|
||||||
{
|
{
|
||||||
int X, Y, W, H;
|
if (evas_filter_object_render(eo_obj, obj, output, context, surface, x, y, do_async, EINA_TRUE))
|
||||||
Evas_Filter_Context *filter;
|
return;
|
||||||
const int inbuf = 1;
|
|
||||||
const int outbuf = 2;
|
|
||||||
void *filter_ctx;
|
|
||||||
Eina_Bool ok;
|
|
||||||
int ox = 0, oy = 0;
|
|
||||||
void *previous = o->cur.filter->output;
|
|
||||||
Evas_Object_Filter_Data *fcow =
|
|
||||||
eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&(o->cur.filter));
|
|
||||||
|
|
||||||
/* NOTE: Font effect rendering is now done ENTIRELY on CPU.
|
|
||||||
* So we rely on cache/cache2 to allocate a real image buffer,
|
|
||||||
* that we can draw to. The OpenGL texture will be created only
|
|
||||||
* after the rendering has been done, as we simply push the output
|
|
||||||
* image to GL.
|
|
||||||
*/
|
|
||||||
|
|
||||||
W = obj->cur->geometry.w;
|
|
||||||
H = obj->cur->geometry.h;
|
|
||||||
X = obj->cur->geometry.x;
|
|
||||||
Y = obj->cur->geometry.y;
|
|
||||||
|
|
||||||
// Prepare color multiplier
|
|
||||||
COLOR_ONLY_SET(obj, cur->cache, clip);
|
|
||||||
if (obj->cur->clipper)
|
|
||||||
ENFN->context_multiplier_set(output, context,
|
|
||||||
obj->cur->clipper->cur->cache.clip.r,
|
|
||||||
obj->cur->clipper->cur->cache.clip.g,
|
|
||||||
obj->cur->clipper->cur->cache.clip.b,
|
|
||||||
obj->cur->clipper->cur->cache.clip.a);
|
|
||||||
else
|
|
||||||
ENFN->context_multiplier_unset(output, context);
|
|
||||||
|
|
||||||
if (!fcow->chain)
|
|
||||||
{
|
|
||||||
Evas_Filter_Program *pgm;
|
|
||||||
pgm = evas_filter_program_new("Evas_Text", EINA_TRUE);
|
|
||||||
evas_filter_program_source_set_all(pgm, fcow->sources);
|
|
||||||
evas_filter_program_state_set(pgm, eo_obj, obj,
|
|
||||||
fcow->state.cur.name, fcow->state.cur.value,
|
|
||||||
fcow->state.next.name, fcow->state.next.value,
|
|
||||||
fcow->state.pos);
|
|
||||||
if (!evas_filter_program_parse(pgm, fcow->code))
|
|
||||||
{
|
|
||||||
ERR("Filter program parsing failed");
|
|
||||||
evas_filter_program_del(pgm);
|
|
||||||
fcow->invalid = EINA_TRUE;
|
|
||||||
|
|
||||||
eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(o->cur.filter),
|
|
||||||
fcow, EINA_TRUE);
|
|
||||||
goto normal_render;
|
|
||||||
}
|
|
||||||
fcow->chain = pgm;
|
|
||||||
fcow->invalid = EINA_FALSE;
|
|
||||||
}
|
|
||||||
else if (previous && !fcow->changed)
|
|
||||||
{
|
|
||||||
Eina_Bool redraw;
|
|
||||||
|
|
||||||
redraw = evas_filter_program_state_set(fcow->chain, eo_obj, obj,
|
|
||||||
fcow->state.cur.name, fcow->state.cur.value,
|
|
||||||
fcow->state.next.name, fcow->state.next.value,
|
|
||||||
fcow->state.pos);
|
|
||||||
if (redraw)
|
|
||||||
DBG("Filter redraw by state change!");
|
|
||||||
|
|
||||||
// Scan proxies to find if any changed
|
|
||||||
if (!redraw && fcow->sources)
|
|
||||||
{
|
|
||||||
Evas_Filter_Proxy_Binding *pb;
|
|
||||||
Evas_Object_Protected_Data *source;
|
|
||||||
Eina_Iterator *iter;
|
|
||||||
|
|
||||||
iter = eina_hash_iterator_data_new(fcow->sources);
|
|
||||||
EINA_ITERATOR_FOREACH(iter, pb)
|
|
||||||
{
|
|
||||||
source = eo_data_scope_get(pb->eo_source, EVAS_OBJECT_CLASS);
|
|
||||||
if (source->changed)
|
|
||||||
{
|
|
||||||
redraw = EINA_TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eina_iterator_free(iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!redraw)
|
|
||||||
{
|
|
||||||
// Render this image only
|
|
||||||
ENFN->image_draw(ENDT, context,
|
|
||||||
surface, previous,
|
|
||||||
0, 0, W, H, // src
|
|
||||||
X + x, Y + y, W, H, // dst
|
|
||||||
EINA_FALSE, // smooth
|
|
||||||
do_async);
|
|
||||||
|
|
||||||
eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(o->cur.filter),
|
|
||||||
fcow, EINA_TRUE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
evas_filter_program_state_set(fcow->chain, eo_obj, obj,
|
|
||||||
fcow->state.cur.name, fcow->state.cur.value,
|
|
||||||
fcow->state.next.name, fcow->state.next.value,
|
|
||||||
fcow->state.pos);
|
|
||||||
|
|
||||||
filter = evas_filter_context_new(obj->layer->evas, do_async);
|
|
||||||
|
|
||||||
// Run script
|
|
||||||
ok = evas_filter_context_program_use(filter, fcow->chain);
|
|
||||||
if (!filter || !ok)
|
|
||||||
{
|
|
||||||
ERR("Parsing failed?");
|
|
||||||
evas_filter_context_destroy(filter);
|
|
||||||
|
|
||||||
eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(o->cur.filter),
|
|
||||||
fcow, EINA_TRUE);
|
|
||||||
goto normal_render;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proxies
|
|
||||||
evas_filter_context_proxy_render_all(filter, eo_obj, EINA_FALSE);
|
|
||||||
|
|
||||||
// Draw Context
|
|
||||||
filter_ctx = ENFN->context_new(ENDT);
|
|
||||||
ENFN->context_color_set(ENDT, filter_ctx, 255, 255, 255, 255);
|
|
||||||
|
|
||||||
// Allocate all buffers now
|
|
||||||
evas_filter_context_buffers_allocate_all(filter);
|
|
||||||
evas_filter_target_set(filter, context, surface, X + x, Y + y);
|
|
||||||
|
|
||||||
// Steal output and release previous
|
|
||||||
fcow->output = evas_filter_buffer_backing_steal(filter, outbuf);
|
|
||||||
if (fcow->output != previous)
|
|
||||||
evas_filter_buffer_backing_release(filter, previous);
|
|
||||||
|
|
||||||
// Render text to input buffer
|
|
||||||
EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
|
|
||||||
if ((o->font) && (it->text_props.len > 0))
|
|
||||||
{
|
|
||||||
evas_filter_font_draw(filter, filter_ctx, inbuf, o->font,
|
|
||||||
sl + ox + it->x,
|
|
||||||
st + oy + (int) o->max_ascent,
|
|
||||||
&it->text_props,
|
|
||||||
do_async);
|
|
||||||
}
|
|
||||||
|
|
||||||
ENFN->context_free(ENDT, filter_ctx);
|
|
||||||
|
|
||||||
// Add post-run callback and run filter
|
|
||||||
evas_filter_context_post_run_callback_set(filter, _filter_cb, eo_obj);
|
|
||||||
ok = evas_filter_run(filter);
|
|
||||||
fcow->changed = EINA_FALSE;
|
|
||||||
|
|
||||||
if (!ok) fcow->invalid = EINA_TRUE;
|
|
||||||
|
|
||||||
eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&(o->cur.filter),
|
|
||||||
fcow, EINA_TRUE);
|
|
||||||
|
|
||||||
if (ok)
|
|
||||||
{
|
|
||||||
DBG("Effect rendering done.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ERR("Rendering failed");
|
|
||||||
goto normal_render;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End of the EXPERIMENTAL code */
|
|
||||||
|
|
||||||
normal_render:
|
|
||||||
|
|
||||||
/* shadows */
|
/* shadows */
|
||||||
switch (o->cur.style & EVAS_TEXT_STYLE_MASK_BASIC)
|
switch (o->cur.style & EVAS_TEXT_STYLE_MASK_BASIC)
|
||||||
{
|
{
|
||||||
|
@ -2279,7 +2072,8 @@ _evas_object_text_rehint(Evas_Object *eo_obj)
|
||||||
/* DO II */
|
/* DO II */
|
||||||
_evas_object_text_recalc(eo_obj, o->cur.text);
|
_evas_object_text_recalc(eo_obj, o->cur.text);
|
||||||
o->changed = 1;
|
o->changed = 1;
|
||||||
_evas_text_filter_changed_set(o, EINA_TRUE);
|
if (o->has_filter)
|
||||||
|
eo_do(eo_obj, evas_filter_changed_set(EINA_TRUE));
|
||||||
evas_object_change(eo_obj, obj);
|
evas_object_change(eo_obj, obj);
|
||||||
evas_object_clip_dirty(eo_obj, obj);
|
evas_object_clip_dirty(eo_obj, obj);
|
||||||
evas_object_coords_recalc(eo_obj, obj);
|
evas_object_coords_recalc(eo_obj, obj);
|
||||||
|
@ -2354,10 +2148,7 @@ _evas_object_text_recalc(Evas_Object *eo_obj, Eina_Unicode *text)
|
||||||
|
|
||||||
w = _evas_object_text_horiz_advance_without_ellipsis_get(o);
|
w = _evas_object_text_horiz_advance_without_ellipsis_get(o);
|
||||||
h = _evas_object_text_vert_advance_get(eo_obj, o);
|
h = _evas_object_text_vert_advance_get(eo_obj, o);
|
||||||
if (!o->cur.filter->chain)
|
_evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
|
||||||
evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
|
|
||||||
else
|
|
||||||
evas_filter_program_padding_get(o->cur.filter->chain, &l, &r, &t, &b);
|
|
||||||
|
|
||||||
if (o->cur.ellipsis >= 0.0)
|
if (o->cur.ellipsis >= 0.0)
|
||||||
{
|
{
|
||||||
|
@ -2377,12 +2168,7 @@ _evas_object_text_recalc(Evas_Object *eo_obj, Eina_Unicode *text)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int t = 0, b = 0, l = 0, r = 0;
|
int t = 0, b = 0, l = 0, r = 0;
|
||||||
|
_evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
|
||||||
if (!o->cur.filter->chain)
|
|
||||||
evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
|
|
||||||
else
|
|
||||||
evas_filter_program_padding_get(o->cur.filter->chain, &l, &r, &t, &b);
|
|
||||||
|
|
||||||
eo_do_super(eo_obj, MY_CLASS,
|
eo_do_super(eo_obj, MY_CLASS,
|
||||||
efl_gfx_size_set(0, o->max_ascent + o->max_descent + t + b));
|
efl_gfx_size_set(0, o->max_ascent + o->max_descent + t + b));
|
||||||
//// obj->cur->cache.geometry.validity = 0;
|
//// obj->cur->cache.geometry.validity = 0;
|
||||||
|
@ -2391,222 +2177,6 @@ _evas_object_text_recalc(Evas_Object *eo_obj, Eina_Unicode *text)
|
||||||
o->last_computed.h = obj->cur->geometry.h;
|
o->last_computed.h = obj->cur->geometry.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
EOLIAN static void
|
|
||||||
_evas_text_filter_program_set(Eo *eo_obj, Evas_Text_Data *o, const char *arg)
|
|
||||||
{
|
|
||||||
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
|
|
||||||
Evas_Filter_Program *pgm = NULL;
|
|
||||||
|
|
||||||
if (!o) return;
|
|
||||||
if (o->cur.filter->code == arg) return;
|
|
||||||
if (o->cur.filter->code && arg && !strcmp(arg, o->cur.filter->code)) return;
|
|
||||||
|
|
||||||
evas_object_async_block(obj);
|
|
||||||
EINA_COW_WRITE_BEGIN(evas_object_filter_cow, o->cur.filter, Evas_Object_Filter_Data, fcow)
|
|
||||||
{
|
|
||||||
// Parse filter program
|
|
||||||
evas_filter_program_del(fcow->chain);
|
|
||||||
if (arg)
|
|
||||||
{
|
|
||||||
pgm = evas_filter_program_new("Evas_Text", EINA_TRUE);
|
|
||||||
evas_filter_program_source_set_all(pgm, fcow->sources);
|
|
||||||
evas_filter_program_state_set(pgm, eo_obj, obj,
|
|
||||||
fcow->state.cur.name, fcow->state.cur.value,
|
|
||||||
fcow->state.next.name, fcow->state.next.value,
|
|
||||||
fcow->state.pos);
|
|
||||||
if (!evas_filter_program_parse(pgm, arg))
|
|
||||||
{
|
|
||||||
ERR("Parsing failed!");
|
|
||||||
evas_filter_program_del(pgm);
|
|
||||||
pgm = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fcow->chain = pgm;
|
|
||||||
fcow->changed = EINA_TRUE;
|
|
||||||
fcow->invalid = (pgm == NULL);
|
|
||||||
eina_stringshare_replace(&fcow->code, arg);
|
|
||||||
}
|
|
||||||
EINA_COW_WRITE_END(evas_object_filter_cow, o->cur.filter, fcow);
|
|
||||||
|
|
||||||
// Update object
|
|
||||||
_evas_object_text_items_clear(o);
|
|
||||||
o->changed = 1;
|
|
||||||
_evas_object_text_recalc(eo_obj, o->cur.text);
|
|
||||||
evas_object_change(eo_obj, obj);
|
|
||||||
evas_object_clip_dirty(eo_obj, obj);
|
|
||||||
evas_object_coords_recalc(eo_obj, obj);
|
|
||||||
evas_object_inform_call_resize(eo_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
_filter_source_hash_free_cb(void *data)
|
|
||||||
{
|
|
||||||
Evas_Filter_Proxy_Binding *pb = data;
|
|
||||||
Evas_Object_Protected_Data *proxy, *source;
|
|
||||||
Evas_Text_Data *o;
|
|
||||||
|
|
||||||
proxy = eo_data_scope_get(pb->eo_proxy, EVAS_OBJECT_CLASS);
|
|
||||||
source = eo_data_scope_get(pb->eo_source, EVAS_OBJECT_CLASS);
|
|
||||||
|
|
||||||
if (source)
|
|
||||||
{
|
|
||||||
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy,
|
|
||||||
Evas_Object_Proxy_Data, source_write)
|
|
||||||
source_write->proxies = eina_list_remove(source_write->proxies, pb->eo_proxy);
|
|
||||||
EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, source_write)
|
|
||||||
}
|
|
||||||
|
|
||||||
o = eo_data_scope_get(pb->eo_proxy, MY_CLASS);
|
|
||||||
|
|
||||||
if (o && proxy)
|
|
||||||
{
|
|
||||||
if (!eina_hash_population(o->cur.filter->sources))
|
|
||||||
{
|
|
||||||
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, proxy->proxy,
|
|
||||||
Evas_Object_Proxy_Data, proxy_write)
|
|
||||||
proxy_write->is_proxy = EINA_FALSE;
|
|
||||||
EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, proxy_write)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
eina_stringshare_del(pb->name);
|
|
||||||
free(pb);
|
|
||||||
}
|
|
||||||
|
|
||||||
EOLIAN static void
|
|
||||||
_evas_text_filter_source_set(Eo *eo_obj, Evas_Text_Data *o, const char *name, Evas_Object *eo_source)
|
|
||||||
{
|
|
||||||
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
|
|
||||||
Evas_Filter_Proxy_Binding *pb, *pb_old = NULL;
|
|
||||||
Evas_Object_Protected_Data *source = NULL;
|
|
||||||
Evas_Object_Filter_Data *fcow = NULL;
|
|
||||||
|
|
||||||
if (eo_source) source = eo_data_scope_get(eo_source, EVAS_OBJECT_CLASS);
|
|
||||||
|
|
||||||
evas_object_async_block(obj);
|
|
||||||
if (!name)
|
|
||||||
{
|
|
||||||
if (!eo_source || !o->cur.filter->sources) return;
|
|
||||||
if (eina_hash_del_by_data(o->cur.filter->sources, eo_source))
|
|
||||||
goto update;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!source && !o->cur.filter->sources)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (o->cur.filter->sources)
|
|
||||||
{
|
|
||||||
pb_old = eina_hash_find(o->cur.filter->sources, name);
|
|
||||||
if (pb_old && (pb_old->eo_source == eo_source)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fcow = eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&o->cur.filter);
|
|
||||||
|
|
||||||
if (!fcow->sources)
|
|
||||||
{
|
|
||||||
fcow->sources = eina_hash_string_small_new
|
|
||||||
(EINA_FREE_CB(_filter_source_hash_free_cb));
|
|
||||||
}
|
|
||||||
else if (pb_old)
|
|
||||||
eina_hash_del(fcow->sources, name, pb_old);
|
|
||||||
|
|
||||||
if (!source)
|
|
||||||
{
|
|
||||||
pb_old = eina_hash_find(fcow->sources, name);
|
|
||||||
if (!pb_old)
|
|
||||||
{
|
|
||||||
eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&o->cur.filter,
|
|
||||||
fcow, EINA_TRUE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
eina_hash_del_by_key(fcow->sources, name);
|
|
||||||
goto update;
|
|
||||||
}
|
|
||||||
|
|
||||||
pb = calloc(1, sizeof(*pb));
|
|
||||||
pb->eo_proxy = eo_obj;
|
|
||||||
pb->eo_source = eo_source;
|
|
||||||
pb->name = eina_stringshare_add(name);
|
|
||||||
|
|
||||||
if (!eina_list_data_find(source->proxy->proxies, eo_obj))
|
|
||||||
{
|
|
||||||
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy, Evas_Object_Proxy_Data, source_write)
|
|
||||||
source_write->proxies = eina_list_append(source_write->proxies, eo_obj);
|
|
||||||
EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, source_write)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!obj->proxy->is_proxy)
|
|
||||||
{
|
|
||||||
EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, obj->proxy, Evas_Object_Proxy_Data, proxy_write)
|
|
||||||
proxy_write->is_proxy = EINA_TRUE;
|
|
||||||
EINA_COW_WRITE_END(evas_object_proxy_cow, obj->proxy, proxy_write)
|
|
||||||
}
|
|
||||||
|
|
||||||
eina_hash_add(fcow->sources, pb->name, pb);
|
|
||||||
evas_filter_program_source_set_all(fcow->chain, fcow->sources);
|
|
||||||
|
|
||||||
// Update object
|
|
||||||
update:
|
|
||||||
if (fcow)
|
|
||||||
{
|
|
||||||
fcow->changed = EINA_TRUE;
|
|
||||||
fcow->invalid = EINA_FALSE;
|
|
||||||
eina_cow_done(evas_object_filter_cow, (const Eina_Cow_Data**)&o->cur.filter,
|
|
||||||
fcow, EINA_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
_evas_object_text_items_clear(o);
|
|
||||||
o->changed = 1;
|
|
||||||
_evas_object_text_recalc(eo_obj, o->cur.text);
|
|
||||||
evas_object_change(eo_obj, obj);
|
|
||||||
evas_object_clip_dirty(eo_obj, obj);
|
|
||||||
evas_object_coords_recalc(eo_obj, obj);
|
|
||||||
evas_object_inform_call_resize(eo_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
EOLIAN static void
|
|
||||||
_evas_text_filter_state_set(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o,
|
|
||||||
const char *cur_state, double cur_val,
|
|
||||||
const char *next_state, double next_val, double pos)
|
|
||||||
{
|
|
||||||
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
|
|
||||||
|
|
||||||
evas_object_async_block(obj);
|
|
||||||
if ((cur_state != o->cur.filter->state.cur.name) || (cur_val != o->cur.filter->state.cur.value) ||
|
|
||||||
(next_state != o->cur.filter->state.next.name) || (next_val != o->cur.filter->state.next.value) ||
|
|
||||||
(pos != o->cur.filter->state.pos))
|
|
||||||
{
|
|
||||||
EINA_COW_WRITE_BEGIN(evas_object_filter_cow, o->cur.filter, Evas_Object_Filter_Data, fcow)
|
|
||||||
{
|
|
||||||
fcow->changed = 1;
|
|
||||||
fcow->state.cur.name = cur_state;
|
|
||||||
fcow->state.cur.value = cur_val;
|
|
||||||
fcow->state.next.name = next_state;
|
|
||||||
fcow->state.next.value = next_val;
|
|
||||||
fcow->state.pos = pos;
|
|
||||||
|
|
||||||
if (o->cur.filter->chain)
|
|
||||||
{
|
|
||||||
evas_filter_program_state_set(o->cur.filter->chain, eo_obj, obj,
|
|
||||||
fcow->state.cur.name, fcow->state.cur.value,
|
|
||||||
fcow->state.next.name, fcow->state.next.value,
|
|
||||||
fcow->state.pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EINA_COW_WRITE_END(evas_object_filter_cow, o->cur.filter, fcow);
|
|
||||||
|
|
||||||
// Mark as changed
|
|
||||||
_evas_object_text_items_clear(o);
|
|
||||||
o->changed = 1;
|
|
||||||
_evas_object_text_recalc(eo_obj, o->cur.text);
|
|
||||||
evas_object_change(eo_obj, obj);
|
|
||||||
evas_object_clip_dirty(eo_obj, obj);
|
|
||||||
evas_object_coords_recalc(eo_obj, obj);
|
|
||||||
evas_object_inform_call_resize(eo_obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EAPI void
|
EAPI void
|
||||||
evas_object_text_font_source_set(Eo *obj, const char *font_source)
|
evas_object_text_font_source_set(Eo *obj, const char *font_source)
|
||||||
{
|
{
|
||||||
|
@ -2646,4 +2216,43 @@ evas_object_text_text_get(const Eo *obj)
|
||||||
return eo_do_ret((Eo *) obj, ret, efl_text_get());
|
return eo_do_ret((Eo *) obj, ret, efl_text_get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* urgh. why are those needed? */
|
||||||
|
|
||||||
|
EOLIAN void
|
||||||
|
_evas_text_efl_gfx_filter_program_set(Eo *obj, Evas_Text_Data *pd EINA_UNUSED, const char *code)
|
||||||
|
{
|
||||||
|
pd->has_filter = (code != NULL);
|
||||||
|
eo_do_super(obj, MY_CLASS, efl_gfx_filter_program_set(code));
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN const char *
|
||||||
|
_evas_text_efl_gfx_filter_program_get(Eo *obj, Evas_Text_Data *pd EINA_UNUSED)
|
||||||
|
{
|
||||||
|
const char *code;
|
||||||
|
return eo_do_super_ret(obj, MY_CLASS, code, efl_gfx_filter_program_get());
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN void
|
||||||
|
_evas_text_efl_gfx_filter_source_set(Eo *obj, Evas_Text_Data *pd EINA_UNUSED, const char *name, Efl_Gfx_Base *source)
|
||||||
|
{
|
||||||
|
eo_do_super(obj, MY_CLASS, efl_gfx_filter_source_set(name, source));
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN void
|
||||||
|
_evas_text_efl_gfx_filter_source_get(Eo *obj, Evas_Text_Data *pd EINA_UNUSED, const char *name, Efl_Gfx_Base **source)
|
||||||
|
{
|
||||||
|
eo_do_super(obj, MY_CLASS, efl_gfx_filter_source_get(name, source));
|
||||||
|
}
|
||||||
|
|
||||||
|
EOLIAN void
|
||||||
|
_evas_text_efl_gfx_filter_state_set(Eo *obj, Evas_Text_Data *pd EINA_UNUSED,
|
||||||
|
const char *cur_state, double cur_val,
|
||||||
|
const char *next_state, double next_val, double pos)
|
||||||
|
{
|
||||||
|
eo_do_super(obj, MY_CLASS, efl_gfx_filter_state_set(cur_state, cur_val, next_state, next_val, pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include "canvas/evas_text.eo.c"
|
#include "canvas/evas_text.eo.c"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
class Evas.Text (Evas.Object, Efl.Text, Efl.Text_Properties)
|
class Evas.Text (Evas.Object, Efl.Text, Efl.Text_Properties, Evas.Filter)
|
||||||
{
|
{
|
||||||
legacy_prefix: evas_object_text;
|
legacy_prefix: evas_object_text;
|
||||||
eo_prefix: evas_obj_text;
|
eo_prefix: evas_obj_text;
|
||||||
|
@ -219,64 +219,6 @@ class Evas.Text (Evas.Object, Efl.Text, Efl.Text_Properties)
|
||||||
a: int; /*@ The alpha component of the given color. */
|
a: int; /*@ The alpha component of the given color. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@property filter_program {
|
|
||||||
set {
|
|
||||||
/*@ Set an Evas filter program on this Text Object.
|
|
||||||
|
|
||||||
If the program fails to compile (syntax error, invalid
|
|
||||||
buffer name, etc...), the standard text effects will be
|
|
||||||
applied instead (SHADOW, etc...). switch back to the
|
|
||||||
standard text effects.
|
|
||||||
|
|
||||||
@since 1.9
|
|
||||||
@note EXPERIMENTAL FEATURE. This is an unstable API,
|
|
||||||
please use only for testing purposes.
|
|
||||||
@see @ref evasfiltersref "Evas filters reference"
|
|
||||||
*/
|
|
||||||
legacy: null;
|
|
||||||
}
|
|
||||||
values {
|
|
||||||
program: const(char)*; /*@ The program code, as defined
|
|
||||||
by the @ref evasfiltersref "Evas filters script language".
|
|
||||||
Pass NULL to remove the former program and switch back
|
|
||||||
to the standard text effect */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@property filter_source {
|
|
||||||
set {
|
|
||||||
/*@ Bind an object to use as a mask or texture with Evas Filters.
|
|
||||||
|
|
||||||
This will create automatically a new RGBA buffer containing
|
|
||||||
the source object's pixels (as it is rendered).
|
|
||||||
|
|
||||||
@since 1.9
|
|
||||||
@note EXPERIMENTAL FEATURE. This is an unstable API,
|
|
||||||
please use only for testing purposes.
|
|
||||||
@see @ref evasfiltersref "Evas filters reference" */
|
|
||||||
legacy: null;
|
|
||||||
}
|
|
||||||
values {
|
|
||||||
name: const(char)*; /*@ Object name as used in the program code */
|
|
||||||
eobj: Evas.Object *; /*@ Eo object to use through proxy rendering */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@property filter_state {
|
|
||||||
set {
|
|
||||||
/*@ Set the current state of the filter (for use from Edje)
|
|
||||||
|
|
||||||
@internal
|
|
||||||
@since 1.15
|
|
||||||
*/
|
|
||||||
legacy: null;
|
|
||||||
}
|
|
||||||
values {
|
|
||||||
cur_state: const(char)*;
|
|
||||||
cur_val: double(0.0);
|
|
||||||
next_state: const(char)*;
|
|
||||||
next_val: double(0.0);
|
|
||||||
animpos: double(0.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@property max_descent {
|
@property max_descent {
|
||||||
get {
|
get {
|
||||||
return: Evas.Coord;
|
return: Evas.Coord;
|
||||||
|
@ -384,5 +326,12 @@ class Evas.Text (Evas.Object, Efl.Text, Efl.Text_Properties)
|
||||||
Efl.Text_Properties.font.set;
|
Efl.Text_Properties.font.set;
|
||||||
Efl.Text_Properties.font_source.get;
|
Efl.Text_Properties.font_source.get;
|
||||||
Efl.Text_Properties.font_source.set;
|
Efl.Text_Properties.font_source.set;
|
||||||
|
Efl.Gfx.Filter.program.set;
|
||||||
|
Efl.Gfx.Filter.program.get;
|
||||||
|
Efl.Gfx.Filter.source_set;
|
||||||
|
Efl.Gfx.Filter.source_get;
|
||||||
|
Efl.Gfx.Filter.state.set;
|
||||||
|
Evas.Filter.dirty;
|
||||||
|
Evas.Filter.input_render;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1798,6 +1798,9 @@ void evas_model_set_from_torus_primitive(Evas_Canvas3D_Mesh *mesh, int frame, Ev
|
||||||
void evas_model_set_from_surface_primitive(Evas_Canvas3D_Mesh *mesh, int frame, Evas_Canvas3D_Surface_Func func, int precision, Evas_Vec2 tex_scale);
|
void evas_model_set_from_surface_primitive(Evas_Canvas3D_Mesh *mesh, int frame, Evas_Canvas3D_Surface_Func func, int precision, Evas_Vec2 tex_scale);
|
||||||
void evas_model_set_from_terrain_primitive(Evas_Canvas3D_Mesh *mesh, int frame, int precision, Evas_Vec2 tex_scale);
|
void evas_model_set_from_terrain_primitive(Evas_Canvas3D_Mesh *mesh, int frame, int precision, Evas_Vec2 tex_scale);
|
||||||
|
|
||||||
|
/* Filter functions */
|
||||||
|
Eina_Bool evas_filter_object_render(Eo *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async, Eina_Bool alpha);
|
||||||
|
|
||||||
extern int _evas_alloc_error;
|
extern int _evas_alloc_error;
|
||||||
extern int _evas_event_counter;
|
extern int _evas_event_counter;
|
||||||
|
|
||||||
|
|
|
@ -306,7 +306,7 @@ START_TEST(evas_filter_text_padding_test)
|
||||||
// Don't test proxy cases here.
|
// Don't test proxy cases here.
|
||||||
if (tc->source) continue;
|
if (tc->source) continue;
|
||||||
|
|
||||||
eo_do(to, evas_obj_text_filter_program_set(tc->code));
|
eo_do(to, efl_gfx_filter_program_set(tc->code));
|
||||||
evas_object_text_style_pad_get(to, &l, &r, &t, &b);
|
evas_object_text_style_pad_get(to, &l, &r, &t, &b);
|
||||||
evas_object_geometry_get(to, NULL, NULL, &W, &H);
|
evas_object_geometry_get(to, NULL, NULL, &W, &H);
|
||||||
//fprintf(stderr, "Case %d: %dx%d for padding %d,%d,%d,%d\n", k, W, H, l, r, t, b);
|
//fprintf(stderr, "Case %d: %dx%d for padding %d,%d,%d,%d\n", k, W, H, l, r, t, b);
|
||||||
|
@ -394,14 +394,14 @@ START_TEST(evas_filter_text_render_test)
|
||||||
evas_object_show(o);
|
evas_object_show(o);
|
||||||
eo_do(to,
|
eo_do(to,
|
||||||
efl_gfx_color_set(255, 255, 255, 255),
|
efl_gfx_color_set(255, 255, 255, 255),
|
||||||
evas_obj_text_filter_source_set(tc->source, o),
|
efl_gfx_filter_source_set(tc->source, o),
|
||||||
evas_obj_text_filter_program_set(tc->code));
|
efl_gfx_filter_program_set(tc->code));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eo_do(to,
|
eo_do(to,
|
||||||
efl_gfx_color_set(255, 255, 255, 255),
|
efl_gfx_color_set(255, 255, 255, 255),
|
||||||
evas_obj_text_filter_program_set(tc->code));
|
efl_gfx_filter_program_set(tc->code));
|
||||||
}
|
}
|
||||||
|
|
||||||
evas_object_geometry_get(to, NULL, NULL, &w, &h);
|
evas_object_geometry_get(to, NULL, NULL, &w, &h);
|
||||||
|
|
Loading…
Reference in New Issue