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 if (b->id != NULL) {
67 lwc_string_unref(b->id);
68 }
69
70 if (b->node != NULL) {
71 dom_node_unref(b->node);
72 }
73
74 if (b->scroll_x != NULL) {
77 free(data);
78 }
79
80 if (b->scroll_y != NULL) {
83 free(data);
84 }
85
86 return 0;
87}
88
89
90/* Exported function documented in html/box.h */
91struct box *
92box_create(css_select_results *styles,
93 css_computed_style *style,
94 bool style_owned,
95 nsurl *href,
96 const char *target,
97 const char *title,
98 lwc_string *id,
99 void *context)
100{
101 unsigned int i;
102 struct box *box;
103
104 box = talloc(context, struct box);
105 if (!box) {
106 return 0;
107 }
108
110
112 box->flags = 0;
113 box->flags = style_owned ? (box->flags | STYLE_OWNED) : box->flags;
114 box->styles = styles;
115 box->style = style;
116 box->x = box->y = 0;
118 box->height = 0;
121 for (i = 0; i != 4; i++)
122 box->margin[i] = box->padding[i] = box->border[i].width = 0;
123 box->scroll_x = box->scroll_y = NULL;
124 box->min_width = 0;
126 box->byte_offset = 0;
127 box->text = NULL;
128 box->length = 0;
129 box->space = 0;
130 box->href = (href == NULL) ? NULL : nsurl_ref(href);
131 box->target = target;
132 box->title = title;
133 box->columns = 1;
134 box->rows = 1;
135 box->start_column = 0;
136 box->next = NULL;
137 box->prev = NULL;
138 box->children = NULL;
139 box->last = NULL;
140 box->parent = NULL;
141 box->inline_end = NULL;
142 box->float_children = NULL;
143 box->float_container = NULL;
144 box->next_float = NULL;
146 box->list_value = 1;
147 box->list_marker = NULL;
148 box->col = NULL;
149 box->gadget = NULL;
150 box->usemap = NULL;
151 box->id = id;
152 box->background = NULL;
153 box->object = NULL;
154 box->object_params = NULL;
155 box->iframe = NULL;
156 box->node = NULL;
157
158 return box;
159}
160
161
162/* Exported function documented in html/box.h */
163void box_add_child(struct box *parent, struct box *child)
164{
165 assert(parent);
166 assert(child);
167
168 if (parent->children != 0) { /* has children already */
169 parent->last->next = child;
170 child->prev = parent->last;
171 } else { /* this is the first child */
172 parent->children = child;
173 child->prev = 0;
174 }
175
176 parent->last = child;
177 child->parent = parent;
178}
179
180
181/* Exported function documented in html/box.h */
182void box_insert_sibling(struct box *box, struct box *new_box)
183{
184 new_box->parent = box->parent;
185 new_box->prev = box;
186 new_box->next = box->next;
187 box->next = new_box;
188 if (new_box->next)
189 new_box->next->prev = new_box;
190 else if (new_box->parent)
191 new_box->parent->last = new_box;
192}
193
194
195/* Exported function documented in html/box.h */
197{
198 struct box *parent = box->parent;
199 struct box *next = box->next;
200 struct box *prev = box->prev;
201
202 if (parent) {
203 if (parent->children == box)
204 parent->children = next;
205 if (parent->last == box)
206 parent->last = next ? next : prev;
207 }
208
209 if (prev)
210 prev->next = next;
211 if (next)
212 next->prev = prev;
213
214 box_free(box);
215}
216
217
218/* Exported function documented in html/box.h */
219void box_free(struct box *box)
220{
221 struct box *child, *next;
222
223 /* free children first */
224 for (child = box->children; child; child = next) {
225 next = child->next;
226 box_free(child);
227 }
228
229 /* last this box */
231}
232
233
234/* Exported function documented in html/box.h */
235void box_free_box(struct box *box)
236{
237 if (!(box->flags & CLONE)) {
238 if (box->gadget)
240 if (box->scroll_x != NULL)
242 if (box->scroll_y != NULL)
244 if (box->styles != NULL)
245 css_select_results_destroy(box->styles);
246 }
247
249}
250
251
252/* exported interface documented in html/box.h */
255 struct box *box,
256 bool bottom,
257 bool right)
258{
259 struct html_scrollbar_data *data;
260 int visible_width, visible_height;
261 int full_width, full_height;
262 nserror res;
263
264 if (!bottom && box->scroll_x != NULL) {
267 free(data);
268 box->scroll_x = NULL;
269 }
270
271 if (!right && box->scroll_y != NULL) {
274 free(data);
275 box->scroll_y = NULL;
276 }
277
278 if (!bottom && !right) {
279 return NSERROR_OK;
280 }
281
282 visible_width = box->width + box->padding[RIGHT] + box->padding[LEFT];
283 visible_height = box->height + box->padding[TOP] + box->padding[BOTTOM];
284
285 full_width = ((box->descendant_x1 - box->border[RIGHT].width) >
286 visible_width) ?
288 visible_width;
289 full_height = ((box->descendant_y1 - box->border[BOTTOM].width) >
290 visible_height) ?
292 visible_height;
293
294 if (right) {
295 if (box->scroll_y == NULL) {
296 data = malloc(sizeof(struct html_scrollbar_data));
297 if (data == NULL) {
298 return NSERROR_NOMEM;
299 }
300 data->c = c;
301 data->box = box;
302 res = scrollbar_create(false,
303 visible_height,
304 full_height,
305 visible_height,
306 data,
308 &(box->scroll_y));
309 if (res != NSERROR_OK) {
310 return res;
311 }
312 } else {
314 visible_height,
315 visible_height,
316 full_height);
317 }
318 }
319 if (bottom) {
320 if (box->scroll_x == NULL) {
321 data = malloc(sizeof(struct html_scrollbar_data));
322 if (data == NULL) {
323 return NSERROR_OK;
324 }
325 data->c = c;
326 data->box = box;
327 res = scrollbar_create(true,
328 visible_width - (right ? SCROLLBAR_WIDTH : 0),
329 full_width,
330 visible_width,
331 data,
333 &box->scroll_x);
334 if (res != NSERROR_OK) {
335 return res;
336 }
337 } else {
339 visible_width -
340 (right ? SCROLLBAR_WIDTH : 0),
341 visible_width, full_width);
342 }
343 }
344
345 if (right && bottom) {
347 }
348
349 return NSERROR_OK;
350}
351
352
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:1601
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.