summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
authorMichael Drake <tlsa@netsurf-browser.org>2013-03-19 16:22:24 +0000
committerMichael Drake <tlsa@netsurf-browser.org>2013-03-19 16:22:24 +0000
commit2ad0d239152b3c0b5f9c309a6157671b7f62df25 (patch)
treec2b830544cef23b407284573c00270e9b98dcf57 /desktop
parentf4ce62ebfe56283763533f1b778cee074ee6f372 (diff)
downloadnetsurf-2ad0d239152b3c0b5f9c309a6157671b7f62df25.tar.gz
netsurf-2ad0d239152b3c0b5f9c309a6157671b7f62df25.tar.bz2
Start reducing unnecessary redraws: when only start OR end of selection has changed, only redraw the lines affected. (Reduces redraw of vertical regions only. Still redraw full width for changed lines.)
Diffstat (limited to 'desktop')
-rw-r--r--desktop/textarea.c61
1 files changed, 54 insertions, 7 deletions
diff --git a/desktop/textarea.c b/desktop/textarea.c
index 06b5ea356..b0efd66d0 100644
--- a/desktop/textarea.c
+++ b/desktop/textarea.c
@@ -461,6 +461,7 @@ 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);
@@ -478,18 +479,64 @@ static bool textarea_select(struct textarea *ta, int b_start, int b_end,
!force_redraw)
return true;
- ta->sel_start = b_start;
- ta->sel_end = b_end;
-
msg.ta = ta;
msg.type = TEXTAREA_MSG_REDRAW_REQUEST;
- msg.data.redraw.x0 = 0;
- msg.data.redraw.y0 = 0;
- msg.data.redraw.x1 = ta->vis_width;
- msg.data.redraw.y1 = ta->vis_height;
+
+ 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 */
+ msg.data.redraw.x0 = 0;
+ msg.data.redraw.y0 = 0;
+ msg.data.redraw.x1 = ta->vis_width;
+ msg.data.redraw.y1 = ta->vis_height;
+ } else {
+ /* Redraw to cover change in selection start or change in
+ * selection end */
+ int b_low, b_high;
+ if (ta->sel_start != b_start) {
+ /* Selection start changed */
+ if (ta->sel_start < b_start) {
+ b_low = ta->sel_start;
+ b_high = b_start;
+ } else {
+ b_low = b_start;
+ b_high = ta->sel_start;
+ }
+ } else {
+ /* Selection end changed */
+ if (ta->sel_end < b_end) {
+ b_low = ta->sel_end;
+ b_high = b_end;
+ } else {
+ b_low = b_end;
+ b_high = ta->sel_end;
+ }
+ }
+
+ 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;
+ break;
+ }
+ for (; line_end < ta->line_count - 1; line_end++)
+ if (ta->lines[line_end + 1].b_start > b_high)
+ break;
+
+ msg.data.redraw.x0 = 0;
+ msg.data.redraw.y0 = max(0, ta->line_height * line_start +
+ ta->text_y_offset - ta->scroll_y);
+ msg.data.redraw.x1 = ta->vis_width;
+ msg.data.redraw.y1 = min(ta->vis_height,
+ ta->line_height * line_end + ta->text_y_offset +
+ ta->line_height - ta->scroll_y);
+ }
ta->callback(ta->data, &msg);
+ ta->sel_start = b_start;
+ ta->sel_end = b_end;
+
if (!pre_existing_selection && ta->sel_start != -1) {
/* Didn't have a selection before, but do now */
msg.type = TEXTAREA_MSG_SELECTION_REPORT;