NetSurf
Macros | Enumerations | Functions
box.c File Reference

implementation of box tree manipulation. More...

#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <dom/dom.h>
#include "utils/nsoption.h"
#include "utils/log.h"
#include "utils/talloc.h"
#include "utils/nsurl.h"
#include "netsurf/misc.h"
#include "netsurf/content.h"
#include "netsurf/mouse.h"
#include "css/utils.h"
#include "css/dump.h"
#include "desktop/scrollbar.h"
#include "desktop/gui_internal.h"
#include "desktop/search.h"
#include "html/box.h"
#include "html/form_internal.h"
#include "html/html_internal.h"
#include "html/interaction.h"
Include dependency graph for box.c:

Go to the source code of this file.

Macros

#define box_is_float(box)
 

Enumerations

enum  box_walk_dir {
  BOX_WALK_CHILDREN, BOX_WALK_PARENT, BOX_WALK_NEXT_SIBLING, BOX_WALK_FLOAT_CHILDREN,
  BOX_WALK_NEXT_FLOAT_SIBLING, BOX_WALK_FLOAT_CONTAINER
}
 Direction to move in a box-tree walk. More...
 

Functions

static int box_talloc_destructor (struct box *b)
 Destructor for box nodes which own styles. More...
 
struct boxbox_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. More...
 
void box_add_child (struct box *parent, struct box *child)
 Add a child to a box tree node. More...
 
void box_insert_sibling (struct box *box, struct box *new_box)
 Insert a new box as a sibling to a box in a tree. More...
 
void box_unlink_and_free (struct box *box)
 Unlink a box from the box tree and then free it recursively. More...
 
void box_free (struct box *box)
 Free a box tree recursively. More...
 
void box_free_box (struct box *box)
 Free the data in a single box structure. More...
 
void box_coords (struct box *box, int *x, int *y)
 Find the absolute coordinates of a box. More...
 
void box_bounds (struct box *box, struct rect *r)
 Find the bounds of a box. More...
 
static bool box_contains_point (const nscss_len_ctx *len_ctx, const struct box *box, int x, int y, bool *physically)
 Determine if a point lies within a box. More...
 
static struct boxbox_move_xy (struct box *b, enum box_walk_dir dir, int *x, int *y)
 Move from box to next box in given direction, adjusting for box coord change. More...
 
static struct boxbox_next_xy (struct box *b, int *x, int *y, bool skip_children)
 Itterator for walking to next box in interaction order. More...
 
struct boxbox_at_point (const nscss_len_ctx *len_ctx, struct box *box, const int x, const int y, int *box_x, int *box_y)
 Find the boxes at a point. More...
 
static bool box_nearer_text_box (struct box *box, int bx, int by, int x, int y, int dir, struct box **nearest, int *tx, int *ty, int *nr_xd, int *nr_yd)
 Check whether box is nearer mouse coordinates than current nearest box. More...
 
static bool box_nearest_text_box (struct box *box, int bx, int by, int fx, int fy, int x, int y, int dir, struct box **nearest, int *tx, int *ty, int *nr_xd, int *nr_yd)
 Pick the text box child of 'box' that is closest to and above-left (dir -ve) or below-right (dir +ve) of the point 'x,y'. More...
 
struct boxbox_pick_text_box (struct html_content *html, int x, int y, int dir, int *dx, int *dy)
 Peform pick text on browser window contents to locate the box under the mouse pointer, or nearest in the given direction if the pointer is not over a text box. More...
 
struct boxbox_find_by_id (struct box *box, lwc_string *id)
 Find a box based upon its id attribute. More...
 
bool box_visible (struct box *box)
 Determine if a box is visible when the tree is rendered. More...
 
void box_dump (FILE *stream, struct box *box, unsigned int depth, bool style)
 Print a box tree to a file. More...
 
nserror box_handle_scrollbars (struct content *c, struct box *box, bool bottom, bool right)
 Applies the given scroll setup to a box. More...
 
bool box_vscrollbar_present (const struct box *const box)
 Determine if a box has a vertical scrollbar. More...
 
bool box_hscrollbar_present (const struct box *const box)
 Determine if a box has a horizontal scrollbar. More...
 

Detailed Description

implementation of box tree manipulation.

Definition in file box.c.

