tests/evas/evas_suite.c \
tests/evas/evas_test_init.c \
tests/evas/evas_test_object.c \
+tests/evas/evas_test_object_smart.c \
tests/evas/evas_test_textblock.c \
tests/evas/evas_test_text.c \
tests/evas/evas_test_callbacks.c \
Eo.Base.constructor;
Eo.Base.destructor;
Eo.Base.dbg_info_get;
+ Evas.Object.paragraph_direction.set;
Evas.Object_Smart.hide;
Evas.Object_Smart.calculate;
Evas.Object_Smart.show;
eo_do((Edje_Object *)obj, efl_file_get(file, group));
}
+EOLIAN static void
+_edje_object_evas_object_paragraph_direction_set(Eo *obj, Edje *ed, Evas_BiDi_Direction dir)
+{
+ eo_do_super(obj, MY_CLASS, evas_obj_paragraph_direction_set(dir));
+
+ /* Make it dirty to recalculate edje.
+ It needs to move text objects according to new paragraph direction */
+ ed->dirty = EINA_TRUE;
+ eo_do(obj, evas_obj_smart_need_recalculate_set(1));
+}
+
#include "edje_object.eo.c"
dispmode: Evas.Display_Mode; [[Display mode hint.]]
}
}
+ @property paragraph_direction {
+ [[This handles text paragraph direction of the given object.
+ Even if the given object is not textblock or text, its smart child objects
+ can inherit the paragraph direction from the given object.
+ The default paragraph direction is @Evas.BiDi_Direction.inherit.]]
+ set {
+ }
+ get {
+ }
+ values {
+ dir: Evas.BiDi_Direction; [[Paragraph direction for the given object.]]
+ }
+ }
clipees_has @const {
[[Test if any object is clipped by $obj.
return EINA_FALSE;
}
+EOLIAN static void
+_evas_object_paragraph_direction_set(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj EINA_UNUSED, Evas_BiDi_Direction dir EINA_UNUSED)
+{
+ return;
+}
+
+EOLIAN static Evas_BiDi_Direction
+_evas_object_paragraph_direction_get(Eo *eo_obj EINA_UNUSED, Evas_Object_Protected_Data *obj EINA_UNUSED)
+{
+ return EVAS_BIDI_DIRECTION_NEUTRAL;
+}
+
#include "canvas/evas_object.eo.c"
unsigned char recalculate_cycle;
+ Evas_BiDi_Direction paragraph_direction : 2;
+ Eina_Bool inherit_paragraph_direction : 1;
Eina_Bool deletions_waiting : 1;
Eina_Bool need_recalculate : 1;
Eina_Bool update_boundingbox_needed : 1;
static unsigned int evas_object_smart_id_get(Evas_Object *eo_obj);
static unsigned int evas_object_smart_visual_id_get(Evas_Object *eo_obj);
static void *evas_object_smart_engine_data_get(Evas_Object *eo_obj);
+static void _evas_object_smart_paragraph_direction_set_internal(Eo *eo_obj,
+ Evas_BiDi_Direction dir);
static const Evas_Object_Func object_func =
{
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
Evas_Object_Protected_Data *smart = eo_data_scope_get(smart_obj, EVAS_OBJECT_CLASS);
+ Evas_Smart_Data *member_o;
if (obj->delete_me)
{
evas_object_smart_member_cache_invalidate(eo_obj, EINA_TRUE, EINA_TRUE,
EINA_TRUE);
obj->restack = 1;
+
+ if (obj->is_smart)
+ {
+ member_o = eo_data_scope_get(eo_obj, EVAS_OBJECT_SMART_CLASS);
+
+ if ((member_o->inherit_paragraph_direction) &&
+ (member_o->paragraph_direction != o->paragraph_direction))
+ {
+ member_o->paragraph_direction = o->paragraph_direction;
+ _evas_object_smart_paragraph_direction_set_internal(eo_obj, o->paragraph_direction);
+ }
+ }
+
evas_object_change(eo_obj, obj);
evas_object_mapped_clip_across_mark(eo_obj, obj);
if (smart->smart.smart && smart->smart.smart->smart_class->member_add)
_evas_object_smart_member_del(Eo *smart_obj, Evas_Smart_Data *_pd EINA_UNUSED, Evas_Object *eo_obj)
{
Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
+ Evas_Smart_Data *member_o;
if (!obj->smart.parent) return;
}
EINA_COW_STATE_WRITE_END(obj, state_write, cur);
+ if (obj->is_smart)
+ {
+ member_o = eo_data_scope_get(eo_obj, EVAS_OBJECT_SMART_CLASS);
+
+ if ((member_o->inherit_paragraph_direction) &&
+ (member_o->paragraph_direction != EVAS_BIDI_DIRECTION_NEUTRAL))
+ {
+ member_o->paragraph_direction = EVAS_BIDI_DIRECTION_NEUTRAL;
+ _evas_object_smart_paragraph_direction_set_internal(eo_obj, EVAS_BIDI_DIRECTION_NEUTRAL);
+ }
+ }
+
evas_object_inject(eo_obj, obj, obj->layer->evas->evas);
obj->restack = 1;
evas_object_change(eo_obj, obj);
smart = class_data;
smart->object = eo_obj;
+ smart->inherit_paragraph_direction = EINA_TRUE;
eo_obj = eo_do_super_ret(eo_obj, MY_CLASS, eo_obj, eo_constructor());
evas_object_smart_init(eo_obj);
eina_hash_free(_evas_smart_class_names_hash_table);
}
+static void
+_evas_object_smart_paragraph_direction_set_internal(Eo *eo_obj,
+ Evas_BiDi_Direction dir)
+{
+ Evas_Object_Protected_Data *o;
+ Evas_Smart_Data *member_o;
+
+ EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(eo_obj), o)
+ {
+ evas_object_change(o->object, o);
+
+ if (o->is_smart)
+ {
+ member_o = eo_data_scope_get(o->object, EVAS_OBJECT_SMART_CLASS);
+
+ if ((member_o->inherit_paragraph_direction) &&
+ (member_o->paragraph_direction != dir))
+ {
+ member_o->paragraph_direction = dir;
+ _evas_object_smart_paragraph_direction_set_internal(o->object, dir);
+ }
+ }
+ }
+}
+
+EOLIAN static void
+_evas_object_smart_evas_object_paragraph_direction_set(Eo *eo_obj, Evas_Smart_Data *o, Evas_BiDi_Direction dir)
+{
+ Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
+ Evas_Smart_Data *parent;
+
+ MAGIC_CHECK(eo_obj, Evas_Object, MAGIC_OBJ);
+ return;
+ MAGIC_CHECK_END();
+
+ if ((!(o->inherit_paragraph_direction) && (o->paragraph_direction == dir)) ||
+ (o->inherit_paragraph_direction && (dir == EVAS_BIDI_DIRECTION_INHERIT)))
+ return;
+
+ if (dir == EVAS_BIDI_DIRECTION_INHERIT)
+ {
+ o->inherit_paragraph_direction = EINA_TRUE;
+ Evas_BiDi_Direction parent_dir = EVAS_BIDI_DIRECTION_NEUTRAL;
+
+ if (obj->smart.parent)
+ {
+ parent = eo_data_scope_get(obj->smart.parent, EVAS_OBJECT_SMART_CLASS);
+
+ if (parent)
+ parent_dir = parent->paragraph_direction;
+ }
+
+ if (parent_dir != o->paragraph_direction)
+ {
+ o->paragraph_direction = parent_dir;
+ evas_object_change(eo_obj, obj);
+ }
+ }
+ else
+ {
+ o->inherit_paragraph_direction = EINA_FALSE;
+ o->paragraph_direction = dir;
+ evas_object_change(eo_obj, obj);
+ }
+
+ _evas_object_smart_paragraph_direction_set_internal(eo_obj, o->paragraph_direction);
+}
+
+EOLIAN static Evas_BiDi_Direction
+_evas_object_smart_evas_object_paragraph_direction_get(Eo *eo_obj EINA_UNUSED, Evas_Smart_Data *o)
+{
+ return o->paragraph_direction;
+}
+
#include "canvas/evas_object_smart.eo.c"
Evas.Object.smart_type_check_ptr;
Evas.Object.smart_type_check;
Evas.Object.smart_data.get;
+ Evas.Object.paragraph_direction.set;
+ Evas.Object.paragraph_direction.get;
}
}
float max_ascent, max_descent;
Evas_BiDi_Direction bidi_dir : 2;
+ Evas_BiDi_Direction paragraph_direction : 2;
+ Eina_Bool inherit_paragraph_direction : 1;
+ Eina_Bool changed_paragraph_direction : 1;
Eina_Bool changed : 1;
Eina_Bool has_filter : 1;
};
o->cur.text == text &&
obj->cur->scale == obj->prev->scale &&
((o->last_computed.advance <= obj->cur->geometry.w && !o->last_computed.ellipsis) ||
- o->last_computed.w == obj->cur->geometry.w))
+ (o->last_computed.w == obj->cur->geometry.w)) &&
+ !o->changed_paragraph_direction)
return;
o->last_computed.ellipsis = EINA_FALSE;
}
evas_bidi_paragraph_props_unref(o->bidi_par_props);
if (text)
- o->bidi_par_props = evas_bidi_paragraph_props_get(text, len, segment_idxs);
+ {
+ Evas_BiDi_Direction par_dir;
+ EvasBiDiParType bidi_par_type;
+
+ par_dir = o->paragraph_direction;
+
+ switch (par_dir)
+ {
+ case EVAS_BIDI_DIRECTION_LTR:
+ bidi_par_type = EVAS_BIDI_PARAGRAPH_LTR;
+ break;
+ case EVAS_BIDI_DIRECTION_RTL:
+ bidi_par_type = EVAS_BIDI_PARAGRAPH_RTL;
+ break;
+ case EVAS_BIDI_DIRECTION_NEUTRAL:
+ default:
+ bidi_par_type = EVAS_BIDI_PARAGRAPH_NEUTRAL;
+ break;
+ }
+
+ o->bidi_par_props = evas_bidi_paragraph_props_get(text, len, segment_idxs, bidi_par_type);
+ }
if (o->bidi_par_props)
o->bidi_dir = EVAS_BIDI_PAR_TYPE_TO_DIRECTION(o->bidi_par_props->direction);
}
EOLIAN static Evas_BiDi_Direction
-_evas_text_direction_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
+_evas_text_direction_get(Eo *eo_obj, Evas_Text_Data *o)
{
+#ifdef BIDI_SUPPORT
+ Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
+
+ if (o->inherit_paragraph_direction)
+ {
+ Evas_BiDi_Direction parent_dir = EVAS_BIDI_DIRECTION_NEUTRAL;
+
+ if (obj->smart.parent)
+ parent_dir = evas_object_paragraph_direction_get(obj->smart.parent);
+
+ if (parent_dir != o->paragraph_direction)
+ {
+ o->paragraph_direction = parent_dir;
+ o->changed_paragraph_direction = EINA_TRUE;
+ }
+ }
+
+ if (o->changed_paragraph_direction)
+ {
+ _evas_object_text_recalc(eo_obj, o->cur.text);
+ evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
+ eo_obj, obj);
+ }
+#endif
+
return o->bidi_dir;
}
o->prev = o->cur;
#ifdef BIDI_SUPPORT
o->bidi_par_props = evas_bidi_paragraph_props_new();
+ o->inherit_paragraph_direction = EINA_TRUE;
#endif
eo_do(eo_obj, evas_filter_constructor());
obj->cur->clipper,
obj->cur->clipper->private_data);
}
+
+#ifdef BIDI_SUPPORT
+ if (o->inherit_paragraph_direction)
+ {
+ Evas_BiDi_Direction parent_dir = EVAS_BIDI_DIRECTION_NEUTRAL;
+
+ if (obj->smart.parent)
+ parent_dir = evas_object_paragraph_direction_get(obj->smart.parent);
+
+ if (parent_dir != o->paragraph_direction)
+ {
+ o->paragraph_direction = parent_dir;
+ o->changed_paragraph_direction = EINA_TRUE;
+ }
+ }
+#endif
+
/* If object size changed and ellipsis is set */
if (((o->cur.ellipsis >= 0.0 ||
o->cur.ellipsis != o->prev.ellipsis) &&
((obj->cur->geometry.w != o->last_computed.w) ||
(obj->cur->geometry.h != o->last_computed.h))) ||
- (obj->cur->scale != obj->prev->scale))
+ (obj->cur->scale != obj->prev->scale) ||
+ (o->changed_paragraph_direction))
{
_evas_object_text_recalc(eo_obj, o->cur.text);
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
}
o->last_computed.w = obj->cur->geometry.w;
o->last_computed.h = obj->cur->geometry.h;
+#ifdef BIDI_SUPPORT
+ o->changed_paragraph_direction = EINA_FALSE;
+#endif
}
EAPI void
eo_do(obj, efl_gfx_filter_source_set(name, (Efl_Gfx_Base *)eo_source));
}
+EOLIAN static void
+_evas_text_evas_object_paragraph_direction_set(Eo *eo_obj, Evas_Text_Data *o, Evas_BiDi_Direction dir)
+{
+#ifdef BIDI_SUPPORT
+ Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
+
+ if ((!(o->inherit_paragraph_direction) && (o->paragraph_direction == dir)) ||
+ (o->inherit_paragraph_direction && (dir == EVAS_BIDI_DIRECTION_INHERIT)))
+ return;
+
+ if (dir == EVAS_BIDI_DIRECTION_INHERIT)
+ {
+ o->inherit_paragraph_direction = EINA_TRUE;
+ Evas_BiDi_Direction parent_dir = EVAS_BIDI_DIRECTION_NEUTRAL;
+
+ if (obj->smart.parent)
+ parent_dir = evas_object_paragraph_direction_get(obj->smart.parent);
+
+ if (parent_dir != o->paragraph_direction)
+ {
+ o->paragraph_direction = parent_dir;
+ o->changed_paragraph_direction = EINA_TRUE;
+ evas_object_change(eo_obj, obj);
+ }
+ }
+ else
+ {
+ o->inherit_paragraph_direction = EINA_FALSE;
+ o->paragraph_direction = dir;
+ o->changed_paragraph_direction = EINA_TRUE;
+ evas_object_change(eo_obj, obj);
+ }
+#else
+ (void) eo_obj;
+ (void) o;
+ (void) dir;
+#endif
+}
+
+EOLIAN static Evas_BiDi_Direction
+_evas_text_evas_object_paragraph_direction_get(Eo *eo_obj EINA_UNUSED,
+ Evas_Text_Data *o)
+{
+ return o->paragraph_direction;
+}
+
#include "canvas/evas_text.eo.c"
void *engine_data;
const char *repch;
const char *bidi_delimiters;
+ Evas_BiDi_Direction paragraph_direction : 2;
struct {
int w, h, oneline_h;
Eina_Bool valid : 1;
Eina_Bool have_ellipsis : 1;
Eina_Bool hyphenating : 1;
Eina_Bool legacy_newline : 1;
+ Eina_Bool inherit_paragraph_direction : 1;
+ Eina_Bool changed_paragraph_direction : 1;
};
struct _Evas_Textblock_Selection_Iterator
{
const Eina_Unicode *text;
int *segment_idxs = NULL;
+ Evas_BiDi_Direction par_dir;
+ EvasBiDiParType bidi_par_type;
+
text = eina_ustrbuf_string_get(par->text_node->unicode);
if (o->bidi_delimiters)
segment_idxs = evas_bidi_segment_idxs_get(text, o->bidi_delimiters);
+ par_dir = o->paragraph_direction;
+
+ switch (par_dir)
+ {
+ case EVAS_BIDI_DIRECTION_LTR:
+ bidi_par_type = EVAS_BIDI_PARAGRAPH_LTR;
+ break;
+ case EVAS_BIDI_DIRECTION_RTL:
+ bidi_par_type = EVAS_BIDI_PARAGRAPH_RTL;
+ break;
+ case EVAS_BIDI_DIRECTION_NEUTRAL:
+ default:
+ bidi_par_type = EVAS_BIDI_PARAGRAPH_NEUTRAL;
+ break;
+ }
+
evas_bidi_paragraph_props_unref(par->bidi_props);
par->bidi_props = evas_bidi_paragraph_props_get(text,
eina_ustrbuf_length_get(par->text_node->unicode),
- segment_idxs);
+ segment_idxs, bidi_par_type);
par->direction = EVAS_BIDI_PARAGRAPH_DIRECTION_IS_RTL(par->bidi_props) ?
EVAS_BIDI_DIRECTION_RTL : EVAS_BIDI_DIRECTION_LTR;
par->is_bidi = !!par->bidi_props;
o->content_changed = 0;
o->format_changed = EINA_FALSE;
o->redraw = 1;
+#ifdef BIDI_SUPPORT
+ o->changed_paragraph_direction = EINA_FALSE;
+#endif
}
/*
evas_object_textblock_text_markup_set(eo_obj, "");
o->legacy_newline = EINA_TRUE;
+#ifdef BIDI_SUPPORT
+ o->inherit_paragraph_direction = EINA_TRUE;
+#endif
}
EOLIAN static void
}
static void
-evas_object_textblock_coords_recalc(Evas_Object *eo_obj EINA_UNUSED,
+evas_object_textblock_coords_recalc(Evas_Object *eo_obj,
Evas_Object_Protected_Data *obj,
void *type_private_data)
{
Evas_Textblock_Data *o = type_private_data;
+#ifdef BIDI_SUPPORT
+ if (o->inherit_paragraph_direction)
+ {
+ Evas_BiDi_Direction parent_dir = EVAS_BIDI_DIRECTION_NEUTRAL;
+
+ if (obj->smart.parent)
+ {
+ parent_dir = evas_object_paragraph_direction_get(obj->smart.parent);
+ }
+
+ if (parent_dir != o->paragraph_direction)
+ {
+ o->paragraph_direction = parent_dir;
+ o->changed_paragraph_direction = EINA_TRUE;
+ }
+ }
+#endif
+
if (
// width changed thus we may have to re-wrap or change centering etc.
(obj->cur->geometry.w != o->last_w) ||
(o->content_changed) ||
// if format changed (eg styles) we need to re-format/match tags etc.
(o->format_changed) ||
- (o->obstacle_changed)
+ (o->obstacle_changed) ||
+ (o->changed_paragraph_direction)
)
{
- LYDBG("ZZ: invalidate 2 %p ## %i != %i || %3.3f || %i && %i != %i | %i %i\n", eo_obj, obj->cur->geometry.w, o->last_w, o->valign, o->have_ellipsis, obj->cur->geometry.h, o->last_h, o->content_changed, o->format_changed);
+ LYDBG("ZZ: invalidate 2 %p ## %i != %i || %3.3f || %i && %i != %i | %i %i || %d\n", eo_obj, obj->cur->geometry.w, o->last_w, o->valign, o->have_ellipsis, obj->cur->geometry.h, o->last_h, o->content_changed, o->format_changed, o->changed_paragraph_direction);
+
+ if (o->changed_paragraph_direction)
+ {
+ _evas_textblock_invalidate_all(o);
+ _evas_textblock_changed(o, eo_obj);
+ }
+
o->formatted.valid = 0;
o->changed = 1;
}
_evas_textblock_changed(o, eo_obj);
}
+EOLIAN static void
+_evas_textblock_evas_object_paragraph_direction_set(Eo *eo_obj,
+ Evas_Textblock_Data *o,
+ Evas_BiDi_Direction dir)
+{
+#ifdef BIDI_SUPPORT
+ Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
+
+ if ((!(o->inherit_paragraph_direction) && (o->paragraph_direction == dir)) ||
+ (o->inherit_paragraph_direction && (dir == EVAS_BIDI_DIRECTION_INHERIT)))
+ return;
+
+ if (dir == EVAS_BIDI_DIRECTION_INHERIT)
+ {
+ o->inherit_paragraph_direction = EINA_TRUE;
+ Evas_BiDi_Direction parent_dir = EVAS_BIDI_DIRECTION_NEUTRAL;
+
+ if (obj->smart.parent)
+ parent_dir = evas_object_paragraph_direction_get(obj->smart.parent);
+
+ if (parent_dir != o->paragraph_direction)
+ {
+ o->paragraph_direction = parent_dir;
+ o->changed_paragraph_direction = EINA_TRUE;
+ _evas_textblock_invalidate_all(o);
+ _evas_textblock_changed(o, eo_obj);
+ }
+ }
+ else
+ {
+ o->inherit_paragraph_direction = EINA_FALSE;
+ o->paragraph_direction = dir;
+ o->changed_paragraph_direction = EINA_TRUE;
+ _evas_textblock_invalidate_all(o);
+ _evas_textblock_changed(o, eo_obj);
+ }
+#else
+ (void) eo_obj;
+ (void) o;
+ (void) dir;
+#endif
+}
+
+EOLIAN static Evas_BiDi_Direction
+_evas_textblock_evas_object_paragraph_direction_get(Eo *eo_obj EINA_UNUSED,
+ Evas_Textblock_Data *o)
+{
+ return o->paragraph_direction;
+}
+
/**
* @}
*/
Evas.Filter.input_alpha;
Evas.Filter.input_render;
Evas.Filter.dirty;
+ Evas.Object.paragraph_direction.set;
+ Evas.Object.paragraph_direction.get;
}
}
Eo.Base.constructor;
Eo.Base.destructor;
Eo.Base.dbg_info_get;
+ Evas.Object.paragraph_direction.set;
+ Evas.Object.paragraph_direction.get;
}
}
natural = 0,
neutral = 0,
ltr,
- rtl
+ rtl,
+ inherit
}
enum Evas.Text_Style_Type {
* @param ustr The string to update according to.
* @param len The length of the string
* @param segment_idxs A -1 terminated array of points to start a new bidi analysis at (used for section high level bidi overrides). - NULL means none.
+ * @param base_bidi The base BiDi direction of paragraph.
* @return returns allocated paragraph props on success, NULL otherwise.
*/
Evas_BiDi_Paragraph_Props *
evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr, size_t len,
- int *segment_idxs)
+ int *segment_idxs, EvasBiDiParType base_bidi)
{
Evas_BiDi_Paragraph_Props *bidi_props = NULL;
EvasBiDiCharType *char_types = NULL;
if (!eina_ustr)
return NULL;
-
- if (!evas_bidi_is_rtl_str(eina_ustr)) /* No need to handle bidi */
+ /* No need to handle bidi */
+ if (!evas_bidi_is_rtl_str(eina_ustr) &&
+ (base_bidi != EVAS_BIDI_PARAGRAPH_RTL))
{
len = -1;
goto cleanup;
#endif
bidi_props = evas_bidi_paragraph_props_new();
+ bidi_props->direction = base_bidi;
/* Prep work for reordering */
char_types = (EvasBiDiCharType *) malloc(sizeof(EvasBiDiCharType) * len);
for (itr = segment_idxs ; *itr > 0 ; itr++)
{
- direction = EVAS_BIDI_PARAGRAPH_NEUTRAL;
+ direction = base_bidi;
if (!fribidi_get_par_embedding_levels(char_types + pos,
*itr - pos,
&direction,
pos = *itr + 1;
}
- direction = EVAS_BIDI_PARAGRAPH_NEUTRAL;
+ direction = base_bidi;
if (!fribidi_get_par_embedding_levels(char_types + pos,
len - pos,
&direction,
evas_bidi_props_reorder_line(Eina_Unicode *eina_ustr, size_t start, size_t len, const Evas_BiDi_Paragraph_Props *props, EvasBiDiStrIndex **_v_to_l);
Evas_BiDi_Paragraph_Props *
-evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr, size_t len, int *segment_idxs) EINA_ARG_NONNULL(1) EINA_MALLOC EINA_WARN_UNUSED_RESULT;
+evas_bidi_paragraph_props_get(const Eina_Unicode *eina_ustr, size_t len, int *segment_idxs, EvasBiDiParType base_bidi) EINA_ARG_NONNULL(1) EINA_MALLOC EINA_WARN_UNUSED_RESULT;
void
evas_bidi_props_copy_and_ref(const Evas_BiDi_Props *src, Evas_BiDi_Props *dst);
{ "Meshes", evas_test_mesh },
{ "Masking", evas_test_mask },
{ "Evas GL", evas_test_evasgl },
+ { "Object Smart", evas_test_object_smart },
{ NULL, NULL }
};
void evas_test_mesh(TCase *tc);
void evas_test_mask(TCase *tc);
void evas_test_evasgl(TCase *tc);
+void evas_test_object_smart(TCase *tc);
#endif /* _EVAS_SUITE_H */
--- /dev/null
+/*
+ * TODO:
+ * * Test different font lodaing mechanisms.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <Eina.h>
+
+#include "evas_suite.h"
+#include "Evas.h"
+#include "evas_tests_helpers.h"
+
+#define TEST_FONT_SOURCE TESTS_SRC_DIR "/TestFont.eet"
+#define TEST_TEXTBLOCK_FONT "font=DejaVuSans font_source=" TEST_FONT_SOURCE
+#define TEST_TEXTBLOCK_FONT_SIZE "14"
+#define TEST_TEXT_FONT "DejaVuSans,UnDotum"
+#define TEST_TEXT_FONT_SIZE 14
+
+static const char *style_buf =
+ "DEFAULT='" TEST_TEXTBLOCK_FONT " font_size="TEST_TEXTBLOCK_FONT_SIZE" color=#000 text_class=entry'"
+ "newline='br'"
+ "b='+ font_weight=bold'";
+
+#define START_EVAS_OBJECT_SMART_TEST() \
+ Evas *evas; \
+ Evas_Object *smart_obj; \
+ evas = EVAS_TEST_INIT_EVAS(); \
+ smart_obj = evas_object_box_add(evas); \
+ fail_if(!smart_obj); \
+do \
+{ \
+} \
+while (0)
+
+#define END_EVAS_OBJECT_SMART_TEST() \
+do \
+{ \
+ evas_object_del(smart_obj); \
+ evas_free(evas); \
+ evas_shutdown(); \
+} \
+while (0)
+
+#define ADD_EVAS_TEXTBLOCK() \
+ Evas_Object *tb; \
+ Evas_Textblock_Style *st; \
+ Evas_Textblock_Cursor *cur; \
+ evas_font_hinting_set(evas, EVAS_FONT_HINTING_AUTO); \
+ tb = evas_object_textblock_add(evas); \
+ fail_if(!tb); \
+ evas_object_textblock_legacy_newline_set(tb, EINA_FALSE); \
+ st = evas_textblock_style_new(); \
+ fail_if(!st); \
+ evas_textblock_style_set(st, style_buf); \
+ fail_if(strcmp(style_buf, evas_textblock_style_get(st))); \
+ evas_object_textblock_style_set(tb, st); \
+ cur = evas_object_textblock_cursor_new(tb); \
+do \
+{ \
+} \
+while (0)
+
+#define ADD_EVAS_TEXT() \
+ Evas_Object *to; \
+ evas_font_hinting_set(evas, EVAS_FONT_HINTING_AUTO); \
+ to = evas_object_text_add(evas); \
+ fail_if(!to); \
+ evas_object_text_font_source_set(to, TEST_FONT_SOURCE); \
+ evas_object_text_font_set(to, TEST_TEXT_FONT, TEST_TEXT_FONT_SIZE); \
+do \
+{ \
+} \
+while (0)
+
+#define DELETE_EVAS_TEXTBLOCK() \
+do \
+{ \
+ evas_textblock_cursor_free(cur); \
+ evas_object_del(tb); \
+ evas_textblock_style_free(st); \
+} \
+while (0)
+
+#define DELETE_EVAS_TEXT() \
+do \
+{ \
+ evas_object_del(to); \
+} \
+while (0)
+
+START_TEST(evas_object_smart_paragraph_direction)
+{
+ START_EVAS_OBJECT_SMART_TEST();
+
+ ADD_EVAS_TEXTBLOCK();
+ evas_object_resize(tb, 500, 500);
+ evas_object_textblock_text_markup_set(tb, "%^&");
+ fail_if(strcmp(evas_object_textblock_text_markup_get(tb), "%^&"));
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_INHERIT);
+
+ ADD_EVAS_TEXT();
+ evas_object_text_text_set(to, "%^&");
+ fail_if(strcmp(evas_object_text_text_get(to), "%^&"));
+ evas_object_paragraph_direction_set(to, EVAS_BIDI_DIRECTION_INHERIT);
+
+ /* Test evas_object_paragraph_direction_set API with smart objects. */
+ Evas_Object *smart_child = evas_object_box_add(evas);
+ Evas_BiDi_Direction dir;
+ Evas_Coord x, y, w, h;
+ Evas_Coord xx, yy, ww, hh;
+
+ evas_object_smart_member_add(smart_child, smart_obj);
+ evas_object_smart_member_add(tb, smart_child);
+ evas_object_smart_member_add(to, smart_child);
+
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &x, &y, &w, &h, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ fail_if(evas_object_text_direction_get(to) == EVAS_BIDI_DIRECTION_RTL);
+
+ /* Change paragraph direction of smart parent object */
+ evas_object_paragraph_direction_set(smart_obj, EVAS_BIDI_DIRECTION_RTL);
+ dir = EVAS_BIDI_DIRECTION_LTR;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir != EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x >= xx) || (y != yy) || (w != ww) || (h != hh));
+ fail_if(evas_object_text_direction_get(to) != EVAS_BIDI_DIRECTION_RTL);
+
+ /* The paragraph direction of smart member object has to be reset
+ if smart member object is removed from smart parent. */
+ evas_object_smart_member_del(smart_child);
+
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &x, &y, &w, &h, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x >= xx) || (y != yy) || (w != ww) || (h != hh));
+ fail_if(evas_object_text_direction_get(to) == EVAS_BIDI_DIRECTION_RTL);
+
+ /* The paragraph direction of smart member object has to be changed
+ if smart member object is appended to smart parent. */
+ evas_object_smart_member_add(smart_child, smart_obj);
+
+ dir = EVAS_BIDI_DIRECTION_LTR;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir != EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x >= xx) || (y != yy) || (w != ww) || (h != hh));
+ fail_if(evas_object_text_direction_get(to) != EVAS_BIDI_DIRECTION_RTL);
+
+ /* Ignore smart parent's paragraph direction */
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_NEUTRAL);
+ evas_object_paragraph_direction_set(to, EVAS_BIDI_DIRECTION_NEUTRAL);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &x, &y, &w, &h, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x >= xx) || (y != yy) || (w != ww) || (h != hh));
+ fail_if(evas_object_text_direction_get(to) == EVAS_BIDI_DIRECTION_RTL);
+
+ evas_object_smart_member_del(tb);
+ evas_object_smart_member_del(to);
+ evas_object_del(smart_child);
+
+ DELETE_EVAS_TEXTBLOCK();
+ DELETE_EVAS_TEXT();
+ END_EVAS_OBJECT_SMART_TEST();
+}
+END_TEST
+
+void evas_test_object_smart(TCase *tc)
+{
+ tcase_add_test(tc, evas_object_smart_paragraph_direction);
+}
fail_if(evas_object_text_direction_get(to) != EVAS_BIDI_DIRECTION_LTR);
#endif
+#ifdef HAVE_FRIBIDI
+ /* Check direction with evas_object_paragraph_direction_set API */
+ evas_object_text_text_set(to, "12345");
+ fail_if(evas_object_text_direction_get(to) == EVAS_BIDI_DIRECTION_RTL);
+ evas_object_paragraph_direction_set(to, EVAS_BIDI_DIRECTION_RTL);
+ fail_if(evas_object_text_direction_get(to) != EVAS_BIDI_DIRECTION_RTL);
+ evas_object_paragraph_direction_set(to, EVAS_BIDI_DIRECTION_NEUTRAL);
+#endif
+
END_TEXT_TEST();
}
END_TEST
fail_if(evas_textblock_cursor_compare(main_cur, cur));
}
+#ifdef HAVE_FRIBIDI
/* Check direction */
evas_object_textblock_text_markup_set(tb, "test");
fail_if(strcmp(evas_object_textblock_text_markup_get(tb), "test"));
evas_textblock_cursor_geometry_get(cur, NULL, NULL, NULL, NULL, &dir,
EVAS_TEXTBLOCK_CURSOR_BEFORE);
fail_if(dir != EVAS_BIDI_DIRECTION_RTL);
+ evas_object_textblock_text_markup_set(tb, "123");
+ fail_if(strcmp(evas_object_textblock_text_markup_get(tb), "123"));
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, NULL, NULL, NULL, NULL, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir != EVAS_BIDI_DIRECTION_LTR);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, NULL, NULL, NULL, NULL, &dir,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE);
+ fail_if(dir != EVAS_BIDI_DIRECTION_LTR);
+ evas_object_textblock_text_markup_set(tb, "%^&");
+ fail_if(strcmp(evas_object_textblock_text_markup_get(tb), "%^&"));
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, NULL, NULL, NULL, NULL, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir != EVAS_BIDI_DIRECTION_LTR);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, NULL, NULL, NULL, NULL, &dir,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE);
+ fail_if(dir != EVAS_BIDI_DIRECTION_LTR);
+
+ /* Check direction with evas_object_paragraph_direction_set API */
+ {
+ Evas_Coord xx, yy, ww, hh;
+
+ /* LTR text case */
+ evas_object_textblock_text_markup_set(tb, "test");
+ fail_if(strcmp(evas_object_textblock_text_markup_get(tb), "test"));
+
+ /* EVAS_TEXTBLOCK_CURSOR_UNDER */
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_NEUTRAL);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &x, &y, &w, &h, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_RTL);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x >= xx) || (y != yy) || (w != ww) || (h != hh));
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_LTR);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x != xx) || (y != yy) || (w != ww) || (h != hh));
+
+ /* EVAS_TEXTBLOCK_CURSOR_BEFORE */
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_NEUTRAL);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &x, &y, &w, &h, &dir,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_RTL);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x >= xx) || (y != yy) || (w != ww) || (h != hh));
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_LTR);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x != xx) || (y != yy) || (w != ww) || (h != hh));
+
+ /* RTL text case */
+ evas_object_textblock_text_markup_set(tb, "עוד פסקה");
+ fail_if(strcmp(evas_object_textblock_text_markup_get(tb), "עוד פסקה"));
+
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_NEUTRAL);
+ dir = EVAS_BIDI_DIRECTION_LTR;
+ evas_textblock_cursor_geometry_get(cur, &x, &y, &w, &h, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir != EVAS_BIDI_DIRECTION_RTL);
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_LTR);
+ dir = EVAS_BIDI_DIRECTION_LTR;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir != EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x <= xx) || (y != yy) || (w != ww) || (h != hh));
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_RTL);
+ dir = EVAS_BIDI_DIRECTION_LTR;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir != EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x != xx) || (y != yy) || (w != ww) || (h != hh));
+
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_NEUTRAL);
+ dir = EVAS_BIDI_DIRECTION_LTR;
+ evas_textblock_cursor_geometry_get(cur, &x, &y, &w, &h, &dir,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE);
+ fail_if(dir != EVAS_BIDI_DIRECTION_RTL);
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_LTR);
+ dir = EVAS_BIDI_DIRECTION_LTR;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE);
+ fail_if(dir != EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x <= xx) || (y != yy) || (w != ww) || (h != hh));
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_RTL);
+ dir = EVAS_BIDI_DIRECTION_LTR;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE);
+ fail_if(dir != EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x != xx) || (y != yy) || (w != ww) || (h != hh));
+
+ /* NEUTRAL(European Number) text case */
+ /* It doesn't change characters sequence. */
+ evas_object_textblock_text_markup_set(tb, "123");
+ fail_if(strcmp(evas_object_textblock_text_markup_get(tb), "123"));
+
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_NEUTRAL);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &x, &y, &w, &h, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_RTL);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x >= xx) || (y != yy) || (w != ww) || (h != hh));
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_LTR);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x != xx) || (y != yy) || (w != ww) || (h != hh));
+
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_NEUTRAL);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &x, &y, &w, &h, &dir,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_RTL);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x >= xx) || (y != yy) || (w != ww) || (h != hh));
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_LTR);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x != xx) || (y != yy) || (w != ww) || (h != hh));
+
+ /* NEUTRAL(Other Neutrals) text case */
+ /* It changes characters sequence. */
+ evas_object_textblock_text_markup_set(tb, "%^&");
+ fail_if(strcmp(evas_object_textblock_text_markup_get(tb), "%^&"));
+
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_NEUTRAL);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &x, &y, &w, &h, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_RTL);
+ dir = EVAS_BIDI_DIRECTION_LTR;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir != EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x >= xx) || (y != yy) || (w != ww) || (h != hh));
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_LTR);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_UNDER);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x != xx) || (y != yy) || (w != ww) || (h != hh));
+
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_NEUTRAL);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &x, &y, &w, &h, &dir,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_RTL);
+ dir = EVAS_BIDI_DIRECTION_LTR;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE);
+ fail_if(dir != EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x >= xx) || (y != yy) || (w != ww) || (h != hh));
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_LTR);
+ dir = EVAS_BIDI_DIRECTION_RTL;
+ evas_textblock_cursor_geometry_get(cur, &xx, &yy, &ww, &hh, &dir,
+ EVAS_TEXTBLOCK_CURSOR_BEFORE);
+ fail_if(dir == EVAS_BIDI_DIRECTION_RTL);
+ fail_if((x != xx) || (y != yy) || (w != ww) || (h != hh));
+
+ /* Reset paragraph direction */
+ evas_object_paragraph_direction_set(tb, EVAS_BIDI_DIRECTION_NEUTRAL);
+ }
-#ifdef HAVE_FRIBIDI
evas_object_textblock_text_markup_set(tb,
"testנסיוןtestנסיון<ps/>"
"נסיוןtestנסיוןtest<ps/>"