hermet pushed a commit to branch master.

http://git.enlightenment.org/tools/enventor.git/commit/?id=6104c3cd7fac4dc7f63fb148ca1d07a3e84913c8

commit 6104c3cd7fac4dc7f63fb148ca1d07a3e84913c8
Author: ChunEon Park <[email protected]>
Date:   Mon May 26 23:35:57 2014 +0900

    syntax_color: apply syntax_color on only visible text region.
    
    it's really faster than before while editing large text.
---
 src/bin/edc_editor.c       | 86 ++++++++++++++++++++++++++++++++++++--------
 src/bin/main.c             |  6 ++--
 src/bin/syntax_color.c     | 88 +++++++++++++++++++++++++++++++---------------
 src/include/edc_editor.h   |  2 +-
 src/include/edc_parser.h   |  2 ++
 src/include/syntax_color.h |  4 +--
 6 files changed, 140 insertions(+), 48 deletions(-)

diff --git a/src/bin/edc_editor.c b/src/bin/edc_editor.c
index a043fe8..2e16fd2 100644
--- a/src/bin/edc_editor.c
+++ b/src/bin/edc_editor.c
@@ -4,7 +4,9 @@
 
 //FIXME: Make flexible
 const int MAX_LINE_DIGIT_CNT = 10;
-const double SYNTAX_COLOR_TIME = 0.25;
+const int SYNTAX_COLOR_SPARE_LINES = 25;
+const double SYNTAX_COLOR_DEFAULT_TIME = 0.25;
+const double SYNTAX_COLOR_SHORT_TIME = 0.025;
 
 struct editor_s
 {
@@ -19,6 +21,7 @@ struct editor_s
 
    int cur_line;
    int line_max;
+   Evas_Coord scroller_h;
 
    Ecore_Timer *syntax_color_timer;
 
@@ -80,23 +83,52 @@ line_decrease(edit_data *ed, int cnt)
 }
 
 static void
+current_visible_text_region_get(edit_data *ed, int *from_line, int *to_line)
+{
+   Evas_Coord region_y, region_h;
+   Evas_Coord cursor_h;
+
+   elm_scroller_region_get(ed->scroller, NULL, &region_y, NULL, &region_h);
+   elm_entry_cursor_geometry_get(ed->en_edit, NULL, NULL, NULL, &cursor_h);
+
+   int from = (region_y / cursor_h) - SYNTAX_COLOR_SPARE_LINES;
+   int to = from + (region_h / cursor_h) + SYNTAX_COLOR_SPARE_LINES;
+   from -= SYNTAX_COLOR_SPARE_LINES;
+   to += SYNTAX_COLOR_SPARE_LINES;
+
+   if (from < 1) from = 1;
+   if (to > ed->line_max) to = ed->line_max;
+
+   *from_line = from;
+   *to_line = to;
+}
+
+static void
 syntax_color_apply(edit_data *ed)
 {
-   //FIXME: Optimize here by applying color syntax for only changed lines 
-   char *text = (char *) elm_entry_entry_get(ed->en_edit);
+   Evas_Object *tb = elm_entry_textblock_get(ed->en_edit);
+   char *text = (char *) evas_object_textblock_text_markup_get(tb);
    int pos = elm_entry_cursor_pos_get(ed->en_edit);
+
+   int from_line, to_line;
+   current_visible_text_region_get(ed, &from_line, &to_line);
+
+   char *from, *to;
    char *utf8 = (char *) color_cancel(syntax_color_data_get(ed->sh), text,
-                                      strlen(text));
+                                      strlen(text), from_line, to_line, &from,
+                                      &to);
    if (!utf8) return;
+
    const char *translated = color_apply(syntax_color_data_get(ed->sh), utf8,
-                                        strlen(utf8));
+                                        strlen(utf8), from, to);
+   if (!translated) return;
 
    /* I'm not sure this will be problem.
       But it can avoid entry_object_text_escaped_set() in Edje.
       Logically that's unnecessary in this case. */
-   Evas_Object *tb = elm_entry_textblock_get(ed->en_edit);
    evas_object_textblock_text_markup_set(tb, translated);
    elm_entry_calc_force(ed->en_edit);
+   elm_entry_cursor_pos_set(ed->en_edit, 0);
    elm_entry_cursor_pos_set(ed->en_edit, pos);
    //FIXME: Need to recover selection area.
 }
@@ -112,11 +144,10 @@ syntax_color_timer_cb(void *data)
 }
 
 static void
-syntax_color_timer_update(edit_data *ed)
+syntax_color_timer_update(edit_data *ed, double time)
 {
    ecore_timer_del(ed->syntax_color_timer);
-   ed->syntax_color_timer = ecore_timer_add(SYNTAX_COLOR_TIME,
-                                            syntax_color_timer_cb, ed);
+   ed->syntax_color_timer = ecore_timer_add(time, syntax_color_timer_cb, ed);
 }
 
 static void