Macro Definition Documentation

◆ box_is_float

#define box_is_float (   box)
Value:
box->type == BOX_FLOAT_RIGHT)
box_type type
Type of box.
Definition: box.h:240
Node in box tree.
Definition: box.h:236

Definition at line 51 of file box.c.

Referenced by box_coords(), box_move_xy(), and box_next_xy().

Enumeration Type Documentation

◆ box_walk_dir

Direction to move in a box-tree walk.

Enumerator
BOX_WALK_CHILDREN 
BOX_WALK_PARENT 
BOX_WALK_NEXT_SIBLING 
BOX_WALK_FLOAT_CHILDREN 
BOX_WALK_NEXT_FLOAT_SIBLING 
BOX_WALK_FLOAT_CONTAINER 

Definition at line 426 of file box.c.

Function Documentation

◆ box_add_child()

void box_add_child ( struct box parent,
struct box child 
)

Add a child to a box tree node.

Parameters
parentbox giving birth
childbox to link as last child of parent

Definition at line 173 of file box.c.

References box::children, box::last, box::next, parent, box::parent, and box::prev.

Referenced by box_construct_element(), box_construct_element_after(), box_construct_generate(), box_construct_text(), box_input(), box_input_text(), box_normalise_block(), box_normalise_table(), box_normalise_table_row(), box_normalise_table_row_group(), and box_select().

Here is the caller graph for this function:

◆ box_at_point()

struct box* box_at_point ( const nscss_len_ctx len_ctx,
struct box box,
const int  x,
const int  y,
int *  box_x,
int *  box_y 
)

Find the boxes at a point.

Parameters
len_ctxCSS length conversion context for document.
boxbox to search children of
xpoint to find, in global document coordinates
ypoint to find, in global document coordinates
box_xposition of box, in global document coordinates, updated to position of returned box, if any
box_yposition of box, in global document coordinates, updated to position of returned box, if any
Returns
box at given point, or 0 if none found

To find all the boxes in the hierarchy at a certain point, use code like this:

struct box *box = top_of_document_to_search;
int box_x = 0, box_y = 0;
while ((box = box_at_point(len_ctx, box, x, y, &box_x, &box_y))) {
// process box
}

Definition at line 621 of file box.c.

References box_contains_point(), box_next_xy(), box::scroll_x, box::scroll_y, and scrollbar_get_offset().

Referenced by get_mouse_action_node(), html_drop_file_at_point(), html_get_contextual_content(), and html_scroll_at_point().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ box_bounds()

void box_bounds ( struct box box,
struct rect r 
)

Find the bounds of a box.

Parameters
boxthe box to calculate bounds of
rreceives bounds

Definition at line 281 of file box.c.

References BOTTOM, box_coords(), height, box::height, LEFT, box::padding, RIGHT, TOP, width, box::width, rect::x0, rect::x1, rect::y0, and rect::y1.

Referenced by browser_window_create_iframes(), and form_control_bounding_rect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ box_contains_point()

static bool box_contains_point ( const nscss_len_ctx len_ctx,
const struct box box,
int  x,
int  y,
bool *  physically 
)
static

Determine if a point lies within a box.

Parameters
[in]len_ctxCSS length conversion context to use.
[in]boxBox to consider
[in]xCoordinate relative to box
[in]yCoordinate relative to box
[out]physicallyIf function returning true, physically is set true iff point is within the box's physical dimensions and false if the point is not within the box's physical dimensions but is in the area defined by the box's descendants. If function returns false, physically is undefined.
Returns
true if the point is within the box or a descendant box

This is a helper function for box_at_point().

Definition at line 312 of file box.c.

References box::border, BOTTOM, box::descendant_x0, box::descendant_y0, box::height, LEFT, box::list_marker, nscss_len2px(), box::padding, RIGHT, box::style, TOP, box_border::width, box::width, box::x, rect::x0, rect::x1, box::y, rect::y0, and rect::y1.

Referenced by box_at_point().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ box_coords()

void box_coords ( struct box box,
int *  x,
int *  y 
)

Find the absolute coordinates of a box.

Parameters
boxthe box to calculate coordinates of
xupdated to x coordinate
yupdated to y coordinate

Definition at line 263 of file box.c.

