NetSurf
box_manipulate.c
Go to the documentation of this file.
1/*
2 * Copyright 2005-2007 James Bursa <bursa@users.sourceforge.net>
3 * Copyright 2003 Phil Mellor <monkeyson@users.sourceforge.net>
4 * Copyright 2005 John M Bell <jmb202@ecs.soton.ac.uk>
5 * Copyright 2008 Michael Drake <tlsa@netsurf-browser.org>
6 * Copyright 2020 Vincent Sanders <vince@netsurf-browser.org>
7 *
8 * This file is part of NetSurf, http://www.netsurf-browser.org/
9 *
10 * NetSurf is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
13 *
14 * NetSurf is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/**
24 * \file
25 * implementation of box tree manipulation.
26 */
27
28
29#include "utils/errors.h"
30#include "utils/talloc.h"
31#include "utils/nsurl.h"
32#include "netsurf/types.h"
33#include "netsurf/mouse.h"
34#include "desktop/scrollbar.h"
35
36#include "html/private.h"
37#include "html/form_internal.h"
38#include "html/interaction.h"
39#include "html/box.h"
40#include "html/box_manipulate.h"
41
42
43/**
44 * Destructor for box nodes which own styles
45 *
46 * \param b The box being destroyed.
47 * \return 0 to allow talloc to continue destroying the tree.
48 */
49static int box_talloc_destructor(struct box *b)
50{
51 struct html_scrollbar_data *data;
52
53 if ((b->flags & STYLE_OWNED) && b->style != NULL) {
54 css_computed_style_destroy(b->style);
55 b->style = NULL;
56 }
57
58 if (b->styles != NULL) {
59 css_select_results_destroy(b->styles);
60 b->styles = NULL;
61 }
62
63 if (b->href != NULL)
64 nsurl_unref(b->href);
65
66 lwc_string_unref(b->id);
67
68 if (b->node != NULL) {
69 dom_node_unref(b->node);
70 }
71
72 if (b->scroll_x != NULL) {
75 free(data);
76 }
77
78 if (b->scroll_y != NULL) {
81 free(data);
82 }
83
84 return 0;
85}
86
87
88/* Exported function documented in html/box.h */
89struct box *
90box_create(css_select_results *styles,
91 css_computed_style *style,
92 bool style_owned,
93 nsurl *href,
94 const char *target,
95 const char *title,
96 lwc_string *id,
97 void *context)
98{
99 unsigned int i;
100 struct box *box;
101
102 box = talloc(context, struct box);
103 if (!box) {
104 return 0;
105 }
106
108
110 box->flags = 0;
111 box->flags = style_owned ? (box->flags | STYLE_OWNED) : box->flags;
112 box->styles = styles;
113 box->style = style;
114 box->x = box->y = 0;
116 box->height = 0;
119 for (i = 0; i != 4; i++)
120 box->margin[i] = box->padding[i] = box->border[i].width = 0;
121 box->scroll_x = box->scroll_y = NULL;
122 box->min_width = 0;
124 box->byte_offset = 0;
125 box->text = NULL;
126 box->length = 0;
127 box->space = 0;
128 box->href = (href == NULL) ? NULL : nsurl_ref(href);
129 box->target = target;
130 box->title = title;
131 box->columns = 1;
132 box->rows = 1;
133 box->start_column = 0;
134 box->next = NULL;
135 box->prev = NULL;
136 box->children = NULL;
137 box->last = NULL;
138 box->parent = NULL;
139 box->inline_end = NULL;
140 box->float_children = NULL;
141 box->float_container = NULL;
142 box->next_float = NULL;
144 box->list_value = 1;
145 box->list_marker = NULL;
146 box->col = NULL;
147 box->gadget = NULL;
148 box->usemap = NULL;
149 box->id = id;
150 box->background = NULL;
151 box->object = NULL;
152 box->object_params = NULL;
153 box->iframe = NULL;
154 box->node = NULL;
155
156 return box;
157}
158
159
160/* Exported function documented in html/box.h */
161void box_add_child(struct box *parent, struct box *child)
162{
163 assert(parent);
164 assert(child);
165
166 if (parent->children != 0) { /* has children already */
167 parent->last->next = child;
168 child->prev = parent->last;
169 } else { /* this is the first child */
170 parent->children = child;
171 child->prev = 0;
172 }
173
174 parent->last = child;
175 child->parent = parent;
176}
177
178
179/* Exported function documented in html/box.h */
180void box_insert_sibling(struct box *box, struct box *new_box)
181{
182 new_box->parent = box->parent;
183 new_box->prev = box;
184 new_box->next = box->next;
185 box->next = new_box;
186 if (new_box->next)
187 new_box->next->prev = new_box;
188 else if (new_box->parent)
189 new_box->parent->last = new_box;
190}
191
192
193/* Exported function documented in html/box.h */
195{
196 struct box *parent = box->parent;
197 struct box *next = box->next;
198 struct box *prev = box->prev;
199
200 if (parent) {
201 if (parent->children == box)
202 parent->children = next;
203 if (parent->last == box)
204 parent->last = next ? next : prev;
205 }
206
207 if (prev)
208 prev->next = next;
209 if (next)
210 next->prev = prev;
211
212 box_free(box);
213}
214
215
216/* Exported function documented in html/box.h */
217void box_free(struct box *box)
218{
219 struct box *child, *next;
220
221 /* free children first */
222 for (child = box->children; child; child = next) {
223 next = child->next;
224 box_free(child);
225 }
226
227 /* last this box */
229}
230
231
232/* Exported function documented in html/box.h */
233void box_free_box(struct box *box)
234{
235 if (!(box->flags & CLONE)) {
236 if (box->gadget)
238 if (box->scroll_x != NULL)
240 if (box->scroll_y != NULL)
242 if (box->styles != NULL)
243 css_select_results_destroy(box->styles);
244 }
245
247}
248
249
250/* exported interface documented in html/box.h */
253 struct box *box,
254 bool bottom,
255 bool right)
256{
257 struct html_scrollbar_data *data;
258 int visible_width, visible_height;
259 int full_width, full_height;
260 nserror res;
261
262 if (!bottom && box->scroll_x != NULL) {
265 free(data);
266 box->scroll_x = NULL;
267 }
268
269 if (!right && box->scroll_y != NULL) {
272 free(data);
273 box->scroll_y = NULL;
274 }
275
276 if (!bottom && !right) {
277 return NSERROR_OK;
278 }
279
280 visible_width = box->width + box->padding[RIGHT] + box->padding[LEFT];
281 visible_height = box->height + box->padding[TOP] + box->padding[BOTTOM];
282
283 full_width = ((box->descendant_x1 - box->border[RIGHT].width) >
284 visible_width) ?
286 visible_width;
287 full_height = ((box->descendant_y1 - box->border[BOTTOM].width) >
288 visible_height) ?
290 visible_height;
291
292 if (right) {
293 if (box->scroll_y == NULL) {
294 data = malloc(sizeof(struct html_scrollbar_data));
295 if (data == NULL) {
296 return NSERROR_NOMEM;
297 }
298 data->c = c;
299 data->box = box;
300 res = scrollbar_create(false,
301 visible_height,
302 full_height,
303 visible_height,
304 data,
306 &(box->scroll_y));
307 if (res != NSERROR_OK) {
308 return res;
309 }
310 } else {
312 visible_height,
313 visible_height,
314 full_height);
315 }
316 }
317 if (bottom) {
318 if (box->scroll_x == NULL) {
319 data = malloc(sizeof(struct html_scrollbar_data));
320 if (data == NULL) {
321 return NSERROR_OK;
322 }
323 data->c = c;
324 data->box = box;
325 res = scrollbar_create(true,
326 visible_width - (right ? SCROLLBAR_WIDTH : 0),
327 full_width,
328 visible_width,
329 data,
331 &box->scroll_x);
332 if (res != NSERROR_OK) {
333 return res;
334 }
335 } else {
337 visible_width -
338 (right ? SCROLLBAR_WIDTH : 0),
339 visible_width, full_width);
340 }
341 }
342
343 if (right && bottom) {
345 }
346
347 return NSERROR_OK;
348}
349
350
Box interface.
#define UNKNOWN_WIDTH
Definition: box.h:45
#define UNKNOWN_MAX_WIDTH
Definition: box.h:46
@ BOX_INLINE
Definition: box.h:58
@ CLONE
Definition: box.h:83
@ STYLE_OWNED
Definition: box.h:80
@ TOP
Definition: box.h:98
@ BOTTOM
Definition: box.h:98
@ LEFT
Definition: box.h:98
@ RIGHT
Definition: box.h:98
void box_insert_sibling(struct box *box, struct box *new_box)
Insert a new box as a sibling to a box in a tree.
void box_unlink_and_free(struct box *box)
Unlink a box from the box tree and then free it recursively.
void box_free_box(struct box *box)
Free the data in a single box structure.
struct box * box_create(css_select_results *styles, css_computed_style *style, bool style_owned, nsurl *href, const char *target, const char *title, lwc_string *id, void *context)
Create a box tree node.
static int box_talloc_destructor(struct box *b)
Destructor for box nodes which own styles.
nserror box_handle_scrollbars(struct content *c, struct box *box, bool bottom, bool right)
Applies the given scroll setup to a box.
void box_free(struct box *box)
Free a box tree recursively.
void box_add_child(struct box *parent, struct box *child)
Add a child to a box tree node.
Box tree manipulation interface.
wimp_w parent
Definition: dialog.c:88
Error codes.
nserror
Enumeration of error codes.
Definition: errors.h:29
@ NSERROR_NOMEM
Memory exhaustion.
Definition: errors.h:32
@ NSERROR_OK
No error.
Definition: errors.h:30
void form_free_control(struct form_control *control)
Free a struct form_control.
Definition: form.c:1455
Interface to form handling functions internal to HTML content handler.
Core mouse and pointer states.
void html_overflow_scroll_callback(void *client_data, struct scrollbar_msg_data *scrollbar_data)
Callback for in-page scrollbars.
Definition: interaction.c:1612
HTML content user interaction handling.
NetSurf URL handling (interface).
void nsurl_unref(nsurl *url)
Drop a reference to a NetSurf URL object.
nsurl * nsurl_ref(nsurl *url)
Increment the reference count to a NetSurf URL object.
struct nsurl nsurl
NetSurf URL object.
Definition: nsurl.h:31
Private data for text/html content.
void scrollbar_make_pair(struct scrollbar *horizontal, struct scrollbar *vertical)
Connect a horizontal and a vertical scrollbar into a pair so that they co-operate during 2D drags.
Definition: scrollbar.c:990
nserror scrollbar_create(bool horizontal, int length, int full_size, int visible_size, void *client_data, scrollbar_client_callback client_callback, struct scrollbar **s)
Create a scrollbar.
Definition: scrollbar.c:93
void * scrollbar_get_data(struct scrollbar *s)
Get the scrollbar's client data.
Definition: scrollbar.c:1004
void scrollbar_destroy(struct scrollbar *s)
Destroy a scrollbar.
Definition: scrollbar.c:138
void scrollbar_set_extents(struct scrollbar *s, int length, int visible_size, int full_size)
Set the length of the scrollbar widget, the size of the visible area, and the size of the full area.
Definition: scrollbar.c:640
Scrollbar widget interface.
#define SCROLLBAR_WIDTH
Definition: scrollbar.h:32
int width
border-width (pixels)
Definition: box.h:107
Node in box tree.
Definition: box.h:177
int descendant_y1
bottom edge of descendants
Definition: box.h:312
struct box_border border[4]
Border: TOP, RIGHT, BOTTOM, LEFT.
Definition: box.h:327
int list_value
List item value.
Definition: box.h:412
int min_width
Width of box taking all line breaks (including margins etc).
Definition: box.h:343
int width
Width of content box (excluding padding etc.).
Definition: box.h:289
struct box * parent
Parent box, or NULL.
Definition: box.h:236
struct scrollbar * scroll_x
Horizontal scroll.
Definition: box.h:332
lwc_string * id
value of id attribute (or name for anchors)
Definition: box.h:210
size_t byte_offset
Byte offset within a textual representation of this content.
Definition: box.h:370
struct column * col
Array of table column data for TABLE only.
Definition: box.h:407
const char * title
Title, or NULL.
Definition: box.h:386
struct box * inline_end
INLINE_END box corresponding to this INLINE box, or INLINE box corresponding to this INLINE_END box.
Definition: box.h:242
struct box * children
First child box, or NULL.
Definition: box.h:226
int height
Height of content box (excluding padding etc.).
Definition: box.h:293
struct hlcache_handle * background
Background image for this box, or NULL if none.
Definition: box.h:435
struct box * float_container
If box is a float, points to box's containing block.
Definition: box.h:261
struct box * prev
Previous sibling box, or NULL.
Definition: box.h:221
struct box * list_marker
List marker box if this is a list-item, or NULL.
Definition: box.h:417
int margin[4]
Margin: TOP, RIGHT, BOTTOM, LEFT.
Definition: box.h:317
char * usemap
(Image)map to use with this object, or NULL if none
Definition: box.h:429
int max_width
Width that would be taken with no line breaks.
Definition: box.h:349
const char * target
Link target, or NULL.
Definition: box.h:381
struct box * next_float
Next sibling float box.
Definition: box.h:256
css_select_results * styles
Computed styles for elements and their pseudo elements.
Definition: box.h:197
struct box * last
Last child box, or NULL.
Definition: box.h:231
struct box * next
Next sibling box, or NULL.
Definition: box.h:216
int descendant_x0
left edge of descendants
Definition: box.h:309
struct scrollbar * scroll_y
Vertical scroll.
Definition: box.h:337
unsigned int start_column
Start column for TABLE_CELL only.
Definition: box.h:402
box_type type
Type of box.
Definition: box.h:181
struct nsurl * href
Link, or NULL.
Definition: box.h:376
struct box * float_children
First float child box, or NULL.
Definition: box.h:251
int descendant_x1
right edge of descendants
Definition: box.h:311
struct browser_window * iframe
Iframe's browser_window, or NULL if none.
Definition: box.h:452
css_computed_style * style
Style for this box.
Definition: box.h:205
size_t length
Length of text.
Definition: box.h:360
struct object_params * object_params
Parameters for the object, or NULL.
Definition: box.h:446
struct hlcache_handle * object
Object in this box (usually an image), or NULL if none.
Definition: box.h:441
char * text
Text, or NULL if none.
Definition: box.h:355
int padding[4]
Padding: TOP, RIGHT, BOTTOM, LEFT.
Definition: box.h:322
int x
Coordinate of left padding edge relative to parent box, or relative to ancestor that contains this bo...
Definition: box.h:280
box_flags flags
Box flags.
Definition: box.h:186
int space
Width of space after current text (depends on font and size).
Definition: box.h:365
int cached_place_below_level
Level below which floats have been placed.
Definition: box.h:272
struct form_control * gadget
Form control data, or NULL if not a form control.
Definition: box.h:423
int descendant_y0
top edge of descendants
Definition: box.h:310
unsigned int rows
Number of rows for TABLE only.
Definition: box.h:397
struct dom_node * node
DOM node that generated this box or NULL.
Definition: box.h:191
unsigned int columns
Number of columns for TABLE / TABLE_CELL.
Definition: box.h:392
int y
Coordinate of top padding edge, relative as for x.
Definition: box.h:284
Content which corresponds to a single URL.
Context for scrollbar.
Definition: interaction.h:32
struct box * box
Definition: interaction.h:34
struct content * c
Definition: interaction.h:33
int talloc_free(void *ptr)
Definition: talloc.c:760
#define talloc_set_destructor(ptr, function)
Definition: talloc.h:75
#define talloc(ctx, type)
Definition: talloc.h:85
NetSurf types.