summaryrefslogtreecommitdiff
path: root/legacy/evas
diff options
context:
space:
mode:
authorTom Hacohen <tom@stosb.com>2011-07-26 11:47:19 +0000
committerTom Hacohen <tom@stosb.com>2011-07-26 11:47:19 +0000
commit681e4bfa8cb9f1fc4d3070224327161bc2937e61 (patch)
treefaeb6d59bfcf2e88108c36c890bf315b6ea997f9 /legacy/evas
parentab5e8633dfaf9c2a8bf88724a41f92b80365bbf8 (diff)
Evas textblock: Fixed _format_append to parse tags + incomplete stuff.
Added the first step to allow <b> </b> exact matching when handling formats. I.e making "<b>a<i>b</b>c</i>d" behave like expected. SVN revision: 61746
Diffstat (limited to 'legacy/evas')
-rw-r--r--legacy/evas/src/lib/canvas/evas_object_textblock.c176
1 files changed, 135 insertions, 41 deletions
diff --git a/legacy/evas/src/lib/canvas/evas_object_textblock.c b/legacy/evas/src/lib/canvas/evas_object_textblock.c
index e1f0c5ea28..74bda33507 100644
--- a/legacy/evas/src/lib/canvas/evas_object_textblock.c
+++ b/legacy/evas/src/lib/canvas/evas_object_textblock.c
@@ -215,6 +215,7 @@ struct _Evas_Object_Textblock_Node_Format
215{ 215{
216 EINA_INLIST; 216 EINA_INLIST;
217 const char *format; 217 const char *format;
218 const char *orig_format;
218 Evas_Object_Textblock_Node_Text *text_node; 219 Evas_Object_Textblock_Node_Text *text_node;
219 size_t offset; 220 size_t offset;
220 unsigned char anchor : 2; 221 unsigned char anchor : 2;
@@ -333,6 +334,7 @@ struct _Evas_Object_Textblock_Format_Item
333 334
334struct _Evas_Object_Textblock_Format 335struct _Evas_Object_Textblock_Format
335{ 336{
337 Evas_Object_Textblock_Node_Format *fnode;
336 double halign; 338 double halign;
337 double valign; 339 double valign;
338 struct { 340 struct {
@@ -1748,6 +1750,7 @@ struct _Ctxt
1748 1750
1749static void _layout_text_add_logical_item(Ctxt *c, Evas_Object_Textblock_Text_Item *ti, Eina_List *rel); 1751static void _layout_text_add_logical_item(Ctxt *c, Evas_Object_Textblock_Text_Item *ti, Eina_List *rel);
1750static void _text_item_update_sizes(Ctxt *c, Evas_Object_Textblock_Text_Item *ti); 1752static void _text_item_update_sizes(Ctxt *c, Evas_Object_Textblock_Text_Item *ti);
1753static void _layout_do_format(const Evas_Object *obj, Ctxt *c, Evas_Object_Textblock_Format **_fmt, Evas_Object_Textblock_Node_Format *n, int *style_pad_l, int *style_pad_r, int *style_pad_t, int *style_pad_b, Eina_Bool create_item);
1751/** 1754/**
1752 * @internal 1755 * @internal
1753 * Adjust the ascent/descent of the format and context. 1756 * Adjust the ascent/descent of the format and context.
@@ -2067,12 +2070,14 @@ _paragraphs_free(const Evas_Object *obj, Evas_Object_Textblock_Paragraph *pars)
2067 * @see _layout_format_pop() 2070 * @see _layout_format_pop()
2068 */ 2071 */
2069static Evas_Object_Textblock_Format * 2072static Evas_Object_Textblock_Format *
2070_layout_format_push(Ctxt *c, Evas_Object_Textblock_Format *fmt) 2073_layout_format_push(Ctxt *c, Evas_Object_Textblock_Format *fmt,
2074 Evas_Object_Textblock_Node_Format *fnode)
2071{ 2075{
2072 if (fmt) 2076 if (fmt)
2073 { 2077 {
2074 fmt = _format_dup(c->obj, fmt); 2078 fmt = _format_dup(c->obj, fmt);
2075 c->format_stack = eina_list_prepend(c->format_stack, fmt); 2079 c->format_stack = eina_list_prepend(c->format_stack, fmt);
2080 fmt->fnode = fnode;
2076 } 2081 }
2077 else 2082 else
2078 { 2083 {
@@ -2099,18 +2104,81 @@ _layout_format_push(Ctxt *c, Evas_Object_Textblock_Format *fmt)
2099 * and set it to point to the next item instead, else return fmt. 2104 * and set it to point to the next item instead, else return fmt.
2100 * 2105 *
2101 * @param c the context to work on - Not NULL. 2106 * @param c the context to work on - Not NULL.
2102 * @param fmt the format to free. 2107 * @param format - the text of the format to free (assured to start with '-').
2103 * @return the next format in the stack, or format if there's none. 2108 * @return the next format in the stack, or format if there's none.
2104 * @see _layout_format_push() 2109 * @see _layout_format_push()
2105 */ 2110 */
2106static Evas_Object_Textblock_Format * 2111static Evas_Object_Textblock_Format *
2107_layout_format_pop(Ctxt *c, Evas_Object_Textblock_Format *fmt) 2112_layout_format_pop(Ctxt *c, const char *format)
2108{ 2113{
2114 Evas_Object_Textblock_Format *fmt = eina_list_data_get(c->format_stack);
2115
2109 if ((c->format_stack) && (c->format_stack->next)) 2116 if ((c->format_stack) && (c->format_stack->next))
2110 { 2117 {
2111 _format_unref_free(c->obj, fmt); 2118 Eina_List *redo_nodes = NULL;
2112 c->format_stack = eina_list_remove_list(c->format_stack, c->format_stack); 2119 format++; /* Skip the '-' */
2113 fmt = c->format_stack->data; 2120
2121 /* Generic pop, should just pop. */
2122 if (((format[1] == ' ') && !format[2]) ||
2123 !format[1])
2124 {
2125 _format_unref_free(c->obj, fmt);
2126 c->format_stack =
2127 eina_list_remove_list(c->format_stack, c->format_stack);
2128 }
2129 else
2130 {
2131 size_t len = strlen(format);
2132 Eina_List *i, *i_next;
2133 /* Remove only the matching format. */
2134 EINA_LIST_FOREACH_SAFE(c->format_stack, i, i_next, fmt)
2135 {
2136 /* Stop when we reach the base item */
2137 if (!i_next)
2138 break;
2139
2140 c->format_stack =
2141 eina_list_remove_list(c->format_stack, c->format_stack);
2142
2143 /* Make sure the ending tag matches the starting tag.
2144 * I.e whole of the ending tag matches the start of the
2145 * starting tag, and the starting tag's next char is either
2146 * NULL or white. Skip the starting '+'. */
2147 if (!strncmp(fmt->fnode->orig_format + 1, format, len) &&
2148 (!fmt->fnode->orig_format[len + 1] ||
2149 (fmt->fnode->orig_format[len + 1] == '=') ||
2150 _is_white(fmt->fnode->orig_format[len + 1])))
2151 {
2152 _format_unref_free(c->obj, fmt);
2153 break;
2154 }
2155 else
2156 {
2157 redo_nodes = eina_list_prepend(redo_nodes, fmt->fnode);
2158 _format_unref_free(c->obj, fmt);
2159 }
2160 }
2161 }
2162
2163 /* Redo all the nodes needed to be redone */
2164 {
2165 Evas_Object_Textblock_Node_Format *fnode;
2166 Eina_List *i, *i_next;
2167
2168 EINA_LIST_FOREACH_SAFE(redo_nodes, i, i_next, fnode)
2169 {
2170 /* FIXME: Actually do something with the new acquired padding,
2171 * the can be different and affect our padding! */
2172 Evas_Coord style_pad_l, style_pad_r, style_pad_t, style_pad_b;
2173 redo_nodes = eina_list_remove_list(redo_nodes, i);
2174 fmt = eina_list_data_get(c->format_stack);
2175 _layout_do_format(c->obj, c, &fmt, fnode,
2176 &style_pad_l, &style_pad_r,
2177 &style_pad_t, &style_pad_b, EINA_FALSE);
2178 }
2179 }
2180
2181 fmt = eina_list_data_get(c->format_stack);
2114 } 2182 }
2115 return fmt; 2183 return fmt;
2116} 2184}
@@ -3034,7 +3102,7 @@ _layout_do_format(const Evas_Object *obj __UNUSED__, Ctxt *c,
3034 fi->parent.h = h; 3102 fi->parent.h = h;
3035 } 3103 }
3036 /* Not sure if it's the best handling, but will do it for now. */ 3104 /* Not sure if it's the best handling, but will do it for now. */
3037 fmt = _layout_format_push(c, fmt); 3105 fmt = _layout_format_push(c, fmt, n);
3038 handled = 1; 3106 handled = 1;
3039 } 3107 }
3040 3108
@@ -3043,13 +3111,13 @@ _layout_do_format(const Evas_Object *obj __UNUSED__, Ctxt *c,
3043 Eina_Bool push_fmt = EINA_FALSE; 3111 Eina_Bool push_fmt = EINA_FALSE;
3044 if (s[0] == '+') 3112 if (s[0] == '+')
3045 { 3113 {
3046 fmt = _layout_format_push(c, fmt); 3114 fmt = _layout_format_push(c, fmt, n);
3047 s++; 3115 s++;
3048 push_fmt = EINA_TRUE; 3116 push_fmt = EINA_TRUE;
3049 } 3117 }
3050 else if (s[0] == '-') 3118 else if (s[0] == '-')
3051 { 3119 {
3052 fmt = _layout_format_pop(c, fmt); 3120 fmt = _layout_format_pop(c, n->orig_format);
3053 s++; 3121 s++;
3054 } 3122 }
3055 while ((item = _format_parse(&s))) 3123 while ((item = _format_parse(&s)))
@@ -4022,7 +4090,7 @@ _layout(const Evas_Object *obj, int w, int h, int *w_ret, int *h_ret)
4022 /* setup default base style */ 4090 /* setup default base style */
4023 if ((c->o->style) && (c->o->style->default_tag)) 4091 if ((c->o->style) && (c->o->style->default_tag))
4024 { 4092 {
4025 c->fmt = _layout_format_push(c, NULL); 4093 c->fmt = _layout_format_push(c, NULL, NULL);
4026 _format_fill(c->obj, c->fmt, c->o->style->default_tag); 4094 _format_fill(c->obj, c->fmt, c->o->style->default_tag);
4027 } 4095 }
4028 if (!c->fmt) 4096 if (!c->fmt)
@@ -4777,38 +4845,9 @@ evas_object_textblock_text_markup_prepend(Evas_Textblock_Cursor *cur, const char
4777 ttag = malloc(ttag_len + 1); 4845 ttag = malloc(ttag_len + 1);
4778 if (ttag) 4846 if (ttag)
4779 { 4847 {
4780 const char *match;
4781 size_t replace_len;
4782
4783 memcpy(ttag, tag_start + 1, ttag_len); 4848 memcpy(ttag, tag_start + 1, ttag_len);
4784 ttag[ttag_len] = 0; 4849 ttag[ttag_len] = 0;
4785 match = _style_match_tag(o->style, ttag, ttag_len, &replace_len); 4850 evas_textblock_cursor_format_prepend(cur, ttag);
4786 if (match)
4787 {
4788 evas_textblock_cursor_format_prepend(cur, match);
4789 }
4790 else
4791 {
4792 char *ttag2;
4793
4794 ttag2 = malloc(ttag_len + 2 + 1);
4795 if (ttag2)
4796 {
4797 if (ttag[0] == '/')
4798 {
4799 strcpy(ttag2, "- ");
4800 strcat(ttag2, ttag + 1);
4801 }
4802 else
4803 {
4804 strcpy(ttag2, "+ ");
4805 strcat(ttag2, ttag);
4806 }
4807 evas_textblock_cursor_format_prepend(cur, ttag2);
4808 free(ttag2);
4809 }
4810 }
4811 free(ttag);
4812 } 4851 }
4813 tag_start = tag_end = NULL; 4852 tag_start = tag_end = NULL;
4814 } 4853 }
@@ -6702,6 +6741,7 @@ _evas_textblock_node_format_free(Evas_Object_Textblock *o,
6702{ 6741{
6703 if (!n) return; 6742 if (!n) return;
6704 eina_stringshare_del(n->format); 6743 eina_stringshare_del(n->format);
6744 eina_stringshare_del(n->orig_format);
6705 if (n->anchor == ANCHOR_ITEM) 6745 if (n->anchor == ANCHOR_ITEM)
6706 o->anchors_item = eina_list_remove(o->anchors_item, n); 6746 o->anchors_item = eina_list_remove(o->anchors_item, n);
6707 else if (n->anchor == ANCHOR_A) 6747 else if (n->anchor == ANCHOR_A)
@@ -6723,7 +6763,61 @@ _evas_textblock_node_format_new(Evas_Object_Textblock *o, const char *format)
6723 Evas_Object_Textblock_Node_Format *n; 6763 Evas_Object_Textblock_Node_Format *n;
6724 6764
6725 n = calloc(1, sizeof(Evas_Object_Textblock_Node_Format)); 6765 n = calloc(1, sizeof(Evas_Object_Textblock_Node_Format));
6726 n->format = eina_stringshare_add(format); 6766 /* Create orig_format and format */
6767 {
6768 const char *match;
6769 size_t format_len = strlen(format);
6770 size_t replace_len;
6771
6772 match = _style_match_tag(o->style, format, format_len, &replace_len);
6773 if (match)
6774 {
6775 if ((match[0] == '+') || (match[0] == '-'))
6776 {
6777 char *norm_format;
6778 norm_format = malloc(format_len + 2 + 1);
6779 memcpy(norm_format, match, 2);
6780 memcpy(norm_format + 2, format, format_len);
6781 norm_format[format_len + 2] = '\0';
6782 n->orig_format =
6783 eina_stringshare_add_length(norm_format, format_len + 2);
6784 free(norm_format);
6785 }
6786 else
6787 {
6788 n->orig_format =
6789 eina_stringshare_add_length(format, format_len);
6790 }
6791 n->format = eina_stringshare_add(match);
6792 }
6793 else
6794 {
6795 char *norm_format;
6796
6797 norm_format = malloc(format_len + 2 + 1);
6798 if (norm_format)
6799 {
6800 if (format[0] == '/')
6801 {
6802 memcpy(norm_format, "- ", 2);
6803 memcpy(norm_format + 2, format + 1, format_len - 1);
6804 norm_format[format_len + 2 - 1] = '\0';
6805 }
6806 else
6807 {
6808 memcpy(norm_format, "+ ", 2);
6809 memcpy(norm_format + 2, format, format_len);
6810 norm_format[format_len + 2] = '\0';
6811 }
6812 n->orig_format = eina_stringshare_add(norm_format);
6813 free(norm_format);
6814 }
6815 n->format = eina_stringshare_ref(n->orig_format);
6816 }
6817 }
6818
6819 format = n->format;
6820
6727 _evas_textblock_format_is_visible(n, format); 6821 _evas_textblock_format_is_visible(n, format);
6728 if (n->anchor == ANCHOR_A) 6822 if (n->anchor == ANCHOR_A)
6729 { 6823 {