From c91c763d49bc7cd01aa06c0dabbd15fecc97da80 Mon Sep 17 00:00:00 2001 From: Miciah Dashiel Butler Masters Date: Sun, 28 May 2006 01:08:46 +0000 Subject: [PATCH] Eliminate link_bg Instead of saving the old link colours when selecting a link and using that to restore them when unselecting it, just copy the data from the document. - Eliminate struct link_bg and the .link_bg and .link_bg_n members of struct document_view. - Eliminate the free_link routine and don't call it from draw_doc, clear_link, or detach_formatted. - Add a .old_current_link member to struct view_state and initialise it in init_vs. - Don't save link_bg in draw_current_link. - Rewrite clear_link to use the document data instead of link_bg. - Modify init_link_drawing not to allocate ling_bg and to return a pointer to a static variable for the template character. --- src/document/view.h | 22 ++++-------- src/viewer/text/draw.c | 1 - src/viewer/text/link.c | 79 +++++++++++++----------------------------- src/viewer/text/link.h | 1 - src/viewer/text/view.c | 1 - src/viewer/text/vs.c | 1 + src/viewer/text/vs.h | 1 + 7 files changed, 33 insertions(+), 73 deletions(-) diff --git a/src/document/view.h b/src/document/view.h index 931c1ca3..1e134df6 100644 --- a/src/document/view.h +++ b/src/document/view.h @@ -9,11 +9,6 @@ struct document; struct view_state; -struct link_bg { - int x, y; - struct screen_char c; -}; - struct document_view { LIST_HEAD(struct document_view); @@ -24,23 +19,18 @@ struct document_view { struct document *document; struct view_state *vs; - /* The elements of this array correspond to the points of the active - * link. Each element stores the colour and attributes - * that the corresponding point had before the link was selected. - * The last element is an exception: it is the template character, - * which holds the colour and attributes that the active link was - * given upon being selected. */ - /* XXX: The above is guesswork; please confirm or correct. -- Miciah */ - struct link_bg *link_bg; - - int link_bg_n; /* number of elements in link_bg, - not including the template */ struct box box; /* pos and size of window */ int last_x, last_y; /* last pos of window */ int depth; int used; }; +#define get_old_current_link(doc_view) \ + (((doc_view) \ + && (doc_view)->vs->old_current_link >= 0 \ + && (doc_view)->vs->old_current_link < (doc_view)->document->nlinks) \ + ? &(doc_view)->document->links[(doc_view)->vs->old_current_link] : NULL) + #define get_current_link(doc_view) \ (((doc_view) \ && (doc_view)->vs->current_link >= 0 \ diff --git a/src/viewer/text/draw.c b/src/viewer/text/draw.c index cdf87603..c1f0362b 100644 --- a/src/viewer/text/draw.c +++ b/src/viewer/text/draw.c @@ -257,7 +257,6 @@ draw_doc(struct session *ses, struct document_view *doc_view, int active) draw_view_status(ses, doc_view, active); return; } - free_link(doc_view); doc_view->last_x = vx; doc_view->last_y = vy; draw_box(term, box, ' ', 0, &color); diff --git a/src/viewer/text/link.c b/src/viewer/text/link.c index 33db7f1e..34d54102 100644 --- a/src/viewer/text/link.c +++ b/src/viewer/text/link.c @@ -141,29 +141,18 @@ get_link_cursor_offset(struct document_view *doc_view, struct link *link) return 0; } -/* Allocate doc_view->link_bg with enough space to save the colour - * and attributes of each point of the given link plus one byte - * for the template character. Initialise that template character - * with the colour and attributes appropriate for an active link. */ +/* Initialise a static template character with the colour and attributes + * appropriate for an active link and return that character. */ static inline struct screen_char * init_link_drawing(struct document_view *doc_view, struct link *link, int invert) { struct document_options *doc_opts; - struct screen_char *template; + static struct screen_char template; enum color_flags color_flags; enum color_mode color_mode; struct color_pair colors; - /* Allocate an extra background char to work on here. */ - doc_view->link_bg = mem_alloc((1 + link->npoints) * sizeof(*doc_view->link_bg)); - if (!doc_view->link_bg) return NULL; - - doc_view->link_bg_n = link->npoints; - - /* Setup the template char. */ - template = &doc_view->link_bg[link->npoints].c; - - template->attr = SCREEN_ATTR_STANDOUT; + template.attr = SCREEN_ATTR_STANDOUT; doc_opts = &doc_view->document->options; @@ -171,10 +160,10 @@ init_link_drawing(struct document_view *doc_view, struct link *link, int invert) color_mode = doc_opts->color_mode; if (doc_opts->active_link.underline) - template->attr |= SCREEN_ATTR_UNDERLINE; + template.attr |= SCREEN_ATTR_UNDERLINE; if (doc_opts->active_link.bold) - template->attr |= SCREEN_ATTR_BOLD; + template.attr |= SCREEN_ATTR_BOLD; if (doc_opts->active_link.color) { colors.foreground = doc_opts->active_link.fg; @@ -207,13 +196,12 @@ init_link_drawing(struct document_view *doc_view, struct link *link, int invert) } } - set_term_color(template, &colors, color_flags, color_mode); + set_term_color(&template, &colors, color_flags, color_mode); - return template; + return &template; } -/* Save the current link's colours and attributes to doc_view->link_bg - * and give it the appropriate colour and attributes for an active link. */ +/* Give the current link the appropriate colour and attributes. */ void draw_current_link(struct session *ses, struct document_view *doc_view) { @@ -230,9 +218,6 @@ draw_current_link(struct session *ses, struct document_view *doc_view) assert(ses->tab == get_current_tab(term)); if_assert_failed return; - assertm(!doc_view->link_bg, "link background not empty"); - if_assert_failed mem_free(doc_view->link_bg); - link = get_current_link(doc_view); if (!link) return; @@ -258,16 +243,10 @@ draw_current_link(struct session *ses, struct document_view *doc_view) struct screen_char *co; if (!is_in_box(&doc_view->box, x, y)) { - doc_view->link_bg[i].x = -1; - doc_view->link_bg[i].y = -1; continue; } - doc_view->link_bg[i].x = x; - doc_view->link_bg[i].y = y; - co = get_char(term, x, y); - copy_screen_chars(&doc_view->link_bg[i].c, co, 1); if (i == cursor_offset) { int blockable = (!link_is_textinput(link) @@ -281,16 +260,8 @@ draw_current_link(struct session *ses, struct document_view *doc_view) copy_screen_chars(co, template, 1); set_screen_dirty(term->screen, y, y); } -} -void -free_link(struct document_view *doc_view) -{ - assert(doc_view); - if_assert_failed return; - - mem_free_set(&doc_view->link_bg, NULL); - doc_view->link_bg_n = 0; + doc_view->vs->old_current_link = doc_view->vs->current_link; } /* Restore the colours and attributes that the active link had @@ -298,28 +269,28 @@ free_link(struct document_view *doc_view) void clear_link(struct terminal *term, struct document_view *doc_view) { - assert(term && doc_view); - if_assert_failed return; + struct link *link = get_current_link(doc_view); + struct link *last = get_old_current_link(doc_view); - if (doc_view->link_bg) { - struct link_bg *link_bg = doc_view->link_bg; + if (last && last != link) { + int xpos = doc_view->box.x - doc_view->vs->x; + int ypos = doc_view->box.y - doc_view->vs->y; int i; - for (i = doc_view->link_bg_n - 1; i >= 0; i--) { - struct link_bg *bgchar = &link_bg[i]; + for (i = 0; i < last->npoints; ++i) { + int x = last->points[i].x; + int y = last->points[i].y; - if (bgchar->x != -1 && bgchar->y != -1) { - struct terminal_screen *screen = term->screen; - struct screen_char *co; - - co = get_char(term, bgchar->x, bgchar->y); - copy_screen_chars(co, &bgchar->c, 1); - set_screen_dirty(screen, bgchar->y, bgchar->y); + if (is_in_box(&doc_view->box, x + xpos, y + ypos)){ + struct screen_char *ch; + + ch = get_char(term, x + xpos, y + ypos); + copy_struct(ch, &doc_view->document->data[y].chars[x]); } } - - free_link(doc_view); } + + doc_view->vs->old_current_link = doc_view->vs->current_link; } void diff --git a/src/viewer/text/link.h b/src/viewer/text/link.h index 4cfc5491..14e1d3ef 100644 --- a/src/viewer/text/link.h +++ b/src/viewer/text/link.h @@ -13,7 +13,6 @@ struct terminal; struct uri; void set_link(struct document_view *doc_view); -void free_link(struct document_view *doc_view); void clear_link(struct terminal *term, struct document_view *doc_view); void draw_current_link(struct session *ses, struct document_view *doc_view); diff --git a/src/viewer/text/view.c b/src/viewer/text/view.c index f135528b..963c15ce 100644 --- a/src/viewer/text/view.c +++ b/src/viewer/text/view.c @@ -75,7 +75,6 @@ detach_formatted(struct document_view *doc_view) doc_view->vs->doc_view = NULL; doc_view->vs = NULL; } - if (doc_view->link_bg) free_link(doc_view); mem_free_set(&doc_view->name, NULL); } diff --git a/src/viewer/text/vs.c b/src/viewer/text/vs.c index c5067cfc..99cf249e 100644 --- a/src/viewer/text/vs.c +++ b/src/viewer/text/vs.c @@ -28,6 +28,7 @@ init_vs(struct view_state *vs, struct uri *uri, int plain) { memset(vs, 0, sizeof(*vs)); vs->current_link = -1; + vs->old_current_link = -1; vs->plain = plain; vs->uri = uri ? get_uri_reference(uri) : NULL; vs->did_fragment = !uri->fragmentlen; diff --git a/src/viewer/text/vs.h b/src/viewer/text/vs.h index b19ce2f5..84336bd1 100644 --- a/src/viewer/text/vs.h +++ b/src/viewer/text/vs.h @@ -20,6 +20,7 @@ struct view_state { int x, y; int current_link; + int old_current_link; int plain; unsigned int wrap:1;