Layout Architecture
description
Transcript of Layout Architecture
Layout Architecture
Layout
• fixed, relative• stack/grid– flow (mostly) root->leaf; parent positions child
• flow– flow leaves->root; children resize parents
• constraint– variety: geometric, linear, …
• might subsume above styles?– want implicit else verbose and too hard (obj. funcs..)
Box Modelhttp://xtech06.usefulinc.com/schedule/paper/146
• words (leaves) form sentences form paragraphs form pages• generally horizontal focus with lee-way in vertical alignment (ex: word
wrapping)• HTML: left-right top-bottom flow eval
– w/ nearly 1 pass (modulo tables)• XUL: sibling constraints (box model)
– flow + constraints– Intrinsics: w = max(min_size, min(avail, pref))
• complicated constraints: http://groups.google.com/group/netscape.public.mozilla.layout/msg/0455a21b048ffac3
– Frame: intrinsic widths; Box: intrinsic widths + heights• Incremental semantics: local change handling matches whole document
semantics
External Style Sheets
• HTML specifies ~semantic document– style is orthogonal– templating (mass changes) important
• CSS: patterns read right-to-left– XUL handbook views good ‘naming’ a useful perf.
optimization (http://developer.mozilla.org/en/Writing_Efficient_CSS)– CSS2.1 chapters (dec. ord. imp): 10,9,11,8
(https://wiki.mozilla.org/Gecko:Reflow_Refactoring)– generated content: div { content: url(f.gif) ‘hello’ }
Mild Context Adaptivity
Selectorshttp://www.w3.org/TR/2006/WD-CSS21-20060411/selector.html
• B ::= (T ‘{‘ <rules> ‘}’)*• T ::= E [‘,’ E]* //or (not nested)• E :: = E E //descendant
| E ‘>’ E //child | E + E //E2 with prev. sib. of E1 | L
• L ::= [ ‘[‘ P+ ‘]’ ] [<tag> | ‘*’ | ‘#’ <id>] (‘.’ <class>)* [ S ]*• P ::= <attr> | <attr> <relation> <val>• S ::= ‘:’ <pseudo>
– pseudo-classes: might get dynamically activated– Pseduo-elements: (first-element, …)– might generate content (:before, :after) like counters or bullets
• bottom-up on tree (right-left on selector)– trivially parallel
Cascading Style Sheets: Induced Dependencies
• many unspec. props. on an elt. are inherited– Eg., font-size
• some props can be a rel. val of a parent’s prop– Eg., #foo { font-size: 2em } means double of parent
• some props can be a rel. val of another in same elt– Eg., #foo {font-size: 2px; text-indent: 2em; }
• #foo {line-height: 120%} /* of font-size */– In that case, pass down computed/closed val
• as opposed to rel/dyn one• body {
font-size: 12px; text-indent: 3em; /* i.e., 36px */ }h1 { font-size: 15px }<body><h1> text-indent is 36px, not 45px </h1></body>
• Funnier ones: counters that can increment & reset• Computed vs used values: don’t need rendering for former
– Actual value: used value after approximation (eg., color fixing for monitor)
Hierarchical Rules
• ex: what happens when “left: 2, right: 3” ?– use direction property to pick
• ex: abs & fixed pos => no float• ex: width != margin-left + padding-left + …– fudge margins (left or right based on direction)
• some additional preprocessing here..
• Rule-based precedence – pre-compile rules into FSM? [work-efficiency]• dynamic / async. stylesheet loading…
– Not sure how to understand the ‘cascade’ spec (http://www.w3.org/TR/2006/WD-CSS21-20060411/cascade.html)
• Strange maxsum precedence order
WebKit
• fork from KDE/KHTML• macs: Safari / iPhone• common for embeddings– Google Android & Chrome
Basic flow: WebKit Rendering 1http://webkit.org/blog/114/webcore-rendering-i-the-basics/
• DOM tree is emitted by parser– Document
• SVGDocument• HTMLDocument
– Element or Text
• linked to renderTree with renderObjects– renderBox is a box model renderObject– attach() a renderObject to Element before attach()ing children
• may query CSS for (uncomputed) renderStyle• no position or size yet
– may need to create anonymous/invis. renderObjects
Basic Flow: WebKit Layout 2http://webkit.org/blog/115/webcore-rendering-ii-blocks-and-inlines/
• 2 types of flows– Inline flow: element part of a line– Box flow: element to stack boxes/lines– Replaced element: unknown; either (eg., plugins)
• Element can act diff. inside & outside– inline-block: inline outside, block flow inside
• inline-table
• Block flow: children all inline or all block• Inline flow: children all inline
Basic Flow: WebKit Layout 2http://webkit.org/blog/115/webcore-rendering-ii-blocks-and-inlines/
• Pre-processing • <div>hello <div>block</div></div>
– <div><anon-block>hello</anon-block> <div>block</div></div>
• <i>some <b>inline</b> <div>or </div><div>really bad</div> code</i>– <anon-block>
<anon-block><i>some <b>inline</b></i></> <anon-block><div>or</div><div>really bad</div></> <anon-block><i>code</i></anon-block></anon-block>
– notice funny chaining on <i>– called continuation()/splitflow()
Basic Flow: WebKit Layout 3http://webkit.org/blog/116/webcore-rendering-iii-layout-basics/
• Containing-block ~positions items inside• Root’s: RenderView (visible browser area)• Fixed’s: RenderView (visible browser area)
– all ~independent of each other (paint phase)• Static (def)/relative: closest block ancestor• Absolute: closest non-statically positioned block ancestor
– meaning closest absolute/fixed/relative parent?• Layout loop:
– for each child:• maybe relayout() // sometimes despite dirty bits• place()• maybe relayout()
– clean dirty bits
Basic Flow: WebKit Layout 4http://webkit.org/blog/117/webcore-rendering-iv-absolutefixed-and-relative-positioning/
• static: default inline or block (rel. parent)• relative (top, right, bottom, left):– computable @ paint-time, not layout time
Basic Flow: WebKit Layout 4http://webkit.org/blog/117/webcore-rendering-iv-absolutefixed-and-relative-positioning/
• absolute & fixed:– becomes block layout if not before
• after positioning (before rendering):– top,left:auto => removed from flow, but painted in natural location!
• display() vs originalDisplay()– independent of siblings (stack on z plane)
• fixed is a special case of absolute: position relative to viewport instead of closest containing block
• relative inlined element may become containing view of abs. pos. child– meaning must be positioned before location of children can be
figured out• but *relative* positioning of children can still be done independently..
Basic Flow: WebKit Layout 5http://webkit.org/blog/118/webcore-rendering-v-floats/
• Elements may float (left, right) of siblings– non-local: sibling lines calculate around these– nesting behavior?
• Elements may clear themselves from (left,right) floating siblings– block elements can do this too (?)– nesting behavior?
Intermezzo: Overflows
• Element’s contents may conflict with specified size• Handling specified via overflow property– hidden: anything outside containing box clipped– scroll: clip, but display scrollbars
• Good for dynamic regions: resizing won’t introduce new scrollbars as they’re already there
– auto: UA choice, must have scrollbars on overflow– Visible: content not clipped
• TODO check if paint time or layout time
WebKit Space Managershttps://bugzilla.mozilla.org/attachment.cgi?bugid=115310&action=viewall
• Space manager stores data for block layout– occupied & free space in horizontal bands• w/height?
• in reflow, block propagates down a new one– Going up: destroy new, restore old– add child floats (observing block lines?)– Compute free space for line based on prev?
Mozilla’s Gecko
• started as Netscape engine• had a huge overhaul (“new layout”)– behind on acid tests– … but believed to be (one of?) best ‘overall’
Terminologyhttp://www.mozilla.org/newlayout/doc/reflow.html
• Reflow – compute flow layout• Frame – a box (x,y offset from parent + w,h)– ex: wrapping paragraph has a frame per line– first line of para is primary, rest are continuing– Frame construction: build frame tree
• Painting – mapping layout to pixels (and back)• Dispatch queue w/ coalescing (batch changes
somehow)
Reflow data passinghttp://www.mozilla.org/newlayout/doc/reflow.html
• Reflow State: parent creates, sends to child– Ex: root receives viewport dims– Ex: if fixed width, pass it down– Often fresh between frames• Ex: width of parent – padding – margin
• ReflowMetrics: child sends to parent– Children of unconstrained <div>
• Space Manager in a block containing floats tracks space & dirtying of lines
Interactions w/Layout
• Initial Layout• Style change (font-size – global impact)– intrinsics, sizes need recalc
• Resize (containing frame)– intrinsics same, sizes need recalc
• Incremental – guaranteed changes only below• Dirty (bits) –coalescing mult. incrementals below– some changes will notify parents, which may dirty
themselves too– ReflowDirty Incremental phase recalcs pos’s?
Floats• normalize floats: shift up & left (right) until
– touches containing block– touches another float– cannot overlap floating boxes of opposite type– cannot be higher than preceding line boxes, floats
• float policy within container seems sequential– Inside of float is a block
• but can do inner containers in parallel? (width vs height?)
• Line-boxes: flow around• non-position boxes: ignore all floats
– ex: – what if line-boxes in-between?
• clearance– push top margin of element below floats (left ones, right, both types, or don’t)– floats can have clearence– additional parallelism within float
Z-Indexing: Stacking Contexts• Page is like a bunch of layered transparencies
– back/bottom/negatives to top (you!)• Siblings atomic wrt each other
– As if all of sibling was below or above you• Really a paint-time issue
– Paint from bottom to top? – could also do top-to-bottom until all holes are covered
• Users can specify z-indexes• Floats, inlines, blocks separated on diff. contexts• Order: Background, Negatives, Blocks, Floats, Inlines,
Positioned, positives
More on width/heights• Width: 5%, 5em, … etc.
– relative to containing view (parent)• Blocks, abs/fixed pos elts:
– 100% width of parent by default (usually)• Floats, some abs (left+right:auto), inline block
– shrink-to-fit: base on intrinsics• … that may require layout of children (line breaking..)1. preferred min width: all combos of breaks
– would breaking everywhere be sufficient?
2. preferred width: only break where explicitly specified3. available width• child layout depends on container… container depends on child
– unclear why stable..
Ratios
• w = intrinsic_ratio * h• common for ‘replaced’ elements– flash, images, video (?), svg
• TODO non-linear constraints?