summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--desktop/textinput.c47
-rw-r--r--render/box.h10
-rw-r--r--render/box_construct.c7
-rw-r--r--render/html.h2
-rw-r--r--render/html_redraw.c11
-rw-r--r--render/layout.c55
-rw-r--r--render/textplain.c2
7 files changed, 70 insertions, 64 deletions
diff --git a/desktop/textinput.c b/desktop/textinput.c
index 70fdca6c4..be6eb0227 100644
--- a/desktop/textinput.c
+++ b/desktop/textinput.c
@@ -45,7 +45,6 @@
#include "utils/utf8.h"
#include "utils/utils.h"
-
/** ghost caret used to indicate the insertion point when dragging text
into a textarea/input field */
struct caret ghost_caret;
@@ -96,6 +95,8 @@ static bool word_right(const char *text, size_t len, size_t *poffset,
static bool ensure_caret_visible(struct browser_window *bw,
struct box *textarea);
+#define SPACE_LEN(b) ((b->space == 0) ? 0 : 1)
+
/**
* Remove the given text caret from the window by invalidating it
* and causing its former position to be redrawn.
@@ -424,11 +425,11 @@ bool browser_window_textarea_callback(struct browser_window *bw,
selection_clear(bw->sel, false);
if (end_box != text_box ||
- char_offset < text_box->length + text_box->space) {
+ char_offset < text_box->length + SPACE_LEN(text_box)) {
/* there's something at the end of the line to delete */
- textarea_cut(bw, text_box, char_offset,
- end_box, end_box->length + end_box->space,
- false);
+ textarea_cut(bw, text_box, char_offset, end_box,
+ end_box->length + SPACE_LEN(end_box),
+ false);
reflow = true;
break;
}
@@ -753,11 +754,11 @@ bool browser_window_textarea_callback(struct browser_window *bw,
if (reflow)
textarea_reflow(bw, textarea, inline_container);
- if (text_box->length + text_box->space <= char_offset) {
+ if (text_box->length + SPACE_LEN(text_box) <= char_offset) {
if (text_box->next && text_box->next->type == BOX_TEXT) {
/* the text box has been split when reflowing and
the caret is in the second part */
- char_offset -= (text_box->length + text_box->space);
+ char_offset -= (text_box->length + SPACE_LEN(text_box));
text_box = text_box->next;
assert(text_box);
assert(char_offset <= text_box->length);
@@ -771,7 +772,7 @@ bool browser_window_textarea_callback(struct browser_window *bw,
(text_box->next &&
text_box->next->type == BOX_BR));
- char_offset = text_box->length + text_box->space;
+ char_offset = text_box->length + SPACE_LEN(text_box);
}
}
@@ -1376,13 +1377,13 @@ bool browser_window_textarea_paste_text(struct browser_window *bw,
char_offset = textarea->gadget->caret_box_offset;
text_box = textarea->gadget->caret_text_box;
- while ((char_offset > text_box->length + text_box->space) &&
+ while ((char_offset > text_box->length + SPACE_LEN(text_box)) &&
(text_box->next) &&
(text_box->next->type == BOX_TEXT)) {
LOG(("Caret out of range: Was %d in boxlen %d "
"space %d", char_offset,
- text_box->length, text_box->space));
- char_offset -= text_box->length + text_box->space;
+ text_box->length, SPACE_LEN(text_box)));
+ char_offset -= text_box->length + SPACE_LEN(text_box);
text_box = text_box->next;
}
@@ -1716,15 +1717,15 @@ bool textbox_insert(struct browser_window *bw, struct box *text_box,
/* insert in text box */
text = talloc_realloc(current_content, text_box->text,
char,
- text_box->length + text_box->space + utf8_len + 1);
+ text_box->length + SPACE_LEN(text_box) + utf8_len + 1);
if (!text) {
warn_user("NoMemory", 0);
return false;
}
text_box->text = text;
- if (text_box->space &&
- char_offset == text_box->length + text_box->space) {
+ if (text_box->space != 0 &&
+ char_offset == text_box->length + SPACE_LEN(text_box)) {
if (hide)
text_box->space = 0;
else {
@@ -1798,18 +1799,18 @@ bool textbox_delete(struct browser_window *bw, struct box *text_box,
}
/* delete from visible textbox */
- if (next_offset <= text_box->length + text_box->space) {
+ if (next_offset <= text_box->length + SPACE_LEN(text_box)) {
/* handle removal of trailing space */
- if (text_box->space && next_offset > text_box->length) {
+ if (text_box->space != 0 && next_offset > text_box->length) {
if (char_offset > 0) {
/* is the trailing character still a space? */
int tmp = utf8_prev(text_box->text, char_offset);
if (isspace(text_box->text[tmp]))
char_offset = tmp;
else
- text_box->space = false;
+ text_box->space = 0;
} else {
- text_box->space = false;
+ text_box->space = 0;
}
text_box->length = char_offset;
@@ -1846,7 +1847,7 @@ bool textbox_delete(struct browser_window *bw, struct box *text_box,
bool delete_handler(struct browser_window *bw, struct box *b,
int offset, size_t length)
{
- size_t text_length = b->length + b->space;
+ size_t text_length = b->length + SPACE_LEN(b);
/* only remove if its not the first box */
if (offset <= 0 && length >= text_length && b->prev != NULL) {
@@ -2053,21 +2054,23 @@ bool textarea_cut(struct browser_window *bw,
/* append box text to clipboard and then delete it */
if (clipboard &&
!gui_add_to_clipboard(box->text + start_idx,
- box->length - start_idx, box->space)) {
+ box->length - start_idx,
+ SPACE_LEN(box))) {
gui_commit_clipboard();
return false;
}
if (del) {
if (!delete_handler(bw, box, start_idx,
- (box->length + box->space) -
+ (box->length + SPACE_LEN(box)) -
start_idx) && clipboard) {
gui_commit_clipboard();
return false;
}
} else {
textbox_delete(bw, box, start_idx,
- (box->length + box->space) - start_idx);
+ (box->length + SPACE_LEN(box)) -
+ start_idx);
}
}
diff --git a/render/box.h b/render/box.h
index b4151ca3b..e49bfddd7 100644
--- a/render/box.h
+++ b/render/box.h
@@ -101,6 +101,10 @@ struct object_params;
struct object_param;
+#define UNKNOWN_WIDTH INT_MAX
+#define UNKNOWN_MAX_WIDTH INT_MAX
+
+
/** Type of a struct box. */
typedef enum {
BOX_BLOCK, BOX_INLINE_CONTAINER, BOX_INLINE,
@@ -187,8 +191,8 @@ struct box {
char *text; /**< Text, or 0 if none. Unterminated. */
size_t length; /**< Length of text. */
- /** Text is followed by a space. */
- unsigned int space : 1;
+ /** Width of space after current text (depends on font and size). */
+ int space;
/** This box is a continuation of the previous box (eg from line
* breaking). */
unsigned int clone : 1;
@@ -293,8 +297,6 @@ extern const char *TARGET_TOP;
extern const char *TARGET_BLANK;
-#define UNKNOWN_WIDTH INT_MAX
-#define UNKNOWN_MAX_WIDTH INT_MAX
void *box_style_alloc(void *ptr, size_t len, void *pw);
struct box * box_create(css_select_results *styles, css_computed_style *style,
diff --git a/render/box_construct.c b/render/box_construct.c
index 6f91629fd..092edb3ba 100644
--- a/render/box_construct.c
+++ b/render/box_construct.c
@@ -718,7 +718,8 @@ bool box_construct_text(xmlNode *n, struct content *content,
assert((*inline_container)->last != 0);
- (*inline_container)->last->space = 1;
+ (*inline_container)->last->space =
+ UNKNOWN_WIDTH;
}
free(text);
@@ -759,7 +760,7 @@ bool box_construct_text(xmlNode *n, struct content *content,
/* strip ending space char off */
if (box->length > 1 && box->text[box->length - 1] == ' ') {
- box->space = 1;
+ box->space = UNKNOWN_WIDTH;
box->length--;
}
@@ -797,7 +798,7 @@ bool box_construct_text(xmlNode *n, struct content *content,
memmove(box->text, &box->text[1], box->length);
if (box->prev != NULL)
- box->prev->space = 1;
+ box->prev->space = UNKNOWN_WIDTH;
}
} else {
diff --git a/render/html.h b/render/html.h
index ee2f041bf..c06252a4f 100644
--- a/render/html.h
+++ b/render/html.h
@@ -225,7 +225,7 @@ size_t html_selection_drag_end(struct hlcache_handle *h,
browser_mouse_state mouse, int x, int y, int dir);
bool text_redraw(const char *utf8_text, size_t utf8_len,
- size_t offset, bool space,
+ size_t offset, int space,
const plot_font_style_t *fstyle,
int x, int y,
const struct rect *clip,
diff --git a/render/html_redraw.c b/render/html_redraw.c
index 428289efc..75dcf18aa 100644
--- a/render/html_redraw.c
+++ b/render/html_redraw.c
@@ -820,7 +820,7 @@ bool html_redraw_text_box(struct box *box, int x, int y,
* \param utf8_text pointer to UTF-8 text string
* \param utf8_len length of string, in bytes
* \param offset byte offset within textual representation
- * \param space indicates whether string is followed by a space
+ * \param space width of space that follows string (0 = no space)
* \param fstyle text style to use
* \param x x ordinate at which to plot text
* \param y y ordinate at which to plot text
@@ -832,7 +832,7 @@ bool html_redraw_text_box(struct box *box, int x, int y,
*/
bool text_redraw(const char *utf8_text, size_t utf8_len,
- size_t offset, bool space, const plot_font_style_t *fstyle,
+ size_t offset, int space, const plot_font_style_t *fstyle,
int x, int y, const struct rect *clip, int height,
float scale, bool excluded)
{
@@ -891,12 +891,7 @@ bool text_redraw(const char *utf8_text, size_t utf8_len,
/* is there a trailing space that should be highlighted
* as well? */
if (end_idx > utf8_len) {
- int spc_width;
- /* \todo is there a more elegant/efficient
- * solution? */
- if (nsfont.font_width(fstyle, " ", 1,
- &spc_width))
- endx += spc_width;
+ endx += space;
}
if (scale != 1.0) {
diff --git a/render/layout.c b/render/layout.c
index 0a6292e82..3fc94f0c6 100644
--- a/render/layout.c
+++ b/render/layout.c
@@ -1922,6 +1922,11 @@ static bool layout_text_box_split(struct content *content,
struct box *c2;
const struct font_functions *font_func = content->data.html.font_func;
+ if (split_box->space == 0 || split_box->space == UNKNOWN_WIDTH) {
+ font_func->font_width(fstyle, " ", 1, &split_box->space);
+ }
+ space_width = split_box->space;
+
/* Create clone of split_box, c2 */
c2 = talloc_memdup(content, split_box, sizeof *c2);
if (!c2)
@@ -1935,14 +1940,12 @@ static bool layout_text_box_split(struct content *content,
return false;
/* Set c2 according to the remaining text */
- font_func->font_width(fstyle, " ", 1, &space_width);
c2->width -= new_width + space_width;
c2->length = split_box->length - (new_length + 1);
/* Update split_box for its reduced text */
split_box->length = new_length;
split_box->width = new_width;
- split_box->space = 1;
/* Insert c2 into box list */
c2->next = split_box->next;
@@ -2100,13 +2103,13 @@ bool layout_line(struct box *first, int *width, int *y,
}
} else if (b->type == BOX_INLINE_END) {
b->width = 0;
- if (b->space) {
- /** \todo optimize out */
+ if (b->space == UNKNOWN_WIDTH) {
font_func->font_width(&fstyle, " ", 1,
- &space_after);
- } else {
- space_after = 0;
+ &b->space);
+ /** \todo handle errors */
}
+ space_after = b->space;
+
x += b->padding[RIGHT] + b->border[RIGHT].width +
b->margin[RIGHT];
continue;
@@ -2153,18 +2156,17 @@ bool layout_line(struct box *first, int *width, int *y,
b->width += SCROLLBAR_WIDTH;
} else {
font_func->font_width(&fstyle, b->text,
- b->length, &b->width);
+ b->length, &b->width);
}
}
x += b->width;
- if (b->space)
- /** \todo optimize out */
+ if (b->space == UNKNOWN_WIDTH) {
font_func->font_width(&fstyle, " ", 1,
- &space_after);
- else
- space_after = 0;
-
+ &b->space);
+ /** \todo handle errors */
+ }
+ space_after = b->space;
continue;
}
@@ -2285,16 +2287,17 @@ bool layout_line(struct box *first, int *width, int *y,
if (b->object)
space_after = 0;
else if (b->text || b->type == BOX_INLINE_END) {
- space_after = 0;
- if (b->space) {
+ if (b->space == UNKNOWN_WIDTH) {
font_plot_style_from_css(b->style,
&fstyle);
- /** \todo handle errors, optimize */
+ /** \todo handle errors */
font_func->font_width(&fstyle, " ", 1,
- &space_after);
+ &b->space);
}
- } else
+ space_after = b->space;
+ } else {
space_after = 0;
+ }
split_box = b;
move_y = true;
inline_count++;
@@ -2726,9 +2729,10 @@ struct box *layout_minmax_line(struct box *first,
&fixed, &frac);
if (0 < fixed)
max += fixed;
- if (b->next && b->space) {
- font_func->font_width(&fstyle, " ", 1, &width);
- max += width;
+ if (b->next && b->space == UNKNOWN_WIDTH) {
+ font_func->font_width(&fstyle, " ", 1,
+ &b->space);
+ max += b->space;
}
continue;
}
@@ -2772,9 +2776,10 @@ struct box *layout_minmax_line(struct box *first,
}
}
max += b->width;
- if (b->next && b->space) {
- font_func->font_width(&fstyle, " ", 1, &width);
- max += width;
+ if (b->next && b->space == UNKNOWN_WIDTH) {
+ font_func->font_width(&fstyle, " ", 1,
+ &b->space);
+ max += b->space;
}
/* min = widest word */
diff --git a/render/textplain.c b/render/textplain.c
index 0879841fe..3a3ffd184 100644
--- a/render/textplain.c
+++ b/render/textplain.c
@@ -612,7 +612,7 @@ bool textplain_redraw(struct content *c, int x, int y,
next_offset = utf8_next(text, length, next_offset);
if (!text_redraw(text + offset, next_offset - offset,
- line[lineno].start + offset, false,
+ line[lineno].start + offset, 0,
&textplain_style,
tx, y + (lineno * scaled_line_height),
clip, line_height, scale, false))