tree: ec22a0732128fb17e78e7cb8224e1968da35f060 [path history] [tgz]
  1. AdjustForAbsoluteZoom.h
  2. BUILD.gn
  3. BackgroundBleedAvoidance.h
  4. BaselineAlignment.cpp
  5. BaselineAlignment.h
  6. BidiRun.h
  7. BidiRunForLine.cpp
  8. BidiRunForLine.h
  9. CollapsedBorderValue.cpp
  10. CollapsedBorderValue.h
  11. CollapsedBorderValueTest.cpp
  12. ColumnBalancer.cpp
  13. ColumnBalancer.h
  14. ContentChangeType.h
  15. CounterNode.cpp
  16. CounterNode.h
  17. DepthOrderedLayoutObjectList.cpp
  18. DepthOrderedLayoutObjectList.h
  19. FlexibleBoxAlgorithm.cpp
  20. FlexibleBoxAlgorithm.h
  21. FloatingObjects.cpp
  22. FloatingObjects.h
  23. FragmentainerIterator.cpp
  24. FragmentainerIterator.h
  25. FragmentationContext.h
  26. GeneratedChildren.h
  27. Grid.cpp
  28. Grid.h
  29. GridLayoutUtils.cpp
  30. GridLayoutUtils.h
  31. GridTrackSizingAlgorithm.cpp
  32. GridTrackSizingAlgorithm.h
  33. HitTestCache.cpp
  34. HitTestCache.h
  35. HitTestCanvasResult.cpp
  36. HitTestCanvasResult.h
  37. HitTestLocation.cpp
  38. HitTestLocation.h
  39. HitTestRequest.h
  40. HitTestResult.cpp
  41. HitTestResult.h
  42. HitTestingTransformState.cpp
  43. HitTestingTransformState.h
  44. IntersectionGeometry.cpp
  45. IntersectionGeometry.h
  46. LayoutAnalyzer.cpp
  47. LayoutAnalyzer.h
  48. LayoutBR.cpp
  49. LayoutBR.h
  50. LayoutBlock.cpp
  51. LayoutBlock.h
  52. LayoutBlockFlow.cpp
  53. LayoutBlockFlow.h
  54. LayoutBlockFlowLine.cpp
  55. LayoutBlockTest.cpp
  56. LayoutBox.cpp
  57. LayoutBox.h
  58. LayoutBoxModelObject.cpp
  59. LayoutBoxModelObject.h
  60. LayoutBoxModelObjectTest.cpp
  61. LayoutBoxTest.cpp
  62. LayoutButton.cpp
  63. LayoutButton.h
  64. LayoutCountTest.cpp
  65. LayoutCounter.cpp
  66. LayoutCounter.h
  67. LayoutDeprecatedFlexibleBox.cpp
  68. LayoutDeprecatedFlexibleBox.h
  69. LayoutDetailsMarker.cpp
  70. LayoutDetailsMarker.h
  71. LayoutEmbeddedContent.cpp
  72. LayoutEmbeddedContent.h
  73. LayoutEmbeddedContentTest.cpp
  74. LayoutEmbeddedObject.cpp
  75. LayoutEmbeddedObject.h
  76. LayoutFieldset.cpp
  77. LayoutFieldset.h
  78. LayoutFileUploadControl.cpp
  79. LayoutFileUploadControl.h
  80. LayoutFlexibleBox.cpp
  81. LayoutFlexibleBox.h
  82. LayoutFlowThread.cpp
  83. LayoutFlowThread.h
  84. LayoutFrame.cpp
  85. LayoutFrame.h
  86. LayoutFrameSet.cpp
  87. LayoutFrameSet.h
  88. LayoutFullScreen.cpp
  89. LayoutFullScreen.h
  90. LayoutGeometryMap.cpp
  91. LayoutGeometryMap.h
  92. LayoutGeometryMapStep.h
  93. LayoutGeometryMapTest.cpp
  94. LayoutGrid.cpp
  95. LayoutGrid.h
  96. LayoutHTMLCanvas.cpp
  97. LayoutHTMLCanvas.h
  98. LayoutIFrame.cpp
  99. LayoutIFrame.h
  100. LayoutImage.cpp
  101. LayoutImage.h
  102. LayoutImageResource.cpp
  103. LayoutImageResource.h
  104. LayoutImageResourceStyleImage.cpp
  105. LayoutImageResourceStyleImage.h
  106. LayoutInline.cpp
  107. LayoutInline.h
  108. LayoutInlineTest.cpp
  109. LayoutListBox.cpp
  110. LayoutListBox.h
  111. LayoutListItem.cpp
  112. LayoutListItem.h
  113. LayoutListMarker.cpp
  114. LayoutListMarker.h
  115. LayoutMedia.cpp
  116. LayoutMedia.h
  117. LayoutMediaTest.cpp
  118. LayoutMenuList.cpp
  119. LayoutMenuList.h
  120. LayoutMultiColumnFlowThread.cpp
  121. LayoutMultiColumnFlowThread.h
  122. LayoutMultiColumnFlowThreadTest.cpp
  123. LayoutMultiColumnSet.cpp
  124. LayoutMultiColumnSet.h
  125. LayoutMultiColumnSpannerPlaceholder.cpp
  126. LayoutMultiColumnSpannerPlaceholder.h
  127. LayoutObject.cpp
  128. LayoutObject.h
  129. LayoutObjectChildList.cpp
  130. LayoutObjectChildList.h
  131. LayoutObjectInlines.h
  132. LayoutObjectTest.cpp
  133. LayoutPagedFlowThread.cpp
  134. LayoutPagedFlowThread.h
  135. LayoutProgress.cpp
  136. LayoutProgress.h
  137. LayoutProgressTest.cpp
  138. LayoutQuote.cpp
  139. LayoutQuote.h
  140. LayoutReplaced.cpp
  141. LayoutReplaced.h
  142. LayoutRuby.cpp
  143. LayoutRuby.h
  144. LayoutRubyBase.cpp
  145. LayoutRubyBase.h
  146. LayoutRubyRun.cpp
  147. LayoutRubyRun.h
  148. LayoutRubyText.cpp
  149. LayoutRubyText.h
  150. LayoutScrollbar.cpp
  151. LayoutScrollbar.h
  152. LayoutScrollbarPart.cpp
  153. LayoutScrollbarPart.h
  154. LayoutScrollbarTheme.cpp
  155. LayoutScrollbarTheme.h
  156. LayoutSearchField.cpp
  157. LayoutSearchField.h
  158. LayoutSlider.cpp
  159. LayoutSlider.h
  160. LayoutSliderContainer.cpp
  161. LayoutSliderContainer.h
  162. LayoutSliderThumb.cpp
  163. LayoutSliderThumb.h
  164. LayoutState.cpp
  165. LayoutState.h
  166. LayoutTable.cpp
  167. LayoutTable.h
  168. LayoutTableBoxComponent.cpp
  169. LayoutTableBoxComponent.h
  170. LayoutTableCaption.cpp
  171. LayoutTableCaption.h
  172. LayoutTableCell.cpp
  173. LayoutTableCell.h
  174. LayoutTableCellTest.cpp
  175. LayoutTableCol.cpp
  176. LayoutTableCol.h
  177. LayoutTableColTest.cpp
  178. LayoutTableRow.cpp
  179. LayoutTableRow.h
  180. LayoutTableRowTest.cpp
  181. LayoutTableSection.cpp
  182. LayoutTableSection.h
  183. LayoutTableSectionTest.cpp
  184. LayoutTableTest.cpp
  185. LayoutTestHelper.cpp
  186. LayoutTestHelper.h
  187. LayoutText.cpp
  188. LayoutText.h
  189. LayoutTextCombine.cpp
  190. LayoutTextCombine.h
  191. LayoutTextControl.cpp
  192. LayoutTextControl.h
  193. LayoutTextControlMultiLine.cpp
  194. LayoutTextControlMultiLine.h
  195. LayoutTextControlSingleLine.cpp
  196. LayoutTextControlSingleLine.h
  197. LayoutTextFragment.cpp
  198. LayoutTextFragment.h
  199. LayoutTextFragmentTest.cpp
  200. LayoutTextTest.cpp
  201. LayoutTheme.cpp
  202. LayoutTheme.h
  203. LayoutThemeAndroid.cpp
  204. LayoutThemeAndroid.h
  205. LayoutThemeDefault.cpp
  206. LayoutThemeDefault.h
  207. LayoutThemeFontProvider.cpp
  208. LayoutThemeFontProvider.h
  209. LayoutThemeFontProviderDefault.cpp
  210. LayoutThemeFontProviderWin.cpp
  211. LayoutThemeFuchsia.cpp
  212. LayoutThemeLinux.cpp
  213. LayoutThemeLinux.h
  214. LayoutThemeMac.h
  215. LayoutThemeMac.mm
  216. LayoutThemeMobile.cpp
  217. LayoutThemeMobile.h
  218. LayoutThemeTest.cpp
  219. LayoutThemeWin.cpp
  220. LayoutThemeWin.h
  221. LayoutTreeAsText.cpp
  222. LayoutTreeAsText.h
  223. LayoutVTTCue.cpp
  224. LayoutVTTCue.h
  225. LayoutVideo.cpp
  226. LayoutVideo.h
  227. LayoutView.cpp
  228. LayoutView.h
  229. LayoutViewTest.cpp
  230. LayoutWordBreak.cpp
  231. LayoutWordBreak.h
  232. ListMarkerText.cpp
  233. ListMarkerText.h
  234. MapCoordinatesFlags.h
  235. MapCoordinatesTest.cpp
  236. MinMaxSize.cpp
  237. MinMaxSize.h
  238. MinMaxSizeTest.cpp
  239. MultiColumnFragmentainerGroup.cpp
  240. MultiColumnFragmentainerGroup.h
  241. MultiColumnFragmentainerGroupTest.cpp
  242. OWNERS
  243. OrderIterator.cpp
  244. OrderIterator.h
  245. OverflowModel.h
  246. OverflowModelTest.cpp
  247. PaginationTest.cpp
  248. PaintContainmentTest.cpp
  249. PointerEventsHitRules.cpp
  250. PointerEventsHitRules.h
  251. README.md
  252. ScrollAnchor.cpp
  253. ScrollAnchor.h
  254. ScrollAnchorTest.cpp
  255. ScrollbarsTest.cpp
  256. SubtreeLayoutScope.cpp
  257. SubtreeLayoutScope.h
  258. TableGridCell.cpp
  259. TableGridCell.h
  260. TableLayoutAlgorithm.h
  261. TableLayoutAlgorithmAuto.cpp
  262. TableLayoutAlgorithmAuto.h
  263. TableLayoutAlgorithmFixed.cpp
  264. TableLayoutAlgorithmFixed.h
  265. TextAutosizer.cpp
  266. TextAutosizer.h
  267. TextAutosizerTest.cpp
  268. TextDecorationOffset.cpp
  269. TextDecorationOffset.h
  270. TextDecorationOffsetBase.cpp
  271. TextDecorationOffsetBase.h
  272. TextRunConstructor.cpp
  273. TextRunConstructor.h
  274. TracedLayoutObject.cpp
  275. TracedLayoutObject.h
  276. VerticalPositionCache.h
  277. ViewFragmentationContext.cpp
  278. ViewFragmentationContext.h
  279. VisualRectMappingTest.cpp
  280. WebFontRenderingAndroid.cpp
  281. WebFontRenderingLinux.cpp
  282. WebFontRenderingWin.cpp
  283. api/
  284. custom/
  285. doc/
  286. line/
  287. ng/
  288. resources/
  289. shapes/
  290. svg/
