summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bin/edje/edje_cc_handlers.c194
-rw-r--r--src/lib/edje/edje_private.h2
-rw-r--r--src/lib/edje/edje_text.c65
-rw-r--r--src/lib/evas/canvas/evas_object_text.c38
-rw-r--r--src/lib/evas/filters/evas_filter_parser.c2
5 files changed, 197 insertions, 104 deletions
diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c
index 2268190134..53bf91e758 100644
--- a/src/bin/edje/edje_cc_handlers.c
+++ b/src/bin/edje/edje_cc_handlers.c
@@ -362,6 +362,7 @@ static void st_collections_group_parts_part_description_text_source(void);
362static void st_collections_group_parts_part_description_text_text_source(void); 362static void st_collections_group_parts_part_description_text_text_source(void);
363static void st_collections_group_parts_part_description_text_ellipsis(void); 363static void st_collections_group_parts_part_description_text_ellipsis(void);
364static void st_collections_group_parts_part_description_text_filter(void); 364static void st_collections_group_parts_part_description_text_filter(void);
365static void st_collections_group_parts_part_description_text_filter_source(void);
365static void st_collections_group_parts_part_description_box_layout(void); 366static void st_collections_group_parts_part_description_box_layout(void);
366static void st_collections_group_parts_part_description_box_align(void); 367static void st_collections_group_parts_part_description_box_align(void);
367static void st_collections_group_parts_part_description_box_padding(void); 368static void st_collections_group_parts_part_description_box_padding(void);
@@ -814,6 +815,8 @@ New_Statement_Handler statement_handlers[] =
814 {"collections.group.parts.part.description.text.elipsis", st_collections_group_parts_part_description_text_ellipsis}, 815 {"collections.group.parts.part.description.text.elipsis", st_collections_group_parts_part_description_text_ellipsis},
815 {"collections.group.parts.part.description.text.ellipsis", st_collections_group_parts_part_description_text_ellipsis}, 816 {"collections.group.parts.part.description.text.ellipsis", st_collections_group_parts_part_description_text_ellipsis},
816 {"collections.group.parts.part.description.text.filter", st_collections_group_parts_part_description_text_filter}, 817 {"collections.group.parts.part.description.text.filter", st_collections_group_parts_part_description_text_filter},
818 {"collections.group.parts.part.description.text.filter.code", st_collections_group_parts_part_description_text_filter}, /* dup */
819 {"collections.group.parts.part.description.text.filter.source", st_collections_group_parts_part_description_text_filter_source},
817 {"collections.group.parts.part.description.box.layout", st_collections_group_parts_part_description_box_layout}, 820 {"collections.group.parts.part.description.box.layout", st_collections_group_parts_part_description_box_layout},
818 {"collections.group.parts.part.description.box.align", st_collections_group_parts_part_description_box_align}, 821 {"collections.group.parts.part.description.box.align", st_collections_group_parts_part_description_box_align},
819 {"collections.group.parts.part.description.box.padding", st_collections_group_parts_part_description_box_padding}, 822 {"collections.group.parts.part.description.box.padding", st_collections_group_parts_part_description_box_padding},
@@ -6696,15 +6699,18 @@ st_collections_group_parts_part_description_inherit(void)
6696 ted->text.domain = STRDUP(ted->text.domain); 6699 ted->text.domain = STRDUP(ted->text.domain);
6697 ted->text.text_class = STRDUP(ted->text.text_class); 6700 ted->text.text_class = STRDUP(ted->text.text_class);
6698 ted->text.font.str = STRDUP(ted->text.font.str); 6701 ted->text.font.str = STRDUP(ted->text.font.str);
6699 ted->text.filter.code = STRDUP(ted->text.filter.code);
6700 {
6701 Eina_List *l;
6702 Eina_Stringshare *name;
6703 static int part_key = 0;
6704 6702
6705 EINA_LIST_FOREACH(ted->text.filter.sources, l, name) 6703 /* Filters stuff */
6706 data_queue_part_lookup(pc, name, &part_key); 6704 ted->text.filter.code = STRDUP(ted->text.filter.code);
6707 } 6705 if (ted->text.filter.code)
6706 {
6707 Eina_List *list, *l;
6708 const char *name;
6709 list = ted->text.filter.sources;
6710 ted->text.filter.sources = NULL;
6711 EINA_LIST_FOREACH(list, l, name)
6712 ted->text.filter.sources = eina_list_append(ted->text.filter.sources, STRDUP(name));
6713 }
6708 6714
6709 data_queue_copied_part_nest_lookup(pc, &(tparent->text.id_source), &(ted->text.id_source), &ted->text.id_source_part); 6715 data_queue_copied_part_nest_lookup(pc, &(tparent->text.id_source), &(ted->text.id_source), &ted->text.id_source_part);
6710 data_queue_copied_part_nest_lookup(pc, &(tparent->text.id_text_source), &(ted->text.id_text_source), &ted->text.id_text_source_part); 6716 data_queue_copied_part_nest_lookup(pc, &(tparent->text.id_text_source), &(ted->text.id_text_source), &ted->text.id_text_source_part);
@@ -8979,31 +8985,88 @@ st_collections_group_parts_part_description_text_ellipsis(void)
8979/** 8985/**
8980 @page edcref 8986 @page edcref
8981 8987
8988 @context
8989 part {
8990 type: TEXT; // or IMAGE
8991 description {
8992 ..
8993 text {
8994 ..
8995 filter {
8996 code: "blend {} -- ..."
8997 source: "part1" "buf";
8998 source: "part2" "otherbuf";
8999 source: "part3";
9000 }
9001 // or as short form:
9002 filter: "blend {} -- ..."
9003 }
9004 ..
9005 }
9006 }
8982 @property 9007 @property
8983 filter 9008 filter.code
8984 @parameters 9009 @parameters
8985 [filter program as a string] 9010 [filter program as a string]
8986 @effect 9011 @effect
8987 Applies a series of filtering operations to the text. 9012 Applies a series of image filters to a TEXT or IMAGE part. The argument
8988 EXPERIMENTAL FEATURE. TO BE DOCUMENTED. 9013 to this field is the source code of a Lua program invoking various
9014 filter operations. For more information, please refer to the page
9015 "Evas filters reference".
9016 @see evasfiltersref
8989 @endproperty 9017 @endproperty
8990*/ 9018*/
8991static void 9019static void
8992st_collections_group_parts_part_description_text_filter(void) 9020st_collections_group_parts_part_description_text_filter(void)
8993{ 9021{
8994 Edje_Part_Description_Text *ed; 9022 Edje_Part_Description_Text *ed;
8995 Eina_List *sources = NULL;
8996 Eina_Stringshare *name;
8997 char *token, *code;
8998 Eina_Bool valid = EINA_TRUE;
8999 Edje_Part_Collection *pc;
9000 9023
9001 static int part_key = 0; 9024 check_arg_count(1);
9025
9026 if (current_part->type != EDJE_PART_TYPE_TEXT)
9027 {
9028 ERR("parse error %s:%i. text attributes in non-TEXT part.",
9029 file_in, line - 1);
9030 exit(-1);
9031 }
9032
9033 ed = (Edje_Part_Description_Text*) current_desc;
9034
9035 free((void*) ed->text.filter.code);
9036 ed->text.filter.code = parse_str(0);
9037}
9038
9039/**
9040 @page edcref
9041
9042 @property
9043 filter.source
9044 @parameters
9045 [another part's name] [(optional) buffer name for filter program]
9046 @effect
9047 Binds another part as an image source (like a proxy source) for a
9048 text or image filter operation. Optionally, a buffer name may be
9049 specified, so the same filter code can be used with different sources.
9050 For more information, please refer to the page "Evas filters reference".
9051 @see evasfiltersref
9052 @endproperty
9053*/
9054static void
9055st_collections_group_parts_part_description_text_filter_source(void)
9056{
9057 Edje_Part_Description_Text *ed;
9058 Edje_Part_Collection *pc;
9059 char *name = NULL, *part, *str;
9060 size_t sn = 0, sp;
9061 int *part_key;
9002 9062
9003 static const char *allowed_name_chars = 9063 static const char *allowed_name_chars =
9004 "abcdefghijklmnopqrstuvwxyzABCDEFGHJIKLMNOPQRSTUVWXYZ0123456789_"; 9064 "abcdefghijklmnopqrstuvwxyzABCDEFGHJIKLMNOPQRSTUVWXYZ0123456789_";
9005 9065
9006 check_arg_count(1); 9066 /* 1 or 2 args only */
9067 check_min_arg_count(1);
9068 if (get_arg_count() > 1)
9069 check_arg_count(2);
9007 9070
9008 if (current_part->type != EDJE_PART_TYPE_TEXT) 9071 if (current_part->type != EDJE_PART_TYPE_TEXT)
9009 { 9072 {
@@ -9014,72 +9077,55 @@ st_collections_group_parts_part_description_text_filter(void)
9014 9077
9015 ed = (Edje_Part_Description_Text*) current_desc; 9078 ed = (Edje_Part_Description_Text*) current_desc;
9016 pc = eina_list_data_get(eina_list_last(edje_collections)); 9079 pc = eina_list_data_get(eina_list_last(edje_collections));
9017 if (ed->text.filter.code) 9080
9081 part = parse_str(0);
9082 sp = strlen(part);
9083
9084 if (get_arg_count() > 1)
9018 { 9085 {
9019 EINA_LIST_FREE(ed->text.filter.sources, name) 9086 name = parse_str(1);
9087 if (name) sn = strlen(name);
9088 if (!name || (strspn(name, allowed_name_chars) != sn))
9020 { 9089 {
9021 part_lookup_delete(pc, name, &part_key, NULL); 9090 ERR("parse error %s:%i. invalid name for a filter buffer: %s",
9022 eina_stringshare_del(name); 9091 file_in, line - 1, name);
9092 exit(-1);
9023 } 9093 }
9024 free((void*)ed->text.filter.code);
9025 } 9094 }
9026 ed->text.filter.sources = NULL;
9027
9028 ed->text.filter.code = parse_str(0);
9029 if (!ed->text.filter.code) return;
9030 9095
9031 // Parse list of buffers that have a source 9096 if (!name && (strspn(part, allowed_name_chars) == sp))
9032 // note: does not support comments 9097 str = strdup(part);
9033 code = strdup(ed->text.filter.code); 9098 else
9034 for (token = strtok(code, ";"); token; token = strtok(NULL, ";"))
9035 { 9099 {
9036 size_t len; 9100 if (!name)
9037
9038 len = strspn(token, " \n\t");
9039 token += len;
9040
9041 if (!strncasecmp("buffer", token, 6))
9042 { 9101 {
9043 // note: a valid string won't necessary compile at runtime 9102 // name = part so we replace all invalid chars by '_'
9044 9103 size_t k;
9045 token = strchr(token, ':'); 9104 name = strdup(part);
9046 if (!token) 9105 sn = strlen(name);
9047 { 9106 for (k = 0; k < sn; k++)
9048 valid = EINA_FALSE;
9049 break;
9050 }
9051 token = strchr(token, '(');
9052 if (!token)
9053 {
9054 valid = EINA_FALSE;
9055 break;
9056 }
9057 token = strcasestr(token, "src");
9058 if (!token) continue;
9059 token += 3;
9060 len = strspn(token, " =\n\t");
9061 if (!len || !token[len])
9062 { 9107 {
9063 valid = EINA_FALSE; 9108 if (!index(allowed_name_chars, name[k]))
9064 break; 9109 name[k] = '_';
9065 }
9066 token += len;
9067 len = strspn(token, allowed_name_chars);
9068 if (!len || !token[len])
9069 {
9070 valid = EINA_FALSE;
9071 break;
9072 } 9110 }
9073 token[len] = '\0';
9074 name = eina_stringshare_add(token);
9075
9076 sources = eina_list_append(sources, name);
9077 data_queue_part_lookup(pc, name, &part_key);
9078 } 9111 }
9079 } 9112 sn += sp + 1;
9080 free(code); 9113 str = malloc(sn + 1);
9081 9114 if (!str) exit(-1);
9082 if (valid) ed->text.filter.sources = sources; 9115 strncpy(str, name, sn);
9116 strncat(str, ":", sn);
9117 strncat(str, part, sn);
9118 str[sn] = '\0';
9119 }
9120 ed->text.filter.sources = eina_list_append(ed->text.filter.sources, str);
9121
9122 // note: this is leaked. not a big deal.
9123 part_key = malloc(sizeof(int));
9124 *part_key = -1;
9125 data_queue_part_lookup(pc, part, part_key);
9126
9127 free(part);
9128 free(name);
9083} 9129}
9084 9130
9085 9131
diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h
index 419350cf65..8aec84a227 100644
--- a/src/lib/edje/edje_private.h
+++ b/src/lib/edje/edje_private.h
@@ -1281,7 +1281,7 @@ struct _Edje_Part_Description_Spec_Border
1281struct _Edje_Part_Description_Spec_Filter 1281struct _Edje_Part_Description_Spec_Filter
1282{ 1282{
1283 const char *code; 1283 const char *code;
1284 Eina_List *sources; 1284 Eina_List *sources; /* "part" or "buffer:part" */
1285}; 1285};
1286 1286
1287struct _Edje_Part_Description_Spec_Image 1287struct _Edje_Part_Description_Spec_Image
diff --git a/src/lib/edje/edje_text.c b/src/lib/edje/edje_text.c
index cf6c187690..8ee579e34a 100644
--- a/src/lib/edje/edje_text.c
+++ b/src/lib/edje/edje_text.c
@@ -204,8 +204,8 @@ _edje_text_recalc_apply(Edje *ed, Edje_Real_Part *ep,
204 char *font2 = NULL; 204 char *font2 = NULL;
205 char *sfont = NULL; 205 char *sfont = NULL;
206 int size; 206 int size;
207 const char *filter, *source_name; 207 const char *filter;
208 Eina_List *filter_sources = NULL, *prev_sources = NULL, *li; 208 Eina_List *filter_sources = NULL, *prev_sources = NULL;
209 Evas_Coord tw, th; 209 Evas_Coord tw, th;
210 Evas_Coord sw, sh; 210 Evas_Coord sw, sh;
211 int inlined_font = 0, free_text = 0; 211 int inlined_font = 0, free_text = 0;
@@ -531,15 +531,60 @@ arrange_text:
531 /* filters */ 531 /* filters */
532 if (filter) 532 if (filter)
533 { 533 {
534 eo_do(ep->object, 534 const char *src1, *src2, *part;
535 EINA_LIST_FOREACH(prev_sources, li, source_name) 535 Eina_List *li1, *li2;
536 evas_obj_text_filter_source_set(source_name, NULL);
537 536
538 EINA_LIST_FOREACH(filter_sources, li, source_name) 537 eo_do(ep->object,
538 evas_obj_text_filter_program_set(filter);
539 /* update sources. really not optimal. lots of strxxx and loops */
540 if (prev_sources != filter_sources)
539 { 541 {
540 Edje_Real_Part *rp = _edje_real_part_get(ed, source_name); 542 /* remove sources that are not there anymore
541 evas_obj_text_filter_source_set(source_name, rp ? rp->object : NULL); 543 * this O(n^2) loop assumes a very small number of sources */
542 }; 544 EINA_LIST_FOREACH(prev_sources, li1, src1)
545 {
546 Eina_Bool found = 0;
547 EINA_LIST_FOREACH(filter_sources, li2, src2)
548 {
549 if (!strcmp(src1, src2))
550 {
551 found = 1;
552 break;
553 }
554 }
555 if (!found)
556 {
557 part = strchr(src1, ':');
558 if (!part)
559 evas_obj_text_filter_source_set(src1, NULL);
560 else
561 {
562 char *name = strdup(src1);
563 name[part - src1] = 0;
564 evas_obj_text_filter_source_set(name, NULL);
565 free(name);
566 }
567 }
568 }
569 /* add all sources by part name */
570 EINA_LIST_FOREACH(filter_sources, li1, src1)
571 {
572 Edje_Real_Part *rp;
573 char *name = NULL;
574 if ((part = strchr(src1, ':')) != NULL)
575 {
576 name = strdup(src1);
577 name[part - src1] = 0;
578 part++;
579 }
580 else
581 part = src1;
582 rp = _edje_real_part_get(ed, part);
583 evas_obj_text_filter_source_set(name ? name : part, rp ? rp->object : NULL);
584 free(name);
585 }
586 }
587 /* pass edje state for transitions */
543 if (ep->param2) 588 if (ep->param2)
544 { 589 {
545 evas_obj_text_filter_state_set(chosen_desc->common.state.name, chosen_desc->common.state.value, 590 evas_obj_text_filter_state_set(chosen_desc->common.state.name, chosen_desc->common.state.value,
@@ -551,7 +596,7 @@ arrange_text:
551 evas_obj_text_filter_state_set(chosen_desc->common.state.name, chosen_desc->common.state.value, 596 evas_obj_text_filter_state_set(chosen_desc->common.state.name, chosen_desc->common.state.value,
552 NULL, 0.0, state_val); 597 NULL, 0.0, state_val);
553 } 598 }
554 evas_obj_text_filter_program_set(filter)); 599 );
555 } 600 }
556 else 601 else
557 eo_do(ep->object, evas_obj_text_filter_program_set(NULL)); 602 eo_do(ep->object, evas_obj_text_filter_program_set(NULL));
diff --git a/src/lib/evas/canvas/evas_object_text.c b/src/lib/evas/canvas/evas_object_text.c
index f517a97562..80a7e75f46 100644
--- a/src/lib/evas/canvas/evas_object_text.c
+++ b/src/lib/evas/canvas/evas_object_text.c
@@ -2495,6 +2495,12 @@ _evas_text_filter_source_set(Eo *eo_obj, Evas_Text_Data *o, const char *name, Ev
2495 if (!source && !o->cur.filter->sources) 2495 if (!source && !o->cur.filter->sources)
2496 return; 2496 return;
2497 2497
2498 if (o->cur.filter->sources)
2499 {
2500 pb_old = eina_hash_find(o->cur.filter->sources, name);
2501 if (pb_old && (pb_old->eo_source == eo_source)) return;
2502 }
2503
2498 fcow = eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&o->cur.filter); 2504 fcow = eina_cow_write(evas_object_filter_cow, (const Eina_Cow_Data**)&o->cur.filter);
2499 2505
2500 if (!fcow->sources) 2506 if (!fcow->sources)
@@ -2502,15 +2508,8 @@ _evas_text_filter_source_set(Eo *eo_obj, Evas_Text_Data *o, const char *name, Ev
2502 fcow->sources = eina_hash_string_small_new 2508 fcow->sources = eina_hash_string_small_new
2503 (EINA_FREE_CB(_filter_source_hash_free_cb)); 2509 (EINA_FREE_CB(_filter_source_hash_free_cb));
2504 } 2510 }
2505 else 2511 else if (pb_old)
2506 { 2512 eina_hash_del(fcow->sources, name, pb_old);
2507 pb_old = eina_hash_find(fcow->sources, name);
2508 if (pb_old)
2509 {
2510 if (pb_old->eo_source == eo_source) goto update;
2511 eina_hash_del(fcow->sources, name, pb_old);
2512 }
2513 }
2514 2513
2515 if (!source) 2514 if (!source)
2516 { 2515 {
@@ -2530,16 +2529,19 @@ _evas_text_filter_source_set(Eo *eo_obj, Evas_Text_Data *o, const char *name, Ev
2530 pb->eo_source = eo_source; 2529 pb->eo_source = eo_source;
2531 pb->name = eina_stringshare_add(name); 2530 pb->name = eina_stringshare_add(name);
2532 2531
2533 EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy, 2532 if (!eina_list_data_find(source->proxy->proxies, eo_obj))
2534 Evas_Object_Proxy_Data, source_write) 2533 {
2535 if (!eina_list_data_find(source_write->proxies, eo_obj)) 2534 EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, source->proxy, Evas_Object_Proxy_Data, source_write)
2536 source_write->proxies = eina_list_append(source_write->proxies, eo_obj); 2535 source_write->proxies = eina_list_append(source_write->proxies, eo_obj);
2537 EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, source_write) 2536 EINA_COW_WRITE_END(evas_object_proxy_cow, source->proxy, source_write)
2537 }
2538 2538
2539 EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, obj->proxy, 2539 if (!obj->proxy->is_proxy)
2540 Evas_Object_Proxy_Data, proxy_write) 2540 {
2541 proxy_write->is_proxy = EINA_TRUE; 2541 EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, obj->proxy, Evas_Object_Proxy_Data, proxy_write)
2542 EINA_COW_WRITE_END(evas_object_proxy_cow, obj->proxy, proxy_write) 2542 proxy_write->is_proxy = EINA_TRUE;
2543 EINA_COW_WRITE_END(evas_object_proxy_cow, obj->proxy, proxy_write)
2544 }
2543 2545
2544 eina_hash_add(fcow->sources, pb->name, pb); 2546 eina_hash_add(fcow->sources, pb->name, pb);
2545 evas_filter_program_source_set_all(fcow->chain, fcow->sources); 2547 evas_filter_program_source_set_all(fcow->chain, fcow->sources);
diff --git a/src/lib/evas/filters/evas_filter_parser.c b/src/lib/evas/filters/evas_filter_parser.c
index 7bf812be75..f25f82ac00 100644
--- a/src/lib/evas/filters/evas_filter_parser.c
+++ b/src/lib/evas/filters/evas_filter_parser.c
@@ -856,7 +856,7 @@ _lua_buffer_new(lua_State *L)
856 instr->type = EVAS_FILTER_MODE_BUFFER; 856 instr->type = EVAS_FILTER_MODE_BUFFER;
857 instr->parse_run = _buffer_instruction_parse_run; 857 instr->parse_run = _buffer_instruction_parse_run;
858 _instruction_param_seq_add(instr, "type", VT_STRING, "rgba"); 858 _instruction_param_seq_add(instr, "type", VT_STRING, "rgba");
859 _instruction_param_seq_add(instr, "src", VT_BUFFER, NULL); 859 _instruction_param_seq_add(instr, "src", VT_STRING, NULL);
860 860
861 // drop "buffer" metatable 861 // drop "buffer" metatable
862 _lua_implicit_metatable_drop(L, _lua_buffer_meta); 862 _lua_implicit_metatable_drop(L, _lua_buffer_meta);