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. |
| 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 |
| 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 |