= 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 == Transforms == * 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) and 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