mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-23 12:36:51 +03:00
Remove pointless nasty skanky broken box tree duplication from hell
svn path=/trunk/netsurf/; revision=11970
This commit is contained in:
parent
7e85d15cb6
commit
68e12d28f9
276
render/box.c
276
render/box.c
@ -51,13 +51,6 @@ static bool box_nearest_text_box(struct box *box, int bx, int by,
|
||||
#define box_is_float(box) (box->type == BOX_FLOAT_LEFT || \
|
||||
box->type == BOX_FLOAT_RIGHT)
|
||||
|
||||
typedef struct box_duplicate_llist box_duplicate_llist;
|
||||
struct box_duplicate_llist {
|
||||
struct box_duplicate_llist *prev;
|
||||
struct box *box;
|
||||
};
|
||||
static struct box_duplicate_llist *box_duplicate_last = NULL;
|
||||
|
||||
/**
|
||||
* Allocator
|
||||
*
|
||||
@ -1006,275 +999,6 @@ void box_dump(FILE *stream, struct box *box, unsigned int depth)
|
||||
}
|
||||
}
|
||||
|
||||
/* Box tree duplication below
|
||||
*/
|
||||
|
||||
/** structure for translating addresses in the box tree */
|
||||
struct box_dict_element{
|
||||
struct box *old, *new;
|
||||
};
|
||||
|
||||
static bool box_duplicate_main_tree(struct box *box, struct content *c,
|
||||
int *count);
|
||||
static void box_duplicate_create_dict(struct box *old_box, struct box *new_box,
|
||||
struct box_dict_element **dict);
|
||||
static void box_duplicate_update( struct box *box,
|
||||
struct box_dict_element *dict,
|
||||
int n);
|
||||
|
||||
static int box_compare_dict_elements(const struct box_dict_element *a,
|
||||
const struct box_dict_element *b);
|
||||
|
||||
int box_compare_dict_elements(const struct box_dict_element *a,
|
||||
const struct box_dict_element *b)
|
||||
{
|
||||
return (a->old < b->old) ? -1 : ((a->old > b->old) ? 1 : 0);
|
||||
}
|
||||
|
||||
/** Duplication of a box tree. We assume that all the content is fetched,
|
||||
and we reuse a lot of content like strings, fetched objects etc - just
|
||||
replicating all we need to create two different layouts.
|
||||
\return true on success, false on lack of memory
|
||||
*/
|
||||
struct box* box_duplicate_tree(struct box *root, struct content *c)
|
||||
{
|
||||
struct box *new_root;/**< Root of the new box tree*/
|
||||
int box_number = 0;
|
||||
struct box_dict_element *box_dict, *box_dict_end;
|
||||
|
||||
box_duplicate_last = NULL;
|
||||
|
||||
/* 1. Duplicate parent - children structure, list_markers*/
|
||||
new_root = talloc_memdup(c, root, sizeof (struct box));
|
||||
if (!box_duplicate_main_tree(new_root, c, &box_number))
|
||||
return NULL;
|
||||
|
||||
/* 2. Create address translation dictionary*/
|
||||
/*TODO: dont save unnecessary addresses*/
|
||||
|
||||
box_dict_end = box_dict = malloc(box_number *
|
||||
sizeof(struct box_dict_element));
|
||||
|
||||
if (box_dict == NULL)
|
||||
return NULL;
|
||||
box_duplicate_create_dict(root, new_root, &box_dict_end);
|
||||
|
||||
assert((box_dict_end - box_dict) == box_number);
|
||||
|
||||
/*3. Sort it*/
|
||||
|
||||
qsort(box_dict, (box_dict_end - box_dict), sizeof(struct box_dict_element),
|
||||
(int (*)(const void *, const void *))box_compare_dict_elements);
|
||||
|
||||
/* 4. Update inline_end and float_children pointers */
|
||||
|
||||
box_duplicate_update(new_root, box_dict, (box_dict_end - box_dict));
|
||||
|
||||
free(box_dict);
|
||||
|
||||
return new_root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively duplicates children of an element, and also if present - its
|
||||
* list_marker, style and text.
|
||||
* \param box Current box to duplicate its children
|
||||
* \param c talloc memory pool
|
||||
* \param count number of boxes seen so far
|
||||
* \return true if successful, false otherwise (lack of memory)
|
||||
*/
|
||||
bool box_duplicate_main_tree(struct box *box, struct content *c, int *count)
|
||||
{
|
||||
struct box *b, *prev;
|
||||
|
||||
prev = NULL;
|
||||
|
||||
for (b = box->children; b; b = b->next) {
|
||||
struct box *copy;
|
||||
|
||||
/*Copy child*/
|
||||
copy = talloc_memdup(c, b, sizeof (struct box));
|
||||
if (copy == NULL)
|
||||
return false;
|
||||
|
||||
copy->parent = box;
|
||||
|
||||
if (prev != NULL)
|
||||
prev->next = copy;
|
||||
else
|
||||
box->children = copy;
|
||||
|
||||
if (copy->type == BOX_INLINE) {
|
||||
struct box_duplicate_llist *temp;
|
||||
|
||||
temp = malloc(sizeof(struct box_duplicate_llist));
|
||||
if (temp == NULL)
|
||||
return false;
|
||||
temp->prev = box_duplicate_last;
|
||||
temp->box = copy;
|
||||
box_duplicate_last = temp;
|
||||
}
|
||||
else if (copy->type == BOX_INLINE_END) {
|
||||
struct box_duplicate_llist *temp;
|
||||
|
||||
box_duplicate_last->box->inline_end = copy;
|
||||
copy->inline_end = box_duplicate_last->box;
|
||||
|
||||
temp = box_duplicate_last;
|
||||
box_duplicate_last = temp->prev;
|
||||
free(temp);
|
||||
}
|
||||
|
||||
/* Recursively visit child */
|
||||
if (!box_duplicate_main_tree(copy, c, count))
|
||||
return false;
|
||||
|
||||
prev = copy;
|
||||
}
|
||||
|
||||
box->last = prev;
|
||||
|
||||
if (box->object != NULL && option_suppress_images && (
|
||||
#ifdef WITH_JPEG
|
||||
content_get_type(box->object) == CONTENT_JPEG ||
|
||||
#endif
|
||||
#ifdef WITH_GIF
|
||||
content_get_type(box->object) == CONTENT_GIF ||
|
||||
#endif
|
||||
#ifdef WITH_BMP
|
||||
content_get_type(box->object) == CONTENT_BMP ||
|
||||
content_get_type(box->object) == CONTENT_ICO ||
|
||||
#endif
|
||||
#if defined(WITH_MNG) || defined(WITH_PNG)
|
||||
content_get_type(box->object) == CONTENT_PNG ||
|
||||
#endif
|
||||
#ifdef WITH_MNG
|
||||
content_get_type(box->object) == CONTENT_JNG ||
|
||||
content_get_type(box->object) == CONTENT_MNG ||
|
||||
#endif
|
||||
#ifdef WITH_WEBP
|
||||
content_get_type(box->object) == CONTENT_WEBP ||
|
||||
#endif
|
||||
#ifdef WITH_AMIGA_ICON
|
||||
content_get_type(box->object) == CONTENT_AMIGA_ICON ||
|
||||
#endif
|
||||
#if defined(WITH_SPRITE) || defined(WITH_NSSPRITE)
|
||||
content_get_type(box->object) == CONTENT_SPRITE ||
|
||||
#endif
|
||||
#ifdef WITH_DRAW
|
||||
content_get_type(box->object) == CONTENT_DRAW ||
|
||||
#endif
|
||||
#ifdef WITH_PLUGIN
|
||||
content_get_type(box->object) == CONTENT_PLUGIN ||
|
||||
#endif
|
||||
#ifdef WITH_THEME_INSTALL
|
||||
content_get_type(box->object) == CONTENT_THEME ||
|
||||
#endif
|
||||
#ifdef WITH_ARTWORKS
|
||||
content_get_type(box->object) == CONTENT_ARTWORKS ||
|
||||
#endif
|
||||
#if defined(WITH_NS_SVG) || defined(WITH_RSVG)
|
||||
content_get_type(box->object) == CONTENT_SVG ||
|
||||
#endif
|
||||
#ifdef WITH_APPLE_IMAGE
|
||||
content_get_type(box->object) == CONTENT_APPLE_IMAGE ||
|
||||
#endif
|
||||
false))
|
||||
box->object = NULL;
|
||||
|
||||
if (box->list_marker) {
|
||||
box->list_marker = talloc_memdup(c, box->list_marker,
|
||||
sizeof *box->list_marker);
|
||||
if (box->list_marker == NULL)
|
||||
return false;
|
||||
box->list_marker->parent = box;
|
||||
}
|
||||
|
||||
if (box->text) {
|
||||
box->text = talloc_memdup(c, box->text, box->length);
|
||||
if (box->text == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (box->style) {
|
||||
box->style = talloc_memdup(c, box->style, sizeof *box->style);
|
||||
if (box->style == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*Make layout calculate the size of this element later
|
||||
(might change because of font change etc.) */
|
||||
box->width = UNKNOWN_WIDTH;
|
||||
box->min_width = 0;
|
||||
box->max_width = UNKNOWN_MAX_WIDTH;
|
||||
|
||||
(*count)++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively creates a dictionary of addresses - binding the address of a box
|
||||
* with its copy.
|
||||
* \param old_box original box
|
||||
* \param new_box copy of the original box
|
||||
* \param dict pointer to a pointer to the current position in the dictionary
|
||||
*/
|
||||
void box_duplicate_create_dict(struct box *old_box, struct box *new_box,
|
||||
struct box_dict_element **dict)
|
||||
{
|
||||
/**Children of the old and new boxes*/
|
||||
struct box *b_old, *b_new;
|
||||
|
||||
for (b_old = old_box->children, b_new = new_box->children;
|
||||
b_old != NULL && b_new != NULL;
|
||||
b_old = b_old->next, b_new = b_new->next)
|
||||
box_duplicate_create_dict(b_old, b_new, dict);
|
||||
|
||||
/*The new tree should be a exact copy*/
|
||||
assert(b_old == NULL && b_new == NULL);
|
||||
|
||||
(*dict)->old = old_box;
|
||||
(*dict)->new = new_box;
|
||||
(*dict)++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively updates pointers in box tree.
|
||||
* \param box current box in the new box tree
|
||||
* \param box_dict box pointers dictionary
|
||||
* \param n number of memory addresses in the dictionary
|
||||
*/
|
||||
void box_duplicate_update(struct box *box,
|
||||
struct box_dict_element *box_dict,
|
||||
int n)
|
||||
{
|
||||
struct box_dict_element *box_dict_element;
|
||||
struct box *b;
|
||||
struct box_dict_element element;
|
||||
|
||||
for (b = box->children; b; b = b->next)
|
||||
box_duplicate_update(b, box_dict, n);
|
||||
|
||||
if (box->float_children) {
|
||||
element.old = box->float_children;
|
||||
box_dict_element = bsearch(&element,
|
||||
box_dict, n,
|
||||
sizeof(struct box_dict_element),
|
||||
(int (*)(const void *, const void *))box_compare_dict_elements);
|
||||
box->float_children = box_dict_element->new;
|
||||
}
|
||||
|
||||
if (box->next_float) {
|
||||
element.old = box->next_float;
|
||||
box_dict_element = bsearch(&element,
|
||||
box_dict, n,
|
||||
sizeof(struct box_dict_element),
|
||||
(int (*)(const void *, const void *))box_compare_dict_elements);
|
||||
box->next_float = box_dict_element->new;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the given scroll setup to a box. This includes scroll
|
||||
* creation/deletion as well as scroll dimension updates.
|
||||
|
@ -332,6 +332,4 @@ bool xml_to_box(xmlNode *n, struct content *c);
|
||||
|
||||
bool box_normalise_block(struct box *block, struct content *c);
|
||||
|
||||
struct box* box_duplicate_tree(struct box *root, struct content *c);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user