@@ -164,7 +195,7 @@ edit_changed_cb(void *data, Evas_Object *obj EINA_UNUSED, 
void *event_info)
       right after applying syntax color. This workaround makes avoid to not
       applying syntax color while entry has the selected text. */
    if (elm_entry_selection_get(ed->en_edit)) return;
-   syntax_color_timer_update(ed);
+   syntax_color_timer_update(ed, SYNTAX_COLOR_DEFAULT_TIME);
 }
 
 static void
@@ -317,7 +348,7 @@ edit_template_insert(edit_data *ed)
 
    elm_entry_cursor_pos_set(ed->en_edit, cursor_pos);
 
-   syntax_color_timer_update(ed);
+   syntax_color_timer_update(ed, 0);
    snprintf(buf, sizeof(buf), "Template code inserted. (%s)", buf2);
    stats_info_msg_update(buf);
 }
@@ -397,7 +428,7 @@ edit_template_part_insert(edit_data *ed, Edje_Part_Type 
type)
 
    elm_entry_cursor_pos_set(ed->en_edit, cursor_pos);
 
-   syntax_color_timer_update(ed);
+   syntax_color_timer_update(ed, SYNTAX_COLOR_SHORT_TIME);
    snprintf(buf, sizeof(buf), "Template code inserted. (%s Part)", part);
    stats_info_msg_update(buf);
 }
@@ -741,6 +772,25 @@ key_up_cb(void *data, int type EINA_UNUSED, void *ev)
    return ECORE_CALLBACK_PASS_ON;
 }
 
+static void
+scroller_scroll_cb(void *data, Evas_Object *obj, void *event_info)
+{
+   edit_data *ed = data;
+   syntax_color_timer_update(ed, SYNTAX_COLOR_SHORT_TIME);
+}
+
+static void
+scroller_resize_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+   edit_data *ed = data;
+   Evas_Coord h;
+   evas_object_geometry_get(obj, NULL, NULL, NULL, &h);
+
+   if (h == ed->scroller_h) return;
+   syntax_color_timer_update(ed, SYNTAX_COLOR_SHORT_TIME);
+   ed->scroller_h = h;
+}
+
 edit_data *
 edit_init(Evas_Object *parent)
 {
@@ -759,6 +809,12 @@ edit_init(Evas_Object *parent)
    elm_scroller_policy_set(scroller, ELM_SCROLLER_POLICY_AUTO,
                            ELM_SCROLLER_POLICY_AUTO);
    elm_object_focus_allow_set(scroller, EINA_FALSE);
+   evas_object_smart_callback_add(scroller, "scroll,up", scroller_scroll_cb,
+                                  ed);
+   evas_object_smart_callback_add(scroller, "scroll,down", scroller_scroll_cb,
+                                  ed);
+   evas_object_event_callback_add(scroller, EVAS_CALLBACK_RESIZE,
+                                  scroller_resize_cb, ed);
    evas_object_size_hint_weight_set(scroller, EVAS_HINT_EXPAND,
                                     EVAS_HINT_EXPAND);
    evas_object_size_hint_align_set(scroller, EVAS_HINT_FILL, EVAS_HINT_FILL);
@@ -811,7 +867,7 @@ edit_init(Evas_Object *parent)
    ed->cur_line = -1;
 
    edit_line_number_toggle(ed);
-   edit_font_size_update(ed, EINA_FALSE);
+   edit_font_size_update(ed, EINA_FALSE, EINA_FALSE);
 
    return ed;
 }
@@ -960,7 +1016,7 @@ edit_new(edit_data *ed)
 }
 
 void
-edit_font_size_update(edit_data *ed, Eina_Bool msg)
+edit_font_size_update(edit_data *ed, Eina_Bool msg, Eina_Bool update)
 {
    elm_object_scale_set(ed->layout, config_font_size_get());
 
@@ -969,6 +1025,8 @@ edit_font_size_update(edit_data *ed, Eina_Bool msg)
    char buf[128];
    snprintf(buf, sizeof(buf), "Font Size: %1.1fx", config_font_size_get());
    stats_info_msg_update(buf);
+
+   if (update) syntax_color_timer_update(ed, 0);
 }
 
 void
