michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: michael@0: Gecko Layout Engine michael@0: Troy Chevalier michael@0: 8 August 1999 michael@0: michael@0: Overview michael@0: Gecko is Mozilla's new layout engine. It is based on the HTML4, CSS1, XML 1.0, michael@0: and DOM Internet standards, and it is built using a modular XPCOM-based michael@0: architecture. michael@0: michael@0: When we talk about layout, we're referring to the formatting process that applies michael@0: presentation styles to a source document. The formatting process is controlled michael@0: by the style specification. michael@0: michael@0: Components michael@0: Here are a list of components and terms that will be referenced by this document. michael@0: michael@0: michael@0: Parser michael@0: Either the HTML michael@0: or XML parser. Processes the document and makes calls to the content sink. michael@0: michael@0: Content sink michael@0: Called by the parser. Responsible for building the content model. michael@0: michael@0: Content model michael@0: Consists of document object and a tree of content objects. Changes to the michael@0: content model result in modifications of the frame model. michael@0: michael@0: Frame model michael@0: Frames are formatting michael@0: objects. Each frame defines a particular set of formatting characteristics. michael@0: michael@0: Reflow michael@0: The formatting process. Reflow of the frame model defines the visual appearance michael@0: of the formatted document. michael@0: michael@0: Frame construction michael@0: Initial creation and updating of the frame model in response to changes to the michael@0: content model and changes to the style data. michael@0: michael@0: Style system michael@0: Provide the mapping and management of style data onto document content in a given michael@0: presentation. Major components are style set, style sheets, style sheet and michael@0: rules, style context, and style sheet loader. michael@0: michael@0: Presentation shell michael@0: Controlling point for managing the presentation of a document. michael@0: michael@0: View system michael@0: Consists of a view manager and view objects arranged in a tree hierarchy. michael@0: Views support overlapped positioning, z-order sorting, and opacity levels. michael@0: michael@0: michael@0: Document Loading michael@0: The basic flow of control is as follows: as the parser encounters tokens it notifies michael@0: the content sink that a new node (or child node) is encountered. The content sink michael@0: creates the appropriate type content object and inserts it into the content model. michael@0: michael@0: Whenever the content model changes the document's observers are notified. The presentation michael@0: shell is one of the document observers. The presentation shell forwards the document michael@0: change notification to the style set object michael@0: michael@0: The style set passes the notification to the frame construction code, the michael@0: frame construction code creates new frames and inserts them into the frame model. The michael@0: document is reflowed, and the formatted changes are displayed. michael@0: michael@0: michael@0: michael@0: The actual interfaces involved are: michael@0: michael@0: nsIDocument michael@0: nsIDocumentObserver michael@0: nsIPresShell michael@0: nsIStyleSet michael@0: nsIStyleFrameConstruction michael@0: nsIFrame michael@0: michael@0: michael@0: michael@0: All of the interface files are located in the mozilla/layout/base/public michael@0: directory. michael@0: michael@0: Object Lifetimes michael@0: Gecko supports multiple views of the same document. This means you can print the michael@0: same document that you're viewing on the screen, and there's only one content michael@0: model. Because there's just a single content model, each of the content objects michael@0: is referenced counted. The document holds a reference to the root content object, michael@0: and each content node holds a reference to its child content nodes. michael@0: michael@0: Each view of the document has a separate presentation shell, style manager, michael@0: style set, and frame hierarchy. The presentation shell is the controlling point for michael@0: the presentation of a document, and it holds a reference to the document object. michael@0: michael@0: Frames and views are not referenced counted. The lifetime of the frame hierarchy michael@0: is bounded by the lifetime of the presentation shell which owns the frames. The michael@0: lifetime of the view hierarchy is bounded by the lifetime of the view manager michael@0: that owns the views. michael@0: michael@0: Frames michael@0: Each frame defines a particular set of formatting characteristics. Frames have michael@0: the opportunity to: michael@0: michael@0: reflow (format) their child frames michael@0: render their appearance michael@0: handle mouse and keyboard events michael@0: display a cursor michael@0: have an associated view object michael@0: michael@0: michael@0: michael@0: Frames can have multiple child lists, the default unnamed child list michael@0: (referred to as the principal child list) and additional named child lists. michael@0: There is an ordering of frames within a child list, but no ordering michael@0: between frames in different child lists of the same parent frame. michael@0: michael@0: The principal child list contains the flowed children, and the additional michael@0: child lists are for out-of-flow frames like floated elements and absolutely michael@0: positioned elements. michael@0: michael@0: Child frames are linked together in a singly linked list. Each frame michael@0: defines its own local coordinate space. Frame bounding rects are in twips, michael@0: and the origin is relative to the upper-left corner of its parent frame. michael@0: The bounding rect includes the content area, borders, and padding. michael@0: michael@0: Frame Construction michael@0: The frame construction process begins with a notification that content michael@0: has been added or removed or that style has changed. michael@0: michael@0: The first step is to resolve style information for the content element. michael@0: This process creates a style context that is stored in the frame (see michael@0: nsIStyleContext). michael@0: michael@0: Once style is resolved construction rules are used to decide the type of michael@0: frame to create. First we look at the element's tag and special case some michael@0: things like IMG elements. If we don't create a frame that way, then we use michael@0: the 'display' property to dictate what type of frame to create. Typically michael@0: it's a block or inline frame. michael@0: michael@0: For a 'display' value of 'none' no frame is created. For elements that are michael@0: out of the flow (for example, a floated element or an absolutely positioned michael@0: element), a placeholder frame is also created. The placeholder frame is inserted michael@0: into the flow exactly where the out-of-flow frame would have been inserted. michael@0: The out-of-flow frame is then inserted as a child of its containing block in michael@0: one of the additional child lists. Floated frames are inserted into the michael@0: "Float-list" and absolutely positioned frames are inserted into the michael@0: "Absolute-list". michael@0: michael@0: Frame Manager michael@0: The frame manager is owned by the presentation shell and used by both the michael@0: presentation shell and the frame construction code. It serves two main michael@0: purposes: michael@0: michael@0: provides a service for mapping from content object to frame and from out-of-flow michael@0: frame to placeholder frame michael@0: coordinates structural modifications to the frame model michael@0: michael@0: michael@0: michael@0: In many places in the frame code we need to find the frame associated with michael@0: a particular content object. In order to quickly implement this operation we michael@0: maintain a mapping from content objects to frames. The frame construction adds michael@0: and removes entries from the map as frames are created and destroyed. michael@0: michael@0: When creating new frames and removing existing frames, the frame construction michael@0: code doesn't directly modify the frame hierarchy. Instead if informs the frame michael@0: manager and has it coordinate the request. If the frame model lock is available, michael@0: the change is processed immediately; otherwise, the request is queued and michael@0: processed later. michael@0: michael@0: The frame manager also coordinates processing of replaced elements that can't michael@0: be rendered (for example, an IMG or OBJECT element), and it allows client to michael@0: register to be notified when a particular frame is being destroyed. This is michael@0: needed because frames are not reference counted. It's used by the event manager michael@0: and other clients to ensure that any outstanding references to the frame are michael@0: cleaned up. michael@0: michael@0: Reflow Process michael@0: The fact that are two reflow interfaces reflects an early michael@0: goal of having core layout and HTML specific layout. The core reflow process would michael@0: be the same for all frames, and each class of formatting objects (for michael@0: example, CSS and DSSSL) would have their own reflow additions. michael@0: michael@0: The reflow process is a top-down protocol where a frame is given some michael@0: available space and asked to reflow its child frames and return a desired michael@0: size. michael@0: michael@0: The reflow process is not part of the nsIFrame interface. The generic reflow michael@0: interface is defined in the nsIFrameReflow interface, and the HTML/CSS specific michael@0: reflow interface is defined in the nsIHTMLReflow interface. michael@0: michael@0: An important part of the reflow process is the calculation of the computed michael@0: values for the CSS properties. This includes things like 'width', 'height', michael@0: and 'margin', and involves calculation of the containing block width and height michael@0: and percentage based values and properties whose value is inherited. michael@0: michael@0: This process is encapsulated in the HTML specific reflow state struct michael@0: (struct nsHTMLReflowState) that is passed in as part of reflow. The reflow michael@0: states are linked together with the reflow state for a child frame pointing michael@0: to its parent frame's reflow state. This allows us to walk up the reflow state michael@0: structures and calculate containing block width and height and percentage michael@0: based values. michael@0: michael@0: In addition to the computed values for the CSS box model properties, the michael@0: following items are also included: michael@0: michael@0: reflow reason that indicates why the frame is being reflowed michael@0: a rendering context that can be used to measure text michael@0: reflow command (only used for incremental reflow) michael@0: space manager michael@0: michael@0: michael@0: michael@0: The most common reflow reasons are 'eReflowReason_Resize' (the viewport michael@0: has changed size) and 'eReflowReason_Incremental' (processing of an incremental michael@0: reflow command). michael@0: michael@0: Reflow commands (see nsHTMLReflowCommand in mozilla/layout/html/base/src) are used michael@0: to kick off an incremental reflow. They're generated either by the style system michael@0: (in response to a style change) or by a frame itself (for example, if a frame has michael@0: dirty child frames that need to be reflowed it will generate a reflow command). michael@0: michael@0: Reflow commands are queued by the presentation shell and then dispatched. Reflow michael@0: commands have a target frame, which is the frame for which the reflow command michael@0: is destined. In the example above the target frame is the frame with dirty child michael@0: frames that need to be reflowed. Reflow command processing follows a path from michael@0: the root frame down to the target frame. michael@0: michael@0: The space manager (see nsISpaceManager in mozilla/layout/base/public) is used michael@0: when flowing text around floated elements. It has an API for managing bands of michael@0: unavailable space (space that is reserved for a floated element). Internally it michael@0: organizes the band data similar to how a region data structure works. michael@0: michael@0: Frame Classes michael@0: There are four main categories of frame classes, all of which are located michael@0: in mozilla/layout/html/src: michael@0: michael@0: michael@0: core frame classes michael@0: table frame classes michael@0: form frame classes michael@0: frameset frame classes michael@0: michael@0: michael@0: michael@0: The core frame classes implement the CSS viewport abstraction, scrolling, michael@0: block and inline display of flowed elements, floats, and absolute positioning. michael@0: michael@0: For more information on block layout, click michael@0: here. For more information about michael@0: line layout, click here. michael@0: michael@0: The table frame classes correspond to the HTML4 table spec, and in addition michael@0: to the table frame there are row group frames, row frames, column group frames, michael@0: column frames, and cell frames. There is an "outer" table frame as well that's michael@0: really an anonymous frame that contains the caption frame and the table frame michael@0: itself. michael@0: michael@0: Table layout is determined in a 3-step process. In the first step, the table michael@0: is flowed into an infinitely wide and tall space. This gives us the minimum and michael@0: desired sizes for every cell in the table. In the second step, the table constraints michael@0: are factored in and widths are assigned to every cell. In the third step, heights are michael@0: assigned to every cell based on the computed width constraint. The results of the first michael@0: step are cached and only need to be recomputed when content or constraints are changed. michael@0: michael@0: Event Manager michael@0: To be written michael@0: michael@0: