2016-06-09 23:55:28 -07:00
|
|
|
#define EFL_CANVAS_FILTER_INTERNAL_PROTECTED
|
2015-06-23 01:25:44 -07:00
|
|
|
|
2013-06-20 03:53:29 -07:00
|
|
|
#include "evas_common_private.h" /* Includes evas_bidi_utils stuff. */
|
2002-11-08 00:02:15 -08:00
|
|
|
#include "evas_private.h"
|
2015-06-17 00:26:30 -07:00
|
|
|
|
|
|
|
#include "../efl/interfaces/efl_gfx_filter.eo.h"
|
2016-06-09 23:55:28 -07:00
|
|
|
#include "efl_canvas_filter_internal.eo.h"
|
2013-12-09 03:55:38 -08:00
|
|
|
#include "evas_filter.h"
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2014-06-02 06:47:59 -07:00
|
|
|
#define MY_CLASS EVAS_TEXT_CLASS
|
2012-10-08 18:58:41 -07:00
|
|
|
|
2013-11-07 03:16:01 -08:00
|
|
|
#define MY_CLASS_NAME "Evas_Text"
|
2013-01-28 22:36:23 -08:00
|
|
|
|
2014-01-16 18:19:02 -08:00
|
|
|
#ifdef EVAS_CSERVE2
|
|
|
|
# include "evas_cs2_private.h"
|
|
|
|
#endif
|
|
|
|
|
2005-11-26 00:04:20 -08:00
|
|
|
/* save typing */
|
2015-05-26 03:37:21 -07:00
|
|
|
#define COL_OBJECT(obj, sub) ARGB_JOIN(obj->sub->color.a, obj->sub->color.r, obj->sub->color.g, obj->sub->color.b)
|
|
|
|
#define COL_JOIN(o, sub, color) ARGB_JOIN(o->sub.color.a, o->sub.color.r, o->sub.color.g, o->sub.color.b)
|
2005-11-26 00:04:20 -08:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
/* private magic number for text objects */
|
|
|
|
static const char o_type[] = "text";
|
|
|
|
|
|
|
|
/* private struct for text object internal data */
|
2014-03-09 00:31:28 -08:00
|
|
|
typedef struct _Evas_Text_Data Evas_Text_Data;
|
2011-01-30 02:36:02 -08:00
|
|
|
typedef struct _Evas_Object_Text_Item Evas_Object_Text_Item;
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
struct _Evas_Text_Data
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2005-11-26 00:04:20 -08:00
|
|
|
DATA32 magic;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
struct {
|
remove memcmp calls for better performance where size is known
so i have been doing some profiling on my rpi3 ... and it seems
memcmp() is like the number one top used function - especially running
e in wayland compositor mode. it uses accoring to perf top about 9-15%
of samples (samples are not adding up to 100%). no - i cant seem to
get a call graph because all that happens is the whole kernel locks up
solid if i try, so i can only get the leaf node call stats. what
function was currently active at the sample time. memcmp is the
biggest by far. 2-3 times anything else.
13.47% libarmmem.so [.] memcmp
6.43% libevas.so.1.18.99 [.] _evas_render_phase1_object_pro
4.74% libevas.so.1.18.99 [.] evas_render_updates_internal.c
2.84% libeo.so.1.18.99 [.] _eo_obj_pointer_get
2.49% libevas.so.1.18.99 [.] evas_render_updates_internal_l
2.03% libpthread-2.24.so [.] pthread_getspecific
1.61% libeo.so.1.18.99 [.] efl_data_scope_get
1.60% libevas.so.1.18.99 [.] _evas_event_object_list_raw_in
1.54% libevas.so.1.18.99 [.] evas_object_smart_changed_get
1.32% libgcc_s.so.1 [.] __udivsi3
1.21% libevas.so.1.18.99 [.] evas_object_is_active
1.14% libc-2.24.so [.] malloc
0.96% libevas.so.1.18.99 [.] evas_render_mapped
0.85% libeo.so.1.18.99 [.] efl_isa
yeah. it's perf. it's sampling so not 100% accurate, but close to
"good enough" for the bigger stuff. so interestingly memcmp() is
actually in a special library/module (libarmmem.so) and is a REAL
function call. so doing memcmp's for small bits of memory ESPECIALLY
when we know their size in advance is not great. i am not sure our own
use of memcmp() is the actual culprit because even with this patch
memcmp still is right up there. we use it for stringshare which is
harder to remove as stringshare has variable sized memory blobs to
compare.
but the point remains - memcmp() is an ACTUAL function call. even on
x86 (i checked the assembly). and replacing it with a static inline
custom comparer is better. in fact i did that and benchmarked it as a
sample case for eina_tiler which has 4 ints (16 bytes) to compare
every time. i also compiled to assembly on x86 to inspect and make sure
things made sense.
the text color compare was just comparing 4 bytes as a color (an int
worth) which was silly to use memcmp on as it could just cast to an
int and do a == b. the map was a little more evil as it was 2 ptrs
plus 2 bitfields, but the way bitfields work means i can assume the
last byte is both bitfields combined. i can be a little more evil for
the rect tests as 4 ints compared is the same as comparing 2 long
longs (64bit types). yes. don't get pedantic. all platforms efl works
on work this way and this is a base assumption in efl and it's true
everywhere worth talking about.
yes - i tried __int128 too. it was not faster on x86 anyway and can't
compile on armv7. in my speed tests on x86-64, comparing 2 rects by
casting to a struct of 2 long long's and comparing just those is 70%
faster than comapring 4 ints. and the 2 long longs is 360% faster than
a memcmp. on arm (my rpi3) the long long is 12% faster than the 4 ints,
and it is 226% faster than a memcmp().
it'd be best if we didnt even have to compare at all, but with these
algorithms we do, so doing it faster is better.
we probably should nuke all the memcmp's we have that are not of large
bits of memory or variable sized bits of memory.
i set breakpoints for memcmp and found at least a chunk in efl. but
also it seems the vc4 driver was also doing it too. i have no idea how
much memory it was doing this to and it may ultimately be the biggest
culprit here, BUT we may as well reduce our overhead since i've found
this anyway. less "false positives" when hunting problems.
why am i doing this? i'm setting framerate hiccups. eg like we drop 3,
5 or 10 frames, then drop another bunch, then go back to smooth, then
this hiccup again. finding out WHAT is causing that hiccup is hard. i
can only SEE the hiccups on my rpi3 - not on x86. i am not so sure
it's cpufreq bouncing about as i've locked cpu to 600mhz and it still
happens. it's something else. maybe something we are polling? maybe
it's something in our drm/kms backend? maybe its in the vc4 drivers or
kernel parts? i have no idea. trying to hunt this is hard, but this is
important as this is something that possibly is affecting everyone but
other hw is fast enough to hide it...
in the meantime find and optimize what i find along the way.
@optimize
2016-11-05 20:30:13 -07:00
|
|
|
// WARNING - you cannot change the below outline/shadow etc. members
|
|
|
|
// and their content without also updating _color_same() in this
|
|
|
|
// file
|
2013-03-12 03:01:32 -07:00
|
|
|
struct {
|
2015-11-17 03:22:17 -08:00
|
|
|
unsigned char r, g, b, a;
|
2013-03-12 03:01:32 -07:00
|
|
|
} outline, shadow, glow, glow2;
|
|
|
|
|
2010-07-28 05:00:41 -07:00
|
|
|
const char *utf8_text; /* The text exposed to the API */
|
|
|
|
const char *font;
|
2011-08-01 01:20:52 -07:00
|
|
|
Evas_Font_Description *fdesc;
|
2010-07-28 05:00:41 -07:00
|
|
|
const char *source;
|
2013-03-12 03:01:32 -07:00
|
|
|
Eina_Unicode *text;
|
2005-11-26 00:04:20 -08:00
|
|
|
|
2012-12-12 06:05:29 -08:00
|
|
|
double ellipsis;
|
2013-03-12 03:01:32 -07:00
|
|
|
|
|
|
|
Evas_Font_Size size;
|
2013-12-09 03:55:38 -08:00
|
|
|
Evas_Text_Style_Type style;
|
2017-09-25 02:34:22 -07:00
|
|
|
Efl_Text_Font_Bitmap_Scalable bitmap_scalable;
|
2002-11-08 00:02:15 -08:00
|
|
|
} cur, prev;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2013-03-12 03:01:32 -07:00
|
|
|
struct {
|
|
|
|
Evas_Object_Text_Item *ellipsis_start;
|
|
|
|
Evas_Object_Text_Item *ellipsis_end;
|
|
|
|
Evas_Coord w, h;
|
2013-09-30 23:29:38 -07:00
|
|
|
int advance;
|
2015-12-08 23:50:33 -08:00
|
|
|
int width_without_ellipsis;
|
2013-10-01 04:34:03 -07:00
|
|
|
Eina_Bool ellipsis;
|
2013-03-12 03:01:32 -07:00
|
|
|
} last_computed;
|
|
|
|
|
2011-01-30 02:36:02 -08:00
|
|
|
Evas_BiDi_Paragraph_Props *bidi_par_props;
|
2011-04-14 08:34:01 -07:00
|
|
|
const char *bidi_delimiters;
|
2011-01-30 02:36:02 -08:00
|
|
|
Evas_Object_Text_Item *items;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2011-05-29 06:00:54 -07:00
|
|
|
Evas_Font_Set *font;
|
2009-09-03 22:13:19 -07:00
|
|
|
|
2013-03-12 03:01:32 -07:00
|
|
|
float ascent, descent;
|
|
|
|
float max_ascent, max_descent;
|
2012-12-12 21:12:14 -08:00
|
|
|
|
2013-02-21 05:39:37 -08:00
|
|
|
Evas_BiDi_Direction bidi_dir : 2;
|
2015-11-19 03:37:07 -08:00
|
|
|
Evas_BiDi_Direction paragraph_direction : 2;
|
|
|
|
Eina_Bool inherit_paragraph_direction : 1;
|
|
|
|
Eina_Bool changed_paragraph_direction : 1;
|
2015-11-12 07:43:43 -08:00
|
|
|
Eina_Bool changed : 1;
|
|
|
|
Eina_Bool has_filter : 1;
|
2011-01-30 02:36:02 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
struct _Evas_Object_Text_Item
|
|
|
|
{
|
|
|
|
EINA_INLIST;
|
|
|
|
|
|
|
|
size_t text_pos;
|
|
|
|
size_t visual_pos;
|
2011-01-30 02:36:39 -08:00
|
|
|
Evas_Text_Props text_props;
|
2011-01-30 02:36:02 -08:00
|
|
|
Evas_Coord x, w, h, adv;
|
2002-11-08 00:02:15 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
/* private methods for text objects */
|
2012-10-08 18:58:41 -07:00
|
|
|
static void evas_object_text_init(Evas_Object *eo_obj);
|
2013-07-08 17:46:15 -07:00
|
|
|
static void evas_object_text_render(Evas_Object *eo_obj,
|
2017-05-12 15:03:05 -07:00
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
void *type_private_data,
|
|
|
|
void *engine, void *output, void *context, void *surface,
|
|
|
|
int x, int y, Eina_Bool do_async);
|
2013-07-08 17:46:15 -07:00
|
|
|
static void evas_object_text_free(Evas_Object *eo_obj,
|
|
|
|
Evas_Object_Protected_Data *obj);
|
|
|
|
static void evas_object_text_render_pre(Evas_Object *eo_obj,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
void *type_private_data);
|
|
|
|
static void evas_object_text_render_post(Evas_Object *eo_obj,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
void *type_private_data);
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
static unsigned int evas_object_text_id_get(Evas_Object *eo_obj);
|
|
|
|
static unsigned int evas_object_text_visual_id_get(Evas_Object *eo_obj);
|
|
|
|
static void *evas_object_text_engine_data_get(Evas_Object *eo_obj);
|
2008-08-25 22:45:04 -07:00
|
|
|
|
2013-07-08 17:46:15 -07:00
|
|
|
static int evas_object_text_is_opaque(Evas_Object *eo_obj,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
void *type_private_data);
|
|
|
|
static int evas_object_text_was_opaque(Evas_Object *eo_obj,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
void *type_private_data);
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2012-12-30 17:49:36 -08:00
|
|
|
static void _evas_object_text_recalc(Evas_Object *eo_obj, Eina_Unicode *text);
|
2008-11-15 02:39:46 -08:00
|
|
|
|
2007-05-06 04:29:37 -07:00
|
|
|
static const Evas_Object_Func object_func =
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
/* methods (compulsory) */
|
2012-10-08 18:58:41 -07:00
|
|
|
NULL,
|
2002-11-08 00:02:15 -08:00
|
|
|
evas_object_text_render,
|
|
|
|
evas_object_text_render_pre,
|
|
|
|
evas_object_text_render_post,
|
2008-08-30 19:04:31 -07:00
|
|
|
evas_object_text_id_get,
|
|
|
|
evas_object_text_visual_id_get,
|
2008-08-25 22:45:04 -07:00
|
|
|
evas_object_text_engine_data_get,
|
2002-11-08 00:02:15 -08:00
|
|
|
/* these are optional. NULL = nothing */
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
evas_object_text_is_opaque,
|
|
|
|
evas_object_text_was_opaque,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2008-11-15 02:39:46 -08:00
|
|
|
NULL,
|
2009-02-16 20:53:03 -08:00
|
|
|
NULL,
|
2010-08-18 08:11:07 -07:00
|
|
|
NULL,
|
2015-07-21 05:54:23 -07:00
|
|
|
NULL,
|
2016-11-14 18:22:14 -08:00
|
|
|
NULL, // render_prepare
|
2009-02-16 20:53:03 -08:00
|
|
|
NULL
|
2002-11-08 00:02:15 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
/* the actual api call to add a rect */
|
|
|
|
/* it has no other api calls as all properties are standard */
|
2003-03-04 18:30:20 -08:00
|
|
|
|
2011-01-30 02:36:02 -08:00
|
|
|
static int
|
2012-10-08 18:58:41 -07:00
|
|
|
_evas_object_text_char_coords_get(const Evas_Object *eo_obj,
|
2014-03-09 00:31:28 -08:00
|
|
|
const Evas_Text_Data *o,
|
2011-01-30 02:36:02 -08:00
|
|
|
size_t pos, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
|
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2011-01-30 02:36:02 -08:00
|
|
|
Evas_Object_Text_Item *it;
|
|
|
|
|
|
|
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
|
|
|
|
{
|
|
|
|
if ((it->text_pos <= pos) &&
|
2011-05-03 23:57:35 -07:00
|
|
|
(pos < (it->text_pos + it->text_props.text_len)))
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2011-07-12 08:04:07 -07:00
|
|
|
int ret;
|
2017-08-25 10:51:24 -07:00
|
|
|
ret = ENFN->font_char_coords_get(ENC, o->font,
|
2011-01-30 02:36:39 -08:00
|
|
|
&it->text_props, pos - it->text_pos, x, y, w, h);
|
2011-07-12 08:04:07 -07:00
|
|
|
if (x) *x += it->x;
|
|
|
|
return ret;
|
2011-01-30 02:36:02 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_evas_object_text_item_clean(Evas_Object_Text_Item *it)
|
|
|
|
{
|
2011-01-30 02:36:39 -08:00
|
|
|
evas_common_text_props_content_unref(&it->text_props);
|
2011-01-30 02:36:02 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2014-03-09 00:31:28 -08:00
|
|
|
_evas_object_text_item_del(Evas_Text_Data *o, Evas_Object_Text_Item *it)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2013-01-11 00:31:09 -08:00
|
|
|
if (o->last_computed.ellipsis_start == it)
|
|
|
|
o->last_computed.ellipsis_start = NULL;
|
|
|
|
else if (o->last_computed.ellipsis_end == it)
|
|
|
|
o->last_computed.ellipsis_end = NULL;
|
|
|
|
|
2013-11-03 03:33:05 -08:00
|
|
|
if ((EINA_INLIST_GET(it)->next) ||
|
|
|
|
(EINA_INLIST_GET(it)->prev) ||
|
2013-11-03 18:27:59 -08:00
|
|
|
(EINA_INLIST_GET(o->items) == (EINA_INLIST_GET(it))))
|
2013-11-02 03:35:45 -07:00
|
|
|
o->items = (Evas_Object_Text_Item *)eina_inlist_remove
|
|
|
|
(EINA_INLIST_GET(o->items), EINA_INLIST_GET(it));
|
2012-12-12 06:05:29 -08:00
|
|
|
_evas_object_text_item_clean(it);
|
|
|
|
free(it);
|
|
|
|
}
|
2011-01-30 02:36:02 -08:00
|
|
|
|
remove memcmp calls for better performance where size is known
so i have been doing some profiling on my rpi3 ... and it seems
memcmp() is like the number one top used function - especially running
e in wayland compositor mode. it uses accoring to perf top about 9-15%
of samples (samples are not adding up to 100%). no - i cant seem to
get a call graph because all that happens is the whole kernel locks up
solid if i try, so i can only get the leaf node call stats. what
function was currently active at the sample time. memcmp is the
biggest by far. 2-3 times anything else.
13.47% libarmmem.so [.] memcmp
6.43% libevas.so.1.18.99 [.] _evas_render_phase1_object_pro
4.74% libevas.so.1.18.99 [.] evas_render_updates_internal.c
2.84% libeo.so.1.18.99 [.] _eo_obj_pointer_get
2.49% libevas.so.1.18.99 [.] evas_render_updates_internal_l
2.03% libpthread-2.24.so [.] pthread_getspecific
1.61% libeo.so.1.18.99 [.] efl_data_scope_get
1.60% libevas.so.1.18.99 [.] _evas_event_object_list_raw_in
1.54% libevas.so.1.18.99 [.] evas_object_smart_changed_get
1.32% libgcc_s.so.1 [.] __udivsi3
1.21% libevas.so.1.18.99 [.] evas_object_is_active
1.14% libc-2.24.so [.] malloc
0.96% libevas.so.1.18.99 [.] evas_render_mapped
0.85% libeo.so.1.18.99 [.] efl_isa
yeah. it's perf. it's sampling so not 100% accurate, but close to
"good enough" for the bigger stuff. so interestingly memcmp() is
actually in a special library/module (libarmmem.so) and is a REAL
function call. so doing memcmp's for small bits of memory ESPECIALLY
when we know their size in advance is not great. i am not sure our own
use of memcmp() is the actual culprit because even with this patch
memcmp still is right up there. we use it for stringshare which is
harder to remove as stringshare has variable sized memory blobs to
compare.
but the point remains - memcmp() is an ACTUAL function call. even on
x86 (i checked the assembly). and replacing it with a static inline
custom comparer is better. in fact i did that and benchmarked it as a
sample case for eina_tiler which has 4 ints (16 bytes) to compare
every time. i also compiled to assembly on x86 to inspect and make sure
things made sense.
the text color compare was just comparing 4 bytes as a color (an int
worth) which was silly to use memcmp on as it could just cast to an
int and do a == b. the map was a little more evil as it was 2 ptrs
plus 2 bitfields, but the way bitfields work means i can assume the
last byte is both bitfields combined. i can be a little more evil for
the rect tests as 4 ints compared is the same as comparing 2 long
longs (64bit types). yes. don't get pedantic. all platforms efl works
on work this way and this is a base assumption in efl and it's true
everywhere worth talking about.
yes - i tried __int128 too. it was not faster on x86 anyway and can't
compile on armv7. in my speed tests on x86-64, comparing 2 rects by
casting to a struct of 2 long long's and comparing just those is 70%
faster than comapring 4 ints. and the 2 long longs is 360% faster than
a memcmp. on arm (my rpi3) the long long is 12% faster than the 4 ints,
and it is 226% faster than a memcmp().
it'd be best if we didnt even have to compare at all, but with these
algorithms we do, so doing it faster is better.
we probably should nuke all the memcmp's we have that are not of large
bits of memory or variable sized bits of memory.
i set breakpoints for memcmp and found at least a chunk in efl. but
also it seems the vc4 driver was also doing it too. i have no idea how
much memory it was doing this to and it may ultimately be the biggest
culprit here, BUT we may as well reduce our overhead since i've found
this anyway. less "false positives" when hunting problems.
why am i doing this? i'm setting framerate hiccups. eg like we drop 3,
5 or 10 frames, then drop another bunch, then go back to smooth, then
this hiccup again. finding out WHAT is causing that hiccup is hard. i
can only SEE the hiccups on my rpi3 - not on x86. i am not so sure
it's cpufreq bouncing about as i've locked cpu to 600mhz and it still
happens. it's something else. maybe something we are polling? maybe
it's something in our drm/kms backend? maybe its in the vc4 drivers or
kernel parts? i have no idea. trying to hunt this is hard, but this is
important as this is something that possibly is affecting everyone but
other hw is fast enough to hide it...
in the meantime find and optimize what i find along the way.
@optimize
2016-11-05 20:30:13 -07:00
|
|
|
static inline Eina_Bool
|
|
|
|
_color_same(const void *col1, const void *col2)
|
|
|
|
{
|
|
|
|
const unsigned int *icol1 = col1, *icol2 = col2;
|
|
|
|
return (*icol1 == *icol2);
|
|
|
|
}
|
|
|
|
|
2012-12-12 22:50:08 -08:00
|
|
|
static void
|
2014-03-09 00:31:28 -08:00
|
|
|
_evas_object_text_items_clean(Evas_Object_Protected_Data *obj, Evas_Text_Data *o)
|
2012-12-12 22:50:08 -08:00
|
|
|
{
|
|
|
|
/* FIXME: also preserve item */
|
2013-01-01 00:22:46 -08:00
|
|
|
if ((o->cur.font == o->prev.font) &&
|
|
|
|
(o->cur.fdesc == o->prev.fdesc) &&
|
|
|
|
(o->cur.size == o->prev.size) &&
|
remove memcmp calls for better performance where size is known
so i have been doing some profiling on my rpi3 ... and it seems
memcmp() is like the number one top used function - especially running
e in wayland compositor mode. it uses accoring to perf top about 9-15%
of samples (samples are not adding up to 100%). no - i cant seem to
get a call graph because all that happens is the whole kernel locks up
solid if i try, so i can only get the leaf node call stats. what
function was currently active at the sample time. memcmp is the
biggest by far. 2-3 times anything else.
13.47% libarmmem.so [.] memcmp
6.43% libevas.so.1.18.99 [.] _evas_render_phase1_object_pro
4.74% libevas.so.1.18.99 [.] evas_render_updates_internal.c
2.84% libeo.so.1.18.99 [.] _eo_obj_pointer_get
2.49% libevas.so.1.18.99 [.] evas_render_updates_internal_l
2.03% libpthread-2.24.so [.] pthread_getspecific
1.61% libeo.so.1.18.99 [.] efl_data_scope_get
1.60% libevas.so.1.18.99 [.] _evas_event_object_list_raw_in
1.54% libevas.so.1.18.99 [.] evas_object_smart_changed_get
1.32% libgcc_s.so.1 [.] __udivsi3
1.21% libevas.so.1.18.99 [.] evas_object_is_active
1.14% libc-2.24.so [.] malloc
0.96% libevas.so.1.18.99 [.] evas_render_mapped
0.85% libeo.so.1.18.99 [.] efl_isa
yeah. it's perf. it's sampling so not 100% accurate, but close to
"good enough" for the bigger stuff. so interestingly memcmp() is
actually in a special library/module (libarmmem.so) and is a REAL
function call. so doing memcmp's for small bits of memory ESPECIALLY
when we know their size in advance is not great. i am not sure our own
use of memcmp() is the actual culprit because even with this patch
memcmp still is right up there. we use it for stringshare which is
harder to remove as stringshare has variable sized memory blobs to
compare.
but the point remains - memcmp() is an ACTUAL function call. even on
x86 (i checked the assembly). and replacing it with a static inline
custom comparer is better. in fact i did that and benchmarked it as a
sample case for eina_tiler which has 4 ints (16 bytes) to compare
every time. i also compiled to assembly on x86 to inspect and make sure
things made sense.
the text color compare was just comparing 4 bytes as a color (an int
worth) which was silly to use memcmp on as it could just cast to an
int and do a == b. the map was a little more evil as it was 2 ptrs
plus 2 bitfields, but the way bitfields work means i can assume the
last byte is both bitfields combined. i can be a little more evil for
the rect tests as 4 ints compared is the same as comparing 2 long
longs (64bit types). yes. don't get pedantic. all platforms efl works
on work this way and this is a base assumption in efl and it's true
everywhere worth talking about.
yes - i tried __int128 too. it was not faster on x86 anyway and can't
compile on armv7. in my speed tests on x86-64, comparing 2 rects by
casting to a struct of 2 long long's and comparing just those is 70%
faster than comapring 4 ints. and the 2 long longs is 360% faster than
a memcmp. on arm (my rpi3) the long long is 12% faster than the 4 ints,
and it is 226% faster than a memcmp().
it'd be best if we didnt even have to compare at all, but with these
algorithms we do, so doing it faster is better.
we probably should nuke all the memcmp's we have that are not of large
bits of memory or variable sized bits of memory.
i set breakpoints for memcmp and found at least a chunk in efl. but
also it seems the vc4 driver was also doing it too. i have no idea how
much memory it was doing this to and it may ultimately be the biggest
culprit here, BUT we may as well reduce our overhead since i've found
this anyway. less "false positives" when hunting problems.
why am i doing this? i'm setting framerate hiccups. eg like we drop 3,
5 or 10 frames, then drop another bunch, then go back to smooth, then
this hiccup again. finding out WHAT is causing that hiccup is hard. i
can only SEE the hiccups on my rpi3 - not on x86. i am not so sure
it's cpufreq bouncing about as i've locked cpu to 600mhz and it still
happens. it's something else. maybe something we are polling? maybe
it's something in our drm/kms backend? maybe its in the vc4 drivers or
kernel parts? i have no idea. trying to hunt this is hard, but this is
important as this is something that possibly is affecting everyone but
other hw is fast enough to hide it...
in the meantime find and optimize what i find along the way.
@optimize
2016-11-05 20:30:13 -07:00
|
|
|
(_color_same(&o->cur.outline, &o->prev.outline)) &&
|
|
|
|
(_color_same(&o->cur.shadow, &o->prev.shadow)) &&
|
|
|
|
(_color_same(&o->cur.glow, &o->prev.glow)) &&
|
|
|
|
(_color_same(&o->cur.glow2, &o->prev.glow2)) &&
|
2013-01-01 00:22:46 -08:00
|
|
|
(o->cur.style == o->prev.style) &&
|
2017-01-06 09:57:46 -08:00
|
|
|
(EINA_DBL_EQ(obj->cur->scale, obj->prev->scale)))
|
2012-12-12 22:50:08 -08:00
|
|
|
{
|
2013-01-01 00:22:46 -08:00
|
|
|
if ((o->last_computed.ellipsis_start) &&
|
|
|
|
(o->last_computed.ellipsis_start == o->items))
|
2012-12-12 22:50:08 -08:00
|
|
|
o->items = (Evas_Object_Text_Item *) eina_inlist_remove(EINA_INLIST_GET(o->items),
|
2012-12-27 16:58:10 -08:00
|
|
|
EINA_INLIST_GET(o->last_computed.ellipsis_start));
|
2013-01-01 00:22:46 -08:00
|
|
|
if ((o->last_computed.ellipsis_end) &&
|
|
|
|
(EINA_INLIST_GET(o->last_computed.ellipsis_end) == EINA_INLIST_GET(o->items)->last))
|
2012-12-12 22:50:08 -08:00
|
|
|
o->items = (Evas_Object_Text_Item *) eina_inlist_remove(EINA_INLIST_GET(o->items),
|
2012-12-27 16:58:10 -08:00
|
|
|
EINA_INLIST_GET(o->last_computed.ellipsis_end));
|
2012-12-12 22:50:08 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-10-28 02:44:26 -07:00
|
|
|
/* It is not guaranteed that the ellipsis are still inside the items, so remove them by force */
|
|
|
|
if (o->last_computed.ellipsis_start)
|
|
|
|
_evas_object_text_item_del(o, o->last_computed.ellipsis_start);
|
2012-12-12 22:50:08 -08:00
|
|
|
o->last_computed.ellipsis_start = NULL;
|
2013-10-28 02:44:26 -07:00
|
|
|
|
|
|
|
if (o->last_computed.ellipsis_end)
|
|
|
|
_evas_object_text_item_del(o, o->last_computed.ellipsis_end);
|
2012-12-12 22:50:08 -08:00
|
|
|
o->last_computed.ellipsis_end = NULL;
|
|
|
|
}
|
|
|
|
while (o->items)
|
|
|
|
{
|
|
|
|
_evas_object_text_item_del(o, o->items);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-12 06:05:29 -08:00
|
|
|
static void
|
2014-03-09 00:31:28 -08:00
|
|
|
_evas_object_text_items_clear(Evas_Text_Data *o)
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
2013-01-01 00:22:46 -08:00
|
|
|
if ((o->last_computed.ellipsis_start) &&
|
|
|
|
(o->last_computed.ellipsis_start != o->items))
|
2012-12-12 22:50:08 -08:00
|
|
|
{
|
2013-10-28 03:45:46 -07:00
|
|
|
_evas_object_text_item_del(o, o->last_computed.ellipsis_start);
|
2012-12-12 22:50:08 -08:00
|
|
|
}
|
|
|
|
o->last_computed.ellipsis_start = NULL;
|
2013-01-01 00:22:46 -08:00
|
|
|
if ((o->last_computed.ellipsis_end) &&
|
|
|
|
(EINA_INLIST_GET(o->last_computed.ellipsis_end) != EINA_INLIST_GET(o->items)->last))
|
2012-12-12 22:50:08 -08:00
|
|
|
{
|
2013-10-28 03:45:46 -07:00
|
|
|
_evas_object_text_item_del(o, o->last_computed.ellipsis_end);
|
2012-12-12 22:50:08 -08:00
|
|
|
}
|
|
|
|
o->last_computed.ellipsis_end = NULL;
|
2011-01-30 02:36:02 -08:00
|
|
|
while (o->items)
|
|
|
|
{
|
2012-12-12 06:05:29 -08:00
|
|
|
_evas_object_text_item_del(o, o->items);
|
2011-01-30 02:36:02 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-30 02:40:14 -08:00
|
|
|
#ifdef BIDI_SUPPORT
|
2011-01-30 02:38:55 -08:00
|
|
|
static int
|
|
|
|
_evas_object_text_it_compare_logical(const void *_it1, const void *_it2)
|
|
|
|
{
|
|
|
|
const Evas_Object_Text_Item *it1 = _it1, *it2 = _it2;
|
|
|
|
if (it1->text_pos < it2->text_pos)
|
|
|
|
return -1;
|
|
|
|
else if (it1->text_pos == it2->text_pos)
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
}
|
2011-01-30 02:40:14 -08:00
|
|
|
#endif
|
2011-04-08 00:26:20 -07:00
|
|
|
|
2011-01-30 02:36:02 -08:00
|
|
|
static int
|
2012-10-08 18:58:41 -07:00
|
|
|
_evas_object_text_last_up_to_pos(const Evas_Object *eo_obj,
|
2014-03-09 00:31:28 -08:00
|
|
|
const Evas_Text_Data *o, Evas_Coord cx, Evas_Coord cy)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2011-01-30 02:36:02 -08:00
|
|
|
Evas_Object_Text_Item *it;
|
2015-11-18 02:56:48 -08:00
|
|
|
int pos = -1;
|
2011-01-30 02:36:02 -08:00
|
|
|
|
2011-01-30 02:38:55 -08:00
|
|
|
#ifdef BIDI_SUPPORT
|
|
|
|
/* Reorder if it's a bidi text */
|
|
|
|
if (o->bidi_par_props)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2011-01-30 02:38:55 -08:00
|
|
|
Eina_List *logical_it = NULL;
|
|
|
|
Evas_Object_Text_Item *i;
|
|
|
|
Eina_List *itr;
|
|
|
|
Evas_Coord x = 0;
|
|
|
|
/* Insert all to the logical list */
|
|
|
|
EINA_INLIST_FOREACH(o->items, i)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2011-01-30 02:38:55 -08:00
|
|
|
logical_it = eina_list_sorted_insert(logical_it,
|
|
|
|
_evas_object_text_it_compare_logical, i);
|
|
|
|
}
|
|
|
|
EINA_LIST_FOREACH(logical_it, itr, it)
|
|
|
|
{
|
|
|
|
if ((x <= cx) && (cx < x + it->adv))
|
|
|
|
{
|
2017-08-25 10:51:24 -07:00
|
|
|
pos = it->text_pos + ENFN->font_last_up_to_pos(ENC,
|
2011-05-29 06:00:54 -07:00
|
|
|
o->font,
|
2011-04-07 09:25:56 -07:00
|
|
|
&it->text_props,
|
2011-01-30 02:38:55 -08:00
|
|
|
cx - x,
|
2017-04-09 20:15:19 -07:00
|
|
|
cy, 0);
|
2015-11-18 02:52:34 -08:00
|
|
|
break;
|
2011-01-30 02:38:55 -08:00
|
|
|
}
|
|
|
|
x += it->adv;
|
|
|
|
}
|
|
|
|
eina_list_free(logical_it);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
|
|
|
|
{
|
|
|
|
if ((it->x <= cx) && (cx < it->x + it->adv))
|
|
|
|
{
|
2017-08-25 10:51:24 -07:00
|
|
|
return it->text_pos + ENFN->font_last_up_to_pos(ENC,
|
2011-05-29 06:00:54 -07:00
|
|
|
o->font,
|
2011-04-07 09:25:56 -07:00
|
|
|
&it->text_props,
|
2011-01-30 02:38:55 -08:00
|
|
|
cx - it->x,
|
2017-04-09 20:15:19 -07:00
|
|
|
cy, 0);
|
2011-01-30 02:38:55 -08:00
|
|
|
}
|
2011-01-30 02:36:02 -08:00
|
|
|
}
|
|
|
|
}
|
2015-11-18 02:56:48 -08:00
|
|
|
return pos;
|
2011-01-30 02:36:02 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-10-08 18:58:41 -07:00
|
|
|
_evas_object_text_char_at_coords(const Evas_Object *eo_obj,
|
2014-03-09 00:31:28 -08:00
|
|
|
const Evas_Text_Data *o, Evas_Coord cx, Evas_Coord cy,
|
2011-01-30 02:36:02 -08:00
|
|
|
Evas_Coord *rx, Evas_Coord *ry, Evas_Coord *rw, Evas_Coord *rh)
|
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2011-01-30 02:36:02 -08:00
|
|
|
Evas_Object_Text_Item *it;
|
|
|
|
|
|
|
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
|
|
|
|
{
|
2011-01-30 02:38:55 -08:00
|
|
|
if ((it->x <= cx) && (cx < it->x + it->adv))
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2017-08-25 10:51:24 -07:00
|
|
|
return it->text_pos + ENFN->font_char_at_coords_get(ENC,
|
2011-05-29 06:00:54 -07:00
|
|
|
o->font,
|
2011-04-07 09:25:56 -07:00
|
|
|
&it->text_props,
|
2011-07-12 08:04:10 -07:00
|
|
|
cx - it->x,
|
2011-01-30 02:36:02 -08:00
|
|
|
cy,
|
|
|
|
rx, ry,
|
|
|
|
rw, rh);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-03-17 03:29:16 -07:00
|
|
|
static Evas_Coord
|
2015-12-08 23:50:33 -08:00
|
|
|
_evas_object_text_horiz_width_without_ellipsis_get(const Evas_Text_Data *o)
|
2014-03-17 03:29:16 -07:00
|
|
|
{
|
2015-12-08 23:50:33 -08:00
|
|
|
return o->last_computed.width_without_ellipsis;
|
2014-03-17 03:29:16 -07:00
|
|
|
}
|
|
|
|
|
2011-01-30 02:36:02 -08:00
|
|
|
static Evas_Coord
|
2014-03-09 00:31:28 -08:00
|
|
|
_evas_object_text_horiz_advance_get(const Evas_Text_Data *o)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2013-10-02 03:07:48 -07:00
|
|
|
return o->last_computed.advance;
|
2011-01-30 02:36:02 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static Evas_Coord
|
2012-11-04 03:51:42 -08:00
|
|
|
_evas_object_text_vert_advance_get(const Evas_Object *obj EINA_UNUSED,
|
2014-03-09 00:31:28 -08:00
|
|
|
const Evas_Text_Data *o)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2011-01-30 02:44:17 -08:00
|
|
|
return o->max_ascent + o->max_descent;
|
2011-01-30 02:36:02 -08:00
|
|
|
}
|
|
|
|
|
2006-01-06 15:05:17 -08:00
|
|
|
EAPI Evas_Object *
|
2002-11-08 00:02:15 -08:00
|
|
|
evas_object_text_add(Evas *e)
|
|
|
|
{
|
|
|
|
MAGIC_CHECK(e, Evas, MAGIC_EVAS);
|
|
|
|
return NULL;
|
|
|
|
MAGIC_CHECK_END();
|
2017-07-06 00:47:41 -07:00
|
|
|
return efl_add(EVAS_TEXT_CLASS, e, efl_canvas_object_legacy_ctor(efl_added));
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2015-05-19 03:41:27 -07:00
|
|
|
EOLIAN static Eo *
|
2016-08-10 07:23:04 -07:00
|
|
|
_evas_text_efl_object_constructor(Eo *eo_obj, Evas_Text_Data *o EINA_UNUSED)
|
2004-01-22 18:14:45 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS));
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_text_init(eo_obj);
|
2014-10-21 18:53:45 -07:00
|
|
|
|
2015-05-19 03:41:27 -07:00
|
|
|
return eo_obj;
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
2018-02-12 13:02:06 -08:00
|
|
|
_evas_text_efl_text_font_font_source_set(Eo *eo_obj, Evas_Text_Data *o, const char *font_source)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2017-02-21 00:48:08 -08:00
|
|
|
if (((o->cur.source) && (font_source) &&
|
|
|
|
(!strcmp(o->cur.source, font_source))) ||
|
|
|
|
(!o->cur.source && !font_source))
|
2004-01-22 18:14:45 -08:00
|
|
|
return;
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_object_async_block(obj);
|
2010-07-17 12:49:16 -07:00
|
|
|
/*
|
2008-10-15 07:38:34 -07:00
|
|
|
if (o->cur.source) eina_stringshare_del(o->cur.source);
|
|
|
|
if (font_source) o->cur.source = eina_stringshare_add(font_source);
|
2004-01-22 18:14:45 -08:00
|
|
|
else o->cur.source = NULL;
|
2010-07-17 12:49:16 -07:00
|
|
|
*/
|
|
|
|
eina_stringshare_replace(&o->cur.source, font_source);
|
2004-01-22 18:14:45 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static const char*
|
2018-02-12 13:02:06 -08:00
|
|
|
_evas_text_efl_text_font_font_source_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
return o->cur.source;
|
2004-01-22 18:14:45 -08:00
|
|
|
}
|
|
|
|
|
2017-09-25 02:34:22 -07:00
|
|
|
static void
|
|
|
|
_evas_text_font_reload(Eo *eo_obj, Evas_Text_Data *o)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-21 22:02:53 -07:00
|
|
|
Eina_Bool pass = EINA_FALSE, freeze = EINA_FALSE;
|
|
|
|
Eina_Bool source_invisible = EINA_FALSE;
|
2016-10-21 05:25:41 -07:00
|
|
|
Eina_List *was = NULL;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
if (!(obj->layer->evas->is_frozen))
|
2005-07-22 03:28:11 -07:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
pass = evas_event_passes_through(eo_obj, obj);
|
|
|
|
freeze = evas_event_freezes_through(eo_obj, obj);
|
2012-10-21 21:57:32 -07:00
|
|
|
source_invisible = evas_object_is_source_invisible(eo_obj, obj);
|
|
|
|
if ((!pass) && (!freeze) && (!source_invisible))
|
2016-10-21 05:25:41 -07:00
|
|
|
was = _evas_pointer_list_in_rect_get(obj->layer->evas, eo_obj, obj,
|
|
|
|
1, 1);
|
2005-07-22 03:28:11 -07:00
|
|
|
}
|
2010-05-21 00:10:45 -07:00
|
|
|
|
2003-01-09 20:58:51 -08:00
|
|
|
/* DO IT */
|
2011-05-29 06:00:54 -07:00
|
|
|
if (o->font)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2017-11-06 18:22:09 -08:00
|
|
|
evas_font_free(o->font);
|
2011-10-31 07:50:00 -07:00
|
|
|
o->font = NULL;
|
2004-01-22 23:53:08 -08:00
|
|
|
}
|
2011-08-01 01:20:52 -07:00
|
|
|
|
2017-11-06 18:22:09 -08:00
|
|
|
o->font = evas_font_load(obj->layer->evas->font_path,
|
|
|
|
obj->layer->evas->hinting,
|
|
|
|
o->cur.fdesc, o->cur.source,
|
|
|
|
(int)(((double) o->cur.size) * obj->cur->scale),
|
|
|
|
o->cur.bitmap_scalable);
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2011-01-30 02:44:23 -08:00
|
|
|
o->ascent = 0;
|
|
|
|
o->descent = 0;
|
|
|
|
o->max_ascent = 0;
|
|
|
|
o->max_descent = 0;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2013-11-03 22:28:16 -08:00
|
|
|
_evas_object_text_items_clear(o);
|
2012-12-30 17:49:36 -08:00
|
|
|
_evas_object_text_recalc(eo_obj, o->cur.text);
|
2002-11-08 00:02:15 -08:00
|
|
|
o->changed = 1;
|
2015-06-17 00:26:30 -07:00
|
|
|
if (o->has_filter)
|
2016-03-01 10:06:28 -08:00
|
|
|
evas_filter_changed_set(eo_obj, EINA_TRUE);
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_change(eo_obj, obj);
|
|
|
|
evas_object_clip_dirty(eo_obj, obj);
|
|
|
|
evas_object_coords_recalc(eo_obj, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (!obj->layer->evas->is_frozen && !pass && !freeze && obj->cur->visible)
|
|
|
|
_evas_canvas_event_pointer_in_list_mouse_move_feed(obj->layer->evas, was, eo_obj, obj, 1, 1, EINA_TRUE, NULL);
|
|
|
|
eina_list_free(was);
|
2017-10-19 16:07:39 -07:00
|
|
|
evas_object_inform_call_resize(eo_obj, obj);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2017-09-25 02:34:22 -07:00
|
|
|
EOLIAN static void
|
2018-02-12 13:02:06 -08:00
|
|
|
_evas_text_efl_text_font_font_set(Eo *eo_obj, Evas_Text_Data *o, const char *font, Evas_Font_Size size)
|
2017-09-25 02:34:22 -07:00
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
|
|
|
Evas_Font_Description *fdesc;
|
|
|
|
|
|
|
|
if ((!font) || (size <= 0)) return;
|
|
|
|
|
|
|
|
evas_object_async_block(obj);
|
|
|
|
if ((size == o->cur.size) &&
|
|
|
|
(o->cur.font && !strcmp(font, o->cur.font))) return;
|
|
|
|
|
|
|
|
/* We can't assume the given font is same with current fdesc by comparing string.
|
|
|
|
Since Evas starts to supporting "auto" for language,
|
|
|
|
the given font string should be parsed once before comparing it. */
|
|
|
|
fdesc = evas_font_desc_new();
|
|
|
|
|
|
|
|
/* Set default language according to locale. */
|
|
|
|
eina_stringshare_replace(&(fdesc->lang), evas_font_lang_normalize("auto"));
|
|
|
|
evas_font_name_parse(fdesc, font);
|
|
|
|
|
|
|
|
if (o->cur.fdesc && !evas_font_desc_cmp(fdesc, o->cur.fdesc) &&
|
|
|
|
(size == o->cur.size))
|
|
|
|
{
|
|
|
|
evas_font_desc_unref(fdesc);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (o->cur.fdesc) evas_font_desc_unref(o->cur.fdesc);
|
|
|
|
o->cur.fdesc = fdesc;
|
|
|
|
|
|
|
|
o->cur.size = size;
|
|
|
|
eina_stringshare_replace(&o->cur.font, font);
|
|
|
|
o->prev.font = NULL;
|
|
|
|
|
|
|
|
_evas_text_font_reload(eo_obj, o);
|
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
2018-02-12 13:02:06 -08:00
|
|
|
_evas_text_efl_text_font_font_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o, const char **font, Evas_Font_Size *size)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2003-04-15 19:04:30 -07:00
|
|
|
if (font) *font = o->cur.font;
|
|
|
|
if (size) *size = o->cur.size;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2012-12-12 06:05:29 -08:00
|
|
|
static void
|
2014-03-09 00:31:28 -08:00
|
|
|
_evas_object_text_item_update_sizes(Evas_Object_Protected_Data *obj, Evas_Text_Data *o, Evas_Object_Text_Item *it)
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
2017-08-25 10:51:24 -07:00
|
|
|
ENFN->font_string_size_get(ENC,
|
2012-12-12 06:05:29 -08:00
|
|
|
o->font,
|
|
|
|
&it->text_props,
|
|
|
|
&it->w, &it->h);
|
2017-08-25 10:51:24 -07:00
|
|
|
it->adv = ENFN->font_h_advance_get(ENC, o->font,
|
2012-12-12 06:05:29 -08:00
|
|
|
&it->text_props);
|
|
|
|
}
|
2011-01-30 02:36:02 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
* Create a new text layout item from the string and the format.
|
|
|
|
*
|
|
|
|
* @param c the context to work on - Not NULL.
|
|
|
|
* @param fmt the format to use.
|
|
|
|
* @param str the string to use.
|
|
|
|
*/
|
|
|
|
static Evas_Object_Text_Item *
|
2012-12-12 06:05:29 -08:00
|
|
|
_evas_object_text_item_new(Evas_Object_Protected_Data *obj,
|
2014-03-09 00:31:28 -08:00
|
|
|
Evas_Text_Data *o,
|
2012-12-12 06:05:29 -08:00
|
|
|
Evas_Font_Instance *fi, const Eina_Unicode *str,
|
|
|
|
Evas_Script_Type script,
|
|
|
|
size_t pos, size_t visual_pos, size_t len)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
|
|
|
Evas_Object_Text_Item *it;
|
|
|
|
|
|
|
|
it = calloc(1, sizeof(Evas_Object_Text_Item));
|
|
|
|
it->text_pos = pos;
|
|
|
|
it->visual_pos = visual_pos;
|
2011-01-30 02:36:39 -08:00
|
|
|
evas_common_text_props_bidi_set(&it->text_props, o->bidi_par_props,
|
|
|
|
it->text_pos);
|
2011-05-29 02:20:18 -07:00
|
|
|
evas_common_text_props_script_set(&it->text_props, script);
|
|
|
|
|
2011-05-30 01:42:26 -07:00
|
|
|
if (fi)
|
2011-01-30 02:45:17 -08:00
|
|
|
{
|
2017-08-25 10:51:24 -07:00
|
|
|
ENFN->font_text_props_info_create(ENC,
|
2011-05-29 02:20:18 -07:00
|
|
|
fi, str + pos, &it->text_props,
|
2016-02-04 02:07:08 -08:00
|
|
|
o->bidi_par_props, it->text_pos, len, EVAS_TEXT_PROPS_MODE_SHAPE,
|
|
|
|
o->cur.fdesc->lang);
|
2012-12-12 06:05:29 -08:00
|
|
|
_evas_object_text_item_update_sizes(obj, o, it);
|
2011-01-30 02:45:17 -08:00
|
|
|
}
|
2011-01-30 02:36:02 -08:00
|
|
|
o->items = (Evas_Object_Text_Item *)
|
|
|
|
eina_inlist_append(EINA_INLIST_GET(o->items), EINA_INLIST_GET(it));
|
|
|
|
return it;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
* Orders o->items according to the visual position.
|
|
|
|
*
|
|
|
|
* @param obj the evas object
|
|
|
|
* @param o the text object
|
|
|
|
*/
|
|
|
|
static void
|
2014-03-09 00:31:28 -08:00
|
|
|
_evas_object_text_item_order(Evas_Object *eo_obj, Evas_Text_Data *o)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2012-10-08 18:58:41 -07:00
|
|
|
(void) eo_obj;
|
2011-01-30 02:36:02 -08:00
|
|
|
#ifdef BIDI_SUPPORT
|
|
|
|
/* Reorder if it's a bidi text */
|
|
|
|
if (o->bidi_par_props)
|
|
|
|
{
|
|
|
|
Evas_Object_Text_Item *i, *j, *min;
|
|
|
|
i = o->items;
|
|
|
|
while (i)
|
|
|
|
{
|
|
|
|
min = i;
|
|
|
|
EINA_INLIST_FOREACH(i, j)
|
|
|
|
{
|
|
|
|
if (j->visual_pos < min->visual_pos)
|
|
|
|
{
|
|
|
|
min = j;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (min != i)
|
|
|
|
{
|
|
|
|
o->items = (Evas_Object_Text_Item *) eina_inlist_remove(EINA_INLIST_GET(o->items), EINA_INLIST_GET(min));
|
|
|
|
o->items = (Evas_Object_Text_Item *) eina_inlist_prepend_relative(EINA_INLIST_GET(o->items), EINA_INLIST_GET(min), EINA_INLIST_GET(i));
|
|
|
|
}
|
|
|
|
|
|
|
|
i = (Evas_Object_Text_Item *) EINA_INLIST_GET(min)->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* calculate the positions according to the order. */
|
|
|
|
{
|
|
|
|
Evas_Object_Text_Item *it = o->items;
|
|
|
|
Evas_Coord x = 0;
|
|
|
|
|
|
|
|
while (it)
|
|
|
|
{
|
|
|
|
it->x = x;
|
|
|
|
x += it->adv;
|
|
|
|
it = (Evas_Object_Text_Item *) EINA_INLIST_GET(it)->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-12 06:05:29 -08:00
|
|
|
/**
|
|
|
|
* Create ellipsis.
|
|
|
|
*/
|
|
|
|
static const Eina_Unicode _ellip_str[2] = { 0x2026, '\0' };
|
|
|
|
|
|
|
|
/* FIXME: We currently leak ellipsis items. */
|
|
|
|
static Evas_Object_Text_Item *
|
2014-03-09 00:31:28 -08:00
|
|
|
_layout_ellipsis_item_new(Evas_Object_Protected_Data *obj, Evas_Text_Data *o)
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
2013-10-29 01:00:48 -07:00
|
|
|
Evas_Object_Text_Item *ellip_ti = NULL;
|
2013-10-16 01:57:34 -07:00
|
|
|
Evas_Script_Type script;
|
2013-10-29 01:00:48 -07:00
|
|
|
Evas_Font_Instance *script_fi = NULL, *cur_fi = NULL;
|
2012-12-12 06:05:29 -08:00
|
|
|
size_t len = 1; /* The length of _ellip_str */
|
|
|
|
|
2013-10-16 01:57:34 -07:00
|
|
|
script = evas_common_language_script_type_get(_ellip_str, 1);
|
|
|
|
|
|
|
|
if (o->font)
|
|
|
|
{
|
2017-08-25 10:51:24 -07:00
|
|
|
(void) ENFN->font_run_end_get(ENC, o->font, &script_fi, &cur_fi,
|
2013-10-16 01:57:34 -07:00
|
|
|
script, _ellip_str, 1);
|
2015-11-17 03:22:17 -08:00
|
|
|
ellip_ti = _evas_object_text_item_new(obj, o, cur_fi,
|
|
|
|
_ellip_str, script, 0, 0, len);
|
2013-10-16 01:57:34 -07:00
|
|
|
}
|
|
|
|
|
2012-12-12 06:05:29 -08:00
|
|
|
return ellip_ti;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EINA_TRUE if this item is ok and should be included, false if should be
|
|
|
|
* discarded. */
|
|
|
|
static Eina_Bool
|
2014-03-09 00:31:28 -08:00
|
|
|
_layout_text_item_trim(Evas_Object_Protected_Data *obj, Evas_Text_Data *o, Evas_Object_Text_Item *ti, int idx, Eina_Bool want_start)
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
|
|
|
Evas_Text_Props new_text_props;
|
2014-05-21 02:39:36 -07:00
|
|
|
if (idx >= (int) ti->text_props.text_len)
|
2012-12-12 06:05:29 -08:00
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
memset(&new_text_props, 0, sizeof (new_text_props));
|
|
|
|
|
2012-12-13 02:36:00 -08:00
|
|
|
while (!evas_common_text_props_split(&ti->text_props, &new_text_props, idx))
|
|
|
|
idx--;
|
2012-12-12 06:05:29 -08:00
|
|
|
if (want_start)
|
|
|
|
{
|
|
|
|
evas_common_text_props_content_unref(&new_text_props);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
evas_common_text_props_content_unref(&ti->text_props);
|
|
|
|
memcpy(&ti->text_props, &new_text_props, sizeof(ti->text_props));
|
|
|
|
ti->text_pos += idx;
|
|
|
|
ti->visual_pos += idx;
|
|
|
|
}
|
|
|
|
_evas_object_text_item_update_sizes(obj, o, ti);
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2015-06-17 00:26:30 -07:00
|
|
|
static void
|
2015-06-25 04:17:58 -07:00
|
|
|
_evas_object_text_pad_get(const Eo *eo_obj, Evas_Text_Data *o, int *l, int *r, int *t, int *b)
|
2015-06-17 00:26:30 -07:00
|
|
|
{
|
|
|
|
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
|
2016-03-01 10:06:28 -08:00
|
|
|
efl_gfx_filter_padding_get(eo_obj, l, r, t, b);
|
2015-06-17 00:26:30 -07:00
|
|
|
}
|
|
|
|
|
2011-01-30 02:36:02 -08:00
|
|
|
/**
|
|
|
|
* @internal
|
|
|
|
* Populates o->items with the items of the text according to text
|
|
|
|
*
|
|
|
|
* @param obj the evas object
|
|
|
|
* @param o the text object
|
|
|
|
* @param text the text to layout
|
|
|
|
*/
|
|
|
|
static void
|
2014-03-09 00:31:28 -08:00
|
|
|
_evas_object_text_layout(Evas_Object *eo_obj, Evas_Text_Data *o, Eina_Unicode *text)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2011-01-30 02:36:02 -08:00
|
|
|
EvasBiDiStrIndex *v_to_l = NULL;
|
2015-12-08 23:50:33 -08:00
|
|
|
Evas_Coord advance = 0, width = 0;
|
2011-01-30 02:36:02 -08:00
|
|
|
size_t pos, visual_pos;
|
2012-01-18 15:33:21 -08:00
|
|
|
int len = eina_unicode_strlen(text);
|
2013-10-02 04:52:59 -07:00
|
|
|
int l = 0, r = 0;
|
2011-01-30 02:36:02 -08:00
|
|
|
#ifdef BIDI_SUPPORT
|
2012-01-18 15:33:21 -08:00
|
|
|
int par_len = len;
|
2011-04-14 08:34:01 -07:00
|
|
|
int *segment_idxs = NULL;
|
2016-07-11 00:26:13 -07:00
|
|
|
Eina_Bool is_bidi = EINA_FALSE;
|
2012-12-12 21:12:14 -08:00
|
|
|
#endif
|
|
|
|
|
2012-12-17 05:04:35 -08:00
|
|
|
if (o->items &&
|
|
|
|
!memcmp(&o->cur, &o->prev, sizeof (o->cur)) &&
|
2012-12-16 19:34:08 -08:00
|
|
|
o->cur.text == text &&
|
2017-01-06 09:57:46 -08:00
|
|
|
(EINA_DBL_EQ(obj->cur->scale, obj->prev->scale)) &&
|
2013-10-01 04:34:03 -07:00
|
|
|
((o->last_computed.advance <= obj->cur->geometry.w && !o->last_computed.ellipsis) ||
|
2015-11-19 03:37:07 -08:00
|
|
|
(o->last_computed.w == obj->cur->geometry.w)) &&
|
|
|
|
!o->changed_paragraph_direction)
|
2013-06-20 04:28:18 -07:00
|
|
|
return;
|
2012-12-12 21:12:14 -08:00
|
|
|
|
2013-10-01 04:34:03 -07:00
|
|
|
o->last_computed.ellipsis = EINA_FALSE;
|
2013-02-28 13:36:32 -08:00
|
|
|
evas_object_content_change(eo_obj, obj);
|
|
|
|
|
2012-12-16 19:34:08 -08:00
|
|
|
if (o->items) _evas_object_text_items_clean(obj, o);
|
|
|
|
|
2013-02-21 05:39:37 -08:00
|
|
|
if (text && *text)
|
|
|
|
o->bidi_dir = EVAS_BIDI_DIRECTION_LTR;
|
|
|
|
else
|
|
|
|
o->bidi_dir = EVAS_BIDI_DIRECTION_NEUTRAL;
|
|
|
|
|
2012-12-12 21:12:14 -08:00
|
|
|
#ifdef BIDI_SUPPORT
|
2014-08-22 03:42:36 -07:00
|
|
|
if (text)
|
|
|
|
{
|
|
|
|
if (o->bidi_delimiters)
|
|
|
|
segment_idxs = evas_bidi_segment_idxs_get(text, o->bidi_delimiters);
|
|
|
|
}
|
2011-01-30 02:36:02 -08:00
|
|
|
evas_bidi_paragraph_props_unref(o->bidi_par_props);
|
2014-08-22 03:42:36 -07:00
|
|
|
if (text)
|
2015-11-19 03:37:07 -08:00
|
|
|
{
|
|
|
|
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);
|
2016-07-11 00:26:13 -07:00
|
|
|
is_bidi = !!o->bidi_par_props;
|
2015-11-19 03:37:07 -08:00
|
|
|
}
|
2013-02-21 05:39:37 -08:00
|
|
|
|
|
|
|
if (o->bidi_par_props)
|
|
|
|
o->bidi_dir = EVAS_BIDI_PAR_TYPE_TO_DIRECTION(o->bidi_par_props->direction);
|
|
|
|
|
2011-01-30 02:36:02 -08:00
|
|
|
evas_bidi_props_reorder_line(NULL, 0, len, o->bidi_par_props, &v_to_l);
|
2011-04-14 08:34:01 -07:00
|
|
|
if (segment_idxs) free(segment_idxs);
|
2011-01-30 02:36:02 -08:00
|
|
|
#endif
|
|
|
|
visual_pos = pos = 0;
|
|
|
|
|
2014-08-22 03:42:36 -07:00
|
|
|
if (text)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2015-12-08 23:50:33 -08:00
|
|
|
const Evas_Object_Text_Item *last_it = NULL;
|
2016-07-11 00:26:13 -07:00
|
|
|
#ifdef BIDI_SUPPORT
|
|
|
|
size_t max_vpos = 0;
|
|
|
|
#endif
|
2015-12-08 23:50:33 -08:00
|
|
|
|
2014-08-22 03:42:36 -07:00
|
|
|
while (len > 0)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2014-08-22 03:42:36 -07:00
|
|
|
Evas_Font_Instance *script_fi = NULL;
|
|
|
|
int script_len = len, tmp_cut;
|
|
|
|
Evas_Script_Type script;
|
|
|
|
tmp_cut = evas_common_language_script_end_of_run_get
|
|
|
|
(text + pos,
|
|
|
|
o->bidi_par_props,
|
|
|
|
pos, len);
|
|
|
|
if (tmp_cut > 0) script_len = tmp_cut;
|
|
|
|
|
|
|
|
script = evas_common_language_script_type_get(text + pos, script_len);
|
|
|
|
|
|
|
|
while (script_len > 0)
|
2011-05-29 02:20:18 -07:00
|
|
|
{
|
2014-08-22 03:42:36 -07:00
|
|
|
const Evas_Object_Text_Item *it;
|
|
|
|
Evas_Font_Instance *cur_fi = NULL;
|
|
|
|
int run_len = script_len;
|
|
|
|
if (o->font)
|
|
|
|
{
|
|
|
|
run_len = ENFN->font_run_end_get
|
2017-08-25 10:51:24 -07:00
|
|
|
(ENC, o->font, &script_fi, &cur_fi,
|
2014-08-22 03:42:36 -07:00
|
|
|
script, text + pos, script_len);
|
|
|
|
}
|
2011-01-30 02:36:02 -08:00
|
|
|
#ifdef BIDI_SUPPORT
|
2014-08-22 03:42:36 -07:00
|
|
|
visual_pos = evas_bidi_position_logical_to_visual
|
|
|
|
(v_to_l, par_len, pos);
|
2011-01-30 02:36:02 -08:00
|
|
|
#else
|
2014-08-22 03:42:36 -07:00
|
|
|
visual_pos = pos;
|
2011-01-30 02:36:02 -08:00
|
|
|
#endif
|
2014-08-22 03:42:36 -07:00
|
|
|
it = _evas_object_text_item_new(obj, o, cur_fi, text, script,
|
|
|
|
pos, visual_pos, run_len);
|
2011-05-29 02:20:18 -07:00
|
|
|
|
2014-08-22 03:42:36 -07:00
|
|
|
advance += it->adv;
|
|
|
|
pos += run_len;
|
|
|
|
script_len -= run_len;
|
|
|
|
len -= run_len;
|
2015-12-08 23:50:33 -08:00
|
|
|
|
|
|
|
if (it->w > 0)
|
2016-07-11 00:26:13 -07:00
|
|
|
{
|
|
|
|
#ifdef BIDI_SUPPORT
|
|
|
|
if (is_bidi)
|
|
|
|
{
|
|
|
|
if (!last_it || (visual_pos >= max_vpos))
|
|
|
|
{
|
|
|
|
last_it = it;
|
|
|
|
max_vpos = visual_pos;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
last_it = it;
|
|
|
|
}
|
|
|
|
}
|
2014-08-22 03:42:36 -07:00
|
|
|
}
|
2011-01-30 02:36:02 -08:00
|
|
|
}
|
2015-12-08 23:50:33 -08:00
|
|
|
|
|
|
|
width = advance;
|
|
|
|
if (last_it)
|
|
|
|
width += last_it->w - last_it->adv;
|
2011-01-30 02:36:02 -08:00
|
|
|
}
|
2015-12-08 23:50:33 -08:00
|
|
|
o->last_computed.width_without_ellipsis = width;
|
2011-01-30 02:36:02 -08:00
|
|
|
|
2015-06-17 00:26:30 -07:00
|
|
|
_evas_object_text_pad_get(eo_obj, o, &l, &r, NULL, NULL);
|
2013-10-02 04:52:59 -07:00
|
|
|
|
2012-12-12 06:05:29 -08:00
|
|
|
/* Handle ellipsis */
|
2015-12-08 23:50:33 -08:00
|
|
|
if (pos && (o->cur.ellipsis >= 0.0) && (width + l + r > obj->cur->geometry.w) && (obj->cur->geometry.w > 0))
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
2013-03-12 05:58:19 -07:00
|
|
|
Evas_Coord ellip_frame = obj->cur->geometry.w;
|
2012-12-12 06:05:29 -08:00
|
|
|
Evas_Object_Text_Item *start_ellip_it = NULL, *end_ellip_it = NULL;
|
2013-10-01 04:34:03 -07:00
|
|
|
|
2013-10-02 04:52:59 -07:00
|
|
|
o->last_computed.ellipsis = EINA_TRUE;
|
|
|
|
|
2012-12-12 06:05:29 -08:00
|
|
|
/* Account of the ellipsis item width. As long as ellipsis != 0
|
|
|
|
* we have a left ellipsis. And the same with 1 and right. */
|
2017-01-06 09:57:46 -08:00
|
|
|
if (!EINA_DBL_EQ(o->cur.ellipsis, 0.0))
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
2012-12-12 22:50:08 -08:00
|
|
|
if (o->last_computed.ellipsis_start)
|
|
|
|
{
|
|
|
|
start_ellip_it = o->last_computed.ellipsis_start;
|
|
|
|
o->items = (Evas_Object_Text_Item *)
|
|
|
|
eina_inlist_append(EINA_INLIST_GET(o->items), EINA_INLIST_GET(start_ellip_it));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-10-16 01:57:34 -07:00
|
|
|
start_ellip_it = _layout_ellipsis_item_new(obj, o);
|
2012-12-12 22:50:08 -08:00
|
|
|
}
|
|
|
|
o->last_computed.ellipsis_start = start_ellip_it;
|
2015-12-08 23:50:33 -08:00
|
|
|
ellip_frame -= start_ellip_it->w;
|
2012-12-12 06:05:29 -08:00
|
|
|
}
|
2017-01-06 09:57:46 -08:00
|
|
|
if (!EINA_DBL_EQ(o->cur.ellipsis, 1.0))
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
|
|
|
/* FIXME: Should take the last item's font and style and etc. *//* weird it's a text, should always have the same style/font */
|
2012-12-12 22:50:08 -08:00
|
|
|
if (o->last_computed.ellipsis_end)
|
|
|
|
{
|
|
|
|
end_ellip_it = o->last_computed.ellipsis_end;
|
|
|
|
o->items = (Evas_Object_Text_Item *)
|
|
|
|
eina_inlist_append(EINA_INLIST_GET(o->items), EINA_INLIST_GET(end_ellip_it));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-10-16 01:57:34 -07:00
|
|
|
end_ellip_it = _layout_ellipsis_item_new(obj, o);
|
2012-12-12 22:50:08 -08:00
|
|
|
}
|
|
|
|
o->last_computed.ellipsis_end = end_ellip_it;
|
2015-12-08 23:50:33 -08:00
|
|
|
ellip_frame -= end_ellip_it->w;
|
2012-12-12 06:05:29 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* The point where we should start from, going for the full
|
|
|
|
* ellip frame. */
|
2015-12-08 23:50:33 -08:00
|
|
|
Evas_Coord ellipsis_coord = o->cur.ellipsis * (width - ellip_frame);
|
2012-12-12 06:05:29 -08:00
|
|
|
if (start_ellip_it)
|
|
|
|
{
|
|
|
|
Evas_Object_Text_Item *itr = o->items;
|
|
|
|
advance = 0;
|
|
|
|
|
2015-12-08 23:50:33 -08:00
|
|
|
while (itr && (advance + l + r + itr->w < ellipsis_coord))
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
|
|
|
Eina_Inlist *itrn = EINA_INLIST_GET(itr)->next;
|
|
|
|
if ((itr != start_ellip_it) && (itr != end_ellip_it))
|
|
|
|
{
|
|
|
|
advance += itr->adv;
|
|
|
|
_evas_object_text_item_del(o, itr);
|
|
|
|
}
|
|
|
|
itr = (Evas_Object_Text_Item *) itrn;
|
|
|
|
}
|
|
|
|
if (itr && (itr != start_ellip_it))
|
|
|
|
{
|
2017-08-25 10:51:24 -07:00
|
|
|
int cut = ENFN->font_last_up_to_pos(ENC,
|
2012-12-12 06:05:29 -08:00
|
|
|
o->font,
|
|
|
|
&itr->text_props,
|
2013-10-02 04:52:59 -07:00
|
|
|
ellipsis_coord - (advance + l + r),
|
2017-04-09 20:15:19 -07:00
|
|
|
0, start_ellip_it->w);
|
Evas text: fix RTL text ellipsis issues
Summary:
Visual position of ellipsis item should be set according to
its bidi direction. But, by setting visual position in same way
as logical position, the end ellipsis could be put opposite side.
Also, start ellipsis must placed on left side of RTL text.
@fix T3187
Test Plan: Test an sample on T3187
Reviewers: tasn, woohyun, herdsman
Subscribers: raster, Blackmole, z-wony, cedric, jpeg, minudf
Maniphest Tasks: T3187
Differential Revision: https://phab.enlightenment.org/D3769
2016-08-18 04:39:40 -07:00
|
|
|
if (cut >= 0)
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
|
|
|
start_ellip_it->text_pos = itr->text_pos;
|
Evas text: fix RTL text ellipsis issues
Summary:
Visual position of ellipsis item should be set according to
its bidi direction. But, by setting visual position in same way
as logical position, the end ellipsis could be put opposite side.
Also, start ellipsis must placed on left side of RTL text.
@fix T3187
Test Plan: Test an sample on T3187
Reviewers: tasn, woohyun, herdsman
Subscribers: raster, Blackmole, z-wony, cedric, jpeg, minudf
Maniphest Tasks: T3187
Differential Revision: https://phab.enlightenment.org/D3769
2016-08-18 04:39:40 -07:00
|
|
|
|
|
|
|
if (itr->text_props.bidi_dir == EVAS_BIDI_DIRECTION_RTL)
|
|
|
|
start_ellip_it->visual_pos = itr->visual_pos + cut + 1;
|
|
|
|
else
|
|
|
|
start_ellip_it->visual_pos = itr->visual_pos;
|
|
|
|
|
|
|
|
if (!_layout_text_item_trim(obj, o, itr, cut + 1, EINA_FALSE))
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
|
|
|
_evas_object_text_item_del(o, itr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Evas text: fix RTL text ellipsis issues
Summary:
Visual position of ellipsis item should be set according to
its bidi direction. But, by setting visual position in same way
as logical position, the end ellipsis could be put opposite side.
Also, start ellipsis must placed on left side of RTL text.
@fix T3187
Test Plan: Test an sample on T3187
Reviewers: tasn, woohyun, herdsman
Subscribers: raster, Blackmole, z-wony, cedric, jpeg, minudf
Maniphest Tasks: T3187
Differential Revision: https://phab.enlightenment.org/D3769
2016-08-18 04:39:40 -07:00
|
|
|
if (!o->bidi_par_props)
|
|
|
|
{
|
|
|
|
o->items = (Evas_Object_Text_Item *) eina_inlist_remove(EINA_INLIST_GET(o->items), EINA_INLIST_GET(start_ellip_it));
|
|
|
|
o->items = (Evas_Object_Text_Item *) eina_inlist_prepend(EINA_INLIST_GET(o->items), EINA_INLIST_GET(start_ellip_it));
|
|
|
|
}
|
2012-12-12 06:05:29 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (end_ellip_it)
|
|
|
|
{
|
|
|
|
Evas_Object_Text_Item *itr = o->items;
|
|
|
|
advance = 0;
|
|
|
|
|
|
|
|
while (itr)
|
|
|
|
{
|
|
|
|
if (itr != end_ellip_it) /* was start_ellip_it */
|
|
|
|
{
|
2015-12-08 23:50:33 -08:00
|
|
|
if (advance + l + r + itr->w >= ellip_frame)
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
advance += itr->adv;
|
|
|
|
}
|
|
|
|
itr = (Evas_Object_Text_Item *) EINA_INLIST_GET(itr)->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (itr == end_ellip_it)
|
|
|
|
{
|
|
|
|
/* FIXME: We shouldn't do anything. */
|
|
|
|
}
|
|
|
|
|
2015-11-03 20:58:58 -08:00
|
|
|
/* In case when we reach end of itr list, and have NULL */
|
|
|
|
int cut = -1;
|
|
|
|
if (itr && (itr != end_ellip_it))
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
2017-08-25 10:51:24 -07:00
|
|
|
cut = ENFN->font_last_up_to_pos(ENC,
|
2015-11-03 20:58:58 -08:00
|
|
|
o->font,
|
|
|
|
&itr->text_props,
|
|
|
|
ellip_frame - (advance + l + r),
|
2017-04-09 20:15:19 -07:00
|
|
|
0, end_ellip_it->w);
|
2015-11-03 20:58:58 -08:00
|
|
|
if (cut >= 0)
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
2015-11-03 20:58:58 -08:00
|
|
|
end_ellip_it->text_pos = itr->text_pos + cut;
|
Evas text: fix RTL text ellipsis issues
Summary:
Visual position of ellipsis item should be set according to
its bidi direction. But, by setting visual position in same way
as logical position, the end ellipsis could be put opposite side.
Also, start ellipsis must placed on left side of RTL text.
@fix T3187
Test Plan: Test an sample on T3187
Reviewers: tasn, woohyun, herdsman
Subscribers: raster, Blackmole, z-wony, cedric, jpeg, minudf
Maniphest Tasks: T3187
Differential Revision: https://phab.enlightenment.org/D3769
2016-08-18 04:39:40 -07:00
|
|
|
|
|
|
|
if (itr->text_props.bidi_dir == EVAS_BIDI_DIRECTION_RTL)
|
|
|
|
end_ellip_it->visual_pos = itr->visual_pos - 1;
|
|
|
|
else
|
|
|
|
end_ellip_it->visual_pos = itr->visual_pos + cut;
|
|
|
|
|
2015-11-03 20:58:58 -08:00
|
|
|
if (_layout_text_item_trim(obj, o, itr, cut, EINA_TRUE))
|
|
|
|
{
|
|
|
|
itr = (Evas_Object_Text_Item *) EINA_INLIST_GET(itr)->next;
|
|
|
|
}
|
2012-12-12 06:05:29 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-11-03 20:58:58 -08:00
|
|
|
|
2012-12-12 06:05:29 -08:00
|
|
|
/* Remove the rest of the items */
|
|
|
|
while (itr)
|
|
|
|
{
|
|
|
|
Eina_Inlist *itrn = EINA_INLIST_GET(itr)->next;
|
|
|
|
if ((itr != start_ellip_it) && (itr != end_ellip_it))
|
2015-11-17 03:22:17 -08:00
|
|
|
{
|
|
|
|
_evas_object_text_item_del(o, itr);
|
|
|
|
}
|
2012-12-12 06:05:29 -08:00
|
|
|
itr = (Evas_Object_Text_Item *) itrn;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-12-17 05:04:35 -08:00
|
|
|
if (o->cur.text != text) free(o->cur.text);
|
2012-12-16 19:34:08 -08:00
|
|
|
o->cur.text = text;
|
2012-12-12 21:12:14 -08:00
|
|
|
o->prev = o->cur;
|
2013-10-01 04:34:03 -07:00
|
|
|
|
|
|
|
{
|
|
|
|
Evas_Object_Text_Item *itr = o->items;
|
|
|
|
advance = 0;
|
|
|
|
|
|
|
|
while (itr)
|
|
|
|
{
|
|
|
|
advance += itr->adv;
|
|
|
|
itr = (Evas_Object_Text_Item *) EINA_INLIST_GET(itr)->next;
|
|
|
|
}
|
|
|
|
o->last_computed.advance = advance;
|
|
|
|
}
|
2012-12-12 06:05:29 -08:00
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
_evas_object_text_item_order(eo_obj, o);
|
2011-01-30 02:36:02 -08:00
|
|
|
|
|
|
|
if (v_to_l) free(v_to_l);
|
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
2017-09-15 02:37:25 -07:00
|
|
|
_evas_text_efl_gfx_size_set(Eo *eo_obj, Evas_Text_Data *o, Eina_Size2D sz)
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-12-30 17:49:36 -08:00
|
|
|
|
2017-09-15 02:37:25 -07:00
|
|
|
if (_evas_object_intercept_call_evas(obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 0, sz.w, sz.h))
|
2017-02-21 00:48:08 -08:00
|
|
|
return;
|
|
|
|
|
2013-08-05 01:43:17 -07:00
|
|
|
EINA_COW_STATE_WRITE_BEGIN(obj, state_write, cur)
|
|
|
|
{
|
2017-09-15 02:37:25 -07:00
|
|
|
state_write->geometry.w = sz.w;
|
|
|
|
state_write->geometry.h = sz.h;
|
2013-08-05 01:43:17 -07:00
|
|
|
}
|
|
|
|
EINA_COW_STATE_WRITE_END(obj, state_write, cur);
|
|
|
|
|
|
|
|
_evas_object_text_recalc(eo_obj, o->cur.text);
|
2012-12-12 06:05:29 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
|
|
|
_evas_text_ellipsis_set(Eo *eo_obj, Evas_Text_Data *o, double ellipsis)
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-12-12 06:05:29 -08:00
|
|
|
|
2017-01-06 09:57:46 -08:00
|
|
|
if (EINA_DBL_EQ(o->cur.ellipsis, ellipsis)) return;
|
2012-12-12 06:05:29 -08:00
|
|
|
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_object_async_block(obj);
|
2016-02-16 07:14:38 -08:00
|
|
|
o->prev.ellipsis = o->cur.ellipsis;
|
2012-12-12 06:05:29 -08:00
|
|
|
o->cur.ellipsis = ellipsis;
|
|
|
|
o->changed = 1;
|
2015-06-17 00:26:30 -07:00
|
|
|
if (o->has_filter)
|
2016-03-01 10:06:28 -08:00
|
|
|
evas_filter_changed_set(eo_obj, EINA_TRUE);
|
2012-12-12 06:05:29 -08:00
|
|
|
evas_object_change(eo_obj, obj);
|
|
|
|
evas_object_clip_dirty(eo_obj, obj);
|
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static double
|
|
|
|
_evas_text_ellipsis_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
return o->cur.ellipsis;
|
2012-12-12 06:05:29 -08:00
|
|
|
}
|
2011-01-30 02:36:02 -08:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
2016-08-10 07:23:04 -07:00
|
|
|
_evas_text_efl_object_dbg_info_get(Eo *eo_obj, Evas_Text_Data *o EINA_UNUSED, Efl_Dbg_Info *root)
|
2013-01-28 22:36:23 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
efl_dbg_info_get(efl_super(eo_obj, MY_CLASS), root);
|
|
|
|
Efl_Dbg_Info *group = EFL_DBG_INFO_LIST_APPEND(root, MY_CLASS_NAME);
|
2013-01-28 22:36:23 -08:00
|
|
|
|
|
|
|
const char *text;
|
|
|
|
int size;
|
2018-02-12 13:02:06 -08:00
|
|
|
efl_text_font_get(eo_obj, &text, &size);
|
2016-08-15 06:44:41 -07:00
|
|
|
EFL_DBG_INFO_APPEND(group, "Font", EINA_VALUE_TYPE_STRING, text);
|
|
|
|
EFL_DBG_INFO_APPEND(group, "Text size", EINA_VALUE_TYPE_INT, size);
|
2013-01-28 22:36:23 -08:00
|
|
|
|
2018-02-12 13:02:06 -08:00
|
|
|
text = efl_text_font_source_get(eo_obj);
|
2016-08-15 06:44:41 -07:00
|
|
|
EFL_DBG_INFO_APPEND(group, "Font source", EINA_VALUE_TYPE_STRING, text);
|
2013-01-28 22:36:23 -08:00
|
|
|
|
2016-03-01 10:06:28 -08:00
|
|
|
text = efl_text_get(eo_obj);
|
2016-08-15 06:44:41 -07:00
|
|
|
EFL_DBG_INFO_APPEND(group, "Text", EINA_VALUE_TYPE_STRING, text);
|
2013-01-28 22:36:23 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
2014-07-24 09:42:09 -07:00
|
|
|
_evas_text_efl_text_text_set(Eo *eo_obj, Evas_Text_Data *o, const char *_text)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2016-10-21 05:25:41 -07:00
|
|
|
int len;
|
2012-10-08 18:58:41 -07:00
|
|
|
Eina_Unicode *text;
|
2016-10-21 05:25:41 -07:00
|
|
|
Eina_List *was = NULL;
|
2012-10-08 18:58:41 -07:00
|
|
|
|
2011-02-20 22:12:28 -08:00
|
|
|
if ((o->cur.utf8_text) && (_text) && (!strcmp(o->cur.utf8_text, _text)))
|
|
|
|
return;
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_object_async_block(obj);
|
2011-02-16 08:00:17 -08:00
|
|
|
text = eina_unicode_utf8_to_unicode(_text, &len);
|
2011-01-30 02:36:02 -08:00
|
|
|
|
|
|
|
if (!text) text = eina_unicode_strdup(EINA_UNICODE_EMPTY_STRING);
|
2016-10-21 05:25:41 -07:00
|
|
|
was = _evas_pointer_list_in_rect_get(obj->layer->evas, eo_obj, obj, 1, 1);
|
2002-11-08 00:02:15 -08:00
|
|
|
/* DO II */
|
2011-01-30 02:35:17 -08:00
|
|
|
/*Update bidi_props*/
|
2011-01-30 02:36:02 -08:00
|
|
|
|
2013-10-28 02:44:26 -07:00
|
|
|
_evas_object_text_items_clear(o);
|
2010-07-28 05:00:41 -07:00
|
|
|
|
2012-12-30 17:49:36 -08:00
|
|
|
_evas_object_text_recalc(eo_obj, text);
|
|
|
|
eina_stringshare_replace(&o->cur.utf8_text, _text);
|
|
|
|
o->prev.utf8_text = NULL;
|
|
|
|
|
2012-12-30 17:59:00 -08:00
|
|
|
if (o->cur.text != text) free(text);
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
o->changed = 1;
|
2015-06-17 00:26:30 -07:00
|
|
|
if (o->has_filter)
|
2016-03-01 10:06:28 -08:00
|
|
|
evas_filter_changed_set(eo_obj, EINA_TRUE);
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_change(eo_obj, obj);
|
|
|
|
evas_object_clip_dirty(eo_obj, obj);
|
|
|
|
evas_object_coords_recalc(eo_obj, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (obj->cur->visible)
|
|
|
|
_evas_canvas_event_pointer_in_list_mouse_move_feed(obj->layer->evas, was, eo_obj, obj, 1, 1, EINA_FALSE, NULL);
|
|
|
|
eina_list_free(was);
|
2017-10-19 16:07:39 -07:00
|
|
|
evas_object_inform_call_resize(eo_obj, obj);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
2015-02-10 03:44:38 -08:00
|
|
|
_evas_text_bidi_delimiters_set(Eo *eo_obj, Evas_Text_Data *o, const char *delim)
|
2011-04-14 08:34:01 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_object_async_block(obj);
|
2011-04-14 08:34:01 -07:00
|
|
|
eina_stringshare_replace(&o->bidi_delimiters, delim);
|
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static const char*
|
|
|
|
_evas_text_bidi_delimiters_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
return o->bidi_delimiters;
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static const char*
|
2014-07-24 09:42:09 -07:00
|
|
|
_evas_text_efl_text_text_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
return o->cur.utf8_text;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static Evas_BiDi_Direction
|
2015-11-19 03:37:07 -08:00
|
|
|
_evas_text_direction_get(Eo *eo_obj, Evas_Text_Data *o)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2015-11-19 03:37:07 -08:00
|
|
|
#ifdef BIDI_SUPPORT
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2015-11-19 03:37:07 -08:00
|
|
|
|
|
|
|
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
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
return o->bidi_dir;
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static Evas_Coord
|
|
|
|
_evas_text_ascent_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
return o->ascent;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static Evas_Coord
|
|
|
|
_evas_text_descent_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
return o->descent;
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static Evas_Coord
|
|
|
|
_evas_text_max_ascent_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
return o->max_ascent;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static Evas_Coord
|
|
|
|
_evas_text_max_descent_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
return o->max_descent;
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static Evas_Coord
|
|
|
|
_evas_text_inset_get(Eo *eo_obj, Evas_Text_Data *o)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-08 18:58:41 -07:00
|
|
|
Evas_Coord inset = 0;
|
2014-03-09 00:31:28 -08:00
|
|
|
if (!o->font) return inset;
|
|
|
|
if (!o->items) return inset;
|
2017-08-25 10:51:24 -07:00
|
|
|
inset = ENFN->font_inset_get(ENC, o->font, &o->items->text_props);
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
return inset;
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static Evas_Coord
|
|
|
|
_evas_text_horiz_advance_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
|
|
|
Evas_Coord horiz = 0;
|
2014-03-09 00:31:28 -08:00
|
|
|
if (!o->font) return horiz;
|
|
|
|
if (!o->items) return horiz;
|
|
|
|
horiz = _evas_object_text_horiz_advance_get(o);
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
return horiz;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static Evas_Coord
|
|
|
|
_evas_text_vert_advance_get(Eo *eo_obj, Evas_Text_Data *o)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
Evas_Coord vert;
|
|
|
|
vert = 0;
|
|
|
|
if (!o->font) return vert;
|
2012-10-08 18:58:41 -07:00
|
|
|
if (!o->items)
|
|
|
|
{
|
2014-08-11 05:33:12 -07:00
|
|
|
vert = o->max_ascent + o->max_descent;
|
2014-03-09 00:31:28 -08:00
|
|
|
return vert;
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
2014-03-09 00:31:28 -08:00
|
|
|
vert = _evas_object_text_vert_advance_get(eo_obj, o);
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
return vert;
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static Eina_Bool
|
2015-06-25 04:17:58 -07:00
|
|
|
_evas_text_char_pos_get(const Eo *eo_obj, Evas_Text_Data *o, int pos, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
Eina_Bool ret;
|
|
|
|
ret = EINA_FALSE;
|
2012-10-08 18:58:41 -07:00
|
|
|
|
|
|
|
int l = 0, r = 0, t = 0, b = 0;
|
|
|
|
int x = 0, y = 0, w = 0, h = 0;
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
if (!o->font) return ret;
|
|
|
|
if (!o->items || (pos < 0)) return ret;
|
2012-10-08 18:58:41 -07:00
|
|
|
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-08 18:58:41 -07:00
|
|
|
|
|
|
|
Eina_Bool int_ret = _evas_object_text_char_coords_get(eo_obj, o, (size_t) pos,
|
2011-01-30 02:36:02 -08:00
|
|
|
&x, &y, &w, &h);
|
2015-06-17 00:26:30 -07:00
|
|
|
|
|
|
|
_evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
|
2005-11-26 00:04:20 -08:00
|
|
|
y += o->max_ascent - t;
|
2010-10-13 07:14:40 -07:00
|
|
|
x -= l;
|
2003-06-06 19:32:30 -07:00
|
|
|
if (x < 0)
|
|
|
|
{
|
2015-11-17 03:22:17 -08:00
|
|
|
w += x;
|
|
|
|
x = 0;
|
2003-06-06 19:32:30 -07:00
|
|
|
}
|
2013-03-12 05:58:19 -07:00
|
|
|
if ((x + w) > obj->cur->geometry.w) w = obj->cur->geometry.w - x;
|
2003-06-06 19:32:30 -07:00
|
|
|
if (w < 0) w = 0;
|
|
|
|
if (y < 0)
|
|
|
|
{
|
2015-11-17 03:22:17 -08:00
|
|
|
h += y;
|
|
|
|
y = 0;
|
2003-06-06 19:32:30 -07:00
|
|
|
}
|
2013-03-12 05:58:19 -07:00
|
|
|
if ((y + h) > obj->cur->geometry.h) h = obj->cur->geometry.h - y;
|
2003-06-06 19:32:30 -07:00
|
|
|
if (h < 0) h = 0;
|
2002-11-08 00:02:15 -08:00
|
|
|
if (cx) *cx = x;
|
|
|
|
if (cy) *cy = y;
|
2005-11-26 00:04:20 -08:00
|
|
|
if (cw) *cw = w + l + r;
|
|
|
|
if (ch) *ch = h + t + b;
|
2014-03-09 00:31:28 -08:00
|
|
|
ret = int_ret;
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
return ret;
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static int
|
2015-06-25 04:17:58 -07:00
|
|
|
_evas_text_last_up_to_pos(const Eo *eo_obj, Evas_Text_Data *o, Evas_Coord x, Evas_Coord y)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
int ret;
|
|
|
|
ret = -1;
|
2012-10-08 18:58:41 -07:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
if (!o->font) return ret;
|
|
|
|
if (!o->items) return ret;
|
2012-10-08 18:58:41 -07:00
|
|
|
int int_ret = _evas_object_text_last_up_to_pos(eo_obj, o, x, y - o->max_ascent);
|
2014-03-09 00:31:28 -08:00
|
|
|
ret = int_ret;
|
|
|
|
|
|
|
|
return ret;
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static int
|
2015-06-25 04:17:58 -07:00
|
|
|
_evas_text_char_coords_get(const Eo *eo_obj, Evas_Text_Data *o, Evas_Coord x, Evas_Coord y, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
int ret;
|
|
|
|
ret = -1;
|
2009-09-29 21:23:21 -07:00
|
|
|
|
2005-11-26 00:04:20 -08:00
|
|
|
int l = 0, r = 0, t = 0, b = 0;
|
2012-10-08 18:58:41 -07:00
|
|
|
int rx = 0, ry = 0, rw = 0, rh = 0;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
if (!o->font) return ret;
|
|
|
|
if (!o->items) return ret;
|
2012-10-08 18:58:41 -07:00
|
|
|
|
|
|
|
int int_ret = _evas_object_text_char_at_coords(eo_obj, o, x, y - o->max_ascent,
|
2011-01-30 02:36:02 -08:00
|
|
|
&rx, &ry, &rw, &rh);
|
2015-06-17 00:26:30 -07:00
|
|
|
_evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
|
2005-11-26 00:04:20 -08:00
|
|
|
ry += o->max_ascent - t;
|
2010-10-13 07:14:40 -07:00
|
|
|
rx -= l;
|
2003-06-06 19:32:30 -07:00
|
|
|
if (rx < 0)
|
|
|
|
{
|
2015-11-17 03:22:17 -08:00
|
|
|
rw += rx;
|
|
|
|
rx = 0;
|
2003-06-06 19:32:30 -07:00
|
|
|
}
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2013-03-12 05:58:19 -07:00
|
|
|
if ((rx + rw) > obj->cur->geometry.w) rw = obj->cur->geometry.w - rx;
|
2003-06-06 19:32:30 -07:00
|
|
|
if (rw < 0) rw = 0;
|
|
|
|
if (ry < 0)
|
|
|
|
{
|
2015-11-17 03:22:17 -08:00
|
|
|
rh += ry;
|
|
|
|
ry = 0;
|
2003-06-06 19:32:30 -07:00
|
|
|
}
|
2013-03-12 05:58:19 -07:00
|
|
|
if ((ry + rh) > obj->cur->geometry.h) rh = obj->cur->geometry.h - ry;
|
2003-06-06 19:32:30 -07:00
|
|
|
if (rh < 0) rh = 0;
|
2002-11-08 00:02:15 -08:00
|
|
|
if (cx) *cx = rx;
|
|
|
|
if (cy) *cy = ry;
|
2005-11-26 00:04:20 -08:00
|
|
|
if (cw) *cw = rw + l + r;
|
|
|
|
if (ch) *ch = rh + t + b;
|
2014-03-09 00:31:28 -08:00
|
|
|
ret = int_ret;
|
2002-11-08 00:02:15 -08:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
return ret;
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
|
|
|
_evas_text_style_set(Eo *eo_obj, Evas_Text_Data *o, Evas_Text_Style_Type style)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-08 18:58:41 -07:00
|
|
|
int pl = 0, pr = 0, pt = 0, pb = 0, l = 0, r = 0, t = 0, b = 0;
|
2013-08-05 01:43:17 -07:00
|
|
|
int w = 0, h = 0;
|
2012-10-08 18:58:41 -07:00
|
|
|
|
2010-07-17 12:49:16 -07:00
|
|
|
if (o->cur.style == style) return;
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_object_async_block(obj);
|
2012-10-08 18:58:41 -07:00
|
|
|
|
2015-06-17 00:26:30 -07:00
|
|
|
_evas_object_text_pad_get(eo_obj, o, &pl, &pr, &pt, &pb);
|
|
|
|
//evas_text_style_pad_get(o->cur.style, &pl, &pr, &pt, &pb);
|
2005-11-26 00:04:20 -08:00
|
|
|
o->cur.style = style;
|
2015-06-17 00:26:30 -07:00
|
|
|
_evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
|
|
|
|
//evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
|
2013-03-12 05:58:19 -07:00
|
|
|
|
2013-08-05 01:43:17 -07:00
|
|
|
if (o->items) w = obj->cur->geometry.w + (l - pl) + (r - pr);
|
|
|
|
h = obj->cur->geometry.h + (t - pt) + (b - pb);
|
2013-03-12 05:58:19 -07:00
|
|
|
|
2017-09-15 02:37:25 -07:00
|
|
|
efl_gfx_size_set(efl_super(eo_obj, MY_CLASS), EINA_SIZE2D(w, h));
|
2014-07-16 04:30:51 -07:00
|
|
|
evas_object_change(eo_obj, obj);
|
2005-11-26 00:04:20 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static Evas_Text_Style_Type
|
|
|
|
_evas_text_style_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
return o->cur.style;
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
|
|
|
_evas_text_shadow_color_set(Eo *eo_obj, Evas_Text_Data *o, int r, int g, int b, int a)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2005-11-26 00:04:20 -08:00
|
|
|
if ((o->cur.shadow.r == r) && (o->cur.shadow.g == g) &&
|
|
|
|
(o->cur.shadow.b == b) && (o->cur.shadow.a == a))
|
|
|
|
return;
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_object_async_block(obj);
|
2005-11-26 00:04:20 -08:00
|
|
|
o->cur.shadow.r = r;
|
|
|
|
o->cur.shadow.g = g;
|
|
|
|
o->cur.shadow.b = b;
|
|
|
|
o->cur.shadow.a = a;
|
2010-03-06 20:48:52 -08:00
|
|
|
o->changed = 1;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_change(eo_obj, obj);
|
2005-11-26 00:04:20 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
|
|
|
_evas_text_shadow_color_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o, int *r, int *g, int *b, int *a)
|
2005-11-26 00:04:20 -08:00
|
|
|
{
|
|
|
|
if (r) *r = o->cur.shadow.r;
|
|
|
|
if (g) *g = o->cur.shadow.g;
|
|
|
|
if (b) *b = o->cur.shadow.b;
|
|
|
|
if (a) *a = o->cur.shadow.a;
|
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
|
|
|
_evas_text_glow_color_set(Eo *eo_obj, Evas_Text_Data *o, int r, int g, int b, int a)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2005-11-26 00:04:20 -08:00
|
|
|
if ((o->cur.glow.r == r) && (o->cur.glow.g == g) &&
|
|
|
|
(o->cur.glow.b == b) && (o->cur.glow.a == a))
|
|
|
|
return;
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_object_async_block(obj);
|
2005-11-26 00:04:20 -08:00
|
|
|
o->cur.glow.r = r;
|
|
|
|
o->cur.glow.g = g;
|
|
|
|
o->cur.glow.b = b;
|
|
|
|
o->cur.glow.a = a;
|
2010-03-06 20:48:52 -08:00
|
|
|
o->changed = 1;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_change(eo_obj, obj);
|
2005-11-26 00:04:20 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
|
|
|
_evas_text_glow_color_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o, int *r, int *g, int *b, int *a)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2005-11-26 00:04:20 -08:00
|
|
|
if (r) *r = o->cur.glow.r;
|
|
|
|
if (g) *g = o->cur.glow.g;
|
|
|
|
if (b) *b = o->cur.glow.b;
|
|
|
|
if (a) *a = o->cur.glow.a;
|
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
|
|
|
_evas_text_glow2_color_set(Eo *eo_obj, Evas_Text_Data *o, int r, int g, int b, int a)
|
2005-11-26 00:04:20 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2005-11-26 00:04:20 -08:00
|
|
|
if ((o->cur.glow2.r == r) && (o->cur.glow2.g == g) &&
|
|
|
|
(o->cur.glow2.b == b) && (o->cur.glow2.a == a))
|
|
|
|
return;
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_object_async_block(obj);
|
2005-11-26 00:04:20 -08:00
|
|
|
o->cur.glow2.r = r;
|
|
|
|
o->cur.glow2.g = g;
|
|
|
|
o->cur.glow2.b = b;
|
|
|
|
o->cur.glow2.a = a;
|
2010-03-06 20:48:52 -08:00
|
|
|
o->changed = 1;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_change(eo_obj, obj);
|
2005-11-26 00:04:20 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
|
|
|
_evas_text_glow2_color_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o, int *r, int *g, int *b, int *a)
|
2005-11-26 00:04:20 -08:00
|
|
|
{
|
|
|
|
if (r) *r = o->cur.glow2.r;
|
|
|
|
if (g) *g = o->cur.glow2.g;
|
|
|
|
if (b) *b = o->cur.glow2.b;
|
|
|
|
if (a) *a = o->cur.glow2.a;
|
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
|
|
|
_evas_text_outline_color_set(Eo *eo_obj, Evas_Text_Data *o, int r, int g, int b, int a)
|
2005-11-26 00:04:20 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2005-11-26 00:04:20 -08:00
|
|
|
if ((o->cur.outline.r == r) && (o->cur.outline.g == g) &&
|
|
|
|
(o->cur.outline.b == b) && (o->cur.outline.a == a))
|
|
|
|
return;
|
2015-02-10 03:44:38 -08:00
|
|
|
evas_object_async_block(obj);
|
2005-11-26 00:04:20 -08:00
|
|
|
o->cur.outline.r = r;
|
|
|
|
o->cur.outline.g = g;
|
|
|
|
o->cur.outline.b = b;
|
|
|
|
o->cur.outline.a = a;
|
2010-03-06 20:48:52 -08:00
|
|
|
o->changed = 1;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_change(eo_obj, obj);
|
2005-11-26 00:04:20 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
|
|
|
_evas_text_outline_color_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o, int *r, int *g, int *b, int *a)
|
2012-10-08 18:58:41 -07:00
|
|
|
{
|
2005-11-26 00:04:20 -08:00
|
|
|
if (r) *r = o->cur.outline.r;
|
|
|
|
if (g) *g = o->cur.outline.g;
|
|
|
|
if (b) *b = o->cur.outline.b;
|
|
|
|
if (a) *a = o->cur.outline.a;
|
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
2015-06-17 00:26:30 -07:00
|
|
|
_evas_text_style_pad_get(Eo *eo_obj, Evas_Text_Data *o, int *l, int *r, int *t, int *b)
|
2005-11-26 00:04:20 -08:00
|
|
|
{
|
2015-06-17 00:26:30 -07:00
|
|
|
_evas_object_text_pad_get(eo_obj, o, l, r, t, b);
|
2005-11-26 00:04:20 -08:00
|
|
|
}
|
|
|
|
|
2006-01-06 15:05:17 -08:00
|
|
|
EAPI int
|
2003-06-04 23:08:43 -07:00
|
|
|
evas_string_char_next_get(const char *str, int pos, int *decoded)
|
|
|
|
{
|
|
|
|
int p, d;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2013-01-17 01:38:49 -08:00
|
|
|
if ((!str) || (pos < 0))
|
|
|
|
{
|
|
|
|
if (decoded) *decoded = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
2003-06-04 23:08:43 -07:00
|
|
|
p = pos;
|
2013-01-21 18:14:07 -08:00
|
|
|
d = eina_unicode_utf8_next_get(str, &p);
|
2003-06-04 23:08:43 -07:00
|
|
|
if (decoded) *decoded = d;
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2006-01-06 15:05:17 -08:00
|
|
|
EAPI int
|
2003-06-04 23:08:43 -07:00
|
|
|
evas_string_char_prev_get(const char *str, int pos, int *decoded)
|
|
|
|
{
|
|
|
|
int p, d;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2003-06-04 23:08:43 -07:00
|
|
|
if (decoded) *decoded = 0;
|
2010-07-17 12:49:16 -07:00
|
|
|
if ((!str) || (pos < 1)) return 0;
|
2003-06-04 23:08:43 -07:00
|
|
|
p = pos;
|
2011-02-16 08:00:17 -08:00
|
|
|
d = eina_unicode_utf8_get_prev(str, &p);
|
2003-06-04 23:08:43 -07:00
|
|
|
if (decoded) *decoded = d;
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2008-12-15 14:03:04 -08:00
|
|
|
EAPI int
|
|
|
|
evas_string_char_len_get(const char *str)
|
|
|
|
{
|
2010-07-17 12:49:16 -07:00
|
|
|
if (!str) return 0;
|
2011-02-16 08:00:17 -08:00
|
|
|
return eina_unicode_utf8_get_len(str);
|
2008-12-15 14:03:04 -08:00
|
|
|
}
|
|
|
|
|
2005-11-26 00:04:20 -08:00
|
|
|
void
|
|
|
|
evas_text_style_pad_get(Evas_Text_Style_Type style, int *l, int *r, int *t, int *b)
|
|
|
|
{
|
2011-04-11 05:05:59 -07:00
|
|
|
int sl = 0, sr = 0, st = 0, sb = 0;
|
2011-05-08 08:43:44 -07:00
|
|
|
|
|
|
|
/* Don't calc anything if there's no style. */
|
2011-05-09 00:40:14 -07:00
|
|
|
if (style != EVAS_TEXT_STYLE_PLAIN)
|
2011-04-11 05:05:59 -07:00
|
|
|
{
|
2011-05-09 00:40:14 -07:00
|
|
|
int shad_sz = 0, shad_dst = 0, out_sz = 0;
|
|
|
|
int dx = 0, minx = 0, maxx = 0;
|
|
|
|
int dy = 0, miny = 0, maxy = 0;
|
|
|
|
Eina_Bool have_shadow = EINA_FALSE;
|
2011-05-08 08:43:44 -07:00
|
|
|
|
2011-05-09 00:40:14 -07:00
|
|
|
switch (style & EVAS_TEXT_STYLE_MASK_BASIC)
|
2011-05-08 08:43:44 -07:00
|
|
|
{
|
2011-05-09 00:40:14 -07:00
|
|
|
case EVAS_TEXT_STYLE_SHADOW:
|
|
|
|
shad_dst = 1;
|
|
|
|
have_shadow = EINA_TRUE;
|
2011-05-08 08:43:44 -07:00
|
|
|
break;
|
2011-05-09 00:40:14 -07:00
|
|
|
case EVAS_TEXT_STYLE_OUTLINE_SHADOW:
|
|
|
|
case EVAS_TEXT_STYLE_FAR_SHADOW:
|
|
|
|
shad_dst = 2;
|
|
|
|
out_sz = 1;
|
|
|
|
have_shadow = EINA_TRUE;
|
2011-05-08 08:43:44 -07:00
|
|
|
break;
|
2011-05-09 00:40:14 -07:00
|
|
|
case EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW:
|
|
|
|
shad_dst = 1;
|
|
|
|
shad_sz = 2;
|
|
|
|
out_sz = 1;
|
|
|
|
have_shadow = EINA_TRUE;
|
2011-05-08 08:43:44 -07:00
|
|
|
break;
|
2011-05-09 00:40:14 -07:00
|
|
|
case EVAS_TEXT_STYLE_FAR_SOFT_SHADOW:
|
|
|
|
shad_dst = 2;
|
|
|
|
shad_sz = 2;
|
|
|
|
have_shadow = EINA_TRUE;
|
2011-05-08 08:43:44 -07:00
|
|
|
break;
|
2011-05-09 00:40:14 -07:00
|
|
|
case EVAS_TEXT_STYLE_SOFT_SHADOW:
|
|
|
|
shad_dst = 1;
|
|
|
|
shad_sz = 2;
|
|
|
|
have_shadow = EINA_TRUE;
|
2011-05-08 08:43:44 -07:00
|
|
|
break;
|
2011-05-09 00:40:14 -07:00
|
|
|
case EVAS_TEXT_STYLE_GLOW:
|
|
|
|
case EVAS_TEXT_STYLE_SOFT_OUTLINE:
|
|
|
|
out_sz = 2;
|
2011-05-08 08:43:44 -07:00
|
|
|
break;
|
2011-05-09 00:40:14 -07:00
|
|
|
case EVAS_TEXT_STYLE_OUTLINE:
|
|
|
|
out_sz = 1;
|
2011-05-08 08:43:44 -07:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2005-11-26 00:04:20 -08:00
|
|
|
|
2011-05-09 00:40:14 -07:00
|
|
|
minx = -out_sz;
|
|
|
|
maxx = out_sz;
|
|
|
|
miny = -out_sz;
|
|
|
|
maxy = out_sz;
|
|
|
|
if (have_shadow)
|
|
|
|
{
|
|
|
|
int shx1, shx2, shy1, shy2;
|
|
|
|
switch (style & EVAS_TEXT_STYLE_MASK_SHADOW_DIRECTION)
|
|
|
|
{
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT:
|
|
|
|
dx = 1;
|
|
|
|
dy = 1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM:
|
|
|
|
dx = 0;
|
|
|
|
dy = 1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_LEFT:
|
|
|
|
dx = -1;
|
|
|
|
dy = 1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_LEFT:
|
|
|
|
dx = -1;
|
|
|
|
dy = 0;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_LEFT:
|
|
|
|
dx = -1;
|
|
|
|
dy = -1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP:
|
|
|
|
dx = 0;
|
|
|
|
dy = -1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT:
|
|
|
|
dx = 1;
|
|
|
|
dy = -1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_RIGHT:
|
|
|
|
dx = 1;
|
|
|
|
dy = 0;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
shx1 = dx * shad_dst;
|
|
|
|
shx1 -= shad_sz;
|
|
|
|
shx2 = dx * shad_dst;
|
|
|
|
shx2 += shad_sz;
|
|
|
|
if (shx1 < minx) minx = shx1;
|
|
|
|
if (shx2 > maxx) maxx = shx2;
|
|
|
|
|
|
|
|
shy1 = dy * shad_dst;
|
|
|
|
shy1 -= shad_sz;
|
|
|
|
shy2 = dy * shad_dst;
|
|
|
|
shy2 += shad_sz;
|
|
|
|
if (shy1 < miny) miny = shy1;
|
|
|
|
if (shy2 > maxy) maxy = shy2;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (l) sl = *l;
|
|
|
|
if (r) sr = *r;
|
|
|
|
if (t) st = *t;
|
|
|
|
if (b) sb = *b;
|
2005-11-26 00:04:20 -08:00
|
|
|
|
2011-05-09 00:40:14 -07:00
|
|
|
if (sr < maxx) sr = maxx;
|
|
|
|
if (sl < -minx) sl = -minx;
|
|
|
|
if (sb < maxy) sb = maxy;
|
|
|
|
if (st < -miny) st = -miny;
|
|
|
|
}
|
2009-09-03 22:13:19 -07:00
|
|
|
|
2005-11-26 00:04:20 -08:00
|
|
|
if (l) *l = sl;
|
|
|
|
if (r) *r = sr;
|
|
|
|
if (t) *t = st;
|
2005-11-26 05:58:33 -08:00
|
|
|
if (b) *b = sb;
|
2005-11-26 00:04:20 -08:00
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
|
|
|
|
/* all nice and private */
|
|
|
|
static void
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_text_init(Evas_Object *eo_obj)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2002-11-08 00:02:15 -08:00
|
|
|
/* set up methods (compulsory) */
|
|
|
|
obj->func = &object_func;
|
2016-08-15 06:44:41 -07:00
|
|
|
obj->private_data = efl_data_ref(eo_obj, MY_CLASS);
|
2002-11-08 00:02:15 -08:00
|
|
|
obj->type = o_type;
|
2005-05-21 19:49:50 -07:00
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
Evas_Text_Data *o = obj->private_data;
|
2002-11-08 00:02:15 -08:00
|
|
|
/* alloc obj private data */
|
2016-02-16 07:14:38 -08:00
|
|
|
o->prev.ellipsis = o->cur.ellipsis = -1.0;
|
2017-09-25 02:34:22 -07:00
|
|
|
o->prev.bitmap_scalable = o->cur.bitmap_scalable = EFL_TEXT_FONT_BITMAP_SCALABLE_COLOR;
|
2002-11-08 00:02:15 -08:00
|
|
|
o->prev = o->cur;
|
2010-09-01 07:26:55 -07:00
|
|
|
#ifdef BIDI_SUPPORT
|
2011-01-30 02:36:02 -08:00
|
|
|
o->bidi_par_props = evas_bidi_paragraph_props_new();
|
2015-11-19 03:37:07 -08:00
|
|
|
o->inherit_paragraph_direction = EINA_TRUE;
|
2010-09-01 07:26:55 -07:00
|
|
|
#endif
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
EOLIAN static void
|
2016-08-10 07:23:04 -07:00
|
|
|
_evas_text_efl_object_destructor(Eo *eo_obj, Evas_Text_Data *o EINA_UNUSED)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_text_free(eo_obj, obj);
|
2016-08-15 06:44:41 -07:00
|
|
|
efl_destructor(efl_super(eo_obj, MY_CLASS));
|
2012-10-08 18:58:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_object_text_free(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
|
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
|
2002-11-08 00:02:15 -08:00
|
|
|
|
|
|
|
/* free obj */
|
2013-08-27 01:20:56 -07:00
|
|
|
_evas_object_text_items_clear(o);
|
2010-07-28 05:00:41 -07:00
|
|
|
if (o->cur.utf8_text) eina_stringshare_del(o->cur.utf8_text);
|
2008-10-15 07:38:34 -07:00
|
|
|
if (o->cur.font) eina_stringshare_del(o->cur.font);
|
2011-08-01 01:20:52 -07:00
|
|
|
if (o->cur.fdesc) evas_font_desc_unref(o->cur.fdesc);
|
2008-10-15 07:38:34 -07:00
|
|
|
if (o->cur.source) eina_stringshare_del(o->cur.source);
|
2015-10-20 11:51:17 -07:00
|
|
|
if (o->bidi_delimiters) eina_stringshare_del(o->bidi_delimiters);
|
2012-12-17 05:04:35 -08:00
|
|
|
if (o->cur.text) free(o->cur.text);
|
2013-03-26 04:09:41 -07:00
|
|
|
if (o->font && obj->layer && obj->layer->evas)
|
2017-11-06 18:22:09 -08:00
|
|
|
evas_font_free(o->font);
|
2013-08-26 20:43:22 -07:00
|
|
|
o->font = NULL;
|
2016-02-15 02:41:37 -08:00
|
|
|
o->cur.utf8_text = NULL;
|
|
|
|
o->cur.font = NULL;
|
|
|
|
o->cur.fdesc = NULL;
|
|
|
|
o->cur.source = NULL;
|
|
|
|
o->bidi_delimiters = NULL;
|
|
|
|
o->cur.text = NULL;
|
|
|
|
o->prev = o->cur;
|
2010-09-01 07:26:55 -07:00
|
|
|
#ifdef BIDI_SUPPORT
|
2011-01-30 02:36:02 -08:00
|
|
|
evas_bidi_paragraph_props_unref(o->bidi_par_props);
|
2016-02-15 02:41:37 -08:00
|
|
|
o->bidi_par_props = NULL;
|
2010-09-01 07:26:55 -07:00
|
|
|
#endif
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2013-01-11 11:55:40 -08:00
|
|
|
void
|
|
|
|
evas_font_draw_async_check(Evas_Object_Protected_Data *obj,
|
2017-05-12 15:03:05 -07:00
|
|
|
void *engine, void *data, void *context, void *surface,
|
2013-01-11 11:55:40 -08:00
|
|
|
Evas_Font_Set *font,
|
|
|
|
int x, int y, int w, int h, int ow, int oh,
|
|
|
|
Evas_Text_Props *intl_props, Eina_Bool do_async)
|
|
|
|
{
|
|
|
|
Eina_Bool async_unref;
|
|
|
|
|
2017-05-12 15:03:05 -07:00
|
|
|
async_unref = obj->layer->evas->engine.func->font_draw(engine, data, context, surface,
|
2013-01-11 11:55:40 -08:00
|
|
|
font, x, y, w, h, ow, oh,
|
|
|
|
intl_props, do_async);
|
|
|
|
if (do_async && async_unref)
|
|
|
|
{
|
|
|
|
evas_common_font_glyphs_ref(intl_props->glyphs);
|
|
|
|
evas_unref_queue_glyph_put(obj->layer->evas, intl_props->glyphs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-17 00:26:30 -07:00
|
|
|
/* ugly binding between evas_fitler_mixin.c and this object */
|
2014-03-03 22:17:11 -08:00
|
|
|
|
2016-01-12 22:19:07 -08:00
|
|
|
EOLIAN static void
|
2016-06-09 23:55:28 -07:00
|
|
|
_evas_text_efl_canvas_filter_internal_filter_dirty(Eo *eo_obj, Evas_Text_Data *o)
|
2015-06-17 00:26:30 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2016-03-01 21:41:32 -08:00
|
|
|
|
2015-06-17 00:26:30 -07:00
|
|
|
_evas_object_text_items_clear(o);
|
|
|
|
o->changed = 1;
|
2016-03-01 21:41:32 -08:00
|
|
|
evas_object_change(eo_obj, obj);
|
2015-06-17 00:26:30 -07:00
|
|
|
_evas_object_text_recalc(eo_obj, o->cur.text);
|
|
|
|
}
|
2014-03-03 22:17:11 -08:00
|
|
|
|
2016-01-12 22:19:07 -08:00
|
|
|
EOLIAN static Eina_Bool
|
2016-06-09 23:55:28 -07:00
|
|
|
_evas_text_efl_canvas_filter_internal_filter_input_alpha(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o EINA_UNUSED)
|
2015-06-18 05:45:21 -07:00
|
|
|
{
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2016-12-22 02:41:04 -08:00
|
|
|
EOLIAN static void
|
|
|
|
_evas_text_efl_canvas_filter_internal_filter_state_prepare(Eo *eo_obj, Evas_Text_Data *o,
|
|
|
|
Efl_Canvas_Filter_State *state, void *data EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
|
|
|
|
|
|
|
#define STATE_COLOR(dst, src) dst.r = src.r; dst.g = src.g; dst.b = src.b; dst.a = src.a
|
|
|
|
STATE_COLOR(state->color, obj->cur->color);
|
|
|
|
STATE_COLOR(state->text.glow, o->cur.glow);
|
|
|
|
STATE_COLOR(state->text.glow2, o->cur.glow2);
|
|
|
|
STATE_COLOR(state->text.shadow, o->cur.shadow);
|
|
|
|
STATE_COLOR(state->text.outline, o->cur.outline);
|
|
|
|
#undef STATE_COLOR
|
|
|
|
|
|
|
|
state->w = obj->cur->geometry.w;
|
|
|
|
state->h = obj->cur->geometry.h;
|
|
|
|
state->scale = obj->cur->scale;
|
|
|
|
}
|
|
|
|
|
2016-01-12 22:19:07 -08:00
|
|
|
EOLIAN static Eina_Bool
|
2016-06-09 23:55:28 -07:00
|
|
|
_evas_text_efl_canvas_filter_internal_filter_input_render(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o,
|
2017-05-12 15:03:05 -07:00
|
|
|
void *_filter, void *engine, void *output, void *drawctx, void *draw EINA_UNUSED,
|
2016-12-22 02:41:04 -08:00
|
|
|
int l, int r EINA_UNUSED, int t, int b EINA_UNUSED,
|
2017-01-10 03:07:51 -08:00
|
|
|
int x, int y,
|
2016-12-22 02:41:04 -08:00
|
|
|
Eina_Bool do_async)
|
2015-06-17 00:26:30 -07:00
|
|
|
{
|
|
|
|
Evas_Filter_Context *filter = _filter;
|
|
|
|
Evas_Object_Text_Item *it;
|
2014-03-03 22:17:11 -08:00
|
|
|
|
2015-06-17 00:26:30 -07:00
|
|
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
|
|
|
|
if ((o->font) && (it->text_props.len > 0))
|
|
|
|
{
|
2017-05-12 15:03:05 -07:00
|
|
|
if (!evas_filter_font_draw(filter, engine, output, drawctx,
|
2015-06-18 05:45:21 -07:00
|
|
|
EVAS_FILTER_BUFFER_INPUT_ID, o->font,
|
2017-01-10 03:07:51 -08:00
|
|
|
x + l + it->x,
|
|
|
|
y + t + (int) o->max_ascent,
|
2015-06-18 05:45:21 -07:00
|
|
|
&it->text_props,
|
|
|
|
do_async))
|
|
|
|
return EINA_FALSE;
|
2015-06-17 00:26:30 -07:00
|
|
|
}
|
2015-06-18 05:45:21 -07:00
|
|
|
|
|
|
|
return EINA_TRUE;
|
2014-03-03 22:17:11 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
evas_object_text_render(Evas_Object *eo_obj,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
void *type_private_data,
|
2017-05-12 15:03:05 -07:00
|
|
|
void *engine, void *output, void *context, void *surface,
|
2013-12-09 03:55:38 -08:00
|
|
|
int x, int y, Eina_Bool do_async)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2005-11-26 00:04:20 -08:00
|
|
|
int i, j;
|
2014-03-09 00:31:28 -08:00
|
|
|
Evas_Text_Data *o = type_private_data;
|
2011-01-30 02:36:02 -08:00
|
|
|
Evas_Object_Text_Item *it;
|
2005-11-26 00:04:20 -08:00
|
|
|
const char vals[5][5] =
|
|
|
|
{
|
2015-11-17 03:22:17 -08:00
|
|
|
{0, 1, 2, 1, 0},
|
|
|
|
{1, 3, 4, 3, 1},
|
|
|
|
{2, 4, 5, 4, 2},
|
|
|
|
{1, 3, 4, 3, 1},
|
|
|
|
{0, 1, 2, 1, 0}
|
2005-11-26 00:04:20 -08:00
|
|
|
};
|
2006-02-15 18:06:55 -08:00
|
|
|
int sl = 0, st = 0;
|
2013-12-09 03:55:38 -08:00
|
|
|
int shad_dst = 0, shad_sz = 0, dx = 0, dy = 0, haveshad = 0;
|
2002-11-08 00:02:15 -08:00
|
|
|
|
|
|
|
/* render object to surface with context, and offxet by x,y */
|
2015-06-17 00:26:30 -07:00
|
|
|
_evas_object_text_pad_get(eo_obj, o, &sl, NULL, &st, NULL);
|
2017-05-12 15:03:05 -07:00
|
|
|
ENFN->context_multiplier_unset(engine, context);
|
|
|
|
ENFN->context_render_op_set(engine, context, obj->cur->render_op);
|
2011-03-29 06:52:42 -07:00
|
|
|
/* FIXME: This clipping is just until we fix inset handling correctly. */
|
2017-05-12 15:03:05 -07:00
|
|
|
ENFN->context_clip_clip(engine, context,
|
|
|
|
obj->cur->geometry.x + x,
|
|
|
|
obj->cur->geometry.y + y,
|
|
|
|
obj->cur->geometry.w,
|
|
|
|
obj->cur->geometry.h);
|
2013-12-09 03:55:38 -08:00
|
|
|
|
2005-05-21 19:49:50 -07:00
|
|
|
/*
|
2005-11-26 00:04:20 -08:00
|
|
|
ENFN->context_color_set(output,
|
2009-02-22 23:21:37 -08:00
|
|
|
context,
|
|
|
|
230, 160, 30, 100);
|
2005-11-26 00:04:20 -08:00
|
|
|
ENFN->rectangle_draw(output,
|
2009-02-22 23:21:37 -08:00
|
|
|
context,
|
|
|
|
surface,
|
2013-03-12 05:58:19 -07:00
|
|
|
obj->cur->geometry.x + x,
|
|
|
|
obj->cur->geometry.y + y,
|
|
|
|
obj->cur->geometry.w,
|
|
|
|
obj->cur->geometry.h);
|
2003-04-20 01:26:32 -07:00
|
|
|
*/
|
2005-11-26 07:56:51 -08:00
|
|
|
#define COLOR_ONLY_SET(object, sub, col) \
|
2017-05-12 15:03:05 -07:00
|
|
|
ENFN->context_color_set(engine, context, \
|
2015-11-17 03:22:17 -08:00
|
|
|
object->sub.col.r, \
|
|
|
|
object->sub.col.g, \
|
|
|
|
object->sub.col.b, \
|
|
|
|
object->sub.col.a);
|
2005-11-26 00:04:20 -08:00
|
|
|
|
2005-11-26 07:56:51 -08:00
|
|
|
#define COLOR_SET(object, sub, col) \
|
2013-03-12 05:58:19 -07:00
|
|
|
if (obj->cur->clipper)\
|
2015-11-17 03:22:17 -08:00
|
|
|
{ \
|
2017-05-12 15:03:05 -07:00
|
|
|
ENFN->context_color_set(engine, context, \
|
2015-11-17 03:22:17 -08:00
|
|
|
((int)object->sub.col.r * ((int)obj->cur->clipper->cur->cache.clip.r + 1)) >> 8, \
|
|
|
|
((int)object->sub.col.g * ((int)obj->cur->clipper->cur->cache.clip.g + 1)) >> 8, \
|
|
|
|
((int)object->sub.col.b * ((int)obj->cur->clipper->cur->cache.clip.b + 1)) >> 8, \
|
|
|
|
((int)object->sub.col.a * ((int)obj->cur->clipper->cur->cache.clip.a + 1)) >> 8); \
|
|
|
|
} \
|
2006-01-14 01:26:22 -08:00
|
|
|
else\
|
2017-05-12 15:03:05 -07:00
|
|
|
ENFN->context_color_set(engine, context, \
|
2015-11-17 03:22:17 -08:00
|
|
|
object->sub.col.r, \
|
|
|
|
object->sub.col.g, \
|
|
|
|
object->sub.col.b, \
|
|
|
|
object->sub.col.a);
|
2005-11-26 07:56:51 -08:00
|
|
|
|
2005-11-26 00:04:20 -08:00
|
|
|
#define COLOR_SET_AMUL(object, sub, col, amul) \
|
2013-03-12 05:58:19 -07:00
|
|
|
if (obj->cur->clipper) \
|
2015-11-17 03:22:17 -08:00
|
|
|
{ \
|
2017-05-12 15:03:05 -07:00
|
|
|
ENFN->context_color_set(engine, context, \
|
2015-11-17 03:22:17 -08:00
|
|
|
(((int)object->sub.col.r) * ((int)obj->cur->clipper->cur->cache.clip.r) * (amul)) / 65025, \
|
|
|
|
(((int)object->sub.col.g) * ((int)obj->cur->clipper->cur->cache.clip.g) * (amul)) / 65025, \
|
|
|
|
(((int)object->sub.col.b) * ((int)obj->cur->clipper->cur->cache.clip.b) * (amul)) / 65025, \
|
|
|
|
(((int)object->sub.col.a) * ((int)obj->cur->clipper->cur->cache.clip.a) * (amul)) / 65025); \
|
|
|
|
} \
|
2006-01-14 01:26:22 -08:00
|
|
|
else \
|
2017-05-12 15:03:05 -07:00
|
|
|
ENFN->context_color_set(engine, context, \
|
2015-11-17 03:22:17 -08:00
|
|
|
(((int)object->sub.col.r) * (amul)) / 255, \
|
|
|
|
(((int)object->sub.col.g) * (amul)) / 255, \
|
|
|
|
(((int)object->sub.col.b) * (amul)) / 255, \
|
|
|
|
(((int)object->sub.col.a) * (amul)) / 255);
|
2005-11-26 00:04:20 -08:00
|
|
|
|
2016-12-30 01:55:55 -08:00
|
|
|
#define DRAW_TEXT(ox, oy) \
|
2017-05-12 15:03:05 -07:00
|
|
|
if ((o->font) && (it->text_props.len > 0)) { \
|
|
|
|
ENFN->context_cutout_target(engine, context, \
|
2016-12-30 01:55:55 -08:00
|
|
|
obj->cur->geometry.x + x + sl + ox + it->x, \
|
2017-05-12 15:03:05 -07:00
|
|
|
obj->cur->geometry.y + y + st + oy, \
|
|
|
|
it->w, it->h); \
|
2017-08-25 10:49:49 -07:00
|
|
|
evas_font_draw_async_check(obj, engine, \
|
|
|
|
output, \
|
2017-05-12 15:03:05 -07:00
|
|
|
context, \
|
|
|
|
surface, \
|
|
|
|
o->font, \
|
|
|
|
obj->cur->geometry.x + x + sl + ox + it->x, \
|
|
|
|
obj->cur->geometry.y + y + st + oy + \
|
|
|
|
(int)o->max_ascent, \
|
|
|
|
obj->cur->geometry.w, \
|
|
|
|
obj->cur->geometry.h, \
|
|
|
|
obj->cur->geometry.w, \
|
|
|
|
obj->cur->geometry.h, \
|
|
|
|
&it->text_props, \
|
|
|
|
do_async); \
|
2016-12-30 01:55:55 -08:00
|
|
|
}
|
2011-04-11 05:05:59 -07:00
|
|
|
|
2015-06-17 00:26:30 -07:00
|
|
|
if (o->has_filter)
|
2013-12-09 03:55:38 -08:00
|
|
|
{
|
2017-05-12 15:03:05 -07:00
|
|
|
if (evas_filter_object_render(eo_obj, obj,
|
|
|
|
engine, output, context, surface,
|
|
|
|
x, y, do_async, EINA_TRUE))
|
2015-06-17 00:26:30 -07:00
|
|
|
return;
|
2013-12-09 03:55:38 -08:00
|
|
|
}
|
|
|
|
|
2011-04-29 12:26:56 -07:00
|
|
|
/* shadows */
|
|
|
|
switch (o->cur.style & EVAS_TEXT_STYLE_MASK_BASIC)
|
|
|
|
{
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW:
|
2015-11-23 03:53:29 -08:00
|
|
|
shad_dst = 1;
|
|
|
|
haveshad = 1;
|
|
|
|
break;
|
2011-04-29 12:26:56 -07:00
|
|
|
case EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW:
|
|
|
|
shad_dst = 1;
|
2015-11-23 03:53:29 -08:00
|
|
|
shad_sz = 2;
|
2011-04-29 12:26:56 -07:00
|
|
|
haveshad = 1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_OUTLINE_SHADOW:
|
|
|
|
case EVAS_TEXT_STYLE_FAR_SHADOW:
|
|
|
|
shad_dst = 2;
|
|
|
|
haveshad = 1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_FAR_SOFT_SHADOW:
|
|
|
|
shad_dst = 2;
|
|
|
|
shad_sz = 2;
|
|
|
|
haveshad = 1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SOFT_SHADOW:
|
|
|
|
shad_dst = 1;
|
|
|
|
shad_sz = 2;
|
|
|
|
haveshad = 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (haveshad)
|
|
|
|
{
|
|
|
|
if (shad_dst > 0)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2011-04-29 12:26:56 -07:00
|
|
|
switch (o->cur.style & EVAS_TEXT_STYLE_MASK_SHADOW_DIRECTION)
|
|
|
|
{
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT:
|
|
|
|
dx = 1;
|
|
|
|
dy = 1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM:
|
|
|
|
dx = 0;
|
|
|
|
dy = 1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_LEFT:
|
|
|
|
dx = -1;
|
|
|
|
dy = 1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_LEFT:
|
|
|
|
dx = -1;
|
|
|
|
dy = 0;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_LEFT:
|
|
|
|
dx = -1;
|
|
|
|
dy = -1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP:
|
|
|
|
dx = 0;
|
|
|
|
dy = -1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT:
|
|
|
|
dx = 1;
|
|
|
|
dy = -1;
|
|
|
|
break;
|
|
|
|
case EVAS_TEXT_STYLE_SHADOW_DIRECTION_RIGHT:
|
|
|
|
dx = 1;
|
|
|
|
dy = 0;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
dx *= shad_dst;
|
|
|
|
dy *= shad_dst;
|
2011-01-30 02:36:02 -08:00
|
|
|
}
|
2011-04-29 12:26:56 -07:00
|
|
|
}
|
|
|
|
EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
|
|
|
|
{
|
2017-05-12 15:03:05 -07:00
|
|
|
ENFN->context_multiplier_set(engine, context, 0, 0, 0, 0);
|
2011-04-29 12:26:56 -07:00
|
|
|
/* Shadows */
|
2011-04-13 02:29:45 -07:00
|
|
|
if (haveshad)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2011-04-13 02:29:45 -07:00
|
|
|
switch (shad_sz)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2011-04-13 02:29:45 -07:00
|
|
|
case 0:
|
|
|
|
COLOR_SET(o, cur, shadow);
|
|
|
|
DRAW_TEXT(dx, dy);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
for (j = 0; j < 5; j++)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2011-04-13 02:29:45 -07:00
|
|
|
for (i = 0; i < 5; i++)
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
2011-04-13 02:29:45 -07:00
|
|
|
if (vals[i][j] != 0)
|
|
|
|
{
|
|
|
|
COLOR_SET_AMUL(o, cur, shadow, vals[i][j] * 50);
|
|
|
|
DRAW_TEXT(i - 2 + dx, j - 2 + dy);
|
|
|
|
}
|
2011-01-30 02:36:02 -08:00
|
|
|
}
|
|
|
|
}
|
2011-04-13 02:29:45 -07:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2011-01-30 02:36:02 -08:00
|
|
|
}
|
|
|
|
}
|
2011-04-29 12:26:56 -07:00
|
|
|
|
2011-01-30 02:36:02 -08:00
|
|
|
/* glows */
|
|
|
|
if (o->cur.style == EVAS_TEXT_STYLE_GLOW)
|
|
|
|
{
|
|
|
|
for (j = 0; j < 5; j++)
|
|
|
|
{
|
|
|
|
for (i = 0; i < 5; i++)
|
|
|
|
{
|
|
|
|
if (vals[i][j] != 0)
|
|
|
|
{
|
|
|
|
COLOR_SET_AMUL(o, cur, glow, vals[i][j] * 50);
|
|
|
|
DRAW_TEXT(i - 2, j - 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
COLOR_SET(o, cur, glow2);
|
|
|
|
DRAW_TEXT(-1, 0);
|
|
|
|
DRAW_TEXT(1, 0);
|
|
|
|
DRAW_TEXT(0, -1);
|
|
|
|
DRAW_TEXT(0, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* outlines */
|
2015-11-23 03:53:29 -08:00
|
|
|
if (((o->cur.style & EVAS_TEXT_STYLE_MASK_BASIC) == EVAS_TEXT_STYLE_OUTLINE) ||
|
|
|
|
((o->cur.style & EVAS_TEXT_STYLE_MASK_BASIC) == EVAS_TEXT_STYLE_OUTLINE_SHADOW) ||
|
|
|
|
((o->cur.style & EVAS_TEXT_STYLE_MASK_BASIC) == EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW))
|
2011-01-30 02:36:02 -08:00
|
|
|
{
|
|
|
|
COLOR_SET(o, cur, outline);
|
|
|
|
DRAW_TEXT(-1, 0);
|
|
|
|
DRAW_TEXT(1, 0);
|
|
|
|
DRAW_TEXT(0, -1);
|
|
|
|
DRAW_TEXT(0, 1);
|
|
|
|
}
|
|
|
|
else if (o->cur.style == EVAS_TEXT_STYLE_SOFT_OUTLINE)
|
|
|
|
{
|
|
|
|
for (j = 0; j < 5; j++)
|
|
|
|
{
|
|
|
|
for (i = 0; i < 5; i++)
|
|
|
|
{
|
|
|
|
if (((i != 2) || (j != 2)) && (vals[i][j] != 0))
|
|
|
|
{
|
|
|
|
COLOR_SET_AMUL(o, cur, outline, vals[i][j] * 50);
|
|
|
|
DRAW_TEXT(i - 2, j - 2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* normal text */
|
2017-05-12 15:03:05 -07:00
|
|
|
ENFN->context_multiplier_unset(engine, context);
|
2015-03-23 20:53:34 -07:00
|
|
|
|
|
|
|
if (obj->cur->clipper)
|
2017-05-12 15:03:05 -07:00
|
|
|
ENFN->context_multiplier_set(engine, context,
|
2015-03-23 20:53:34 -07:00
|
|
|
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);
|
|
|
|
|
2013-03-12 05:58:19 -07:00
|
|
|
COLOR_ONLY_SET(obj, cur->cache, clip);
|
2011-01-30 02:36:02 -08:00
|
|
|
DRAW_TEXT(0, 0);
|
2017-05-12 15:03:05 -07:00
|
|
|
ENFN->context_multiplier_unset(engine, context);
|
2005-11-26 00:04:20 -08:00
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2013-07-08 17:46:15 -07:00
|
|
|
evas_object_text_render_pre(Evas_Object *eo_obj,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
|
|
|
void *type_private_data)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
Evas_Text_Data *o = type_private_data;
|
2012-12-15 17:49:36 -08:00
|
|
|
int is_v = 0, was_v = 0;
|
2002-11-08 00:02:15 -08:00
|
|
|
/* dont pre-render the obj twice! */
|
|
|
|
if (obj->pre_render_done) return;
|
2013-01-02 21:38:03 -08:00
|
|
|
obj->pre_render_done = EINA_TRUE;
|
2010-07-17 12:49:16 -07:00
|
|
|
/* pre-render phase. this does anything an object needs to do just before
|
2014-03-09 00:31:28 -08:00
|
|
|
rendering. This could mean loading the image data, retrieving it from
|
2010-07-17 12:49:16 -07:00
|
|
|
elsewhere, decoding video etc.
|
2014-03-09 00:31:28 -08:00
|
|
|
Then when this is done the object needs to figure if it changed and
|
2010-07-17 12:49:16 -07:00
|
|
|
if so what and where and add the appropriate redraw rectangles */
|
2002-11-08 00:02:15 -08:00
|
|
|
/* if someone is clipping this obj - go calculate the clipper */
|
2013-03-12 05:58:19 -07:00
|
|
|
if (obj->cur->clipper)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2015-11-17 03:22:17 -08:00
|
|
|
if (obj->cur->cache.clip.dirty)
|
|
|
|
{
|
|
|
|
evas_object_clip_recalc(obj->cur->clipper);
|
|
|
|
}
|
|
|
|
obj->cur->clipper->func->render_pre(obj->cur->clipper->object,
|
|
|
|
obj->cur->clipper,
|
|
|
|
obj->cur->clipper->private_data);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2015-11-19 03:37:07 -08:00
|
|
|
|
|
|
|
#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
|
|
|
|
|
2012-12-12 06:05:29 -08:00
|
|
|
/* If object size changed and ellipsis is set */
|
2016-02-16 07:14:38 -08:00
|
|
|
if (((o->cur.ellipsis >= 0.0) &&
|
2015-11-17 03:22:17 -08:00
|
|
|
((obj->cur->geometry.w != o->last_computed.w) ||
|
|
|
|
(obj->cur->geometry.h != o->last_computed.h))) ||
|
2017-01-06 09:57:46 -08:00
|
|
|
(!EINA_DBL_EQ(o->cur.ellipsis, o->prev.ellipsis)) ||
|
|
|
|
(!EINA_DBL_EQ(obj->cur->scale, obj->prev->scale)) ||
|
2015-11-19 03:37:07 -08:00
|
|
|
(o->changed_paragraph_direction))
|
2012-12-12 06:05:29 -08:00
|
|
|
{
|
2013-09-30 23:29:38 -07:00
|
|
|
_evas_object_text_recalc(eo_obj, o->cur.text);
|
|
|
|
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
|
2015-11-17 03:22:17 -08:00
|
|
|
eo_obj, obj);
|
2013-09-30 23:29:38 -07:00
|
|
|
goto done;
|
2012-12-12 06:05:29 -08:00
|
|
|
}
|
2010-07-17 12:49:16 -07:00
|
|
|
/* now figure what changed and add draw rects
|
|
|
|
if it just became visible or invisible */
|
2012-10-08 18:58:41 -07:00
|
|
|
is_v = evas_object_is_visible(eo_obj, obj);
|
|
|
|
was_v = evas_object_was_visible(eo_obj, obj);
|
2002-11-08 00:02:15 -08:00
|
|
|
if (is_v != was_v)
|
|
|
|
{
|
2015-11-17 03:22:17 -08:00
|
|
|
evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes,
|
|
|
|
eo_obj, is_v, was_v);
|
|
|
|
goto done;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2012-10-25 08:24:27 -07:00
|
|
|
if (obj->changed_map || obj->changed_src_visible)
|
2009-11-06 00:44:49 -08:00
|
|
|
{
|
2015-11-17 03:22:17 -08:00
|
|
|
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
|
|
|
|
eo_obj, obj);
|
2009-11-06 00:44:49 -08:00
|
|
|
goto done;
|
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
/* its not visible - we accounted for it appearing or not so just abort */
|
|
|
|
if (!is_v) goto done;
|
|
|
|
/* clipper changed this is in addition to anything else for obj */
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_render_pre_clipper_change(&obj->layer->evas->clip_changes, eo_obj);
|
2002-11-08 00:02:15 -08:00
|
|
|
/* if we restacked (layer or just within a layer) and dont clip anyone */
|
|
|
|
if (obj->restack)
|
|
|
|
{
|
2015-11-17 03:22:17 -08:00
|
|
|
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
|
|
|
|
eo_obj, obj);
|
|
|
|
goto done;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
/* if it changed color */
|
2013-03-12 05:58:19 -07:00
|
|
|
if ((obj->cur->color.r != obj->prev->color.r) ||
|
|
|
|
(obj->cur->color.g != obj->prev->color.g) ||
|
|
|
|
(obj->cur->color.b != obj->prev->color.b) ||
|
|
|
|
(obj->cur->color.a != obj->prev->color.a))
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2015-11-17 03:22:17 -08:00
|
|
|
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
|
|
|
|
eo_obj, obj);
|
|
|
|
goto done;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2010-07-17 12:49:16 -07:00
|
|
|
/* if it changed geometry - and obviously not visibility or color
|
|
|
|
calculate differences since we have a constant color fill
|
|
|
|
we really only need to update the differences */
|
2013-03-12 05:58:19 -07:00
|
|
|
if ((obj->cur->geometry.x != obj->prev->geometry.x) ||
|
|
|
|
(obj->cur->geometry.y != obj->prev->geometry.y) ||
|
|
|
|
(obj->cur->geometry.w != obj->prev->geometry.w) ||
|
|
|
|
(obj->cur->geometry.h != obj->prev->geometry.h))
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2015-11-17 03:22:17 -08:00
|
|
|
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
|
|
|
|
eo_obj, obj);
|
|
|
|
goto done;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
2013-03-12 05:58:19 -07:00
|
|
|
if (obj->cur->render_op != obj->prev->render_op)
|
2006-05-02 00:28:49 -07:00
|
|
|
{
|
2015-11-17 03:22:17 -08:00
|
|
|
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
|
|
|
|
eo_obj, obj);
|
|
|
|
goto done;
|
2006-05-02 00:28:49 -07:00
|
|
|
}
|
2002-11-08 00:02:15 -08:00
|
|
|
if (o->changed)
|
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
|
2012-12-14 01:07:38 -08:00
|
|
|
eo_obj, obj);
|
|
|
|
goto done;
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
done:
|
2014-03-09 00:31:28 -08:00
|
|
|
evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes,
|
2015-11-17 03:22:17 -08:00
|
|
|
eo_obj, is_v, was_v);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-02-03 18:31:55 -08:00
|
|
|
evas_object_text_render_post(Evas_Object *eo_obj EINA_UNUSED,
|
|
|
|
Evas_Object_Protected_Data *obj,
|
2013-07-08 17:46:15 -07:00
|
|
|
void *type_private_data EINA_UNUSED)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2010-07-17 12:49:16 -07:00
|
|
|
/* 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
|
|
|
|
data anymore we can free it if the object deems this is a good idea */
|
2002-11-08 00:02:15 -08:00
|
|
|
/* remove those pesky changes */
|
2017-02-03 18:31:55 -08:00
|
|
|
evas_object_clip_changes_clean(obj);
|
2002-11-08 00:02:15 -08:00
|
|
|
/* move cur to prev safely for object data */
|
2017-02-03 18:31:55 -08:00
|
|
|
evas_object_cur_prev(obj);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
static unsigned int
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_text_id_get(Evas_Object *eo_obj)
|
2008-08-30 19:04:31 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
|
2008-08-30 19:04:31 -07:00
|
|
|
if (!o) return 0;
|
|
|
|
return MAGIC_OBJ_TEXT;
|
|
|
|
}
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
static unsigned int
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_text_visual_id_get(Evas_Object *eo_obj)
|
2008-08-25 22:45:04 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
|
2008-08-25 22:45:04 -07:00
|
|
|
if (!o) return 0;
|
|
|
|
return MAGIC_OBJ_SHAPE;
|
|
|
|
}
|
|
|
|
|
2010-07-17 12:49:16 -07:00
|
|
|
static void *
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_text_engine_data_get(Evas_Object *eo_obj)
|
2008-08-25 22:45:04 -07:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
|
2008-08-25 22:45:04 -07:00
|
|
|
if (!o) return NULL;
|
2011-05-29 06:00:54 -07:00
|
|
|
return o->font;
|
2008-08-25 22:45:04 -07:00
|
|
|
}
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
static int
|
2013-07-08 17:46:15 -07:00
|
|
|
evas_object_text_is_opaque(Evas_Object *eo_obj EINA_UNUSED,
|
|
|
|
Evas_Object_Protected_Data *obj EINA_UNUSED,
|
|
|
|
void *type_private_data EINA_UNUSED)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2014-03-09 00:31:28 -08:00
|
|
|
/* this returns 1 if the internal object data implies that the object is
|
2010-07-17 12:49:16 -07:00
|
|
|
currently fully opaque over the entire gradient it occupies */
|
2002-11-08 00:02:15 -08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2013-07-08 17:46:15 -07:00
|
|
|
evas_object_text_was_opaque(Evas_Object *eo_obj EINA_UNUSED,
|
|
|
|
Evas_Object_Protected_Data *obj EINA_UNUSED,
|
|
|
|
void *type_private_data EINA_UNUSED)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2010-07-17 12:49:16 -07:00
|
|
|
/* this returns 1 if the internal object data implies that the object was
|
|
|
|
currently fully opaque over the entire gradient it occupies */
|
2002-11-08 00:02:15 -08:00
|
|
|
return 0;
|
|
|
|
}
|
2006-02-28 19:48:02 -08:00
|
|
|
|
2017-11-29 00:59:34 -08:00
|
|
|
EOLIAN static void
|
2017-11-30 18:51:56 -08:00
|
|
|
_evas_text_efl_gfx_scale_set(Evas_Object *eo_obj, Evas_Text_Data *o,
|
2017-11-29 00:59:34 -08:00
|
|
|
double scale)
|
2008-11-15 02:39:46 -08:00
|
|
|
{
|
|
|
|
int size;
|
|
|
|
const char *font;
|
2009-09-03 22:13:19 -07:00
|
|
|
|
2017-11-30 18:51:56 -08:00
|
|
|
if (EINA_DBL_EQ(efl_gfx_scale_get(eo_obj), scale)) return;
|
|
|
|
efl_gfx_scale_set(efl_super(eo_obj, MY_CLASS), scale);
|
2017-11-29 00:59:34 -08:00
|
|
|
|
2008-11-15 02:39:46 -08:00
|
|
|
font = eina_stringshare_add(o->cur.font);
|
|
|
|
size = o->cur.size;
|
|
|
|
if (o->cur.font) eina_stringshare_del(o->cur.font);
|
|
|
|
o->cur.font = NULL;
|
|
|
|
o->prev.font = NULL;
|
|
|
|
o->cur.size = 0;
|
|
|
|
o->prev.size = 0;
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_text_font_set(eo_obj, font, size);
|
2008-11-15 02:39:46 -08:00
|
|
|
}
|
|
|
|
|
2006-02-28 19:48:02 -08:00
|
|
|
void
|
2012-10-08 18:58:41 -07:00
|
|
|
_evas_object_text_rehint(Evas_Object *eo_obj)
|
2006-02-28 19:48:02 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
|
|
|
Evas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
|
2016-10-21 05:25:41 -07:00
|
|
|
Eina_List *was = NULL;
|
2009-09-03 22:13:19 -07:00
|
|
|
|
2011-05-29 06:00:54 -07:00
|
|
|
if (!o->font) return;
|
2017-11-06 18:22:09 -08:00
|
|
|
evas_font_load_hinting_set(o->font, obj->layer->evas->hinting);
|
2016-10-21 05:25:41 -07:00
|
|
|
was = _evas_pointer_list_in_rect_get(obj->layer->evas, eo_obj, obj, 1, 1);
|
2006-02-28 19:48:02 -08:00
|
|
|
/* DO II */
|
2012-12-30 17:49:36 -08:00
|
|
|
_evas_object_text_recalc(eo_obj, o->cur.text);
|
2011-01-30 02:44:23 -08:00
|
|
|
o->changed = 1;
|
2015-06-17 00:26:30 -07:00
|
|
|
if (o->has_filter)
|
2016-03-01 10:06:28 -08:00
|
|
|
evas_filter_changed_set(eo_obj, EINA_TRUE);
|
2012-10-08 18:58:41 -07:00
|
|
|
evas_object_change(eo_obj, obj);
|
|
|
|
evas_object_clip_dirty(eo_obj, obj);
|
|
|
|
evas_object_coords_recalc(eo_obj, obj);
|
2016-10-21 05:25:41 -07:00
|
|
|
if (obj->cur->visible)
|
|
|
|
_evas_canvas_event_pointer_in_list_mouse_move_feed(obj->layer->evas, was, eo_obj, obj, 1, 1, EINA_FALSE, NULL);
|
|
|
|
eina_list_free(was);
|
2017-10-19 16:07:39 -07:00
|
|
|
evas_object_inform_call_resize(eo_obj, obj);
|
2011-01-30 02:44:23 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2012-12-30 17:49:36 -08:00
|
|
|
_evas_object_text_recalc(Evas_Object *eo_obj, Eina_Unicode *text)
|
2011-01-30 02:44:23 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
|
|
|
Evas_Text_Data *o = efl_data_scope_get(eo_obj, MY_CLASS);
|
2011-01-30 02:44:23 -08:00
|
|
|
|
|
|
|
if (!text) text = eina_unicode_strdup(EINA_UNICODE_EMPTY_STRING);
|
|
|
|
|
2012-10-08 18:58:41 -07:00
|
|
|
_evas_object_text_layout(eo_obj, o, text);
|
2011-01-30 02:44:23 -08:00
|
|
|
|
2013-05-10 09:44:30 -07:00
|
|
|
/* Calc ascent/descent. */
|
2013-06-07 10:09:30 -07:00
|
|
|
if (o->items)
|
2013-05-10 09:44:30 -07:00
|
|
|
{
|
2014-08-17 06:22:44 -07:00
|
|
|
/*
|
2013-05-10 09:44:30 -07:00
|
|
|
Evas_Object_Text_Item *item;
|
|
|
|
|
|
|
|
for (item = o->items ; item ;
|
|
|
|
item = EINA_INLIST_CONTAINER_GET(
|
|
|
|
EINA_INLIST_GET(item)->next, Evas_Object_Text_Item))
|
|
|
|
{
|
|
|
|
int asc = 0, desc = 0;
|
|
|
|
|
2014-08-17 06:22:44 -07:00
|
|
|
// Skip items without meaning full information.
|
2013-06-09 01:30:34 -07:00
|
|
|
if (!item->text_props.font_instance) continue;
|
2013-05-10 09:44:30 -07:00
|
|
|
|
|
|
|
asc = evas_common_font_instance_ascent_get(item->text_props.font_instance);
|
|
|
|
desc = evas_common_font_instance_descent_get(item->text_props.font_instance);
|
2013-06-09 01:30:34 -07:00
|
|
|
if (asc > o->ascent) o->ascent = asc;
|
|
|
|
if (desc > o->descent) o->descent = desc;
|
2013-05-10 09:44:30 -07:00
|
|
|
|
2013-06-09 01:30:34 -07:00
|
|
|
asc = evas_common_font_instance_max_ascent_get(item->text_props.font_instance);
|
|
|
|
desc = evas_common_font_instance_max_descent_get(item->text_props.font_instance);
|
|
|
|
if (asc > o->max_ascent) o->max_ascent = asc;
|
|
|
|
if (desc > o->max_descent) o->max_descent = desc;
|
2013-05-10 09:44:30 -07:00
|
|
|
}
|
2014-08-17 06:22:44 -07:00
|
|
|
*/
|
|
|
|
if (o->font)
|
|
|
|
{
|
2017-08-25 10:51:24 -07:00
|
|
|
o->ascent = ENFN->font_ascent_get(ENC, o->font);
|
|
|
|
o->descent = ENFN->font_descent_get(ENC, o->font);
|
|
|
|
o->max_ascent = ENFN->font_max_ascent_get(ENC, o->font);
|
|
|
|
o->max_descent = ENFN->font_max_descent_get(ENC, o->font);
|
2014-08-17 06:22:44 -07:00
|
|
|
}
|
2013-05-10 09:44:30 -07:00
|
|
|
}
|
2013-06-07 10:09:30 -07:00
|
|
|
else if (o->font)
|
|
|
|
{
|
2017-08-25 10:51:24 -07:00
|
|
|
o->ascent = ENFN->font_ascent_get(ENC, o->font);
|
|
|
|
o->descent = ENFN->font_descent_get(ENC, o->font);
|
|
|
|
o->max_ascent = ENFN->font_max_ascent_get(ENC, o->font);
|
|
|
|
o->max_descent = ENFN->font_max_descent_get(ENC, o->font);
|
2013-06-07 10:09:30 -07:00
|
|
|
}
|
|
|
|
|
2011-05-29 06:00:54 -07:00
|
|
|
if ((o->font) && (o->items))
|
2006-02-28 19:48:02 -08:00
|
|
|
{
|
2013-10-02 03:07:48 -07:00
|
|
|
int w, h;
|
|
|
|
int l = 0, r = 0, t = 0, b = 0;
|
2009-09-03 22:13:19 -07:00
|
|
|
|
2015-12-08 23:50:33 -08:00
|
|
|
w = _evas_object_text_horiz_width_without_ellipsis_get(o);
|
2012-10-08 18:58:41 -07:00
|
|
|
h = _evas_object_text_vert_advance_get(eo_obj, o);
|
2015-06-17 00:26:30 -07:00
|
|
|
_evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
|
2013-03-12 05:58:19 -07:00
|
|
|
|
2013-10-01 04:34:03 -07:00
|
|
|
if (o->cur.ellipsis >= 0.0)
|
2013-10-01 19:02:05 -07:00
|
|
|
{
|
|
|
|
int min;
|
|
|
|
|
2013-10-02 04:52:59 -07:00
|
|
|
min = w + l + r < obj->cur->geometry.w || obj->cur->geometry.w == 0 ? w + l + r : obj->cur->geometry.w;
|
2017-09-15 02:37:25 -07:00
|
|
|
efl_gfx_size_set(efl_super(eo_obj, MY_CLASS), EINA_SIZE2D(min, h + t + b));
|
2013-10-01 19:02:05 -07:00
|
|
|
}
|
2013-10-01 04:34:03 -07:00
|
|
|
else
|
2013-10-01 19:02:05 -07:00
|
|
|
{
|
2017-09-15 02:37:25 -07:00
|
|
|
efl_gfx_size_set(efl_super(eo_obj, MY_CLASS), EINA_SIZE2D(w + l + r, h + t + b));
|
2013-10-01 19:02:05 -07:00
|
|
|
}
|
2013-03-12 05:58:19 -07:00
|
|
|
//// obj->cur->cache.geometry.validity = 0;
|
2006-02-28 19:48:02 -08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-12-09 03:55:38 -08:00
|
|
|
int t = 0, b = 0, l = 0, r = 0;
|
2015-06-17 00:26:30 -07:00
|
|
|
_evas_object_text_pad_get(eo_obj, o, &l, &r, &t, &b);
|
2017-09-15 02:37:25 -07:00
|
|
|
efl_gfx_size_set(efl_super(eo_obj, MY_CLASS), EINA_SIZE2D(0, o->max_ascent + o->max_descent + t + b));
|
2013-03-12 05:58:19 -07:00
|
|
|
//// obj->cur->cache.geometry.validity = 0;
|
2006-02-28 19:48:02 -08:00
|
|
|
}
|
2013-03-12 05:58:19 -07:00
|
|
|
o->last_computed.w = obj->cur->geometry.w;
|
|
|
|
o->last_computed.h = obj->cur->geometry.h;
|
2015-11-19 03:37:07 -08:00
|
|
|
#ifdef BIDI_SUPPORT
|
|
|
|
o->changed_paragraph_direction = EINA_FALSE;
|
|
|
|
#endif
|
2006-02-28 19:48:02 -08:00
|
|
|
}
|
2011-01-30 02:44:23 -08:00
|
|
|
|
2014-07-19 10:31:16 -07:00
|
|
|
EAPI void
|
|
|
|
evas_object_text_font_source_set(Eo *obj, const char *font_source)
|
|
|
|
{
|
2018-02-12 13:02:06 -08:00
|
|
|
efl_text_font_source_set((Eo *) obj, font_source);
|
2014-07-19 10:31:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const char *
|
|
|
|
evas_object_text_font_source_get(const Eo *obj)
|
|
|
|
{
|
|
|
|
const char *font_source = 0;
|
2018-02-12 13:02:06 -08:00
|
|
|
font_source = efl_text_font_source_get((Eo *) obj);
|
2014-07-19 10:31:16 -07:00
|
|
|
return font_source;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_object_text_font_set(Eo *obj, const char *font, Evas_Font_Size size)
|
|
|
|
{
|
2018-02-12 13:02:06 -08:00
|
|
|
efl_text_font_set((Eo *) obj, font, size);
|
2014-07-19 10:31:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
|
|
|
evas_object_text_font_get(const Eo *obj, const char **font, Evas_Font_Size *size)
|
|
|
|
{
|
2018-02-12 13:02:06 -08:00
|
|
|
efl_text_font_get((Eo *) obj, font, size);
|
2014-07-19 10:31:16 -07:00
|
|
|
}
|
|
|
|
|
2014-07-24 09:42:09 -07:00
|
|
|
EAPI void
|
|
|
|
evas_object_text_text_set(Eo *obj, const char *text)
|
|
|
|
{
|
2016-03-01 10:06:28 -08:00
|
|
|
efl_text_set((Eo *) obj, text);
|
2014-07-24 09:42:09 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EAPI const char *
|
|
|
|
evas_object_text_text_get(const Eo *obj)
|
|
|
|
{
|
2016-03-01 10:06:28 -08:00
|
|
|
return efl_text_get((Eo *) obj);
|
2014-07-24 09:42:09 -07:00
|
|
|
}
|
|
|
|
|
2016-01-12 22:19:07 -08:00
|
|
|
EOLIAN static void
|
2016-02-28 22:23:18 -08:00
|
|
|
_evas_text_efl_gfx_filter_filter_program_set(Eo *obj, Evas_Text_Data *pd EINA_UNUSED, const char *code, const char *name)
|
2015-06-17 00:26:30 -07:00
|
|
|
{
|
|
|
|
pd->has_filter = (code != NULL);
|
2016-08-15 06:44:41 -07:00
|
|
|
efl_gfx_filter_program_set(efl_super(obj, MY_CLASS), code, name);
|
2015-06-17 00:26:30 -07:00
|
|
|
}
|
|
|
|
|
2016-06-28 18:58:57 -07:00
|
|
|
/* deprecated */
|
2016-02-28 22:47:36 -08:00
|
|
|
EAPI void
|
2016-06-28 18:58:57 -07:00
|
|
|
evas_object_text_filter_program_set(Evas_Object *obj, const char *code)
|
2016-02-28 22:47:36 -08:00
|
|
|
{
|
2016-06-28 18:58:57 -07:00
|
|
|
efl_gfx_filter_program_set(obj, code, NULL);
|
2016-02-28 22:47:36 -08:00
|
|
|
}
|
|
|
|
|
2016-06-28 18:58:57 -07:00
|
|
|
/* deprecated */
|
2016-02-28 22:47:36 -08:00
|
|
|
EAPI void
|
|
|
|
evas_object_text_filter_source_set(Evas_Object *obj, const char *name, Evas_Object *source)
|
|
|
|
{
|
2016-03-03 02:00:26 -08:00
|
|
|
efl_gfx_filter_source_set(obj, name, source);
|
2016-02-28 22:47:36 -08:00
|
|
|
}
|
|
|
|
|
2015-11-19 03:37:07 -08:00
|
|
|
EOLIAN static void
|
2016-06-20 21:26:15 -07:00
|
|
|
_evas_text_efl_canvas_object_paragraph_direction_set(Eo *eo_obj, Evas_Text_Data *o,
|
|
|
|
Evas_BiDi_Direction dir)
|
2015-11-19 03:37:07 -08:00
|
|
|
{
|
|
|
|
#ifdef BIDI_SUPPORT
|
2016-08-15 06:44:41 -07:00
|
|
|
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
|
2015-11-19 03:37:07 -08:00
|
|
|
|
|
|
|
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
|
2016-06-20 21:26:15 -07:00
|
|
|
_evas_text_efl_canvas_object_paragraph_direction_get(Eo *eo_obj EINA_UNUSED,
|
|
|
|
Evas_Text_Data *o)
|
2015-11-19 03:37:07 -08:00
|
|
|
{
|
|
|
|
return o->paragraph_direction;
|
|
|
|
}
|
|
|
|
|
2017-09-25 02:34:22 -07:00
|
|
|
EOLIAN static void
|
|
|
|
_evas_text_efl_text_font_font_bitmap_scalable_set(Eo *eo_obj, Evas_Text_Data *o, Efl_Text_Font_Bitmap_Scalable bitmap_scalable)
|
|
|
|
{
|
|
|
|
if (o->cur.bitmap_scalable == bitmap_scalable) return;
|
|
|
|
o->prev.bitmap_scalable = o->cur.bitmap_scalable;
|
|
|
|
o->cur.bitmap_scalable = bitmap_scalable;
|
|
|
|
_evas_text_font_reload(eo_obj, o);
|
|
|
|
}
|
|
|
|
|
|
|
|
EOLIAN static Efl_Text_Font_Bitmap_Scalable
|
|
|
|
_evas_text_efl_text_font_font_bitmap_scalable_get(Eo *eo_obj EINA_UNUSED, Evas_Text_Data *o)
|
|
|
|
{
|
|
|
|
return o->cur.bitmap_scalable;
|
|
|
|
}
|
|
|
|
|
2017-04-21 08:58:38 -07:00
|
|
|
#define EVAS_TEXT_EXTRA_OPS \
|
|
|
|
EFL_OBJECT_OP_FUNC(efl_dbg_info_get, _evas_text_efl_object_dbg_info_get)
|
|
|
|
|
2014-03-09 00:31:28 -08:00
|
|
|
#include "canvas/evas_text.eo.c"
|