summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Hirt <hirt.danny@gmail.com>2017-08-23 21:43:51 +0300
committerDaniel Hirt <hirt.danny@gmail.com>2017-08-24 12:38:13 +0300
commite63be982d904a01ade5aced9ef9924a78d155b8a (patch)
treeb27700520cb454c86ff3f023369c203b687fbd89
parente20a44b7e7284cd81db34c7c09d797155c391f04 (diff)
Canvas text: prevent change of context width field
The 'c->w' field gets manipulated for querying cutoffs of text with its boundaries. Better to keep it a read-only field, to reduce confusion. Also updated querying internal functions for better readability.
-rw-r--r--src/lib/evas/canvas/evas_object_textblock.c86
1 files changed, 48 insertions, 38 deletions
diff --git a/src/lib/evas/canvas/evas_object_textblock.c b/src/lib/evas/canvas/evas_object_textblock.c
index 11e023432b..01cefea7ca 100644
--- a/src/lib/evas/canvas/evas_object_textblock.c
+++ b/src/lib/evas/canvas/evas_object_textblock.c
@@ -3993,16 +3993,18 @@ _layout_text_item_new(Ctxt *c EINA_UNUSED, Evas_Object_Textblock_Format *fmt)
3993 */ 3993 */
3994static int 3994static int
3995_layout_text_cutoff_get(Ctxt *c, Evas_Object_Textblock_Format *fmt, 3995_layout_text_cutoff_get(Ctxt *c, Evas_Object_Textblock_Format *fmt,
3996 const Evas_Object_Textblock_Text_Item *ti, int width_offset) 3996 const Evas_Object_Textblock_Text_Item *ti,
3997 Evas_Coord w, Evas_Coord from_x, int width_offset)
3997{ 3998{
3998 if (fmt->font.font) 3999 if (fmt->font.font)
3999 { 4000 {
4000 Evas_Coord x; 4001 Evas_Coord x;
4001 x = c->w - c->o->style_pad.l - c->o->style_pad.r - c->marginl - 4002 Evas_Object_Protected_Data *obj = c->evas_o;
4002 c->marginr - c->x - ti->x_adjustment; 4003
4004 x = w - c->o->style_pad.l - c->o->style_pad.r - c->marginl -
4005 c->marginr - from_x - ti->x_adjustment;
4003 if (x < 0) 4006 if (x < 0)
4004 x = 0; 4007 x = 0;
4005 Evas_Object_Protected_Data *obj = efl_data_scope_get(c->obj, EFL_CANVAS_OBJECT_CLASS);
4006 return ENFN->font_last_up_to_pos(ENDT, fmt->font.font, 4008 return ENFN->font_last_up_to_pos(ENDT, fmt->font.font,
4007 &ti->text_props, x, 0, width_offset); 4009 &ti->text_props, x, 0, width_offset);
4008 } 4010 }
@@ -4764,7 +4766,8 @@ _layout_update_par(Ctxt *c)
4764static int 4766static int
4765_layout_get_charwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt, 4767_layout_get_charwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt,
4766 const Evas_Object_Textblock_Item *it, size_t line_start, 4768 const Evas_Object_Textblock_Item *it, size_t line_start,
4767 const char *breaks) 4769 const char *breaks,
4770 Evas_Coord w, Evas_Coord from_x)
4768{ 4771{
4769 int wrap; 4772 int wrap;
4770 size_t uwrap; 4773 size_t uwrap;
@@ -4777,7 +4780,8 @@ _layout_get_charwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt,
4777 if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT) 4780 if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT)
4778 wrap = 0; 4781 wrap = 0;
4779 else 4782 else
4780 wrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), 0); 4783 wrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it),
4784 w, from_x, 0);
4781 4785
4782 if (wrap < 0) 4786 if (wrap < 0)
4783 return -1; 4787 return -1;
@@ -4817,7 +4821,8 @@ _layout_word_end(const char *breaks, size_t pos, size_t len)
4817static int 4821static int
4818_layout_get_hyphenationwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt, 4822_layout_get_hyphenationwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt,
4819 const Evas_Object_Textblock_Item *it, size_t line_start, 4823 const Evas_Object_Textblock_Item *it, size_t line_start,
4820 const char *breaks, const char *wordbreaks) 4824 const char *breaks, const char *wordbreaks,
4825 Evas_Coord w, Evas_Coord from_x)
4821{ 4826{
4822 size_t wrap; 4827 size_t wrap;
4823 size_t orig_wrap; 4828 size_t orig_wrap;
@@ -4835,17 +4840,14 @@ _layout_get_hyphenationwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt,
4835 swrap = 0; 4840 swrap = 0;
4836 else 4841 else
4837 { 4842 {
4838 Evas_Coord cw;
4839
4840 /* Get cutoff */ 4843 /* Get cutoff */
4841 swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), 0); 4844 swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), 0,
4845 w, from_x);
4842 4846
4843 /* Get cutoff considering an additional hyphen item */ 4847 /* Get cutoff considering an additional hyphen item */
4844 cw = c->w;
4845 c->hyphen_ti = _layout_hyphen_item_new(c, _ITEM_TEXT(it)); 4848 c->hyphen_ti = _layout_hyphen_item_new(c, _ITEM_TEXT(it));
4846 c->w -= c->hyphen_ti->parent.w; 4849 hyphen_swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it),
4847 hyphen_swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), c->hyphen_ti->parent.w); 4850 w - c->hyphen_ti->parent.w, from_x, c->hyphen_ti->parent.w);
4848 c->w = cw;
4849 4851
4850 /* Stronger condition than '< 0' for hyphenations */ 4852 /* Stronger condition than '< 0' for hyphenations */
4851 if (hyphen_swrap >= 2) 4853 if (hyphen_swrap >= 2)
@@ -4974,13 +4976,15 @@ _layout_get_hyphenationwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt,
4974 4976
4975 /* Hyphenation falls-back to char wrapping at start of line */ 4977 /* Hyphenation falls-back to char wrapping at start of line */
4976 return _layout_get_charwrap(c, fmt, it, 4978 return _layout_get_charwrap(c, fmt, it,
4977 line_start, breaks); 4979 line_start, breaks, w, from_x);
4978} 4980}
4979 4981
4980static int 4982static int
4981_layout_get_word_mixwrap_common(Ctxt *c, Evas_Object_Textblock_Format *fmt, 4983_layout_get_word_mixwrap_common(Ctxt *c, Evas_Object_Textblock_Format *fmt,
4982 const Evas_Object_Textblock_Item *it, Eina_Bool mixed_wrap, 4984 const Evas_Object_Textblock_Item *it, Eina_Bool mixed_wrap,
4983 size_t line_start, const char *breaks, Eina_Bool scan_fwd) 4985 size_t line_start, const char *breaks,
4986 Evas_Coord w, Evas_Coord from_x,
4987 Eina_Bool scan_fwd)
4984{ 4988{
4985 Eina_Bool wrap_after = EINA_FALSE; 4989 Eina_Bool wrap_after = EINA_FALSE;
4986 size_t wrap; 4990 size_t wrap;
@@ -4995,7 +4999,7 @@ _layout_get_word_mixwrap_common(Ctxt *c, Evas_Object_Textblock_Format *fmt,
4995 if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT) 4999 if (it->type == EVAS_TEXTBLOCK_ITEM_FORMAT)
4996 swrap = 0; 5000 swrap = 0;
4997 else 5001 else
4998 swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), 0); 5002 swrap = _layout_text_cutoff_get(c, fmt, _ITEM_TEXT(it), w, from_x, 0);
4999 /* Avoiding too small textblocks to even contain one char. 5003 /* Avoiding too small textblocks to even contain one char.
5000 * FIXME: This can cause breaking inside ligatures. */ 5004 * FIXME: This can cause breaking inside ligatures. */
5001 5005
@@ -5052,7 +5056,7 @@ _layout_get_word_mixwrap_common(Ctxt *c, Evas_Object_Textblock_Format *fmt,
5052 if (mixed_wrap) 5056 if (mixed_wrap)
5053 { 5057 {
5054 return _layout_get_charwrap(c, fmt, it, 5058 return _layout_get_charwrap(c, fmt, it,
5055 line_start, breaks); 5059 line_start, breaks, w, from_x);
5056 } 5060 }
5057 else 5061 else
5058 { 5062 {
@@ -5083,20 +5087,24 @@ _layout_get_word_mixwrap_common(Ctxt *c, Evas_Object_Textblock_Format *fmt,
5083static int 5087static int
5084_layout_get_wordwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt, 5088_layout_get_wordwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt,
5085 const Evas_Object_Textblock_Item *it, size_t line_start, 5089 const Evas_Object_Textblock_Item *it, size_t line_start,
5086 const char *breaks, Eina_Bool allow_scan_fwd) 5090 const char *breaks,
5091 Evas_Coord w, Evas_Coord from_x,
5092 Eina_Bool allow_scan_fwd)
5087{ 5093{
5088 return _layout_get_word_mixwrap_common(c, fmt, it, EINA_FALSE, line_start, 5094 return _layout_get_word_mixwrap_common(c, fmt, it, EINA_FALSE, line_start,
5089 breaks, allow_scan_fwd); 5095 breaks, w, from_x, allow_scan_fwd);
5090} 5096}
5091 5097
5092/* -1 means no wrap */ 5098/* -1 means no wrap */
5093static int 5099static int
5094_layout_get_mixedwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt, 5100_layout_get_mixedwrap(Ctxt *c, Evas_Object_Textblock_Format *fmt,
5095 const Evas_Object_Textblock_Item *it, size_t line_start, 5101 const Evas_Object_Textblock_Item *it, size_t line_start,
5096 const char *breaks, Eina_Bool allow_scan_fwd) 5102 const char *breaks,
5103 Evas_Coord w, Evas_Coord from_x,
5104 Eina_Bool allow_scan_fwd)
5097{ 5105{
5098 return _layout_get_word_mixwrap_common(c, fmt, it, EINA_TRUE, line_start, 5106 return _layout_get_word_mixwrap_common(c, fmt, it, EINA_TRUE, line_start,
5099 breaks, allow_scan_fwd); 5107 breaks, w, from_x, allow_scan_fwd);
5100} 5108}
5101 5109
5102static Evas_Object_Textblock_Text_Item * 5110static Evas_Object_Textblock_Text_Item *
@@ -5157,13 +5165,14 @@ _layout_handle_ellipsis(Ctxt *c, Evas_Object_Textblock_Item *it, Eina_List *i)
5157{ 5165{
5158 Evas_Object_Textblock_Text_Item *ti, *ellip_ti; 5166 Evas_Object_Textblock_Text_Item *ti, *ellip_ti;
5159 Evas_Object_Textblock_Item *last_it, *prev_it; 5167 Evas_Object_Textblock_Item *last_it, *prev_it;
5160 Evas_Coord save_cx, save_cw, ellip_w; 5168 Evas_Coord save_cx, ellip_w;
5169 Evas_Coord temp_w;
5161 int wrap; 5170 int wrap;
5162 ellip_ti = _layout_ellipsis_item_new(c, it); 5171 ellip_ti = _layout_ellipsis_item_new(c, it);
5163 prev_it = last_it = it; 5172 prev_it = last_it = it;
5164 5173
5165 save_cx = c->x; 5174 save_cx = c->x;
5166 save_cw = c->w; 5175 temp_w = c->w;
5167 ellip_w = ellip_ti->parent.w; 5176 ellip_w = ellip_ti->parent.w;
5168#ifdef BIDI_SUPPORT 5177#ifdef BIDI_SUPPORT
5169 // XXX: with RTL considerations in mind, we need to take max(adv, w) as the 5178 // XXX: with RTL considerations in mind, we need to take max(adv, w) as the
@@ -5174,10 +5183,10 @@ _layout_handle_ellipsis(Ctxt *c, Evas_Object_Textblock_Item *it, Eina_List *i)
5174 ellip_w = ellip_ti->parent.adv; 5183 ellip_w = ellip_ti->parent.adv;
5175 } 5184 }
5176#endif 5185#endif
5177 c->w -= ellip_w; 5186 temp_w -= ellip_w;
5178 5187
5179 /* If there is no enough space for ellipsis item, remove all of items */ 5188 /* If there is no enough space for ellipsis item, remove all of items */
5180 if (c->w <= 0) 5189 if (temp_w <= 0)
5181 { 5190 {
5182 while (c->ln->items) 5191 while (c->ln->items)
5183 { 5192 {
@@ -5195,7 +5204,8 @@ _layout_handle_ellipsis(Ctxt *c, Evas_Object_Textblock_Item *it, Eina_List *i)
5195 { 5204 {
5196 ti = _ITEM_TEXT(last_it); 5205 ti = _ITEM_TEXT(last_it);
5197 5206
5198 wrap = _layout_text_cutoff_get(c, last_it->format, ti, ellip_ti->parent.w); 5207 wrap = _layout_text_cutoff_get(c, last_it->format, ti,
5208 temp_w, c->x, ellip_ti->parent.w);
5199 5209
5200 if ((wrap > 0) && !IS_AT_END(ti, (size_t) wrap)) 5210 if ((wrap > 0) && !IS_AT_END(ti, (size_t) wrap))
5201 { 5211 {
@@ -5224,7 +5234,7 @@ _layout_handle_ellipsis(Ctxt *c, Evas_Object_Textblock_Item *it, Eina_List *i)
5224 /* We will ignore format items. ex) tab 5234 /* We will ignore format items. ex) tab
5225 * But, if there is <item> tag and size is acceptable, we have to insert it to line. */ 5235 * But, if there is <item> tag and size is acceptable, we have to insert it to line. */
5226 if (!strncmp(_ITEM_FORMAT(last_it)->item, "item", 4) && 5236 if (!strncmp(_ITEM_FORMAT(last_it)->item, "item", 4) &&
5227 ((c->w - c->o->style_pad.l - c->o->style_pad.r - c->marginl - c->marginr) >= (c->x + last_it->adv))) 5237 ((temp_w - c->o->style_pad.l - c->o->style_pad.r - c->marginl - c->marginr) >= (c->x + last_it->adv)))
5228 { 5238 {
5229 break; 5239 break;
5230 } 5240 }
@@ -5245,9 +5255,9 @@ _layout_handle_ellipsis(Ctxt *c, Evas_Object_Textblock_Item *it, Eina_List *i)
5245 /* We need to renew ellipsis item. 5255 /* We need to renew ellipsis item.
5246 * Because, base format is changed to last_it. 5256 * Because, base format is changed to last_it.
5247 * We can't reuse it. */ 5257 * We can't reuse it. */
5248 c->w += ellip_ti->parent.w; 5258 temp_w += ellip_ti->parent.w;
5249 ellip_ti = _layout_ellipsis_item_new(c, last_it); 5259 ellip_ti = _layout_ellipsis_item_new(c, last_it);
5250 c->w -= ellip_ti->parent.w; 5260 temp_w -= ellip_ti->parent.w;
5251 c->x -= last_it->adv; 5261 c->x -= last_it->adv;
5252 if (c->x < 0) 5262 if (c->x < 0)
5253 c->x = 0; 5263 c->x = 0;
@@ -5256,7 +5266,6 @@ _layout_handle_ellipsis(Ctxt *c, Evas_Object_Textblock_Item *it, Eina_List *i)
5256 } 5266 }
5257 5267
5258 c->x = save_cx; 5268 c->x = save_cx;
5259 c->w = save_cw;
5260 /* If we should add this item, do it */ 5269 /* If we should add this item, do it */
5261 if (last_it == it) 5270 if (last_it == it)
5262 { 5271 {
@@ -5730,26 +5739,27 @@ _layout_par(Ctxt *c)
5730 * was pushed forward by an obstacle once, as there 5739 * was pushed forward by an obstacle once, as there
5731 * is a chance it will fit in the next lines. */ 5740 * is a chance it will fit in the next lines. */
5732 Eina_Bool allow_scan_fwd = (!obs && !item_preadv); 5741 Eina_Bool allow_scan_fwd = (!obs && !item_preadv);
5733 Evas_Coord save_cw = c->w; 5742 Evas_Coord cw = c->w;
5734 if (obs) 5743 if (obs)
5735 { 5744 {
5736 c->w = obs->x; 5745 cw -= obs->w;
5737 } 5746 }
5738 if (it->format->wrap_word) 5747 if (it->format->wrap_word)
5739 wrap = _layout_get_wordwrap(c, it->format, it, 5748 wrap = _layout_get_wordwrap(c, it->format, it,
5740 line_start, line_breaks, allow_scan_fwd); 5749 line_start, line_breaks,
5750 cw, c->x, allow_scan_fwd);
5741 else if (it->format->wrap_char) 5751 else if (it->format->wrap_char)
5742 wrap = _layout_get_charwrap(c, it->format, it, 5752 wrap = _layout_get_charwrap(c, it->format, it,
5743 line_start, line_breaks); 5753 line_start, line_breaks, cw, c->x);
5744 else if (it->format->wrap_mixed) 5754 else if (it->format->wrap_mixed)
5745 wrap = _layout_get_mixedwrap(c, it->format, it, 5755 wrap = _layout_get_mixedwrap(c, it->format, it,
5746 line_start, line_breaks, allow_scan_fwd); 5756 line_start, line_breaks, cw, c->x, allow_scan_fwd);
5747 else if (it->format->wrap_hyphenation) 5757 else if (it->format->wrap_hyphenation)
5748 wrap = _layout_get_hyphenationwrap(c, it->format, it, 5758 wrap = _layout_get_hyphenationwrap(c, it->format, it,
5749 line_start, line_breaks, word_breaks); 5759 line_start, line_breaks, word_breaks,
5760 cw, c->x);
5750 else 5761 else
5751 wrap = -1; 5762 wrap = -1;
5752 c->w = save_cw;
5753 } 5763 }
5754 5764
5755 /* If it's before the item, rollback and apply. 5765 /* If it's before the item, rollback and apply.