mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
updated document regardling block and line-layout operation; this is html documents that are not part of the build nor part of any install process, etc.
This commit is contained in:
parent
0ac3221281
commit
af2ba3fbb6
@ -2,134 +2,203 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="GENERATOR" content="Mozilla/4.51 [en] (X11; U; Linux 2.0.36 i686) [Netscape]">
|
||||
<meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; Linux 2.2.5-22 i686) [Netscape]">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<table CELLSPACING=0 CELLPADDING=0 COLS=1 WIDTH="100%" BGCOLOR="#33CCFF" NOSAVE >
|
||||
<tr>
|
||||
<td><font size=+3>Block Layout</font></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>This document attempts to describe how "block" layout works in the mozilla
|
||||
<h1>
|
||||
<u>Block Layout</u></h1>
|
||||
This document attempts to describe how "block" layout works in the mozilla
|
||||
layout engine.
|
||||
<p><tt>nsBlockFrame</tt> implements layout behavior that conforms to the
|
||||
CSS "block" display property. The primary responsibility of the block code
|
||||
is to manage "line layout". Line layout is the process where inline elements
|
||||
are placed on a "line" hozironatally (left to right or right to left if
|
||||
the CSS direction property is set rtl). In addition to line layout, blocks
|
||||
are responsible for placement of left and right floating elements, and
|
||||
handling "clear" semantics of child blocks or BR elements.
|
||||
<p>To manage the child frames, nsBlockFrame uses a singly linked list of
|
||||
nsLineBox's. nsLineBox's contain enough state to find all of the children
|
||||
that belong to the block, plus support incremental reflow [Currently there
|
||||
is too much state here - we waste memory].
|
||||
<br>
|
||||
<br>
|
||||
<table CELLSPACING=0 CELLPADDING=0 COLS=1 WIDTH="100%" BGCOLOR="#33CCFF" NOSAVE >
|
||||
<tr>
|
||||
<td><font size=+2>Who's Who</font></td>
|
||||
</tr>
|
||||
</table>
|
||||
CSS "display:block" and "display: list-item" layout. It has several responsibilities:
|
||||
<ol>
|
||||
<li>
|
||||
Line layout. The block is responsible for flowing inline elements
|
||||
into "lines" and applying all of the css behavior as one might expect,
|
||||
including line-height, vertical-align, relative positioning, etc.</li>
|
||||
|
||||
<li>
|
||||
Floater management. The block is responsible for the reflow and placement
|
||||
of floating elements.</li>
|
||||
|
||||
<li>
|
||||
Child block management. Blocks can contain inline elements and block elements.
|
||||
Hence, blocks are responsible for reflowing child blocks. The majority
|
||||
of that logic has been split out into nsBlockReflowContext, but a fair
|
||||
amount remains here.</li>
|
||||
|
||||
<li>
|
||||
Supporting table reflow. The block has to carefully compute the "max-element-size"
|
||||
information needed by tables. Hence, any time changes are made here one
|
||||
should always run the table regression tests because the odds are you broke
|
||||
one of them!</li>
|
||||
</ol>
|
||||
|
||||
<h3>
|
||||
<u>The Big Picture for Block Reflow</u></h3>
|
||||
The block frame uses a list of nsLineBox's to keep track of each "line"
|
||||
of frames it manages. There are two types of lines:
|
||||
<blockquote>"inline" lines which contain only inline elements
|
||||
<br>"block" lines which contain exactly one block element</blockquote>
|
||||
Each line has a "dirty" bit which indicates that it needs reflow. Reflow
|
||||
consists of identifying which lines need to be marked dirty and then reflowing
|
||||
all lines. For lines which are "clean" the reflow logic will endeavor to
|
||||
recover the state of reflow <i>as if the line had been reflowed</i>. This
|
||||
saves time and allows for a faster incremental reflow. For lines which
|
||||
are dirty, the line is reflowed appropriately.
|
||||
<p>The only special thing about incremental reflow command handling is
|
||||
that it marks lines dirty before proceeding, and keeps track of the child
|
||||
frame that is the next frame on the reflow command path.
|
||||
<p>Here is a list of the various classes involved in block layout:
|
||||
<p><b>nsBlockFrame</b>
|
||||
<p>The primary culprit.
|
||||
<p><b>nsBlockReflowState</b>
|
||||
<p>This helper class is used to augment the nsHTMLReflowState with other
|
||||
information needed by the block reflow logic during reflow. It is a temporary
|
||||
object that is designed to live on the processor stack.
|
||||
<p><b>nsBlockBandData</b>
|
||||
<p>Another helper class that wraps up management of a space manager (nsISpaceManager,
|
||||
nsSpaceManager) and nsBandData. It also assits in management of floating
|
||||
elements. While nsSpaceManager is policy free, nsBlockBandData provides
|
||||
specific HTML and CSS policy.
|
||||
<p><b>nsBlockReflowContext</b>
|
||||
<p>A helper class that encapsulates the logic needed to reflow a child
|
||||
block frame. This is used by the block code reflow a child block, as well
|
||||
as by the inline frame code to reflow an anonymous block, and by the block
|
||||
code to reflow floating elements (which are to be treated as blocks according
|
||||
to the CSS2 spec).
|
||||
<p><b>nsLineBox</b>
|
||||
<p>A data class used to store line information for the block frame code.
|
||||
Each line has a list of children (though the frames are linked together
|
||||
<blockquote>The primary culprit.</blockquote>
|
||||
<b>nsBlockReflowState</b>
|
||||
<blockquote>This helper class is used to augment the nsHTMLReflowState
|
||||
with other information needed by the block reflow logic during reflow.
|
||||
It is a temporary object that is designed to live on the processor stack
|
||||
and contains "running" state used by the blocks reflow logic.</blockquote>
|
||||
<b>nsBlockBandData</b>
|
||||
<blockquote>Another helper class that wraps up management of a space manager
|
||||
(nsISpaceManager, nsSpaceManager) and nsBandData. It also assists in management
|
||||
of floating elements. While nsSpaceManager is policy free, nsBlockBandData
|
||||
provides specific HTML and CSS policy.</blockquote>
|
||||
<b>nsBlockReflowContext</b>
|
||||
<blockquote>A helper class that encapsulates the logic needed to reflow
|
||||
a child block frame. This is used by the block code reflow a child block
|
||||
and to reflow floating elements (which are to be treated as blocks according
|
||||
to the CSS2 spec).</blockquote>
|
||||
<b>nsLineBox</b>
|
||||
<blockquote>A data class used to store line information for the block frame
|
||||
code. Each line has a list of children (though the frames are linked together
|
||||
across lines to maintain the sibling list for nsIFrame::FirstChild) and
|
||||
some other state used to assit in incremental reflow.
|
||||
<p><b>nsLineLayout</b>
|
||||
<p>This class is the line layout engine. Its a passive entity in the sense
|
||||
that its the responsibility of the block/inline code to use the class (this
|
||||
is done so that the line layout engine doesn't have to manage child frame
|
||||
lists so that both nsBlockFrame and nsInlineFrame can use the class).
|
||||
<p><b>nsTextRun</b>
|
||||
<p>This is a data class used to store text run information. Tex turns are
|
||||
logically contiguous runs of text (they may or may not be structurally
|
||||
contiguous). The block frame stores a pointer to a list of nsTextRun's
|
||||
and during line layout provides the list to the nsLineLayout engine so
|
||||
that when text is reflowed the text layout code (nsTextFrame) can find
|
||||
related text to properly handle word breaking.
|
||||
<br><b></b>
|
||||
<table CELLSPACING=0 CELLPADDING=0 COLS=1 WIDTH="100%" BGCOLOR="#33CCFF" NOSAVE >
|
||||
<tr>
|
||||
<td><font size=+2>Child Frame Management</font></td>
|
||||
</tr>
|
||||
</table>
|
||||
some other state used to assist in incremental reflow.</blockquote>
|
||||
<b>nsLineLayout</b>
|
||||
<blockquote>This class is the line layout engine. Its a passive entity
|
||||
in the sense that its the responsibility of the block/inline code to use
|
||||
the class (this is done so that the line layout engine doesn't have to
|
||||
manage child frame lists so that both nsBlockFrame and nsInlineFrame can
|
||||
use the class).</blockquote>
|
||||
<b>nsTextRun</b>
|
||||
<blockquote>This is a data class used to store text run information. Text
|
||||
runs are <i>logically</i> contiguous runs of text (they may or may not
|
||||
be structurally contiguous). The block frame stores a pointer to a list
|
||||
of nsTextRun's and during line layout provides the list to the nsLineLayout
|
||||
engine so that when text is reflowed the text layout code (nsTextFrame)
|
||||
can find related text to properly handle word breaking.</blockquote>
|
||||
|
||||
<p>When the blocks child list is modified (AppendFrames, InsertFrames,
|
||||
RemoveFrame) the block code updates its nsLineBox list. Since each nsLineBox
|
||||
is typed (some are marked "inline" and some are marked "block"), the update
|
||||
logic maintains the invaraint of "one block frame per block line". Most
|
||||
of the logic is straightforward, however there is some ugly code to manage
|
||||
"first-line" frames. First-line frames are used when CSS's ":first-line"
|
||||
style is selected for the block. When this is the case, the block code
|
||||
creates an "anonymous first line" frame to manage the first inline children
|
||||
(all of the inlines that preceed the first child block of the block).
|
||||
<h3>
|
||||
<u>Frame construction methods</u></h3>
|
||||
When the blocks child list is modified (AppendFrames, InsertFrames, RemoveFrame)
|
||||
the block code updates its nsLineBox list. Since each nsLineBox is typed
|
||||
(some are marked "inline" and some are marked "block"), the update logic
|
||||
maintains the invariant of "one block frame per block line".
|
||||
<p>When structural changes are made to the blocks children (append/insert/remove)
|
||||
the block code updates the line's and then marks the affected lines "dirty"
|
||||
(each nsLineBox has a dirty bit). After the structural changes are finished
|
||||
then the block will generate an incremental reflow command of type "ReflowDirty".
|
||||
<h3>
|
||||
<u>Line Layout</u></h3>
|
||||
Line layout consists of the placement of inline elements on a line until
|
||||
there is no more room on the line. At that point the line is "broken" and
|
||||
continued on the next line. This process continues until all inline elements
|
||||
have been exhausted. The block code maintains a list of "nsLineBox"'s to
|
||||
facilitate this. These are used instead of frames because they use less
|
||||
memory and because it allows the block to directly control their behavior.
|
||||
<p>The helper class nsLineLayout provides the majority of the line layout
|
||||
behavior needed by the block.
|
||||
<p>The block does keep "text-run" information around for the nsLineLayout
|
||||
logic to use during reflow. Text runs keep track of logically adjacent
|
||||
pieces of text within a block. This information is essential for properly
|
||||
computing line and word breaking. Why? Well, because in html you can write
|
||||
something like this:
|
||||
<p> <p>I <b>W</b>as thinking one day</p>
|
||||
<p>Notice that the word "Was" is composed of two pieces of text, and that
|
||||
they do <i>not</i> have the same parent (content or frame). To properly
|
||||
reflow this and not break the word prematurely after the "W", the text-run
|
||||
information is used by the text frame code to "look ahead" and prevent
|
||||
premature breaking.
|
||||
<p>Lines also keep track of the type of "break" that occurred on the line.
|
||||
This is used, for example, to support html's "<br clear=left>" behavior.
|
||||
<h3>
|
||||
<u>Floater Management</u></h3>
|
||||
Since child block elements are containing blocks for floaters, the only
|
||||
place where a block frame will see a floater is as part of an inline line.
|
||||
Consequently, the nsLineBox will only keep track of floaters on inline
|
||||
lines (saving storage for block lines).
|
||||
<p>The nsLineLayout class and the block frame cooperate in the management
|
||||
of floaters. Since the frame construction code leaves a "placeholder" frame
|
||||
in-flow where the floater was found, when nsLineLayout reflows a placeholder
|
||||
frame it knows to inform the block about it. That triggers the blocks "AddFloater"
|
||||
logic which then determines where the floater should be placed (on the
|
||||
current line or below the current line).
|
||||
<p>The block frame uses the space manager to manage the effects of floaters,
|
||||
namely the consumption of available space. For example, for a left aligned
|
||||
floating element, the inline elements must be placed to the right of the
|
||||
floater. To simplify this process, the spacemanager is used to keep track
|
||||
of available and busy space. Floaters when placed mark space as busy and
|
||||
the spacemanager will them compute the available space. Most of this logic
|
||||
is handled by the nsBlockReflowState which uses a helper class, nsBlockBandData,
|
||||
in concert with the space manager, to do the available space computations.
|
||||
<h3>
|
||||
<u>Child Block Placement</u></h3>
|
||||
Child block reflow is done primarily by using the nsBlockReflowContext
|
||||
code. However, a key detail worth mentioning here is how margins are handled.
|
||||
When the nsHTMLReflowState was created, we placed into it the logic for
|
||||
computing margins, border and padding (among other things). Unfortunately,
|
||||
given the css rules for sibling and generational margin collapsing, the
|
||||
nsHTMLReflowState is unable to properly compute top and bottom margins.
|
||||
Hence, the block frame and the nsBlockReflowContext code perform that function.
|
||||
At the time that the nsBlockReflowContext was designed and implemented
|
||||
we thought that it could compute the top-margin itself and then proceed
|
||||
to place the child block element. However, that turned out to be wrong
|
||||
(oh well) because the correct available space isn't known until <i>after</i>
|
||||
the top margin is computed. Hence, there is some unfortunate duplication
|
||||
of reflow state calculations present in the block frame code.
|
||||
<h3>
|
||||
<u>Bullets</u></h3>
|
||||
Another type of block frame is the "display: list-item". List-items use
|
||||
nsBulletFrame's to manage bullet reflow. However, the block is responsible
|
||||
for bullet placement. In most situations, the nsLineLayout class is used
|
||||
to do the placement. However, if the first effective child of the block
|
||||
is another block, then the block has to do the placement itself.
|
||||
<h3>
|
||||
<u>Blank lines</u></h3>
|
||||
Because our content model contains as much of the original source documents
|
||||
content as possible, we end up with a lot of white space that ends up being
|
||||
compressed into nothingness. This white space ends up impacting this logic
|
||||
in several ways. For example:
|
||||
<p> <div>
|
||||
<br> <p>abc</p>
|
||||
<br> <p>def</p>
|
||||
<br> </div>
|
||||
<p>In the content model for the above html, there is white space between
|
||||
the various block elements (some after the <div>, some after the first
|
||||
</p>, again after the second </p>).
|
||||
<p>For css margin collapsing to work properly, each of those instances
|
||||
of white space has to behave as if they didn't exist. Consequently, there
|
||||
is special logic in the inline line reflow code, and in the nsBlockReflowContext
|
||||
code and in the GetTopBlockChild method, to basically ignore such lines.
|
||||
<h3>
|
||||
<u>First-letter style</u></h3>
|
||||
The block contributes, in a small way, to first-letter style reflow. The
|
||||
frame construction code is responsible for creating the list of child frames
|
||||
for all frames, including the block. It manages the creation of letter-frames,
|
||||
where appropriate, so that all the block has to do is reflow them almost
|
||||
normally like other inline frames.
|
||||
<p>There are two things different that the block does:
|
||||
<p>It is responsible for calling nsLineLayout::SetFirstLetterStyleOK
|
||||
<br>It is responsible for continuing to place frames on a line, even after
|
||||
a frame has said "it can't fit". Normally during inline reflow, if a frame
|
||||
comes back and says it can't fit, the block will end the line, push all
|
||||
remaining frames to the next line and pick up the reflow from there after
|
||||
making sure the frame that didn't fit is continued. For letter-frames,
|
||||
this would result in the first-letter being on one line with the remaining
|
||||
text on subsequent lines. Hence, the block code handles this special case.
|
||||
<br>
|
||||
<table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#33CCFF" NOSAVE >
|
||||
<tr>
|
||||
<td><font size=+2>Basic Reflow Logic</font></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>The block's reflow engine uses the nsLineBox's dirty bit to determine
|
||||
what to reflow. For each line in the block, its dirty bit is examined.
|
||||
If the bit is not set then the line is considered "clean" and the block
|
||||
determines
|
||||
<b>where</b> the line is to be placed. For dirty lines, the
|
||||
line is reflowed and when finished, lines affected by the reflow are marked
|
||||
dirty. The loop proceeds until either there is no more space for placing
|
||||
lines, or there are no more lines (including draining lines from continuations).
|
||||
<p>For each line reflowed, there are two types of lines: block lines and
|
||||
inline lines. Block lines use ReflowBlockFrame to setup and reflow the
|
||||
single block child on the line. Inline lines use nsReflowInlineFrames to
|
||||
setup and reflow one or more inline frames on the line.
|
||||
<p>nsBlockReflowContext is a helper class used to reflow child block frames.
|
||||
nsLineLayout is a helper class used to reflow inline frames. See the document
|
||||
on line layout for more detail on how it works.
|
||||
<br>
|
||||
<table BORDER=0 CELLSPACING=0 COLS=1 WIDTH="100%" BGCOLOR="#33CCFF" NOSAVE >
|
||||
<tr>
|
||||
<td><font size=+2>Floater Handling</font></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>When frames are created by the frame construction code, "placeholders"
|
||||
are made that remain in-the-flow while the floating element is moved out-of-flow.
|
||||
Block frames receive child floating frames and keep them on a floater list.
|
||||
Note that if an inline frame contains a floating element it to will recieve
|
||||
a placeholder frame, but the floating frame will go to the inline frames
|
||||
containing block.
|
||||
<p>During the reflow of an inline line, the line layout logic will become
|
||||
aware of reflowing a placeholder frame for a floating element. When it
|
||||
does, it will inform the containing block of the floater so that the block
|
||||
and reflow and then place the floating element. To assist in this process,
|
||||
the nsBlockReflowState (misnamed) and the nsBlockBandData classes are used
|
||||
by the block code to do the bulk of the work. These classes also assist
|
||||
heavily in handling of the CSS "clear" property and HTML BR elements.
|
||||
<h3>
|
||||
<u>First-line style</u></h3>
|
||||
First-line is handled entirely by the frame construction code.
|
||||
<br>
|
||||
<br>
|
||||
</body>
|
||||
|
@ -2,47 +2,42 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="GENERATOR" content="Mozilla/4.5 [en] (X11; I; Linux 2.0.36 i686) [Netscape]">
|
||||
<meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; Linux 2.2.5-22 i686) [Netscape]">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<table CELLSPACING=0 CELLPADDING=0 COLS=1 WIDTH="100%" BGCOLOR="#33CCFF" NOSAVE >
|
||||
<tr>
|
||||
<td><font size=+4>Line Layout</font></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>Line layout is the process of placing inline frames horizontally (left
|
||||
<h1>
|
||||
<u>Line Layout</u></h1>
|
||||
Line layout is the process of placing inline frames horizontally (left
|
||||
to right or right to left depending on the CSS direction property value).
|
||||
An attempt is made to describe how it works.
|
||||
<p>nsLineLayout is the class that provides <b>support</b> for line layout.
|
||||
The container frames nsBlockFrame and nsInlineFrame use nsLineLayout to
|
||||
perform line layout and span layout. Span layout is a subset of line layout
|
||||
used for inline container classes - for example, the HTML "B" element).
|
||||
Because of spans, nsLineLayout handles the nested nature of line layout.
|
||||
<p>nsLineLayout is the class that provides support for line layout. The
|
||||
container frames nsBlockFrame and nsInlineFrame use nsLineLayout to perform
|
||||
line layout and span layout. Span layout is a subset of line layout used
|
||||
for inline container classes - for example, the HTML "B" element). Because
|
||||
of spans, nsLineLayout handles the nested nature of line layout.
|
||||
<p>Line layout as a process contains the following steps:
|
||||
<ol>
|
||||
<li>
|
||||
Initialize the nsLineLayout object (done in nsBlockFrame). This prepares
|
||||
the line layout engine for reflow by initializing its internal data structures.<br>
|
||||
<BR></li>
|
||||
the line layout engine for reflow by initializing its internal data structures.</li>
|
||||
|
||||
<br>
|
||||
<li>
|
||||
Reflowing of inline frames. The block code uses nsLineLayout's <b>ReflowFrame</b>
|
||||
method to reflow each inline frame in a line. This continues until the
|
||||
line runs out of room or the block runs out of frames. The block may be
|
||||
reflowing a span (an instance of nsInlineFrame) which will recursively
|
||||
use nsLineLayout for reflow and placement of the frames in the span.<br>
|
||||
<br>
|
||||
Note that the container frames (nsBlockFrame/nsInlineFrame) call nsLineLayout's
|
||||
ReflowFrame method instead of having the line layout code process a list
|
||||
of children. This is done so that the container frames can handle the issues
|
||||
of "pushing" and "pulling" of frames across continuations. Because
|
||||
block and inline maintain different data structures for their child lists,
|
||||
and because we don't want to mandate a common base class, the line layout
|
||||
code doesn't control the "outer loop" of frame reflow.<br>
|
||||
<BR></li>
|
||||
use nsLineLayout for reflow and placement of the frames in the span.</li>
|
||||
|
||||
<p><br>Note that the container frames (nsBlockFrame/nsInlineFrame) call
|
||||
nsLineLayout's ReflowFrame method instead of having the line layout code
|
||||
process a list of children. This is done so that the container frames can
|
||||
handle the issues of "pushing" and "pulling" of frames across continuations.
|
||||
Because block and inline maintain different data structures for their child
|
||||
lists, and because we don't want to mandate a common base class, the line
|
||||
layout code doesn't control the "outer loop" of frame reflow.
|
||||
<br>
|
||||
<li>
|
||||
Finish line layout by vertically aligning the frames, horizontally aligning
|
||||
the frames and relatively positioning the frames on the line.</li>
|
||||
@ -68,36 +63,52 @@ breaks like page breaks, floater breaks, etc. Currently, we only support
|
||||
line breaks, and floater clearing breaks. Breaks can occur before the frame
|
||||
(NS_INLINE_IS_BREAK_BEFORE) or after the frame (NS_INLINE_IS_BREAK_AFTER)</li>
|
||||
</ul>
|
||||
The handling of the reflow status is done by the container frame <b>using</b>
|
||||
The handling of the reflow status is done by the container frame using
|
||||
nsLineLayout.
|
||||
<br>
|
||||
<table CELLSPACING=0 CELLPADDING=0 COLS=1 WIDTH="100%" BGCOLOR="#33CCFF" NOSAVE >
|
||||
<tr>
|
||||
<td><font size=+3>Line Breaking</font></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>Another aspect of nsLineLayout is that it supports line breaking. At
|
||||
the highest level, line breaking consists of identifying where it is appropriate
|
||||
<h3>
|
||||
<u>Line Breaking</u></h3>
|
||||
Another aspect of nsLineLayout is that it supports line breaking. At the
|
||||
highest level, line breaking consists of identifying where it is appropriate
|
||||
to break a line that doesn't fit in the available horizontal space. At
|
||||
a lower level, some frames are breakable (e.g. text) and some frames are
|
||||
not (e.g. images).
|
||||
<p>In order to break text properly, some out-of-band information is needed
|
||||
by the text frame code (nsTextFrame). In particular, because a "word" (a
|
||||
non-breakable unit of text) may span several frames (for example: <b>"<B>H</B>ello
|
||||
there"</b> is breakable after the <b>"o"</b> in ello but not after
|
||||
by the text frame code (nsTextFrame). In particular, because a "word" (a
|
||||
non-breakable unit of text) may span several frames (for example: <b>"<B>H</B>ello
|
||||
there"</b> is breakable after the <b>"o"</b> in "<b>ello</b>" but not after
|
||||
the <b>"H"</b>), text-run information is used to allow the text frame to
|
||||
find adjacent text and look at them to determine where the next breakable
|
||||
point is. nsLineLayout supports this by keeping track of the text-runs
|
||||
as well as both storing and interrogating "word" state.
|
||||
<p>In addition, nsLineLayout assists in the compression/expansion of whitespace
|
||||
for the CSS white-space property. Compression occurs when neighboring
|
||||
whitespace either inside a single piece of text is compressed or when spaces
|
||||
between abutting elements is collapsed. Expansion occurs in preformatted
|
||||
text when tabs are found. nsLineLayout keeps track of a "column" which
|
||||
is used to determine where the next tab "moves" to.
|
||||
<br>
|
||||
<br>
|
||||
<h3>
|
||||
<u>White-space</u></h3>
|
||||
To support the white-space property, the line layout logic keeps track
|
||||
of the presence of white-space in the line as it told to reflow each inline
|
||||
frame. This allows for the compression of leading whitespace and the compression
|
||||
of adjacent whitespace that is in seperate inline elements.
|
||||
<p>As a post-processing step, the TrimTrailingWhiteSpace logic is used
|
||||
to remove those pesky pices of white-space that end up being placed at
|
||||
the end of a line, that shouldn't really be seen.
|
||||
<p>To support pre-formatted text that contains tab characters, the line
|
||||
layout class keeps track of the current column on behalf of the text frame
|
||||
code.
|
||||
<h3>
|
||||
<u>Vertical Alignment</u></h3>
|
||||
Vertical alignment is peformed as a two and a half pass process. The first
|
||||
pass is done during nsInlineFrame reflow: the child frames of the nsInlineFrame
|
||||
are vertically aligned as best as can be done at the time. There are certain
|
||||
values for the vertical-align property that require the alignment be done
|
||||
after the lines entire height is known; those frames are placed during
|
||||
the last half pass.
|
||||
<p>The second pass is done by the block frame when all of the frames for
|
||||
a line are known. This is where the final height of the line
|
||||
<br>(not the line-height property) is known and where the final half pass
|
||||
can be done to place all of the top and bottom aligned elements.
|
||||
<br>
|
||||
<h3>
|
||||
<u>Horizontal Alignment</u></h3>
|
||||
After all frames on a line have been placed vertically, the block code
|
||||
will use nsLineLayout to perform horizontal alignment within the extra
|
||||
space.
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user