mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
document/dom: Split rendering utilities to util.*
These are functions that are commonly used by the individual renderers to put stuff on the canvas etc.
This commit is contained in:
parent
f88f49d955
commit
144bd77240
@ -1,6 +1,6 @@
|
|||||||
top_builddir=../../..
|
top_builddir=../../..
|
||||||
include $(top_builddir)/Makefile.config
|
include $(top_builddir)/Makefile.config
|
||||||
|
|
||||||
OBJS = renderer.o
|
OBJS = renderer.o util.o
|
||||||
|
|
||||||
include $(top_srcdir)/Makefile.lib
|
include $(top_srcdir)/Makefile.lib
|
||||||
|
@ -12,15 +12,14 @@
|
|||||||
|
|
||||||
#include "elinks.h"
|
#include "elinks.h"
|
||||||
|
|
||||||
#include "bookmarks/bookmarks.h" /* get_bookmark() */
|
|
||||||
#include "cache/cache.h"
|
#include "cache/cache.h"
|
||||||
#include "document/css/css.h"
|
#include "document/css/css.h"
|
||||||
#include "document/css/parser.h"
|
#include "document/css/parser.h"
|
||||||
#include "document/css/property.h"
|
#include "document/css/property.h"
|
||||||
#include "document/css/stylesheet.h"
|
#include "document/css/stylesheet.h"
|
||||||
#include "document/docdata.h"
|
|
||||||
#include "document/document.h"
|
#include "document/document.h"
|
||||||
#include "document/dom/renderer.h"
|
#include "document/dom/renderer.h"
|
||||||
|
#include "document/dom/util.h"
|
||||||
#include "document/renderer.h"
|
#include "document/renderer.h"
|
||||||
#include "dom/configuration.h"
|
#include "dom/configuration.h"
|
||||||
#include "dom/scanner.h"
|
#include "dom/scanner.h"
|
||||||
@ -30,60 +29,17 @@
|
|||||||
#include "dom/node.h"
|
#include "dom/node.h"
|
||||||
#include "dom/stack.h"
|
#include "dom/stack.h"
|
||||||
#include "intl/charsets.h"
|
#include "intl/charsets.h"
|
||||||
#include "globhist/globhist.h" /* get_global_history_item() */
|
|
||||||
#include "protocol/uri.h"
|
#include "protocol/uri.h"
|
||||||
#include "terminal/draw.h"
|
#include "terminal/draw.h"
|
||||||
#include "util/box.h"
|
|
||||||
#include "util/error.h"
|
#include "util/error.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "util/snprintf.h"
|
#include "util/snprintf.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
|
|
||||||
|
|
||||||
struct dom_renderer {
|
|
||||||
enum sgml_document_type doctype;
|
|
||||||
struct document *document;
|
|
||||||
|
|
||||||
struct conv_table *convert_table;
|
|
||||||
enum convert_string_mode convert_mode;
|
|
||||||
|
|
||||||
struct uri *base_uri;
|
|
||||||
|
|
||||||
unsigned char *source;
|
|
||||||
unsigned char *end;
|
|
||||||
|
|
||||||
unsigned char *position;
|
|
||||||
int canvas_x, canvas_y;
|
|
||||||
|
|
||||||
#ifdef HAVE_REGEX_H
|
|
||||||
regex_t url_regex;
|
|
||||||
unsigned int find_url:1;
|
|
||||||
#endif
|
|
||||||
struct screen_char styles[DOM_NODES];
|
|
||||||
|
|
||||||
/* RSS renderer variables */
|
|
||||||
struct dom_node *channel;
|
|
||||||
struct dom_node_list *items;
|
|
||||||
struct dom_node *item;
|
|
||||||
struct dom_node *node;
|
|
||||||
struct dom_string text;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define URL_REGEX "(file://|((f|ht|nt)tp(s)?|smb)://[[:alnum:]]+([-@:.]?[[:alnum:]])*\\.[[:alpha:]]{2,4}(:[[:digit:]]+)?)(/(%[[:xdigit:]]{2}|[-_~&=;?.a-z0-9])*)*"
|
#define URL_REGEX "(file://|((f|ht|nt)tp(s)?|smb)://[[:alnum:]]+([-@:.]?[[:alnum:]])*\\.[[:alpha:]]{2,4}(:[[:digit:]]+)?)(/(%[[:xdigit:]]{2}|[-_~&=;?.a-z0-9])*)*"
|
||||||
#define URL_REGFLAGS (REG_ICASE | REG_EXTENDED)
|
#define URL_REGFLAGS (REG_ICASE | REG_EXTENDED)
|
||||||
|
|
||||||
static void
|
|
||||||
init_template(struct screen_char *template, struct document_options *options,
|
|
||||||
color_T background, color_T foreground, enum screen_char_attr attr)
|
|
||||||
{
|
|
||||||
struct color_pair colors = INIT_COLOR_PAIR(background, foreground);
|
|
||||||
|
|
||||||
template->attr = attr;
|
|
||||||
template->data = ' ';
|
|
||||||
set_term_color(template, &colors,
|
|
||||||
options->color_flags, options->color_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Checks the user CSS for properties for each DOM node type name */
|
/* Checks the user CSS for properties for each DOM node type name */
|
||||||
static inline void
|
static inline void
|
||||||
@ -200,245 +156,6 @@ done_dom_renderer(struct dom_renderer *renderer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Document maintainance */
|
|
||||||
|
|
||||||
static struct screen_char *
|
|
||||||
realloc_line(struct document *document, int x, int y)
|
|
||||||
{
|
|
||||||
struct line *line = realloc_lines(document, y);
|
|
||||||
|
|
||||||
if (!line) return NULL;
|
|
||||||
|
|
||||||
if (x > line->length) {
|
|
||||||
if (!ALIGN_LINE(&line->chars, line->length, x))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (; line->length < x; line->length++) {
|
|
||||||
line->chars[line->length].data = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x > document->width) document->width = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
return line->chars;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct node *
|
|
||||||
add_search_node(struct dom_renderer *renderer, int width)
|
|
||||||
{
|
|
||||||
struct node *node = mem_alloc(sizeof(*node));
|
|
||||||
|
|
||||||
if (node) {
|
|
||||||
set_box(&node->box, renderer->canvas_x, renderer->canvas_y,
|
|
||||||
width, 1);
|
|
||||||
add_to_list(renderer->document->nodes, node);
|
|
||||||
}
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define X(renderer) ((renderer)->canvas_x)
|
|
||||||
#define Y(renderer) ((renderer)->canvas_y)
|
|
||||||
#define POS(renderer) (&(renderer)->document->data[Y(renderer)].chars[X(renderer)])
|
|
||||||
#define WIDTH(renderer, add) ((renderer)->canvas_x + (add))
|
|
||||||
|
|
||||||
static void
|
|
||||||
render_dom_line(struct dom_renderer *renderer, struct screen_char *template,
|
|
||||||
unsigned char *string, int length)
|
|
||||||
{
|
|
||||||
struct document *document = renderer->document;
|
|
||||||
struct conv_table *convert = renderer->convert_table;
|
|
||||||
enum convert_string_mode mode = renderer->convert_mode;
|
|
||||||
int x, charlen;
|
|
||||||
#ifdef CONFIG_UTF8
|
|
||||||
int utf8 = document->options.utf8;
|
|
||||||
unsigned char *end;
|
|
||||||
#endif /* CONFIG_UTF8 */
|
|
||||||
|
|
||||||
|
|
||||||
assert(renderer && template && string && length);
|
|
||||||
|
|
||||||
string = convert_string(convert, string, length, document->options.cp,
|
|
||||||
mode, &length, NULL, NULL);
|
|
||||||
if (!string) return;
|
|
||||||
|
|
||||||
if (!realloc_line(document, WIDTH(renderer, length), Y(renderer))) {
|
|
||||||
mem_free(string);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
add_search_node(renderer, length);
|
|
||||||
|
|
||||||
#ifdef CONFIG_UTF8
|
|
||||||
end = string + length;
|
|
||||||
#endif /* CONFIG_UTF8 */
|
|
||||||
for (x = 0, charlen = 1; x < length;x += charlen, renderer->canvas_x++) {
|
|
||||||
unsigned char *text = &string[x];
|
|
||||||
|
|
||||||
/* This is mostly to be able to break out so the indentation
|
|
||||||
* level won't get to high. */
|
|
||||||
switch (*text) {
|
|
||||||
case ASCII_TAB:
|
|
||||||
{
|
|
||||||
int tab_width = 7 - (X(renderer) & 7);
|
|
||||||
int width = WIDTH(renderer, length - x + tab_width);
|
|
||||||
|
|
||||||
template->data = ' ';
|
|
||||||
|
|
||||||
if (!realloc_line(document, width, Y(renderer)))
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Only loop over the expanded tab chars and let the
|
|
||||||
* ``main loop'' add the actual tab char. */
|
|
||||||
for (; tab_width-- > 0; renderer->canvas_x++)
|
|
||||||
copy_screen_chars(POS(renderer), template, 1);
|
|
||||||
charlen = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
#ifdef CONFIG_UTF8
|
|
||||||
if (utf8) {
|
|
||||||
unicode_val_T data;
|
|
||||||
charlen = utf8charlen(text);
|
|
||||||
data = utf8_to_unicode(&text, end);
|
|
||||||
|
|
||||||
template->data = (unicode_val_T)data;
|
|
||||||
|
|
||||||
if (unicode_to_cell(data) == 2) {
|
|
||||||
copy_screen_chars(POS(renderer),
|
|
||||||
template, 1);
|
|
||||||
|
|
||||||
X(renderer)++;
|
|
||||||
template->data = UCS_NO_CHAR;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else
|
|
||||||
#endif /* CONFIG_UTF8 */
|
|
||||||
template->data = isscreensafe(*text) ? *text:'.';
|
|
||||||
}
|
|
||||||
|
|
||||||
copy_screen_chars(POS(renderer), template, 1);
|
|
||||||
}
|
|
||||||
mem_free(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline unsigned char *
|
|
||||||
split_dom_line(unsigned char *line, int length, int *linelen)
|
|
||||||
{
|
|
||||||
unsigned char *end = line + length;
|
|
||||||
unsigned char *pos;
|
|
||||||
|
|
||||||
/* End of line detection.
|
|
||||||
* We handle \r, \r\n and \n types here. */
|
|
||||||
for (pos = line; pos < end; pos++) {
|
|
||||||
int step = 0;
|
|
||||||
|
|
||||||
if (pos[step] == ASCII_CR)
|
|
||||||
step++;
|
|
||||||
|
|
||||||
if (pos[step] == ASCII_LF)
|
|
||||||
step++;
|
|
||||||
|
|
||||||
if (step) {
|
|
||||||
*linelen = pos - line;
|
|
||||||
return pos + step;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*linelen = length;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
render_dom_text(struct dom_renderer *renderer, struct screen_char *template,
|
|
||||||
unsigned char *string, int length)
|
|
||||||
{
|
|
||||||
int linelen;
|
|
||||||
|
|
||||||
for (; length > 0; string += linelen, length -= linelen) {
|
|
||||||
unsigned char *newline = split_dom_line(string, length, &linelen);
|
|
||||||
|
|
||||||
if (linelen)
|
|
||||||
render_dom_line(renderer, template, string, linelen);
|
|
||||||
|
|
||||||
if (newline) {
|
|
||||||
renderer->canvas_y++;
|
|
||||||
renderer->canvas_x = 0;
|
|
||||||
linelen = newline - string;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define realloc_document_links(doc, size) \
|
|
||||||
ALIGN_LINK(&(doc)->links, (doc)->nlinks, size)
|
|
||||||
|
|
||||||
static inline struct link *
|
|
||||||
add_dom_link(struct dom_renderer *renderer, unsigned char *string, int length,
|
|
||||||
unsigned char *uristring, int urilength)
|
|
||||||
{
|
|
||||||
struct document *document = renderer->document;
|
|
||||||
int x = renderer->canvas_x;
|
|
||||||
int y = renderer->canvas_y;
|
|
||||||
unsigned char *where;
|
|
||||||
struct link *link;
|
|
||||||
struct point *point;
|
|
||||||
struct screen_char template;
|
|
||||||
color_T fgcolor;
|
|
||||||
|
|
||||||
if (!realloc_document_links(document, document->nlinks + 1))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
link = &document->links[document->nlinks];
|
|
||||||
|
|
||||||
if (!realloc_points(link, length))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
uristring = convert_string(renderer->convert_table,
|
|
||||||
uristring, urilength, document->options.cp,
|
|
||||||
CSM_DEFAULT, NULL, NULL, NULL);
|
|
||||||
if (!uristring) return NULL;
|
|
||||||
|
|
||||||
where = join_urls(renderer->base_uri, uristring);
|
|
||||||
|
|
||||||
mem_free(uristring);
|
|
||||||
|
|
||||||
if (!where)
|
|
||||||
return NULL;
|
|
||||||
#ifdef CONFIG_GLOBHIST
|
|
||||||
else if (get_global_history_item(where))
|
|
||||||
fgcolor = document->options.default_vlink;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_BOOKMARKS
|
|
||||||
else if (get_bookmark(where))
|
|
||||||
fgcolor = document->options.default_bookmark_link;
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
fgcolor = document->options.default_link;
|
|
||||||
|
|
||||||
link->npoints = length;
|
|
||||||
link->type = LINK_HYPERTEXT;
|
|
||||||
link->where = where;
|
|
||||||
link->color.background = document->options.default_bg;
|
|
||||||
link->color.foreground = fgcolor;
|
|
||||||
link->number = document->nlinks;
|
|
||||||
|
|
||||||
init_template(&template, &document->options,
|
|
||||||
link->color.background, link->color.foreground, 0);
|
|
||||||
|
|
||||||
render_dom_text(renderer, &template, string, length);
|
|
||||||
|
|
||||||
for (point = link->points; length > 0; length--, point++, x++) {
|
|
||||||
point->x = x;
|
|
||||||
point->y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
document->nlinks++;
|
|
||||||
document->links_sorted = 0;
|
|
||||||
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* DOM Source Renderer */
|
/* DOM Source Renderer */
|
||||||
|
|
||||||
#define check_dom_node_source(renderer, str, len) \
|
#define check_dom_node_source(renderer, str, len) \
|
||||||
|
273
src/document/dom/util.c
Normal file
273
src/document/dom/util.c
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
/* Utilities for rendering document bits */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h> /* FreeBSD needs this before regex.h */
|
||||||
|
#ifdef HAVE_REGEX_H
|
||||||
|
#include <regex.h>
|
||||||
|
#endif
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "elinks.h"
|
||||||
|
|
||||||
|
#include "bookmarks/bookmarks.h" /* get_bookmark() */
|
||||||
|
#include "document/docdata.h"
|
||||||
|
#include "document/document.h"
|
||||||
|
#include "document/dom/util.h"
|
||||||
|
#include "intl/charsets.h"
|
||||||
|
#include "globhist/globhist.h" /* get_global_history_item() */
|
||||||
|
#include "protocol/uri.h"
|
||||||
|
#include "terminal/draw.h"
|
||||||
|
#include "util/error.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/box.h"
|
||||||
|
|
||||||
|
|
||||||
|
inline void
|
||||||
|
init_template(struct screen_char *template, struct document_options *options,
|
||||||
|
color_T background, color_T foreground, enum screen_char_attr attr)
|
||||||
|
{
|
||||||
|
struct color_pair colors = INIT_COLOR_PAIR(background, foreground);
|
||||||
|
|
||||||
|
template->attr = attr;
|
||||||
|
template->data = ' ';
|
||||||
|
set_term_color(template, &colors,
|
||||||
|
options->color_flags, options->color_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct screen_char *
|
||||||
|
realloc_line(struct document *document, int x, int y)
|
||||||
|
{
|
||||||
|
struct line *line = realloc_lines(document, y);
|
||||||
|
|
||||||
|
if (!line) return NULL;
|
||||||
|
|
||||||
|
if (x > line->length) {
|
||||||
|
if (!ALIGN_LINE(&line->chars, line->length, x))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (; line->length < x; line->length++) {
|
||||||
|
line->chars[line->length].data = ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x > document->width) document->width = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
return line->chars;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct node *
|
||||||
|
add_search_node(struct dom_renderer *renderer, int width)
|
||||||
|
{
|
||||||
|
struct node *node = mem_alloc(sizeof(*node));
|
||||||
|
|
||||||
|
if (node) {
|
||||||
|
set_box(&node->box, renderer->canvas_x, renderer->canvas_y,
|
||||||
|
width, 1);
|
||||||
|
add_to_list(renderer->document->nodes, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define POS(renderer) (&(renderer)->document->data[Y(renderer)].chars[X(renderer)])
|
||||||
|
#define WIDTH(renderer, add) ((renderer)->canvas_x + (add))
|
||||||
|
|
||||||
|
static void
|
||||||
|
render_dom_line(struct dom_renderer *renderer, struct screen_char *template,
|
||||||
|
unsigned char *string, int length)
|
||||||
|
{
|
||||||
|
struct document *document = renderer->document;
|
||||||
|
struct conv_table *convert = renderer->convert_table;
|
||||||
|
enum convert_string_mode mode = renderer->convert_mode;
|
||||||
|
int x, charlen;
|
||||||
|
#ifdef CONFIG_UTF8
|
||||||
|
int utf8 = document->options.utf8;
|
||||||
|
unsigned char *end;
|
||||||
|
#endif /* CONFIG_UTF8 */
|
||||||
|
|
||||||
|
|
||||||
|
assert(renderer && template && string && length);
|
||||||
|
|
||||||
|
string = convert_string(convert, string, length, document->options.cp,
|
||||||
|
mode, &length, NULL, NULL);
|
||||||
|
if (!string) return;
|
||||||
|
|
||||||
|
if (!realloc_line(document, WIDTH(renderer, length), Y(renderer))) {
|
||||||
|
mem_free(string);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_search_node(renderer, length);
|
||||||
|
|
||||||
|
#ifdef CONFIG_UTF8
|
||||||
|
end = string + length;
|
||||||
|
#endif /* CONFIG_UTF8 */
|
||||||
|
for (x = 0, charlen = 1; x < length;x += charlen, renderer->canvas_x++) {
|
||||||
|
unsigned char *text = &string[x];
|
||||||
|
|
||||||
|
/* This is mostly to be able to break out so the indentation
|
||||||
|
* level won't get to high. */
|
||||||
|
switch (*text) {
|
||||||
|
case ASCII_TAB:
|
||||||
|
{
|
||||||
|
int tab_width = 7 - (X(renderer) & 7);
|
||||||
|
int width = WIDTH(renderer, length - x + tab_width);
|
||||||
|
|
||||||
|
template->data = ' ';
|
||||||
|
|
||||||
|
if (!realloc_line(document, width, Y(renderer)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Only loop over the expanded tab chars and let the
|
||||||
|
* ``main loop'' add the actual tab char. */
|
||||||
|
for (; tab_width-- > 0; renderer->canvas_x++)
|
||||||
|
copy_screen_chars(POS(renderer), template, 1);
|
||||||
|
charlen = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
#ifdef CONFIG_UTF8
|
||||||
|
if (utf8) {
|
||||||
|
unicode_val_T data;
|
||||||
|
charlen = utf8charlen(text);
|
||||||
|
data = utf8_to_unicode(&text, end);
|
||||||
|
|
||||||
|
template->data = (unicode_val_T)data;
|
||||||
|
|
||||||
|
if (unicode_to_cell(data) == 2) {
|
||||||
|
copy_screen_chars(POS(renderer),
|
||||||
|
template, 1);
|
||||||
|
|
||||||
|
X(renderer)++;
|
||||||
|
template->data = UCS_NO_CHAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else
|
||||||
|
#endif /* CONFIG_UTF8 */
|
||||||
|
template->data = isscreensafe(*text) ? *text:'.';
|
||||||
|
}
|
||||||
|
|
||||||
|
copy_screen_chars(POS(renderer), template, 1);
|
||||||
|
}
|
||||||
|
mem_free(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned char *
|
||||||
|
split_dom_line(unsigned char *line, int length, int *linelen)
|
||||||
|
{
|
||||||
|
unsigned char *end = line + length;
|
||||||
|
unsigned char *pos;
|
||||||
|
|
||||||
|
/* End of line detection.
|
||||||
|
* We handle \r, \r\n and \n types here. */
|
||||||
|
for (pos = line; pos < end; pos++) {
|
||||||
|
int step = 0;
|
||||||
|
|
||||||
|
if (pos[step] == ASCII_CR)
|
||||||
|
step++;
|
||||||
|
|
||||||
|
if (pos[step] == ASCII_LF)
|
||||||
|
step++;
|
||||||
|
|
||||||
|
if (step) {
|
||||||
|
*linelen = pos - line;
|
||||||
|
return pos + step;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*linelen = length;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
render_dom_text(struct dom_renderer *renderer, struct screen_char *template,
|
||||||
|
unsigned char *string, int length)
|
||||||
|
{
|
||||||
|
int linelen;
|
||||||
|
|
||||||
|
for (; length > 0; string += linelen, length -= linelen) {
|
||||||
|
unsigned char *newline = split_dom_line(string, length, &linelen);
|
||||||
|
|
||||||
|
if (linelen)
|
||||||
|
render_dom_line(renderer, template, string, linelen);
|
||||||
|
|
||||||
|
if (newline) {
|
||||||
|
renderer->canvas_y++;
|
||||||
|
renderer->canvas_x = 0;
|
||||||
|
linelen = newline - string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define realloc_document_links(doc, size) \
|
||||||
|
ALIGN_LINK(&(doc)->links, (doc)->nlinks, size)
|
||||||
|
|
||||||
|
inline struct link *
|
||||||
|
add_dom_link(struct dom_renderer *renderer, unsigned char *string, int length,
|
||||||
|
unsigned char *uristring, int urilength)
|
||||||
|
{
|
||||||
|
struct document *document = renderer->document;
|
||||||
|
int x = renderer->canvas_x;
|
||||||
|
int y = renderer->canvas_y;
|
||||||
|
unsigned char *where;
|
||||||
|
struct link *link;
|
||||||
|
struct point *point;
|
||||||
|
struct screen_char template;
|
||||||
|
color_T fgcolor;
|
||||||
|
|
||||||
|
if (!realloc_document_links(document, document->nlinks + 1))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
link = &document->links[document->nlinks];
|
||||||
|
|
||||||
|
if (!realloc_points(link, length))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
uristring = convert_string(renderer->convert_table,
|
||||||
|
uristring, urilength, document->options.cp,
|
||||||
|
CSM_DEFAULT, NULL, NULL, NULL);
|
||||||
|
if (!uristring) return NULL;
|
||||||
|
|
||||||
|
where = join_urls(renderer->base_uri, uristring);
|
||||||
|
|
||||||
|
mem_free(uristring);
|
||||||
|
|
||||||
|
if (!where)
|
||||||
|
return NULL;
|
||||||
|
#ifdef CONFIG_GLOBHIST
|
||||||
|
else if (get_global_history_item(where))
|
||||||
|
fgcolor = document->options.default_vlink;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_BOOKMARKS
|
||||||
|
else if (get_bookmark(where))
|
||||||
|
fgcolor = document->options.default_bookmark_link;
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
fgcolor = document->options.default_link;
|
||||||
|
|
||||||
|
link->npoints = length;
|
||||||
|
link->type = LINK_HYPERTEXT;
|
||||||
|
link->where = where;
|
||||||
|
link->color.background = document->options.default_bg;
|
||||||
|
link->color.foreground = fgcolor;
|
||||||
|
link->number = document->nlinks;
|
||||||
|
|
||||||
|
init_template(&template, &document->options,
|
||||||
|
link->color.background, link->color.foreground, 0);
|
||||||
|
|
||||||
|
render_dom_text(renderer, &template, string, length);
|
||||||
|
|
||||||
|
for (point = link->points; length > 0; length--, point++, x++) {
|
||||||
|
point->x = x;
|
||||||
|
point->y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
document->nlinks++;
|
||||||
|
document->links_sorted = 0;
|
||||||
|
|
||||||
|
return link;
|
||||||
|
}
|
64
src/document/dom/util.h
Normal file
64
src/document/dom/util.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#ifndef EL__DOCUMENT_DOM_UTIL_H
|
||||||
|
#define EL__DOCUMENT_DOM_UTIL_H
|
||||||
|
|
||||||
|
/* This header is meant to be used only amongst the DOM renderers. */
|
||||||
|
|
||||||
|
#include <sys/types.h> /* FreeBSD needs this before regex.h */
|
||||||
|
#ifdef HAVE_REGEX_H
|
||||||
|
#include <regex.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "dom/sgml/sgml.h"
|
||||||
|
#include "intl/charsets.h"
|
||||||
|
#include "terminal/draw.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct document;
|
||||||
|
struct uri;
|
||||||
|
struct dom_node;
|
||||||
|
struct dom_node_list;
|
||||||
|
struct dom_string;
|
||||||
|
|
||||||
|
struct dom_renderer {
|
||||||
|
enum sgml_document_type doctype;
|
||||||
|
struct document *document;
|
||||||
|
|
||||||
|
struct conv_table *convert_table;
|
||||||
|
enum convert_string_mode convert_mode;
|
||||||
|
|
||||||
|
struct uri *base_uri;
|
||||||
|
|
||||||
|
unsigned char *source;
|
||||||
|
unsigned char *end;
|
||||||
|
|
||||||
|
unsigned char *position;
|
||||||
|
int canvas_x, canvas_y;
|
||||||
|
|
||||||
|
#ifdef HAVE_REGEX_H
|
||||||
|
regex_t url_regex;
|
||||||
|
unsigned int find_url:1;
|
||||||
|
#endif
|
||||||
|
struct screen_char styles[DOM_NODES];
|
||||||
|
|
||||||
|
/* RSS renderer variables */
|
||||||
|
struct dom_node *channel;
|
||||||
|
struct dom_node_list *items;
|
||||||
|
struct dom_node *item;
|
||||||
|
struct dom_node *node;
|
||||||
|
struct dom_string text;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define X(renderer) ((renderer)->canvas_x)
|
||||||
|
#define Y(renderer) ((renderer)->canvas_y)
|
||||||
|
|
||||||
|
|
||||||
|
void init_template(struct screen_char *template,
|
||||||
|
struct document_options *options,
|
||||||
|
color_T background, color_T foreground,
|
||||||
|
enum screen_char_attr attr);
|
||||||
|
void render_dom_text(struct dom_renderer *renderer, struct screen_char *template,
|
||||||
|
unsigned char *string, int length);
|
||||||
|
struct link *add_dom_link(struct dom_renderer *renderer, unsigned char *string,
|
||||||
|
int length, unsigned char *uristring, int urilength);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user