summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2017-06-01 21:43:45 (GMT)
committer Vincent Sanders <vince@kyllikki.org>2017-06-01 21:43:45 (GMT)
commit08a86bfa0e5d961f255f8e64ddcdb6f179db485d (patch)
tree495189ec9354a27ee22b1c12a305c0578b6f99bc
parent6b997431d34d3711c62cf4bfe7f3456f45072273 (diff)
downloadnetsurf-08a86bfa0e5d961f255f8e64ddcdb6f179db485d.tar.gz
netsurf-08a86bfa0e5d961f255f8e64ddcdb6f179db485d.tar.bz2
clean up doccomments and formatting in texplain content handler
There is an intention to replace the render interface and it will be helpful to reduce the size of the exposed API as much as possible. This is the first step towards that goal.
-rw-r--r--render/textplain.c918
-rw-r--r--render/textplain.h102
2 files changed, 536 insertions, 484 deletions
diff --git a/render/textplain.c b/render/textplain.c
index d376888..5d28d9c 100644
--- a/render/textplain.c
+++ b/render/textplain.c
@@ -17,8 +17,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Content for text/plain (implementation).
+/**
+ * \file
+ *
+ * plain text content handling implementation.
*/
#include <assert.h>
@@ -85,7 +87,6 @@ typedef struct textplain_content {
#define CHUNK 32768 /* Must be a power of 2 */
#define MARGIN 4
-
#define TAB_WIDTH 8 /* must be power of 2 currently */
#define TEXT_SIZE 10 * FONT_SIZE_SCALE /* Unscaled text size in pt */
@@ -100,96 +101,13 @@ static plot_font_style_t textplain_style = {
static int textplain_tab_width = 256; /* try for a sensible default */
-static void textplain_fini(void);
-static nserror textplain_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
- llcache_handle *llcache, const char *fallback_charset,
- bool quirks, struct content **c);
-static nserror textplain_create_internal(textplain_content *c,
- lwc_string *charset);
-static bool textplain_process_data(struct content *c,
- const char *data, unsigned int size);
-static bool textplain_convert(struct content *c);
-static void textplain_mouse_track(struct content *c, struct browser_window *bw,
- browser_mouse_state mouse, int x, int y);
-static void textplain_mouse_action(struct content *c, struct browser_window *bw,
- browser_mouse_state mouse, int x, int y);
-static bool textplain_keypress(struct content *c, uint32_t key);
-static void textplain_search(struct content *c, void *gui_data,
- search_flags_t flags, const char *string);
-static void textplain_search_clear(struct content *c);
-static void textplain_reformat(struct content *c, int width, int height);
-static void textplain_destroy(struct content *c);
-static bool textplain_redraw(struct content *c, struct content_redraw_data *data,
- const struct rect *clip, const struct redraw_context *ctx);
-static void textplain_open(struct content *c, struct browser_window *bw,
- struct content *page, struct object_params *params);
-void textplain_close(struct content *c);
-char *textplain_get_selection(struct content *c);
-static nserror textplain_clone(const struct content *old,
- struct content **newc);
-static content_type textplain_content_type(void);
-
-static parserutils_error textplain_charset_hack(const uint8_t *data, size_t len,
- uint16_t *mibenum, uint32_t *source);
-static bool textplain_drain_input(textplain_content *c,
- parserutils_inputstream *stream, parserutils_error terminator);
-static bool textplain_copy_utf8_data(textplain_content *c,
- const uint8_t *buf, size_t len);
-static int textplain_coord_from_offset(const char *text, size_t offset,
- size_t length);
-static float textplain_line_height(void);
-
-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,
- .search = textplain_search,
- .search_clear = textplain_search_clear,
- .redraw = textplain_redraw,
- .open = textplain_open,
- .close = textplain_close,
- .get_selection = textplain_get_selection,
- .clone = textplain_clone,
- .type = textplain_content_type,
- .no_share = true,
-};
-
static lwc_string *textplain_default_charset;
-/**
- * Initialise the text content handler
- */
-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);
- }
-
- return error;
-}
/**
* Clean up after the text content handler
*/
-void textplain_fini(void)
+static void textplain_fini(void)
{
if (textplain_default_charset != NULL) {
lwc_string_unref(textplain_default_charset);
@@ -197,67 +115,37 @@ void textplain_fini(void)
}
}
-/**
- * Create a CONTENT_TEXTPLAIN.
- */
-
-nserror textplain_create(const content_handler *handler,
- lwc_string *imime_type, const http_parameter *params,
- llcache_handle *llcache, const char *fallback_charset,
- bool quirks, struct content **c)
-{
- textplain_content *text;
- nserror error;
- lwc_string *encoding;
-
- text = calloc(1, sizeof(textplain_content));
- if (text == NULL)
- return NSERROR_NOMEM;
-
- error = content__init(&text->base, handler, imime_type, params,
- llcache, fallback_charset, quirks);
- if (error != NSERROR_OK) {
- free(text);
- return error;
- }
-
- error = http_parameter_list_find_item(params, corestring_lwc_charset,
- &encoding);
- if (error != NSERROR_OK) {
- encoding = lwc_string_ref(textplain_default_charset);
- }
- error = textplain_create_internal(text, encoding);
- if (error != NSERROR_OK) {
- lwc_string_unref(encoding);
- free(text);
- return error;
- }
-
- lwc_string_unref(encoding);
-
- *c = (struct content *) text;
-
- return NSERROR_OK;
-}
-
-/*
- * Hack around bug in libparserutils: if the client provides an
- * encoding up front, but does not provide a charset detection
- * callback, then libparserutils will replace the provided encoding
- * with UTF-8. This breaks our input handling.
+/**
+ * Work around feature in libparserutils
+ *
+ * if the client provides an encoding up front, but does not provide a
+ * charset detection callback, then libparserutils will replace the
+ * provided encoding with UTF-8. This breaks our input handling.
*
- * We avoid this by providing a callback that does precisely nothing,
+ * Avoid this by providing a callback that does precisely nothing,
* thus preserving whatever charset information we decided on in
* textplain_create.
*/
-parserutils_error textplain_charset_hack(const uint8_t *data, size_t len,
- uint16_t *mibenum, uint32_t *source)
+static parserutils_error
+textplain_charset_hack(const uint8_t *data,
+ size_t len,
+ uint16_t *mibenum,
+ uint32_t *source)
{
return PARSERUTILS_OK;
-}
+}
+
-nserror textplain_create_internal(textplain_content *c, lwc_string *encoding)
+/**
+ * setup plain text render.
+ *
+ * \param[in] c content object.
+ * \param[in] encoding the encoding of the content.
+ * \return NSERROR_OK else appropriate error code.
+ */
+static nserror
+textplain_create_internal(textplain_content *c, lwc_string *encoding)
{
char *utf8_data;
parserutils_inputstream *stream;
@@ -270,18 +158,18 @@ nserror textplain_create_internal(textplain_content *c, lwc_string *encoding)
if (utf8_data == NULL)
goto no_memory;
- error = parserutils_inputstream_create(lwc_string_data(encoding), 0,
- textplain_charset_hack, &stream);
+ error = parserutils_inputstream_create(lwc_string_data(encoding), 0,
+ textplain_charset_hack, &stream);
if (error == PARSERUTILS_BADENCODING) {
/* Fall back to Windows-1252 */
error = parserutils_inputstream_create("Windows-1252", 0,
- textplain_charset_hack, &stream);
+ textplain_charset_hack, &stream);
}
if (error != PARSERUTILS_OK) {
free(utf8_data);
goto no_memory;
}
-
+
c->encoding = lwc_string_ref(encoding);
c->inputstream = stream;
c->utf8_data = utf8_data;
@@ -299,28 +187,110 @@ nserror textplain_create_internal(textplain_content *c, lwc_string *encoding)
no_memory:
msg_data.error = messages_get("NoMemory");
content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
+
return NSERROR_NOMEM;
}
-bool textplain_drain_input(textplain_content *c,
- parserutils_inputstream *stream,
- parserutils_error terminator)
+
+/**
+ * Create a CONTENT_TEXTPLAIN.
+ */
+static nserror
+textplain_create(const content_handler *handler,
+ lwc_string *imime_type,
+ const http_parameter *params,
+ llcache_handle *llcache,
+ const char *fallback_charset,
+ bool quirks,
+ struct content **c)
+{
+ textplain_content *text;
+ nserror error;
+ lwc_string *encoding;
+
+ text = calloc(1, sizeof(textplain_content));
+ if (text == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ error = content__init(&text->base, handler, imime_type, params,
+ llcache, fallback_charset, quirks);
+ if (error != NSERROR_OK) {
+ free(text);
+ return error;
+ }
+
+ error = http_parameter_list_find_item(params, corestring_lwc_charset,
+ &encoding);
+ if (error != NSERROR_OK) {
+ encoding = lwc_string_ref(textplain_default_charset);
+ }
+
+ error = textplain_create_internal(text, encoding);
+ if (error != NSERROR_OK) {
+ lwc_string_unref(encoding);
+ free(text);
+ return error;
+ }
+
+ lwc_string_unref(encoding);
+
+ *c = (struct content *) text;
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * copy utf8 encoded data
+ */
+static bool
+textplain_copy_utf8_data(textplain_content *c, const uint8_t *buf, size_t len)
+{
+ if (c->utf8_data_size + len >= c->utf8_data_allocated) {
+ /* Compute next multiple of chunk above the required space */
+ size_t allocated;
+ char *utf8_data;
+
+ allocated = (c->utf8_data_size + len + CHUNK - 1) & ~(CHUNK - 1);
+ utf8_data = realloc(c->utf8_data, allocated);
+ if (utf8_data == NULL)
+ return false;
+
+ c->utf8_data = utf8_data;
+ c->utf8_data_allocated = allocated;
+ }
+
+ memcpy(c->utf8_data + c->utf8_data_size, buf, len);
+ c->utf8_data_size += len;
+
+ return true;
+}
+
+
+/**
+ * drain input
+ */
+static bool
+textplain_drain_input(textplain_content *c,
+ parserutils_inputstream *stream,
+ parserutils_error terminator)
{
static const uint8_t *u_fffd = (const uint8_t *) "\xef\xbf\xfd";
const uint8_t *ch;
size_t chlen, offset = 0;
- while (parserutils_inputstream_peek(stream, offset, &ch, &chlen) !=
- terminator) {
+ while (parserutils_inputstream_peek(stream, offset, &ch, &chlen) !=
+ terminator) {
/* Replace all instances of NUL with U+FFFD */
if (chlen == 1 && *ch == 0) {
if (offset > 0) {
/* Obtain pointer to start of input data */
- parserutils_inputstream_peek(stream, 0,
- &ch, &chlen);
+ parserutils_inputstream_peek(stream, 0,
+ &ch, &chlen);
/* Copy from it up to the start of the NUL */
- if (textplain_copy_utf8_data(c, ch,
- offset) == false)
+ if (textplain_copy_utf8_data(c, ch,
+ offset) == false)
return false;
}
@@ -338,12 +308,12 @@ bool textplain_drain_input(textplain_content *c,
if (offset > CHUNK) {
/* Obtain pointer to start of input data */
- parserutils_inputstream_peek(stream, 0,
- &ch, &chlen);
+ parserutils_inputstream_peek(stream, 0,
+ &ch, &chlen);
/* Emit the data we've read */
- if (textplain_copy_utf8_data(c, ch,
- offset) == false)
+ if (textplain_copy_utf8_data(c, ch,
+ offset) == false)
return false;
/* Advance the inputstream */
@@ -356,7 +326,7 @@ bool textplain_drain_input(textplain_content *c,
if (offset > 0) {
/* Obtain pointer to start of input data */
- parserutils_inputstream_peek(stream, 0, &ch, &chlen);
+ parserutils_inputstream_peek(stream, 0, &ch, &chlen);
/* Emit any data remaining */
if (textplain_copy_utf8_data(c, ch, offset) == false)
return false;
@@ -368,44 +338,20 @@ bool textplain_drain_input(textplain_content *c,
return true;
}
-bool textplain_copy_utf8_data(textplain_content *c,
- const uint8_t *buf, size_t len)
-{
- if (c->utf8_data_size + len >= c->utf8_data_allocated) {
- /* Compute next multiple of chunk above the required space */
- size_t allocated;
- char *utf8_data;
-
- allocated = (c->utf8_data_size + len + CHUNK - 1) & ~(CHUNK - 1);
- utf8_data = realloc(c->utf8_data, allocated);
- if (utf8_data == NULL)
- return false;
-
- c->utf8_data = utf8_data;
- c->utf8_data_allocated = allocated;
- }
-
- memcpy(c->utf8_data + c->utf8_data_size, buf, len);
- c->utf8_data_size += len;
-
- return true;
-}
-
/**
* Process data for CONTENT_TEXTPLAIN.
*/
-
-bool textplain_process_data(struct content *c,
- const char *data, unsigned int size)
+static bool
+textplain_process_data(struct content *c, const char *data, unsigned int size)
{
textplain_content *text = (textplain_content *) c;
parserutils_inputstream *stream = text->inputstream;
union content_msg_data msg_data;
parserutils_error error;
- error = parserutils_inputstream_append(stream,
- (const uint8_t *) data, size);
+ error = parserutils_inputstream_append(stream,
+ (const uint8_t *) data, size);
if (error != PARSERUTILS_OK) {
goto no_memory;
}
@@ -425,8 +371,7 @@ no_memory:
/**
* Convert a CONTENT_TEXTPLAIN for display.
*/
-
-bool textplain_convert(struct content *c)
+static bool textplain_convert(struct content *c)
{
textplain_content *text = (textplain_content *) c;
parserutils_inputstream *stream = text->inputstream;
@@ -452,10 +397,23 @@ bool textplain_convert(struct content *c)
/**
- * Reformat a CONTENT_TEXTPLAIN to a new width.
+ * Calculate the line height, in pixels
+ *
+ * \return Line height, in pixels
*/
+static float textplain_line_height(void)
+{
+ /* Size is in points, so convert to pixels.
+ * Then use a constant line height of 1.2 x font size.
+ */
+ return FIXTOFLT(FDIV((FMUL(FLTTOFIX(1.2), FMUL(nscss_screen_dpi, INTTOFIX((textplain_style.size / FONT_SIZE_SCALE))))), F_72));
+}
-void textplain_reformat(struct content *c, int width, int height)
+
+/**
+ * Reformat a CONTENT_TEXTPLAIN to a new width.
+ */
+static void textplain_reformat(struct content *c, int width, int height)
{
textplain_content *text = (textplain_content *) c;
char *utf8_data = text->utf8_data;
@@ -521,23 +479,25 @@ void textplain_reformat(struct content *c, int width, int height)
if (term || next_col >= columns) {
if (line_count % 1024 == 0) {
- line1 = realloc(line,
- sizeof(struct textplain_line) *
+ line1 = realloc(line,
+ sizeof(struct textplain_line) *
(line_count + 1024 + 3));
if (!line1)
goto no_memory;
text->physical_line = line = line1;
}
+
if (term) {
line[line_count-1].length = i - line_start;
/* skip second char of CR/LF or LF/CR pair */
if (i + 1 < utf8_data_size &&
- utf8_data[i+1] != utf8_data[i] &&
- (utf8_data[i+1] == '\n' || utf8_data[i+1] == '\r'))
+ utf8_data[i+1] != utf8_data[i] &&
+ (utf8_data[i+1] == '\n' ||
+ utf8_data[i+1] == '\r')) {
i++;
- }
- else {
+ }
+ } else {
if (space) {
/* break at last space in line */
i = space;
@@ -545,6 +505,7 @@ void textplain_reformat(struct content *c, int width, int height)
} else
line[line_count-1].length = i - line_start;
}
+
line[line_count++].start = line_start = i + 1;
col = 0;
space = 0;
@@ -574,7 +535,7 @@ no_memory:
* Destroy a CONTENT_TEXTPLAIN and free all resources it owns.
*/
-void textplain_destroy(struct content *c)
+static void textplain_destroy(struct content *c)
{
textplain_content *text = (textplain_content *) c;
@@ -594,7 +555,7 @@ void textplain_destroy(struct content *c)
}
-nserror textplain_clone(const struct content *old, struct content **newc)
+static nserror textplain_clone(const struct content *old, struct content **newc)
{
const textplain_content *old_text = (textplain_content *) old;
textplain_content *text;
@@ -628,7 +589,7 @@ nserror textplain_clone(const struct content *old, struct content **newc)
}
if (old->status == CONTENT_STATUS_READY ||
- old->status == CONTENT_STATUS_DONE) {
+ old->status == CONTENT_STATUS_DONE) {
if (textplain_convert(&text->base) == false) {
content_destroy(&text->base);
return NSERROR_CLONE_FAILED;
@@ -638,71 +599,27 @@ nserror textplain_clone(const struct content *old, struct content **newc)
return NSERROR_OK;
}
-content_type textplain_content_type(void)
-{
- return CONTENT_TEXTPLAIN;
-}
-
-/**
- * Handle mouse tracking (including drags) in a TEXTPLAIN content window.
- *
- * \param c content of type textplain
- * \param bw browser window
- * \param mouse state of mouse buttons and modifier keys
- * \param x coordinate of mouse
- * \param y coordinate of mouse
- */
-void textplain_mouse_track(struct content *c, struct browser_window *bw,
- browser_mouse_state mouse, int x, int y)
+static content_type textplain_content_type(void)
{
- textplain_content *text = (textplain_content *) c;
-
- if (browser_window_get_drag_type(bw) == DRAGGING_SELECTION && !mouse) {
- int dir = -1;
- size_t idx;
-
- if (selection_dragging_start(&text->sel))
- dir = 1;
-
- idx = textplain_offset_from_coords(c, x, y, dir);
- selection_track(&text->sel, mouse, idx);
-
- browser_window_set_drag_type(bw, DRAGGING_NONE, NULL);
- }
-
- switch (browser_window_get_drag_type(bw)) {
-
- case DRAGGING_SELECTION: {
- int dir = -1;
- size_t idx;
-
- if (selection_dragging_start(&text->sel)) dir = 1;
-
- idx = textplain_offset_from_coords(c, x, y, dir);
- selection_track(&text->sel, mouse, idx);
- }
- break;
-
- default:
- textplain_mouse_action(c, bw, mouse, x, y);
- break;
- }
+ return CONTENT_TEXTPLAIN;
}
/**
* Handle mouse clicks and movements in a TEXTPLAIN content window.
*
- * \param c content of type textplain
- * \param bw browser window
- * \param mouse mouse state on action
- * \param x coordinate of mouse
- * \param y coordinate of mouse
+ * \param c content of type textplain
+ * \param bw browser window
+ * \param mouse mouse state on action
+ * \param x coordinate of mouse
+ * \param y coordinate of mouse
*/
-
-void textplain_mouse_action(struct content *c, struct browser_window *bw,
- browser_mouse_state mouse, int x, int y)
+static void
+textplain_mouse_action(struct content *c,
+ struct browser_window *bw,
+ browser_mouse_state mouse,
+ int x, int y)
{
textplain_content *text = (textplain_content *) c;
browser_pointer_shape pointer = BROWSER_POINTER_DEFAULT;
@@ -718,7 +635,7 @@ void textplain_mouse_action(struct content *c, struct browser_window *bw,
if (selection_dragging(&text->sel)) {
browser_window_set_drag_type(bw,
- DRAGGING_SELECTION, NULL);
+ DRAGGING_SELECTION, NULL);
status = messages_get("Selecting");
}
@@ -738,14 +655,63 @@ void textplain_mouse_action(struct content *c, struct browser_window *bw,
/**
+ * Handle mouse tracking (including drags) in a TEXTPLAIN content window.
+ *
+ * \param c content of type textplain
+ * \param bw browser window
+ * \param mouse state of mouse buttons and modifier keys
+ * \param x coordinate of mouse
+ * \param y coordinate of mouse
+ */
+static void
+textplain_mouse_track(struct content *c,
+ struct browser_window *bw,
+ browser_mouse_state mouse,
+ int x, int y)
+{
+ textplain_content *text = (textplain_content *) c;
+
+ if (browser_window_get_drag_type(bw) == DRAGGING_SELECTION && !mouse) {
+ int dir = -1;
+ size_t idx;
+
+ if (selection_dragging_start(&text->sel))
+ dir = 1;
+
+ idx = textplain_offset_from_coords(c, x, y, dir);
+ selection_track(&text->sel, mouse, idx);
+
+ browser_window_set_drag_type(bw, DRAGGING_NONE, NULL);
+ }
+
+ switch (browser_window_get_drag_type(bw)) {
+
+ case DRAGGING_SELECTION: {
+ int dir = -1;
+ size_t idx;
+
+ if (selection_dragging_start(&text->sel)) dir = 1;
+
+ idx = textplain_offset_from_coords(c, x, y, dir);
+ selection_track(&text->sel, mouse, idx);
+ }
+ break;
+
+ default:
+ textplain_mouse_action(c, bw, mouse, x, y);
+ break;
+ }
+}
+
+
+/**
* Handle keypresses.
*
* \param c content of type CONTENT_TEXTPLAIN
* \param key The UCS4 character codepoint
* \return true if key handled, false otherwise
*/
-
-bool textplain_keypress(struct content *c, uint32_t key)
+static bool textplain_keypress(struct content *c, uint32_t key)
{
textplain_content *text = (textplain_content *) c;
struct selection *sel = &text->sel;
@@ -778,6 +744,27 @@ bool textplain_keypress(struct content *c, uint32_t key)
/**
+ * Terminate a search.
+ *
+ * \param c content of type text
+ */
+static void textplain_search_clear(struct content *c)
+{
+ textplain_content *text = (textplain_content *) c;
+
+ assert(c != NULL);
+
+ free(text->search_string);
+ text->search_string = NULL;
+
+ if (text->search != NULL) {
+ search_destroy_context(text->search);
+ }
+ text->search = NULL;
+}
+
+
+/**
* Handle search.
*
* \param c content of type text
@@ -785,16 +772,16 @@ bool textplain_keypress(struct content *c, uint32_t key)
* \param flags search flags
* \param string search string
*/
-void textplain_search(struct content *c, void *gui_data,
- search_flags_t flags, const char *string)
+static void textplain_search(struct content *c, void *gui_data,
+ search_flags_t flags, const char *string)
{
textplain_content *text = (textplain_content *) c;
assert(c != NULL);
if (string != NULL && text->search_string != NULL &&
- strcmp(string, text->search_string) == 0 &&
- text->search != NULL) {
+ strcmp(string, text->search_string) == 0 &&
+ text->search != NULL) {
/* Continue prev. search */
search_step(text->search, flags, string);
@@ -811,7 +798,7 @@ void textplain_search(struct content *c, void *gui_data,
}
text->search = search_create_context(c, CONTENT_TEXTPLAIN,
- gui_data);
+ gui_data);
if (text->search == NULL)
return;
@@ -829,39 +816,21 @@ void textplain_search(struct content *c, void *gui_data,
/**
- * Terminate a search.
- *
- * \param c content of type text
- */
-void textplain_search_clear(struct content *c)
-{
- textplain_content *text = (textplain_content *) c;
-
- assert(c != NULL);
-
- free(text->search_string);
- text->search_string = NULL;
-
- if (text->search != NULL)
- search_destroy_context(text->search);
- text->search = NULL;
-}
-
-
-/**
* Draw a CONTENT_TEXTPLAIN using the current set of plotters (plot).
*
+ * x, y, clip_[xy][01] are in target coordinates.
+ *
* \param c content of type CONTENT_TEXTPLAIN
* \param data redraw data for this content redraw
* \param clip current clip region
* \param ctx current redraw context
* \return true if successful, false otherwise
- *
- * x, y, clip_[xy][01] are in target coordinates.
*/
-
-bool textplain_redraw(struct content *c, struct content_redraw_data *data,
- const struct rect *clip, const struct redraw_context *ctx)
+static bool
+textplain_redraw(struct content *c,
+ struct content_redraw_data *data,
+ const struct rect *clip,
+ const struct redraw_context *ctx)
{
textplain_content *text = (textplain_content *) c;
struct browser_window *bw = text->bw;
@@ -931,20 +900,20 @@ bool textplain_redraw(struct content *c, struct content_redraw_data *data,
next_offset = utf8_next(text_d, length, next_offset);
if (!text_redraw(text_d + offset, next_offset - offset,
- line[lineno].start + offset, 0,
- &textplain_style,
- tx, y + (lineno * scaled_line_height),
- clip, line_height, data->scale, false,
- (struct content *)text, &text->sel,
- text->search, ctx))
+ line[lineno].start + offset, 0,
+ &textplain_style,
+ tx, y + (lineno * scaled_line_height),
+ clip, line_height, data->scale, false,
+ (struct content *)text, &text->sel,
+ text->search, ctx))
return false;
if (next_offset >= length)
break;
res = guit->layout->width(&textplain_style,
- &text_d[offset],
- next_offset - offset,
+ &text_d[offset],
+ next_offset - offset,
&width);
/* locate end of string and align to next tab position */
if (res == NSERROR_OK) {
@@ -953,9 +922,11 @@ bool textplain_redraw(struct content *c, struct content_redraw_data *data,
ntx = x + ((1 + (tx - x) / tab_width) * tab_width);
- /* if the tab character lies within the selection, if any,
- then we must draw it as a filled rectangle so that it's
- consistent with background of the selected text */
+ /* if the tab character lies within the
+ * selection, if any, then we must draw it as
+ * a filled rectangle so that it's consistent
+ * with background of the selected text
+ */
if (bw) {
unsigned tab_ofst = line[lineno].start + next_offset;
@@ -965,17 +936,21 @@ bool textplain_redraw(struct content *c, struct content_redraw_data *data,
if (selection_defined(sel)) {
unsigned start_idx, end_idx;
if (selection_highlighted(sel,
- tab_ofst, tab_ofst + 1,
- &start_idx, &end_idx))
+ tab_ofst,
+ tab_ofst + 1,
+ &start_idx,
+ &end_idx))
highlighted = true;
}
if (!highlighted && (text->search != NULL)) {
unsigned start_idx, end_idx;
if (search_term_highlighted(c,
- tab_ofst, tab_ofst + 1,
- &start_idx, &end_idx,
- text->search))
+ tab_ofst,
+ tab_ofst + 1,
+ &start_idx,
+ &end_idx,
+ text->search))
highlighted = true;
}
@@ -1006,9 +981,11 @@ bool textplain_redraw(struct content *c, struct content_redraw_data *data,
/**
* Handle a window containing a CONTENT_TEXTPLAIN being opened.
*/
-
-void textplain_open(struct content *c, struct browser_window *bw,
- struct content *page, struct object_params *params)
+static void
+textplain_open(struct content *c,
+ struct browser_window *bw,
+ struct content *page,
+ struct object_params *params)
{
textplain_content *text = (textplain_content *) c;
@@ -1022,13 +999,13 @@ void textplain_open(struct content *c, struct browser_window *bw,
/**
* Handle a window containing a CONTENT_TEXTPLAIN being closed.
*/
-
-void textplain_close(struct content *c)
+static void textplain_close(struct content *c)
{
textplain_content *text = (textplain_content *) c;
- if (text->search != NULL)
+ if (text->search != NULL) {
search_destroy_context(text->search);
+ }
text->bw = NULL;
}
@@ -1037,20 +1014,107 @@ void textplain_close(struct content *c)
/**
* Return an textplain content's selection context
*/
-
-char *textplain_get_selection(struct content *c)
+static char *textplain_get_selection(struct content *c)
{
textplain_content *text = (textplain_content *) c;
return selection_get_copy(&text->sel);
}
+
/**
- * Retrieve number of lines in content
+ * Convert a character offset within a line of text into the
+ * horizontal co-ordinate
+ *
+ * The conversion takes into account the font being used and any tabs
+ * in the text
*
- * \param c Content to retrieve line count from
- * \return Number of lines
+ * \param text line of text
+ * \param offset char offset within text
+ * \param length line length
+ * \return x ordinate
*/
+static int
+textplain_coord_from_offset(const char *text, size_t offset, size_t length)
+{
+ int x = 0;
+
+ while (offset > 0) {
+ size_t next_offset = 0;
+ int tx;
+
+ while (next_offset < offset && text[next_offset] != '\t') {
+ next_offset = utf8_next(text, length, next_offset);
+ }
+
+ guit->layout->width(&textplain_style, text, next_offset, &tx);
+
+ x += tx;
+
+ if (next_offset >= offset)
+ break;
+
+ /* align to next tab boundary */
+ next_offset++;
+ x = (1 + (x / textplain_tab_width)) * textplain_tab_width;
+ offset -= next_offset;
+ text += next_offset;
+ length -= next_offset;
+ }
+
+ return x;
+}
+
+
+/**
+ * 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,
+ .search = textplain_search,
+ .search_clear = textplain_search_clear,
+ .redraw = textplain_redraw,
+ .open = textplain_open,
+ .close = textplain_close,
+ .get_selection = textplain_get_selection,
+ .clone = textplain_clone,
+ .type = textplain_content_type,
+ .no_share = true,
+};
+
+
+/* exported interface documented in render/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);
+ }
+
+ return error;
+}
+
+
+/* exported interface documented in render/textplain.h */
unsigned long textplain_line_count(struct content *c)
{
textplain_content *text = (textplain_content *) c;
@@ -1060,12 +1124,8 @@ unsigned long textplain_line_count(struct content *c)
return text->physical_line_count;
}
-/**
- * Retrieve the size (in bytes) of text data
- *
- * \param c Content to retrieve size of
- * \return Size, in bytes, of data
- */
+
+/* exported interface documented in render/textplain.h */
size_t textplain_size(struct content *c)
{
textplain_content *text = (textplain_content *) c;
@@ -1075,21 +1135,8 @@ size_t textplain_size(struct content *c)
return text->utf8_data_size;
}
-/**
-
- * Return byte offset within UTF8 textplain content.
- *
- * given the co-ordinates of a point within a textplain content. 'dir'
- * specifies the direction in which to search (-1 = above-left, +1 =
- * below-right) if the co-ordinates are not contained within a line.
- *
- * \param c content of type CONTENT_TEXTPLAIN
- * \param x x ordinate of point
- * \param y y ordinate of point
- * \param dir direction of search if not within line
- * \return byte offset of character containing (or nearest to) point
- */
+/* exported interface documented in render/textplain.h */
size_t textplain_offset_from_coords(struct content *c, int x, int y, int dir)
{
textplain_content *textc = (textplain_content *) c;
@@ -1122,8 +1169,9 @@ size_t textplain_offset_from_coords(struct content *c, int x, int y, int dir)
size_t next_offset = 0;
int width = INT_MAX;
- while (next_offset < length && text[next_offset] != '\t')
+ while (next_offset < length && text[next_offset] != '\t') {
next_offset = utf8_next(text, length, next_offset);
+ }
if (next_offset < length) {
guit->layout->width(&textplain_style,
@@ -1163,94 +1211,12 @@ size_t textplain_offset_from_coords(struct content *c, int x, int y, int dir)
}
-/**
- * Given a byte offset within the text, return the line number
- * of the line containing that offset (or -1 if offset invalid)
- *
- * \param c content of type CONTENT_TEXTPLAIN
- * \param offset byte offset within textual representation
- * \return line number, or -1 if offset invalid (larger than size)
- */
-
-int textplain_find_line(struct content *c, unsigned offset)
-{
- textplain_content *text = (textplain_content *) c;
- struct textplain_line *line;
- int nlines;
- int lineno = 0;
-
- assert(c != NULL);
-
- line = text->physical_line;
- nlines = text->physical_line_count;
-
- if (offset > text->utf8_data_size)
- return -1;
-
-/* \todo - implement binary search here */
- while (lineno < nlines && line[lineno].start < offset)
- lineno++;
- if (line[lineno].start > offset)
- lineno--;
-
- return lineno;
-}
-
-
-/**
- * Convert a character offset within a line of text into the
- * horizontal co-ordinate, taking into account the font being
- * used and any tabs in the text
- *
- * \param text line of text
- * \param offset char offset within text
- * \param length line length
- * \return x ordinate
- */
-
-int textplain_coord_from_offset(const char *text, size_t offset, size_t length)
-{
- int x = 0;
-
- while (offset > 0) {
- size_t next_offset = 0;
- int tx;
-
- while (next_offset < offset && text[next_offset] != '\t') {
- next_offset = utf8_next(text, length, next_offset);
- }
-
- guit->layout->width(&textplain_style, text, next_offset, &tx);
-
- x += tx;
-
- if (next_offset >= offset)
- break;
-
- /* align to next tab boundary */
- next_offset++;
- x = (1 + (x / textplain_tab_width)) * textplain_tab_width;
- offset -= next_offset;
- text += next_offset;
- length -= next_offset;
- }
-
- return x;
-}
-
-
-/**
- * Given a range of byte offsets within a UTF8 textplain content,
- * return a box that fully encloses the text
- *
- * \param c content of type CONTENT_TEXTPLAIN
- * \param start byte offset of start of text range
- * \param end byte offset of end
- * \param r rectangle to be completed
- */
-
-void textplain_coords_from_range(struct content *c, unsigned start,
- unsigned end, struct rect *r)
+/* exported interface documented in render/textplain.h */
+void
+textplain_coords_from_range(struct content *c,
+ unsigned start,
+ unsigned end,
+ struct rect *r)
{
textplain_content *text = (textplain_content *) c;
float line_height = textplain_line_height();
@@ -1273,42 +1239,38 @@ void textplain_coords_from_range(struct content *c, unsigned start,
r->y0 = (int)(MARGIN + lineno * line_height);
if (lineno + 1 <= nlines || line[lineno + 1].start >= end) {
- /* \todo - it may actually be more efficient just to run
- forwards most of the time */
+ /* \todo - it may actually be more efficient just to
+ * run forwards most of the time
+ */
/* find end */
lineno = textplain_find_line(c, end);
r->x0 = 0;
r->x1 = text->formatted_width;
- }
- else {
+ } else {
/* single line */
const char *text = utf8_data + line[lineno].start;
- r->x0 = textplain_coord_from_offset(text, start - line[lineno].start,
- line[lineno].length);
+ r->x0 = textplain_coord_from_offset(text,
+ start - line[lineno].start,
+ line[lineno].length);
- r->x1 = textplain_coord_from_offset(text, end - line[lineno].start,
- line[lineno].length);
+ r->x1 = textplain_coord_from_offset(text,
+ end - line[lineno].start,
+ line[lineno].length);
}
r->y1 = (int)(MARGIN + (lineno + 1) * line_height);
}
-/**
- * Return a pointer to the requested line of text.
- *
- * \param c content of type CONTENT_TEXTPLAIN
- * \param lineno line number
- * \param poffset receives byte offset of line start within text
- * \param plen receives length of returned line
- * \return pointer to text, or NULL if invalid line number
- */
-
-char *textplain_get_line(struct content *c, unsigned lineno,
- size_t *poffset, size_t *plen)
+/* exported interface documented in render/textplain.h */
+char *
+textplain_get_line(struct content *c,
+ unsigned lineno,
+ size_t *poffset,
+ size_t *plen)
{
textplain_content *text = (textplain_content *) c;
struct textplain_line *line;
@@ -1325,20 +1287,41 @@ char *textplain_get_line(struct content *c, unsigned lineno,
}
-/**
- * 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
- * in the saved/copied text of a selection.
- *
- * \param c content of type CONTENT_TEXTPLAIN
- * \param start starting byte offset within UTF-8 text
- * \param end ending byte offset
- * \param plen receives validated length
- * \return pointer to text, or NULL if no text
- */
+/* exported interface documented in render/textplain.h */
+int textplain_find_line(struct content *c, unsigned offset)
+{
+ textplain_content *text = (textplain_content *) c;
+ struct textplain_line *line;
+ int nlines;
+ int lineno = 0;
+
+ assert(c != NULL);
+
+ line = text->physical_line;
+ nlines = text->physical_line_count;
+
+ if (offset > text->utf8_data_size) {
+ return -1;
+ }
+
+/* \todo - implement binary search here */
+ while (lineno < nlines && line[lineno].start < offset) {
+ lineno++;
+ }
+ if (line[lineno].start > offset) {
+ lineno--;
+ }
-char *textplain_get_raw_data(struct content *c, unsigned start, unsigned end,
- size_t *plen)
+ return lineno;
+}
+
+
+/* exported interface documented in render/textplain.h */
+char *
+textplain_get_raw_data(struct content *c,
+ unsigned start,
+ unsigned end,
+ size_t *plen)
{
textplain_content *text = (textplain_content *) c;
size_t utf8_size;
@@ -1359,26 +1342,8 @@ char *textplain_get_raw_data(struct content *c, unsigned start, unsigned end,
return text->utf8_data + start;
}
-/**
- * Calculate the line height, in pixels
- *
- * \return Line height, in pixels
- */
-float textplain_line_height(void)
-{
- /* Size is in points, so convert to pixels.
- * Then use a constant line height of 1.2 x font size.
- */
- return FIXTOFLT(FDIV((FMUL(FLTTOFIX(1.2), FMUL(nscss_screen_dpi,
- INTTOFIX((textplain_style.size / FONT_SIZE_SCALE))))), F_72));
-}
-/**
- * Get the browser window containing a textplain content
- *
- * \param c text/plain content
- * \return the browser window
- */
+/* exported interface documented in render/textplain.h */
struct browser_window *textplain_get_browser_window(struct content *c)
{
textplain_content *text = (textplain_content *) c;
@@ -1388,4 +1353,3 @@ struct browser_window *textplain_get_browser_window(struct content *c)
return text->bw;
}
-
diff --git a/render/textplain.h b/render/textplain.h
index 6a88c34..0f0128e 100644
--- a/render/textplain.h
+++ b/render/textplain.h
@@ -17,12 +17,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/** \file
- * Content for text/plain (interface).
+/**
+ * \file
+ *
+ * Interface to content handler for plain text.
*/
-#ifndef _NETSURF_RENDER_TEXTPLAIN_H_
-#define _NETSURF_RENDER_TEXTPLAIN_H_
+#ifndef NETSURF_RENDER_TEXTPLAIN_H
+#define NETSURF_RENDER_TEXTPLAIN_H
#include <stddef.h>
#include "netsurf/mouse.h"
@@ -32,20 +34,106 @@ struct hlcache_handle;
struct http_parameter;
struct rect;
+/**
+ * Initialise the text content handler
+ *
+ * \return NSERROR_OK on success else appropriate error code.
+ */
nserror textplain_init(void);
-/* access to lines for text selection and searching */
+
+/**
+ * Retrieve number of lines in content
+ *
+ * \param[in] c Content to retrieve line count from
+ * \return Number of lines
+ */
unsigned long textplain_line_count(struct content *c);
+
+
+/**
+ * Retrieve the size (in bytes) of text data
+ *
+ * \param[in] c Content to retrieve size of
+ * \return Size, in bytes, of data
+ */
size_t textplain_size(struct content *c);
+
+/**
+ * Return byte offset within UTF8 textplain content.
+ *
+ * given the co-ordinates of a point within a textplain content. 'dir'
+ * specifies the direction in which to search (-1 = above-left, +1 =
+ * below-right) if the co-ordinates are not contained within a line.
+ *
+ * \param[in] c content of type CONTENT_TEXTPLAIN
+ * \param[in] x x ordinate of point
+ * \param[in] y y ordinate of point
+ * \param[in] dir direction of search if not within line
+ * \return byte offset of character containing (or nearest to) point
+ */
size_t textplain_offset_from_coords(struct content *c, int x, int y, int dir);
+
+
+/**
+ * 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 requested line of text.
+ *
+ * \param[in] c content of type CONTENT_TEXTPLAIN
+ * \param[in] lineno line number
+ * \param[out] poffset receives byte offset of line start within text
+ * \param[out] plen receives length of returned line
+ * \return pointer to text, or NULL if invalid line number
+ */
char *textplain_get_line(struct content *c, unsigned lineno,
size_t *poffset, size_t *plen);
+
+
+/**
+ * Find line number of byte in text
+ *
+ * Given a byte offset within the text, return the line number
+ * of the line containing that offset.
+ *
+ * \param[in] c content of type CONTENT_TEXTPLAIN
+ * \param[in] offset byte offset within textual representation
+ * \return line number, or -1 if offset invalid (larger than size)
+ */
int textplain_find_line(struct content *c, unsigned offset);
-char *textplain_get_raw_data(struct content *c,
- unsigned start, unsigned end, size_t *plen);
+
+
+/**
+ * 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
+ * in the saved/copied text of a selection.
+ *
+ * \param[in] c content of type CONTENT_TEXTPLAIN
+ * \param[in] start starting byte offset within UTF-8 text
+ * \param[in] end ending byte offset
+ * \param[out] plen receives validated length
+ * \return pointer to text, or NULL if no text
+ */
+char *textplain_get_raw_data(struct content *c, unsigned start, unsigned end, size_t *plen);
+
+
+/**
+ * Get the browser window containing a textplain content
+ *
+ * \param[in] c text/plain content
+ * \return the browser window
+ */
struct browser_window *textplain_get_browser_window(struct content *c);
#endif