third_party/WebKit/Source/core/layout/README.md

Blink Layout

The Source/core/layout directory contains the implementation of layout objects. It covers the following document lifecycle states:

  • LayoutSubtreeChange (InLayoutSubtreeChange and LayoutSubtreeChangeClean)
  • PreLayout (InPreLayout)
  • PerformLayout (InPerformLayout)
  • AfterPerformLayout (AfterPerformLayout and LayoutClean)

Note that a new Blink layout system is under development. See the LayoutNG design document.

The layout code is maintained by the layout team.

Scroll origin vs. offset vs. position

When a LayoutBox has scrollable overflow, it is associated with a PaintLayerScrollableArea. PaintLayerScrollableArea uses a “scroll origin” to represent the location of the top/left corner of the content rect (the visible part of the content) in the coordinate system defined by the top/left corner of the overflow rect, when the box is scrolled all the way to the beginning of its content.

For content which flows left-to-right and top-to-bottom, the scroll origin will be (0, 0), i.e., the top/left of the content rect is coincident with the top/left of the overflow rect when the box is scrolled all the way to the beginning of content.

For content which flows right-to-left (including direction:ltr, writing-mode:vertical-rl, and flex-direction:row-reverse), the x-coordinate of the scroll origin will be positive; and for content which flows bottom-to-top (e.g., flex-direction:column-reverse and vertical writing-mode with direction:ltr), the y-coordinate of the scroll origin will be positive.