References box_is_float, box::float_container, box::parent, box::scroll_x, box::scroll_y, scrollbar_get_offset(), box::x, and box::y.

Referenced by box_bounds(), box_textarea_callback(), form_select_menu_callback(), form_select_mouse_drag_end(), html__redraw_a_box(), html_box_drag_start(), html_drop_file_at_point(), html_get_id_offset(), html_object_callback(), html_overflow_scroll_drag_end(), html_redraw(), html_redraw_a_box(), html_set_focus(), layout_calculate_descendant_bboxes(), mouse_action_drag_content(), mouse_action_drag_scrollbar(), mouse_action_drag_textarea(), mouse_action_select_menu(), redraw_handler(), and search_text().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ box_create()

struct box* box_create ( css_select_results *  styles,
css_computed_style *  style,
bool  style_owned,
struct nsurl href,
const char *  target,
const char *  title,
lwc_string *  id,
void *  context 
)

Create a box tree node.

Parameters
stylesselection results for the box, or NULL
stylecomputed style for the box (not copied), or 0
style_ownedwhether style is owned by this box
hrefhref for the box (copied), or 0
targettarget for the box (not copied), or 0
titletitle for the box (not copied), or 0
idid for the box (not copied), or 0
contextcontext for allocations
Returns
allocated and initialised box, or 0 on memory exhaustion

styles is always owned by the box, if it is set. style is only owned by the box in the case of implied boxes.

Definition at line 103 of file box.c.

References box::background, box::border, BOX_INLINE, box_talloc_destructor(), box::byte_offset, box::cached_place_below_level, box::children, box::col, box::columns, box::descendant_x0, box::descendant_x1, box::descendant_y0, box::descendant_y1, box::flags, box::float_children, box::float_container, box::gadget, box::height, box::href, box::id, box::iframe, box::inline_end, box::last, box::length, box::list_marker, box::margin, box::max_width, box::min_width, box::next, box::next_float, box::node, nsurl_ref(), box::object, box::object_params, box::padding, box::parent, box::prev, box::rows, box::scroll_x, box::scroll_y, box::space, box::start_column, box::style, STYLE_OWNED, box::styles, talloc, talloc_set_destructor, box::target, box::text, box::title, box::type, UNKNOWN_MAX_WIDTH, UNKNOWN_WIDTH, box::usemap, box_border::width, box::width, box::x, and box::y.

Referenced by box_construct_element(), box_construct_element_after(), box_construct_generate(), box_construct_marker(), box_construct_text(), box_input(), box_input_text(), box_normalise_block(), box_normalise_table(), box_normalise_table_row(), box_normalise_table_row_group(), box_normalise_table_spans(), and box_select().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ box_dump()

void box_dump ( FILE *  stream,
struct box box,
unsigned int  depth,
bool  style 
)

◆ box_find_by_id()

struct box* box_find_by_id ( struct box box,
lwc_string *  id 
)

Find a box based upon its id attribute.

Parameters
boxbox tree to search
idid to look for
Returns
the box or 0 if not found

Definition at line 873 of file box.c.

References box_find_by_id(), box::children, box::id, and box::next.

Referenced by box_find_by_id(), and html_get_id_offset().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ box_free()

void box_free ( struct box box)

Free a box tree recursively.

Parameters
boxbox to free recursively

The box and all its children is freed.

Definition at line 229 of file box.c.

References box_free(), box_free_box(), box::children, and box::next.

Referenced by box_free(), box_normalise_inline_container(), box_normalise_table(), and box_unlink_and_free().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ box_free_box()

void box_free_box ( struct box box)

Free the data in a single box structure.

Parameters
boxbox to free

Definition at line 245 of file box.c.

References CLONE, box::flags, form_free_control(), box::gadget, box::scroll_x, box::scroll_y, scrollbar_destroy(), box::styles, and talloc_free().

Referenced by box_free().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ box_handle_scrollbars()

nserror box_handle_scrollbars ( struct content c,
struct box box,
bool  bottom,
bool  right 
)

Applies the given scroll setup to a box.

This includes scroll creation/deletion as well as scroll dimension updates.

Parameters
ccontent in which the box is located
boxthe box to handle the scrolls for
bottomwhether the horizontal scrollbar should be present
rightwhether the vertical scrollbar should be present
Returns
true on success false otherwise

