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, ®ion_y, NULL, ®ion_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); --
