efl.canvas.textblock: allow all white spaces in style string not just space
authorAli Alzyod <ali198724@gmail.com>
Tue, 11 Feb 2020 11:03:00 +0000 (12:03 +0100)
committerJongmin Lee <jm105.lee@samsung.com>
Tue, 11 Feb 2020 22:00:11 +0000 (07:00 +0900)
Summary:
style string can contain any kind of white spaces and it will be fine

For example
```
"font=sans font_size=30 color=red "
```
Is the same as
```
"font=sans\tfont_size=30\n  color=red "
```

Reviewers: woohyun, segfaultxavi, tasn, zmike

Reviewed By: segfaultxavi

Subscribers: bu5hm4n, cedric, #reviewers, #committers

Tags: #efl

Maniphest Tasks: T8532

Differential Revision: https://phab.enlightenment.org/D11303

src/lib/evas/canvas/evas_object_textblock.c
src/tests/evas/evas_test_textblock.c

index ecf1fcb4c14e2becdcf6d814a839c716c495c08e..322df6817c78b97f42e188ba1e5824d18c700577 100644 (file)
@@ -1376,8 +1376,6 @@ static const Escape_Value escape_values_v_common_sorted[] = {
    ESCAPE_VALUE("&gt;", "\x3e"),
 };
 
-
-
 /**
  * @internal
  * Checks if a char is a whitespace.
@@ -3342,6 +3340,22 @@ _format_is_param(const char *item)
    return EINA_FALSE;
 }
 
+/**
+ * @internal
+ * Returns first occurrence of whitespace character
+ * otherwise return NULL.
+ *
+ * @param[in] string to search.
+ */
+static const char*
+_strchr_whitespace(const char* str)
+{
+   if (!str) return NULL;
+   while (*str && !isspace(*str)) str++;
+   if(*str) return str;
+   return NULL;
+}
+
 /**
  * @internal
  * Parse the format item and populate key and val with the stringshares that
@@ -3366,7 +3380,7 @@ _format_param_parse(const char *item, const char **key, char **val, Allocator *a
    start++; /* Advance after the '=' */
    /* If we can find a quote as the first non-space char,
     * our new delimiter is a quote, not a space. */
-   while (*start == ' ')
+   while (isspace(*start))
       start++;
 
    if (*start == '\'')
@@ -3378,9 +3392,9 @@ _format_param_parse(const char *item, const char **key, char **val, Allocator *a
      }
    else
      {
-        end = strchr(start, ' ');
+        end = _strchr_whitespace(start);
         while ((end) && (end > start) && (end[-1] == '\\'))
-          end = strchr(end + 1, ' ');
+          end = _strchr_whitespace(end + 1);
      }
 
    /* Null terminate before the spaces */
@@ -3414,7 +3428,7 @@ end:
  * @return the current item parsed from the string.
  */
 static const char *
-_format_parse(const char **s)
+_format_parse(const char **s, Eina_Bool all_whitespaces)
 {
    const char *p;
    const char *s1 = NULL, *s2 = NULL;
@@ -3426,7 +3440,13 @@ _format_parse(const char **s)
      {
         if (!s1)
           {
-             if (*p != ' ') s1 = p;
+             if (all_whitespaces)
+               {
+                  if (!isspace(*p))
+                    s1 = p;
+               }
+             else if(*p != ' ')
+               s1 = p;
              if (*p == 0) break;
           }
         else if (!s2)
@@ -3438,7 +3458,13 @@ _format_parse(const char **s)
 
              if ((p > *s) && (p[-1] != '\\') && (!quote))
                {
-                  if (*p == ' ') s2 = p;
+                  if (all_whitespaces)
+                  {
+                     if (isspace(*p))
+                       s2 = p;
+                  }
+                  else if(*p == ' ')
+                    s2 = p;
                }
              if (*p == 0) s2 = p;
           }
@@ -3474,12 +3500,12 @@ _format_fill(Evas_Object *eo_obj, Evas_Object_Textblock_Format *fmt, const char
    s = str;
 
    /* get rid of any spaces at the start of the string */
-   while (*s == ' ') s++;
+   while (isspace(*s)) s++;
 
    Allocator allocator;
    _allocator_init(&allocator);
 
-   while ((item = _format_parse(&s)))
+   while ((item = _format_parse(&s, EINA_TRUE)))
      {
         const char *key = NULL;
         char *val = NULL;
@@ -5828,7 +5854,7 @@ _layout_do_format(const Evas_Object *obj, Ctxt *c,
           {
              fmt = _layout_format_pop(c, n->orig_format);
           }
-        while ((item = _format_parse(&s)))
+        while ((item = _format_parse(&s, EINA_FALSE)))
           {
              if (_format_is_param(item))
                {
@@ -11041,7 +11067,7 @@ _evas_textblock_format_is_visible(Evas_Object_Textblock_Node_Format *fnode,
         fnode->format_change = EINA_TRUE;
      }
 
-   while ((item = _format_parse(&s)))
+   while ((item = _format_parse(&s, EINA_FALSE)))
      {
         int itlen = s - item;
         /* We care about all of the formats even after a - except for
@@ -17026,7 +17052,7 @@ _evas_textblock_annotations_insert(Eo *eo_obj, Efl_Text_Cursor_Handle *start, Ef
 
    /* Sanitize the string and reject format items, closing '/' marks. */
    buf = eina_strbuf_new();
-   while ((item = _format_parse(&format)))
+   while ((item = _format_parse(&format, EINA_FALSE)))
      {
         int itlen = format - item;
         /* We care about all of the formats even after a - except for
index a4e493a4281b27a798c5131fcfc5c3ac92d63633..4de3477fb2370b6ab4ccc5918a2af3ec559e640a 100644 (file)
@@ -4965,6 +4965,7 @@ EFL_END_TEST
 EFL_START_TEST(efl_text_style)
 {
    START_EFL_CANVAS_TEXTBLOCK_TEST();
+   Eina_Size2D size1, size2;
 
    int changed_emit = 0;
    efl_event_callback_add(txt, EFL_CANVAS_TEXTBLOCK_EVENT_CHANGED, _increment_int_changed, &changed_emit);
@@ -4983,6 +4984,15 @@ EFL_START_TEST(efl_text_style)
    efl_text_markup_set(txt, "");
    ck_assert_int_eq(changed_emit, 2);
 
+   // Style Applying
+   efl_text_set(txt,"A");
+   efl_canvas_textblock_style_apply(txt,"\tfont_size=2\t");
+   size1 = efl_canvas_textblock_size_native_get(txt);
+   efl_canvas_textblock_style_apply(txt,"\nfont_size=20\n");
+   size2 = efl_canvas_textblock_size_native_get(txt);
+   ck_assert(size1.w < size2.w);
+   ck_assert(size1.h < size2.h);
+
    END_EFL_CANVAS_TEXTBLOCK_TEST();
 }
 EFL_END_TEST