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


This directory contains 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.

Overflow and scrolling

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):

                |          |/|          |
                |          |/|          |
                |          |/|          |
direction:rtl   |          |/|   box    |
                |          |/|          |
                |          |/|          |

                      overflow rect

                |            |          |/|
                |            |          |/|
                |            |          |/|
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:

html {
    writing-mode: vertical-rl;
<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>

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(), and topLeftLocation().

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.

LayoutBox::topLeftLocation() performs flipping as needed. If the containing block is not passed to the method, looking it up requires walking up the layout tree, which can be expensive.

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 topLeftLocation().

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
  • GeometryMapper (or just point to its section in paint README). For now, see the Web page geometries design document.


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


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.