The Vex Layout Engine

The purpose of the Vex Layout Engine is to create a visual representation of a document given a CSS stylesheet. This visual representation is a nested hierarchy of rectangular boxes, implemented as a tree of objects each implementing the Box interface. Each box has the following properties.

Additionally, each box supports the following operations.

There are two main types of box. Block boxes normally contain other boxes and stack their children vertically (with TableRowBox being an exception whose children are stacked horizontally). Inline boxes may contain child boxes or other content such as text; their children are stacked horizontally and they may be split to wrap content into a series of lines.

A box may acquire its children in a number of ways. Boxes associated with document elements (e.g. BlockElementBox) create their own children by inspecting the child nodes of the associated element. This can happen immediately in the box's constructor, or may be deferred for performance. In other cases, a box's children are created by its parent and passed to its constructor. Finally, simple boxes such as DocumentTextBox and PlaceholderBox have no child boxes; they serve simply to display content or to aid in navigation.

Layout Process

The layout process begins with a VexWidgetImpl object, which creates a RootBox containing a BlockElementBox corresponding with the document's root element. Each BlockElementBox does not initially create its children. Instead, it estimates its height based on the current font size and the number of characters covered by the element.

At any one time, the user can only view a particular horizontal band of the document. To avoid unnecessary work, the VexWidgetImpl only requests that the RootBox lay out (that is, create and position children) within that horizontal band. Each BlockElementBox that is asked to layout a band creates its children, then propagates the layout call to children that fall inside the band. Newly created children that fall outside the visible band are not laid out. Instead, they are left with their initial size estimates.

While many BlockElementBoxes contain only other BlockElementBox children, eventually a BlockElementBox will need to lay out a run of inline content, that is, text and inline-formatted elements...

Document Changes and Layout Updates

Content Boxes

A box is said to have content if it corresponds to a range of character offsets in the source document. The simplest type of content box is a DocumentTextBox, which corresponds to a sequence of characters in the source document. BlockElementBoxes and InlineElementBoxes also have content. Boxes such as StaticTextBox and DrawableBox are purely visual and do not represent document content.

Keyboard Navigation

The user can change the insertion point by pressing one of the four arrow keys, the PgUp or PgDn keys, or the Home or End keys. The challenge of keyboard navigation is to calculate a new document offset for the insertion point given the current insertion point and the desired direction of motion. Complicating the situation is the fact that ranges of offsets may be invisible (e.g. inside a display:none block); the new offset must be visible.

Mouse Navigation