/* Size of the index array */
#define TEXTBLOCK_PAR_INDEX_SIZE 10
+
+#define ASYNC_BLOCK do { \
+ if (o->layout_th) \
+ { \
+ ecore_thread_wait(o->layout_th, 1); \
+ }} while(0)
+
+#include "Ecore.h"
+
struct _Evas_Object_Textblock
{
+ Ecore_Thread *layout_th;
+ int layout_jobs;
Evas_Textblock_Style *style;
Eina_List *styles;
Efl_Text_Cursor_Cursor *cursor;
int underline_extend;
int have_underline, have_underline2;
double align, valign;
+ struct {
+ int l, r, t, b;
+ } style_pad;
Textblock_Position position;
Evas_Textblock_Align_Auto align_auto : 2;
Eina_Bool width_changed : 1;
/** FIXME: Document */
static void
-_layout_pre(Ctxt *c, int *style_pad_l, int *style_pad_r, int *style_pad_t,
- int *style_pad_b)
+_layout_pre(Ctxt *c)
{
+ int *style_pad_l, *style_pad_r, *style_pad_t, *style_pad_b;
Evas_Object *eo_obj = c->obj;
Efl_Canvas_Text_Data *o = c->o;
+ style_pad_l = &c->style_pad.l;
+ style_pad_r = &c->style_pad.r;
+ style_pad_b = &c->style_pad.b;
+ style_pad_t = &c->style_pad.t;
+
/* Mark text nodes as dirty if format have changed. */
if (o->format_changed)
_format_changes_invalidate_text_nodes(c);
if (o->style_pad.t > *style_pad_t) *style_pad_t = o->style_pad.t;
if (o->style_pad.b > *style_pad_b) *style_pad_b = o->style_pad.b;
}
-}
-
-/**
- * @internal
- * Create the layout from the nodes.
- *
- * @param obj the evas object - NOT NULL.
- * @param calc_only true if should only calc sizes false if should also create the layout.. It assumes native size is being calculated, doesn't support formatted size atm.
- * @param w the object's w, -1 means no wrapping (i.e infinite size)
- * @param h the object's h, -1 means inifinte size.
- * @param w_ret the object's calculated w.
- * @param h_ret the object's calculated h.
- */
-static void
-_layout(const Evas_Object *eo_obj, int w, int h, int *w_ret, int *h_ret)
-{
- Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
- Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
- Ctxt ctxt, *c;
- Evas *eo_e;
- int style_pad_l = 0, style_pad_r = 0, style_pad_t = 0, style_pad_b = 0;
-
- LYDBG("ZZ: layout %p %4ix%4i | w=%4i | last_w=%4i --- '%s'\n", eo_obj, w, h, obj->cur->geometry.w, o->last_w, o->markup_text);
- /* setup context */
- c = &ctxt;
- c->obj = (Evas_Object *)eo_obj;
- c->o = o;
- c->paragraphs = c->par = NULL;
- c->format_stack = NULL;
- c->fmt = NULL;
- c->x = c->y = 0;
- c->w = w;
- c->h = h;
- c->wmax = c->hmax = 0;
- c->ascent = c->descent = 0;
- c->maxascent = c->maxdescent = 0;
- c->marginl = c->marginr = 0;
- c->have_underline = 0;
- c->have_underline2 = 0;
- c->underline_extend = 0;
- c->line_no = 0;
- c->align = 0.0;
- c->align_auto = EINA_TRUE;
- c->ln = NULL;
- c->width_changed = (obj->cur->geometry.w != o->last_w);
- c->obs_infos = NULL;
- c->hyphen_ti = NULL;
- c->handle_obstacles = EINA_FALSE;
-
- /* Update all obstacles */
- if (c->o->obstacle_changed || c->width_changed)
- {
- _layout_obstacles_update(c);
- c->handle_obstacles = EINA_TRUE;
- }
-
- c->evas_o = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
- eo_e = evas_object_evas_get(eo_obj);
- c->evas = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
-
- /* Start of logical layout creation */
- /* setup default base style */
- {
- Eina_List *itr;
- Evas_Textblock_Style *style;
- Eina_Bool finalize = EINA_FALSE;
- if (!c->fmt)
- {
- c->fmt = _layout_format_push(c, NULL, NULL);
- finalize = EINA_TRUE;
- }
- if ((c->o->style) && (c->o->style->default_tag))
- {
- _format_fill(c->obj, c->fmt, c->o->style->default_tag);
- finalize = EINA_TRUE;
- }
-
- EINA_LIST_FOREACH(c->o->styles, itr, style)
- {
- if ((style) && (style->default_tag))
- {
- _format_fill(c->obj, c->fmt, style->default_tag);
- finalize = EINA_TRUE;
- }
- }
-
- if (finalize)
- _format_finalize(c->obj, c->fmt);
- }
- if (!c->fmt)
- {
- if (w_ret) *w_ret = 0;
- if (h_ret) *h_ret = 0;
- return;
- }
-
- _layout_pre(c, &style_pad_l, &style_pad_r, &style_pad_t, &style_pad_b);
- c->paragraphs = o->paragraphs;
-
/* If there are no paragraphs, create the minimum needed,
* if the last paragraph has no lines/text, create that as well */
if (!c->paragraphs)
ti->parent.text_pos = 0;
_layout_text_add_logical_item(c, ti, NULL);
}
-
/* End of logical layout creation */
+}
+static void
+_layout_visual(Ctxt *c)
+{
/* Start of visual layout creation */
{
Evas_Object_Textblock_Paragraph *last_vis_par = NULL;
- int par_index_step = o->num_paragraphs / TEXTBLOCK_PAR_INDEX_SIZE;
+ int par_index_step = c->o->num_paragraphs / TEXTBLOCK_PAR_INDEX_SIZE;
int par_count = 1; /* Force it to take the first one */
int par_index_pos = 0;
if (par_index_step == 0) par_index_step = 1;
/* Clear all of the index */
- memset(o->par_index, 0, sizeof(o->par_index));
+ memset(c->o->par_index, 0, sizeof(c->o->par_index));
EINA_INLIST_FOREACH(c->paragraphs, c->par)
{
{
par_count = par_index_step;
- o->par_index[par_index_pos++] = c->par;
+ c->o->par_index[par_index_pos++] = c->par;
}
}
}
}
+}
+
+static void _layout(const Evas_Object *eo_obj, int w, int h, int *w_ret, int *h_ret);
+
+static void
+_layout_done(Ctxt *c, Evas_Coord *w_ret, Evas_Coord *h_ret)
+{
/* Clean the rest of the format stack */
while (c->format_stack)
{
if (h_ret) *h_ret = c->hmax;
/* Vertically align the textblock */
- if ((o->valign > 0.0) && (c->h > c->hmax))
+ if ((c->o->valign > 0.0) && (c->h > c->hmax))
{
- Evas_Coord adjustment = (c->h - c->hmax) * o->valign;
+ Evas_Coord adjustment = (c->h - c->hmax) * c->o->valign;
Evas_Object_Textblock_Paragraph *par;
EINA_INLIST_FOREACH(c->paragraphs, par)
{
}
}
- if ((o->style_pad.l != style_pad_l) || (o->style_pad.r != style_pad_r) ||
- (o->style_pad.t != style_pad_t) || (o->style_pad.b != style_pad_b))
+ if ((c->o->style_pad.l != c->style_pad.l) || (c->o->style_pad.r != c->style_pad.r) ||
+ (c->o->style_pad.t != c->style_pad.t) || (c->o->style_pad.b != c->style_pad.b))
{
- o->style_pad.l = style_pad_l;
- o->style_pad.r = style_pad_r;
- o->style_pad.t = style_pad_t;
- o->style_pad.b = style_pad_b;
+ c->o->style_pad.l = c->style_pad.l;
+ c->o->style_pad.r = c->style_pad.r;
+ c->o->style_pad.t = c->style_pad.t;
+ c->o->style_pad.b = c->style_pad.b;
_paragraphs_clear(c);
LYDBG("ZZ: ... layout #2\n");
- _layout(eo_obj, w, h, w_ret, h_ret);
- efl_event_callback_call((Eo *) eo_obj, EFL_CANVAS_TEXT_EVENT_STYLE_INSETS_CHANGED, NULL);
+ _layout(c->obj, c->w, c->h, w_ret, h_ret);
+ efl_event_callback_call(c->obj, EFL_CANVAS_TEXT_EVENT_STYLE_INSETS_CHANGED, NULL);
+
+ c->o->obstacle_changed = EINA_FALSE;
+ }
+}
+
+static Eina_Bool
+_layout_setup(Ctxt *c, const Eo *eo_obj, Evas_Coord w, Evas_Coord h)
+{
+ Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
+ Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
+ Evas *eo_e;
+ /* setup context */
+ c->obj = (Evas_Object *)eo_obj;
+ c->o = o;
+ c->paragraphs = c->par = NULL;
+ c->format_stack = NULL;
+ c->fmt = NULL;
+ c->x = c->y = 0;
+ c->w = w;
+ c->h = h;
+ c->wmax = c->hmax = 0;
+ c->ascent = c->descent = 0;
+ c->maxascent = c->maxdescent = 0;
+ c->marginl = c->marginr = 0;
+ c->have_underline = 0;
+ c->have_underline2 = 0;
+ c->underline_extend = 0;
+ c->line_no = 0;
+ c->align = 0.0;
+ c->align_auto = EINA_TRUE;
+ c->ln = NULL;
+ c->width_changed = (obj->cur->geometry.w != o->last_w);
+ c->obs_infos = NULL;
+ c->hyphen_ti = NULL;
+ c->handle_obstacles = EINA_FALSE;
+ c->w = w;
+ c->h = h;
+ c->style_pad.r = c->style_pad.l = c->style_pad.t = c->style_pad.b = 0;
+
+ /* Update all obstacles */
+ if (c->o->obstacle_changed || c->width_changed)
+ {
+ _layout_obstacles_update(c);
+ c->handle_obstacles = EINA_TRUE;
+ }
+
+ c->evas_o = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
+ eo_e = evas_object_evas_get(eo_obj);
+ c->evas = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
+
+ /* Start of logical layout creation */
+ /* setup default base style */
+ {
+ Eina_List *itr;
+ Evas_Textblock_Style *style;
+ Eina_Bool finalize = EINA_FALSE;
+ if (!c->fmt)
+ {
+ c->fmt = _layout_format_push(c, NULL, NULL);
+ finalize = EINA_TRUE;
+ }
+ if ((c->o->style) && (c->o->style->default_tag))
+ {
+ _format_fill(c->obj, c->fmt, c->o->style->default_tag);
+ finalize = EINA_TRUE;
+ }
+
+ EINA_LIST_FOREACH(c->o->styles, itr, style)
+ {
+ if ((style) && (style->default_tag))
+ {
+ _format_fill(c->obj, c->fmt, style->default_tag);
+ finalize = EINA_TRUE;
+ }
+ }
+
+ if (finalize)
+ _format_finalize(c->obj, c->fmt);
+ }
+ if (!c->fmt)
+ {
+ return EINA_FALSE;
}
- c->o->obstacle_changed = EINA_FALSE;
+ c->paragraphs = o->paragraphs;
+
+ return EINA_TRUE;
+}
+
+/**
+ * @internal
+ * Create the layout from the nodes.
+ *
+ * @param obj the evas object - NOT NULL.
+ * @param calc_only true if should only calc sizes false if should also create the layout.. It assumes native size is being calculated, doesn't support formatted size atm.
+ * @param w the object's w, -1 means no wrapping (i.e infinite size)
+ * @param h the object's h, -1 means inifinte size.
+ * @param w_ret the object's calculated w.
+ * @param h_ret the object's calculated h.
+ */
+static void
+_layout(const Evas_Object *eo_obj, int w, int h, int *w_ret, int *h_ret)
+{
+ Ctxt ctxt, *c;
+ c = &ctxt;
+
+ LYDBG("ZZ: layout %p %4ix%4i | w=%4i | last_w=%4i --- '%s'\n", eo_obj, w, h, obj->cur->geometry.w, o->last_w, o->markup_text);
+
+ if (!_layout_setup(c, eo_obj, w, h))
+ {
+ if (w_ret) *w_ret = 0;
+ if (h_ret) *h_ret = 0;
+ return;
+ }
+ _layout_pre(c);
+ _layout_visual(c);
+ _layout_done(c, w_ret, h_ret);
}
/*
* @internal
* Check if the object needs a relayout, and if so, execute it.
*/
-static inline void
-_relayout_if_needed(Evas_Object *eo_obj, const Efl_Canvas_Text_Data *o)
+static Eina_Bool
+_relayout_if_needed(Evas_Object *eo_obj, Efl_Canvas_Text_Data *o)
{
+ ASYNC_BLOCK;
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
evas_object_textblock_coords_recalc(eo_obj, obj, obj->private_data);
- if (!o->formatted.valid)
+ if (o->formatted.valid)
{
- LYDBG("ZZ: relayout\n");
- _relayout(eo_obj);
+ return EINA_TRUE;
}
+ LYDBG("ZZ: relayout\n");
+ _relayout(eo_obj);
+ return EINA_TRUE;
}
/**
}
static Evas_Textblock_Obstacle *
-_obstacle_find(Efl_Canvas_Text_Data *obj, Eo *eo_obs)
+_obstacle_find(Efl_Canvas_Text_Data *o, Eo *eo_obs)
{
Evas_Textblock_Obstacle *obs;
Eina_List *i;
- EINA_LIST_FOREACH(obj->obstacles, i, obs)
+ EINA_LIST_FOREACH(o->obstacles, i, obs)
{
if (eo_obs == obs->eo_obs)
return obs;
_obstacle_del_cb(void *data, const Efl_Event *event)
{
Eo *eo_obj = data;
- Efl_Canvas_Text_Data *obj = efl_data_scope_get(eo_obj, MY_CLASS);
+ Efl_Canvas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
Eina_List *i;
Evas_Textblock_Obstacle *obs;
- EINA_LIST_FOREACH(obj->obstacles, i, obs)
+ EINA_LIST_FOREACH(o->obstacles, i, obs)
{
if (event->object == obs->eo_obs)
break;
}
- obj->obstacles = eina_list_remove_list(obj->obstacles, i);
+ o->obstacles = eina_list_remove_list(o->obstacles, i);
free(obs);
- _evas_textblock_changed(obj, data);
- obj->obstacle_changed = EINA_TRUE;
+ _evas_textblock_changed(o, data);
+ o->obstacle_changed = EINA_TRUE;
}
static void
}
static void
-_obstacles_free(Eo *eo_obj, Efl_Canvas_Text_Data *obj)
+_obstacles_free(Eo *eo_obj, Efl_Canvas_Text_Data *o)
{
Evas_Textblock_Obstacle *obs;
- EINA_LIST_FREE(obj->obstacles, obs)
+ EINA_LIST_FREE(o->obstacles, obs)
{
_obstacle_free(eo_obj, obs);
}
EOLIAN static Eina_Bool
_efl_canvas_text_obstacle_add(Eo *eo_obj,
- Efl_Canvas_Text_Data *obj, Eo *eo_obs)
+ Efl_Canvas_Text_Data *o, Eo *eo_obs)
{
Evas_Textblock_Obstacle *obs;
if (!efl_isa(eo_obs, EFL_CANVAS_OBJECT_CLASS))
return EINA_FALSE;
- obs = _obstacle_find(obj, eo_obs);
+ obs = _obstacle_find(o, eo_obs);
if (obs) return EINA_FALSE;
obs = calloc(1, sizeof(Evas_Textblock_Obstacle));
obs->eo_obs = eo_obs;
efl_event_callback_add(eo_obs, EFL_EVENT_DEL, _obstacle_del_cb, eo_obj);
- obj->obstacles = eina_list_append(obj->obstacles, obs);
+ o->obstacles = eina_list_append(o->obstacles, obs);
_obstacle_update(obs, eo_obj);
- _evas_textblock_changed(obj, eo_obj);
- obj->obstacle_changed = EINA_TRUE;
+ _evas_textblock_changed(o, eo_obj);
+ o->obstacle_changed = EINA_TRUE;
return EINA_TRUE;
}
EOLIAN static Eina_Bool
-_efl_canvas_text_obstacle_del(Eo *eo_obj, Efl_Canvas_Text_Data *obj,
+_efl_canvas_text_obstacle_del(Eo *eo_obj, Efl_Canvas_Text_Data *o,
Eo *eo_obs EINA_UNUSED)
{
Evas_Textblock_Obstacle *obs;
if (!efl_isa(eo_obs, EFL_CANVAS_OBJECT_CLASS))
return EINA_FALSE;
- EINA_LIST_FOREACH(obj->obstacles, i, obs)
+ EINA_LIST_FOREACH(o->obstacles, i, obs)
{
if (eo_obs == obs->eo_obs)
{
}
}
if (!i) return EINA_FALSE;
- obj->obstacles = eina_list_remove_list(obj->obstacles, i);
+ o->obstacles = eina_list_remove_list(o->obstacles, i);
_obstacle_free(eo_obj, obs);
- _evas_textblock_changed(obj, eo_obj);
- obj->obstacle_changed = EINA_TRUE;
+ _evas_textblock_changed(o, eo_obj);
+ o->obstacle_changed = EINA_TRUE;
return EINA_TRUE;
}
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_paragraph_first(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
{
+ ASYNC_BLOCK;
evas_textblock_cursor_paragraph_first(cur);
efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_paragraph_last(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
{
+ ASYNC_BLOCK;
evas_textblock_cursor_paragraph_last(cur);
efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_paragraph_next(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Evas_Textblock_Cursor *cur)
{
+ ASYNC_BLOCK;
evas_textblock_cursor_paragraph_next(cur);
efl_event_callback_legacy_call(obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
_efl_canvas_text_efl_text_cursor_cursor_paragraph_prev(Eo *obj EINA_UNUSED,
Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
{
+ ASYNC_BLOCK;
_evas_textblock_cursor_paragraph_prev(cur);
efl_event_callback_legacy_call(obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_word_start(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur EINA_UNUSED)
{
+ ASYNC_BLOCK;
evas_textblock_cursor_word_start(cur);
efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_word_end(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur EINA_UNUSED)
{
+ ASYNC_BLOCK;
evas_textblock_cursor_word_end(cur);
efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_char_next(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
{
+ ASYNC_BLOCK;
evas_textblock_cursor_char_next(cur);
efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_char_prev(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
{
+ ASYNC_BLOCK;
_evas_textblock_cursor_char_prev(cur);
efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_paragraph_char_first(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
{
+ ASYNC_BLOCK;
evas_textblock_cursor_paragraph_char_first(cur);
efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_paragraph_char_last(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
{
+ ASYNC_BLOCK;
evas_textblock_cursor_paragraph_char_last(cur);
efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_line_char_last(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
{
+ ASYNC_BLOCK;
evas_textblock_cursor_line_char_last(cur);
efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_line_char_first(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
{
+ ASYNC_BLOCK;
evas_textblock_cursor_line_char_first(cur);
efl_event_callback_legacy_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
EOLIAN static int
_efl_canvas_text_efl_text_cursor_cursor_position_get(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
{
+ ASYNC_BLOCK;
Evas_Object_Textblock_Node_Text *n;
size_t npos = 0;
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_position_set(Eo *cur_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur, int _pos)
{
+ ASYNC_BLOCK;
evas_textblock_cursor_pos_set(cur, _pos);
efl_event_callback_legacy_call(cur_obj, EFL_CANVAS_TEXT_EVENT_CURSOR_CHANGED, NULL);
}
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_line_jump_by(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur EINA_UNUSED, int by)
{
+ ASYNC_BLOCK;
int ln;
ln = evas_textblock_cursor_line_geometry_get(cur, NULL, NULL, NULL, NULL) + by;
_efl_canvas_text_efl_text_cursor_cursor_compare(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED,
const Efl_Text_Cursor_Cursor *cur1, const Efl_Text_Cursor_Cursor *cur2)
{
+ ASYNC_BLOCK;
Evas_Object_Protected_Data *obj = efl_data_scope_get(cur1->obj, EFL_CANVAS_OBJECT_CLASS);
evas_object_async_block(obj);
return evas_textblock_cursor_compare(cur1, cur2);
EOLIAN static Eina_Bool
_efl_canvas_text_efl_text_cursor_cursor_equal(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, const Efl_Text_Cursor_Cursor *cur, const Efl_Text_Cursor_Cursor *cur2)
{
+ ASYNC_BLOCK;
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
evas_object_async_block(obj);
return ((cur->node == cur2->node) && (cur->pos == cur2->pos));
_efl_canvas_text_efl_text_cursor_cursor_copy(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED,
Efl_Text_Cursor_Cursor *dst, const Efl_Text_Cursor_Cursor *src)
{
+ ASYNC_BLOCK;
if (!efl_text_cursor_equal(obj, dst, src))
{
_evas_textblock_cursor_copy(dst, src);
Efl_Canvas_Text_Data *o,
Efl_Text_Cursor_Cursor *cur, const char *_text)
{
+ ASYNC_BLOCK;
int len = _efl_canvas_text_cursor_text_append(cur, _text);
_evas_textblock_changed(o, eo_obj);
efl_event_callback_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, NULL);
EOLIAN static void
_efl_canvas_text_efl_text_cursor_cursor_char_delete(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur)
{
+ ASYNC_BLOCK;
evas_textblock_cursor_char_delete(cur);
efl_event_callback_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, NULL);
}
}
EOLIAN static Eina_Unicode
-_efl_canvas_text_efl_text_cursor_cursor_content_get(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *pd EINA_UNUSED,
+_efl_canvas_text_efl_text_cursor_cursor_content_get(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED,
const Efl_Text_Cursor_Cursor *cur)
{
+ ASYNC_BLOCK;
return eina_ustrbuf_string_get(cur->node->unicode)[cur->pos];
}
EOLIAN static Eina_Bool
_efl_canvas_text_efl_text_cursor_cursor_geometry_get(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, const Efl_Text_Cursor_Cursor *cur, Efl_Text_Cursor_Cursor_Type ctype, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch, Evas_Coord *cx2, Evas_Coord *cy2, Evas_Coord *cw2, Evas_Coord *ch2)
{
+ ASYNC_BLOCK;
if (!cur) return EINA_FALSE;
Evas_Object_Protected_Data *obj = efl_data_scope_get(cur->obj, EFL_CANVAS_OBJECT_CLASS);
evas_object_async_block(obj);
- _relayout_if_needed(cur->obj, o);
+ if (!_relayout_if_needed(cur->obj, o)) return EINA_FALSE;
if (ctype == EFL_TEXT_CURSOR_TYPE_UNDER)
{
_efl_canvas_text_efl_text_cursor_cursor_coord_set(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Cursor_Cursor *cur EINA_UNUSED,
Evas_Coord x, Evas_Coord y)
{
+ ASYNC_BLOCK;
evas_textblock_cursor_char_coord_set(cur, x, y);
}
Evas_Object_Textblock_Item *itr;
Evas_Object_Textblock_Line *ln, *cur_ln = NULL;
Efl_Canvas_Text_Data *o = type_private_data;
+ ASYNC_BLOCK;
+
Eina_List *shadows = NULL;
Eina_List *glows = NULL;
Eina_List *outlines = NULL;
Plus, one more scenario is that the object isn't visible but actually is visible
by evas_map. */
if (o->changed || o->content_changed || o->format_changed || o->obstacle_changed)
+ {
_relayout_if_needed(eo_obj, o);
+ }
/* If there are no paragraphs and thus there are no lines,
* there's nothing left to do. */
- if (!o->paragraphs) return;
+ if (!o->paragraphs)
+ {
+ return;
+ }
/* render object to surface with context, and offxet by x,y */
ENFN->context_multiplier_unset(engine, context);
void *type_private_data)
{
Efl_Canvas_Text_Data *o = type_private_data;
+ ASYNC_BLOCK;
+
int is_v, was_v;
/* dont pre-render the obj twice! */
/* then when this is done the object needs to figure if it changed and */
/* if so what and where and add the appropriate redraw textblocks */
- evas_object_textblock_coords_recalc(eo_obj, obj, obj->private_data);
+ //evas_object_textblock_coords_recalc(eo_obj, obj, obj->private_data);
+ if (!_relayout_if_needed(eo_obj, o))
+ {
+ o->redraw = 0;
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
+ eo_obj, obj);
+ is_v = evas_object_is_visible(eo_obj, obj);
+ was_v = evas_object_was_visible(eo_obj, obj);
+ goto done;
+ }
if (o->changed)
{
LYDBG("ZZ: relayout 16\n");
- _relayout(eo_obj);
o->redraw = 0;
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
eo_obj, obj);
Evas_Object_Protected_Data *obj,
void *type_private_data)
{
- /* Efl_Canvas_Text_Data *o; */
+ Efl_Canvas_Text_Data *o = type_private_data;
+ ASYNC_BLOCK;
/* this moves the current data to the previous state parts of the object */
/* in whatever way is safest for the object. also if we don't need object */
/* move cur to prev safely for object data */
evas_object_cur_prev(obj);
/* o->prev = o->cur; */
- EINA_SAFETY_ON_NULL_RETURN(type_private_data);
- _filter_output_cache_prune(obj, type_private_data);
+ EINA_SAFETY_ON_NULL_RETURN(o);
+ _filter_output_cache_prune(obj, o);
}
static unsigned int evas_object_textblock_id_get(Evas_Object *eo_obj)
}
EOLIAN static void
-_efl_canvas_text_efl_text_text_set(Eo *eo_obj, Efl_Canvas_Text_Data *o EINA_UNUSED,
+_efl_canvas_text_efl_text_text_set(Eo *eo_obj, Efl_Canvas_Text_Data *o,
const char *text)
{
+ ASYNC_BLOCK;
evas_object_textblock_text_markup_set(eo_obj, "");
efl_text_cursor_text_insert(eo_obj, o->cursor, text);
- efl_event_callback_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, NULL);
+ //efl_event_callback_call(eo_obj, EFL_CANVAS_TEXT_EVENT_CHANGED, NULL);
}
static char *
Efl_Canvas_Text_Data *o, Efl_Text_Annotate_Annotation *annotation,
const char *format)
{
+ ASYNC_BLOCK;
Efl_Text_Cursor_Cursor start, end;
Eina_Bool ret = EINA_TRUE;
_efl_canvas_text_efl_text_annotate_annotation_del(Eo *eo_obj EINA_UNUSED,
Efl_Canvas_Text_Data *o, Efl_Text_Annotate_Annotation *annotation)
{
+ ASYNC_BLOCK;
if (!annotation || (annotation->obj != eo_obj))
{
ERR("Used invalid handle or of a different object");
Efl_Text_Cursor_Cursor *start, Efl_Text_Cursor_Cursor *end,
const char *format)
{
+ ASYNC_BLOCK;
Efl_Text_Annotate_Annotation *ret;
ret = _textblock_annotation_insert(eo_obj, o, start, end, format,
static void
_efl_canvas_text_efl_text_font_font_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, const char *font EINA_UNUSED, int size EINA_UNUSED)
{
+ ASYNC_BLOCK;
Eina_Bool changed = EINA_FALSE;
Eina_Stringshare *nfont;
static void
_efl_canvas_text_efl_text_font_font_slant_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Font_Slant font_slant EINA_UNUSED)
{
+ ASYNC_BLOCK;
if (_FMT_INFO(font_slant) == font_slant) return;
_FMT_INFO(font_slant) = font_slant;
_canvas_text_format_changed(obj, o);
static void
_efl_canvas_text_efl_text_font_font_width_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Font_Width font_width EINA_UNUSED)
{
+ ASYNC_BLOCK;
if (_FMT_INFO(font_width) == font_width) return;
_FMT_INFO(font_width) = font_width;
_canvas_text_format_changed(obj, o);
static void
_efl_canvas_text_efl_text_style_normal_color_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, unsigned char r EINA_UNUSED, unsigned char g EINA_UNUSED, unsigned char b EINA_UNUSED, unsigned char a EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_COLOR_SET(normal);
}
static void
_efl_canvas_text_efl_text_style_backing_type_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Style_Backing_Type type EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_SET(backing, type);
}
static void
_efl_canvas_text_efl_text_style_backing_color_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, unsigned char r EINA_UNUSED, unsigned char g EINA_UNUSED, unsigned char b EINA_UNUSED, unsigned char a EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_COLOR_SET(backing);
}
static void
_efl_canvas_text_efl_text_style_underline_type_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Style_Underline_Type type EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_SET(underline, type);
}
static void
_efl_canvas_text_efl_text_style_underline_color_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, unsigned char r EINA_UNUSED, unsigned char g EINA_UNUSED, unsigned char b EINA_UNUSED, unsigned char a EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_COLOR_SET(underline);
}
static void
_efl_canvas_text_efl_text_style_underline_height_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, double height EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_SET(underline_height, height);
}
static void
_efl_canvas_text_efl_text_style_underline_dashed_color_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, unsigned char r EINA_UNUSED, unsigned char g EINA_UNUSED, unsigned char b EINA_UNUSED, unsigned char a EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_COLOR_SET(underline_dash);
}
static void
_efl_canvas_text_efl_text_style_underline_dashed_width_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, int width EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_SET(underline_dash_width, width);
}
static void
_efl_canvas_text_efl_text_style_underline_dashed_gap_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, int gap EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_SET(underline_dash_gap, gap);
}
static void
_efl_canvas_text_efl_text_style_underline2_type_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Style_Underline_Type type EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_SET(underline2, type);
}
static void
_efl_canvas_text_efl_text_style_underline2_color_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, unsigned char r EINA_UNUSED, unsigned char g EINA_UNUSED, unsigned char b EINA_UNUSED, unsigned char a EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_COLOR_SET(underline2);
}
static void
_efl_canvas_text_efl_text_style_strikethrough_type_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Style_Strikethrough_Type type EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_SET(strikethrough, type);
}
static void
_efl_canvas_text_efl_text_style_strikethrough_color_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, unsigned char r EINA_UNUSED, unsigned char g EINA_UNUSED, unsigned char b EINA_UNUSED, unsigned char a EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_COLOR_SET(strikethrough);
}
static void
_efl_canvas_text_efl_text_style_effect_type_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Style_Effect_Type type EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_INFO_SET_START(effect, type);
_FMT(style) = _map_style_effect[type].y;
// Re-apply shadow direction
static void
_efl_canvas_text_efl_text_style_outline_color_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, unsigned char r EINA_UNUSED, unsigned char g EINA_UNUSED, unsigned char b EINA_UNUSED, unsigned char a EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_COLOR_SET(outline);
}
static void
_efl_canvas_text_efl_text_style_shadow_direction_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Style_Shadow_Direction type EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_INFO_SET_START(shadow_direction, type);
EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET(_FMT(style), _map_shadow_dir[type].y);
_FMT_INFO_SET_END();
static void
_efl_canvas_text_efl_text_style_shadow_color_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, unsigned char r EINA_UNUSED, unsigned char g EINA_UNUSED, unsigned char b EINA_UNUSED, unsigned char a EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_COLOR_SET(shadow);
}
static void
_efl_canvas_text_efl_text_style_glow_color_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, unsigned char r EINA_UNUSED, unsigned char g EINA_UNUSED, unsigned char b EINA_UNUSED, unsigned char a EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_COLOR_SET(glow);
}
static void
_efl_canvas_text_efl_text_style_glow2_color_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, unsigned char r EINA_UNUSED, unsigned char g EINA_UNUSED, unsigned char b EINA_UNUSED, unsigned char a EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_COLOR_SET(glow2);
}
_efl_canvas_text_efl_text_style_gfx_filter_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED,
const char *gfx_filter_name)
{
+ ASYNC_BLOCK;
Eina_Stringshare *ngfx_filter_name;
if (_FMT_INFO(gfx_filter_name) != gfx_filter_name)
static void
_efl_canvas_text_efl_text_format_ellipsis_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, double value EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_SET(ellipsis, value);
}
static void
_efl_canvas_text_efl_text_format_wrap_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Efl_Text_Format_Wrap wrap EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_INFO_SET_START(wrap, wrap);
_FMT(wrap_word) = (wrap == EFL_TEXT_FORMAT_WRAP_WORD);
_FMT(wrap_char) = (wrap == EFL_TEXT_FORMAT_WRAP_CHAR);
static void
_efl_canvas_text_efl_text_format_multiline_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Eina_Bool enabled EINA_UNUSED)
{
+ ASYNC_BLOCK;
if (o->multiline == enabled) return;
o->multiline = enabled;
_canvas_text_format_changed(obj, o);
static void
_efl_canvas_text_efl_text_format_halign_set(Eo *obj, Efl_Canvas_Text_Data *o, Efl_Text_Format_Horizontal_Alignment_Type type)
{
+ ASYNC_BLOCK;
if (type == EFL_TEXT_HORIZONTAL_ALIGNMENT_AUTO)
{
_FMT_SET(halign_auto, EVAS_TEXTBLOCK_ALIGN_AUTO_NORMAL);
_efl_canvas_text_efl_text_format_valign_set(Eo *obj, Efl_Canvas_Text_Data *o,
Efl_Text_Format_Vertical_Alignment_Type type)
{
+ ASYNC_BLOCK;
double value = 0.0; // EFL_TEXT_VERTICAL_ALIGNMENT_TOP
if (type == EFL_TEXT_VERTICAL_ALIGNMENT_CENTER)
{
static void
_efl_canvas_text_efl_text_format_linegap_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, double value EINA_UNUSED)
{
+ ASYNC_BLOCK;
double linerelgap = _FMT(linerelgap);
_FMT(linerelgap) = 0.0;
static void
_efl_canvas_text_efl_text_format_linerelgap_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, double value EINA_UNUSED)
{
+ ASYNC_BLOCK;
double linegap = _FMT(linegap);
_FMT(linegap) = 0.0;
static void
_efl_canvas_text_efl_text_format_tabstops_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, int value EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_SET(tabstops, value);
}
static void
_efl_canvas_text_efl_text_format_password_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, Eina_Bool enabled EINA_UNUSED)
{
+ ASYNC_BLOCK;
_FMT_SET(password, enabled);
}
static void
_efl_canvas_text_efl_text_format_replacement_char_set(Eo *obj EINA_UNUSED, Efl_Canvas_Text_Data *o EINA_UNUSED, const char *repch EINA_UNUSED)
{
+ ASYNC_BLOCK;
Eina_Stringshare *nrepch;
if (o->repch != repch)
{
evas_textblock_cursor_free(cur);
}
+/* Async Layout */
+
+typedef struct _Text_Promise_Ctx Text_Promise_Ctx;
+struct _Text_Promise_Ctx
+{
+ int ret;
+ Ctxt *c;
+ Evas_Coord style_pad_l, style_pad_r, style_pad_t, style_pad_b;
+ Evas_Coord *w_ret, *h_ret;
+ Eina_Promise *p;
+ Eina_Value *v;
+};
+
+static void
+_text_layout_async_do(void *todo, Ecore_Thread *thread EINA_UNUSED)
+{
+ Text_Promise_Ctx *td = todo;
+ _layout_visual(td->c);
+}
+
+static void
+_resolve_async(Text_Promise_Ctx *td, Evas_Coord w, Evas_Coord h)
+{
+ Eina_Value v;
+ Eina_Rectangle r = { 0, 0, w, h };
+ eina_value_setup(&v, EINA_VALUE_TYPE_RECTANGLE);
+ eina_value_pset(&v, &r);
+ eina_promise_resolve(td->p, v);
+ free(td);
+}
+
+static void
+_text_layout_async_done(void *todo, Ecore_Thread *thread EINA_UNUSED)
+{
+ Text_Promise_Ctx *td = todo;
+ Ctxt *c = td->c;
+ Eo *obj = c->obj;
+ Efl_Canvas_Text_Data *o = c->o;
+ Evas_Coord w_ret, h_ret;
+ _layout_done(c, &w_ret, &h_ret);
+
+ c->o->formatted.valid = 1;
+ c->o->formatted.oneline_h = 0;
+ c->o->last_w = c->evas_o->cur->geometry.w;
+ c->o->wrap_changed = EINA_FALSE;
+ c->o->last_h = c->evas_o->cur->geometry.h;
+ if ((c->o->paragraphs) && (!EINA_INLIST_GET(c->o->paragraphs)->next) &&
+ (c->o->paragraphs->lines) && (!EINA_INLIST_GET(c->o->paragraphs->lines)->next))
+ {
+ if (c->evas_o->cur->geometry.h < c->o->formatted.h)
+ {
+ c->o->formatted.oneline_h = c->o->formatted.h;
+ }
+ }
+ c->o->changed = 0;
+ c->o->content_changed = 0;
+ c->o->format_changed = EINA_FALSE;
+ c->o->redraw = 1;
+#ifdef BIDI_SUPPORT
+ c->o->changed_paragraph_direction = EINA_FALSE;
+#endif
+
+ o->formatted.w = c->wmax;
+ o->formatted.h = c->hmax;
+ c->o->changed = EINA_TRUE;
+ evas_object_change(c->obj, c->evas_o);
+ free(c);
+
+ _resolve_async(td, o->formatted.w, o->formatted.h);
+
+ o->layout_th = NULL;
+ o->layout_jobs--;
+ if (o->layout_jobs > 0)
+ {
+ efl_canvas_text_async_layout(obj);
+ }
+}
+
+static void
+_dummy_cancel(void *data EINA_UNUSED, const Eina_Promise *dead EINA_UNUSED)
+{
+}
+
+static Eina_Future_Scheduler *
+_future_scheduler_get(void)
+{
+ return efl_loop_future_scheduler_get(ecore_main_loop_get());
+}
+
+EOLIAN static Eina_Future *
+_efl_canvas_text_async_layout(Eo *eo_obj EINA_UNUSED, Efl_Canvas_Text_Data *o)
+{
+ Ctxt *c;
+ Eina_Promise *p;
+ Eina_Future *f;
+ Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
+
+ Text_Promise_Ctx *ctx = calloc(1, sizeof(*ctx));
+ p = eina_promise_new(_future_scheduler_get(), _dummy_cancel, ctx);
+ if (!p)
+ {
+ CRI("Failed to allocate a promise");
+ return NULL;
+ }
+ ctx->p = p;
+ f = eina_future_new(p);
+
+ if (o->layout_th)
+ {
+ o->layout_jobs++;
+ return f;
+ }
+ evas_object_textblock_coords_recalc(eo_obj, obj, obj->private_data);
+ if (o->formatted.valid)
+ {
+ _resolve_async(ctx, o->formatted.w, o->formatted.w);
+ return f;
+ }
+
+ c = calloc(1, sizeof(*c));
+ ctx->c = c;
+
+ if (!_layout_setup(c, eo_obj,
+ obj->cur->geometry.w, obj->cur->geometry.h))
+ {
+ _resolve_async(ctx, 0, 0);
+ return f;
+ }
+ _layout_pre(c);
+ o->layout_th = ecore_thread_run(_text_layout_async_do, _text_layout_async_done,
+ NULL, ctx);
+ return f;
+}
+
#include "canvas/efl_canvas_text.eo.c"