In all cases, the term ‘scrollOffset’ (or just ‘offset’) is used to represent the distance of the scrolling viewport from its location when scrolled to the beginning of content, and it uses type ScrollOffset. The term ‘scrollPosition’ (or just ‘position’) represents a point in the coordinate space defined by the overflow rect, and it uses type FloatPoint.

For illustrations of these concepts, see these files:

doc/ltr-tb-scroll.png doc/rtl-bt-scroll.png doc/rtl-tb-scroll.png

When computing the scroll origin, if the box is laid out right-to-left and it has a scrollbar for the orthogonal direction (e.g., a vertical scrollbar in a direction:rtl block), the size of the scrollbar must be added to the scroll origin calculation. Here are two examples -- note that it doesn't matter whether the vertical scrollbar is placed on the right or left of the box (the vertical scrollbar is the |/| part):

                               content
                                 rect
                             |<-------->|
                    scroll
                    origin
                |----------->|
                 _______________________
                |          |/|          |
                |          |/|          |
                |          |/|          |
direction:rtl   |          |/|   box    |
                |          |/|          |
                |          |/|          |
                |__________|/|__________|

                      overflow rect
                |<--------------------->|

                               content
                                 rect
                             |<-------->|
                    scroll
                    origin
                |----------->|
                 _________________________
                |            |          |/|
                |            |          |/|
                |            |          |/|