diff --git a/src/bin/main.c b/src/bin/main.c
index 2b385d7..3d83559 100644
--- a/src/bin/main.c
+++ b/src/bin/main.c
@@ -305,12 +305,12 @@ main_mouse_wheel_cb(void *data, int type EINA_UNUSED, 
void *ev)
         if (event->z < 0)
           {
              config_font_size_set(config_font_size_get() + 0.1f);
-             edit_font_size_update(ad->ed, EINA_TRUE);
+             edit_font_size_update(ad->ed, EINA_TRUE, EINA_TRUE);
           }
         else
           {
              config_font_size_set(config_font_size_get() - 0.1f);
-             edit_font_size_update(ad->ed, EINA_TRUE);
+             edit_font_size_update(ad->ed, EINA_TRUE, EINA_TRUE);
           }
 
         return ECORE_CALLBACK_PASS_ON;
@@ -365,7 +365,7 @@ config_update_cb(void *data)
    app_data *ad = data;
    build_cmd_set();
    edit_line_number_toggle(ad->ed);
-   edit_font_size_update(ad->ed, EINA_FALSE);
+   edit_font_size_update(ad->ed, EINA_FALSE, EINA_TRUE);
 
    base_tools_toggle(EINA_FALSE);
    base_statusbar_toggle(EINA_FALSE);
diff --git a/src/bin/syntax_color.c b/src/bin/syntax_color.c
index cc52d5b..45a829b 100644
--- a/src/bin/syntax_color.c
+++ b/src/bin/syntax_color.c
@@ -281,10 +281,9 @@ static int
 tab_skip(Eina_Strbuf *strbuf, const char **src, int length, char **cur,
         char **prev)
 {
-   int cmp_size = 6;    //strlen("<tab/>");
-   if (strncmp(*cur, "<tab/>", cmp_size)) return 0;
-   eina_strbuf_append_length(strbuf, *prev, (*cur - *prev + cmp_size));
-   *cur += cmp_size;
+   if (strncmp(*cur, TAB, TAB_LEN)) return 0;
+   eina_strbuf_append_length(strbuf, *prev, (*cur - *prev + TAB_LEN));
+   *cur += TAB_LEN;
    if (*cur > (*src + length)) return -1;
    *prev = *cur;
 
@@ -532,7 +531,8 @@ nospace:
 }
 
 const char *
-color_cancel(color_data *cd, const char *src, int length)
+color_cancel(color_data *cd, const char *src, int length, int from_pos,
+             int to_pos, char **from, char **to)
 {
    if (!src || length < 1) return NULL;
    Eina_Strbuf *strbuf = cd->strbuf;
@@ -541,14 +541,31 @@ color_cancel(color_data *cd, const char *src, int length)
    const char *str = NULL;
    char *prev = (char *) src;
    char *cur = (char *) src;
+   int line = 1;
+   Eina_Bool find_from = EINA_TRUE;
+   Eina_Bool find_to = EINA_TRUE;
 
    while (cur && (cur <= (src + length)))
      {
+        if (find_from && (line == from_pos))
+          {
+             from_pos = eina_strbuf_length_get(strbuf);
+             find_from = EINA_FALSE;
+          }
+        if (find_to && (line == to_pos))
+          {
+             to_pos = eina_strbuf_length_get(strbuf);
+             find_to = EINA_FALSE;
+          }
+
         //escape EOL: <br/>
         if (br_skip(strbuf, &src, length, &cur, &prev) == 1)
-          continue;
+        {
+           line++;
+           continue;
+        }
 
-        //escape EOL: <tab/>
+        //escape TAB: <tab/>
         if (tab_skip(strbuf, &src, length, &cur, &prev) == 1)
           continue;
 
@@ -569,6 +586,14 @@ color_cancel(color_data *cd, const char *src, int length)
         if (prev + 1 < cur) eina_strbuf_append(strbuf, prev);
         str = eina_strbuf_string_get(strbuf);
      }
+
+   //Exceptional Handling
+   if (find_from) from_pos = 0;
+   if (find_to) to_pos = eina_strbuf_length_get(strbuf);
+
+   *from = ((char *) str) + from_pos;
+   *to = ((char *) str) + to_pos;
+
    return str;
 }
 
@@ -659,17 +684,14 @@ color_markup_insert(Eina_Strbuf *strbuf, const char 
**src, int length, char **cu
    return 0;
 }
 
-/* 
-       OPTIMIZATION POINT 
-       1. Apply Color only changed line.
-*/
 const char *
