1 #include "evas_common.h" /* Includes evas_bidi_utils stuff. */
2 #include "evas_private.h"
5 #define ENFN obj->layer->evas->engine.func
6 #define ENDT obj->layer->evas->engine.data.output
8 /* private magic number for text objects */
9 static const char o_type[] = "text";
11 /* private struct for text object internal data */
12 typedef struct _Evas_Object_Text Evas_Object_Text;
13 typedef struct _Evas_Object_Text_Item Evas_Object_Text_Item;
15 struct _Evas_Object_Text
20 const char *utf8_text; /* The text exposed to the API */
22 Evas_Font_Description *fdesc;
26 unsigned char r, g, b, a;
27 } outline, shadow, glow, glow2;
32 float ascent, descent;
33 float max_ascent, max_descent;
34 Evas_BiDi_Paragraph_Props *bidi_par_props;
35 const char *bidi_delimiters;
36 Evas_Object_Text_Item *items;
43 struct _Evas_Object_Text_Item
49 Evas_Text_Props text_props;
50 Evas_Coord x, w, h, adv;
53 /* private methods for text objects */
54 static void evas_object_text_init(Evas_Object *obj);
55 static void *evas_object_text_new(void);
56 static void evas_object_text_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y);
57 static void evas_object_text_free(Evas_Object *obj);
58 static void evas_object_text_render_pre(Evas_Object *obj);
59 static void evas_object_text_render_post(Evas_Object *obj);
61 static unsigned int evas_object_text_id_get(Evas_Object *obj);
62 static unsigned int evas_object_text_visual_id_get(Evas_Object *obj);
63 static void *evas_object_text_engine_data_get(Evas_Object *obj);
65 static int evas_object_text_is_opaque(Evas_Object *obj);
66 static int evas_object_text_was_opaque(Evas_Object *obj);
68 static void evas_object_text_scale_update(Evas_Object *obj);
69 static void _evas_object_text_recalc(Evas_Object *obj);
71 static const Evas_Object_Func object_func =
73 /* methods (compulsory) */
74 evas_object_text_free,
75 evas_object_text_render,
76 evas_object_text_render_pre,
77 evas_object_text_render_post,
78 evas_object_text_id_get,
79 evas_object_text_visual_id_get,
80 evas_object_text_engine_data_get,
81 /* these are optional. NULL = nothing */
86 evas_object_text_is_opaque,
87 evas_object_text_was_opaque,
91 evas_object_text_scale_update,
97 /* the actual api call to add a rect */
98 /* it has no other api calls as all properties are standard */
100 EVAS_MEMPOOL(_mp_obj);
103 _evas_object_text_char_coords_get(const Evas_Object *obj,
104 const Evas_Object_Text *o,
105 size_t pos, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
107 Evas_Object_Text_Item *it;
109 EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
111 if ((it->text_pos <= pos) &&
112 (pos < (it->text_pos + it->text_props.text_len)))
115 ret = ENFN->font_char_coords_get(ENDT, o->font,
116 &it->text_props, pos - it->text_pos, x, y, w, h);
125 _evas_object_text_item_clean(Evas_Object_Text_Item *it)
127 evas_common_text_props_content_unref(&it->text_props);
131 _evas_object_text_items_clear(Evas_Object_Text *o)
133 Evas_Object_Text_Item *it;
138 o->items = (Evas_Object_Text_Item *) eina_inlist_remove(
139 EINA_INLIST_GET(o->items),
140 EINA_INLIST_GET(it));
141 _evas_object_text_item_clean(it);
148 _evas_object_text_it_compare_logical(const void *_it1, const void *_it2)
150 const Evas_Object_Text_Item *it1 = _it1, *it2 = _it2;
151 if (it1->text_pos < it2->text_pos)
153 else if (it1->text_pos == it2->text_pos)
162 _evas_object_text_last_up_to_pos(const Evas_Object *obj,
163 const Evas_Object_Text *o, Evas_Coord cx, Evas_Coord cy)
165 Evas_Object_Text_Item *it;
168 /*FIXME: not very efficient, sort the items arrays. */
169 /* Reorder if it's a bidi text */
170 if (o->bidi_par_props)
172 Eina_List *logical_it = NULL;
173 Evas_Object_Text_Item *i;
176 /* Insert all to the logical list */
177 EINA_INLIST_FOREACH(o->items, i)
179 logical_it = eina_list_sorted_insert(logical_it,
180 _evas_object_text_it_compare_logical, i);
182 EINA_LIST_FOREACH(logical_it, itr, it)
184 if ((x <= cx) && (cx < x + it->adv))
186 return it->text_pos + ENFN->font_last_up_to_pos(ENDT,
194 eina_list_free(logical_it);
199 EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
201 if ((it->x <= cx) && (cx < it->x + it->adv))
203 return it->text_pos + ENFN->font_last_up_to_pos(ENDT,
215 _evas_object_text_char_at_coords(const Evas_Object *obj,
216 const Evas_Object_Text *o, Evas_Coord cx, Evas_Coord cy,
217 Evas_Coord *rx, Evas_Coord *ry, Evas_Coord *rw, Evas_Coord *rh)
219 Evas_Object_Text_Item *it;
221 EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
223 if ((it->x <= cx) && (cx < it->x + it->adv))
225 return it->text_pos + ENFN->font_char_at_coords_get(ENDT,
238 _evas_object_text_horiz_advance_get(const Evas_Object *obj,
239 const Evas_Object_Text *o)
241 Evas_Object_Text_Item *it;
246 EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
254 _evas_object_text_vert_advance_get(const Evas_Object *obj __UNUSED__,
255 const Evas_Object_Text *o)
257 return o->max_ascent + o->max_descent;
261 evas_object_text_add(Evas *e)
265 MAGIC_CHECK(e, Evas, MAGIC_EVAS);
268 obj = evas_object_new(e);
269 evas_object_text_init(obj);
270 evas_object_inject(obj, e);
275 evas_object_text_font_source_set(Evas_Object *obj, const char *font_source)
279 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
282 o = (Evas_Object_Text *)(obj->object_data);
283 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
287 if ((o->cur.source) && (font_source) &&
288 (!strcmp(o->cur.source, font_source)))
291 if (o->cur.source) eina_stringshare_del(o->cur.source);
292 if (font_source) o->cur.source = eina_stringshare_add(font_source);
293 else o->cur.source = NULL;
295 eina_stringshare_replace(&o->cur.source, font_source);
299 evas_object_text_font_source_get(const Evas_Object *obj)
303 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
306 o = (Evas_Object_Text *)(obj->object_data);
307 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
310 return o->cur.source;
314 evas_object_text_font_set(Evas_Object *obj, const char *font, Evas_Font_Size size)
317 int is, was = 0, pass = 0, freeze = 0;
318 Evas_Font_Description *fdesc;
320 if ((!font) || (size <= 0)) return;
321 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
324 o = (Evas_Object_Text *)(obj->object_data);
325 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
329 fdesc = evas_font_desc_new();
330 evas_font_name_parse(fdesc, font);
331 if (o->cur.fdesc && !evas_font_desc_cmp(fdesc, o->cur.fdesc) &&
332 (size == o->cur.size))
334 evas_font_desc_unref(fdesc);
338 if (o->cur.fdesc) evas_font_desc_unref(o->cur.fdesc);
339 o->cur.fdesc = fdesc;
342 eina_stringshare_replace(&o->cur.font, font);
345 if (obj->layer->evas->events_frozen <= 0)
347 pass = evas_event_passes_through(obj);
348 freeze = evas_event_freezes_through(obj);
349 if ((!pass) && (!freeze))
350 was = evas_object_is_in_output_rect(obj,
351 obj->layer->evas->pointer.x,
352 obj->layer->evas->pointer.y, 1, 1);
355 #ifdef EVAS_FRAME_QUEUING
357 evas_common_pipe_op_text_flush((RGBA_Font *) o->font);
363 evas_font_free(obj->layer->evas, o->font);
367 o->font = evas_font_load(obj->layer->evas, o->cur.fdesc, o->cur.source,
368 (int)(((double) o->cur.size) * obj->cur.scale));
371 o->ascent = ENFN->font_ascent_get(ENDT, o->font);
372 o->descent = ENFN->font_descent_get(ENDT, o->font);
373 o->max_ascent = ENFN->font_max_ascent_get(ENDT, o->font);
374 o->max_descent = ENFN->font_max_descent_get(ENDT, o->font);
383 _evas_object_text_recalc(obj);
385 evas_object_change(obj);
386 evas_object_clip_dirty(obj);
387 evas_object_coords_recalc(obj);
388 if (obj->layer->evas->events_frozen <= 0)
390 if ((!pass) && (!freeze))
392 is = evas_object_is_in_output_rect(obj,
393 obj->layer->evas->pointer.x,
394 obj->layer->evas->pointer.y,
396 if ((is ^ was) && obj->cur.visible)
397 evas_event_feed_mouse_move(obj->layer->evas,
398 obj->layer->evas->pointer.x,
399 obj->layer->evas->pointer.y,
400 obj->layer->evas->last_timestamp,
404 evas_object_inform_call_resize(obj);
408 evas_object_text_font_get(const Evas_Object *obj, const char **font, Evas_Font_Size *size)
412 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
413 if (font) *font = "";
417 o = (Evas_Object_Text *)(obj->object_data);
418 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
419 if (font) *font = "";
423 if (font) *font = o->cur.font;
424 if (size) *size = o->cur.size;
430 * Create a new text layout item from the string and the format.
432 * @param c the context to work on - Not NULL.
433 * @param fmt the format to use.
434 * @param str the string to use.
436 static Evas_Object_Text_Item *
437 _evas_object_text_item_new(Evas_Object *obj, Evas_Object_Text *o,
438 Evas_Font_Instance *fi, const Eina_Unicode *str, Evas_Script_Type script,
439 size_t pos, size_t visual_pos, size_t len)
441 Evas_Object_Text_Item *it;
443 it = calloc(1, sizeof(Evas_Object_Text_Item));
445 it->visual_pos = visual_pos;
446 evas_common_text_props_bidi_set(&it->text_props, o->bidi_par_props,
448 evas_common_text_props_script_set(&it->text_props, script);
452 ENFN->font_text_props_info_create(ENDT,
453 fi, str + pos, &it->text_props,
454 o->bidi_par_props, it->text_pos, len);
456 ENFN->font_string_size_get(ENDT,
460 it->adv = ENFN->font_h_advance_get(ENDT, o->font,
463 o->items = (Evas_Object_Text_Item *)
464 eina_inlist_append(EINA_INLIST_GET(o->items), EINA_INLIST_GET(it));
470 * Orders o->items according to the visual position.
472 * @param obj the evas object
473 * @param o the text object
476 _evas_object_text_item_order(Evas_Object *obj, Evas_Object_Text *o)
480 /*FIXME: not very efficient, sort the items arrays. */
481 /* Reorder if it's a bidi text */
482 if (o->bidi_par_props)
484 Evas_Object_Text_Item *i, *j, *min;
489 EINA_INLIST_FOREACH(i, j)
491 if (j->visual_pos < min->visual_pos)
498 o->items = (Evas_Object_Text_Item *) eina_inlist_remove(EINA_INLIST_GET(o->items), EINA_INLIST_GET(min));
499 o->items = (Evas_Object_Text_Item *) eina_inlist_prepend_relative(EINA_INLIST_GET(o->items), EINA_INLIST_GET(min), EINA_INLIST_GET(i));
502 i = (Evas_Object_Text_Item *) EINA_INLIST_GET(min)->next;
507 /* calculate the positions according to the order. */
509 Evas_Object_Text_Item *it = o->items;
516 it = (Evas_Object_Text_Item *) EINA_INLIST_GET(it)->next;
523 * Populates o->items with the items of the text according to text
525 * @param obj the evas object
526 * @param o the text object
527 * @param text the text to layout
530 _evas_object_text_layout(Evas_Object *obj, Evas_Object_Text *o, const Eina_Unicode *text)
532 EvasBiDiStrIndex *v_to_l = NULL;
533 size_t pos, visual_pos;
534 int len = eina_unicode_strlen(text);
537 int *segment_idxs = NULL;
538 if (o->bidi_delimiters)
539 segment_idxs = evas_bidi_segment_idxs_get(text, o->bidi_delimiters);
540 evas_bidi_paragraph_props_unref(o->bidi_par_props);
541 o->bidi_par_props = evas_bidi_paragraph_props_get(text, len, segment_idxs);
542 evas_bidi_props_reorder_line(NULL, 0, len, o->bidi_par_props, &v_to_l);
543 if (segment_idxs) free(segment_idxs);
545 visual_pos = pos = 0;
549 Evas_Font_Instance *script_fi = NULL;
550 int script_len = len, tmp_cut;
551 Evas_Script_Type script;
552 tmp_cut = evas_common_language_script_end_of_run_get(
557 script_len = tmp_cut;
559 script = evas_common_language_script_type_get(text, script_len);
561 while (script_len > 0)
563 Evas_Font_Instance *cur_fi = NULL;
564 int run_len = script_len;
567 run_len = ENFN->font_run_end_get(ENDT,
568 o->font, &script_fi, &cur_fi,
569 script, text + pos, script_len);
572 visual_pos = evas_bidi_position_logical_to_visual(
573 v_to_l, par_len, pos);
577 _evas_object_text_item_new(obj, o, cur_fi, text, script,
578 pos, visual_pos, run_len);
581 script_len -= run_len;
586 _evas_object_text_item_order(obj, o);
588 if (v_to_l) free(v_to_l);
593 evas_object_text_text_set(Evas_Object *obj, const char *_text)
599 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
602 o = (Evas_Object_Text *)(obj->object_data);
603 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
607 if ((o->cur.utf8_text) && (_text) && (!strcmp(o->cur.utf8_text, _text)))
609 text = eina_unicode_utf8_to_unicode(_text, &len);
611 if (!text) text = eina_unicode_strdup(EINA_UNICODE_EMPTY_STRING);
612 was = evas_object_is_in_output_rect(obj,
613 obj->layer->evas->pointer.x,
614 obj->layer->evas->pointer.y, 1, 1);
616 /*Update bidi_props*/
618 if (o->items) _evas_object_text_items_clear(o);
620 if ((text) && (*text))
622 _evas_object_text_layout(obj, o, text);
623 eina_stringshare_replace(&o->cur.utf8_text, _text);
624 o->prev.utf8_text = NULL;
628 eina_stringshare_replace(&o->cur.utf8_text, NULL);
635 _evas_object_text_recalc(obj);
637 evas_object_change(obj);
638 evas_object_clip_dirty(obj);
639 evas_object_coords_recalc(obj);
640 is = evas_object_is_in_output_rect(obj,
641 obj->layer->evas->pointer.x,
642 obj->layer->evas->pointer.y, 1, 1);
643 if ((is || was) && obj->cur.visible)
644 evas_event_feed_mouse_move(obj->layer->evas,
645 obj->layer->evas->pointer.x,
646 obj->layer->evas->pointer.y,
647 obj->layer->evas->last_timestamp,
649 evas_object_inform_call_resize(obj);
650 if (text) free(text);
654 evas_object_text_bidi_delimiters_set(Evas_Object *obj, const char *delim)
658 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
661 o = (Evas_Object_Text *)(obj->object_data);
662 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
666 eina_stringshare_replace(&o->bidi_delimiters, delim);
670 evas_object_text_bidi_delimiters_get(const Evas_Object *obj)
674 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
677 o = (Evas_Object_Text *)(obj->object_data);
678 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
682 return o->bidi_delimiters;
687 evas_object_text_text_get(const Evas_Object *obj)
691 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
694 o = (Evas_Object_Text *)(obj->object_data);
695 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
698 return o->cur.utf8_text;
701 EAPI Evas_BiDi_Direction
702 evas_object_text_direction_get(const Evas_Object *obj)
706 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
707 return EVAS_BIDI_DIRECTION_NEUTRAL;
709 o = (Evas_Object_Text *)(obj->object_data);
710 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
711 return EVAS_BIDI_DIRECTION_NEUTRAL;
715 return o->items->text_props.bidi.dir;
717 return EVAS_BIDI_DIRECTION_NEUTRAL;
721 evas_object_text_ascent_get(const Evas_Object *obj)
725 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
728 o = (Evas_Object_Text *)(obj->object_data);
729 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
736 evas_object_text_descent_get(const Evas_Object *obj)
740 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
743 o = (Evas_Object_Text *)(obj->object_data);
744 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
751 evas_object_text_max_ascent_get(const Evas_Object *obj)
755 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
758 o = (Evas_Object_Text *)(obj->object_data);
759 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
762 return o->max_ascent;
766 evas_object_text_max_descent_get(const Evas_Object *obj)
770 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
773 o = (Evas_Object_Text *)(obj->object_data);
774 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
777 return o->max_descent;
781 evas_object_text_inset_get(const Evas_Object *obj)
785 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
788 o = (Evas_Object_Text *)(obj->object_data);
789 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
792 if (!o->font) return 0;
793 if (!o->items) return 0;
794 return ENFN->font_inset_get(ENDT, o->font, &o->items->text_props);
798 evas_object_text_horiz_advance_get(const Evas_Object *obj)
802 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
805 o = (Evas_Object_Text *)(obj->object_data);
806 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
809 if (!o->font) return 0;
810 if (!o->items) return 0;
811 return _evas_object_text_horiz_advance_get(obj, o);
815 evas_object_text_vert_advance_get(const Evas_Object *obj)
819 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
822 o = (Evas_Object_Text *)(obj->object_data);
823 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
826 if (!o->font) return 0;
827 if (!o->items) return o->ascent + o->descent;
828 return _evas_object_text_vert_advance_get(obj, o);
832 evas_object_text_char_pos_get(const Evas_Object *obj, int pos, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
835 int l = 0, r = 0, t = 0, b = 0;
836 int ret, x = 0, y = 0, w = 0, h = 0;
838 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
841 o = (Evas_Object_Text *)(obj->object_data);
842 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
845 if (!o->font) return EINA_FALSE;
846 if (!o->items || (pos < 0)) return EINA_FALSE;
847 ret = _evas_object_text_char_coords_get(obj, o, (size_t) pos,
849 evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
850 y += o->max_ascent - t;
857 if ((x + w) > obj->cur.geometry.w) w = obj->cur.geometry.w - x;
864 if ((y + h) > obj->cur.geometry.h) h = obj->cur.geometry.h - y;
868 if (cw) *cw = w + l + r;
869 if (ch) *ch = h + t + b;
875 evas_object_text_last_up_to_pos(const Evas_Object *obj, Evas_Coord x, Evas_Coord y)
879 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
882 o = (Evas_Object_Text *)(obj->object_data);
883 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
886 if (!o->font) return -1;
887 if (!o->items) return -1;
888 return _evas_object_text_last_up_to_pos(obj, o, x, y - o->max_ascent);
892 evas_object_text_char_coords_get(const Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord *cx, Evas_Coord *cy, Evas_Coord *cw, Evas_Coord *ch)
895 int l = 0, r = 0, t = 0, b = 0;
896 int ret, rx = 0, ry = 0, rw = 0, rh = 0;
898 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
901 o = (Evas_Object_Text *)(obj->object_data);
902 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
905 if (!o->font) return -1;
906 if (!o->items) return -1;
907 ret = _evas_object_text_char_at_coords(obj, o, x, y - o->max_ascent,
909 evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
910 ry += o->max_ascent - t;
917 if ((rx + rw) > obj->cur.geometry.w) rw = obj->cur.geometry.w - rx;
924 if ((ry + rh) > obj->cur.geometry.h) rh = obj->cur.geometry.h - ry;
928 if (cw) *cw = rw + l + r;
929 if (ch) *ch = rh + t + b;
934 evas_object_text_style_set(Evas_Object *obj, Evas_Text_Style_Type style)
937 int pl = 0, pr = 0, pt = 0, pb = 0, l = 0, r = 0, t = 0, b = 0;
939 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
942 o = (Evas_Object_Text *)(obj->object_data);
943 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
946 if (o->cur.style == style) return;
947 evas_text_style_pad_get(o->cur.style, &pl, &pr, &pt, &pb);
948 o->cur.style = style;
949 evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
951 obj->cur.geometry.w += (l - pl) + (r - pr);
953 obj->cur.geometry.w = 0;
954 obj->cur.geometry.h += (t - pt) + (b - pb);
955 evas_object_change(obj);
956 evas_object_clip_dirty(obj);
959 EAPI Evas_Text_Style_Type
960 evas_object_text_style_get(const Evas_Object *obj)
964 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
965 return EVAS_TEXT_STYLE_PLAIN;
967 o = (Evas_Object_Text *)(obj->object_data);
968 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
969 return EVAS_TEXT_STYLE_PLAIN;
975 evas_object_text_shadow_color_set(Evas_Object *obj, int r, int g, int b, int a)
979 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
982 o = (Evas_Object_Text *)(obj->object_data);
983 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
986 if ((o->cur.shadow.r == r) && (o->cur.shadow.g == g) &&
987 (o->cur.shadow.b == b) && (o->cur.shadow.a == a))
994 evas_object_change(obj);
998 evas_object_text_shadow_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a)
1000 Evas_Object_Text *o;
1002 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1009 o = (Evas_Object_Text *)(obj->object_data);
1010 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
1017 if (r) *r = o->cur.shadow.r;
1018 if (g) *g = o->cur.shadow.g;
1019 if (b) *b = o->cur.shadow.b;
1020 if (a) *a = o->cur.shadow.a;
1024 evas_object_text_glow_color_set(Evas_Object *obj, int r, int g, int b, int a)
1026 Evas_Object_Text *o;
1028 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1031 o = (Evas_Object_Text *)(obj->object_data);
1032 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
1035 if ((o->cur.glow.r == r) && (o->cur.glow.g == g) &&
1036 (o->cur.glow.b == b) && (o->cur.glow.a == a))
1043 evas_object_change(obj);
1047 evas_object_text_glow_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a)
1049 Evas_Object_Text *o;
1051 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1058 o = (Evas_Object_Text *)(obj->object_data);
1059 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
1066 if (r) *r = o->cur.glow.r;
1067 if (g) *g = o->cur.glow.g;
1068 if (b) *b = o->cur.glow.b;
1069 if (a) *a = o->cur.glow.a;
1073 evas_object_text_glow2_color_set(Evas_Object *obj, int r, int g, int b, int a)
1075 Evas_Object_Text *o;
1077 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1080 o = (Evas_Object_Text *)(obj->object_data);
1081 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
1084 if ((o->cur.glow2.r == r) && (o->cur.glow2.g == g) &&
1085 (o->cur.glow2.b == b) && (o->cur.glow2.a == a))
1092 evas_object_change(obj);
1096 evas_object_text_glow2_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a)
1098 Evas_Object_Text *o;
1100 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1107 o = (Evas_Object_Text *)(obj->object_data);
1108 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
1115 if (r) *r = o->cur.glow2.r;
1116 if (g) *g = o->cur.glow2.g;
1117 if (b) *b = o->cur.glow2.b;
1118 if (a) *a = o->cur.glow2.a;
1122 evas_object_text_outline_color_set(Evas_Object *obj, int r, int g, int b, int a)
1124 Evas_Object_Text *o;
1126 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1129 o = (Evas_Object_Text *)(obj->object_data);
1130 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
1133 if ((o->cur.outline.r == r) && (o->cur.outline.g == g) &&
1134 (o->cur.outline.b == b) && (o->cur.outline.a == a))
1136 o->cur.outline.r = r;
1137 o->cur.outline.g = g;
1138 o->cur.outline.b = b;
1139 o->cur.outline.a = a;
1141 evas_object_change(obj);
1145 evas_object_text_outline_color_get(const Evas_Object *obj, int *r, int *g, int *b, int *a)
1147 Evas_Object_Text *o;
1149 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1156 o = (Evas_Object_Text *)(obj->object_data);
1157 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
1164 if (r) *r = o->cur.outline.r;
1165 if (g) *g = o->cur.outline.g;
1166 if (b) *b = o->cur.outline.b;
1167 if (a) *a = o->cur.outline.a;
1171 evas_object_text_style_pad_get(const Evas_Object *obj, int *l, int *r, int *t, int *b)
1173 int sl = 0, sr = 0, st = 0, sb = 0;
1174 Evas_Object_Text *o;
1176 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
1183 o = (Evas_Object_Text *)(obj->object_data);
1184 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
1191 /* use temps to be certain we have initialized values */
1192 evas_text_style_pad_get(o->cur.style, &sl, &sr, &st, &sb);
1203 evas_string_char_next_get(const char *str, int pos, int *decoded)
1207 if (decoded) *decoded = 0;
1208 if ((!str) || (pos < 0)) return 0;
1210 d = eina_unicode_utf8_get_next(str, &p);
1211 if (decoded) *decoded = d;
1216 evas_string_char_prev_get(const char *str, int pos, int *decoded)
1220 if (decoded) *decoded = 0;
1221 if ((!str) || (pos < 1)) return 0;
1223 d = eina_unicode_utf8_get_prev(str, &p);
1224 if (decoded) *decoded = d;
1229 evas_string_char_len_get(const char *str)
1232 return eina_unicode_utf8_get_len(str);
1236 evas_text_style_pad_get(Evas_Text_Style_Type style, int *l, int *r, int *t, int *b)
1238 int sl = 0, sr = 0, st = 0, sb = 0;
1240 /* Don't calc anything if there's no style. */
1241 if (style != EVAS_TEXT_STYLE_PLAIN)
1243 int shad_sz = 0, shad_dst = 0, out_sz = 0;
1244 int dx = 0, minx = 0, maxx = 0;
1245 int dy = 0, miny = 0, maxy = 0;
1246 Eina_Bool have_shadow = EINA_FALSE;
1248 switch (style & EVAS_TEXT_STYLE_MASK_BASIC)
1250 case EVAS_TEXT_STYLE_SHADOW:
1252 have_shadow = EINA_TRUE;
1254 case EVAS_TEXT_STYLE_OUTLINE_SHADOW:
1255 case EVAS_TEXT_STYLE_FAR_SHADOW:
1258 have_shadow = EINA_TRUE;
1260 case EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW:
1264 have_shadow = EINA_TRUE;
1266 case EVAS_TEXT_STYLE_FAR_SOFT_SHADOW:
1269 have_shadow = EINA_TRUE;
1271 case EVAS_TEXT_STYLE_SOFT_SHADOW:
1274 have_shadow = EINA_TRUE;
1276 case EVAS_TEXT_STYLE_GLOW:
1277 case EVAS_TEXT_STYLE_SOFT_OUTLINE:
1280 case EVAS_TEXT_STYLE_OUTLINE:
1293 int shx1, shx2, shy1, shy2;
1294 switch (style & EVAS_TEXT_STYLE_MASK_SHADOW_DIRECTION)
1296 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT:
1300 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM:
1304 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_LEFT:
1308 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_LEFT:
1312 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_LEFT:
1316 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP:
1320 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT:
1324 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_RIGHT:
1330 shx1 = dx * shad_dst;
1332 shx2 = dx * shad_dst;
1334 if (shx1 < minx) minx = shx1;
1335 if (shx2 > maxx) maxx = shx2;
1337 shy1 = dy * shad_dst;
1339 shy2 = dy * shad_dst;
1341 if (shy1 < miny) miny = shy1;
1342 if (shy2 > maxy) maxy = shy2;
1350 if (sr < maxx) sr = maxx;
1351 if (sl < -minx) sl = -minx;
1352 if (sb < maxy) sb = maxy;
1353 if (st < -miny) st = -miny;
1362 /* all nice and private */
1364 evas_object_text_init(Evas_Object *obj)
1366 /* alloc text ob, setup methods and default values */
1367 obj->object_data = evas_object_text_new();
1368 /* set up default settings for this kind of object */
1369 obj->cur.color.r = 255;
1370 obj->cur.color.g = 255;
1371 obj->cur.color.b = 255;
1372 obj->cur.color.a = 255;
1373 obj->cur.geometry.x = 0;
1374 obj->cur.geometry.y = 0;
1375 obj->cur.geometry.w = 0;
1376 obj->cur.geometry.h = 0;
1378 /* set up object-specific settings */
1379 obj->prev = obj->cur;
1380 /* set up methods (compulsory) */
1381 obj->func = &object_func;
1386 evas_object_text_new(void)
1388 Evas_Object_Text *o;
1390 /* alloc obj private data */
1391 EVAS_MEMPOOL_INIT(_mp_obj, "evas_object_text", Evas_Object_Text, 128, NULL);
1392 o = EVAS_MEMPOOL_ALLOC(_mp_obj, Evas_Object_Text);
1393 if (!o) return NULL;
1394 EVAS_MEMPOOL_PREP(_mp_obj, o, Evas_Object_Text);
1395 o->magic = MAGIC_OBJ_TEXT;
1398 o->bidi_par_props = evas_bidi_paragraph_props_new();
1404 evas_object_text_free(Evas_Object *obj)
1406 Evas_Object_Text *o;
1408 /* frees private object data. very simple here */
1409 o = (Evas_Object_Text *)(obj->object_data);
1410 MAGIC_CHECK(o, Evas_Object_Text, MAGIC_OBJ_TEXT);
1414 if (o->items) _evas_object_text_items_clear(o);
1415 if (o->cur.utf8_text) eina_stringshare_del(o->cur.utf8_text);
1416 if (o->cur.font) eina_stringshare_del(o->cur.font);
1417 if (o->cur.fdesc) evas_font_desc_unref(o->cur.fdesc);
1418 if (o->cur.source) eina_stringshare_del(o->cur.source);
1419 if (o->font) evas_font_free(obj->layer->evas, o->font);
1421 evas_bidi_paragraph_props_unref(o->bidi_par_props);
1424 EVAS_MEMPOOL_FREE(_mp_obj, o);
1428 evas_object_text_render(Evas_Object *obj, void *output, void *context, void *surface, int x, int y)
1431 Evas_Object_Text *o;
1432 Evas_Object_Text_Item *it;
1433 const char vals[5][5] =
1442 int shad_dst, shad_sz, dx, dy, haveshad;
1444 /* render object to surface with context, and offxet by x,y */
1445 o = (Evas_Object_Text *)(obj->object_data);
1446 evas_text_style_pad_get(o->cur.style, &sl, NULL, &st, NULL);
1447 ENFN->context_multiplier_unset(output, context);
1448 ENFN->context_render_op_set(output, context, obj->cur.render_op);
1449 /* FIXME: This clipping is just until we fix inset handling correctly. */
1450 ENFN->context_clip_clip(output, context,
1451 obj->cur.geometry.x + x,
1452 obj->cur.geometry.y + y,
1453 obj->cur.geometry.w,
1454 obj->cur.geometry.h);
1456 ENFN->context_color_set(output,
1459 ENFN->rectangle_draw(output,
1462 obj->cur.geometry.x + x,
1463 obj->cur.geometry.y + y,
1464 obj->cur.geometry.w,
1465 obj->cur.geometry.h);
1467 #define COLOR_ONLY_SET(object, sub, col) \
1468 ENFN->context_color_set(output, context, \
1469 object->sub.col.r, \
1470 object->sub.col.g, \
1471 object->sub.col.b, \
1474 #define COLOR_SET(object, sub, col) \
1475 if (obj->cur.clipper)\
1476 ENFN->context_color_set(output, context, \
1477 ((int)object->sub.col.r * ((int)obj->cur.clipper->cur.cache.clip.r + 1)) >> 8, \
1478 ((int)object->sub.col.g * ((int)obj->cur.clipper->cur.cache.clip.g + 1)) >> 8, \
1479 ((int)object->sub.col.b * ((int)obj->cur.clipper->cur.cache.clip.b + 1)) >> 8, \
1480 ((int)object->sub.col.a * ((int)obj->cur.clipper->cur.cache.clip.a + 1)) >> 8); \
1482 ENFN->context_color_set(output, context, \
1483 object->sub.col.r, \
1484 object->sub.col.g, \
1485 object->sub.col.b, \
1488 #define COLOR_SET_AMUL(object, sub, col, amul) \
1489 if (obj->cur.clipper) \
1490 ENFN->context_color_set(output, context, \
1491 (((int)object->sub.col.r) * ((int)obj->cur.clipper->cur.cache.clip.r) * (amul)) / 65025, \
1492 (((int)object->sub.col.g) * ((int)obj->cur.clipper->cur.cache.clip.g) * (amul)) / 65025, \
1493 (((int)object->sub.col.b) * ((int)obj->cur.clipper->cur.cache.clip.b) * (amul)) / 65025, \
1494 (((int)object->sub.col.a) * ((int)obj->cur.clipper->cur.cache.clip.a) * (amul)) / 65025); \
1496 ENFN->context_color_set(output, context, \
1497 (((int)object->sub.col.r) * (amul)) / 255, \
1498 (((int)object->sub.col.g) * (amul)) / 255, \
1499 (((int)object->sub.col.b) * (amul)) / 255, \
1500 (((int)object->sub.col.a) * (amul)) / 255);
1502 #define DRAW_TEXT(ox, oy) \
1503 if ((o->font) && (it->text_props.len > 0)) \
1504 ENFN->font_draw(output, \
1508 obj->cur.geometry.x + x + sl + ox + it->x, \
1509 obj->cur.geometry.y + y + st + oy + \
1511 (((o->max_ascent * obj->cur.geometry.h) / obj->cur.geometry.h) - 0.5), \
1512 obj->cur.geometry.w, \
1513 obj->cur.geometry.h, \
1514 obj->cur.geometry.w, \
1515 obj->cur.geometry.h, \
1519 shad_dst = shad_sz = dx = dy = haveshad = 0;
1520 switch (o->cur.style & EVAS_TEXT_STYLE_MASK_BASIC)
1522 case EVAS_TEXT_STYLE_SHADOW:
1523 case EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW:
1527 case EVAS_TEXT_STYLE_OUTLINE_SHADOW:
1528 case EVAS_TEXT_STYLE_FAR_SHADOW:
1532 case EVAS_TEXT_STYLE_FAR_SOFT_SHADOW:
1537 case EVAS_TEXT_STYLE_SOFT_SHADOW:
1549 switch (o->cur.style & EVAS_TEXT_STYLE_MASK_SHADOW_DIRECTION)
1551 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT:
1555 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM:
1559 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_LEFT:
1563 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_LEFT:
1567 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_LEFT:
1571 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP:
1575 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT:
1579 case EVAS_TEXT_STYLE_SHADOW_DIRECTION_RIGHT:
1589 EINA_INLIST_FOREACH(EINA_INLIST_GET(o->items), it)
1597 COLOR_SET(o, cur, shadow);
1601 for (j = 0; j < 5; j++)
1603 for (i = 0; i < 5; i++)
1605 if (vals[i][j] != 0)
1607 COLOR_SET_AMUL(o, cur, shadow, vals[i][j] * 50);
1608 DRAW_TEXT(i - 2 + dx, j - 2 + dy);
1619 if (o->cur.style == EVAS_TEXT_STYLE_GLOW)
1621 for (j = 0; j < 5; j++)
1623 for (i = 0; i < 5; i++)
1625 if (vals[i][j] != 0)
1627 COLOR_SET_AMUL(o, cur, glow, vals[i][j] * 50);
1628 DRAW_TEXT(i - 2, j - 2);
1632 COLOR_SET(o, cur, glow2);
1640 if ((o->cur.style == EVAS_TEXT_STYLE_OUTLINE) ||
1641 (o->cur.style == EVAS_TEXT_STYLE_OUTLINE_SHADOW) ||
1642 (o->cur.style == EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW))
1644 COLOR_SET(o, cur, outline);
1650 else if (o->cur.style == EVAS_TEXT_STYLE_SOFT_OUTLINE)
1652 for (j = 0; j < 5; j++)
1654 for (i = 0; i < 5; i++)
1656 if (((i != 2) || (j != 2)) && (vals[i][j] != 0))
1658 COLOR_SET_AMUL(o, cur, outline, vals[i][j] * 50);
1659 DRAW_TEXT(i - 2, j - 2);
1666 COLOR_ONLY_SET(obj, cur.cache, clip);
1672 evas_object_text_render_pre(Evas_Object *obj)
1674 Evas_Object_Text *o;
1677 /* dont pre-render the obj twice! */
1678 if (obj->pre_render_done) return;
1679 obj->pre_render_done = 1;
1680 /* pre-render phase. this does anything an object needs to do just before
1681 rendering. This could mean loading the image data, retrieving it from
1682 elsewhere, decoding video etc.
1683 Then when this is done the object needs to figure if it changed and
1684 if so what and where and add the appropriate redraw rectangles */
1685 o = (Evas_Object_Text *)(obj->object_data);
1686 /* if someone is clipping this obj - go calculate the clipper */
1687 if (obj->cur.clipper)
1689 if (obj->cur.cache.clip.dirty)
1690 evas_object_clip_recalc(obj->cur.clipper);
1691 obj->cur.clipper->func->render_pre(obj->cur.clipper);
1693 /* now figure what changed and add draw rects
1694 if it just became visible or invisible */
1695 is_v = evas_object_is_visible(obj);
1696 was_v = evas_object_was_visible(obj);
1699 evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes,
1703 if (obj->changed_map)
1705 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
1709 /* its not visible - we accounted for it appearing or not so just abort */
1710 if (!is_v) goto done;
1711 /* clipper changed this is in addition to anything else for obj */
1712 evas_object_render_pre_clipper_change(&obj->layer->evas->clip_changes, obj);
1713 /* if we restacked (layer or just within a layer) and dont clip anyone */
1716 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
1720 /* if it changed color */
1721 if ((obj->cur.color.r != obj->prev.color.r) ||
1722 (obj->cur.color.g != obj->prev.color.g) ||
1723 (obj->cur.color.b != obj->prev.color.b) ||
1724 (obj->cur.color.a != obj->prev.color.a))
1726 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
1730 /* if it changed geometry - and obviously not visibility or color
1731 calculate differences since we have a constant color fill
1732 we really only need to update the differences */
1733 if ((obj->cur.geometry.x != obj->prev.geometry.x) ||
1734 (obj->cur.geometry.y != obj->prev.geometry.y) ||
1735 (obj->cur.geometry.w != obj->prev.geometry.w) ||
1736 (obj->cur.geometry.h != obj->prev.geometry.h))
1738 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
1742 if (obj->cur.render_op != obj->prev.render_op)
1744 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
1748 if (obj->cur.scale != obj->prev.scale)
1750 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
1756 if ((o->cur.size != o->prev.size) ||
1757 ((o->cur.font != o->prev.font)) ||
1758 ((o->cur.utf8_text != o->prev.utf8_text)) ||
1759 ((o->cur.style != o->prev.style)) ||
1760 ((o->cur.shadow.r != o->prev.shadow.r)) ||
1761 ((o->cur.shadow.g != o->prev.shadow.g)) ||
1762 ((o->cur.shadow.b != o->prev.shadow.b)) ||
1763 ((o->cur.shadow.a != o->prev.shadow.a)) ||
1764 ((o->cur.outline.r != o->prev.outline.r)) ||
1765 ((o->cur.outline.g != o->prev.outline.g)) ||
1766 ((o->cur.outline.b != o->prev.outline.b)) ||
1767 ((o->cur.outline.a != o->prev.outline.a)) ||
1768 ((o->cur.glow.r != o->prev.glow.r)) ||
1769 ((o->cur.glow.g != o->prev.glow.g)) ||
1770 ((o->cur.glow.b != o->prev.glow.b)) ||
1771 ((o->cur.glow.a != o->prev.glow.a)) ||
1772 ((o->cur.glow2.r != o->prev.glow2.r)) ||
1773 ((o->cur.glow2.g != o->prev.glow2.g)) ||
1774 ((o->cur.glow2.b != o->prev.glow2.b)) ||
1775 ((o->cur.glow2.a != o->prev.glow2.a)))
1777 evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes,
1783 evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes,
1788 evas_object_text_render_post(Evas_Object *obj)
1790 Evas_Object_Text *o;
1792 /* this moves the current data to the previous state parts of the object
1793 in whatever way is safest for the object. also if we don't need object
1794 data anymore we can free it if the object deems this is a good idea */
1795 o = (Evas_Object_Text *)(obj->object_data);
1796 /* remove those pesky changes */
1797 evas_object_clip_changes_clean(obj);
1798 /* move cur to prev safely for object data */
1799 obj->prev = obj->cur;
1805 evas_object_text_id_get(Evas_Object *obj)
1807 Evas_Object_Text *o;
1809 o = (Evas_Object_Text *)(obj->object_data);
1811 return MAGIC_OBJ_TEXT;
1815 evas_object_text_visual_id_get(Evas_Object *obj)
1817 Evas_Object_Text *o;
1819 o = (Evas_Object_Text *)(obj->object_data);
1821 return MAGIC_OBJ_SHAPE;
1825 evas_object_text_engine_data_get(Evas_Object *obj)
1827 Evas_Object_Text *o;
1829 o = (Evas_Object_Text *)(obj->object_data);
1830 if (!o) return NULL;
1835 evas_object_text_is_opaque(Evas_Object *obj __UNUSED__)
1837 /* this returns 1 if the internal object data implies that the object is
1838 currently fully opaque over the entire gradient it occupies */
1843 evas_object_text_was_opaque(Evas_Object *obj __UNUSED__)
1845 /* this returns 1 if the internal object data implies that the object was
1846 currently fully opaque over the entire gradient it occupies */
1851 evas_object_text_scale_update(Evas_Object *obj)
1853 Evas_Object_Text *o;
1857 o = (Evas_Object_Text *)(obj->object_data);
1858 font = eina_stringshare_add(o->cur.font);
1860 if (o->cur.font) eina_stringshare_del(o->cur.font);
1862 o->prev.font = NULL;
1865 evas_object_text_font_set(obj, font, size);
1869 _evas_object_text_rehint(Evas_Object *obj)
1871 Evas_Object_Text *o;
1874 o = (Evas_Object_Text *)(obj->object_data);
1875 if (!o->font) return;
1876 #ifdef EVAS_FRAME_QUEUING
1877 evas_common_pipe_op_text_flush((RGBA_Font *) o->font);
1879 evas_font_load_hinting_set(obj->layer->evas, o->font,
1880 obj->layer->evas->hinting);
1881 was = evas_object_is_in_output_rect(obj,
1882 obj->layer->evas->pointer.x,
1883 obj->layer->evas->pointer.y, 1, 1);
1885 _evas_object_text_recalc(obj);
1887 evas_object_change(obj);
1888 evas_object_clip_dirty(obj);
1889 evas_object_coords_recalc(obj);
1890 is = evas_object_is_in_output_rect(obj,
1891 obj->layer->evas->pointer.x,
1892 obj->layer->evas->pointer.y, 1, 1);
1893 if ((is || was) && obj->cur.visible)
1894 evas_event_feed_mouse_move(obj->layer->evas,
1895 obj->layer->evas->pointer.x,
1896 obj->layer->evas->pointer.y,
1897 obj->layer->evas->last_timestamp,
1899 evas_object_inform_call_resize(obj);
1903 _evas_object_text_recalc(Evas_Object *obj)
1905 Evas_Object_Text *o;
1906 Eina_Unicode *text = NULL;
1907 o = (Evas_Object_Text *)(obj->object_data);
1909 if (o->items) _evas_object_text_items_clear(o);
1910 if (o->cur.utf8_text)
1911 text = eina_unicode_utf8_to_unicode(o->cur.utf8_text,
1914 if (!text) text = eina_unicode_strdup(EINA_UNICODE_EMPTY_STRING);
1916 _evas_object_text_layout(obj, o, text);
1918 if (text) free(text);
1920 if ((o->font) && (o->items))
1923 int l = 0, r = 0, t = 0, b = 0;
1925 w = _evas_object_text_horiz_advance_get(obj, o);
1926 h = _evas_object_text_vert_advance_get(obj, o);
1927 evas_text_style_pad_get(o->cur.style, &l, &r, &t, &b);
1928 obj->cur.geometry.w = w + l + r;
1929 obj->cur.geometry.h = h + t + b;
1930 //// obj->cur.cache.geometry.validity = 0;
1936 evas_text_style_pad_get(o->cur.style, NULL, NULL, &t, &b);
1937 obj->cur.geometry.w = 0;
1938 obj->cur.geometry.h = o->max_ascent + o->max_descent + t + b;
1939 //// obj->cur.cache.geometry.validity = 0;