Definition at line 1029 of file box.c.

References box::border, BOTTOM, html_scrollbar_data::box, html_scrollbar_data::c, box::descendant_x1, box::descendant_y1, box::height, html_overflow_scroll_callback(), LEFT, NSERROR_NOMEM, NSERROR_OK, box::padding, RIGHT, box::scroll_x, box::scroll_y, scrollbar_create(), scrollbar_destroy(), scrollbar_get_data(), scrollbar_make_pair(), scrollbar_set_extents(), SCROLLBAR_WIDTH, TOP, box_border::width, and box::width.

Referenced by html_redraw_box().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ box_hscrollbar_present()

bool box_hscrollbar_present ( const struct box box)

Determine if a box has a horizontal scrollbar.

Parameters
boxscrolling box
Returns
the box has a horizontal scrollbar

Definition at line 1137 of file box.c.

References box::border, box::descendant_x1, LEFT, box::padding, RIGHT, box_border::width, and box::width.

Referenced by html_redraw_box(), and layout_block_add_scrollbar().

Here is the caller graph for this function:

◆ box_insert_sibling()

void box_insert_sibling ( struct box box,
struct box new_box 
)

Insert a new box as a sibling to a box in a tree.

Parameters
boxbox already in tree
new_boxbox to link into tree as next sibling

Definition at line 192 of file box.c.

References box::last, box::next, box::parent, and box::prev.

◆ box_move_xy()

static struct box* box_move_xy ( struct box b,
enum box_walk_dir  dir,
int *  x,
int *  y 
)
static

Move from box to next box in given direction, adjusting for box coord change.

Parameters
bbox to move from from
dirdirection to move in
xbox's global x-coord, updated to position of next box
ybox's global y-coord, updated to position of next box

If no box can be found in given direction, NULL is returned.

Definition at line 447 of file box.c.

References box_is_float, BOX_WALK_CHILDREN, BOX_WALK_FLOAT_CHILDREN, BOX_WALK_FLOAT_CONTAINER, BOX_WALK_NEXT_FLOAT_SIBLING, BOX_WALK_NEXT_SIBLING, BOX_WALK_PARENT, box::children, box::float_children, box::float_container, box::next, box::next_float, box::parent, box::x, and box::y.

Referenced by box_next_xy().

Here is the caller graph for this function:

◆ box_nearer_text_box()

static bool box_nearer_text_box ( struct box box,
int  bx,
int  by,
int  x,
int  y,
int  dir,
struct box **  nearest,
int *  tx,
int *  ty,
int *  nr_xd,
int *  nr_yd 
)
static

Check whether box is nearer mouse coordinates than current nearest box.

Parameters
boxbox to test
bxposition of box, in global document coordinates
byposition of box, in global document coordinates
xmouse point, in global document coordinates
ymouse point, in global document coordinates
dirdirection in which to search (-1 = above-left, +1 = below-right)
nearestnearest text box found, or NULL if none updated if box is nearer than existing nearest
txposition of text_box, in global document coordinates updated if box is nearer than existing nearest
typosition of text_box, in global document coordinates updated if box is nearer than existing nearest
nr_xddistance to nearest text box found updated if box is nearer than existing nearest
nr_yddistance to nearest text box found updated if box is nearer than existing nearest
Returns
true if mouse point is inside box

Definition at line 674 of file box.c.

References BOTTOM, box::height, LEFT, box::list_marker, box::padding, box::parent, RIGHT, TOP, box::width, box::x, and box::y.

Referenced by box_nearest_text_box().

Here is the caller graph for this function:

◆ box_nearest_text_box()

static bool box_nearest_text_box ( struct box box,
int  bx,
int  by,
int  fx,
int  fy,
int  x,
int  y,
int  dir,
struct box **  nearest,
int *  tx,
int *  ty,
int *  nr_xd,
int *  nr_yd 
)
static

Pick the text box child of 'box' that is closest to and above-left (dir -ve) or below-right (dir +ve) of the point 'x,y'.