writing-mode:   |            |    box   |/|
  vertical-rl   |            |          |/|
                |            |          |/|
                |____________|__________|/|

                      overflow rect
                |<--------------------->|

Coordinate Spaces

Layout and Paint work with and frequently refer to three main coordinate spaces (really two, with one variant):

  • Physical coordinates: Corresponds to physical direction of the output per the physical display (screen, printed page). Generally used for painting, thus layout logic that feeds into paint may produce values in this space. CSS properties such as top, right, bottom, and left are in this space. See also the ‘flipped block-flow direction’ variant space below.

  • Logical coordinates: Used in layout to allow for generalized positioning that fits with whatever the writing-mode and direction CSS property values may be. Properties named with before, after, start or end are in this space. These are also known respectively as ‘logical top’, ‘logical bottom’, ‘logical left’, and ‘logical right’.

  • Physical coordinates with flipped block-flow direction: The same as ‘physical coordinates’, but for writing-mode: vertical-rl where blocks are laid out right-to-left, block position is “flipped” from the left to the right side of their containing block. This is essentially a mirror reflection horizontally across the center of a block's containing block.

    For writing-mode values other than vertical-rl there is no change from physical coordinates.

    Layout and paint logic reference this space to connote whether “flipping” has been applied to the values. Final painted output for “flipped block-flow” writing mode must, by definition, incorporate flipping. It can be expensive to look up the writing mode of an object. Performing computation on values known to be in this space can save on the overhead required to unflip/reflip.

