wiki:April 2012 Write Your Own Render Object

Version 6 (modified by, 12 years ago) (diff)


Write Your Own Render Object

Eric Siedel

(Dirk Pranke, scribe)

  • Goal: give you some comfort if you have to write a rendering patch next week
  • Give you some idea about how to create a new object
  • There is an intro talk on Youtube from Eric from a few years ago on this ...
  • There is a page linking to Hyatt's blog posts
  • There are render objects and a render tree
  • There is also a line box tree that does text handling and line - we're largely going to ignore this
    • Everything with "inline" in the name
  • There is also RenderLayer, which can mostly be ignored unless you're doing compositing or other more advanced things *The RenderTree is kind of like a scene list/graph or a display list - it's a fast way of figuring out what to draw rather than having to go back to the DOM

Class hierarchy

  • RenderObject
    • RenderText - holds text and keeps a line box tree. Some things need different styling and become subclasses, e.g.
      • RenderCombineText, RenderTextFragment, etc.
    • RenderBoxModelObject - where most new elements come in for elements in the CSS box model (there are either inline or boxes in the CSS box model)
      • RenderBlock - if you have text children that need to flow or if you need to be a containing block
      • RenderInline - for SPAN, etc. ... are rendered by their containing block
  • What do you subclass from?
    • RenderBlock - if you have children
    • RenderFixed - if you are a single element with a fixed size
    • RenderObject - if you need to do something unusual
  • What do you need to implement?
    • layout()
    • paint()

First figure out how big you are : figure out your width. then size your kids, and then compute your height as necessary to fit everything

Pause for Questions - what do people want to know about?

  • transforms?
  • RenderText vs inline text boxes?
  • xpos / ypos ? have been replaced by accumulated offsets - how do these relate to absolute positioning?
  • logical vs. physical coordinate spaces (e.g., RTL - does x mean "from left" or "from start")?
  • painting the line box tree


  • done in two separate parts of the tree, one for html/css, one for svg
  • for html/css, done in RenderLayer - the layer handles transforms, masking, clipping, etc. RenderObjects are supposed to be dumb.
  • in svg, all of the objects know how to handle transforms intrinsically

RenderText vs. InlineTextBox

  • parts of the render tree are dumb and just contain data (e.g., text nodes) - these don't layout or paint themselves.
    • In this case the containing object creates a list of lines of text (the line box tree)
    • the containing object may have to deal with RTL direction, ligatures, etc.
  • A RenderTextFragment splits off the first letter to handle "first-letter"
  • "first-line" is split off into a different InlineText box

X-Position and the absolute coordinates

  • most objects maintain coordinates from their containing block - you can get the absolute coordinates by either walking up the dom tree computing offsets or going to the RenderLayer which maintains a cache.
  • when you are "position: absolute" you have to go to your positioning context and ancestor instead

Logical vs. Physical coordinate spaces

  • There are multiple coordinate systems in the rendering tree
    • One is for vertical vs. horizontal writing direction (logical height vs. height)
    • logical vs. document order for RTL (right-to-left text)
    • there might be a third (?)
    • before/after and start/end are CSS concepts that map onto logical and physical in WebKit
      • cf. CSS 3 Writing Modes spec ?
      • always use the logical height and width in order to do the right thing

How the Linbox Tree Paints

  • All the painting logic is in RenderBlock, first line down, left to right
    • Creates text run objects and sends those to the GraphicsContext
    • the text run splits between simple and complex
    • the chunking logic is done through the Unicode abstraction to ICU on most ports
      • the logic may also be platform-specific because different text rendering engines may be able to handle different things (e.g., ATSUI vs. DirectWrite)
    • the LTR/RTL logic sorts a list of text runs
  • How do we figure out when to break for lines?
    • all in RenderBlockLineLayout - calls out to ICU to figure out where breaks can occur
    • then we measure the widths of the glyphs and determine where we might want to break
  • There is also a cache of glyphs so that we can measure each character quickly
    • Unclear how this interacts with complex text runs
    • also text rendering optimize legibility can through you down the complex text path

Implementation Notes

  • everything in the render tree is single ownership (new/delete), not ref counted
  • per-document memory arenas for quick destruction
  • there is a single renderer per document rooted at the RenderView
  • display:none objects have no render objects
  • each renderer has 0 or 1 pointers to Nodes; renderers with 0 pointers are "anonymous"
  • you can see the render tree in safari after enabling the internal debug menu and turning off Webkit 2
  • and of course in the -expected.txt files in the LayoutTests


  • Should everything be deriving from RenderBlock? That does a lot ...
    • Yes, although there is discussion of breaking up the RenderBlock object

  • Should we blur the lines between nodes and renderers so that nodes could have multiple renderers (e.g., for pull quotes in regions, or for shadow dom?)
    • Possibly we can do enough of this with anonymous render blocks
    • e.g., -moz-element
    • SVG does this to some extent already becaues of the way the SVG dom works?
    • this is similar to how regions work

  • How does the shadow DOM fit into this?
    • the shadow DOM spec is very DOM-oriented
    • it basically synthesizes the render trees as needed