HLD-SpaceManager.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <!-- This Source Code Form is subject to the terms of the Mozilla Public
  2. - License, v. 2.0. If a copy of the MPL was not distributed with this
  3. - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
  4. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  5. <html>
  6. <head>
  7. <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
  8. <title>Space Manager High Level Design</title>
  9. <meta name="author" content="Marc Attinasi (attinasi@netscape.com)">
  10. </head>
  11. <body>
  12. <h1><font color="#cc0000">Gecko Layout High Level Design Document</font></h1>
  13. <h1>Space Manager High Level Design</h1>
  14. <br>
  15. <h2>Overview</h2>
  16. The Space Manager and associated classes and strructures are used by Block
  17. and Line layout to manage rectangular regions that are occupied and available,
  18. for correct handling of floated elements and the elements that flow around
  19. them. &nbsp;When elements are floated to the left or right in a layout, they
  20. take up space and influence where other elements can be placed. &nbsp;The
  21. Space Manager is responsible for keeping track of where space is taken up
  22. and where it is available. This information is used by block layout to correctly
  23. compute where other floated elements should be placed, and how much space
  24. is available to normal in-flow elements that flow around the floated bits.<br>
  25. <br>
  26. The Space Manager works in concert with several other classes to do its
  27. job. The classes that are considered part of the Space Manager are:<br>
  28. <ul>
  29. <li>nsSpaceManager</li>
  30. <li>nsBandData</li>
  31. <li>nsBlockBandData</li>
  32. <li>BandRect / BandList (private structs)</li>
  33. <li>FrameInfo (private struct)</li>
  34. <li>nsBandtrapezoid</li>
  35. </ul>
  36. Outside of the Space Manager itself, the clients of the Space Manager also
  37. play an inportant part in the management of he available and used space.
  38. &nbsp;The primary classes that interact with the Space Manager are:<br>
  39. <ul>
  40. <li>nsBlockReflowState</li>
  41. <li>nsBlockFrame</li>
  42. <li>nsBoxToBlockAdaptor</li>
  43. </ul>
  44. The general interaction model is to create a Space Manager for a block
  45. frame in the context of a Reflow, and to associate it with the BlockReflowState
  46. so it is passed down to child frames' reflow methods. After reflow, the
  47. Space Manager is destroyed. &nbsp;During reflow, the space manager stores
  48. the space taken up by floats (UpdateSpaceManager in nsBlockFrame) and
  49. provides information about the space available for other elements (GetAvailableSpace
  50. in nsBlockReflowState). &nbsp;<br>
  51. <br>
  52. Additionally, there is a need to manage impacts to lines caused by
  53. changes to floated elements. &nbsp;This is referred to as Propagation
  54. of Float Damage and is handled by the Block Frame, making use of the
  55. Space Manager. When a float is incrementally reflowed, the Space
  56. Manager is notified if the float's region has changed. If so, the
  57. vertical space that has been affected (including both the float's old
  58. region and the float's new region) is noted in the internal
  59. nsIntervalSet as potential float damage (the method is
  60. IncludeInDamage). During the incremental reflow of dirty lines the
  61. block frame may encounter lines that are NOT dirty. In this case the
  62. Space Manager is also asked if &nbsp;there is any float damage, and
  63. if there is then the block further checks to see if that damage
  64. intersects the area of the non-dirty line, marking it dirty if there
  65. is intersection. &nbsp;Thus, changes to floats on other lines may
  66. cause impact to otherwise clean lines, and the Space Manager
  67. facilitates the detection of this. <h2>Data Model</h2>
  68. <h4>Class/Component Diagram</h4>
  69. <blockquote>
  70. <div align="Left"><img src="SpaceManagerClasses.png" alt="SpaceManager Class Diagram" idth="500" eight="459" title="Example Class Diagram">
  71. <br>
  72. </div>
  73. </blockquote>
  74. <ul>
  75. <li>nsSpaceManager: The central point of management of the space taken
  76. up by floats in a block</li>
  77. <li>nsBandData: Provides information about the frames occupying a band
  78. of occupied or available space</li>
  79. <li>nsBlockBandData: A specialization of nsBandData that is used by
  80. nsBlockReflowState to determine the available space, float impacts, and
  81. where floats are cleared. &nbsp;Essentially a CSS-specific wrapper for
  82. generic nsBandData.</li>
  83. <li>BandRect: Keeps the bounds of a band, along with the frames associated
  84. with the band. &nbsp;BandRects are a linked list (provided by PRCListStr
  85. super-class) and also provide some geometry-management methods (SplitVertically,
  86. SplitHorizontally) and some methods that query or manipulate the frames associated
  87. with the band (IsOccupiedBy, AddFrame, RemoveFrame).</li>
  88. <li>BandList: A subclass of BandRect that provides a list interface
  89. - Head(), Tail(), IsEmpty(), etc.</li>
  90. <li>FrameInfo: A structure that keeps information about the rectangle
  91. associated with a specific frame, in a linked list.</li>
  92. <li>nsBandTrapezoid: Represents the discrete regions within a band that
  93. are either Available, Occupied by a single frame, or Occupied by several
  94. frames. &nbsp;This is used to communicate information about the space in
  95. the band to the clients of the SpaceManager. &nbsp;There is no internal use
  96. of the nsBandTrapezoid by the Space Manager, rather it uses its internal
  97. BandList to create a BandData collection, which is largely made up of nsTrapezoid
  98. data.<br>
  99. </li>
  100. </ul>
  101. <h2>Use Case</h2>
  102. <h4>Use Case 1: Space Manager is Created / Destroyed</h4>
  103. Space Manager instances are created in the nsBlockFrame's Reflow method.
  104. &nbsp;<br>
  105. <ul>
  106. <li>An instance is created&nbsp;</li>
  107. <li>The BlockReflowState's previous Space Manager is saved off.</li>
  108. <li>The new Space Manager instance is associated with the BlockReflowState.
  109. &nbsp;</li>
  110. <li>After the block frame's Reflow has completed, the old Space Manager
  111. instance is re-associated with the BlockReflowState</li>
  112. <li>The new Space Manager is destroyed.</li>
  113. </ul>
  114. If the BlockReflowState already had a Space Manager instance associated
  115. with it, it is stored off before being replaced, and the returned to the
  116. BlockReflowState instance after the new one has been destroyed. &nbsp;Thus,
  117. Space Managers are effectively 'nested' during reflow, with each new block
  118. introducing its own Space Manager.
  119. <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
  120. floated block may be added to it. &nbsp;This happens in the method <i>nsBlockReflowState::RecoverFloats</i> and
  121. <i>nsBlockReflowState::FlowAndPlaceFloat</i> (formerly this was done in nsBlockFrame::UpdateSpaceManager). &nbsp;<br>
  122. <br>
  123. The general algorightm in <i>nsBlockReflowState::RecoverFloats</i> is:<br>
  124. <ul>
  125. <li>For each line in the block, see if it has floated blocks</li>
  126. <li>If floats are in the line, iterate over the floats and add each
  127. one to the Space Manager via the AddRectRegion method. &nbsp;The actual rect
  128. for the frame is cached in an nsFloatCache so it does not have to be recomputed.</li>
  129. <li>If the block has any block children, then translate the Space Manager
  130. to the child block's origin and update the space manager in the context
  131. for the child block, recursively. When done with the child, restore the Space
  132. Managers coordinates by translating by the negative of the child block's
  133. origin.&nbsp; <br>
  134. </li>
  135. </ul><br>
  136. The general algorightm in <i>nsBlockReflowState::FlowAndPlaceFloat</i> is:<br>
  137. <ul>
  138. <li>The region that the float currently occupies is recorded.</li>
  139. <li>The band of available space is searched (with nsBlockReflowState::GetAvailableSpace);</li>
  140. <li>The float frame that is get from the passed nsFloatCache argument is reflowed
  141. and its rect is retrieved with GetRect;</li>
  142. <li>The floats margins are added;</li>
  143. <li>Check if the float can be placed in the acutal band: if not advance to the next band;</li>
  144. <li>Check the float type and if it can be added to the space manager;</li>
  145. <li>Align the float to its containing block top if rule
  146. <a href="http://www.w3.org/TR/REC-CSS2/visuren.html#float-position">CSS2/9.5.1/4</a>
  147. is not respected;</li>
  148. <li>Add the float using <i>nsSpaceManager::AddRectRegion</i> </li>
  149. <li>Compare the area that the float used to occupy with the area that it now occupies: if different,
  150. record the vertically affected interval using <i>nsSpaceManager::IncludeInDamage</i></li>
  151. </ul>
  152. <h4>Use Case 3: Space Manager is used to find available space to reflow
  153. into</h4>
  154. The nsBlockFrame makes use of the Space Manager indirectly to get the available
  155. space to reflow a child block or inline frame into. The block frame uses
  156. a helper method on the nsBlockReflowState class to do the actual computation
  157. of available space based on the data in the Space Manager. Here is how it
  158. works for reflowing an inline frame within a block (this also occurs for
  159. reflowing a block frame and, partially, for preparing for a resize reflow).<br>
  160. <ul>
  161. <li>nsBlockFrame first frees all float information for the line that
  162. is being reflowed.</li>
  163. <li>GetAvailableSpace is called on the BlockReflowState</li>
  164. <li>the BlockReflowState calls GetAvailableSpace on its BlockBandData
  165. instance (which was setup in the BlockReflowState's constructor based on
  166. the SpaceManager passed in and computed content area).</li>
  167. <li>BlockBandData then gets the band data from the space manager via
  168. a call to the Space Manager associated with the BlockBandData instance.</li>
  169. <li>The BlockBandData then walks the collection of trapezoids that were
  170. returned by the SpaceManager method GetBandData (as nsBandData wrappers)
  171. and determines the right-most edge of the available space.</li>
  172. <li>The BlockReflowState then stores this available space rect for use
  173. in the rest of the reflow chain.<br>
  174. </li>
  175. </ul>
  176. <h4>Use Case 4: Propagation of Float Damage: detecting and handling float
  177. damage</h4>
  178. This process is driven by the Block Frame.<br>
  179. <ul>
  180. <li>A non-dirty line is encountered by the Block Frame in ReflowDirtyLines</li>
  181. <li>Block Frame calls its PropagateFloatDamage method</li>
  182. <li>The Space Manager is checked to see if there is any float damage</li>
  183. <li>If there is, then the block frame asks the Space Manager if the
  184. line in question intersects the float damage</li>
  185. <li>If the line does intersect a damage interval, then the line is marked
  186. dirty</li>
  187. <li>If the line does not intersect a damage interval, it may still be
  188. marked dirty if:</li>
  189. <ul>
  190. <li>it was impacted by floats before, but is not any longer</li>
  191. <li>it was not impacted by floats befre, but is now</li>
  192. <li><a name="block-line-impact"></a>
  193. it is impacted by floats and is a block<br>
  194. </li>
  195. </ul>
  196. </ul>
  197. <br>
  198. <hr width="100%" size="2"><br>
  199. <h1><font color="#ff0000">Problems / bugs found during documentation:</font></h1>
  200. <ul>
  201. <li>BandRect and BandList are public in nsSpaceManager.h - should be
  202. private (compiles fine)</li>
  203. <li>nsSpaceManager data members are declared protected, but there are
  204. no subclasses. Should be private (compiles fine)</li>
  205. <li>nsBlockFrame::Paint is mucking with nsBlockBandData in and #if 0
  206. block - remove that and the include (compiles fine)</li>
  207. <li>nsSpaceManger has no way of clearing the float damage interval
  208. set - this might be needed if the SpaceManager persists beyond a Reflow</li>
  209. </ul>
  210. <br>
  211. <br>
  212. </body>
  213. </html>