forked from mirrors/gecko-dev
Bug 1896210 Part 1 - Minor format tweak for LayoutOverview.md. r=layout-reviewers,emilio
Drop backslashes because escaping quote, double-quote, etc. is not needed in markdown. Indent fix for lists. Differential Revision: https://phabricator.services.mozilla.com/D210096
This commit is contained in:
parent
e270f922bd
commit
457d0008fc
1 changed files with 122 additions and 124 deletions
|
|
@ -1,3 +1,5 @@
|
|||
<!-- -*- mode: Markdown; fill-column: 72; -*- -->
|
||||
|
||||
# Layout Overview
|
||||
|
||||
Much of the layout code deals with operations on the frame tree (or
|
||||
|
|
@ -5,9 +7,9 @@ rendering tree). In the frame tree, each node represents a rectangle
|
|||
(or, for SVG, other shapes). The frame tree has a shape similar to the
|
||||
content tree, since many content nodes have one corresponding frame,
|
||||
though it differs in a few ways, since some content nodes have more than
|
||||
one frame or don\'t have any frames at all. When elements are
|
||||
one frame or don't have any frames at all. When elements are
|
||||
display:none in CSS or undisplayed for certain other reasons, they
|
||||
won\'t have any frames. When elements are broken across lines or pages,
|
||||
won't have any frames. When elements are broken across lines or pages,
|
||||
they have multiple frames; elements may also have multiple frames when
|
||||
multiple frames nested inside each other are needed to display a single
|
||||
element (for example, a table, a table cell, or many types of form
|
||||
|
|
@ -43,7 +45,7 @@ There were a number of cases where this rule was violated in the past
|
|||
and we stored important data in the frame tree; however, most (though
|
||||
not quite all) such cases are now fixed.
|
||||
|
||||
The rectangle represented by the frame is what CSS calls the element\'s
|
||||
The rectangle represented by the frame is what CSS calls the element's
|
||||
border box. This is the outside edge of the border (or the inside edge
|
||||
of the margin). The margin lives outside the border; and the padding
|
||||
lives inside the border. In addition to nsIFrame::GetRect, we also have
|
||||
|
|
@ -61,7 +63,7 @@ optimizations: it is a rectangle covering all of the area that might be
|
|||
painted when the frame and all of its descendants paint. The scrollable
|
||||
overflow represents the area that the user should be able to scroll to
|
||||
to see the frame and all of its descendants. In some cases differences
|
||||
between the frame\'s rect and its overflow happen because of descendants
|
||||
between the frame's rect and its overflow happen because of descendants
|
||||
that stick out of the frame; in other cases they occur because of some
|
||||
characteristic of the frame itself. The two overflow areas are similar,
|
||||
but there are differences: for example, margins are part of scrollable
|
||||
|
|
@ -86,7 +88,7 @@ the continuations of the span are siblings (since they are both children
|
|||
of the paragraph), but the continuations of the link are not siblings
|
||||
(since each continuation of the link is descended from a different
|
||||
continuation of the span). Traversing the entire frame tree does **not**
|
||||
require explicit traversal of any frames\' continuations-list, since all
|
||||
require explicit traversal of any frames' continuations-list, since all
|
||||
of the continuations are descendants of the element containing the
|
||||
break.
|
||||
|
||||
|
|
@ -99,11 +101,11 @@ nsIFrame::GetNextInFlow and nsIFrame::GetPrevInFlow traverse only the
|
|||
fluid continuations and do not cross fixed continuation boundaries.
|
||||
|
||||
If an inline frame has non-inline children, then we split the original
|
||||
inline frame into parts. The original inline\'s children are distributed
|
||||
inline frame into parts. The original inline's children are distributed
|
||||
into these parts like so: The children of the original inline are
|
||||
grouped into runs of inline and non-inline, and runs of inline get an
|
||||
inline parent, while runs of non-inline get an anonymous block parent.
|
||||
We call this \'ib-splitting\' or \'block-inside-inline splitting\'. This
|
||||
We call this "ib-splitting" or "block-inside-inline splitting." This
|
||||
splitting proceeds recursively up the frame tree until all non-inlines
|
||||
inside inlines are ancestors of a block frame with anonymous block
|
||||
wrappers in between. This splitting maintains the relative order between
|
||||
|
|
@ -125,46 +127,44 @@ TODO: link to documentation of XUL frame classes
|
|||
Code (note that most files in base and generic have useful one line
|
||||
descriptions at the top that show up in DXR):
|
||||
|
||||
- [layout/base/](http://dxr.mozilla.org/mozilla-central/source/layout/base/)
|
||||
contains objects that coordinate everything and a bunch of other
|
||||
miscellaneous things
|
||||
- [layout/generic/](http://dxr.mozilla.org/mozilla-central/source/layout/generic/)
|
||||
contains the basic frame classes as well as support code for their
|
||||
reflow methods (ReflowInput, ReflowOutput)
|
||||
- [layout/forms/](http://dxr.mozilla.org/mozilla-central/source/layout/forms/)
|
||||
contains frame classes for HTML form controls
|
||||
- [layout/tables/](http://dxr.mozilla.org/mozilla-central/source/layout/tables/)
|
||||
contains frame classes for CSS/HTML tables
|
||||
- [layout/mathml/](http://dxr.mozilla.org/mozilla-central/source/layout/mathml/)
|
||||
contains frame classes for MathML
|
||||
- [layout/svg/](http://dxr.mozilla.org/mozilla-central/source/layout/svg/)
|
||||
contains frame classes for SVG
|
||||
- [layout/xul/](http://dxr.mozilla.org/mozilla-central/source/layout/xul/)
|
||||
contains frame classes for the XUL box model and for various XUL
|
||||
widgets
|
||||
- [layout/base/](http://dxr.mozilla.org/mozilla-central/source/layout/base/)
|
||||
contains objects that coordinate everything and a bunch of other
|
||||
miscellaneous things
|
||||
- [layout/generic/](http://dxr.mozilla.org/mozilla-central/source/layout/generic/)
|
||||
contains the basic frame classes as well as support code for their
|
||||
reflow methods (ReflowInput, ReflowOutput)
|
||||
- [layout/forms/](http://dxr.mozilla.org/mozilla-central/source/layout/forms/)
|
||||
contains frame classes for HTML form controls
|
||||
- [layout/tables/](http://dxr.mozilla.org/mozilla-central/source/layout/tables/)
|
||||
contains frame classes for CSS/HTML tables
|
||||
- [layout/mathml/](http://dxr.mozilla.org/mozilla-central/source/layout/mathml/)
|
||||
contains frame classes for MathML
|
||||
- [layout/svg/](http://dxr.mozilla.org/mozilla-central/source/layout/svg/)
|
||||
contains frame classes for SVG
|
||||
- [layout/xul/](http://dxr.mozilla.org/mozilla-central/source/layout/xul/)
|
||||
contains frame classes for the XUL box model and for various XUL
|
||||
widgets
|
||||
|
||||
Bugzilla:
|
||||
|
||||
- All of the components whose names begin with \"Layout\" in the
|
||||
\"Core\" product
|
||||
Bugzilla: all of the components whose names begin with "Layout" in the
|
||||
"Core" product.
|
||||
|
||||
Further documentation:
|
||||
|
||||
- Talk: [Introduction to graphics/layout
|
||||
architecture](https://air.mozilla.org/introduction-to-graphics-layout-architecture/)
|
||||
(Robert O\'Callahan, 2014-04-18)
|
||||
- Talk: [Layout and
|
||||
Styles](https://air.mozilla.org/bz-layout-and-styles/) (Boris
|
||||
Zbarsky, 2014-10-14)
|
||||
- Talk: [Introduction to graphics/layout
|
||||
architecture](https://air.mozilla.org/introduction-to-graphics-layout-architecture/)
|
||||
(Robert O'Callahan, 2014-04-18)
|
||||
- Talk: [Layout and
|
||||
Styles](https://air.mozilla.org/bz-layout-and-styles/) (Boris
|
||||
Zbarsky, 2014-10-14)
|
||||
|
||||
## Frame Construction
|
||||
|
||||
Frame construction is the process of creating frames. This is done when
|
||||
styles change in ways that require frames to be created or recreated or
|
||||
when nodes are inserted into the document. The content tree and the
|
||||
frame tree don\'t have quite the same shape, and the frame construction
|
||||
frame tree don't have quite the same shape, and the frame construction
|
||||
process does some of the work of creating the right shape for the frame
|
||||
tree. It handles the aspects of creating the right shape that don\'t
|
||||
tree. It handles the aspects of creating the right shape that don't
|
||||
depend on layout information. So for example, frame construction handles
|
||||
the work needed to implement [table anonymous
|
||||
objects](http://www.w3.org/TR/CSS21/tables.html#anonymous-boxes) but
|
||||
|
|
@ -189,27 +189,26 @@ frame constructor either fixes up the list of frame construction items
|
|||
so that the resulting frame tree would be valid or throws away the list
|
||||
of frame construction items and requests the destruction and re-creation
|
||||
of the frame for the parent element so that it has a chance to create a
|
||||
list of frame construction items that it `<em>`{=html}can`</em>`{=html}
|
||||
fix up.
|
||||
list of frame construction items that it _can_ fix up.
|
||||
|
||||
Once the frame constructor has a list of frame construction items and an
|
||||
insertion point that would lead to a valid frame tree, it goes ahead and
|
||||
creates frames based on those items. Creation of a non-leaf frame
|
||||
recursively attempts to create frames for the children of that frame\'s
|
||||
recursively attempts to create frames for the children of that frame's
|
||||
element, so in effect frames are created in a depth-first traversal of
|
||||
the content tree.
|
||||
|
||||
The vast majority of the code in the frame constructor, therefore, falls
|
||||
into one of these categories:
|
||||
|
||||
- Code to determine the correct insertion point in the frame tree for
|
||||
new frames.
|
||||
- Code to create, for a given content node, frame construction items.
|
||||
This involves some searches through static data tables for metadata
|
||||
about the frame to be created.
|
||||
- Code to analyze the list of frame construction items.
|
||||
- Code to fix up the list of frame construction items.
|
||||
- Code to create frames from frame construction items.
|
||||
- Code to determine the correct insertion point in the frame tree for
|
||||
new frames.
|
||||
- Code to create, for a given content node, frame construction items.
|
||||
This involves some searches through static data tables for metadata
|
||||
about the frame to be created.
|
||||
- Code to analyze the list of frame construction items.
|
||||
- Code to fix up the list of frame construction items.
|
||||
- Code to create frames from frame construction items.
|
||||
|
||||
Code:
|
||||
[layout/base/nsCSSFrameConstructor.h](http://dxr.mozilla.org/mozilla-central/source/layout/base/nsCSSFrameConstructor.h)
|
||||
|
|
@ -226,8 +225,8 @@ types.
|
|||
|
||||
Reflow is the process of computing the positions and sizes of frames.
|
||||
(After all, frames represent rectangles, and at some point we need to
|
||||
figure out exactly \*what\* rectangle.) Reflow is done recursively, with
|
||||
each frame\'s Reflow method calling the Reflow methods on that frame\'s
|
||||
figure out exactly **what** rectangle.) Reflow is done recursively, with
|
||||
each frame's Reflow method calling the Reflow methods on that frame's
|
||||
descendants.
|
||||
|
||||
In many cases, the correct results are defined by CSS specifications
|
||||
|
|
@ -241,12 +240,12 @@ written in terms of constraints, whereas our layout code consists of
|
|||
algorithms optimized for incremental recomputation.
|
||||
|
||||
The reflow generally starts from the root of the frame tree, though some
|
||||
other types of frame can act as \"reflow roots\" and start a reflow from
|
||||
other types of frame can act as "reflow roots" and start a reflow from
|
||||
them (nsTextControlFrame is one example; see the
|
||||
[NS\_FRAME\_REFLOW\_ROOT](https://searchfox.org/mozilla-central/search?q=symbol:E_%3CT_nsFrameState%3E_NS_FRAME_REFLOW_ROOT&redirect=true)
|
||||
[NS_FRAME_REFLOW_ROOT](https://searchfox.org/mozilla-central/search?q=symbol:E_%3CT_nsFrameState%3E_NS_FRAME_REFLOW_ROOT&redirect=true)
|
||||
frame state bit). Reflow roots must obey the invariant that a change
|
||||
inside one of their descendants never changes their rect or overflow
|
||||
areas (though currently scrollbars are reflow roots but don\'t quite
|
||||
areas (though currently scrollbars are reflow roots but don't quite
|
||||
obey this invariant).
|
||||
|
||||
In many cases, we want to reflow a part of the frame tree, and we want
|
||||
|
|
@ -256,12 +255,12 @@ of work we need to redo to be proportional to the amount of content. We
|
|||
also want to efficiently handle a series of changes to the same content.
|
||||
|
||||
To do this, we maintain two bits on frames:
|
||||
[NS\_FRAME\_IS\_DIRTY](https://searchfox.org/mozilla-central/search?q=symbol:E_%3CT_nsFrameState%3E_NS_FRAME_IS_DIRTY&redirect=true)
|
||||
[NS_FRAME_IS_DIRTY](https://searchfox.org/mozilla-central/search?q=symbol:E_%3CT_nsFrameState%3E_NS_FRAME_IS_DIRTY&redirect=true)
|
||||
indicates that a frame and all of its descendants require reflow.
|
||||
[NS\_FRAME\_HAS\_DIRTY\_CHILDREN](https://searchfox.org/mozilla-central/search?q=symbol:E_%3CT_nsFrameState%3E_NS_FRAME_HAS_DIRTY_CHILDREN&redirect=true)
|
||||
[NS_FRAME_HAS_DIRTY_CHILDREN](https://searchfox.org/mozilla-central/search?q=symbol:E_%3CT_nsFrameState%3E_NS_FRAME_HAS_DIRTY_CHILDREN&redirect=true)
|
||||
indicates that a frame has a descendant that is dirty or has had a
|
||||
descendant removed (i.e., that it has a child that has
|
||||
NS\_FRAME\_IS\_DIRTY or NS\_FRAME\_HAS\_DIRTY\_CHILDREN or it had a
|
||||
NS_FRAME_IS_DIRTY or NS_FRAME_HAS_DIRTY_CHILDREN or it had a
|
||||
child removed). These bits allow coalescing of multiple updates; this
|
||||
coalescing is done in PresShell, which tracks the set of reflow roots
|
||||
that require reflow. The bits are set during calls to
|
||||
|
|
@ -288,13 +287,13 @@ Intrinsic widths are invalidated separately from the dirty bits
|
|||
described above. When a caller informs the pres shell that a frame needs
|
||||
reflow (PresShell::FrameNeedsReflow), it passes one of three options:
|
||||
|
||||
- eResize indicates that no intrinsic widths are dirty
|
||||
- eTreeChange indicates that intrinsic widths on it and its ancestors
|
||||
are dirty (which happens, for example, if new children are added to
|
||||
it)
|
||||
- eStyleChange indicates that intrinsic widths on it, its ancestors,
|
||||
and its descendants are dirty (for example, if the font-size
|
||||
changes)
|
||||
- eResize indicates that no intrinsic widths are dirty
|
||||
- eTreeChange indicates that intrinsic widths on it and its ancestors
|
||||
are dirty (which happens, for example, if new children are added to
|
||||
it)
|
||||
- eStyleChange indicates that intrinsic widths on it, its ancestors,
|
||||
and its descendants are dirty (for example, if the font-size
|
||||
changes)
|
||||
|
||||
Reflow is the area where the XUL frame classes (those that inherit from
|
||||
nsBoxFrame or nsLeafBoxFrame) are most different from the rest. Instead
|
||||
|
|
@ -304,13 +303,13 @@ intrinsic size methods called GetMinSize, GetPrefSize, and GetMaxSize
|
|||
method called Layout. In many cases these methods defer some of the
|
||||
computation to a separate object called a layout manager.
|
||||
|
||||
When an individual frame\'s Reflow method is called, most of the input
|
||||
When an individual frame's Reflow method is called, most of the input
|
||||
is provided on an object called ReflowInput and the output is filled in
|
||||
to an object called ReflowOutput. After reflow, the caller (usually the
|
||||
parent) is responsible for setting the frame\'s size based on the
|
||||
parent) is responsible for setting the frame's size based on the
|
||||
metrics reported. (This can make some computations during reflow
|
||||
difficult, since the new size is found in either the reflow state or the
|
||||
metrics, but the frame\'s size is still the old size. However, it\'s
|
||||
metrics, but the frame's size is still the old size. However, it's
|
||||
useful for invalidating the correct areas that need to be repainted.)
|
||||
|
||||
One major difference worth noting is that in XUL layout, the size of the
|
||||
|
|
@ -333,7 +332,7 @@ print-preview, and multicolumn layout.
|
|||
|
||||
To render a DOM node, represented as `nsIContent` object, Gecko creates
|
||||
zero or more frames (`nsIFrame` objects). Each frame represents a
|
||||
rectangular area usually corresponding to the node\'s CSS box as
|
||||
rectangular area usually corresponding to the node's CSS box as
|
||||
described by the CSS specs. Simple elements are often representable with
|
||||
exactly one frame, but sometimes an element needs to be represented with
|
||||
more than one frame. For example, text breaking across lines:
|
||||
|
|
@ -342,7 +341,7 @@ more than one frame. For example, text breaking across lines:
|
|||
AAA xxxxxxx
|
||||
|
||||
The A element is a single DOM node but obviously a single rectangular
|
||||
frame isn\'t going to represent its layout precisely.
|
||||
frame isn't going to represent its layout precisely.
|
||||
|
||||
Similarly, consider text breaking across pages:
|
||||
|
||||
|
|
@ -372,9 +371,9 @@ fully laid out within the constraints assigned (e.g., when inline text
|
|||
will not fit within a particular width constraint, or when a block
|
||||
cannot be laid out within a particular height constraint).
|
||||
|
||||
Continuation frames created during reflow are called \"fluid\"
|
||||
continuations (or \"in-flows\"). Other continuation frames (currently,
|
||||
those created during bidi resolution), are, in contrast, \"non-fluid\".
|
||||
Continuation frames created during reflow are called "fluid"
|
||||
continuations (or "in-flows"). Other continuation frames (currently,
|
||||
those created during bidi resolution), are, in contrast, "non-fluid".
|
||||
The `NS_FRAME_IS_FLUID_CONTINUATION` state bit indicates whether a
|
||||
continuation frame is fluid or not.
|
||||
|
||||
|
|
@ -400,32 +399,32 @@ breaking and continuations:
|
|||
Certain kinds of frames create multiple child frames for the same
|
||||
content element:
|
||||
|
||||
- `nsPageSequenceFrame` creates multiple page children, each one
|
||||
associated with the entire document, separated by page breaks
|
||||
- `nsColumnSetFrame` creates multiple block children, each one
|
||||
associated with the column element, separated by column breaks
|
||||
- `nsBlockFrame` creates multiple inline children, each one associated
|
||||
with the same inline element, separated by line breaks, or by
|
||||
changes in text direction
|
||||
- `nsTableColFrame` creates non-fluid continuations for itself if it
|
||||
has span=\"N\" and N \> 1
|
||||
- If a block frame is a multi-column container and has
|
||||
`column-span:all` children, it creates multiple `nsColumnSetFrame`
|
||||
children, which are linked together as non-fluid continuations.
|
||||
Similarly, if a block frame is within a multi-column formatting
|
||||
context and has `column-span:all` children, it is chopped into
|
||||
several flows, which are linked together as non-fluid continuations
|
||||
as well. See documentation and example frame trees in
|
||||
[`nsCSSFrameConstructor::ConstructBlock()`](https://searchfox.org/mozilla-central/rev/d24696b5abaf9fb75f7985952eab50d5f4ed52ac/layout/base/nsCSSFrameConstructor.cpp#10431).
|
||||
- `nsPageSequenceFrame` creates multiple page children, each one
|
||||
associated with the entire document, separated by page breaks
|
||||
- `nsColumnSetFrame` creates multiple block children, each one
|
||||
associated with the column element, separated by column breaks
|
||||
- `nsBlockFrame` creates multiple inline children, each one associated
|
||||
with the same inline element, separated by line breaks, or by
|
||||
changes in text direction
|
||||
- `nsTableColFrame` creates non-fluid continuations for itself if it
|
||||
has span="N" and N > 1
|
||||
- If a block frame is a multi-column container and has
|
||||
`column-span:all` children, it creates multiple `nsColumnSetFrame`
|
||||
children, which are linked together as non-fluid continuations.
|
||||
Similarly, if a block frame is within a multi-column formatting
|
||||
context and has `column-span:all` children, it is chopped into
|
||||
several flows, which are linked together as non-fluid continuations
|
||||
as well. See documentation and example frame trees in
|
||||
[`nsCSSFrameConstructor::ConstructBlock()`](https://searchfox.org/mozilla-central/rev/d24696b5abaf9fb75f7985952eab50d5f4ed52ac/layout/base/nsCSSFrameConstructor.cpp#10431).
|
||||
|
||||
#### Overflow Container Continuations
|
||||
|
||||
Sometimes the content of a frame needs to break across pages even though
|
||||
the frame itself is complete. This usually happens if an element with
|
||||
fixed height has overflow that doesn\'t fit on one page. In this case,
|
||||
the completed frame is \"overflow incomplete\", and special
|
||||
fixed height has overflow that doesn't fit on one page. In this case,
|
||||
the completed frame is "overflow incomplete", and special
|
||||
continuations are created to hold its overflow. These continuations are
|
||||
called \"overflow containers\". They are invisible, and are kept on a
|
||||
called "overflow containers". They are invisible, and are kept on a
|
||||
special list in their parent. See documentation in
|
||||
[nsContainerFrame.h](https://searchfox.org/mozilla-central/source/layout/generic/nsContainerFrame.h)
|
||||
and example trees in [bug 379349 comment
|
||||
|
|
@ -447,26 +446,26 @@ to traverse next-continuation links. All continuations are reachable by
|
|||
traversing the `GetNextSibling` links from the result of `GetFirstChild`
|
||||
for all child lists.
|
||||
|
||||
Second, the following property holds:
|
||||
|
||||
- Consider two frames F1 and F2 where F1\'s next-continuation is F2
|
||||
and their respective parent frames are P1 and P2. Then either P1\'s
|
||||
next continuation is P2, or P1 == P2, because P is responsible for
|
||||
breaking F1 and F2.
|
||||
Second, the following property holds: consider two frames F1 and F2
|
||||
where F1's next-continuation is F2 and their respective parent frames
|
||||
are P1 and P2. Then either P1's next continuation is P2, or P1 == P2,
|
||||
because P is responsible for breaking F1 and F2.
|
||||
|
||||
In other words, continuations are sometimes siblings of each other, and
|
||||
sometimes not. If their parent content was broken at the same point,
|
||||
then they are not siblings, since they are children of different
|
||||
continuations of the parent. So in the frame tree for the markup
|
||||
|
||||
` <p>This is <b><i>some <br/>text</i></b>.</p>`
|
||||
```html
|
||||
<p>This is <b><i>some<br/>text</i></b>.</p>
|
||||
```
|
||||
|
||||
the two continuations for the `b` element are siblings (unless the line
|
||||
break is also a page break), but the two continuations for the `i`
|
||||
element are not.
|
||||
|
||||
There is an exception to that property when F1 is a first-in-flow float
|
||||
placeholder. In that case F2\'s parent will be the next-in-flow of F1\'s
|
||||
placeholder. In that case F2's parent will be the next-in-flow of F1's
|
||||
containing block.
|
||||
|
||||
### Reflow statuses
|
||||
|
|
@ -474,33 +473,33 @@ containing block.
|
|||
The aStatus argument of Reflow reflects that. `IsComplete()` means that
|
||||
we reflowed all the content and no more next-in-flows are needed. At
|
||||
that point there may still be next in flows, but the parent will delete
|
||||
them. `IsIncomplete()` means \"some content did not fit in this frame\".
|
||||
them. `IsIncomplete()` means "some content did not fit in this frame".
|
||||
`IsOverflowIncomplete()` means that the frame is itself complete, but
|
||||
some of its content didn\'t fit: this triggers the creation of overflow
|
||||
containers for the frame\'s continuations. `IsIncomplete()` and
|
||||
`NextInFlowNeedsReflow()` means \"some content did not fit in this frame
|
||||
AND it must be reflowed\". These values are defined and documented in
|
||||
some of its content didn't fit: this triggers the creation of overflow
|
||||
containers for the frame's continuations. `IsIncomplete()` and
|
||||
`NextInFlowNeedsReflow()` means "some content did not fit in this frame
|
||||
AND it must be reflowed". These values are defined and documented in
|
||||
[nsIFrame.h](https://searchfox.org/mozilla-central/source/layout/generic/nsIFrame.h)
|
||||
(search for \"Reflow status\").
|
||||
(search for "Reflow status").
|
||||
|
||||
### Dynamic Reflow Considerations
|
||||
|
||||
When we reflow a frame F with fluid continuations, two things can
|
||||
happen:
|
||||
|
||||
- Some child frames do not fit in the passed-in width or height
|
||||
constraint. These frames must be \"pushed\" to F\'s next-in-flow. If
|
||||
F has no next-in-flow, we must create one under F\'s parent\'s
|
||||
next-in-flow \-\-- or if F\'s parent is managing the breaking of F,
|
||||
then we create F\'s next in flow directly under F\'s parent. If F is
|
||||
a block, it pushes overflowing child frames to its \"overflow\"
|
||||
child list and forces F\'s next in flow to be reflowed. When we
|
||||
reflow a block, we pull the child frames from the prev-in-flow\'s
|
||||
overflow list into the current frame.
|
||||
- All child frames fit in the passed-in width or height constraint.
|
||||
Then child frames must be \"pulled\" from F\'s next-in-flow to fill
|
||||
in the available space. If F\'s next-in-flow becomes empty, we may
|
||||
be able to delete it.
|
||||
- Some child frames do not fit in the passed-in width or height
|
||||
constraint. These frames must be "pushed" to F's next-in-flow. If
|
||||
F has no next-in-flow, we must create one under F's parent's
|
||||
next-in-flow --- or if F's parent is managing the breaking of F,
|
||||
then we create F's next in flow directly under F's parent. If F is
|
||||
a block, it pushes overflowing child frames to its "overflow"
|
||||
child list and forces F's next in flow to be reflowed. When we
|
||||
reflow a block, we pull the child frames from the prev-in-flow's
|
||||
overflow list into the current frame.
|
||||
- All child frames fit in the passed-in width or height constraint.
|
||||
Then child frames must be "pulled" from F's next-in-flow to fill
|
||||
in the available space. If F's next-in-flow becomes empty, we may
|
||||
be able to delete it.
|
||||
|
||||
In both of these situations we might end up with a frame F containing
|
||||
two child frames, one of which is a continuation of the other. This is
|
||||
|
|
@ -510,17 +509,16 @@ P3, P1 has child F1 and P3 has child F2, but P2 has no F child.
|
|||
A strategy for avoiding these issues is this: When pulling a frame F2
|
||||
from parent P2 to prev-in-flow P1, if F2 is a breakable container, then:
|
||||
|
||||
- If F2 has no prev-in-flow F1 in P1, then create a new primary frame
|
||||
F1 in P1 for F2\'s content, with F2 as its next-in-flow.
|
||||
- Pull children from F2 to F1 until F2 is empty or we run out of
|
||||
space. If F2 goes empty, pull from the next non-empty next-in-flow.
|
||||
Empty continuations with no next-in-flows can be deleted.
|
||||
- If F2 has no prev-in-flow F1 in P1, then create a new primary frame F1
|
||||
in P1 for F2's content, with F2 as its next-in-flow.
|
||||
- Pull children from F2 to F1 until F2 is empty or we run out of space.
|
||||
If F2 goes empty, pull from the next non-empty next-in-flow. Empty
|
||||
continuations with no next-in-flows can be deleted.
|
||||
|
||||
When pushing a frame F1 from parent P1 to P2, where F1 has a
|
||||
next-in-flow F2 (which must be a child of P2):
|
||||
|
||||
- Merge F2 into F1 by moving all F2\'s children into F1, then deleting
|
||||
F2
|
||||
- Merge F2 into F1 by moving all F2's children into F1, then deleting F2
|
||||
|
||||
For inline frames F, we have our own custom strategy that coalesces
|
||||
adjacent inline frames. This need not change.
|
||||
|
|
|
|||
Loading…
Reference in a new issue