Parameters
boxparent box
bxposition of box, in global document coordinates
byposition of box, in global document coordinates
fxposition of float parent, in global document coordinates
fyposition of float parent, in global document coordinates
xmouse point, in global document coordinates
ymouse point, in global document coordinates
dirdirection in which to search (-1 = above-left, +1 = below-right)
nearestnearest text box found, or NULL if none updated if a descendant of box is nearer than old nearest
txposition of nearest, in global document coordinates updated if a descendant of box is nearer than old nearest
typosition of nearest, in global document coordinates updated if a descendant of box is nearer than old nearest
nr_xddistance to nearest text box found updated if a descendant of box is nearer than old nearest
nr_yddistance to nearest text box found updated if a descendant of box is nearer than old nearest
Returns
true if mouse point is inside text_box

Definition at line 749 of file box.c.

References BOTTOM, BOX_FLOAT_LEFT, BOX_FLOAT_RIGHT, BOX_INLINE_CONTAINER, box_nearer_text_box(), box::children, box::float_children, box::height, LEFT, box::list_marker, box::next, box::object, box::padding, RIGHT, box::scroll_x, box::scroll_y, scrollbar_get_offset(), box::text, TOP, box::type, box::width, box::x, and box::y.

Referenced by box_pick_text_box().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ box_next_xy()

static struct box* box_next_xy ( struct box b,
int *  x,
int *  y,
bool  skip_children 
)
static

Itterator for walking to next box in interaction order.

Parameters
bbox to find next box from
xbox's global x-coord, updated to position of next box
ybox's global y-coord, updated to position of next box
skip_childrenwhether to skip box's children

This walks to a boxes float children before its children. When walking children, floating boxes are skipped.

Definition at line 528 of file box.c.

References box_is_float, box_move_xy(), BOX_WALK_CHILDREN, BOX_WALK_FLOAT_CHILDREN, BOX_WALK_FLOAT_CONTAINER, BOX_WALK_NEXT_FLOAT_SIBLING, BOX_WALK_NEXT_SIBLING, BOX_WALK_PARENT, box::next, box::parent, box::x, and box::y.

Referenced by box_at_point().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ box_pick_text_box()

struct box* box_pick_text_box ( struct html_content html,
int  x,
int  y,
int  dir,
int *  dx,
int *  dy 
)

Peform pick text on browser window contents to locate the box under the mouse pointer, or nearest in the given direction if the pointer is not over a text box.

Parameters
htmlan HTML content
xcoordinate of mouse
ycoordinate of mouse
dirdirection to search (-1 = above-left, +1 = below-right)
dxreceives x ordinate of mouse relative to text box
dyreceives y ordinate of mouse relative to text box

Definition at line 821 of file box.c.

References BOTTOM, box_nearest_text_box(), box::height, html_content::layout, LEFT, box::margin, box::object, box::padding, RIGHT, box::text, TOP, and box::width.

Referenced by html_selection_drag_end(), and mouse_action_drag_selection().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ box_talloc_destructor()

static int box_talloc_destructor ( struct box b)
static

Destructor for box nodes which own styles.

Parameters
bThe box being destroyed.
Returns
0 to allow talloc to continue destroying the tree.

Definition at line 60 of file box.c.

References box::flags, box::href, box::id, box::node, nsurl_unref(), box::scroll_x, box::scroll_y, scrollbar_destroy(), scrollbar_get_data(), box::style, STYLE_OWNED, and box::styles.

Referenced by box_create().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ box_unlink_and_free()

void box_unlink_and_free ( struct box box)

Unlink a box from the box tree and then free it recursively.

Parameters
boxbox to unlink and free recursively.

Definition at line 206 of file box.c.

References box_free(), box::children, box::last, box::next, parent, box::parent, and box::prev.

Here is the call graph for this function:

◆ box_visible()

bool box_visible ( struct box box)

Determine if a box is visible when the tree is rendered.

Parameters
boxbox to check
Returns
true iff the box is rendered

Definition at line 893 of file box.c.

References box::style.

Referenced by html_object_callback().

Here is the caller graph for this function:

◆ box_vscrollbar_present()

bool box_vscrollbar_present ( const struct box box)

Determine if a box has a vertical scrollbar.

Parameters
boxscrolling box
Returns
the box has a vertical scrollbar

Definition at line 1129 of file box.c.

References box::border, BOTTOM, box::descendant_y1, box::height, box::padding, TOP, and box_border::width.

Referenced by html_redraw_box(), and layout_block_add_scrollbar().

Here is the caller graph for this function: