HTML Layout Internals

Big picture

An HTML document comes in from netlib into the HTML parser.  The parser creates parser nodes and feeds them to the content sink.  The content sink constructs a content model that represents the hierarchical structure of the document.  As different sub-trees in the content model are fully available, the stylesheet processor iterates over them and creates the corresponding frame hierarchy.  The frames recursively layout and render themselves.

The part that we are going to drill down into is the code in the block and inline frame classes.  Block and inline are the two primary display types specified in CSS and are used in the layout of most of the HTML tags.  The table related tags have their own display types like "table-cell", "table-row", etc. and their implementation is a separate topic in itself.

Block and inline code

The main classes involved in the layout of HTML documents are nsBlockFrame and nsInlineFrame, both of which inherit from nsContainerFrame (why?).  These classes are persistent across reflows and are organized in a hierarchy to constitute the frame model of the Gecko system.  The frame model is derived by applying style and presentation semantics to the content model.  Each frame in the frame model has a one to one correspondence with a rectangular region on the presentation context (screen, printer, etc.) and contains the formatting information needed to render that rectangle.  The block and inline frame classes implement the nsIFrame and nsIHTMLReflow interfaces.  The nsIFrame interface contains methods for managing child frames and linkage with sibling frames, accessing the style context associated with the frame, painting the frame, and handling events that are passed in from the widget hierarchy.  The nsIHTMLReflow interface inherits from the nsIReflow interface and adds methods related to word breaking and whitespace querying.  The nsIReflow interface defines the Reflow() method that initiates the reflow process along with the DidReflow() method that get calledafter the reflow process.  nsReflowState and nsReflowMetrics are parameters to the templatized nsIReflow interface: the former is used to hold state during reflow of a frame and the latter is used to return the frame's desired size and alignment to the parent frame during the reflow process.

nsBlockReflowContext and nsBlockReflowState both hold state information during the reflow process.  nsBlockReflowContext encapsulates the state and algorithm for reflowing child block frames.  nsBlockReflowState contains state and methods used by a block frame to reflow itself.  Both these classes are instantiated once per block frame.

The nsLineLayout class is the engine used by the block and inline frame classes to layout themselves on a line.  Frames get passed in to the nsLineLayout class via the BeginSpan() and EndSpan() methods.  Each span represents a run of frames with the same style data (???).  Other methods exist on the nsLineLayout class to position and size the frames on the current line.

nsBlockBandData is the class used to manage the processing of the space-manager (nsSpaceManager) band data.  It provides HTML/CSS specific semantics on top of the general space management facilities provided by nsSpaceManager.

nsSpaceManager is a class that is told about regions that reserve space and exposes methods to query for available space in a given band.

The nsLineBox class represents a horizontal line of frames and is singly linked to the next line box in the document.  It is basically a container of a frame list that share the property of being on the same line in the formatted output of the document.

The nsTextRun class holds on to a list of frames containing pieces of text that form a logical text run.  This is needed because a single text run can occur on leaves at many levels of the document's content tree.  This class gives the text layout process an efficient way to get access to text runs and, so, determine where word breaks should occur.

Questions

What are anonymous blocks (nsBlockFrame.h)?
What is the difference between a span and a band (nsLineLayout)?
Why do nsBlockFrame and nsInlineFrame both inherit from nsContainerFrame?

To Do

  1. Provide more information about methods and state of each of the classes above.
  2. Give a description of how the above classes interact with each other as a simple HTML document is laid out.  Then, add in different features to the HTML that exercise different areas of the code, like floats, anonymous blocks, etc.