diff options
Diffstat (limited to 'libraries/evas/src/lib/canvas/evas_object_textblock.c')
-rw-r--r-- | libraries/evas/src/lib/canvas/evas_object_textblock.c | 180 |
1 files changed, 138 insertions, 42 deletions
diff --git a/libraries/evas/src/lib/canvas/evas_object_textblock.c b/libraries/evas/src/lib/canvas/evas_object_textblock.c index 568911c..ee07e20 100644 --- a/libraries/evas/src/lib/canvas/evas_object_textblock.c +++ b/libraries/evas/src/lib/canvas/evas_object_textblock.c | |||
@@ -430,6 +430,7 @@ struct _Evas_Object_Textblock | |||
430 | { | 430 | { |
431 | DATA32 magic; | 431 | DATA32 magic; |
432 | Evas_Textblock_Style *style; | 432 | Evas_Textblock_Style *style; |
433 | Evas_Textblock_Style *style_user; | ||
433 | Evas_Textblock_Cursor *cursor; | 434 | Evas_Textblock_Cursor *cursor; |
434 | Eina_List *cursors; | 435 | Eina_List *cursors; |
435 | Evas_Object_Textblock_Node_Text *text_nodes; | 436 | Evas_Object_Textblock_Node_Text *text_nodes; |
@@ -4185,11 +4186,27 @@ _layout(const Evas_Object *obj, int w, int h, int *w_ret, int *h_ret) | |||
4185 | 4186 | ||
4186 | /* Start of logical layout creation */ | 4187 | /* Start of logical layout creation */ |
4187 | /* setup default base style */ | 4188 | /* setup default base style */ |
4188 | if ((c->o->style) && (c->o->style->default_tag)) | ||
4189 | { | 4189 | { |
4190 | c->fmt = _layout_format_push(c, NULL, NULL); | 4190 | Eina_Bool finalize = EINA_FALSE; |
4191 | _format_fill(c->obj, c->fmt, c->o->style->default_tag); | 4191 | if ((c->o->style) && (c->o->style->default_tag)) |
4192 | _format_finalize(c->obj, c->fmt); | 4192 | { |
4193 | c->fmt = _layout_format_push(c, NULL, NULL); | ||
4194 | _format_fill(c->obj, c->fmt, c->o->style->default_tag); | ||
4195 | finalize = EINA_TRUE; | ||
4196 | } | ||
4197 | |||
4198 | if ((c->o->style_user) && (c->o->style_user->default_tag)) | ||
4199 | { | ||
4200 | if (!c->fmt) | ||
4201 | { | ||
4202 | c->fmt = _layout_format_push(c, NULL, NULL); | ||
4203 | } | ||
4204 | _format_fill(c->obj, c->fmt, c->o->style_user->default_tag); | ||
4205 | finalize = EINA_TRUE; | ||
4206 | } | ||
4207 | |||
4208 | if (finalize) | ||
4209 | _format_finalize(c->obj, c->fmt); | ||
4193 | } | 4210 | } |
4194 | if (!c->fmt) | 4211 | if (!c->fmt) |
4195 | { | 4212 | { |
@@ -4485,9 +4502,9 @@ evas_textblock_style_set(Evas_Textblock_Style *ts, const char *text) | |||
4485 | { | 4502 | { |
4486 | // format MUST be KEY='VALUE'[KEY='VALUE']... | 4503 | // format MUST be KEY='VALUE'[KEY='VALUE']... |
4487 | const char *p; | 4504 | const char *p; |
4488 | const char *key_start, *key_stop, *val_start, *val_stop; | 4505 | const char *key_start, *key_stop, *val_start; |
4489 | 4506 | ||
4490 | key_start = key_stop = val_start = val_stop = NULL; | 4507 | key_start = key_stop = val_start = NULL; |
4491 | p = ts->style_text; | 4508 | p = ts->style_text; |
4492 | while (*p) | 4509 | while (*p) |
4493 | { | 4510 | { |
@@ -4504,19 +4521,54 @@ evas_textblock_style_set(Evas_Textblock_Style *ts, const char *text) | |||
4504 | else if (!val_start) | 4521 | else if (!val_start) |
4505 | { | 4522 | { |
4506 | if (((*p) == '\'') && (*(p + 1))) | 4523 | if (((*p) == '\'') && (*(p + 1))) |
4507 | val_start = p + 1; | 4524 | { |
4508 | } | 4525 | val_start = ++p; |
4509 | else if (!val_stop) | 4526 | } |
4510 | { | ||
4511 | if (((*p) == '\'') && (p > ts->style_text) && (p[-1] != '\\')) | ||
4512 | val_stop = p; | ||
4513 | } | 4527 | } |
4514 | if ((key_start) && (key_stop) && (val_start) && (val_stop)) | 4528 | if ((key_start) && (key_stop) && (val_start)) |
4515 | { | 4529 | { |
4516 | char *tags, *replaces; | 4530 | char *tags, *replaces = NULL; |
4517 | Evas_Object_Style_Tag *tag; | 4531 | Evas_Object_Style_Tag *tag; |
4518 | size_t tag_len = key_stop - key_start; | 4532 | const char *val_stop = NULL; |
4519 | size_t replace_len = val_stop - val_start; | 4533 | size_t tag_len; |
4534 | size_t replace_len; | ||
4535 | |||
4536 | { | ||
4537 | Eina_Strbuf *buf = eina_strbuf_new(); | ||
4538 | val_stop = val_start; | ||
4539 | while(*p) | ||
4540 | { | ||
4541 | if (*p == '\'') | ||
4542 | { | ||
4543 | /* Break if we found the tag end */ | ||
4544 | if (p[-1] != '\\') | ||
4545 | { | ||
4546 | eina_strbuf_append_length(buf, val_stop, | ||
4547 | p - val_stop); | ||
4548 | break; | ||
4549 | } | ||
4550 | else | ||
4551 | { | ||
4552 | eina_strbuf_append_length(buf, val_stop, | ||
4553 | p - val_stop - 1); | ||
4554 | eina_strbuf_append_char(buf, '\''); | ||
4555 | val_stop = p + 1; | ||
4556 | } | ||
4557 | } | ||
4558 | p++; | ||
4559 | } | ||
4560 | replaces = eina_strbuf_string_steal(buf); | ||
4561 | eina_strbuf_free(buf); | ||
4562 | } | ||
4563 | /* If we didn't find an end, just aboart. */ | ||
4564 | if (!*p) | ||
4565 | { | ||
4566 | if (replaces) free(replaces); | ||
4567 | break; | ||
4568 | } | ||
4569 | |||
4570 | tag_len = key_stop - key_start; | ||
4571 | replace_len = val_stop - val_start; | ||
4520 | 4572 | ||
4521 | tags = malloc(tag_len + 1); | 4573 | tags = malloc(tag_len + 1); |
4522 | if (tags) | 4574 | if (tags) |
@@ -4525,12 +4577,6 @@ evas_textblock_style_set(Evas_Textblock_Style *ts, const char *text) | |||
4525 | tags[tag_len] = 0; | 4577 | tags[tag_len] = 0; |
4526 | } | 4578 | } |
4527 | 4579 | ||
4528 | replaces = malloc(replace_len + 1); | ||
4529 | if (replaces) | ||
4530 | { | ||
4531 | memcpy(replaces, val_start, replace_len); | ||
4532 | replaces[replace_len] = 0; | ||
4533 | } | ||
4534 | if ((tags) && (replaces)) | 4580 | if ((tags) && (replaces)) |
4535 | { | 4581 | { |
4536 | if (!strcmp(tags, "DEFAULT")) | 4582 | if (!strcmp(tags, "DEFAULT")) |
@@ -4561,7 +4607,7 @@ evas_textblock_style_set(Evas_Textblock_Style *ts, const char *text) | |||
4561 | if (tags) free(tags); | 4607 | if (tags) free(tags); |
4562 | if (replaces) free(replaces); | 4608 | if (replaces) free(replaces); |
4563 | } | 4609 | } |
4564 | key_start = key_stop = val_start = val_stop = NULL; | 4610 | key_start = key_stop = val_start = NULL; |
4565 | } | 4611 | } |
4566 | p++; | 4612 | p++; |
4567 | } | 4613 | } |
@@ -4576,13 +4622,15 @@ evas_textblock_style_get(const Evas_Textblock_Style *ts) | |||
4576 | } | 4622 | } |
4577 | 4623 | ||
4578 | /* textblock styles */ | 4624 | /* textblock styles */ |
4579 | EAPI void | 4625 | |
4580 | evas_object_textblock_style_set(Evas_Object *obj, Evas_Textblock_Style *ts) | 4626 | static void |
4627 | _textblock_style_generic_set(Evas_Object *obj, Evas_Textblock_Style *ts, | ||
4628 | Evas_Textblock_Style **obj_ts) | ||
4581 | { | 4629 | { |
4582 | TB_HEAD(); | 4630 | TB_HEAD(); |
4583 | if (ts == o->style) return; | 4631 | if (ts == *obj_ts) return; |
4584 | if ((ts) && (ts->delete_me)) return; | 4632 | if ((ts) && (ts->delete_me)) return; |
4585 | if (o->style) | 4633 | if (*obj_ts) |
4586 | { | 4634 | { |
4587 | Evas_Textblock_Style *old_ts; | 4635 | Evas_Textblock_Style *old_ts; |
4588 | if (o->markup_text) | 4636 | if (o->markup_text) |
@@ -4591,7 +4639,7 @@ evas_object_textblock_style_set(Evas_Object *obj, Evas_Textblock_Style *ts) | |||
4591 | o->markup_text = NULL; | 4639 | o->markup_text = NULL; |
4592 | } | 4640 | } |
4593 | 4641 | ||
4594 | old_ts = o->style; | 4642 | old_ts = *obj_ts; |
4595 | old_ts->objects = eina_list_remove(old_ts->objects, obj); | 4643 | old_ts->objects = eina_list_remove(old_ts->objects, obj); |
4596 | if ((old_ts->delete_me) && (!old_ts->objects)) | 4644 | if ((old_ts->delete_me) && (!old_ts->objects)) |
4597 | evas_textblock_style_free(old_ts); | 4645 | evas_textblock_style_free(old_ts); |
@@ -4600,12 +4648,19 @@ evas_object_textblock_style_set(Evas_Object *obj, Evas_Textblock_Style *ts) | |||
4600 | { | 4648 | { |
4601 | ts->objects = eina_list_append(ts->objects, obj); | 4649 | ts->objects = eina_list_append(ts->objects, obj); |
4602 | } | 4650 | } |
4603 | o->style = ts; | 4651 | *obj_ts = ts; |
4604 | 4652 | ||
4605 | _evas_textblock_invalidate_all(o); | 4653 | _evas_textblock_invalidate_all(o); |
4606 | _evas_textblock_changed(o, obj); | 4654 | _evas_textblock_changed(o, obj); |
4607 | } | 4655 | } |
4608 | 4656 | ||
4657 | EAPI void | ||
4658 | evas_object_textblock_style_set(Evas_Object *obj, Evas_Textblock_Style *ts) | ||
4659 | { | ||
4660 | TB_HEAD(); | ||
4661 | _textblock_style_generic_set(obj, ts, &(o->style)); | ||
4662 | } | ||
4663 | |||
4609 | EAPI const Evas_Textblock_Style * | 4664 | EAPI const Evas_Textblock_Style * |
4610 | evas_object_textblock_style_get(const Evas_Object *obj) | 4665 | evas_object_textblock_style_get(const Evas_Object *obj) |
4611 | { | 4666 | { |
@@ -4614,6 +4669,27 @@ evas_object_textblock_style_get(const Evas_Object *obj) | |||
4614 | } | 4669 | } |
4615 | 4670 | ||
4616 | EAPI void | 4671 | EAPI void |
4672 | evas_object_textblock_style_user_push(Evas_Object *obj, Evas_Textblock_Style *ts) | ||
4673 | { | ||
4674 | TB_HEAD(); | ||
4675 | _textblock_style_generic_set(obj, ts, &(o->style_user)); | ||
4676 | } | ||
4677 | |||
4678 | EAPI const Evas_Textblock_Style * | ||
4679 | evas_object_textblock_style_user_peek(const Evas_Object *obj) | ||
4680 | { | ||
4681 | TB_HEAD_RETURN(NULL); | ||
4682 | return o->style_user; | ||
4683 | } | ||
4684 | |||
4685 | EAPI void | ||
4686 | evas_object_textblock_style_user_pop(Evas_Object *obj) | ||
4687 | { | ||
4688 | TB_HEAD(); | ||
4689 | _textblock_style_generic_set(obj, NULL, &(o->style_user)); | ||
4690 | } | ||
4691 | |||
4692 | EAPI void | ||
4617 | evas_object_textblock_replace_char_set(Evas_Object *obj, const char *ch) | 4693 | evas_object_textblock_replace_char_set(Evas_Object *obj, const char *ch) |
4618 | { | 4694 | { |
4619 | TB_HEAD(); | 4695 | TB_HEAD(); |
@@ -4902,7 +4978,7 @@ evas_object_textblock_text_markup_set(Evas_Object *obj, const char *text) | |||
4902 | o->markup_text = NULL; | 4978 | o->markup_text = NULL; |
4903 | } | 4979 | } |
4904 | _nodes_clear(obj); | 4980 | _nodes_clear(obj); |
4905 | if (!o->style) | 4981 | if (!o->style && !o->style_user) |
4906 | { | 4982 | { |
4907 | if (text != o->markup_text) | 4983 | if (text != o->markup_text) |
4908 | { | 4984 | { |
@@ -5244,7 +5320,7 @@ evas_textblock_text_markup_to_utf8(const Evas_Object *obj, const char *text) | |||
5244 | const char *escape; | 5320 | const char *escape; |
5245 | 5321 | ||
5246 | escape = _escaped_char_get(esc_start, esc_end + 1); | 5322 | escape = _escaped_char_get(esc_start, esc_end + 1); |
5247 | eina_strbuf_append(sbuf, escape); | 5323 | if (escape) eina_strbuf_append(sbuf, escape); |
5248 | esc_start = esc_end = NULL; | 5324 | esc_start = esc_end = NULL; |
5249 | } | 5325 | } |
5250 | else if (*p == 0) | 5326 | else if (*p == 0) |
@@ -5650,7 +5726,6 @@ EAPI Eina_Bool | |||
5650 | evas_textblock_cursor_is_format(const Evas_Textblock_Cursor *cur) | 5726 | evas_textblock_cursor_is_format(const Evas_Textblock_Cursor *cur) |
5651 | { | 5727 | { |
5652 | if (!cur || !cur->node) return EINA_FALSE; | 5728 | if (!cur || !cur->node) return EINA_FALSE; |
5653 | if (evas_textblock_cursor_format_is_visible_get(cur)) return EINA_TRUE; | ||
5654 | return (_evas_textblock_cursor_node_format_at_pos_get(cur)) ? | 5729 | return (_evas_textblock_cursor_node_format_at_pos_get(cur)) ? |
5655 | EINA_TRUE : EINA_FALSE; | 5730 | EINA_TRUE : EINA_FALSE; |
5656 | } | 5731 | } |
@@ -5977,9 +6052,9 @@ evas_textblock_cursor_format_prev(Evas_Textblock_Cursor *cur) | |||
5977 | #else | 6052 | #else |
5978 | 6053 | ||
5979 | #define BREAK_AFTER(i) \ | 6054 | #define BREAK_AFTER(i) \ |
5980 | ((!str[i + 1]) || \ | 6055 | ((!text[i + 1]) || \ |
5981 | (_is_white(str[i]) && !_is_white(str[i + 1])) || \ | 6056 | (_is_white(text[i]) && !_is_white(text[i + 1])) || \ |
5982 | (!_is_white(str[i]) && _is_white(str[i + 1]))) | 6057 | (!_is_white(text[i]) && _is_white(text[i + 1]))) |
5983 | 6058 | ||
5984 | #endif | 6059 | #endif |
5985 | 6060 | ||
@@ -7241,7 +7316,13 @@ _evas_textblock_node_format_new(Evas_Object_Textblock *o, const char *_format) | |||
7241 | } | 7316 | } |
7242 | } | 7317 | } |
7243 | 7318 | ||
7244 | match = _style_match_tag(o->style, format, format_len, &replace_len); | 7319 | if (!o->style_user || !(match = _style_match_tag(o->style_user, format, |
7320 | format_len, &replace_len))) | ||
7321 | { | ||
7322 | match = _style_match_tag(o->style, format, format_len, | ||
7323 | &replace_len); | ||
7324 | } | ||
7325 | |||
7245 | if (match) | 7326 | if (match) |
7246 | { | 7327 | { |
7247 | if (match[0] != '-') | 7328 | if (match[0] != '-') |
@@ -7633,6 +7714,7 @@ evas_textblock_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_C | |||
7633 | } | 7714 | } |
7634 | fnode = _evas_textblock_cursor_node_format_at_pos_get(cur1); | 7715 | fnode = _evas_textblock_cursor_node_format_at_pos_get(cur1); |
7635 | 7716 | ||
7717 | n1->dirty = n2->dirty = EINA_TRUE; | ||
7636 | if (should_merge) | 7718 | if (should_merge) |
7637 | { | 7719 | { |
7638 | /* We call this function instead of the cursor one because we already | 7720 | /* We call this function instead of the cursor one because we already |
@@ -7646,7 +7728,6 @@ evas_textblock_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_C | |||
7646 | evas_textblock_cursor_copy(cur1, o->cursor); | 7728 | evas_textblock_cursor_copy(cur1, o->cursor); |
7647 | 7729 | ||
7648 | _evas_textblock_changed(o, cur1->obj); | 7730 | _evas_textblock_changed(o, cur1->obj); |
7649 | n1->dirty = n2->dirty = EINA_TRUE; | ||
7650 | } | 7731 | } |
7651 | 7732 | ||
7652 | 7733 | ||
@@ -8022,6 +8103,7 @@ evas_textblock_cursor_format_is_visible_get(const Evas_Textblock_Cursor *cur) | |||
8022 | 8103 | ||
8023 | if (!cur) return EINA_FALSE; | 8104 | if (!cur) return EINA_FALSE; |
8024 | if (!cur->node) return EINA_FALSE; | 8105 | if (!cur->node) return EINA_FALSE; |
8106 | if (!evas_textblock_cursor_is_format(cur)) return EINA_FALSE; | ||
8025 | text = eina_ustrbuf_string_get(cur->node->unicode); | 8107 | text = eina_ustrbuf_string_get(cur->node->unicode); |
8026 | return EVAS_TEXTBLOCK_IS_VISIBLE_FORMAT_CHAR(text[cur->pos]); | 8108 | return EVAS_TEXTBLOCK_IS_VISIBLE_FORMAT_CHAR(text[cur->pos]); |
8027 | } | 8109 | } |
@@ -9016,12 +9098,22 @@ _size_native_calc_line_finalize(const Evas_Object *obj, Eina_List *items, | |||
9016 | Eina_List *i; | 9098 | Eina_List *i; |
9017 | 9099 | ||
9018 | it = eina_list_data_get(items); | 9100 | it = eina_list_data_get(items); |
9019 | /* If there are no text items yet, calc ascent/descent | ||
9020 | * according to the current format. */ | ||
9021 | if (it && (*ascent + *descent == 0)) | ||
9022 | _layout_format_ascent_descent_adjust(obj, ascent, descent, it->format); | ||
9023 | |||
9024 | *w = 0; | 9101 | *w = 0; |
9102 | |||
9103 | if (it) | ||
9104 | { | ||
9105 | /* If there are no text items yet, calc ascent/descent | ||
9106 | * according to the current format. */ | ||
9107 | if (*ascent + *descent == 0) | ||
9108 | _layout_format_ascent_descent_adjust(obj, ascent, descent, | ||
9109 | it->format); | ||
9110 | |||
9111 | /* Add margins. */ | ||
9112 | if (it->format) | ||
9113 | *w = it->format->margin.l + it->format->margin.r; | ||
9114 | } | ||
9115 | |||
9116 | |||
9025 | /* Adjust all the item sizes according to the final line size, | 9117 | /* Adjust all the item sizes according to the final line size, |
9026 | * and update the x positions of all the items of the line. */ | 9118 | * and update the x positions of all the items of the line. */ |
9027 | EINA_LIST_FOREACH(items, i, it) | 9119 | EINA_LIST_FOREACH(items, i, it) |
@@ -9226,6 +9318,10 @@ evas_object_textblock_free(Evas_Object *obj) | |||
9226 | 9318 | ||
9227 | evas_object_textblock_clear(obj); | 9319 | evas_object_textblock_clear(obj); |
9228 | evas_object_textblock_style_set(obj, NULL); | 9320 | evas_object_textblock_style_set(obj, NULL); |
9321 | while (evas_object_textblock_style_user_peek(obj)) | ||
9322 | { | ||
9323 | evas_object_textblock_style_user_pop(obj); | ||
9324 | } | ||
9229 | o = (Evas_Object_Textblock *)(obj->object_data); | 9325 | o = (Evas_Object_Textblock *)(obj->object_data); |
9230 | free(o->cursor); | 9326 | free(o->cursor); |
9231 | while (o->cursors) | 9327 | while (o->cursors) |