-color_apply(color_data *cd, const char *src, int length)
+color_apply(color_data *cd, const char *src, int length, char *from, char *to)
 {
    Eina_Bool inside_string = EINA_FALSE;
    Eina_Bool inside_comment = EINA_FALSE;
 
    if (!src || (length < 1)) return NULL;
+   if (from == to) return NULL;
 
    Eina_Strbuf *strbuf = cd->cachebuf;
    eina_strbuf_reset(strbuf);
@@ -682,15 +704,18 @@ color_apply(color_data *cd, const char *src, int length)
    while (cur && (cur <= (src + length)))
      {
         //escape empty string
-        if (cur[0] == ' ')
+        if (cur >= from)
           {
-             if (cur > prev)
-               eina_strbuf_append_length(strbuf, prev, (cur - prev) + 1);
-             else
-               eina_strbuf_append_char(strbuf, ' ');
-             ++cur;
-             prev = cur;
-             continue;
+             if (cur[0] == ' ')
+               {
+                  if (cur > prev)
+                    eina_strbuf_append_length(strbuf, prev, (cur - prev) + 1);
+                  else
+                    eina_strbuf_append_char(strbuf, ' ');
+                  ++cur;
+                  prev = cur;
+                  continue;
+               }
           }
 
         //handle comment: /* ~ */
@@ -700,10 +725,13 @@ color_apply(color_data *cd, const char *src, int length)
         else if (ret == -1) goto finished;
 
         //handle comment: //
-        ret = comment2_apply(strbuf, &src, length, &cur, &prev, 
cd->col_comment,
-                             &inside_comment);
-        if (ret == 1) continue;
-        else if (ret == -1) goto finished;
+        if (cur >= from)
+          {
+             ret = comment2_apply(strbuf, &src, length, &cur, &prev,
+                                  cd->col_comment, &inside_comment);
+             if (ret == 1) continue;
+             else if (ret == -1) goto finished;
+          }
 
         //escape string: " ~ "
         ret = string_apply(strbuf, &cur, &prev, cd->col_string, inside_string);
@@ -724,11 +752,15 @@ color_apply(color_data *cd, const char *src, int length)
         if (ret == 1) continue;
 
         //apply color markup
-        ret = color_markup_insert(strbuf, &src, length, &cur, &prev, cd);
-        if (ret == 1) continue;
-        else if (ret == -1) goto finished;
+        if (cur >= from)
+          {
+             ret = color_markup_insert(strbuf, &src, length, &cur, &prev, cd);
+             if (ret == 1) continue;
+             else if (ret == -1) goto finished;
+          }
 
         cur++;
+        if (cur > to) goto finished;
      }
 
    //Same with origin source.
@@ -739,7 +771,7 @@ color_apply(color_data *cd, const char *src, int length)
      {
 finished:
         //append leftovers.
-        if (prev + 1 < cur) eina_strbuf_append(strbuf, prev);
+        if (prev < cur) eina_strbuf_append(strbuf, prev);
         str = eina_strbuf_string_get(strbuf);
      }
 
diff --git a/src/include/edc_editor.h b/src/include/edc_editor.h
index 075942f..314b7f8 100644
--- a/src/include/edc_editor.h
+++ b/src/include/edc_editor.h
@@ -11,7 +11,7 @@ Eina_Bool edit_save(edit_data *ed);
 void edit_new(edit_data* ed);
 void edit_view_sync_cb_set(edit_data *ed, void (*cb)(void *data, 
Eina_Stringshare *part_name, Eina_Stringshare *group_name), void *data);
 void edit_view_sync(edit_data *ed);
-void edit_font_size_update(edit_data *ed, Eina_Bool msg);
+void edit_font_size_update(edit_data *ed, Eina_Bool msg, Eina_Bool update);
 void edit_template_insert(edit_data *ed);
 void edit_template_part_insert(edit_data *ed, Edje_Part_Type type);
 void edit_part_highlight_toggle(edit_data *ed, Eina_Bool msg);
diff --git a/src/include/edc_parser.h b/src/include/edc_parser.h
index 272deee..fa238a8 100644
--- a/src/include/edc_parser.h
+++ b/src/include/edc_parser.h
@@ -3,6 +3,8 @@
 #define QUOT_LEN 1
 #define EOL "<br/>"
 #define EOL_LEN 5
+#define TAB "<tab/>"
+#define TAB_LEN 6
 
 parser_data *parser_init();
 void parser_term(parser_data *pd);
diff --git a/src/include/syntax_color.h b/src/include/syntax_color.h
index fca917b..2125cbc 100644
--- a/src/include/syntax_color.h
+++ b/src/include/syntax_color.h
@@ -1,6 +1,6 @@
 color_data *color_init(Eina_Strbuf *strbuf);
 void color_term(color_data *cd);
-const char *color_cancel(color_data *cd, const char *str, int length);
-const char *color_apply(color_data *cd, const char *str, int length);
+const char *color_cancel(color_data *cd, const char *str, int length, int 
from_pos, int to_pos, char **from, char **to);
+const char *color_apply(color_data *cd, const char *str, int length, char 
*from, char *to);
 Eina_Bool color_ready(color_data *cd);
 

-- 


Reply via email to