Evas_Coord yoff; /**< y offset. */
Eina_Bool merge : 1; /**< Indicates whether this item should merge to the previous item or not */
Eina_Bool visually_deleted : 1; /**< Indicates whether this item is used in the visual layout or not. */
- Eina_Bool has_gfx_filter : 1; /**< True if this item should be rendered with a gfx filter */
};
struct _Evas_Object_Textblock_Text_Item
Evas_Text_Props text_props; /**< Props for this item. */
Evas_Coord inset; /**< Inset of text item. */
Evas_Coord x_adjustment; /**< Used to indicate by how much we adjusted sizes */
+ int gfx_filter_id; /**< Index for the filter context in parent.format->gfx_filter */
};
struct _Evas_Object_Textblock_Format_Item
{
// FIXME: sources not handled! --> global to the textblock
// FIXME: data not handled! --> global to the textblock
- // FIXME: filters need names! --> global to the textblock
Eina_Stringshare *name;
- Evas_Filter_Context *ctx;
+ Eina_Array *contexts; /* contains Evas_Filter_Context items for each sub text item */
Evas_Object *eo_obj;
Evas_Public_Data *evas;
- void *dc; /* draw context */
+ void *dc; /* draw context - no clip, white, no colmul... */
struct {
int l, r, t, b;
} pad;
+ int pending_ctx;
Eina_Bool invalid;
Eina_Bool async;
};
struct _Efl_Canvas_Text_Filter_Post_Render
{
Efl_Canvas_Text_Filter *filter;
- Eina_Bool success;
+ int ctx_id;
+ Eina_Bool success;
};
struct _Efl_Canvas_Text_Filter_Program
struct {
int l, r;
} margin; /**< Left and right margin width. */
- Efl_Canvas_Text_Filter *gfx_filter; /**< Gfx Filter to apply to this node */
+ Efl_Canvas_Text_Filter *gfx_filter; /**< Gfx Filter to apply to the children text items */
int ref; /**< Value of the ref. */
int tabstops; /**< Value of the size of the tab character. */
int linesize; /**< Value of the size of the line of the text. */
}
static void
-_filter_sync_end(Efl_Canvas_Text_Filter *filter, Eina_Bool success)
+_filter_sync_end(Efl_Canvas_Text_Filter *filter, int id, Eina_Bool success)
{
- evas_filter_context_destroy(filter->ctx);
+ Evas_Filter_Context *ctx;
+
+ EINA_SAFETY_ON_NULL_RETURN(filter->contexts);
+ ctx = eina_array_data_get(filter->contexts, id);
+ eina_array_data_set(filter->contexts, id, NULL);
+ evas_filter_context_destroy(ctx);
filter->invalid = !success;
- filter->ctx = NULL;
+
+ if ((--filter->pending_ctx) == 0)
+ {
+ eina_array_free(filter->contexts);
+ filter->contexts = NULL;
+ }
}
static void
{
Efl_Canvas_Text_Filter_Post_Render *post_data = data;
- _filter_sync_end(post_data->filter, post_data->success);
+ _filter_sync_end(post_data->filter, post_data->ctx_id, post_data->success);
free(post_data);
}
{
Efl_Canvas_Text_Filter_Post_Render *post_data;
Efl_Canvas_Text_Filter *filter = data;
+ int ctx_id;
- EINA_SAFETY_ON_FALSE_RETURN(filter->ctx == ctx);
+ ctx_id = evas_filter_context_id_get(ctx);
if (!filter->async)
{
- _filter_sync_end(filter, success);
+ _filter_sync_end(filter, ctx_id, success);
return;
}
post_data = calloc(1, sizeof(*post_data));
post_data->success = success;
post_data->filter = filter;
+ post_data->ctx_id = ctx_id;
evas_post_render_job_add(filter->evas, _filter_post_render_cb, post_data);
}
cr = nr; cg = ng; cb = nb; ca = na; \
}
-#define DRAW_TEXT_FILTER(gfx_f, ox, oy) do { \
- evas_filter_input_render(eo_obj, gfx_f->ctx, gfx_f->dc, ti, \
- gfx_f->pad.l, gfx_f->pad.r, \
- gfx_f->pad.t, gfx_f->pad.b, do_async); \
+#define DRAW_TEXT_FILTER(gf, gf_id, ox, oy) do { \
+ Evas_Filter_Context *ctx = eina_array_data_get(gf->contexts, gf_id); \
+ evas_filter_input_render(eo_obj, ctx, gf->dc, ti, \
+ gf->pad.l, gf->pad.r, \
+ gf->pad.t, gf->pad.b, do_async); \
} while (0)
#define DRAW_TEXT_NOFILTER(ox, oy) do { \
#define DRAW_TEXT(ox, oy) do { \
if (ti->parent.format->font.font) \
{ \
- if (EINA_LIKELY(!itr->has_gfx_filter)) \
+ if (EINA_LIKELY(!ti->gfx_filter_id)) \
DRAW_TEXT_NOFILTER(ox, oy); \
else \
- DRAW_TEXT_FILTER(ti->parent.format->gfx_filter, ox, oy); \
+ DRAW_TEXT_FILTER(ti->parent.format->gfx_filter, ti->gfx_filter_id - 1, ox, oy); \
} } while(0)
/* backing */
Efl_Canvas_Text_Filter *filter;
Evas_Filter_Program *pgm;
Evas_Filter_Context *ctx;
+ int filter_id;
Eina_Bool ok;
filter = ti->parent.format->gfx_filter;
if (!filter->name || filter->invalid)
{
- itr->has_gfx_filter = EINA_FALSE;
+ ti->gfx_filter_id = 0;
continue;
}
if (!program)
{
WRN("Filter '%s' not found on this object", filter->name);
- itr->has_gfx_filter = EINA_FALSE;
+ ti->gfx_filter_id = 0;
continue;
}
{
evas_filter_program_del(pgm);
filter->invalid = EINA_TRUE;
- itr->has_gfx_filter = EINA_FALSE;
+ ti->gfx_filter_id = 0;
continue;
}
program->pgm = pgm;
}
#ifdef DEBUG
- if (filter->ctx) WRN("Previous filter context was not deleted");
+ if (filter->contexts) WRN("Previous filter context was not deleted");
#endif
+ if (!filter->contexts)
+ filter->contexts = eina_array_new(8);
+ filter_id = eina_array_count(filter->contexts);
+
// TODO: sources set
- ctx = evas_filter_context_new(obj->layer->evas, do_async);
+ ctx = evas_filter_context_new(obj->layer->evas, do_async, filter_id);
evas_filter_state_prepare(eo_obj, &state, ti);
evas_filter_program_state_set(pgm, &state);
ok = evas_filter_context_program_use(ctx, pgm);
{
evas_filter_context_destroy(ctx);
filter->invalid = EINA_TRUE;
- itr->has_gfx_filter = EINA_FALSE;
+ ti->gfx_filter_id = 0;
continue;
}
- filter->ctx = ctx;
+
+ eina_array_push(filter->contexts, ctx);
+ ti->gfx_filter_id = filter_id + 1;
ln = ti->parent.ln;
ENFN->context_color_set(ENDT, context, 255, 255, 255, 255);
filter->eo_obj = eo_obj;
filter->evas = obj->layer->evas;
filter->async = do_async;
-
- itr->has_gfx_filter = EINA_TRUE;
+ filter->pending_ctx++;
ENFN->context_multiplier_unset(ENDT, context);
}
yoff = itr->yoff;
ln = itr->ln;
- if (EINA_UNLIKELY(itr->has_gfx_filter))
+ if (EINA_UNLIKELY(ti->gfx_filter_id))
context = ti->parent.format->gfx_filter->dc;
shad_dst = shad_sz = dx = dy = haveshad = 0;
yoff = itr->yoff;
ln = itr->ln;
- if (EINA_UNLIKELY(itr->has_gfx_filter))
+ if (EINA_UNLIKELY(ti->gfx_filter_id))
context = ti->parent.format->gfx_filter->dc;
if ((ti->parent.format->style & EVAS_TEXT_STYLE_MASK_BASIC) == EVAS_TEXT_STYLE_GLOW)
yoff = itr->yoff;
ln = itr->ln;
- if (EINA_UNLIKELY(itr->has_gfx_filter))
+ if (EINA_UNLIKELY(ti->gfx_filter_id))
context = ti->parent.format->gfx_filter->dc;
if (((ti->parent.format->style & EVAS_TEXT_STYLE_MASK_BASIC) == EVAS_TEXT_STYLE_OUTLINE) ||
{
void *fi = _ITEM_TEXT(itr)->text_props.font_instance;
- if (EINA_UNLIKELY(itr->has_gfx_filter))
+ if (EINA_UNLIKELY(ti->gfx_filter_id))
context = ti->parent.format->gfx_filter->dc;
COLOR_SET(normal);
context = context_save;
- if (EINA_UNLIKELY(itr->has_gfx_filter))
+ if (EINA_UNLIKELY(ti->gfx_filter_id))
{
Efl_Canvas_Text_Filter *filter = ti->parent.format->gfx_filter;
- Evas_Filter_Context *ctx = filter->ctx;
+ Evas_Filter_Context *ctx = eina_array_data_get(filter->contexts, ti->gfx_filter_id - 1);
evas_filter_context_post_run_callback_set(ctx, _filter_cb, filter);
evas_filter_run(ctx);
EAPI Eina_Bool evas_filter_program_state_set(Evas_Filter_Program *pgm, const Efl_Canvas_Filter_State *state);
EAPI Eina_Bool evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str);
EAPI void evas_filter_program_del(Evas_Filter_Program *pgm);
-Eina_Bool evas_filter_context_program_use(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm);
EAPI Eina_Bool evas_filter_program_padding_get(Evas_Filter_Program *pgm, int *l, int *r, int *t, int *b);
EAPI void evas_filter_program_source_set_all(Evas_Filter_Program *pgm, Eina_Hash *sources);
-void evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, Eina_Bool do_async);
void evas_filter_program_data_set_all(Evas_Filter_Program *pgm, Eina_Inlist *data);
/* Filter context (low level) */
-Evas_Filter_Context *evas_filter_context_new(Evas_Public_Data *evas, Eina_Bool async);
+Evas_Filter_Context *evas_filter_context_new(Evas_Public_Data *evas, Eina_Bool async, int id);
+int evas_filter_context_id_get(Evas_Filter_Context *ctx);
void evas_filter_context_destroy(Evas_Filter_Context *ctx);
+Eina_Bool evas_filter_context_program_use(Evas_Filter_Context *ctx, Evas_Filter_Program *pgm);
+void evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, Eina_Bool do_async);
void evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx, Evas_Filter_Cb cb, void *data);
#define evas_filter_context_autodestroy(ctx) evas_filter_context_post_run_callback_set(ctx, ((Evas_Filter_Cb) evas_filter_context_destroy), ctx)
Eina_Bool evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx);