summaryrefslogtreecommitdiffstats
path: root/layout/doc/HLD-SpaceManager.html
diff options
context:
space:
mode:
Diffstat (limited to 'layout/doc/HLD-SpaceManager.html')
-rw-r--r--layout/doc/HLD-SpaceManager.html245
1 files changed, 245 insertions, 0 deletions
diff --git a/layout/doc/HLD-SpaceManager.html b/layout/doc/HLD-SpaceManager.html
new file mode 100644
index 000000000..b67d8d5ef
--- /dev/null
+++ b/layout/doc/HLD-SpaceManager.html
@@ -0,0 +1,245 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+
+ <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+ <title>Space Manager High Level Design</title>
+ <meta name="author" content="Marc Attinasi (attinasi@netscape.com)">
+</head>
+ <body>
+
+<h1><font color="#cc0000">Gecko Layout High Level Design Document</font></h1>
+
+<h1>Space Manager High Level Design</h1>
+ <br>
+
+<h2>Overview</h2>
+ The Space Manager and associated classes and strructures are used by Block
+and Line layout to manage rectangular regions that are occupied and available,
+for correct handling of floated elements and the elements that flow around
+them. &nbsp;When elements are floated to the left or right in a layout, they
+take up space and influence where other elements can be placed. &nbsp;The
+Space Manager is responsible for keeping track of where space is taken up
+and where it is available. This information is used by block layout to correctly
+compute where other floated elements should be placed, and how much space
+is available to normal in-flow elements that flow around the floated bits.<br>
+ <br>
+ The Space Manager works in concert with several other classes to do its
+job. The classes that are considered part of the Space Manager are:<br>
+
+<ul>
+ <li>nsSpaceManager</li>
+ <li>nsBandData</li>
+ <li>nsBlockBandData</li>
+ <li>BandRect / BandList (private structs)</li>
+ <li>FrameInfo (private struct)</li>
+ <li>nsBandtrapezoid</li>
+
+</ul>
+ Outside of the Space Manager itself, the clients of the Space Manager also
+ play an inportant part in the management of he available and used space.
+&nbsp;The primary classes that interact with the Space Manager are:<br>
+
+<ul>
+ <li>nsBlockReflowState</li>
+ <li>nsBlockFrame</li>
+ <li>nsBoxToBlockAdaptor</li>
+
+</ul>
+ The general interaction model is to create a Space Manager for a block
+frame in the context of a Reflow, and to associate it with the BlockReflowState
+ so it is passed down to child frames' reflow methods. After reflow, the
+Space Manager is destroyed. &nbsp;During reflow, the space manager stores
+the space taken up by floats (UpdateSpaceManager in nsBlockFrame) and
+provides information about the space available for other elements (GetAvailableSpace
+in nsBlockReflowState). &nbsp;<br>
+ <br>
+ Additionally, there is a need to manage impacts to lines caused by
+changes to floated elements. &nbsp;This is referred to as Propagation
+of Float Damage and is handled by the Block Frame, making use of the
+Space Manager. When a float is incrementally reflowed, the Space
+Manager is notified if the float's region has changed. If so, the
+vertical space that has been affected (including both the float's old
+region and the float's new region) is noted in the internal
+nsIntervalSet as potential float damage (the method is
+IncludeInDamage). During the incremental reflow of dirty lines the
+block frame may encounter lines that are NOT dirty. In this case the
+Space Manager is also asked if &nbsp;there is any float damage, and
+if there is then the block further checks to see if that damage
+intersects the area of the non-dirty line, marking it dirty if there
+is intersection. &nbsp;Thus, changes to floats on other lines may
+cause impact to otherwise clean lines, and the Space Manager
+facilitates the detection of this. <h2>Data Model</h2>
+
+<h4>Class/Component Diagram</h4>
+
+<blockquote>
+ <div align="Left"><img src="SpaceManagerClasses.png" alt="SpaceManager Class Diagram" idth="500" eight="459" title="Example Class Diagram">
+ <br>
+ </div>
+ </blockquote>
+
+ <ul>
+ <li>nsSpaceManager: The central point of management of the space taken
+ up by floats in a block</li>
+ <li>nsBandData: Provides information about the frames occupying a band
+ of occupied or available space</li>
+ <li>nsBlockBandData: A specialization of nsBandData that is used by
+nsBlockReflowState to determine the available space, float impacts, and
+where floats are cleared. &nbsp;Essentially a CSS-specific wrapper for
+generic nsBandData.</li>
+ <li>BandRect: Keeps the bounds of a band, along with the frames associated
+ with the band. &nbsp;BandRects are a linked list (provided by PRCListStr
+super-class) and also provide some geometry-management methods (SplitVertically,
+SplitHorizontally) and some methods that query or manipulate the frames associated
+with the band (IsOccupiedBy, AddFrame, RemoveFrame).</li>
+ <li>BandList: A subclass of BandRect that provides a list interface
+- Head(), Tail(), IsEmpty(), etc.</li>
+ <li>FrameInfo: A structure that keeps information about the rectangle
+ associated with a specific frame, in a linked list.</li>
+ <li>nsBandTrapezoid: Represents the discrete regions within a band that
+ are either Available, Occupied by a single frame, or Occupied by several
+frames. &nbsp;This is used to communicate information about the space in
+the band to the clients of the SpaceManager. &nbsp;There is no internal use
+of the nsBandTrapezoid by the Space Manager, rather it uses its internal
+BandList to create a BandData collection, which is largely made up of nsTrapezoid
+data.<br>
+ </li>
+
+ </ul>
+
+ <h2>Use Case</h2>
+
+ <h4>Use Case 1: Space Manager is Created / Destroyed</h4>
+ Space Manager instances are created in the nsBlockFrame's Reflow method.
+ &nbsp;<br>
+
+ <ul>
+ <li>An instance is created&nbsp;</li>
+ <li>The BlockReflowState's previous Space Manager is saved off.</li>
+ <li>The new Space Manager instance is associated with the BlockReflowState.
+&nbsp;</li>
+ <li>After the block frame's Reflow has completed, the old Space Manager
+instance is re-associated with the BlockReflowState</li>
+ <li>The new Space Manager is destroyed.</li>
+
+ </ul>
+ If the BlockReflowState already had a Space Manager instance associated
+with it, it is stored off before being replaced, and the returned to the
+BlockReflowState instance after the new one has been destroyed. &nbsp;Thus,
+Space Managers are effectively 'nested' during reflow, with each new block
+introducing its own Space Manager.
+
+ <h4>Use Case 2: Float is added to the Space Manager</h4> After a Space Manager is created for a block context's reflow chain, a
+floated block may be added to it. &nbsp;This happens in the method <i>nsBlockReflowState::RecoverFloats</i> and
+<i>nsBlockReflowState::FlowAndPlaceFloat</i> (formerly this was done in nsBlockFrame::UpdateSpaceManager). &nbsp;<br>
+<br>
+The general algorightm in <i>nsBlockReflowState::RecoverFloats</i> is:<br>
+
+ <ul>
+ <li>For each line in the block, see if it has floated blocks</li>
+ <li>If floats are in the line, iterate over the floats and add each
+ one to the Space Manager via the AddRectRegion method. &nbsp;The actual rect
+ for the frame is cached in an nsFloatCache so it does not have to be recomputed.</li>
+ <li>If the block has any block children, then translate the Space Manager
+ to the child block's origin and update the space manager in the context
+for the child block, recursively. When done with the child, restore the Space
+ Managers coordinates by translating by the negative of the child block's
+origin.&nbsp; <br>
+ </li>
+
+ </ul><br>
+
+The general algorightm in <i>nsBlockReflowState::FlowAndPlaceFloat</i> is:<br>
+<ul>
+ <li>The region that the float currently occupies is recorded.</li>
+ <li>The band of available space is searched (with nsBlockReflowState::GetAvailableSpace);</li>
+ <li>The float frame that is get from the passed nsFloatCache argument is reflowed
+ and its rect is retrieved with GetRect;</li>
+ <li>The floats margins are added;</li>
+ <li>Check if the float can be placed in the acutal band: if not advance to the next band;</li>
+ <li>Check the float type and if it can be added to the space manager;</li>
+ <li>Align the float to its containing block top if rule
+ <a href="http://www.w3.org/TR/REC-CSS2/visuren.html#float-position">CSS2/9.5.1/4</a>
+ is not respected;</li>
+ <li>Add the float using <i>nsSpaceManager::AddRectRegion</i> </li>
+ <li>Compare the area that the float used to occupy with the area that it now occupies: if different,
+ record the vertically affected interval using <i>nsSpaceManager::IncludeInDamage</i></li>
+</ul>
+ <h4>Use Case 3: Space Manager is used to find available space to reflow
+ into</h4>
+ The nsBlockFrame makes use of the Space Manager indirectly to get the available
+ space to reflow a child block or inline frame into. The block frame uses
+a helper method on the nsBlockReflowState class to do the actual computation
+ of available space based on the data in the Space Manager. Here is how it
+works for reflowing an inline frame within a block (this also occurs for
+reflowing a block frame and, partially, for preparing for a resize reflow).<br>
+
+ <ul>
+ <li>nsBlockFrame first frees all float information for the line that
+ is being reflowed.</li>
+ <li>GetAvailableSpace is called on the BlockReflowState</li>
+ <li>the BlockReflowState calls GetAvailableSpace on its BlockBandData
+ instance (which was setup in the BlockReflowState's constructor based on
+the SpaceManager passed in and computed content area).</li>
+ <li>BlockBandData then gets the band data from the space manager via
+a call to the Space Manager associated with the BlockBandData instance.</li>
+ <li>The BlockBandData then walks the collection of trapezoids that were
+ returned by the SpaceManager method GetBandData (as nsBandData wrappers)
+and determines the right-most edge of the available space.</li>
+ <li>The BlockReflowState then stores this available space rect for use
+ in the rest of the reflow chain.<br>
+ </li>
+
+ </ul>
+
+ <h4>Use Case 4: Propagation of Float Damage: detecting and handling float
+damage</h4>
+ This process is driven by the Block Frame.<br>
+
+ <ul>
+ <li>A non-dirty line is encountered by the Block Frame in ReflowDirtyLines</li>
+ <li>Block Frame calls its PropagateFloatDamage method</li>
+ <li>The Space Manager is checked to see if there is any float damage</li>
+ <li>If there is, then the block frame asks the Space Manager if the
+line in question intersects the float damage</li>
+ <li>If the line does intersect a damage interval, then the line is marked
+dirty</li>
+ <li>If the line does not intersect a damage interval, it may still be
+marked dirty if:</li>
+
+ <ul>
+ <li>it was impacted by floats before, but is not any longer</li>
+ <li>it was not impacted by floats befre, but is now</li>
+ <li><a name="block-line-impact"></a>
+ it is impacted by floats and is a block<br>
+ </li>
+
+ </ul>
+
+ </ul>
+ <br>
+
+ <hr width="100%" size="2"><br>
+
+ <h1><font color="#ff0000">Problems / bugs found during documentation:</font></h1>
+
+ <ul>
+ <li>BandRect and BandList are public in nsSpaceManager.h - should be
+private (compiles fine)</li>
+ <li>nsSpaceManager data members are declared protected, but there are
+ no subclasses. Should be private (compiles fine)</li>
+ <li>nsBlockFrame::Paint is mucking with nsBlockBandData in and #if 0
+block - remove that and the include (compiles fine)</li>
+ <li>nsSpaceManger has no way of clearing the float damage interval
+set - this might be needed if the SpaceManager persists beyond a Reflow</li>
+ </ul>
+ <br>
+ <br>
+
+ </body>
+ </html>