HTML processing and layout
The modules in the layout directory process and layout HTML pages.
This is the process to render an HTML document:
First the HTML is parsed to a tree of xmlNodes using the HTML parser in libxml.
This happens simultaneously with the fetch [html_process_data()].
Any stylesheets which the document depends on are fetched and parsed.
The tree is converted to a 'box tree' by xml_to_box(). The box tree contains a
node for each block, inline element, table, etc. The aim of this stage is to
determine the 'display' or 'float' CSS property of each element, and create the
corresponding node in the box tree. At this stage the style for each element is
also calculated (from CSS rules and element attributes). The tree is normalised
so that each node only has children of permitted types (eg. TABLE_CELLs must be
within TABLE_ROWs) by adding missing boxes.
The box tree is passed to the layout engine [layout_document()], which finds the
space required by each element and assigns coordinates to the boxes, based on
the style of each element and the available width. This includes formatting
inline elements into lines, laying out tables, and positioning floats. The
layout engine can be invoked again on a already laid out box tree to reformat it
to a new width. Coordinates in the box tree are relative to the position of the
The box tree can then be rendered using each node's coordinates.
Lists are one or more elements with 'display: list-item' (which is set for 'li'
by the default CSS). A list-item is constructed as a BLOCK box and a box for the
marker attached at block->list_marker. The marker contains the bullet, number,
or similar, depending on the list-style-type.
Layout of the block is as normal. A pass of layout after main layout places list
marker boxes to the left of their block (see layout_lists()).
Absolutely positioned boxes are constructed in the box tree in the same place as
if they were not absolutely positioned. Inline boxes are created as
INLINE_BLOCK, tables as TABLE, and other boxes as BLOCK (see
During layout, absolutely positioned boxes in block context (BLOCK or TABLE) are
given a position in layout_block_context(), but treated as having no height. In
inline context (INLINE_BLOCK), they are given a position in layout_line(), but
treated as having no width or height. This is done to determine the static
An additional pass after main layout positions and layouts all absolutely
positioned boxes (see layout_position_absolute()).