From 70fbca36060e2c358a6dc54da853ba6d5ec8724d Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Fri, 22 Mar 2013 18:01:02 +0000 Subject: Reduce redraw area for selection set/change/clear. --- desktop/textarea.c | 50 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 11 deletions(-) (limited to 'desktop') diff --git a/desktop/textarea.c b/desktop/textarea.c index 2ba1c53cc..15d35e1e5 100644 --- a/desktop/textarea.c +++ b/desktop/textarea.c @@ -459,7 +459,6 @@ static bool textarea_select(struct textarea *ta, int b_start, int b_end, int swap; bool pre_existing_selection = (ta->sel_start != -1); struct textarea_msg msg; - int line_start = 0, line_end = 0; if (b_start == b_end) { textarea_clear_selection(ta); @@ -483,18 +482,29 @@ static bool textarea_select(struct textarea *ta, int b_start, int b_end, msg.data.redraw.x1 = ta->vis_width - ta->border_width - ((ta->bar_y == NULL) ? 0 : SCROLLBAR_WIDTH); - if (force_redraw || !pre_existing_selection || - (ta->sel_start != b_start && ta->sel_end != b_end)) { - /* Asked to redraw everything, or there's a new selection, or - * both ends of the selection have moved */ + if (force_redraw) { + /* Asked to redraw everything */ msg.data.redraw.y0 = ta->border_width; msg.data.redraw.y1 = ta->vis_height - ta->border_width - ((ta->bar_x == NULL) ? 0 : SCROLLBAR_WIDTH); } else { - /* Redraw to cover change in selection start or change in - * selection end */ + /* Try to minimise redraw region */ unsigned int b_low, b_high; - if (ta->sel_start != b_start) { + int line_start = 0, line_end = 0; + + if (!pre_existing_selection) { + /* There's a new selection */ + b_low = b_start; + b_high = b_end; + + } else if (ta->sel_start != b_start && ta->sel_end != b_end) { + /* Both ends of the selection have moved */ + b_low = (ta->sel_start < b_start) ? + ta->sel_start : b_start; + b_high = (ta->sel_end > b_end) ? + ta->sel_end : b_end; + + } else if (ta->sel_start != b_start) { /* Selection start changed */ if ((signed)ta->sel_start < b_start) { b_low = ta->sel_start; @@ -503,6 +513,7 @@ static bool textarea_select(struct textarea *ta, int b_start, int b_end, b_low = b_start; b_high = ta->sel_start; } + } else { /* Selection end changed */ if ((signed)ta->sel_end < b_end) { @@ -514,6 +525,7 @@ static bool textarea_select(struct textarea *ta, int b_start, int b_end, } } + /* Find redraw start/end lines */ for (line_end = 0; line_end < ta->line_count - 1; line_end++) if (ta->lines[line_end + 1].b_start > b_low) { line_start = line_end; @@ -523,6 +535,7 @@ static bool textarea_select(struct textarea *ta, int b_start, int b_end, if (ta->lines[line_end + 1].b_start > b_high) break; + /* Set vertical redraw range */ msg.data.redraw.y0 = max(ta->border_width, ta->line_height * line_start + ta->text_y_offset - ta->scroll_y); @@ -2677,22 +2690,37 @@ textarea_mouse_status textarea_mouse_action(struct textarea *ta, bool textarea_clear_selection(struct textarea *ta) { struct textarea_msg msg; + int line_end, line_start = 0; if (ta->sel_start == -1) /* No selection to clear */ return false; + /* Find selection start & end lines */ + for (line_end = 0; line_end < ta->line_count - 1; line_end++) + if (ta->lines[line_end + 1].b_start > (unsigned)ta->sel_start) { + line_start = line_end; + break; + } + for (; line_end < ta->line_count - 1; line_end++) + if (ta->lines[line_end + 1].b_start > (unsigned)ta->sel_end) + break; + /* Clear selection and redraw */ ta->sel_start = ta->sel_end = -1; msg.ta = ta; msg.type = TEXTAREA_MSG_REDRAW_REQUEST; msg.data.redraw.x0 = ta->border_width; - msg.data.redraw.y0 = ta->border_width; + msg.data.redraw.y0 = max(ta->border_width, + ta->line_height * line_start + + ta->text_y_offset - ta->scroll_y); msg.data.redraw.x1 = ta->vis_width - ta->border_width - ((ta->bar_y == NULL) ? 0 : SCROLLBAR_WIDTH); - msg.data.redraw.y1 = ta->vis_height - ta->border_width - - ((ta->bar_x == NULL) ? 0 : SCROLLBAR_WIDTH); + msg.data.redraw.y1 = min(ta->vis_height - ta->border_width - + ((ta->bar_x == NULL) ? 0 : SCROLLBAR_WIDTH), + ta->line_height * line_end + ta->text_y_offset + + ta->line_height - ta->scroll_y); ta->callback(ta->data, &msg); -- cgit v1.2.3