summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop/textarea.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/desktop/textarea.c b/desktop/textarea.c
index e614cc435..1dea06361 100644
--- a/desktop/textarea.c
+++ b/desktop/textarea.c
@@ -861,8 +861,8 @@ static bool textarea_reflow_singleline(struct textarea *ta, size_t b_off,
* \param b_start 0-based byte offset in ta->text to start of modification
* \return true on success false otherwise
*/
-static bool textarea_reflow_multiline(struct textarea *ta, const size_t b_start,
- struct rect *r)
+static bool textarea_reflow_multiline(struct textarea *ta,
+ const size_t b_start, const int b_length, struct rect *r)
{
char *text;
unsigned int len;
@@ -876,6 +876,7 @@ static bool textarea_reflow_multiline(struct textarea *ta, const size_t b_start,
int h_extent; /* horizontal extent */
int v_extent; /* vertical extent */
bool restart = false;
+ bool skip_line = false;
assert(ta->flags & TEXTAREA_MULTILINE);
@@ -1101,12 +1102,28 @@ static bool textarea_reflow_multiline(struct textarea *ta, const size_t b_start,
/* Don't need to redraw above changes, so update redraw request rect*/
if (ta->lines[start].b_start + ta->lines[start].b_length < b_start &&
- restart == false)
+ restart == false) {
/* Start line is unchanged */
start++;
+ skip_line = true;
+ }
+
r->y0 = max(r->y0, (signed)(ta->line_height * start +
ta->text_y_offset - ta->scroll_y));
+ /* Reduce redraw region to single line if possible */
+ if ((skip_line || start == 0) &&
+ ta->lines[start].b_start + ta->lines[start].b_length >=
+ b_start + b_length) {
+ text = ta->text.data + ta->lines[start].b_start +
+ ta->lines[start].b_length;
+ if (*text == '\0' || *text == '\n') {
+ r->y1 = min(r->y1, (signed)
+ (ta->line_height * (start + 1) +
+ ta->text_y_offset - ta->scroll_y));
+ }
+ }
+
return true;
}
@@ -1258,7 +1275,7 @@ static bool textarea_insert_text(struct textarea *ta, const char *text,
/* See to reflow */
if (ta->flags & TEXTAREA_MULTILINE) {
- if (!textarea_reflow_multiline(ta, show_b_off, r))
+ if (!textarea_reflow_multiline(ta, show_b_off, b_len, r))
return false;
} else {
if (!textarea_reflow_singleline(ta, show_b_off, r))
@@ -1410,7 +1427,7 @@ static bool textarea_replace_text(struct textarea *ta, size_t b_start,
/* See to reflow */
if (ta->flags & TEXTAREA_MULTILINE) {
- if (!textarea_reflow_multiline(ta, b_start, r))
+ if (!textarea_reflow_multiline(ta, b_start, *byte_delta, r))
return false;
} else {
if (!textarea_reflow_singleline(ta, show_b_off, r))
@@ -1615,7 +1632,7 @@ struct textarea *textarea_create(const textarea_flags flags,
textarea_setup_text_offsets(ret);
if (flags & TEXTAREA_MULTILINE)
- textarea_reflow_multiline(ret, 0, &r);
+ textarea_reflow_multiline(ret, 0, 0, &r);
else
textarea_reflow_singleline(ret, 0, &r);
@@ -1663,7 +1680,7 @@ bool textarea_set_text(struct textarea *ta, const char *text)
textarea_normalise_text(ta, 0, len);
if (ta->flags & TEXTAREA_MULTILINE) {
- if (!textarea_reflow_multiline(ta, 0, &r))
+ if (!textarea_reflow_multiline(ta, 0, len - 1, &r))
return false;
} else {
if (!textarea_reflow_singleline(ta, 0, &r))
@@ -2819,7 +2836,7 @@ void textarea_set_dimensions(struct textarea *ta, int width, int height)
textarea_setup_text_offsets(ta);
if (ta->flags & TEXTAREA_MULTILINE) {
- textarea_reflow_multiline(ta, 0, &r);
+ textarea_reflow_multiline(ta, 0, ta->show->len -1, &r);
} else {
textarea_reflow_singleline(ta, 0, &r);
}
@@ -2842,7 +2859,7 @@ void textarea_set_layout(struct textarea *ta, int width, int height,
textarea_setup_text_offsets(ta);
if (ta->flags & TEXTAREA_MULTILINE) {
- textarea_reflow_multiline(ta, 0, &r);
+ textarea_reflow_multiline(ta, 0, ta->show->len -1, &r);
} else {
textarea_reflow_singleline(ta, 0, &r);
}