Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # `Source/core/layout` | 1 # `Source/core/layout` |
| 2 | 2 |
| 3 This directory contains implementation of layout objects. It covers the | |
| 4 following document lifecycle states: | |
| 5 | |
| 6 * LayoutSubtreeChange (`InLayoutSubtreeChange` and `LayoutSubtreeChangeClean`) | |
| 7 * PreLayout (`InPreLayout`) | |
| 8 * PerformLayout (`InPerformLayout`) | |
| 9 * AfterPerformLayout (`AfterPerformLayout` and `LayoutClean`) | |
| 10 | |
| 11 Note that a new Blink layout system is under development. See the | |
| 12 [LayoutNG design document](https://docs.google.com/document/d/1uxbDh4uONFQOiGuiu mlJBLGgO4KDWB8ZEkp7Rd47fw4/preview). | |
| 13 | |
| 3 ## Overflow rects and scroll offsets | 14 ## Overflow rects and scroll offsets |
| 4 | 15 |
| 5 PaintLayerScrollableArea uses a "scroll origin" to conceptually represent the di stance between | 16 PaintLayerScrollableArea uses a "scroll origin" to conceptually represent the di stance between |
| 6 the top-left corner of the box'es content rect and the top-left corner of its ov erflow rect | 17 the top-left corner of the box'es content rect and the top-left corner of its ov erflow rect |
| 7 when the box is scrolled to the logical beginning of its content (.e.g. all the way to the left for | 18 when the box is scrolled to the logical beginning of its content (e.g. all the w ay to the left for |
| 8 LTR, all the way to the right for RTL). For left-to-right and top-to-bottom flo ws, the scroll | 19 LTR, all the way to the right for RTL). For left-to-right and top-to-bottom flo ws, the scroll |
| 9 origin is zero, i.e., the top/left of the overflow rect is at the same position as the top/left of | 20 origin is zero, i.e., the top/left of the overflow rect is at the same position as the top/left of |
| 10 the box'es content rect when scrolled to the beginning of flow. For right-to-le ft and bottom-to-top | 21 the box'es content rect when scrolled to the beginning of flow. For right-to-le ft and bottom-to-top |
| 11 flows, the overflow rect extends to the top/left of the client rect. | 22 flows, the overflow rect extends to the top/left of the client rect. |
| 12 | 23 |
| 13 The default calculation for scroll origin is the distance between the top-left c orner of the content | 24 The default calculation for scroll origin is the distance between the top-left c orner of the content |
| 14 rect and the top-left corner of the overflow rect. To illustrate, here is a box with left overflow and | 25 rect and the top-left corner of the overflow rect. To illustrate, here is a box with left overflow and |
| 15 no vertical scrollbar: | 26 no vertical scrollbar: |
| 16 | 27 |
| 17 content | 28 content |
| 18 rect | 29 rect |
| 19 |<-------->| | 30 |<-------->| |
| 20 scroll | 31 scroll |
| 21 origin | 32 origin |
| 22 |<-------->| | 33 |<-------->| |
| 23 _____________________ | 34 _____________________ |
| 24 | | | | 35 | | | |
| 25 | | | | 36 | | | |
| 26 | | | | 37 | | | |
| 27 direction:rtl | | box | | 38 direction:rtl | | box | |
| 28 | | | | 39 | | | |
| 29 | | | | 40 | | | |
| 30 |__________|__________| | 41 |__________|__________| |
| 31 | 42 |
| 32 overflow rect | 43 overflow rect |
| 33 |<--------------------->| | 44 |<--------------------->| |
| 34 | 45 |
| 35 | 46 |
| 36 However, if the box has a scrollbar for the orthogonal direction (e.g., a vertic al scrollbar | 47 However, if the box has a scrollbar for the orthogonal direction (e.g., a vertic al scrollbar |
| 37 in a direction:rtl block), the size of the scrollbar must be added to the scroll origin calculation. | 48 in a direction:rtl block), the size of the scrollbar must be added to the scroll origin calculation. |
| 38 Here are two examples -- note that it doesn't matter whether the vertical scroll bar is placed on | 49 Here are two examples -- note that it doesn't matter whether the vertical scroll bar is placed on |
| 39 the right or left of the box (the vertical scrollbar is the |/| part): | 50 the right or left of the box (the vertical scrollbar is the `|/|` part): |
| 40 | 51 |
| 41 content | 52 content |
| 42 rect | 53 rect |
| 43 |<-------->| | 54 |<-------->| |
| 44 scroll | 55 scroll |
| 45 origin | 56 origin |
| 46 |<---------->| | 57 |<---------->| |
| 47 _______________________ | |
| 48 | |/| | | |
| 49 | |/| | | |
| 50 | |/| | | |
| 51 direction:rtl | |/| box | | |
| 52 | |/| | | |
| 53 | |/| | | |
| 54 |__________|/|__________| | |
| 55 | |
| 56 overflow rect | |
| 57 |<--------------------->| | |
| 58 | |
| 59 | |
| 60 | |
| 61 content | |
| 62 rect | |
| 63 |<-------->| | |
| 64 scroll | |
| 65 origin | |
| 66 |<---------->| | |
| 67 _______________________ | 58 _______________________ |
| 68 | | |/| | 59 | |/| | |
| 69 | | |/| | 60 | |/| | |
| 70 | | |/| | 61 | |/| | |
| 71 writing-mode: | | |/| | 62 direction:rtl | |/| box | |
| 72 vertical-rl | | |/| | 63 | |/| | |
| 73 | | |/| | 64 | |/| | |
| 74 | | |/| | 65 |__________|/|__________| |
| 75 | | |/| | 66 |
| 76 |__________|__________|/| | |
| 77 | |
| 78 overflow rect | 67 overflow rect |
| 79 |<--------------------->| | 68 |<--------------------->| |
| 80 | 69 |
| 70 content | |
| 71 rect | |
| 72 |<-------->| | |
| 73 scroll | |
| 74 origin | |
| 75 |<---------->| | |
| 76 _______________________ | |
| 77 | | |/| | |
| 78 | | |/| | |
| 79 | | |/| | |
| 80 writing-mode: | | |/| | |
| 81 vertical-rl | | |/| | |
| 82 | | |/| | |
| 83 | | |/| | |
| 84 | | |/| | |
| 85 |__________|__________|/| | |
| 86 | |
| 87 overflow rect | |
| 88 |<--------------------->| | |
| 89 | |
| 81 ## Coordinate Spaces | 90 ## Coordinate Spaces |
| 82 | 91 |
| 83 TODO(wkorman): Document writing mode, particularly flipped blocks. | 92 Layout and Paint work with and frequently refer to three main coordinate spaces |
| 93 (really two, with one variant): | |
| 94 | |
| 95 * Physical coordinates: Corresponds to physical direction of the output per the | |
| 96 physical display (screen, printed page). Generally used for painting, thus | |
| 97 layout logic that feeds into paint may produce values in this space. CSS | |
| 98 properties such as `top`, `right`, `bottom`, and `left` are in this space. See | |
| 99 also the 'flipped block-flow direction' variant space below. | |
| 100 | |
| 101 * Logical coordinates: Used in layout to allow for generalized positioning that | |
| 102 fits with whatever the `writing-mode` and `direction` CSS property values may | |
| 103 be. Properties named with `before`, `after`, `start` or `end` are in this | |
| 104 space. These are also known respectively as 'logical top', 'logical bottom', | |
| 105 'logical left', and 'logical right'. | |
| 106 | |
| 107 * Physical coordinates with flipped block-flow direction: The same as 'physical | |
| 108 coordinates', but for `writing-mode: vertical-rl` where blocks are laid out | |
| 109 right-to-left, block position is "flipped" from the left to the right side of | |
| 110 their containing block. This is essentially a mirror reflection horizontally | |
| 111 across the center of a block's containing block. | |
|
chrishtr
2016/09/30 16:47:35
Please add an explicit example of writing mode wit
wkorman
2016/09/30 22:29:07
Done. If I've missed something with the example le
| |
| 112 | |
| 113 For `writing-mode` values other than `vertical-rl` there is no change from | |
| 114 physical coordinates. | |
| 115 | |
| 116 Layout and paint logic reference this space to connote whether "flipping" has | |
| 117 been applied to the values. Final painted output for "flipped block-flow" | |
| 118 writing mode must, by definition, incorporate flipping. It can be expensive to | |
| 119 look up the writing mode of an object. Performing computation on values known | |
| 120 to be in this space can save on the overhead required to unflip/reflip. | |
| 121 | |
| 122 Example with `writing-mode: vertical-rl; direction: ltr`: | |
| 123 | |
| 124 'top' / 'start' side | |
| 125 | |
| 126 block-flow direction | |
| 127 <------------------------------------ | | |
| 128 ------------------------------------- | | |
| 129 | c | s | | | |
| 130 'left' | o | o | | inline 'right' | |
| 131 / | n | m | | direction / | |
| 132 'after' | t | e | | 'before' | |
| 133 side | e | | | side | |
| 134 | n | | | | |
| 135 | t | | | | |
| 136 ------------------------------------- v | |
| 137 | |
| 138 'bottom' / 'end' side | |
| 139 | |
| 140 See also this [demo page](http://pauljadam.com/demos/csstext.html) though note | |
| 141 `horizontal-bt` is obsolete. | |
| 142 | |
| 143 ### Flipped Block-Flow Coordinates | |
| 144 | |
| 145 The nature of "flipping" a value as a mirror reflection within its containing | |
| 146 block is such that flipping twice with the same container will produce the | |
| 147 original result. Thus when working on involved logic it can be easy to | |
| 148 accidentally flip unnecessarily, since flipping (say) one too many times can be | |
| 149 "corrected" by flipping again. This can obviously lead to confusing and less | |
| 150 performant code, so care should be taken to understand and document any changes | |
| 151 to flipping logic. | |
| 152 | |
| 153 Blink test coverage for features used in vertical writing modes, and | |
| 154 `vertical-rl` in particular, may not be as comprehensive as for horizontal | |
| 155 writing mode. Keep this in mind when writing new functionality or tests by | |
| 156 making sure to incorporate coverage for all writing modes when appropriate. | |
| 157 | |
| 158 Values are generally transformed into flipped block-flow coordinates via a set | |
| 159 of methods on the involved layout objects. See in particular | |
| 160 `flipForWritingMode()`, `flipForWritingModeForChild()`, and `topLeftLocation()`. | |
| 161 | |
| 162 `InlineBox::flipForWritingMode()` variants flip the input value within the | |
| 163 inline box's containing block. | |
| 164 | |
| 165 `LayoutBox::flipForWritingMode()` variants flip the input value within the | |
| 166 referenced box. | |
| 167 | |
| 168 `LayoutBox::flipForWritingModeForChild()` variants flip the input value within | |
| 169 the referenced box, offsetting for the specified child box's current x-position | |
| 170 and width. This is useful for a common pattern wherein we build up a point | |
| 171 location starting with the current location of the (child) box. | |
| 172 | |
| 173 `LayoutBox::topLeftLocation()` performs flipping as needed. If the containing | |
| 174 block is not passed to the method, looking it up requires walking up the layout | |
| 175 tree, which can be expensive. | |
| 176 | |
| 177 Note there are two primary similar, but slightly different, methods regarding | |
| 178 finding the containing block for an element: | |
| 179 | |
| 180 * `LayoutObject::container()` returns the containing block for an element as | |
|
chrishtr
2016/09/30 16:47:35
Could you just rename these methods to match their
wkorman
2016/09/30 22:29:07
I'll file a bug to do separately as I'd like to ke
| |
| 181 defined by CSS. | |
| 182 * `LayoutObject::containingBlock()` which returns the enclosing non-anonymous | |
| 183 block for an element. If the containing block is a relatively positioned inline, | |
| 184 it returns that inline's enclosing non-anonymous block. This is the one used by | |
| 185 `topLeftLocation()`. | |
| 186 | |
| 187 There are other containing block methods in `LayoutObject` for special purposes | |
| 188 such as fixed position, absolute position, and paint invalidation. Code will | |
| 189 sometimes just refer to the 'containing' element, which is an unfortunately | |
| 190 ambiguous term. Paying close attention to which method was used to obtain the | |
| 191 containing element is important. | |
| 192 | |
| 193 More complex web platform features such as tables, flexbox, and multicol are | |
| 194 typically implemented atop these primitives, along with checks such as | |
| 195 `isFlippedBlocksWritingMode()`, `isLeftToRightDirection()`, and | |
| 196 `isHorizontalWritingMode()`. See for example | |
| 197 `LayoutTableSection::logicalRectForWritingModeAndDirection()`, | |
| 198 `LayoutFlexibleBox::updateAutoMarginsInCrossAxis()` or | |
| 199 `LayoutMultiColumnFlowThread::flowThreadTranslationAtPoint()`. | |
| 200 | |
| 201 ## Geometry mapping | |
| 202 | |
| 203 TODO(wkorman): Elaborate on: | |
| 204 * `mapToVisualRectInAncestorSpace()` | |
| 205 * `mapAncestorToLocal()` | |
| 206 * `Widget` and `FrameView` trees. Note the former will be done away with at some | |
| 207 point per http://crbug.com/637460. | |
| 208 * `GeometryMapper` (or just point to its section in paint README). For now, see | |
| 209 the | |
| 210 [Web page geometries](https://docs.google.com/document/d/1WZKlOSUK4XI0Le0fgCsy UTVw0dTwutZXGWwzlHXewiU/preview) | |
| 211 design document. | |
| 212 | |
| 213 ## Scrolling | |
| 214 | |
| 215 TODO(wkorman): Provide an overview of scrolling. For now, the BlinkOn talk | |
| 216 on | |
| 217 [Scrolling in Blink](https://docs.google.com/presentation/d/1pwx0qBW4wSmYAOJxq2g b3SMvSTCHz2L2TFx_bjsvm8E/preview) | |
| 218 is a good overview. | |
| 219 | |
| 220 ## Glossaries | |
| 221 | |
| 222 Here we provide a brief overview of key terms relevant to box flow, inline flow, | |
| 223 and text orientation. For more detail see | |
| 224 [CSS Writing Modes Level 3](https://www.w3.org/TR/css-writing-modes-3/). | |
| 225 | |
| 226 The | |
| 227 [CSS Logical Properties Level 1](https://drafts.csswg.org/css-logical-props/) | |
| 228 specification represents the latest CSSWG thinking on logical coordinate space | |
| 229 naming. CSSWG has standardized on `block-start`, `block-end`, `inline-start`, | |
| 230 and `inline-end`, or just `start` and `end` when the axis is either implied or | |
| 231 irrelevant. | |
| 232 | |
| 233 Note that much of the Blink code base predates the logical properties | |
| 234 specification and so does not yet reference logical direction consistently in | |
| 235 the stated manner, though we would like to head in that direction over time. | |
| 236 See also the *physical*, *flow-relative*, and *line-relative* | |
| 237 [abstract box terminology](https://www.w3.org/TR/css-writing-modes-3/#abstract-b ox) | |
| 238 specification. | |
| 239 | |
| 240 * `writing-mode`: either horizontal or vertical, with vertical having either | |
| 241 left-to-right or right-to-left block flow. Geometry is transposed for vertical | |
| 242 writing mode. See calls to `transposed{Rect,Point,Size}()`. | |
| 243 * `direction`/`dir`: "inline base direction" of a box. One of `ltr` or | |
| 244 `rtl`. See calls to `isLeftToRightDirection()`. | |
| 245 * `text-orientation`: orientation of text in a line. Only relevant for vertical | |
| 246 modes. | |
| 247 * orthogonal flow: when a box has a writing mode perpendicular to its containing | |
| 248 block. This can lead to complex cases. See | |
| 249 [specification](https://www.w3.org/TR/css-writing-modes-3/#orthogonal-flows) | |
| 250 for more. | |
| OLD | NEW |