diff options
author | Vincent Sanders <vince@kyllikki.org> | 2020-05-23 20:38:41 +0100 |
---|---|---|
committer | Vincent Sanders <vince@kyllikki.org> | 2020-05-23 23:00:08 +0100 |
commit | e65e41e2d6efccba983cd63aadfb10b5b4a935b2 (patch) | |
tree | 3833ea9b7bb989fd5c96d5d230b66b6d29a59794 /desktop | |
parent | 36b9262e1481fc24d302b58f03006e733b2e6d16 (diff) | |
download | netsurf-e65e41e2d6efccba983cd63aadfb10b5b4a935b2.tar.gz netsurf-e65e41e2d6efccba983cd63aadfb10b5b4a935b2.tar.bz2 |
move content handler specific selection copying into handlers
Diffstat (limited to 'desktop')
-rw-r--r-- | desktop/selection.c | 314 | ||||
-rw-r--r-- | desktop/selection.h | 9 |
2 files changed, 22 insertions, 301 deletions
diff --git a/desktop/selection.c b/desktop/selection.c index 11cd1fb06..d4fa7ca7d 100644 --- a/desktop/selection.c +++ b/desktop/selection.c @@ -57,11 +57,6 @@ #define SPACE_LEN(b) ((b->space == 0) ? 0 : 1) -struct rdw_info { - bool inited; - struct rect r; -}; - struct selection_string { char *buffer; size_t buffer_len; @@ -72,15 +67,6 @@ struct selection_string { }; -typedef bool (*seln_traverse_handler)(const char *text, - size_t length, - struct box *box, - const nscss_len_ctx *len_ctx, - void *handle, - const char *whitespace_text, - size_t whitespace_length); - - /** * Label each text box in the given box subtree with its position * in a textual representation of the content. @@ -113,206 +99,6 @@ static unsigned selection_label_subtree(struct box *box, unsigned idx) /** - * Tests whether a text box lies partially within the given range of - * byte offsets, returning the start and end indexes of the bytes - * that are enclosed. - * - * \param box box to be tested - * \param start_idx byte offset of start of range - * \param end_idx byte offset of end of range - * \param start_offset receives the start offset of the selected part - * \param end_offset receives the end offset of the selected part - * \return true iff the range encloses at least part of the box - */ -static bool -selected_part(struct box *box, - unsigned start_idx, - unsigned end_idx, - unsigned *start_offset, - unsigned *end_offset) -{ - size_t box_length = box->length + SPACE_LEN(box); - - if (box_length > 0) { - if ((box->byte_offset >= start_idx) && - (box->byte_offset + box_length <= end_idx)) { - - /* fully enclosed */ - *start_offset = 0; - *end_offset = box_length; - return true; - } else if ((box->byte_offset + box_length > start_idx) && - (box->byte_offset < end_idx)) { - /* partly enclosed */ - int offset = 0; - int len; - - if (box->byte_offset < start_idx) { - offset = start_idx - box->byte_offset; - } - - len = box_length - offset; - - if (box->byte_offset + box_length > end_idx) { - len = end_idx - (box->byte_offset + offset); - } - - *start_offset = offset; - *end_offset = offset + len; - - return true; - } - } - return false; -} - - -/** - * Traverse the given box subtree, calling the handler function (with - * its handle) for all boxes that lie (partially) within the given - * range - * - * \param box box subtree - * \param len_ctx Length conversion context. - * \param start_idx start of range within textual representation (bytes) - * \param end_idx end of range - * \param handler handler function to call - * \param handle handle to pass - * \param before type of whitespace to place before next encountered text - * \param first whether this is the first box with text - * \param do_marker whether deal enter any marker box - * \return false iff traversal abandoned part-way through - */ -static bool -traverse_tree(struct box *box, - const nscss_len_ctx *len_ctx, - unsigned start_idx, - unsigned end_idx, - seln_traverse_handler handler, - void *handle, - save_text_whitespace *before, - bool *first, - bool do_marker) -{ - struct box *child; - const char *whitespace_text = ""; - size_t whitespace_length = 0; - - assert(box); - - /* If selection starts inside marker */ - if (box->parent && - box->parent->list_marker == box && - !do_marker) { - /* set box to main list element */ - box = box->parent; - } - - /* If box has a list marker */ - if (box->list_marker) { - /* do the marker box before continuing with the rest of the - * list element */ - if (!traverse_tree(box->list_marker, - len_ctx, - start_idx, - end_idx, - handler, - handle, - before, - first, - true)) { - return false; - } - } - - /* we can prune this subtree, it's after the selection */ - if (box->byte_offset >= end_idx) { - return true; - } - - /* read before calling the handler in case it modifies the tree */ - child = box->children; - - /* If nicely formatted output of the selected text is required, work - * out what whitespace should be placed before the next bit of text */ - if (before) { - save_text_solve_whitespace(box, - first, - before, - &whitespace_text, - &whitespace_length); - } else { - whitespace_text = NULL; - } - - if ((box->type != BOX_BR) && - !((box->type == BOX_FLOAT_LEFT || - box->type == BOX_FLOAT_RIGHT) && - !box->text)) { - unsigned start_offset; - unsigned end_offset; - - if (selected_part(box, - start_idx, - end_idx, - &start_offset, - &end_offset)) { - if (!handler(box->text + start_offset, - min(box->length, end_offset) - start_offset, - box, - len_ctx, - handle, - whitespace_text, - whitespace_length)) { - return false; - } - if (before) { - *first = false; - *before = WHITESPACE_NONE; - } - } - } - - /* find the first child that could lie partially within the selection; - * this is important at the top-levels of the tree for pruning subtrees - * that lie entirely before the selection */ - - if (child) { - struct box *next = child->next; - - while (next && next->byte_offset < start_idx) { - child = next; - next = child->next; - } - - while (child) { - /* read before calling the handler in case it modifies - * the tree */ - struct box *next = child->next; - - if (!traverse_tree(child, - len_ctx, - start_idx, - end_idx, - handler, - handle, - before, - first, - false)) { - return false; - } - - child = next; - } - } - - return true; -} - - - - -/** * Redraws the given range of text. * * \param s selection object @@ -404,35 +190,22 @@ static void selection_set_end(struct selection *s, unsigned offset) * \return false iff traversal abandoned part-way through */ static bool -selection_traverse(struct selection *s, - seln_traverse_handler handler, - void *handle) +selection_copy(struct selection *s, struct selection_string *selstr) { - save_text_whitespace before = WHITESPACE_NONE; - bool first = true; - const char *text; - size_t length; - - if (!s->defined) { - return true; /* easy case, nothing to do */ - } + nserror res; - if (s->root) { - /* HTML */ - return traverse_tree(s->root, &s->len_ctx, - s->start_idx, s->end_idx, - handler, handle, - &before, &first, false); + if (s->c->handler->textselection_copy != NULL) { + res = s->c->handler->textselection_copy(s->c, + s->start_idx, + s->end_idx, + selstr); + } else { + res = NSERROR_NOT_IMPLEMENTED; } - /* Text */ - text = textplain_get_raw_data(s->c, s->start_idx, s->end_idx, &length); - - if (text && - !handler(text, length, NULL, NULL, handle, NULL, 0)) { + if (res != NSERROR_OK) { return false; } - return true; } @@ -447,7 +220,7 @@ selection_traverse(struct selection *s, * \param sel_string string to append to, may be resized * \return true iff successful */ -static bool +bool selection_string_append(const char *text, size_t length, bool space, @@ -509,67 +282,6 @@ selection_string_append(const char *text, } -/** - * Selection traversal routine for appending text to a string - * - * \param text pointer to text being added, or NULL for newline - * \param length length of text to be appended (bytes) - * \param box pointer to text box, or NULL if from textplain - * \param len_ctx Length conversion context - * \param handle selection string to append to - * \param whitespace_text whitespace to place before text for formatting - * may be NULL - * \param whitespace_length length of whitespace_text - * \return true iff successful and traversal should continue - */ -static bool -selection_copy_handler(const char *text, - size_t length, - struct box *box, - const nscss_len_ctx *len_ctx, - void *handle, - const char *whitespace_text, - size_t whitespace_length) -{ - bool add_space = false; - plot_font_style_t style; - plot_font_style_t *pstyle = NULL; - - /* add any whitespace which precedes the text from this box */ - if (whitespace_text != NULL && - whitespace_length > 0) { - if (!selection_string_append(whitespace_text, - whitespace_length, - false, - pstyle, - handle)) { - return false; - } - } - - if (box != NULL) { - /* HTML */ - add_space = (box->space != 0); - - if (box->style != NULL) { - /* Override default font style */ - font_plot_style_from_css(len_ctx, box->style, &style); - pstyle = &style; - } else { - /* If there's no style, there must be no text */ - assert(box->text == NULL); - } - } - - /* add the text from this box */ - if (!selection_string_append(text, length, add_space, pstyle, handle)) { - return false; - } - - return true; -} - - /* exported interface documented in desktop/selection.h */ struct selection *selection_create(struct content *c, bool is_html) { @@ -821,7 +533,7 @@ char *selection_get_copy(struct selection *s) if (s == NULL || !s->defined) return NULL; - if (!selection_traverse(s, selection_copy_handler, &sel_string)) { + if (!selection_copy(s, &sel_string)) { free(sel_string.buffer); free(sel_string.styles); return NULL; @@ -849,7 +561,7 @@ bool selection_copy_to_clipboard(struct selection *s) return false; } - if (!selection_traverse(s, selection_copy_handler, &sel_string)) { + if (!selection_copy(s, &sel_string)) { free(sel_string.buffer); free(sel_string.styles); return false; diff --git a/desktop/selection.h b/desktop/selection.h index cfaf59baf..cc8d8da4e 100644 --- a/desktop/selection.h +++ b/desktop/selection.h @@ -29,6 +29,8 @@ struct box; struct browser_window; +struct plot_font_style; +struct selection_string; typedef enum { DRAG_NONE, @@ -218,4 +220,11 @@ char *selection_get_copy(struct selection *s); */ bool selection_highlighted(const struct selection *s, unsigned start, unsigned end, unsigned *start_idx, unsigned *end_idx); +bool +selection_string_append(const char *text, + size_t length, + bool space, + struct plot_font_style *style, + struct selection_string *sel_string); + #endif |