Example with writing-mode: vertical-rl; direction: ltr:

                   'top' / 'start' side

                    block-flow direction
          <------------------------------------ |
          ------------------------------------- |
          |        c   |          s           | |
'left'    |        o   |          o           | |   inline     'right'
   /      |        n   |          m           | |  direction      /
'after'   |        t   |          e           | |              'before'
 side     |        e   |                      | |                side
          |        n   |                      | |
          |        t   |                      | |
          ------------------------------------- v

                'bottom' / 'end' side

Another example -- consider a relative-positioned element:

<style>
html {
    writing-mode: vertical-rl;
}
</style>
<div id="container" style="background-color: lightBlue; width: 300px; height: 200px;">
  <div id="relpos" style="position: relative; top: 50px; left: -60px; width: 70px; height: 80px; background-color: red;"></div>
</div>

The final location of these within an 800x600 frame is as:

container: (492, 8  300x200)
relpos:    (662, 58 70x80)

See the diagram for full detail on dimensions of the involved elements.

Determining the paint invalidation rect for relpos via mapToVisualRectInAncestorSpace() involves walking up the layout tree from relpos flipping the rect within its container at each box. Below we sketch each step as we recurse toward the top of the document, with ‘this’ on the left, the current rect being mapped on the right, and explanation beneath each:

LayoutBlockFlow (relative positioned) DIV id='relpos'   0,0    70x80

    Apply the relative position of 'relpos' while flipping within
    'container' to respect writing mode.

    170 = 300 (container width) - 70 (relpos width) - 60 (relpos left)
    50 = relpos top

LayoutBlockFlow DIV id='container'                      170,50 70x80

    Since body has the same width as container, flipping has
    no effect on the rect in this step.

LayoutBlockFlow BODY                                    170,50 70x80

    Flip within the html block, which is symmetrically 8px larger than body
    due to default margin.

LayoutBlockFlow HTML                                    178,58 70x80

    Flip the rectangle within the view.

    662 = 800 (view width) - 316 (html width) + 178 (current rect left)

LayoutView #document                                    662,58 70x80

Since relative-positioned elements are positioned via physical coordinates, and flipping at each step mirrors the position based on the width of the containing box at that step, we can only compute the final physical pixels in screen space for a relative-positioned element if we walk up the full layout tree from the starting object to the topmost view as described above.

For more examples of writing mode and direction combinations, see this demo page though note horizontal-bt is obsolete.

Flipped Block-Flow Coordinates

The nature of “flipping” a value as a mirror reflection within its containing block is such that flipping twice with the same container will produce the original result. Thus when working on involved logic it can be easy to accidentally flip unnecessarily, since flipping (say) one too many times can be “corrected” by flipping again. This can obviously lead to confusing and less performant code, so care should be taken to understand and document any changes to flipping logic.

Blink test coverage for features used in vertical writing modes, and vertical-rl in particular, may not be as comprehensive as for horizontal writing mode. Keep this in mind when writing new functionality or tests by making sure to incorporate coverage for all writing modes when appropriate.

Values are generally transformed into flipped block-flow coordinates via a set of methods on the involved layout objects. See in particular flipForWritingMode(), flipForWritingModeForChild().

InlineBox::flipForWritingMode() variants flip the input value within the inline box's containing block.

