mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
115 lines
5.6 KiB
HTML
115 lines
5.6 KiB
HTML
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
|
<meta name="GENERATOR" content="Mozilla/4.61 [en] (X11; I; Linux 2.2.5-22 i686) [Netscape]">
|
|
</head>
|
|
<body>
|
|
|
|
<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 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.</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.</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>
|
|
</ol>
|
|
nsLineLayout is also used by nsBlockFrame to construct text-run information;
|
|
this process is independent of normal line layout is pretty much a hack.
|
|
<p>When frames are reflowed they return a reflow status. During line layout,
|
|
there are several additions to the basic reflow status used by most frames:
|
|
<ul>
|
|
<li>
|
|
NS_FRAME_COMPLETE - this is a normal reflow status and indicates that the
|
|
frame is complete and doesn't need to be continued.</li>
|
|
|
|
<li>
|
|
NS_FRAME_NOT_COMPLETE - this is another normal reflow status and indicates
|
|
that the frame is not complete and will need a continuation frame created
|
|
for it (if it doesn't already have one).</li>
|
|
|
|
<li>
|
|
NS_INLINE_BREAK - some kind of break has been requested. Breaks types include
|
|
simple line breaks (like the BR tag in html sometime does) and more complex
|
|
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 using
|
|
nsLineLayout.
|
|
<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 "<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.
|
|
<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>
|