Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Unified Diff: third_party/WebKit/Source/core/layout/README.md

Issue 2380933004: Update layout documentation re: coordinate systems and writing mode. (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/layout/README.md
diff --git a/third_party/WebKit/Source/core/layout/README.md b/third_party/WebKit/Source/core/layout/README.md
index d6943942bb6bd9194587592f22f1a3c75677c466..af4bdb94c74e43991369e21788fdba7fb14eb27f 100644
--- a/third_party/WebKit/Source/core/layout/README.md
+++ b/third_party/WebKit/Source/core/layout/README.md
@@ -1,10 +1,21 @@
# `Source/core/layout`
+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](https://docs.google.com/document/d/1uxbDh4uONFQOiGuiumlJBLGgO4KDWB8ZEkp7Rd47fw4/preview).
+
## Overflow rects and scroll offsets
PaintLayerScrollableArea uses a "scroll origin" to conceptually represent the distance between
the top-left corner of the box'es content rect and the top-left corner of its overflow rect
-when the box is scrolled to the logical beginning of its content (.e.g. all the way to the left for
+when the box is scrolled to the logical beginning of its content (e.g. all the way to the left for
LTR, all the way to the right for RTL). For left-to-right and top-to-bottom flows, the scroll
origin is zero, i.e., the top/left of the overflow rect is at the same position as the top/left of
the box'es content rect when scrolled to the beginning of flow. For right-to-left and bottom-to-top
@@ -14,70 +25,226 @@ The default calculation for scroll origin is the distance between the top-left c
rect and the top-left corner of the overflow rect. To illustrate, here is a box with left overflow and
no vertical scrollbar:
- content
- rect
- |<-------->|
- scroll
- origin
- |<-------->|
- _____________________
- | | |
- | | |
- | | |
-direction:rtl | | box |
- | | |
- | | |
- |__________|__________|
-
- overflow rect
- |<--------------------->|
+ content
+ rect
+ |<-------->|
+ scroll
+ origin
+ |<-------->|
+ _____________________
+ | | |
+ | | |
+ | | |
+ direction:rtl | | box |
+ | | |
+ | | |
+ |__________|__________|
+
+ overflow rect
+ |<--------------------->|
However, if the box 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
- |<---------->|
+the right or left of the box (the vertical scrollbar is the `|/|` part):
+
+ content
+ rect
+ |<-------->|
+ scroll
+ origin
+ |<---------->|
_______________________
- | | |/|
- | | |/|
- | | |/|
-writing-mode: | | |/|
- vertical-rl | | |/|
- | | |/|
- | | |/|
- | | |/|
- |__________|__________|/|
-
+ | |/| |
+ | |/| |
+ | |/| |
+ direction:rtl | |/| box |
+ | |/| |
+ | |/| |
+ |__________|/|__________|
+
overflow rect
|<--------------------->|
+ content
+ rect
+ |<-------->|
+ scroll
+ origin
+ |<---------->|
+ _______________________
+ | | |/|
+ | | |/|
+ | | |/|
+ writing-mode: | | |/|
+ vertical-rl | | |/|
+ | | |/|
+ | | |/|
+ | | |/|
+ |__________|__________|/|
+
+ overflow rect
+ |<--------------------->|
+
## Coordinate Spaces
-TODO(wkorman): Document writing mode, particularly flipped blocks.
+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
+
+See also this [demo page](http://pauljadam.com/demos/csstext.html) 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 http://crbug.com/637460.
+* `GeometryMapper` (or just point to its section in paint README). For now, see
+ the
+ [Web page geometries](https://docs.google.com/document/d/1WZKlOSUK4XI0Le0fgCsyUTVw0dTwutZXGWwzlHXewiU/preview)
+ design document.
+
+## Scrolling
+
+TODO(wkorman): Provide an overview of scrolling. For now, the BlinkOn talk
+on
+[Scrolling in Blink](https://docs.google.com/presentation/d/1pwx0qBW4wSmYAOJxq2gb3SMvSTCHz2L2TFx_bjsvm8E/preview)
+is a good overview.
+
+## 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](https://www.w3.org/TR/css-writing-modes-3/).
+
+The
+[CSS Logical Properties Level 1](https://drafts.csswg.org/css-logical-props/)
+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](https://www.w3.org/TR/css-writing-modes-3/#abstract-box)
+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](https://www.w3.org/TR/css-writing-modes-3/#orthogonal-flows)
+ for more.

Powered by Google App Engine
This is Rietveld 408576698