LayoutBox::flipForWritingMode() variants flip the input value within the referenced box.

LayoutBox::flipForWritingModeForChild() variants flip the input value within the referenced box, offsetting for the specified child box's current x-position and width. This is useful for a common pattern wherein we build up a point location starting with the current location of the (child) box.

For LayoutBox and InlineBox classes and subclasses:

  • physicalLocation() returns the physical location of a box or inline in the containing block. (0,0) is the top-left corner of the containing block. Flipping is performed on the values as needed. For LayoutBox, if the containing block is not passed to physicalLocation(), looking it up requires walking up the layout tree, which can be expensive. InlineBox::physicalLocation() is expensive only if the InlineBox is in flipped block-flow writing mode.
  • location() returns the location of a box or inline in the “physical coordinates with flipped block-flow direction” coordinate space. (0,0) is the top-left corner of the containing block for writing-mode in normal blocks direction (horizontal-tb and vertical-lr), and is the top-right corner of the containing block for writing-mode in flipped block-flow direction (vertical-rl).

Note there are two primary similar, but slightly different, methods regarding finding the containing block for an element:

  • LayoutObject::container() returns the containing block for an element as defined by CSS.
  • LayoutObject::containingBlock() which returns the enclosing non-anonymous block for an element. If the containing block is a relatively positioned inline, it returns that inline's enclosing non-anonymous block. This is the one used by physicalLocation().

There are other containing block methods in LayoutObject for special purposes such as fixed position, absolute position, and paint invalidation. Code will sometimes just refer to the ‘containing’ element, which is an unfortunately ambiguous term. Paying close attention to which method was used to obtain the containing element is important.

More complex web platform features such as tables, flexbox, and multicol are typically implemented atop these primitives, along with checks such as isFlippedBlocksWritingMode(), isLeftToRightDirection(), and isHorizontalWritingMode(). See for example LayoutTableSection::logicalRectForWritingModeAndDirection(), LayoutFlexibleBox::updateAutoMarginsInCrossAxis() or LayoutMultiColumnFlowThread::flowThreadTranslationAtPoint().

Geometry mapping

TODO(wkorman): Elaborate on:

  • mapToVisualRectInAncestorSpace()
  • mapAncestorToLocal()
  • Widget and FrameView trees. Note the former will be done away with at some point per http://crbug.com/637460.
  • GeometryMapper (or just point to its section in paint README). For now, see the Web page geometries design document.

Scrolling

TODO(wkorman): Provide an overview of scrolling. For now, the BlinkOn talk on Scrolling in Blink is a good overview.

Root layer scrolling is an ongoing refactoring of Blink's scrolling architecture, which makes the root PaintLayer responsible for the scrolling that was previously done by FrameView. For more details, see: Root Layer Scrolling.

Glossaries

Here we provide a brief overview of key terms relevant to box flow, inline flow, and text orientation. For more detail see CSS Writing Modes Level 3.

The CSS Logical Properties Level 1 specification represents the latest CSSWG thinking on logical coordinate space naming. CSSWG has standardized on block-start, block-end, inline-start, and inline-end, or just start and end when the axis is either implied or irrelevant.

Note that much of the Blink code base predates the logical properties specification and so does not yet reference logical direction consistently in the stated manner, though we would like to head in that direction over time. See also the physical, flow-relative, and line-relative abstract box terminology specification.

  • writing-mode: either horizontal or vertical, with vertical having either left-to-right or right-to-left block flow. Geometry is transposed for vertical writing mode. See calls to transposed{Rect,Point,Size}().
  • direction/dir: “inline base direction” of a box. One of ltr or rtl. See calls to isLeftToRightDirection().
  • text-orientation: orientation of text in a line. Only relevant for vertical modes.
  • orthogonal flow: when a box has a writing mode perpendicular to its containing block. This can lead to complex cases. See specification for more.