mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-22 12:12:35 +03:00
split selection redraw into content handler specific implementations
This commit is contained in:
parent
0432d95561
commit
36b9262e14
@ -111,6 +111,16 @@ struct content_handler {
|
||||
*/
|
||||
nserror (*textsearch_bounds)(struct content *c, unsigned start_idx, unsigned end_idx, struct box *start_ptr, struct box *end_ptr, struct rect *bounds_out);
|
||||
|
||||
/**
|
||||
* cause a region of the content to be marked invalid and hence redraw
|
||||
*
|
||||
* \param c The content being redrawn
|
||||
* \param start_idx The start index of the text region to be redrawn
|
||||
* \param end_idx The end index of teh text region to be redrawn
|
||||
* \return NSERROR_OK on success else error code
|
||||
*/
|
||||
nserror (*textselection_redraw)(struct content *c, unsigned start_idx, unsigned end_idx);
|
||||
|
||||
/**
|
||||
* create a selection object
|
||||
*/
|
||||
|
@ -20,4 +20,5 @@ S_HTML := box_construct.c \
|
||||
redraw.c \
|
||||
redraw_border.c \
|
||||
script.c \
|
||||
table.c
|
||||
table.c \
|
||||
textselection.c
|
||||
|
@ -70,6 +70,7 @@
|
||||
#include "html/form_internal.h"
|
||||
#include "html/imagemap.h"
|
||||
#include "html/layout.h"
|
||||
#include "html/textselection.h"
|
||||
|
||||
#define CHUNK 4096
|
||||
|
||||
@ -2303,26 +2304,6 @@ html_textsearch_bounds(struct content *c,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create a selection object suitable for this content
|
||||
*/
|
||||
static nserror
|
||||
html_create_selection(struct content *c, struct selection **sel_out)
|
||||
{
|
||||
html_content *html = (html_content *)c;
|
||||
struct selection *sel;
|
||||
sel = selection_create(c, true);
|
||||
if (sel == NULL) {
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
selection_init(sel, html->layout, &html->len_ctx);
|
||||
|
||||
*sel_out = sel;
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* HTML content handler function table
|
||||
*/
|
||||
@ -2354,6 +2335,7 @@ static const content_handler html_content_handler = {
|
||||
.saw_insecure_objects = html_saw_insecure_objects,
|
||||
.textsearch_find = html_textsearch_find,
|
||||
.textsearch_bounds = html_textsearch_bounds,
|
||||
.textselection_redraw = html_textselection_redraw,
|
||||
.create_selection = html_create_selection,
|
||||
.no_share = true,
|
||||
};
|
||||
|
303
content/handlers/html/textselection.c
Normal file
303
content/handlers/html/textselection.c
Normal file
@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Copyright 2006 James Bursa <bursa@users.sourceforge.net>
|
||||
* Copyright 2006 Richard Wilson <info@tinct.net>
|
||||
* Copyright 2008 Michael Drake <tlsa@netsurf-browser.org>
|
||||
* Copyright 2009 Paul Blokus <paul_pl@users.sourceforge.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* implementation of user interaction with a CONTENT_HTML.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <dom/dom.h>
|
||||
|
||||
#include "utils/corestrings.h"
|
||||
#include "utils/messages.h"
|
||||
#include "utils/utils.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/nsoption.h"
|
||||
#include "netsurf/content.h"
|
||||
#include "netsurf/browser_window.h"
|
||||
#include "netsurf/mouse.h"
|
||||
#include "netsurf/misc.h"
|
||||
#include "netsurf/layout.h"
|
||||
#include "netsurf/keypress.h"
|
||||
#include "content/hlcache.h"
|
||||
#include "content/textsearch.h"
|
||||
#include "desktop/frames.h"
|
||||
#include "desktop/scrollbar.h"
|
||||
#include "desktop/selection.h"
|
||||
#include "desktop/textarea.h"
|
||||
#include "javascript/js.h"
|
||||
#include "desktop/gui_internal.h"
|
||||
#include "desktop/save_text.h"
|
||||
|
||||
#include "html/box.h"
|
||||
#include "html/box_textarea.h"
|
||||
#include "html/box_inspect.h"
|
||||
#include "html/font.h"
|
||||
#include "html/form_internal.h"
|
||||
#include "html/private.h"
|
||||
#include "html/imagemap.h"
|
||||
#include "html/textselection.h"
|
||||
|
||||
#define SPACE_LEN(b) ((b->space == 0) ? 0 : 1)
|
||||
|
||||
|
||||
|
||||
struct rdw_info {
|
||||
bool inited;
|
||||
struct rect r;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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 start_idx start of range within textual representation (bytes)
|
||||
* \param end_idx end of range
|
||||
* \param rdwi redraw range to fill in
|
||||
* \param do_marker whether deal enter any marker box
|
||||
* \return false iff traversal abandoned part-way through
|
||||
*/
|
||||
static bool
|
||||
coords_from_range(struct box *box,
|
||||
unsigned start_idx,
|
||||
unsigned end_idx,
|
||||
struct rdw_info *rdwi,
|
||||
bool do_marker)
|
||||
{
|
||||
struct box *child;
|
||||
|
||||
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 (!coords_from_range(box->list_marker,
|
||||
start_idx,
|
||||
end_idx,
|
||||
rdwi,
|
||||
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 ((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)) {
|
||||
int width, height;
|
||||
int x, y;
|
||||
|
||||
/**
|
||||
* \todo it should be possible to reduce the redrawn
|
||||
* area using the offsets
|
||||
*/
|
||||
box_coords(box, &x, &y);
|
||||
|
||||
width = box->padding[LEFT] + box->width + box->padding[RIGHT];
|
||||
height = box->padding[TOP] + box->height + box->padding[BOTTOM];
|
||||
|
||||
if ((box->type == BOX_TEXT) &&
|
||||
(box->space != 0)) {
|
||||
width += box->space;
|
||||
}
|
||||
|
||||
if (rdwi->inited) {
|
||||
if (x < rdwi->r.x0) {
|
||||
rdwi->r.x0 = x;
|
||||
}
|
||||
if (y < rdwi->r.y0) {
|
||||
rdwi->r.y0 = y;
|
||||
}
|
||||
if (x + width > rdwi->r.x1) {
|
||||
rdwi->r.x1 = x + width;
|
||||
}
|
||||
if (y + height > rdwi->r.y1) {
|
||||
rdwi->r.y1 = y + height;
|
||||
}
|
||||
} else {
|
||||
rdwi->inited = true;
|
||||
rdwi->r.x0 = x;
|
||||
rdwi->r.y0 = y;
|
||||
rdwi->r.x1 = x + width;
|
||||
rdwi->r.y1 = y + height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 (!coords_from_range(child,
|
||||
start_idx,
|
||||
end_idx,
|
||||
rdwi,
|
||||
false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
child = next;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create a selection object suitable for this content
|
||||
*/
|
||||
nserror
|
||||
html_create_selection(struct content *c, struct selection **sel_out)
|
||||
{
|
||||
html_content *html = (html_content *)c;
|
||||
struct selection *sel;
|
||||
sel = selection_create(c, true);
|
||||
if (sel == NULL) {
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
selection_init(sel, html->layout, &html->len_ctx);
|
||||
|
||||
*sel_out = sel;
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
nserror
|
||||
html_textselection_redraw(struct content *c,
|
||||
unsigned start_idx,
|
||||
unsigned end_idx)
|
||||
{
|
||||
html_content *html = (html_content *)c;
|
||||
struct rdw_info rdw;
|
||||
|
||||
rdw.inited = false;
|
||||
|
||||
if (!coords_from_range(html->layout, start_idx, end_idx, &rdw, false)) {
|
||||
return NSERROR_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
if (rdw.inited) {
|
||||
content__request_redraw(c,
|
||||
rdw.r.x0,
|
||||
rdw.r.y0,
|
||||
rdw.r.x1 - rdw.r.x0,
|
||||
rdw.r.y1 - rdw.r.y0);
|
||||
}
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
37
content/handlers/html/textselection.h
Normal file
37
content/handlers/html/textselection.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2020 Vincent Sanders <vince@netsurf-browser.org>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* HTML text selection handling
|
||||
*/
|
||||
|
||||
#ifndef NETSURF_HTML_TEXTSELECTION_H
|
||||
#define NETSURF_HTML_TEXTSELECTION_H
|
||||
|
||||
struct content;
|
||||
struct selection;
|
||||
|
||||
/**
|
||||
* create a selection object suitable for this content
|
||||
*/
|
||||
nserror html_create_selection(struct content *c, struct selection **sel_out);
|
||||
|
||||
nserror html_textselection_redraw(struct content *c, unsigned start_idx, unsigned end_idx);
|
||||
|
||||
#endif
|
@ -1452,111 +1452,15 @@ textplain_textsearch_find(struct content *c,
|
||||
|
||||
|
||||
/**
|
||||
* get bounds of a free text search match
|
||||
* Given a range of byte offsets within a UTF8 textplain content,
|
||||
* return a box that fully encloses the text
|
||||
*
|
||||
* \param[in] c content of type CONTENT_TEXTPLAIN
|
||||
* \param[in] start byte offset of start of text range
|
||||
* \param[in] end byte offset of end
|
||||
* \param[out] r rectangle to be completed
|
||||
*/
|
||||
static nserror
|
||||
textplain_textsearch_bounds(struct content *c,
|
||||
unsigned start_idx,
|
||||
unsigned end_idx,
|
||||
struct box *start_box,
|
||||
struct box *end_box,
|
||||
struct rect *bounds)
|
||||
{
|
||||
textplain_coords_from_range(c, start_idx, end_idx, bounds);
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create a selection object suitable for this content
|
||||
*/
|
||||
static nserror
|
||||
textplain_create_selection(struct content *c, struct selection **sel_out)
|
||||
{
|
||||
struct selection *sel;
|
||||
sel = selection_create(c, false);
|
||||
if (sel == NULL) {
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
selection_init(sel, NULL, NULL);
|
||||
|
||||
*sel_out = sel;
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* plain text content handler table
|
||||
*/
|
||||
static const content_handler textplain_content_handler = {
|
||||
.fini = textplain_fini,
|
||||
.create = textplain_create,
|
||||
.process_data = textplain_process_data,
|
||||
.data_complete = textplain_convert,
|
||||
.reformat = textplain_reformat,
|
||||
.destroy = textplain_destroy,
|
||||
.mouse_track = textplain_mouse_track,
|
||||
.mouse_action = textplain_mouse_action,
|
||||
.keypress = textplain_keypress,
|
||||
.redraw = textplain_redraw,
|
||||
.open = textplain_open,
|
||||
.close = textplain_close,
|
||||
.get_selection = textplain_get_selection,
|
||||
.clone = textplain_clone,
|
||||
.type = textplain_content_type,
|
||||
.textsearch_find = textplain_textsearch_find,
|
||||
.textsearch_bounds = textplain_textsearch_bounds,
|
||||
.create_selection = textplain_create_selection,
|
||||
.no_share = true,
|
||||
};
|
||||
|
||||
|
||||
/* exported interface documented in html/textplain.h */
|
||||
nserror textplain_init(void)
|
||||
{
|
||||
lwc_error lerror;
|
||||
nserror error;
|
||||
|
||||
lerror = lwc_intern_string("Windows-1252",
|
||||
SLEN("Windows-1252"),
|
||||
&textplain_default_charset);
|
||||
if (lerror != lwc_error_ok) {
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
error = content_factory_register_handler("text/plain",
|
||||
&textplain_content_handler);
|
||||
if (error != NSERROR_OK) {
|
||||
lwc_string_unref(textplain_default_charset);
|
||||
}
|
||||
|
||||
error = content_factory_register_handler("application/json",
|
||||
&textplain_content_handler);
|
||||
if (error != NSERROR_OK) {
|
||||
lwc_string_unref(textplain_default_charset);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* exported interface documented in html/textplain.h */
|
||||
size_t textplain_size(struct content *c)
|
||||
{
|
||||
textplain_content *text = (textplain_content *) c;
|
||||
|
||||
assert(c != NULL);
|
||||
|
||||
return text->utf8_data_size;
|
||||
}
|
||||
|
||||
|
||||
/* exported interface documented in html/textplain.h */
|
||||
void
|
||||
static void
|
||||
textplain_coords_from_range(struct content *c,
|
||||
unsigned start,
|
||||
unsigned end,
|
||||
@ -1609,6 +1513,136 @@ textplain_coords_from_range(struct content *c,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get bounds of a free text search match
|
||||
*/
|
||||
static nserror
|
||||
textplain_textsearch_bounds(struct content *c,
|
||||
unsigned start_idx,
|
||||
unsigned end_idx,
|
||||
struct box *start_box,
|
||||
struct box *end_box,
|
||||
struct rect *bounds)
|
||||
{
|
||||
textplain_coords_from_range(c, start_idx, end_idx, bounds);
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create a selection object suitable for this content
|
||||
*/
|
||||
static nserror
|
||||
textplain_create_selection(struct content *c, struct selection **sel_out)
|
||||
{
|
||||
struct selection *sel;
|
||||
sel = selection_create(c, false);
|
||||
if (sel == NULL) {
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
selection_init(sel, NULL, NULL);
|
||||
|
||||
*sel_out = sel;
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* invalidate a region based on offsets into the text cauing a redraw
|
||||
*/
|
||||
static nserror
|
||||
textplain_textselection_redraw(struct content *c,
|
||||
unsigned start_idx,
|
||||
unsigned end_idx)
|
||||
{
|
||||
struct rect r;
|
||||
|
||||
if (end_idx <= start_idx) {
|
||||
return NSERROR_BAD_PARAMETER;
|
||||
}
|
||||
|
||||
textplain_coords_from_range(c, start_idx, end_idx, &r);
|
||||
|
||||
content__request_redraw(c, r.x0, r.y0, r.x1 - r.x0, r.y1 - r.y0);
|
||||
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* plain text content handler table
|
||||
*/
|
||||
static const content_handler textplain_content_handler = {
|
||||
.fini = textplain_fini,
|
||||
.create = textplain_create,
|
||||
.process_data = textplain_process_data,
|
||||
.data_complete = textplain_convert,
|
||||
.reformat = textplain_reformat,
|
||||
.destroy = textplain_destroy,
|
||||
.mouse_track = textplain_mouse_track,
|
||||
.mouse_action = textplain_mouse_action,
|
||||
.keypress = textplain_keypress,
|
||||
.redraw = textplain_redraw,
|
||||
.open = textplain_open,
|
||||
.close = textplain_close,
|
||||
.get_selection = textplain_get_selection,
|
||||
.clone = textplain_clone,
|
||||
.type = textplain_content_type,
|
||||
.textsearch_find = textplain_textsearch_find,
|
||||
.textsearch_bounds = textplain_textsearch_bounds,
|
||||
.textselection_redraw = textplain_textselection_redraw,
|
||||
.create_selection = textplain_create_selection,
|
||||
.no_share = true,
|
||||
};
|
||||
|
||||
|
||||
/* exported interface documented in html/textplain.h */
|
||||
nserror textplain_init(void)
|
||||
{
|
||||
lwc_error lerror;
|
||||
nserror error;
|
||||
|
||||
lerror = lwc_intern_string("Windows-1252",
|
||||
SLEN("Windows-1252"),
|
||||
&textplain_default_charset);
|
||||
if (lerror != lwc_error_ok) {
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
error = content_factory_register_handler("text/plain",
|
||||
&textplain_content_handler);
|
||||
if (error != NSERROR_OK) {
|
||||
lwc_string_unref(textplain_default_charset);
|
||||
}
|
||||
|
||||
error = content_factory_register_handler("application/json",
|
||||
&textplain_content_handler);
|
||||
if (error != NSERROR_OK) {
|
||||
lwc_string_unref(textplain_default_charset);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* exported interface documented in html/textplain.h */
|
||||
size_t textplain_size(struct content *c)
|
||||
{
|
||||
textplain_content *text = (textplain_content *) c;
|
||||
|
||||
assert(c != NULL);
|
||||
|
||||
return text->utf8_data_size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* exported interface documented in html/textplain.h */
|
||||
char *
|
||||
textplain_get_raw_data(struct content *c,
|
||||
|
@ -46,19 +46,6 @@ nserror textplain_init(void);
|
||||
size_t textplain_size(struct content *c);
|
||||
|
||||
|
||||
/**
|
||||
* Given a range of byte offsets within a UTF8 textplain content,
|
||||
* return a box that fully encloses the text
|
||||
*
|
||||
* \param[in] c content of type CONTENT_TEXTPLAIN
|
||||
* \param[in] start byte offset of start of text range
|
||||
* \param[in] end byte offset of end
|
||||
* \param[out] r rectangle to be completed
|
||||
*/
|
||||
void textplain_coords_from_range(struct content *c,
|
||||
unsigned start, unsigned end, struct rect *r);
|
||||
|
||||
|
||||
/**
|
||||
* Return a pointer to the raw UTF-8 data, as opposed to the reformatted
|
||||
* text to fit the window width. Thus only hard newlines are preserved
|
||||
|
@ -310,63 +310,6 @@ traverse_tree(struct box *box,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Selection traversal handler for redrawing the screen when the selection
|
||||
* has been altered.
|
||||
*
|
||||
* \param text pointer to text string
|
||||
* \param length length of text to be appended (bytes)
|
||||
* \param box pointer to text box being (partially) added
|
||||
* \param handle unused handle, we don't need one
|
||||
* \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
|
||||
redraw_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)
|
||||
{
|
||||
struct rdw_info *r = (struct rdw_info*)handle;
|
||||
int width, height;
|
||||
int x, y;
|
||||
|
||||
if (!box) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* \todo - it should be possible to reduce the redrawn area by
|
||||
* considering the 'text', 'length' and 'space' parameters */
|
||||
box_coords(box, &x, &y);
|
||||
|
||||
width = box->padding[LEFT] + box->width + box->padding[RIGHT];
|
||||
height = box->padding[TOP] + box->height + box->padding[BOTTOM];
|
||||
|
||||
if ((box->type == BOX_TEXT) &&
|
||||
(box->space != 0)) {
|
||||
width += box->space;
|
||||
}
|
||||
|
||||
if (r->inited) {
|
||||
if (x < r->r.x0) r->r.x0 = x;
|
||||
if (y < r->r.y0) r->r.y0 = y;
|
||||
if (x + width > r->r.x1) r->r.x1 = x + width;
|
||||
if (y + height > r->r.y1) r->r.y1 = y + height;
|
||||
} else {
|
||||
r->inited = true;
|
||||
r->r.x0 = x;
|
||||
r->r.y0 = y;
|
||||
r->r.x1 = x + width;
|
||||
r->r.y1 = y + height;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -376,43 +319,20 @@ redraw_handler(const char *text,
|
||||
* \param start_idx start offset (bytes) within the textual representation
|
||||
* \param end_idx end offset (bytes) within the textual representation
|
||||
*/
|
||||
static void
|
||||
static nserror
|
||||
selection_redraw(struct selection *s, unsigned start_idx, unsigned end_idx)
|
||||
{
|
||||
struct rdw_info rdw;
|
||||
nserror res;
|
||||
|
||||
assert(end_idx >= start_idx);
|
||||
rdw.inited = false;
|
||||
|
||||
if (s->root) {
|
||||
if (!traverse_tree(s->root,
|
||||
&s->len_ctx,
|
||||
start_idx,
|
||||
end_idx,
|
||||
redraw_handler,
|
||||
&rdw,
|
||||
NULL,
|
||||
NULL,
|
||||
false))
|
||||
return;
|
||||
if (s->c->handler->textselection_redraw != NULL) {
|
||||
res = s->c->handler->textselection_redraw(s->c,
|
||||
start_idx,
|
||||
end_idx);
|
||||
} else {
|
||||
if ((s->is_html == false) &&
|
||||
(end_idx > start_idx)) {
|
||||
textplain_coords_from_range(s->c,
|
||||
start_idx,
|
||||
end_idx,
|
||||
&rdw.r);
|
||||
rdw.inited = true;
|
||||
}
|
||||
res = NSERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (rdw.inited) {
|
||||
content__request_redraw(s->c,
|
||||
rdw.r.x0,
|
||||
rdw.r.y0,
|
||||
rdw.r.x1 - rdw.r.x0,
|
||||
rdw.r.y1 - rdw.r.y0);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user