summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Alcantara <pcacjr@profusion.mobi>2013-01-15 17:35:11 +0000
committerUlisses Furquim <ulisses@profusion.mobi>2013-01-15 17:35:11 +0000
commitb557bd9e0d3f1e056a7c554d9767710e096dace8 (patch)
tree2d3aabf729a3e9d4f987d26c557c34381ceb33ae
parent8d983bb092b59423fd90aa324e45935382e4b4b4 (diff)
efl/engines: Introduce multi_font_draw() function
This new engine function will only be used in software generic for now - since it's the only engine used with the async render. This function has been introduced in order to avoid growing thread command queue too much to draw a text_props at a time on render calls from textgrid objects. Patch by: Paulo Alcantara <pcacjr@profusion.mobi> SVN revision: 82832
-rw-r--r--ChangeLog5
-rw-r--r--NEWS2
-rw-r--r--src/lib/evas/canvas/evas_main.c2
-rw-r--r--src/lib/evas/canvas/evas_object_textgrid.c128
-rw-r--r--src/lib/evas/canvas/evas_render.c16
-rw-r--r--src/lib/evas/common/evas_font_draw.c15
-rw-r--r--src/lib/evas/common/evas_text_utils.h27
-rw-r--r--src/lib/evas/include/evas_private.h5
-rw-r--r--src/modules/evas/engines/software_generic/evas_engine.c76
9 files changed, 251 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index d8997ebdb7..421e2e3397 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
12013-01-15 Paulo Alcantara (pcacjr)
2
3 * Evas engines: Introduce multi_font_draw() function
4 * Evas textgrid: Change render to support multi_font_draw()
5
12013-01-15 Tom Hacohen (TAsn) 62013-01-15 Tom Hacohen (TAsn)
2 7
3 * Evas textblock: Fixed issue and simplified cursor_geometry_get. 8 * Evas textblock: Fixed issue and simplified cursor_geometry_get.
diff --git a/NEWS b/NEWS
index 71325bdcee..34437a01ee 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,7 @@ Changes since 1.7.0:
6-------------------- 6--------------------
7 7
8Additions: 8Additions:
9 * Add multiple font draws support to engines
9 * Add DOCTYPE children parsing in eina_simple_xml 10 * Add DOCTYPE children parsing in eina_simple_xml
10 * Add eina_barrier thread API 11 * Add eina_barrier thread API
11 * Add eina_tmpstr_add() and eina_tmpstr_del() 12 * Add eina_tmpstr_add() and eina_tmpstr_del()
@@ -65,6 +66,7 @@ Removed:
65 * Removed XRender, WinCE, X11-16 and X11-8 ecore_evas support. 66 * Removed XRender, WinCE, X11-16 and X11-8 ecore_evas support.
66 67
67Improvements: 68Improvements:
69 * Reduced number of enqueued font commands when rendering textgrid objects
68 * Single EFL tree covering all EFL library components. 70 * Single EFL tree covering all EFL library components.
69 * Speedup Eina Rbtree Iterator by recycling memory instead of 71 * Speedup Eina Rbtree Iterator by recycling memory instead of
70 repeatedly calling malloc/free. 72 repeatedly calling malloc/free.
diff --git a/src/lib/evas/canvas/evas_main.c b/src/lib/evas/canvas/evas_main.c
index 0dc6fae1b8..dbe07e1d31 100644
--- a/src/lib/evas/canvas/evas_main.c
+++ b/src/lib/evas/canvas/evas_main.c
@@ -144,6 +144,7 @@ _constructor(Eo *eo_obj, void *class_data, va_list *list EINA_UNUSED)
144 EVAS_ARRAY_SET(e, clip_changes); 144 EVAS_ARRAY_SET(e, clip_changes);
145 EVAS_ARRAY_SET(e, image_unref_queue); 145 EVAS_ARRAY_SET(e, image_unref_queue);
146 EVAS_ARRAY_SET(e, glyph_unref_queue); 146 EVAS_ARRAY_SET(e, glyph_unref_queue);
147 EVAS_ARRAY_SET(e, texts_unref_queue);
147 148
148#undef EVAS_ARRAY_SET 149#undef EVAS_ARRAY_SET
149} 150}
@@ -251,6 +252,7 @@ _destructor(Eo *eo_e, void *_pd, va_list *list EINA_UNUSED)
251 eina_array_flush(&e->clip_changes); 252 eina_array_flush(&e->clip_changes);
252 eina_array_flush(&e->image_unref_queue); 253 eina_array_flush(&e->image_unref_queue);
253 eina_array_flush(&e->glyph_unref_queue); 254 eina_array_flush(&e->glyph_unref_queue);
255 eina_array_flush(&e->texts_unref_queue);
254 256
255 EINA_LIST_FREE(e->touch_points, touch_point) 257 EINA_LIST_FREE(e->touch_points, touch_point)
256 free(touch_point); 258 free(touch_point);
diff --git a/src/lib/evas/canvas/evas_object_textgrid.c b/src/lib/evas/canvas/evas_object_textgrid.c
index 63f557732e..4e80f7a568 100644
--- a/src/lib/evas/canvas/evas_object_textgrid.c
+++ b/src/lib/evas/canvas/evas_object_textgrid.c
@@ -23,8 +23,8 @@ typedef struct _Evas_Object_Textgrid_Row Evas_Object_Textgrid_Row;
23typedef struct _Evas_Object_Textgrid_Rect Evas_Object_Textgrid_Rect; 23typedef struct _Evas_Object_Textgrid_Rect Evas_Object_Textgrid_Rect;
24typedef struct _Evas_Object_Textgrid_Text Evas_Object_Textgrid_Text; 24typedef struct _Evas_Object_Textgrid_Text Evas_Object_Textgrid_Text;
25typedef struct _Evas_Object_Textgrid_Line Evas_Object_Textgrid_Line; 25typedef struct _Evas_Object_Textgrid_Line Evas_Object_Textgrid_Line;
26typedef struct _Evas_Textgrid_Hash_Master Evas_Textgrid_Hash_Master; 26typedef struct _Evas_Textgrid_Hash_Master Evas_Textgrid_Hash_Master;
27typedef struct _Evas_Textgrid_Hash_Glyphs Evas_Textgrid_Hash_Glyphs; 27typedef struct _Evas_Textgrid_Hash_Glyphs Evas_Textgrid_Hash_Glyphs;
28 28
29struct _Evas_Textgrid_Hash_Master 29struct _Evas_Textgrid_Hash_Master
30{ 30{
@@ -370,7 +370,7 @@ static void
370evas_object_textgrid_row_clear(Evas_Object_Textgrid *o, Evas_Object_Textgrid_Row *r) 370evas_object_textgrid_row_clear(Evas_Object_Textgrid *o, Evas_Object_Textgrid_Row *r)
371{ 371{
372 int i; 372 int i;
373 373
374 if (r->rects) 374 if (r->rects)
375 { 375 {
376 free(r->rects); 376 free(r->rects);
@@ -480,7 +480,7 @@ evas_object_textgrid_row_rect_append(Evas_Object_Textgrid_Row *row, int x, int w
480 if (row->rects_num > row->rects_alloc) 480 if (row->rects_num > row->rects_alloc)
481 { 481 {
482 Evas_Object_Textgrid_Rect *t; 482 Evas_Object_Textgrid_Rect *t;
483 483
484 row->rects_alloc += 8; // dont expect many rects per line 484 row->rects_alloc += 8; // dont expect many rects per line
485 t = realloc(row->rects, sizeof(Evas_Object_Textgrid_Rect) * row->rects_alloc); 485 t = realloc(row->rects, sizeof(Evas_Object_Textgrid_Rect) * row->rects_alloc);
486 if (!t) 486 if (!t)
@@ -501,11 +501,13 @@ evas_object_textgrid_row_rect_append(Evas_Object_Textgrid_Row *row, int x, int w
501static void 501static void
502evas_object_textgrid_row_text_append(Evas_Object_Textgrid_Row *row, Evas_Object *eo_obj, Evas_Object_Textgrid *o, int x, Eina_Unicode codepoint, int r, int g, int b, int a) 502evas_object_textgrid_row_text_append(Evas_Object_Textgrid_Row *row, Evas_Object *eo_obj, Evas_Object_Textgrid *o, int x, Eina_Unicode codepoint, int r, int g, int b, int a)
503{ 503{
504 unsigned int text_props_index;
505
504 row->texts_num++; 506 row->texts_num++;
505 if (row->texts_num > row->texts_alloc) 507 if (row->texts_num > row->texts_alloc)
506 { 508 {
507 Evas_Object_Textgrid_Text *t; 509 Evas_Object_Textgrid_Text *t;
508 510
509 row->texts_alloc += 32; // expect more text per line 511 row->texts_alloc += 32; // expect more text per line
510 t = realloc(row->texts, sizeof(Evas_Object_Textgrid_Text) * row->texts_alloc); 512 t = realloc(row->texts, sizeof(Evas_Object_Textgrid_Text) * row->texts_alloc);
511 if (!t) 513 if (!t)
@@ -516,7 +518,9 @@ evas_object_textgrid_row_text_append(Evas_Object_Textgrid_Row *row, Evas_Object
516 row->texts = t; 518 row->texts = t;
517 } 519 }
518 520
519 row->texts[row->texts_num - 1].text_props = evas_object_textgrid_textprop_ref(eo_obj, o, codepoint); 521 text_props_index = evas_object_textgrid_textprop_ref(eo_obj, o, codepoint);
522
523 row->texts[row->texts_num - 1].text_props = text_props_index;
520 row->texts[row->texts_num - 1].x = x; 524 row->texts[row->texts_num - 1].x = x;
521 row->texts[row->texts_num - 1].r = r; 525 row->texts[row->texts_num - 1].r = r;
522 row->texts[row->texts_num - 1].g = g; 526 row->texts[row->texts_num - 1].g = g;
@@ -531,7 +535,7 @@ evas_object_textgrid_row_line_append(Evas_Object_Textgrid_Row *row, int x, int w
531 if (row->lines_num > row->lines_alloc) 535 if (row->lines_num > row->lines_alloc)
532 { 536 {
533 Evas_Object_Textgrid_Line *t; 537 Evas_Object_Textgrid_Line *t;
534 538
535 row->lines_alloc += 8; // dont expect many lines per line 539 row->lines_alloc += 8; // dont expect many lines per line
536 t = realloc(row->lines, sizeof(Evas_Object_Textgrid_Line) * row->lines_alloc); 540 t = realloc(row->lines, sizeof(Evas_Object_Textgrid_Line) * row->lines_alloc);
537 if (!t) 541 if (!t)
@@ -550,6 +554,18 @@ evas_object_textgrid_row_line_append(Evas_Object_Textgrid_Row *row, int x, int w
550 row->lines[row->lines_num - 1].a = a; 554 row->lines[row->lines_num - 1].a = a;
551} 555}
552 556
557static Eina_Bool
558_drop_glyphs_ref(const void *container EINA_UNUSED, void *data, void *fdata)
559{
560 Evas_Font_Array_Data *fad = data;
561 Evas_Public_Data *pd = fdata;
562
563 evas_common_font_glyphs_unref(fad->glyphs);
564 eina_array_pop(&pd->glyph_unref_queue);
565
566 return EINA_TRUE;
567}
568
553static void 569static void
554evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async) 570evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, void *output, void *context, void *surface, int x, int y, Eina_Bool do_async)
555{ 571{
@@ -559,13 +575,13 @@ evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
559 int xx, yy, xp, yp, w, h, ww, hh; 575 int xx, yy, xp, yp, w, h, ww, hh;
560 int rr = 0, rg = 0, rb = 0, ra = 0, rx = 0, rw = 0, run; 576 int rr = 0, rg = 0, rb = 0, ra = 0, rx = 0, rw = 0, run;
561 577
562 /* render object to surface with context, and offxet by x,y */ 578 /* render object to surface with context, and offset by x,y */
563 Evas_Object_Textgrid *o = eo_data_get(eo_obj, MY_CLASS); 579 Evas_Object_Textgrid *o = eo_data_get(eo_obj, MY_CLASS);
564 ENFN->context_multiplier_unset(output, context); 580 ENFN->context_multiplier_unset(output, context);
565 ENFN->context_render_op_set(output, context, obj->cur.render_op); 581 ENFN->context_render_op_set(output, context, obj->cur.render_op);
566 582
567 if (!(o->font) || (!o->cur.cells)) return; 583 if (!(o->font) || (!o->cur.cells)) return;
568 584
569 w = o->cur.char_width; 585 w = o->cur.char_width;
570 h = o->cur.char_height; 586 h = o->cur.char_height;
571 ww = obj->cur.geometry.w; 587 ww = obj->cur.geometry.w;
@@ -575,7 +591,7 @@ evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
575 for (yy = 0, cells = o->cur.cells; yy < o->cur.h; yy++) 591 for (yy = 0, cells = o->cur.cells; yy < o->cur.h; yy++)
576 { 592 {
577 Evas_Object_Textgrid_Row *row = &(o->cur.rows[yy]); 593 Evas_Object_Textgrid_Row *row = &(o->cur.rows[yy]);
578 594
579 if (row->ch1 < 0) 595 if (row->ch1 < 0)
580 { 596 {
581 cells += o->cur.w; 597 cells += o->cur.w;
@@ -661,34 +677,104 @@ evas_object_textgrid_render(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj
661 for (yy = 0, cells = o->cur.cells; yy < o->cur.h; yy++) 677 for (yy = 0, cells = o->cur.cells; yy < o->cur.h; yy++)
662 { 678 {
663 Evas_Object_Textgrid_Row *row = &(o->cur.rows[yy]); 679 Evas_Object_Textgrid_Row *row = &(o->cur.rows[yy]);
680 Evas_Font_Array *texts;
664 681
665 xp = obj->cur.geometry.x + x; 682 xp = obj->cur.geometry.x + x;
666 for (xx = 0; xx < row->rects_num; xx++) 683 for (xx = 0; xx < row->rects_num; xx++)
667 { 684 {
668 ENFN->context_color_set(output, context, 685 ENFN->context_color_set(output, context,
669 row->rects[xx].r, row->rects[xx].g, 686 row->rects[xx].r, row->rects[xx].g,
670 row->rects[xx].b, row->rects[xx].a); 687 row->rects[xx].b, row->rects[xx].a);
671 ENFN->rectangle_draw(output, context, surface, 688 ENFN->rectangle_draw(output, context, surface,
672 xp + row->rects[xx].x, yp, 689 xp + row->rects[xx].x, yp,
673 row->rects[xx].w, h, 690 row->rects[xx].w, h,
674 do_async); 691 do_async);
675 } 692 }
676 for (xx = 0; xx < row->texts_num; xx++) 693
694 if (row->texts_num)
677 { 695 {
678 ENFN->context_color_set(output, context, 696 if ((do_async) && (ENFN->multi_font_draw))
679 row->texts[xx].r, row->texts[xx].g, 697 {
680 row->texts[xx].b, row->texts[xx].a); 698 Eina_Bool async_unref;
681 evas_font_draw_async_check(obj, output, context, surface, o->font, 699
682 xp + row->texts[xx].x, yp + o->max_ascent, 700 texts = malloc(sizeof(*texts));
683 ww, hh, ww, hh, 701 texts->array = eina_inarray_new(sizeof(Evas_Font_Array_Data),
684 evas_object_textgrid_textprop_int_to(o, row->texts[xx].text_props), 702 32);
685 do_async); 703 texts->refcount = 1;
704
705 for (xx = 0; xx < row->texts_num; xx++)
706 {
707 Evas_Text_Props *props;
708 Evas_Font_Array_Data fad;
709
710 props =
711 evas_object_textgrid_textprop_int_to
712 (o, row->texts[xx].text_props);
713
714 evas_common_font_draw_prepare(props);
715
716 evas_common_font_glyphs_ref(props->glyphs);
717 evas_unref_queue_glyph_put(obj->layer->evas,
718 props->glyphs);
719
720 fad.color.r = row->texts[xx].r;
721 fad.color.g = row->texts[xx].g;
722 fad.color.b = row->texts[xx].b;
723 fad.color.a = row->texts[xx].a;
724 fad.x = row->texts[xx].x;
725 fad.glyphs = props->glyphs;
726
727 if (eina_inarray_push(texts->array, &fad) < 0)
728 ERR("Failed to push text onto texts array %p",
729 texts->array);
730 }
731
732 async_unref =
733 ENFN->multi_font_draw(output, context, surface,
734 o->font, xp, yp + o->max_ascent,
735 ww, hh, ww, hh, texts, do_async);
736 if (async_unref)
737 evas_unref_queue_texts_put(obj->layer->evas, texts);
738 else
739 {
740 eina_inarray_foreach(texts->array, _drop_glyphs_ref,
741 obj->layer->evas);
742 eina_inarray_free(texts->array);
743 free(texts);
744 }
745 }
746 else
747 {
748 for (xx = 0; xx < row->texts_num; xx++)
749 {
750 Evas_Text_Props *props;
751 unsigned int r, g, b, a;
752 int tx = xp + row->texts[xx].x;
753 int ty = yp + o->max_ascent;
754
755 props =
756 evas_object_textgrid_textprop_int_to
757 (o, row->texts[xx].text_props);
758
759 r = row->texts[xx].r;
760 g = row->texts[xx].g;
761 b = row->texts[xx].b;
762 a = row->texts[xx].a;
763
764 ENFN->context_color_set(output, context,
765 r, g, b, a);
766 evas_font_draw_async_check(obj, output, context, surface,
767 o->font, tx, ty, ww, hh,
768 ww, hh, props, do_async);
769 }
770 }
686 } 771 }
772
687 for (xx = 0; xx < row->lines_num; xx++) 773 for (xx = 0; xx < row->lines_num; xx++)
688 { 774 {
689 ENFN->context_color_set(output, context, 775 ENFN->context_color_set(output, context,
690 row->lines[xx].r, row->lines[xx].g, 776 row->lines[xx].r, row->lines[xx].g,
691 row->lines[xx].b, row->lines[xx].a); 777 row->lines[xx].b, row->lines[xx].a);
692 ENFN->rectangle_draw(output, context, surface, 778 ENFN->rectangle_draw(output, context, surface,
693 xp + row->lines[xx].x, yp + row->lines[xx].y, 779 xp + row->lines[xx].x, yp + row->lines[xx].y,
694 row->lines[xx].w, 1, 780 row->lines[xx].w, 1,
diff --git a/src/lib/evas/canvas/evas_render.c b/src/lib/evas/canvas/evas_render.c
index 0b7a056eda..0136f736a9 100644
--- a/src/lib/evas/canvas/evas_render.c
+++ b/src/lib/evas/canvas/evas_render.c
@@ -1843,6 +1843,14 @@ _drop_glyph_ref(const void *container EINA_UNUSED, void *data, void *fdata EINA_
1843 return EINA_TRUE; 1843 return EINA_TRUE;
1844} 1844}
1845 1845
1846static Eina_Bool
1847_drop_texts_ref(const void *container EINA_UNUSED, void *data, void *fdata EINA_UNUSED)
1848{
1849 evas_common_font_fonts_unref(data);
1850
1851 return EINA_TRUE;
1852}
1853
1846static void 1854static void
1847evas_render_wakeup(Evas *eo_e) 1855evas_render_wakeup(Evas *eo_e)
1848{ 1856{
@@ -1887,6 +1895,8 @@ evas_render_wakeup(Evas *eo_e)
1887 eina_array_clean(&e->image_unref_queue); 1895 eina_array_clean(&e->image_unref_queue);
1888 eina_array_foreach(&e->glyph_unref_queue, _drop_glyph_ref, NULL); 1896 eina_array_foreach(&e->glyph_unref_queue, _drop_glyph_ref, NULL);
1889 eina_array_clean(&e->glyph_unref_queue); 1897 eina_array_clean(&e->glyph_unref_queue);
1898 eina_array_foreach(&e->texts_unref_queue, _drop_texts_ref, NULL);
1899 eina_array_clean(&e->texts_unref_queue);
1890 1900
1891 up_cb = e->render.updates_cb; 1901 up_cb = e->render.updates_cb;
1892 up_data = e->render.data; 1902 up_data = e->render.data;
@@ -2172,4 +2182,10 @@ evas_unref_queue_glyph_put(Evas_Public_Data *pd, void *glyph)
2172 eina_array_push(&pd->glyph_unref_queue, glyph); 2182 eina_array_push(&pd->glyph_unref_queue, glyph);
2173} 2183}
2174 2184
2185void
2186evas_unref_queue_texts_put(Evas_Public_Data *pd, void *texts)
2187{
2188 eina_array_push(&pd->texts_unref_queue, texts);
2189}
2190
2175/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/ 2191/* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
diff --git a/src/lib/evas/common/evas_font_draw.c b/src/lib/evas/common/evas_font_draw.c
index cfb8aac6f9..99883926ae 100644
--- a/src/lib/evas/common/evas_font_draw.c
+++ b/src/lib/evas/common/evas_font_draw.c
@@ -239,6 +239,21 @@ evas_common_font_glyphs_unref(Evas_Glyph_Array *array)
239 free(array); 239 free(array);
240} 240}
241 241
242void
243evas_common_font_fonts_ref(Evas_Font_Array *array)
244{
245 array->refcount++;
246}
247
248void
249evas_common_font_fonts_unref(Evas_Font_Array *array)
250{
251 if (--array->refcount) return;
252
253 eina_inarray_free(array->array);
254 free(array);
255}
256
242EAPI void 257EAPI void
243evas_common_font_draw_prepare(Evas_Text_Props *text_props) 258evas_common_font_draw_prepare(Evas_Text_Props *text_props)
244{ 259{
diff --git a/src/lib/evas/common/evas_text_utils.h b/src/lib/evas/common/evas_text_utils.h
index f2f65a396b..144761ea28 100644
--- a/src/lib/evas/common/evas_text_utils.h
+++ b/src/lib/evas/common/evas_text_utils.h
@@ -1,12 +1,13 @@
1#ifndef _EVAS_TEXT_UTILS_H 1#ifndef _EVAS_TEXT_UTILS_H
2# define _EVAS_TEXT_UTILS_H 2# define _EVAS_TEXT_UTILS_H
3 3
4 4typedef struct _Evas_Text_Props Evas_Text_Props;
5typedef struct _Evas_Text_Props Evas_Text_Props;
6// special case props 5// special case props
7typedef struct _Evas_Text_Props_One Evas_Text_Props_One; 6typedef struct _Evas_Text_Props_One Evas_Text_Props_One;
8 7
9typedef struct _Evas_Text_Props_Info Evas_Text_Props_Info; 8typedef struct _Evas_Text_Props_Info Evas_Text_Props_Info;
9typedef struct _Evas_Font_Array_Data Evas_Font_Array_Data;
10typedef struct _Evas_Font_Array Evas_Font_Array;
10typedef struct _Evas_Font_Glyph_Info Evas_Font_Glyph_Info; 11typedef struct _Evas_Font_Glyph_Info Evas_Font_Glyph_Info;
11 12
12typedef enum 13typedef enum
@@ -100,6 +101,21 @@ struct _Evas_Text_Props_Info
100 unsigned int refcount; // 4 101 unsigned int refcount; // 4
101}; 102};
102 103
104struct _Evas_Font_Array_Data
105{
106 struct {
107 unsigned char r, g, b, a;
108 } color;
109 int x;
110 Evas_Glyph_Array *glyphs;
111};
112
113struct _Evas_Font_Array
114{
115 Eina_Inarray *array;
116 unsigned int refcount;
117};
118
103/* Sorted in visual order when created */ 119/* Sorted in visual order when created */
104struct _Evas_Font_Glyph_Info 120struct _Evas_Font_Glyph_Info
105{ 121{
@@ -125,6 +141,11 @@ void
125evas_common_font_glyphs_unref(Evas_Glyph_Array *array); 141evas_common_font_glyphs_unref(Evas_Glyph_Array *array);
126 142
127void 143void
144evas_common_font_fonts_ref(Evas_Font_Array *array);
145void
146evas_common_font_fonts_unref(Evas_Font_Array *array);
147
148void
128evas_common_text_props_bidi_set(Evas_Text_Props *props, 149evas_common_text_props_bidi_set(Evas_Text_Props *props,
129 Evas_BiDi_Paragraph_Props *bidi_par_props, size_t start); 150 Evas_BiDi_Paragraph_Props *bidi_par_props, size_t start);
130 151
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 4a7ec28e74..c5527db740 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -388,6 +388,7 @@ struct _Evas_Public_Data
388 Eina_Array clip_changes; 388 Eina_Array clip_changes;
389 Eina_Array image_unref_queue; 389 Eina_Array image_unref_queue;
390 Eina_Array glyph_unref_queue; 390 Eina_Array glyph_unref_queue;
391 Eina_Array texts_unref_queue;
391 392
392 Eina_Clist calc_list; 393 Eina_Clist calc_list;
393 Eina_Clist calc_done; 394 Eina_Clist calc_done;
@@ -900,6 +901,9 @@ struct _Evas_Func
900 901
901 /* max size query */ 902 /* max size query */
902 void (*image_max_size_get) (void *data, int *maxw, int *maxh); 903 void (*image_max_size_get) (void *data, int *maxw, int *maxh);
904
905 /* multiple font draws */
906 Eina_Bool (*multi_font_draw) (void *data, void *context, void *surface, Evas_Font_Set *font, int x, int y, int w, int h, int ow, int oh, Evas_Font_Array *texts, Eina_Bool do_async);
903}; 907};
904 908
905struct _Evas_Image_Load_Func 909struct _Evas_Image_Load_Func
@@ -1051,6 +1055,7 @@ void _evas_object_textblock_rehint(Evas_Object *obj);
1051 1055
1052void evas_unref_queue_image_put(Evas_Public_Data *pd, void *image); 1056void evas_unref_queue_image_put(Evas_Public_Data *pd, void *image);
1053void evas_unref_queue_glyph_put(Evas_Public_Data *pd, void *glyph); 1057void evas_unref_queue_glyph_put(Evas_Public_Data *pd, void *glyph);
1058void evas_unref_queue_texts_put(Evas_Public_Data *pd, void *glyph);
1054 1059
1055void evas_draw_image_map_async_check(Evas_Object_Protected_Data *obj, 1060void evas_draw_image_map_async_check(Evas_Object_Protected_Data *obj,
1056 void *data, void *context, void *surface, 1061 void *data, void *context, void *surface,
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c
index 9dad67c96d..7c00d541f9 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -282,6 +282,7 @@ typedef struct _Evas_Thread_Command_Polygon Evas_Thread_Command_Polygon;
282typedef struct _Evas_Thread_Command_Image Evas_Thread_Command_Image; 282typedef struct _Evas_Thread_Command_Image Evas_Thread_Command_Image;
283typedef struct _Evas_Thread_Command_Font Evas_Thread_Command_Font; 283typedef struct _Evas_Thread_Command_Font Evas_Thread_Command_Font;
284typedef struct _Evas_Thread_Command_Map Evas_Thread_Command_Map; 284typedef struct _Evas_Thread_Command_Map Evas_Thread_Command_Map;
285typedef struct _Evas_Thread_Command_Multi_Font Evas_Thread_Command_Multi_Font;
285 286
286struct _Evas_Thread_Command_Rect 287struct _Evas_Thread_Command_Rect
287{ 288{
@@ -351,12 +352,21 @@ struct _Evas_Thread_Command_Map
351 int smooth, level, offset; 352 int smooth, level, offset;
352}; 353};
353 354
355struct _Evas_Thread_Command_Multi_Font
356{
357 RGBA_Draw_Context context;
358 void *surface;
359 int x, y;
360 Evas_Font_Array *texts;
361};
362
354Eina_Mempool *_mp_command_rect = NULL; 363Eina_Mempool *_mp_command_rect = NULL;
355Eina_Mempool *_mp_command_line = NULL; 364Eina_Mempool *_mp_command_line = NULL;
356Eina_Mempool *_mp_command_polygon = NULL; 365Eina_Mempool *_mp_command_polygon = NULL;
357Eina_Mempool *_mp_command_image = NULL; 366Eina_Mempool *_mp_command_image = NULL;
358Eina_Mempool *_mp_command_font = NULL; 367Eina_Mempool *_mp_command_font = NULL;
359Eina_Mempool *_mp_command_map = NULL; 368Eina_Mempool *_mp_command_map = NULL;
369Eina_Mempool *_mp_command_multi_font = NULL;
360 370
361/* 371/*
362 ***** 372 *****
@@ -1754,6 +1764,66 @@ eng_image_animated_frame_set(void *data EINA_UNUSED, void *image, int frame_inde
1754} 1764}
1755 1765
1756static void 1766static void
1767_draw_thread_multi_font_draw(void *data)
1768{
1769 Evas_Thread_Command_Multi_Font *mf = data;
1770 Evas_Font_Array_Data *itr;
1771
1772 EINA_INARRAY_FOREACH(mf->texts->array, itr)
1773 {
1774 unsigned int r, g, b, a;
1775 int x = mf->x + itr->x, y = mf->y;
1776
1777 r = itr->color.r;
1778 g = itr->color.g;
1779 b = itr->color.b;
1780 a = itr->color.a;
1781
1782 eng_context_color_set(NULL, &mf->context, r, g, b, a);
1783 evas_common_font_draw(mf->surface, &mf->context, x, y, itr->glyphs);
1784 evas_common_cpu_end_opt();
1785 }
1786
1787 eina_mempool_free(_mp_command_multi_font, mf);
1788}
1789
1790static Eina_Bool
1791_multi_font_draw_thread_cmd(RGBA_Image *dst, RGBA_Draw_Context *dc, int x, int y, Evas_Font_Array *texts)
1792{
1793 Evas_Thread_Command_Multi_Font *mf;
1794
1795 mf = eina_mempool_malloc(_mp_command_multi_font,
1796 sizeof(Evas_Thread_Command_Multi_Font));
1797 if (!mf)
1798 {
1799 ERR("Failed to allocate memory on mempool for multiple text_props "
1800 "commands.");
1801 return EINA_FALSE;
1802 }
1803
1804 memcpy(&mf->context, dc, sizeof(*dc));
1805 mf->surface = dst;
1806 mf->x = x;
1807 mf->y = y;
1808 mf->texts = texts;
1809
1810 evas_thread_cmd_enqueue(_draw_thread_multi_font_draw, mf);
1811
1812 return EINA_TRUE;
1813}
1814
1815static Eina_Bool
1816eng_multi_font_draw(void *data EINA_UNUSED, void *context, void *surface, Evas_Font_Set *font EINA_UNUSED, int x, int y, int w EINA_UNUSED, int h EINA_UNUSED, int ow EINA_UNUSED, int oh EINA_UNUSED, Evas_Font_Array *texts, Eina_Bool do_async)
1817{
1818 if (!texts) return EINA_FALSE;
1819
1820 if (do_async)
1821 return _multi_font_draw_thread_cmd(surface, context, x, y, texts);
1822
1823 return EINA_FALSE;
1824}
1825
1826static void
1757eng_image_cache_flush(void *data EINA_UNUSED) 1827eng_image_cache_flush(void *data EINA_UNUSED)
1758{ 1828{
1759 int tmp_size; 1829 int tmp_size;
@@ -2485,7 +2555,8 @@ static Evas_Func func =
2485 eng_image_animated_loop_count_get, 2555 eng_image_animated_loop_count_get,
2486 eng_image_animated_frame_duration_get, 2556 eng_image_animated_frame_duration_get,
2487 eng_image_animated_frame_set, 2557 eng_image_animated_frame_set,
2488 NULL 2558 NULL,
2559 eng_multi_font_draw,
2489 /* FUTURE software generic calls go here */ 2560 /* FUTURE software generic calls go here */
2490}; 2561};
2491 2562
@@ -3503,6 +3574,9 @@ module_open(Evas_Module *em)
3503 _mp_command_map = eina_mempool_add("chained_mempool", 3574 _mp_command_map = eina_mempool_add("chained_mempool",
3504 "Evas_Thread_Command_Map", NULL, 3575 "Evas_Thread_Command_Map", NULL,
3505 sizeof (Evas_Thread_Command_Map), 64); 3576 sizeof (Evas_Thread_Command_Map), 64);
3577 _mp_command_multi_font =
3578 eina_mempool_add("chained_mempool", "Evas_Thread_Command_Multi_Font",
3579 NULL, sizeof(Evas_Thread_Command_Multi_Font), 128);
3506 3580
3507 init_gl(); 3581 init_gl();
3508 evas_common_pipe_init(); 3582 evas_common_pipe_init();