Edje text: Fix a rare issue causing ellipsis not to work.
[framework/uifw/edje.git] / src / lib / edje_text.c
1 #include "edje_private.h"
2 #define _ELLIP_STR "\xE2\x80\xA6"
3
4 /* returns with and height for this part.
5  *
6  * depending on the value of the use_alternate_font_metrics flag, it will
7  * either use evas_object_geometry_get() or the _advance_get() functions.
8  *
9  * The latter is useful if you want to make sure that width and height
10  * are the same value for the same number of characters in the text.
11  * This usually only makes sense for monospaced fonts.
12  *
13  * In future changes to this file, you probably should use this wrapper
14  * function everywhere instead of calling evas_object_geometry_get()
15  * directly.
16  */
17 static inline void
18 part_get_geometry(Edje_Real_Part *rp, Evas_Coord *w, Evas_Coord *h)
19 {
20    if (!rp->part->use_alternate_font_metrics)
21      evas_object_geometry_get(rp->object, NULL, NULL, w, h);
22    else
23      {
24         if (w) *w = evas_object_text_horiz_advance_get(rp->object);
25         if (h) *h = evas_object_text_vert_advance_get(rp->object);
26      }
27 }
28
29 void
30 _edje_text_init(void)
31 {
32 }
33
34 void
35 _edje_text_part_on_add(Edje *ed, Edje_Real_Part *ep)
36 {
37    Edje_Part *pt = ep->part;
38    Edje_Part_Description_Text *desc;
39    unsigned int i;
40
41    if (ep->part->type != EDJE_PART_TYPE_TEXT) return;
42
43    /* if text class exists for this part, add the edje to the tc member list */
44    desc = (Edje_Part_Description_Text *) pt->default_desc;
45    if ((pt->default_desc) && (desc->text.text_class))
46      _edje_text_class_member_add(ed, desc->text.text_class);
47
48    /* If any other classes exist add them */
49    for (i = 0; i < pt->other.desc_count; ++i)
50      {
51         desc = (Edje_Part_Description_Text *) pt->other.desc[i];
52         if ((desc) && (desc->text.text_class))
53           _edje_text_class_member_add(ed, desc->text.text_class);
54      }
55 }
56
57 void
58 _edje_text_part_on_del(Edje *ed, Edje_Part *pt)
59 {
60    Edje_Part_Description_Text *desc;
61    unsigned int i;
62
63    if (!pt) return;
64    if (pt->type != EDJE_PART_TYPE_TEXT
65        && pt->type != EDJE_PART_TYPE_TEXTBLOCK)
66      return ;
67
68    desc = (Edje_Part_Description_Text *) pt->default_desc;
69    if ((pt->default_desc) && (desc->text.text_class))
70      _edje_text_class_member_del(ed, desc->text.text_class);
71
72    for (i = 0; i < pt->other.desc_count; ++i)
73      {
74         desc = (Edje_Part_Description_Text *) pt->other.desc[i];
75         if (desc->text.text_class)
76           _edje_text_class_member_del(ed, desc->text.text_class);
77      }
78 }
79
80 static void
81 _edje_text_fit_set(char *buf, const char *text, int c1, int c2)
82 {
83    /* helper function called from _edje_text_fit_x().
84     * note that we can use strcpy()/strcat() safely, the buffer lengths
85     * are checked in the caller.
86     */
87
88    if (c1 >= 0)
89      {
90         strcpy(buf, _ELLIP_STR);
91
92         if (c2 >= 0)
93           {
94              strncat(buf, text + c1, c2 - c1);
95              strcat(buf, _ELLIP_STR);
96           }
97         else
98           strcat(buf, text + c1);
99      }
100    else
101      {
102         if (c2 >= 0)
103           {
104              strncpy(buf, text, c2);
105              buf[c2] = 0;
106              strcat(buf, _ELLIP_STR);
107           }
108         else
109           strcpy(buf, text);
110      }
111 }
112
113 static const char *
114 _edje_text_fit_x(Edje *ed, Edje_Real_Part *ep,
115                  Edje_Calc_Params *params,
116                  const char *text, const char *font, int size,
117                  Evas_Coord sw, int *free_text)
118 {
119    Evas_Coord tw = 0, th = 0, p;
120    int l, r;
121    int i;
122    char *buf;
123    int uc1 = -1, uc2 = -1, c1 = -1, c2 = -1;
124    int loop = 0, extra;
125    size_t orig_len;
126    FLOAT_T sc;
127
128    sc = ed->scale;
129    if (sc == ZERO) sc = _edje_scale;
130
131    *free_text = 0;
132    if (sw <= 1) return "";
133
134    if (ep->part->scale) evas_object_scale_set(ep->object, TO_DOUBLE(sc));
135    evas_object_text_font_set(ep->object, font, size);
136    evas_object_text_text_set(ep->object, text);
137
138    part_get_geometry(ep, &tw, &th);
139    evas_object_text_style_pad_get(ep->object, &l, &r, NULL, NULL);
140
141    p = ((sw - tw) * params->type.text.elipsis);
142
143    /* chop chop */
144    if (tw > sw)
145      {
146         if (params->type.text.elipsis != 0.0)
147           /* should be the last in text! not the rightmost */
148           uc1 = evas_object_text_last_up_to_pos(ep->object,
149                 -p + l, th / 2);
150         if (params->type.text.elipsis != 1.0)
151           {
152              /* should be the last in text! not the rightmost */
153              if ((-p + sw -r) < 0)
154                 uc2 = evas_object_text_last_up_to_pos(ep->object, 0, th / 2);
155              else
156                 uc2 = evas_object_text_last_up_to_pos(ep->object,
157                       -p + sw - r, th / 2);
158           }
159         if ((uc1 < 0) && (uc2 < 0))
160           {
161              uc1 = 0;
162              uc2 = 0;
163           }
164      }
165
166    if (!(((uc1 >= 0) || (uc2 >= 0)) && (tw > sw)))
167      return text;
168
169    if ((uc1 == 0) && (uc2 == 0))
170      return text;
171
172    orig_len = strlen(text);
173
174    /* don't overflow orig_len by adding extra
175     * FIXME: we might want to set a max string length somewhere...
176     */
177    extra = 1 + 3 + 3; /* terminator, leading and trailing ellipsis */
178    orig_len = MIN(orig_len, ((size_t) 8192 - extra));
179
180    if (!(buf = malloc(orig_len + extra)))
181      return text;
182
183    /* Convert uc1, uc2 -> c1, c2 */
184    i = 0;
185    if (uc1 >= 0)
186      {
187         c1 = 0;
188         for ( ; i < uc1 ; i++)
189           {
190              c1 = evas_string_char_next_get(text, c1, NULL);
191           }
192      }
193    if (uc2 >= 0)
194      {
195         c2 = c1;
196         for ( ; i < uc2 ; i++)
197           {
198              c2 = evas_string_char_next_get(text, c2, NULL);
199           }
200      }
201
202    buf[0] = '\0';
203
204    while (((c1 >= 0) || (c2 >= 0)) && (tw > sw))
205      {
206         loop++;
207         if (sw <= 0.0)
208           {
209              buf[0] = 0;
210              break;
211           }
212         if ((c1 >= 0) && (c2 >= 0))
213           {
214              if ((loop & 0x1))
215                {
216                   if (c1 >= 0)
217                     c1 = evas_string_char_next_get(text, c1, NULL);
218                }
219              else
220                {
221                   if (c2 >= 0)
222                     {
223                        c2 = evas_string_char_prev_get(text, c2, NULL);
224                        if (c2 < 0)
225                          {
226                             buf[0] = 0;
227                             break;
228                          }
229                     }
230                }
231           }
232         else
233           {
234              if (c1 >= 0)
235                c1 = evas_string_char_next_get(text, c1, NULL);
236              else if (c2 >= 0)
237                {
238                   c2 = evas_string_char_prev_get(text, c2, NULL);
239                   if (c2 < 0)
240                     {
241                        buf[0] = 0;
242                        break;
243                     }
244                }
245           }
246         if ((c1 >= 0) && (c2 >= 0))
247           {
248              if (c1 >= c2)
249                {
250                   buf[0] = 0;
251                   break;
252                }
253           }
254         else if ((c1 > 0 && (size_t) c1 >= orig_len) || c2 == 0)
255           {
256              buf[0] = 0;
257              break;
258           }
259
260         buf[0] = 0;
261
262         _edje_text_fit_set(buf, text, c1, c2);
263
264         evas_object_text_text_set(ep->object, buf);
265         part_get_geometry(ep, &tw, &th);
266      }
267
268    *free_text = 1;
269
270    return buf;
271 }
272
273 static const char *
274 _edje_text_font_get(const char *base, const char *new, char **free_later)
275 {
276    const char *base_style, *new_style, *aux;
277    size_t font_len, style_len;
278
279    if (base && (!new))
280      return base;
281    else if (!base)
282      return new;
283
284    base_style = strstr(base, ":style=");
285    if (!base_style)
286      return new;
287
288    new_style = strstr(new, ":style=");
289    if (new_style)
290      return new;
291
292    font_len = strlen(new);
293    aux = strchr(base_style, ',');
294    style_len = (aux) ? (size_t)(aux - base_style) : strlen(base_style);
295
296    *free_later = malloc(font_len + style_len + 1);
297    memcpy(*free_later, new, font_len);
298    memcpy(*free_later + font_len, base_style, style_len);
299    (*free_later)[font_len + style_len] = '\0';
300
301    return *free_later;
302 }
303
304 const char *
305 _edje_text_class_font_get(Edje *ed, Edje_Part_Description_Text *chosen_desc, int *size, char **free_later)
306 {
307    Edje_Text_Class *tc;
308    const char *text_class_name, *font;
309
310    font = edje_string_get(&chosen_desc->text.font);
311    *size = chosen_desc->text.size;
312
313    text_class_name = chosen_desc->text.text_class;
314    if ((!text_class_name) || (!text_class_name[0]))
315      return font;
316
317    tc = _edje_text_class_find(ed, text_class_name);
318    if (!tc)
319      return font;
320
321    font = _edje_text_font_get(edje_string_get(&chosen_desc->text.font), tc->font, free_later);
322    *size = _edje_text_size_calc(*size, tc);
323
324    return font;
325 }
326
327 void
328 _edje_text_recalc_apply(Edje *ed, Edje_Real_Part *ep,
329                         Edje_Calc_Params *params,
330                         Edje_Part_Description_Text *chosen_desc)
331 {
332    const char   *text = NULL;
333    const char   *str;
334    const char   *font;
335    char         *font2 = NULL;
336    char         *sfont = NULL;
337    int           size;
338    Evas_Coord    tw, th;
339    Evas_Coord    sw, sh;
340    int           inlined_font = 0, free_text = 0;
341    FLOAT_T       sc;
342
343    sc = ed->scale;
344    if (sc == 0.0) sc = _edje_scale;
345    text = edje_string_get(&chosen_desc->text.text);
346    font = _edje_text_class_font_get(ed, chosen_desc, &size, &sfont);
347
348    if (ep->text.text) text = (char *) ep->text.text;
349    if (ep->text.font) font = ep->text.font;
350    if (ep->text.size > 0) size = ep->text.size;
351
352    if (ep->text.text_source)
353      {
354         text = edje_string_get(&(((Edje_Part_Description_Text *)ep->text.text_source->chosen_description)->text.text));
355         if (ep->text.text_source->text.text) text = ep->text.text_source->text.text;
356      }
357    if (ep->text.source)
358      {
359         font = edje_string_get(&(((Edje_Part_Description_Text *)ep->text.source->chosen_description)->text.font));
360         size = ((Edje_Part_Description_Text *)ep->text.source->chosen_description)->text.size;
361         if (ep->text.source->text.font) font = ep->text.source->text.font;
362         if (ep->text.source->text.size > 0) size = ep->text.source->text.size;
363      }
364
365    if (!text) text = "";
366    if (!font) font = "";
367
368    /* check if the font is embedded in the .eet */
369    if (ed->file->fonts)
370      {
371         Edje_Font_Directory_Entry *fnt = eina_hash_find(ed->file->fonts, font);
372
373         if (fnt)
374           {
375              char *font2;
376              
377              size_t len = strlen(font) + sizeof("edje/fonts/") + 1;
378              font2 = alloca(len);
379              sprintf(font2, "edje/fonts/%s", font);
380              font = font2;
381              inlined_font = 1;
382           }
383      }
384
385    if ((_edje_fontset_append) && (font))
386      {
387         font2 = malloc(strlen(font) + 1 + strlen(_edje_fontset_append) + 1);
388         if (font2)
389           {
390              strcpy(font2, font);
391              strcat(font2, ",");
392              strcat(font2, _edje_fontset_append);
393              font = font2;
394           }
395      }
396      {
397         int l, r, t, b;
398
399         evas_object_text_style_pad_get(ep->object, &l, &r, &t, &b);
400         sw = params->w;
401         sh = params->h;
402      }
403
404    size = params->type.text.size;
405
406    if ((ep->text.cache.in_size == size) &&
407        (ep->text.cache.in_w == sw) &&
408        (ep->text.cache.in_h == sh) &&
409        (ep->text.cache.in_str) &&
410        (text) &&
411        (!strcmp(ep->text.cache.in_str, text)) &&
412        (ep->text.cache.align_x == params->type.text.align.x) &&
413        (ep->text.cache.align_y == params->type.text.align.y) &&
414        (ep->text.cache.elipsis == params->type.text.elipsis) &&
415        (ep->text.cache.fit_x == chosen_desc->text.fit_x) &&
416        (ep->text.cache.fit_y == chosen_desc->text.fit_y))
417      {
418         text = (char *)ep->text.cache.out_str;
419         size = ep->text.cache.out_size;
420
421         if (!text) text = "";
422
423         goto arrange_text;
424      }
425    if (ep->text.cache.in_str) eina_stringshare_del(ep->text.cache.in_str);
426    ep->text.cache.in_str = eina_stringshare_add(text);
427    ep->text.cache.in_size = size;
428    if (chosen_desc->text.fit_x && (ep->text.cache.in_str && eina_stringshare_strlen(ep->text.cache.in_str) > 0))
429      {
430         if (inlined_font) evas_object_text_font_source_set(ep->object, ed->path);
431         else evas_object_text_font_source_set(ep->object, NULL);
432
433         if (ep->part->scale) evas_object_scale_set(ep->object, TO_DOUBLE(sc));
434         evas_object_text_font_set(ep->object, font, size);
435         evas_object_text_text_set(ep->object, text);
436         part_get_geometry(ep, &tw, &th);
437         /* Find the wanted font size */
438         if ((tw > sw) && (size > 0) && (tw != 0))
439           {
440              size = (size * sw) / tw;
441
442              if (inlined_font) evas_object_text_font_source_set(ep->object, ed->path);
443              else evas_object_text_font_source_set(ep->object, NULL);
444
445              if (ep->part->scale) evas_object_scale_set(ep->object, TO_DOUBLE(sc));
446              evas_object_text_font_set(ep->object, font, size);
447              part_get_geometry(ep, &tw, &th);
448           }
449         else if ((tw < sw) && (size > 0) && (tw != 0))
450           {
451              size = (size * sw) / tw;
452
453              if (inlined_font) evas_object_text_font_source_set(ep->object, ed->path);
454              else evas_object_text_font_source_set(ep->object, NULL);
455
456              if (ep->part->scale) evas_object_scale_set(ep->object, TO_DOUBLE(sc));
457              evas_object_text_font_set(ep->object, font, size);
458              part_get_geometry(ep, &tw, &th);
459           }
460         /* FIXME: This should possibly be replaced by more proper handling,
461          * but it's still way better than what was here before. */
462         if (tw > sw) size--;
463      }
464    if (chosen_desc->text.fit_y && (ep->text.cache.in_str && eina_stringshare_strlen(ep->text.cache.in_str) > 0))
465      {
466         /* if we fit in the x axis, too, size already has a somewhat
467          * meaningful value, so don't overwrite it with the starting
468          * value in that case
469          */
470         if (!chosen_desc->text.fit_x) size = sh;
471
472         if (inlined_font) evas_object_text_font_source_set(ep->object, ed->path);
473         else evas_object_text_font_source_set(ep->object, NULL);
474
475         if (ep->part->scale) evas_object_scale_set(ep->object, TO_DOUBLE(sc));
476         evas_object_text_font_set(ep->object, font, size);
477         evas_object_text_text_set(ep->object, text);
478         part_get_geometry(ep, &tw, &th);
479
480         /* only grow the font size if we didn't already reach the max size
481          * for the x axis
482          */
483         if (!chosen_desc->text.fit_x && th < sh)
484           {
485              int dif;
486
487              dif = (th - sh) / 4;
488              if (dif < 1) dif = 1;
489              while ((th < sh) && (sw > 0))
490                {
491                   size += dif;
492                   if (size <= 0) break;
493                   if (inlined_font) evas_object_text_font_source_set(ep->object, ed->path);
494                   else evas_object_text_font_source_set(ep->object, NULL);
495
496                   if (ep->part->scale) evas_object_scale_set(ep->object, TO_DOUBLE(sc));
497                   evas_object_text_font_set(ep->object, font, size);
498                   part_get_geometry(ep, &tw, &th);
499                   if ((size > 0) && (th == 0)) break;
500                }
501              size -= dif;
502           }
503         else if (th > sh)
504           {
505              int current;
506
507              if (ep->part->scale) evas_object_scale_set(ep->object, TO_DOUBLE(sc));
508              evas_object_text_font_set(ep->object, font, 10);
509              part_get_geometry(ep, &tw, &th);
510
511              if (th == sh)
512                current = 10;
513              else
514                {
515                   int bottom, top;
516
517                   if (th < sh) bottom = 10;
518                   else if (th > sh) bottom = 1;
519                   else bottom = 0; /* XXX shut up GCC, th == sh is handled before! */
520
521                   top = size;
522                   /* search one that fits (binary search) */
523                   do
524                     {
525                        current = (top + bottom) / 2;
526
527                        if (ep->part->scale) evas_object_scale_set(ep->object, TO_DOUBLE(sc));
528                        evas_object_text_font_set(ep->object, font, current);
529                        part_get_geometry(ep, &tw, &th);
530
531                        if      (th < sh) bottom = current + 1;
532                        else if (th > sh) top    = current - 1;
533                     } while ((bottom < top) && (th != sh));
534                }
535
536              /* search the larger one that fits (linear search) */
537              do
538                {
539                   current++;
540
541                   if (ep->part->scale) evas_object_scale_set(ep->object, TO_DOUBLE(sc));
542                   evas_object_text_font_set(ep->object, font, current);
543                   part_get_geometry(ep, &tw, &th);
544                } while (th <= sh);
545              size = current - 1;
546           }
547      }
548
549    /* Make sure the size is in range */
550    if (size < 1)
551       size = 1;
552    else if ((size > chosen_desc->text.size_range_max) &&
553             (chosen_desc->text.size_range_max > 0))
554       size = chosen_desc->text.size_range_max;
555    else if (size < chosen_desc->text.size_range_min)
556       size = chosen_desc->text.size_range_min;
557
558    /* Handle ellipsis */
559      {
560         if (inlined_font) evas_object_text_font_source_set(ep->object, ed->path);
561         else evas_object_text_font_source_set(ep->object, NULL);
562
563         text = _edje_text_fit_x(ed, ep, params, text, font, size, sw, &free_text);
564      }
565
566    str = eina_stringshare_add(text);
567    if (ep->text.cache.out_str) eina_stringshare_del(ep->text.cache.out_str);
568    ep->text.cache.out_str = str;
569    ep->text.cache.in_w = sw;
570    ep->text.cache.in_h = sh;
571    ep->text.cache.out_size = size;
572    ep->text.cache.align_x = params->type.text.align.x;
573    ep->text.cache.align_y = params->type.text.align.y;
574    ep->text.cache.elipsis = params->type.text.elipsis;
575    ep->text.cache.fit_x = chosen_desc->text.fit_x;
576    ep->text.cache.fit_y = chosen_desc->text.fit_y;
577    arrange_text:
578
579    if (inlined_font) evas_object_text_font_source_set(ep->object, ed->path);
580    else evas_object_text_font_source_set(ep->object, NULL);
581
582    if (ep->part->scale) evas_object_scale_set(ep->object, TO_DOUBLE(sc));
583    evas_object_text_font_set(ep->object, font, size);
584    evas_object_text_text_set(ep->object, text);
585    part_get_geometry(ep, &tw, &th);
586    /* Handle alignment */
587      {
588         double align_x;
589         if (params->type.text.align.x < 0.0)
590           {
591              if (evas_object_text_direction_get(ep->object) ==
592                    EVAS_BIDI_DIRECTION_RTL)
593                {
594                   align_x = 1.0;
595                }
596              else
597                {
598                   align_x = 0.0;
599                }
600           }
601         else
602           {
603              align_x = params->type.text.align.x;
604           }
605         ep->text.offset.x = TO_INT(SCALE(align_x, (sw - tw)));
606         ep->text.offset.y = TO_INT(SCALE(params->type.text.align.y, (sh - th)));
607      }
608
609    evas_object_move(ep->object,
610                     ed->x + params->x + ep->text.offset.x,
611                     ed->y + params->y + ep->text.offset.y);
612
613    if (params->visible) evas_object_show(ep->object);
614    else evas_object_hide(ep->object);
615      {
616         Evas_Text_Style_Type style;
617         Edje_Text_Effect effect;
618
619         style = EVAS_TEXT_STYLE_PLAIN;
620
621         evas_object_color_set(ep->object,
622                               (params->color.r * params->color.a) / 255,
623                               (params->color.g * params->color.a) / 255,
624                               (params->color.b * params->color.a) / 255,
625                               params->color.a);
626         effect = ep->part->effect;
627         switch (effect & EDJE_TEXT_EFFECT_MASK_BASIC)
628           {
629            case EDJE_TEXT_EFFECT_NONE:
630            case EDJE_TEXT_EFFECT_PLAIN:
631              style = EVAS_TEXT_STYLE_PLAIN;
632              break;
633            case EDJE_TEXT_EFFECT_OUTLINE:
634              style = EVAS_TEXT_STYLE_OUTLINE;
635              evas_object_text_outline_color_set(ep->object,
636                                                 (params->type.text.color2.r * params->type.text.color2.a) / 255,
637                                                 (params->type.text.color2.g * params->type.text.color2.a) / 255,
638                                                 (params->type.text.color2.b * params->type.text.color2.a) / 255,
639                                                 params->type.text.color2.a);
640              break;
641            case EDJE_TEXT_EFFECT_SOFT_OUTLINE:
642              style = EVAS_TEXT_STYLE_SOFT_OUTLINE;
643              evas_object_text_outline_color_set(ep->object,
644                                                 (params->type.text.color2.r * params->type.text.color2.a) / 255,
645                                                 (params->type.text.color2.g * params->type.text.color2.a) / 255,
646                                                 (params->type.text.color2.b * params->type.text.color2.a) / 255,
647                                                 params->type.text.color2.a);
648              break;
649            case EDJE_TEXT_EFFECT_SHADOW:
650              style = EVAS_TEXT_STYLE_SHADOW;
651              evas_object_text_shadow_color_set(ep->object,
652                                                (params->type.text.color3.r * params->type.text.color3.a) / 255,
653                                                (params->type.text.color3.g * params->type.text.color3.a) / 255,
654                                                (params->type.text.color3.b * params->type.text.color3.a) / 255,
655                                                params->type.text.color3.a);
656              break;
657            case EDJE_TEXT_EFFECT_SOFT_SHADOW:
658              style = EVAS_TEXT_STYLE_SOFT_SHADOW;
659              evas_object_text_shadow_color_set(ep->object,
660                                                (params->type.text.color3.r * params->type.text.color3.a) / 255,
661                                                (params->type.text.color3.g * params->type.text.color3.a) / 255,
662                                                (params->type.text.color3.b * params->type.text.color3.a) / 255,
663                                                params->type.text.color3.a);
664              break;
665            case EDJE_TEXT_EFFECT_OUTLINE_SHADOW:
666              style = EVAS_TEXT_STYLE_OUTLINE_SHADOW;
667              evas_object_text_outline_color_set(ep->object,
668                                                 (params->type.text.color2.r * params->type.text.color2.a) / 255,
669                                                 (params->type.text.color2.g * params->type.text.color2.a) / 255,
670                                                 (params->type.text.color2.b * params->type.text.color2.a) / 255,
671                                                 params->type.text.color2.a);
672              evas_object_text_shadow_color_set(ep->object,
673                                                (params->type.text.color3.r * params->type.text.color3.a) / 255,
674                                                (params->type.text.color3.g * params->type.text.color3.a) / 255,
675                                                (params->type.text.color3.b * params->type.text.color3.a) / 255,
676                                                params->type.text.color3.a);
677              break;
678            case EDJE_TEXT_EFFECT_OUTLINE_SOFT_SHADOW:
679              style = EVAS_TEXT_STYLE_OUTLINE_SOFT_SHADOW;
680              evas_object_text_outline_color_set(ep->object,
681                                                 (params->type.text.color2.r * params->type.text.color2.a) / 255,
682                                                 (params->type.text.color2.g * params->type.text.color2.a) / 255,
683                                                 (params->type.text.color2.b * params->type.text.color2.a) / 255,
684                                                 params->type.text.color2.a);
685              evas_object_text_shadow_color_set(ep->object,
686                                                (params->type.text.color3.r * params->type.text.color3.a) / 255,
687                                                (params->type.text.color3.g * params->type.text.color3.a) / 255,
688                                                (params->type.text.color3.b * params->type.text.color3.a) / 255,
689                                                params->type.text.color3.a);
690              break;
691            case EDJE_TEXT_EFFECT_FAR_SHADOW:
692              style = EVAS_TEXT_STYLE_FAR_SHADOW;
693              evas_object_text_shadow_color_set(ep->object,
694                                                (params->type.text.color3.r * params->type.text.color3.a) / 255,
695                                                (params->type.text.color3.g * params->type.text.color3.a) / 255,
696                                                (params->type.text.color3.b * params->type.text.color3.a) / 255,
697                                                params->type.text.color3.a);
698              break;
699            case EDJE_TEXT_EFFECT_FAR_SOFT_SHADOW:
700              style = EVAS_TEXT_STYLE_FAR_SOFT_SHADOW;
701              evas_object_text_shadow_color_set(ep->object,
702                                                (params->type.text.color3.r * params->type.text.color3.a) / 255,
703                                                (params->type.text.color3.g * params->type.text.color3.a) / 255,
704                                                (params->type.text.color3.b * params->type.text.color3.a) / 255,
705                                                params->type.text.color3.a);
706              break;
707            case EDJE_TEXT_EFFECT_GLOW:
708              style = EVAS_TEXT_STYLE_GLOW;
709              evas_object_text_glow_color_set(ep->object,
710                                              (params->type.text.color2.r * params->type.text.color2.a) / 255,
711                                              (params->type.text.color2.g * params->type.text.color2.a) / 255,
712                                              (params->type.text.color2.b * params->type.text.color2.a) / 255,
713                                              params->type.text.color2.a);
714              evas_object_text_glow2_color_set(ep->object,
715                                               (params->type.text.color3.r * params->type.text.color3.a) / 255,
716                                               (params->type.text.color3.g * params->type.text.color3.a) / 255,
717                                               (params->type.text.color3.b * params->type.text.color3.a) / 255,
718                                               params->type.text.color3.a);
719              break;
720            default:
721              style = EVAS_TEXT_STYLE_PLAIN;
722              break;
723           }
724         
725         switch (effect & EDJE_TEXT_EFFECT_MASK_SHADOW_DIRECTION)
726           {
727            case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM_RIGHT:
728              EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET
729                 (style, EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_RIGHT);
730              break;
731            case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM:
732              EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET
733                 (style, EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM);
734              break;
735            case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_BOTTOM_LEFT:
736              EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET
737                 (style, EVAS_TEXT_STYLE_SHADOW_DIRECTION_BOTTOM_LEFT);
738              break;
739            case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_LEFT:
740              EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET
741                 (style, EVAS_TEXT_STYLE_SHADOW_DIRECTION_LEFT);
742              break;
743            case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP_LEFT:
744              EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET
745                 (style, EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_LEFT);
746              break;
747            case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP:
748              EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET
749                 (style, EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP);
750              break;
751            case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_TOP_RIGHT:
752              EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET
753                 (style, EVAS_TEXT_STYLE_SHADOW_DIRECTION_TOP_RIGHT);
754              break;
755            case EDJE_TEXT_EFFECT_SHADOW_DIRECTION_RIGHT:
756              EVAS_TEXT_STYLE_SHADOW_DIRECTION_SET
757                 (style, EVAS_TEXT_STYLE_SHADOW_DIRECTION_RIGHT);
758              break;
759            default:
760              break;
761           }
762         evas_object_text_style_set(ep->object, style);
763      }
764    
765    if (free_text) free((char *)text);
766    if (font2) free(font2);
767    if (sfont) free(sfont);
768 }
769
770 Evas_Font_Size
771 _edje_text_size_calc(Evas_Font_Size size, Edje_Text_Class *tc)
772 {
773    int val;
774
775    if (tc->size == 0)
776      {
777         val = size;
778      }
779    else if (tc->size > 0.0)
780      {
781         val = tc->size;
782      }
783    else
784      {
785         val = (size * -tc->size) / 100;
786      }
787    return val;
788 }