layout/xul/nsSprocketLayout.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/xul/nsSprocketLayout.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1643 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +//
    1.10 +// Eric Vaughan
    1.11 +// Netscape Communications
    1.12 +//
    1.13 +// See documentation in associated header file
    1.14 +//
    1.15 +
    1.16 +#include "nsBoxLayoutState.h"
    1.17 +#include "nsSprocketLayout.h"
    1.18 +#include "nsPresContext.h"
    1.19 +#include "nsCOMPtr.h"
    1.20 +#include "nsIContent.h"
    1.21 +#include "nsIPresShell.h"
    1.22 +#include "nsContainerFrame.h"
    1.23 +#include "nsBoxFrame.h"
    1.24 +#include "StackArena.h"
    1.25 +#include "mozilla/Likely.h"
    1.26 +#include <algorithm>
    1.27 +
    1.28 +nsBoxLayout* nsSprocketLayout::gInstance = nullptr;
    1.29 +
    1.30 +//#define DEBUG_GROW
    1.31 +
    1.32 +#define DEBUG_SPRING_SIZE 8
    1.33 +#define DEBUG_BORDER_SIZE 2
    1.34 +#define COIL_SIZE 8
    1.35 +
    1.36 +
    1.37 +nsresult
    1.38 +NS_NewSprocketLayout( nsIPresShell* aPresShell, nsCOMPtr<nsBoxLayout>& aNewLayout)
    1.39 +{
    1.40 +  if (!nsSprocketLayout::gInstance) {
    1.41 +    nsSprocketLayout::gInstance = new nsSprocketLayout();
    1.42 +    NS_IF_ADDREF(nsSprocketLayout::gInstance);
    1.43 +  }
    1.44 +  // we have not instance variables so just return our static one.
    1.45 +  aNewLayout = nsSprocketLayout::gInstance;
    1.46 +  return NS_OK;
    1.47 +} 
    1.48 +
    1.49 +/*static*/ void
    1.50 +nsSprocketLayout::Shutdown()
    1.51 +{
    1.52 +  NS_IF_RELEASE(gInstance);
    1.53 +}
    1.54 +
    1.55 +nsSprocketLayout::nsSprocketLayout()
    1.56 +{
    1.57 +}
    1.58 +
    1.59 +bool 
    1.60 +nsSprocketLayout::IsHorizontal(nsIFrame* aBox)
    1.61 +{
    1.62 +   return (aBox->GetStateBits() & NS_STATE_IS_HORIZONTAL) != 0;
    1.63 +}
    1.64 +
    1.65 +void
    1.66 +nsSprocketLayout::GetFrameState(nsIFrame* aBox, nsFrameState& aState)
    1.67 +{
    1.68 +   aState = aBox->GetStateBits();
    1.69 +}
    1.70 +
    1.71 +static uint8_t
    1.72 +GetFrameDirection(nsIFrame* aBox)
    1.73 +{
    1.74 +   return aBox->StyleVisibility()->mDirection;
    1.75 +}
    1.76 +
    1.77 +static void
    1.78 +HandleBoxPack(nsIFrame* aBox, const nsFrameState& aFrameState, nscoord& aX, nscoord& aY, 
    1.79 +              const nsRect& aOriginalRect, const nsRect& aClientRect)
    1.80 +{
    1.81 +  // In the normal direction we lay out our kids in the positive direction (e.g., |x| will get
    1.82 +  // bigger for a horizontal box, and |y| will get bigger for a vertical box).  In the reverse
    1.83 +  // direction, the opposite is true.  We'll be laying out each child at a smaller |x| or
    1.84 +  // |y|.
    1.85 +  uint8_t frameDirection = GetFrameDirection(aBox);
    1.86 +
    1.87 +  if (aFrameState & NS_STATE_IS_HORIZONTAL) {
    1.88 +    if (aFrameState & NS_STATE_IS_DIRECTION_NORMAL) {
    1.89 +      // The normal direction. |x| increases as we move through our children.
    1.90 +      aX = aClientRect.x;
    1.91 +    }
    1.92 +    else {
    1.93 +      // The reverse direction. |x| decreases as we move through our children.
    1.94 +      aX = aClientRect.x + aOriginalRect.width;
    1.95 +    }
    1.96 +    // |y| is always in the normal direction in horizontal boxes
    1.97 +    aY = aClientRect.y;    
    1.98 +  }
    1.99 +  else {
   1.100 +    // take direction property into account for |x| in vertical boxes
   1.101 +    if (frameDirection == NS_STYLE_DIRECTION_LTR) {
   1.102 +      // The normal direction. |x| increases as we move through our children.
   1.103 +      aX = aClientRect.x;
   1.104 +    }
   1.105 +    else {
   1.106 +      // The reverse direction. |x| decreases as we move through our children.
   1.107 +      aX = aClientRect.x + aOriginalRect.width;
   1.108 +    }
   1.109 +    if (aFrameState & NS_STATE_IS_DIRECTION_NORMAL) {
   1.110 +      // The normal direction. |y| increases as we move through our children.
   1.111 +      aY = aClientRect.y;
   1.112 +    }
   1.113 +    else {
   1.114 +      // The reverse direction. |y| decreases as we move through our children.
   1.115 +      aY = aClientRect.y + aOriginalRect.height;
   1.116 +    }
   1.117 +  }
   1.118 +
   1.119 +  // Get our pack/alignment information.
   1.120 +  nsIFrame::Halignment halign = aBox->GetHAlign();
   1.121 +  nsIFrame::Valignment valign = aBox->GetVAlign();
   1.122 +
   1.123 +  // The following code handles box PACKING.  Packing comes into play in the case where the computed size for 
   1.124 +  // all of our children (now stored in our client rect) is smaller than the size available for
   1.125 +  // the box (stored in |aOriginalRect|).  
   1.126 +  // 
   1.127 +  // Here we adjust our |x| and |y| variables accordingly so that we start at the beginning,
   1.128 +  // middle, or end of the box.
   1.129 +  //
   1.130 +  // XXXdwh JUSTIFY needs to be implemented!
   1.131 +  if (aFrameState & NS_STATE_IS_HORIZONTAL) {
   1.132 +    switch(halign) {
   1.133 +      case nsBoxFrame::hAlign_Left:
   1.134 +        break; // Nothing to do.  The default initialized us properly.
   1.135 +
   1.136 +      case nsBoxFrame::hAlign_Center:
   1.137 +        if (aFrameState & NS_STATE_IS_DIRECTION_NORMAL)
   1.138 +          aX += (aOriginalRect.width - aClientRect.width)/2;
   1.139 +        else 
   1.140 +          aX -= (aOriginalRect.width - aClientRect.width)/2;
   1.141 +        break;
   1.142 +
   1.143 +      case nsBoxFrame::hAlign_Right:
   1.144 +        if (aFrameState & NS_STATE_IS_DIRECTION_NORMAL)
   1.145 +          aX += (aOriginalRect.width - aClientRect.width);
   1.146 +        else
   1.147 +          aX -= (aOriginalRect.width - aClientRect.width);
   1.148 +        break; // Nothing to do for the reverse dir.  The default initialized us properly.
   1.149 +    }
   1.150 +  } else {
   1.151 +    switch(valign) {
   1.152 +      case nsBoxFrame::vAlign_Top:
   1.153 +      case nsBoxFrame::vAlign_BaseLine: // This value is technically impossible to specify for pack.
   1.154 +        break;  // Don't do anything.  We were initialized correctly.
   1.155 +
   1.156 +      case nsBoxFrame::vAlign_Middle:
   1.157 +        if (aFrameState & NS_STATE_IS_DIRECTION_NORMAL)
   1.158 +          aY += (aOriginalRect.height - aClientRect.height)/2;
   1.159 +        else
   1.160 +          aY -= (aOriginalRect.height - aClientRect.height)/2;
   1.161 +        break;
   1.162 +
   1.163 +      case nsBoxFrame::vAlign_Bottom:
   1.164 +        if (aFrameState & NS_STATE_IS_DIRECTION_NORMAL)
   1.165 +          aY += (aOriginalRect.height - aClientRect.height);
   1.166 +        else
   1.167 +          aY -= (aOriginalRect.height - aClientRect.height);
   1.168 +        break;
   1.169 +    }
   1.170 +  }
   1.171 +}
   1.172 +
   1.173 +NS_IMETHODIMP
   1.174 +nsSprocketLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState)
   1.175 +{
   1.176 +  // See if we are collapsed. If we are, then simply iterate over all our
   1.177 +  // children and give them a rect of 0 width and height.
   1.178 +  if (aBox->IsCollapsed()) {
   1.179 +    nsIFrame* child = aBox->GetChildBox();
   1.180 +    while(child) 
   1.181 +    {
   1.182 +      nsBoxFrame::LayoutChildAt(aState, child, nsRect(0,0,0,0));  
   1.183 +      child = child->GetNextBox();
   1.184 +    }
   1.185 +    return NS_OK;
   1.186 +  }
   1.187 +
   1.188 +  nsBoxLayoutState::AutoReflowDepth depth(aState);
   1.189 +  mozilla::AutoStackArena arena;
   1.190 +
   1.191 +  // ----- figure out our size ----------
   1.192 +  const nsSize originalSize = aBox->GetSize();
   1.193 +
   1.194 +  // -- make sure we remove our border and padding  ----
   1.195 +  nsRect clientRect;
   1.196 +  aBox->GetClientRect(clientRect);
   1.197 +
   1.198 +  // |originalClientRect| represents the rect of the entire box (excluding borders
   1.199 +  // and padding).  We store it here because we're going to use |clientRect| to hold
   1.200 +  // the required size for all our kids.  As an example, consider an hbox with a
   1.201 +  // specified width of 300.  If the kids total only 150 pixels of width, then
   1.202 +  // we have 150 pixels left over.  |clientRect| is going to hold a width of 150 and
   1.203 +  // is going to be adjusted based off the value of the PACK property.  If flexible
   1.204 +  // objects are in the box, then the two rects will match.
   1.205 +  nsRect originalClientRect(clientRect);
   1.206 +
   1.207 +  // The frame state contains cached knowledge about our box, such as our orientation
   1.208 +  // and direction.
   1.209 +  nsFrameState frameState = nsFrameState(0);
   1.210 +  GetFrameState(aBox, frameState);
   1.211 +
   1.212 +  // Build a list of our children's desired sizes and computed sizes
   1.213 +  nsBoxSize*         boxSizes = nullptr;
   1.214 +  nsComputedBoxSize* computedBoxSizes = nullptr;
   1.215 +
   1.216 +  nscoord min = 0;
   1.217 +  nscoord max = 0;
   1.218 +  int32_t flexes = 0;
   1.219 +  PopulateBoxSizes(aBox, aState, boxSizes, min, max, flexes);
   1.220 +  
   1.221 +  // The |size| variable will hold the total size of children along the axis of
   1.222 +  // the box.  Continuing with the example begun in the comment above, size would
   1.223 +  // be 150 pixels.
   1.224 +  nscoord size = clientRect.width;
   1.225 +  if (!IsHorizontal(aBox))
   1.226 +    size = clientRect.height;
   1.227 +  ComputeChildSizes(aBox, aState, size, boxSizes, computedBoxSizes);
   1.228 +
   1.229 +  // After the call to ComputeChildSizes, the |size| variable contains the
   1.230 +  // total required size of all the children.  We adjust our clientRect in the
   1.231 +  // appropriate dimension to match this size.  In our example, we now assign
   1.232 +  // 150 pixels into the clientRect.width.
   1.233 +  //
   1.234 +  // The variables |min| and |max| hold the minimum required size box must be 
   1.235 +  // in the OPPOSITE orientation, e.g., for a horizontal box, |min| is the minimum
   1.236 +  // height we require to enclose our children, and |max| is the maximum height
   1.237 +  // required to enclose our children.
   1.238 +  if (IsHorizontal(aBox)) {
   1.239 +    clientRect.width = size;
   1.240 +    if (clientRect.height < min)
   1.241 +      clientRect.height = min;
   1.242 +
   1.243 +    if (frameState & NS_STATE_AUTO_STRETCH) {
   1.244 +      if (clientRect.height > max)
   1.245 +        clientRect.height = max;
   1.246 +    }
   1.247 +  } else {
   1.248 +    clientRect.height = size;
   1.249 +    if (clientRect.width < min)
   1.250 +      clientRect.width = min;
   1.251 +
   1.252 +    if (frameState & NS_STATE_AUTO_STRETCH) {
   1.253 +      if (clientRect.width > max)
   1.254 +        clientRect.width = max;
   1.255 +    }
   1.256 +  }
   1.257 +
   1.258 +  // With the sizes computed, now it's time to lay out our children.
   1.259 +  bool finished;
   1.260 +  nscoord passes = 0;
   1.261 +
   1.262 +  // We flow children at their preferred locations (along with the appropriate computed flex).  
   1.263 +  // After we flow a child, it is possible that the child will change its size.  If/when this happens,
   1.264 +  // we have to do another pass.  Typically only 2 passes are required, but the code is prepared to
   1.265 +  // do as many passes as are necessary to achieve equilibrium.
   1.266 +  nscoord x = 0;
   1.267 +  nscoord y = 0;
   1.268 +  nscoord origX = 0;
   1.269 +  nscoord origY = 0;
   1.270 +
   1.271 +  // |childResized| lets us know if a child changed its size after we attempted to lay it out at
   1.272 +  // the specified size.  If this happens, we usually have to do another pass.
   1.273 +  bool childResized = false;
   1.274 +
   1.275 +  // |passes| stores our number of passes.  If for any reason we end up doing more than, say, 10
   1.276 +  // passes, we assert to indicate that something is seriously screwed up.
   1.277 +  passes = 0;
   1.278 +  do 
   1.279 +  { 
   1.280 +#ifdef DEBUG_REFLOW
   1.281 +    if (passes > 0) {
   1.282 +      AddIndents();
   1.283 +      printf("ChildResized doing pass: %d\n", passes);
   1.284 +    }
   1.285 +#endif 
   1.286 +
   1.287 +    // Always assume that we're done.  This will change if, for example, children don't stay
   1.288 +    // the same size after being flowed.
   1.289 +    finished = true;
   1.290 +
   1.291 +    // Handle box packing.
   1.292 +    HandleBoxPack(aBox, frameState, x, y, originalClientRect, clientRect);
   1.293 +
   1.294 +    // Now that packing is taken care of we set up a few additional
   1.295 +    // tracking variables.
   1.296 +    origX = x;
   1.297 +    origY = y;
   1.298 +
   1.299 +    nscoord nextX = x;
   1.300 +    nscoord nextY = y;
   1.301 +
   1.302 +    // Now we iterate over our box children and our box size lists in 
   1.303 +    // parallel.  For each child, we look at its sizes and figure out
   1.304 +    // where to place it.
   1.305 +    nsComputedBoxSize* childComputedBoxSize = computedBoxSizes;
   1.306 +    nsBoxSize* childBoxSize                 = boxSizes;
   1.307 +
   1.308 +    nsIFrame* child = aBox->GetChildBox();
   1.309 +
   1.310 +    int32_t count = 0;
   1.311 +    while (child || (childBoxSize && childBoxSize->bogus))
   1.312 +    { 
   1.313 +      // If for some reason, our lists are not the same length, we guard
   1.314 +      // by bailing out of the loop.
   1.315 +      if (childBoxSize == nullptr) {
   1.316 +        NS_NOTREACHED("Lists not the same length.");
   1.317 +        break;
   1.318 +      }
   1.319 +        
   1.320 +      nscoord width = clientRect.width;
   1.321 +      nscoord height = clientRect.height;
   1.322 +
   1.323 +      if (!childBoxSize->bogus) {
   1.324 +        // We have a valid box size entry.  This entry already contains information about our
   1.325 +        // sizes along the axis of the box (e.g., widths in a horizontal box).  If our default
   1.326 +        // ALIGN is not stretch, however, then we also need to know the child's size along the
   1.327 +        // opposite axis.
   1.328 +        if (!(frameState & NS_STATE_AUTO_STRETCH)) {
   1.329 +           nsSize prefSize = child->GetPrefSize(aState);
   1.330 +           nsSize minSize = child->GetMinSize(aState);
   1.331 +           nsSize maxSize = child->GetMaxSize(aState);
   1.332 +           prefSize = nsBox::BoundsCheck(minSize, prefSize, maxSize);
   1.333 +       
   1.334 +           AddMargin(child, prefSize);
   1.335 +           width = std::min(prefSize.width, originalClientRect.width);
   1.336 +           height = std::min(prefSize.height, originalClientRect.height);
   1.337 +        }
   1.338 +      }
   1.339 +
   1.340 +      // Obtain the computed size along the axis of the box for this child from the computedBoxSize entry.  
   1.341 +      // We store the result in |width| for horizontal boxes and |height| for vertical boxes.
   1.342 +      if (frameState & NS_STATE_IS_HORIZONTAL)
   1.343 +        width = childComputedBoxSize->size;
   1.344 +      else
   1.345 +        height = childComputedBoxSize->size;
   1.346 +      
   1.347 +      // Adjust our x/y for the left/right spacing.
   1.348 +      if (frameState & NS_STATE_IS_HORIZONTAL) {
   1.349 +        if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
   1.350 +          x += (childBoxSize->left);
   1.351 +        else
   1.352 +          x -= (childBoxSize->right);
   1.353 +      } else {
   1.354 +        if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
   1.355 +          y += (childBoxSize->left);
   1.356 +        else
   1.357 +          y -= (childBoxSize->right);
   1.358 +      }
   1.359 +
   1.360 +      nextX = x;
   1.361 +      nextY = y;
   1.362 +
   1.363 +      // Now we build a child rect.
   1.364 +      nscoord rectX = x;
   1.365 +      nscoord rectY = y;
   1.366 +      if (!(frameState & NS_STATE_IS_DIRECTION_NORMAL)) {
   1.367 +        if (frameState & NS_STATE_IS_HORIZONTAL)
   1.368 +          rectX -= width;
   1.369 +        else
   1.370 +          rectY -= height;
   1.371 +      }
   1.372 +
   1.373 +      // We now create an accurate child rect based off our computed size information.
   1.374 +      nsRect childRect(rectX, rectY, width, height);
   1.375 +
   1.376 +      // Sanity check against our clientRect.  It is possible that a child specified
   1.377 +      // a size that is too large to fit.  If that happens, then we have to grow
   1.378 +      // our client rect.  Remember, clientRect is not the total rect of the enclosing
   1.379 +      // box.  It currently holds our perception of how big the children needed to
   1.380 +      // be.
   1.381 +      if (childRect.width > clientRect.width)
   1.382 +        clientRect.width = childRect.width;
   1.383 +
   1.384 +      if (childRect.height > clientRect.height)
   1.385 +        clientRect.height = childRect.height;
   1.386 +    
   1.387 +      // Either |nextX| or |nextY| is updated by this function call, according
   1.388 +      // to our axis.
   1.389 +      ComputeChildsNextPosition(aBox, x, y, nextX, nextY, childRect);
   1.390 +
   1.391 +      // Now we further update our nextX/Y along our axis.
   1.392 +      // We also set childRect.y/x along the opposite axis appropriately for a
   1.393 +      // stretch alignment.  (Non-stretch alignment is handled below.)
   1.394 +      if (frameState & NS_STATE_IS_HORIZONTAL) {
   1.395 +        if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
   1.396 +          nextX += (childBoxSize->right);
   1.397 +        else
   1.398 +          nextX -= (childBoxSize->left);
   1.399 +        childRect.y = originalClientRect.y;
   1.400 +      }
   1.401 +      else {
   1.402 +        if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
   1.403 +          nextY += (childBoxSize->right);
   1.404 +        else 
   1.405 +          nextY -= (childBoxSize->left);
   1.406 +        childRect.x = originalClientRect.x;
   1.407 +      }
   1.408 +      
   1.409 +      // If we encounter a completely bogus box size, we just leave this child completely
   1.410 +      // alone and continue through the loop to the next child.
   1.411 +      if (childBoxSize->bogus) 
   1.412 +      {
   1.413 +        childComputedBoxSize = childComputedBoxSize->next;
   1.414 +        childBoxSize = childBoxSize->next;
   1.415 +        count++;
   1.416 +        x = nextX;
   1.417 +        y = nextY;
   1.418 +        continue;
   1.419 +      }
   1.420 +
   1.421 +      nsMargin margin(0,0,0,0);
   1.422 +
   1.423 +      bool layout = true;
   1.424 +
   1.425 +      // Deflate the rect of our child by its margin.
   1.426 +      child->GetMargin(margin);
   1.427 +      childRect.Deflate(margin);
   1.428 +      if (childRect.width < 0)
   1.429 +        childRect.width = 0;
   1.430 +      if (childRect.height < 0)
   1.431 +        childRect.height = 0;
   1.432 +
   1.433 +      // Now we're trying to figure out if we have to lay out this child, i.e., to call
   1.434 +      // the child's Layout method.
   1.435 +      if (passes > 0) {
   1.436 +        layout = false;
   1.437 +      } else {
   1.438 +        // Always perform layout if we are dirty or have dirty children
   1.439 +        if (!NS_SUBTREE_DIRTY(child))
   1.440 +          layout = false;
   1.441 +      }
   1.442 +
   1.443 +      nsRect oldRect(child->GetRect());
   1.444 +
   1.445 +      // Non-stretch alignment will be handled in AlignChildren(), so don't
   1.446 +      // change child out-of-axis positions yet.
   1.447 +      if (!(frameState & NS_STATE_AUTO_STRETCH)) {
   1.448 +        if (frameState & NS_STATE_IS_HORIZONTAL) {
   1.449 +          childRect.y = oldRect.y;
   1.450 +        } else {
   1.451 +          childRect.x = oldRect.x;
   1.452 +        }
   1.453 +      }
   1.454 +
   1.455 +      // We computed a childRect.  Now we want to set the bounds of the child to be that rect.
   1.456 +      // If our old rect is different, then we know our size changed and we cache that fact
   1.457 +      // in the |sizeChanged| variable.
   1.458 +
   1.459 +      child->SetBounds(aState, childRect);
   1.460 +      bool sizeChanged = (childRect.width != oldRect.width ||
   1.461 +                            childRect.height != oldRect.height);
   1.462 +
   1.463 +      if (sizeChanged) {
   1.464 +        // Our size is different.  Sanity check against our maximum allowed size to ensure
   1.465 +        // we didn't exceed it.
   1.466 +        nsSize minSize = child->GetMinSize(aState);
   1.467 +        nsSize maxSize = child->GetMaxSize(aState);
   1.468 +        maxSize = nsBox::BoundsCheckMinMax(minSize, maxSize);
   1.469 +
   1.470 +        // make sure the size is in our max size.
   1.471 +        if (childRect.width > maxSize.width)
   1.472 +          childRect.width = maxSize.width;
   1.473 +
   1.474 +        if (childRect.height > maxSize.height)
   1.475 +          childRect.height = maxSize.height;
   1.476 +           
   1.477 +        // set it again
   1.478 +        child->SetBounds(aState, childRect);
   1.479 +      }
   1.480 +
   1.481 +      // If we already determined that layout was required or if our size has changed, then
   1.482 +      // we make sure to call layout on the child, since its children may need to be shifted
   1.483 +      // around as a result of the size change.
   1.484 +      if (layout || sizeChanged)
   1.485 +        child->Layout(aState);
   1.486 +      
   1.487 +      // If the child was a block or inline (e.g., HTML) it may have changed its rect *during* layout. 
   1.488 +      // We have to check for this.
   1.489 +      nsRect newChildRect(child->GetRect());
   1.490 +
   1.491 +      if (!newChildRect.IsEqualInterior(childRect)) {
   1.492 +#ifdef DEBUG_GROW
   1.493 +        child->DumpBox(stdout);
   1.494 +        printf(" GREW from (%d,%d) -> (%d,%d)\n", childRect.width, childRect.height, newChildRect.width, newChildRect.height);
   1.495 +#endif
   1.496 +        newChildRect.Inflate(margin);
   1.497 +        childRect.Inflate(margin);
   1.498 +
   1.499 +        // The child changed size during layout.  The ChildResized method handles this
   1.500 +        // scenario.
   1.501 +        ChildResized(aBox,
   1.502 +                     aState, 
   1.503 +                     child,
   1.504 +                     childBoxSize,
   1.505 +                     childComputedBoxSize,
   1.506 +                     boxSizes, 
   1.507 +                     computedBoxSizes, 
   1.508 +                     childRect,
   1.509 +                     newChildRect,
   1.510 +                     clientRect,
   1.511 +                     flexes,
   1.512 +                     finished);
   1.513 +
   1.514 +        // We note that a child changed size, which means that another pass will be required.
   1.515 +        childResized = true;
   1.516 +
   1.517 +        // Now that a child resized, it's entirely possible that OUR rect is too small.  Now we
   1.518 +        // ensure that |originalClientRect| is grown to accommodate the size of |clientRect|.
   1.519 +        if (clientRect.width > originalClientRect.width)
   1.520 +          originalClientRect.width = clientRect.width;
   1.521 +
   1.522 +        if (clientRect.height > originalClientRect.height)
   1.523 +          originalClientRect.height = clientRect.height;
   1.524 +
   1.525 +        if (!(frameState & NS_STATE_IS_DIRECTION_NORMAL)) {
   1.526 +          // Our childRect had its XMost() or YMost() (depending on our layout
   1.527 +          // direction), positioned at a certain point.  Ensure that the
   1.528 +          // newChildRect satisfies the same constraint.  Note that this is
   1.529 +          // just equivalent to adjusting the x/y by the difference in
   1.530 +          // width/height between childRect and newChildRect.  So we don't need
   1.531 +          // to reaccount for the left and right of the box layout state again.
   1.532 +          if (frameState & NS_STATE_IS_HORIZONTAL)
   1.533 +            newChildRect.x = childRect.XMost() - newChildRect.width;
   1.534 +          else
   1.535 +            newChildRect.y = childRect.YMost() - newChildRect.height;
   1.536 +        }
   1.537 +
   1.538 +        // If the child resized then recompute its position.
   1.539 +        ComputeChildsNextPosition(aBox, x, y, nextX, nextY, newChildRect);
   1.540 +
   1.541 +        if (newChildRect.width >= margin.left + margin.right && newChildRect.height >= margin.top + margin.bottom) 
   1.542 +          newChildRect.Deflate(margin);
   1.543 +
   1.544 +        if (childRect.width >= margin.left + margin.right && childRect.height >= margin.top + margin.bottom) 
   1.545 +          childRect.Deflate(margin);
   1.546 +            
   1.547 +        child->SetBounds(aState, newChildRect);
   1.548 +
   1.549 +        // If we are the first box that changed size, then we don't need to do a second pass
   1.550 +        if (count == 0)
   1.551 +          finished = true;
   1.552 +      }
   1.553 +
   1.554 +      // Now update our x/y finally.
   1.555 +      x = nextX;
   1.556 +      y = nextY;
   1.557 +     
   1.558 +      // Move to the next child.
   1.559 +      childComputedBoxSize = childComputedBoxSize->next;
   1.560 +      childBoxSize = childBoxSize->next;
   1.561 +
   1.562 +      child = child->GetNextBox();
   1.563 +      count++;
   1.564 +    }
   1.565 +
   1.566 +    // Sanity-checking code to ensure we don't do an infinite # of passes.
   1.567 +    passes++;
   1.568 +    NS_ASSERTION(passes < 10, "A Box's child is constantly growing!!!!!");
   1.569 +    if (passes > 10)
   1.570 +      break;
   1.571 +  } while (false == finished);
   1.572 +
   1.573 +  // Get rid of our size lists.
   1.574 +  while(boxSizes)
   1.575 +  {
   1.576 +    nsBoxSize* toDelete = boxSizes;
   1.577 +    boxSizes = boxSizes->next;
   1.578 +    delete toDelete;
   1.579 +  }
   1.580 +
   1.581 +  while(computedBoxSizes)
   1.582 +  {
   1.583 +    nsComputedBoxSize* toDelete = computedBoxSizes;
   1.584 +    computedBoxSizes = computedBoxSizes->next;
   1.585 +    delete toDelete;
   1.586 +  }
   1.587 +
   1.588 +  if (childResized) {
   1.589 +    // See if one of our children forced us to get bigger
   1.590 +    nsRect tmpClientRect(originalClientRect);
   1.591 +    nsMargin bp(0,0,0,0);
   1.592 +    aBox->GetBorderAndPadding(bp);
   1.593 +    tmpClientRect.Inflate(bp);
   1.594 +
   1.595 +    if (tmpClientRect.width > originalSize.width || tmpClientRect.height > originalSize.height)
   1.596 +    {
   1.597 +      // if it did reset our bounds.
   1.598 +      nsRect bounds(aBox->GetRect());
   1.599 +      if (tmpClientRect.width > originalSize.width)
   1.600 +        bounds.width = tmpClientRect.width;
   1.601 +
   1.602 +      if (tmpClientRect.height > originalSize.height)
   1.603 +        bounds.height = tmpClientRect.height;
   1.604 +
   1.605 +      aBox->SetBounds(aState, bounds);
   1.606 +    }
   1.607 +  }
   1.608 +
   1.609 +  // Because our size grew, we now have to readjust because of box packing.  Repack
   1.610 +  // in order to update our x and y to the correct values.
   1.611 +  HandleBoxPack(aBox, frameState, x, y, originalClientRect, clientRect);
   1.612 +
   1.613 +  // Compare against our original x and y and only worry about adjusting the children if
   1.614 +  // we really did have to change the positions because of packing (typically for 'center'
   1.615 +  // or 'end' pack values).
   1.616 +  if (x != origX || y != origY) {
   1.617 +    nsIFrame* child = aBox->GetChildBox();
   1.618 +
   1.619 +    // reposition all our children
   1.620 +    while (child) 
   1.621 +    {
   1.622 +      nsRect childRect(child->GetRect());
   1.623 +      childRect.x += (x - origX);
   1.624 +      childRect.y += (y - origY);
   1.625 +      child->SetBounds(aState, childRect);
   1.626 +      child = child->GetNextBox();
   1.627 +    }
   1.628 +  }
   1.629 +
   1.630 +  // Perform out-of-axis alignment for non-stretch alignments
   1.631 +  if (!(frameState & NS_STATE_AUTO_STRETCH)) {
   1.632 +    AlignChildren(aBox, aState);
   1.633 +  }
   1.634 +  
   1.635 +  // That's it!  If you made it this far without having a nervous breakdown, 
   1.636 +  // congratulations!  Go get yourself a beer.
   1.637 +  return NS_OK;
   1.638 +}
   1.639 +
   1.640 +void
   1.641 +nsSprocketLayout::PopulateBoxSizes(nsIFrame* aBox, nsBoxLayoutState& aState, nsBoxSize*& aBoxSizes, nscoord& aMinSize, nscoord& aMaxSize, int32_t& aFlexes)
   1.642 +{
   1.643 +  // used for the equal size flag
   1.644 +  nscoord biggestPrefWidth = 0;
   1.645 +  nscoord biggestMinWidth = 0;
   1.646 +  nscoord smallestMaxWidth = NS_INTRINSICSIZE;
   1.647 +
   1.648 +  nsFrameState frameState = nsFrameState(0);
   1.649 +  GetFrameState(aBox, frameState);
   1.650 +
   1.651 +  //if (frameState & NS_STATE_CURRENTLY_IN_DEBUG)
   1.652 +  //   printf("In debug\n");
   1.653 +
   1.654 +  aMinSize = 0;
   1.655 +  aMaxSize = NS_INTRINSICSIZE;
   1.656 +
   1.657 +  bool isHorizontal;
   1.658 +
   1.659 +  if (IsHorizontal(aBox))
   1.660 +     isHorizontal = true;
   1.661 +  else
   1.662 +     isHorizontal = false;
   1.663 +
   1.664 +  // this is a nice little optimization
   1.665 +  // it turns out that if we only have 1 flexable child
   1.666 +  // then it does not matter what its preferred size is
   1.667 +  // there is nothing to flex it relative. This is great
   1.668 +  // because we can avoid asking for a preferred size in this
   1.669 +  // case. Why is this good? Well you might have html inside it
   1.670 +  // and asking html for its preferred size is rather expensive.
   1.671 +  // so we can just optimize it out this way.
   1.672 +
   1.673 +  // set flexes
   1.674 +  nsIFrame* child = aBox->GetChildBox();
   1.675 +
   1.676 +  aFlexes = 0;
   1.677 +  nsBoxSize* currentBox = nullptr;
   1.678 +
   1.679 +#if 0
   1.680 +  nsBoxSize* start = aBoxSizes;
   1.681 +  
   1.682 +  while(child)
   1.683 +  {
   1.684 +    // ok if we started with a list move down the list
   1.685 +    // until we reach the end. Then start looking at childen.
   1.686 +    // This feature is used extensively for Grid.
   1.687 +    nscoord flex = 0;    
   1.688 +
   1.689 +    if (!start) {
   1.690 +      if (!currentBox) {
   1.691 +        aBoxSizes      = new (aState) nsBoxSize();
   1.692 +        currentBox      = aBoxSizes;
   1.693 +      } else {
   1.694 +        currentBox->next      = new (aState) nsBoxSize();
   1.695 +        currentBox      = currentBox->next;
   1.696 +      }
   1.697 +    
   1.698 +
   1.699 +      flex = child->GetFlex(aState);
   1.700 +
   1.701 +      currentBox->flex = flex;
   1.702 +      currentBox->collapsed = child->IsCollapsed();
   1.703 +    } else {
   1.704 +      flex = start->flex;
   1.705 +      start = start->next;
   1.706 +    }
   1.707 +    
   1.708 +    if (flex > 0) 
   1.709 +       aFlexes++;
   1.710 +   
   1.711 +    child = child->GetNextBox();
   1.712 +  }
   1.713 +#endif
   1.714 +
   1.715 +  // get pref, min, max
   1.716 +  child = aBox->GetChildBox();
   1.717 +  currentBox = aBoxSizes;
   1.718 +  nsBoxSize* last = nullptr;
   1.719 +
   1.720 +  nscoord maxFlex = 0;
   1.721 +  int32_t childCount = 0;
   1.722 +
   1.723 +  while(child)
   1.724 +  {
   1.725 +    while (currentBox && currentBox->bogus) {
   1.726 +      last = currentBox;
   1.727 +      currentBox = currentBox->next;
   1.728 +    }
   1.729 +    ++childCount;
   1.730 +    nsSize pref(0,0);
   1.731 +    nsSize minSize(0,0);
   1.732 +    nsSize maxSize(NS_INTRINSICSIZE,NS_INTRINSICSIZE);
   1.733 +    nscoord ascent = 0;
   1.734 +    bool collapsed = child->IsCollapsed();
   1.735 +
   1.736 +    if (!collapsed) {
   1.737 +    // only one flexible child? Cool we will just make its preferred size
   1.738 +    // 0 then and not even have to ask for it.
   1.739 +    //if (flexes != 1)  {
   1.740 +
   1.741 +      pref = child->GetPrefSize(aState);
   1.742 +      minSize = child->GetMinSize(aState);
   1.743 +      maxSize = nsBox::BoundsCheckMinMax(minSize, child->GetMaxSize(aState));
   1.744 +      ascent = child->GetBoxAscent(aState);
   1.745 +      nsMargin margin;
   1.746 +      child->GetMargin(margin);
   1.747 +      ascent += margin.top;
   1.748 +    //}
   1.749 +
   1.750 +      pref = nsBox::BoundsCheck(minSize, pref, maxSize);
   1.751 +
   1.752 +      AddMargin(child, pref);
   1.753 +      AddMargin(child, minSize);
   1.754 +      AddMargin(child, maxSize);
   1.755 +    }
   1.756 +
   1.757 +    if (!currentBox) {
   1.758 +      // create one.
   1.759 +      currentBox = new (aState) nsBoxSize();
   1.760 +      if (!aBoxSizes) {
   1.761 +        aBoxSizes = currentBox;
   1.762 +        last = aBoxSizes;
   1.763 +      } else {
   1.764 +        last->next = currentBox;
   1.765 +        last = currentBox;
   1.766 +      }
   1.767 +
   1.768 +      nscoord minWidth;
   1.769 +      nscoord maxWidth;
   1.770 +      nscoord prefWidth;
   1.771 +
   1.772 +      // get sizes from child
   1.773 +      if (isHorizontal) {
   1.774 +          minWidth  = minSize.width;
   1.775 +          maxWidth  = maxSize.width;
   1.776 +          prefWidth = pref.width;
   1.777 +      } else {
   1.778 +          minWidth = minSize.height;
   1.779 +          maxWidth = maxSize.height;
   1.780 +          prefWidth = pref.height;
   1.781 +      }
   1.782 +
   1.783 +      nscoord flex = child->GetFlex(aState);
   1.784 +
   1.785 +      // set them if you collapsed you are not flexible.
   1.786 +      if (collapsed) {
   1.787 +        currentBox->flex = 0;
   1.788 +      }
   1.789 +      else {
   1.790 +        if (flex > maxFlex) {
   1.791 +          maxFlex = flex;
   1.792 +        }
   1.793 +        currentBox->flex = flex;
   1.794 +      }
   1.795 +
   1.796 +      // we specified all our children are equal size;
   1.797 +      if (frameState & NS_STATE_EQUAL_SIZE) {
   1.798 +
   1.799 +        if (prefWidth > biggestPrefWidth) 
   1.800 +          biggestPrefWidth = prefWidth;
   1.801 +
   1.802 +        if (minWidth > biggestMinWidth) 
   1.803 +          biggestMinWidth = minWidth;
   1.804 +
   1.805 +        if (maxWidth < smallestMaxWidth) 
   1.806 +          smallestMaxWidth = maxWidth;
   1.807 +      } else { // not we can set our children right now.
   1.808 +        currentBox->pref    = prefWidth;
   1.809 +        currentBox->min     = minWidth;
   1.810 +        currentBox->max     = maxWidth;
   1.811 +      }
   1.812 +
   1.813 +      NS_ASSERTION(minWidth <= prefWidth && prefWidth <= maxWidth,"Bad min, pref, max widths!");
   1.814 +
   1.815 +    }
   1.816 +
   1.817 +    if (!isHorizontal) {
   1.818 +      if (minSize.width > aMinSize)
   1.819 +        aMinSize = minSize.width;
   1.820 +
   1.821 +      if (maxSize.width < aMaxSize)
   1.822 +        aMaxSize = maxSize.width;
   1.823 +
   1.824 +    } else {
   1.825 +      if (minSize.height > aMinSize)
   1.826 +        aMinSize = minSize.height;
   1.827 +
   1.828 +      if (maxSize.height < aMaxSize)
   1.829 +        aMaxSize = maxSize.height;
   1.830 +    }
   1.831 +
   1.832 +    currentBox->collapsed = collapsed;
   1.833 +    aFlexes += currentBox->flex;
   1.834 +
   1.835 +    child = child->GetNextBox();
   1.836 +
   1.837 +    last = currentBox;
   1.838 +    currentBox = currentBox->next;
   1.839 +
   1.840 +  }
   1.841 +
   1.842 +  if (childCount > 0) {
   1.843 +    nscoord maxAllowedFlex = nscoord_MAX / childCount;
   1.844 +  
   1.845 +    if (MOZ_UNLIKELY(maxFlex > maxAllowedFlex)) {
   1.846 +      // clamp all the flexes
   1.847 +      currentBox = aBoxSizes;
   1.848 +      while (currentBox) {
   1.849 +        currentBox->flex = std::min(currentBox->flex, maxAllowedFlex);
   1.850 +        currentBox = currentBox->next;      
   1.851 +      }
   1.852 +    }
   1.853 +  }
   1.854 +#ifdef DEBUG
   1.855 +  else {
   1.856 +    NS_ASSERTION(maxFlex == 0, "How did that happen?");
   1.857 +  }
   1.858 +#endif
   1.859 +
   1.860 +  // we specified all our children are equal size;
   1.861 +  if (frameState & NS_STATE_EQUAL_SIZE) {
   1.862 +    smallestMaxWidth = std::max(smallestMaxWidth, biggestMinWidth);
   1.863 +    biggestPrefWidth = nsBox::BoundsCheck(biggestMinWidth, biggestPrefWidth, smallestMaxWidth);
   1.864 +
   1.865 +    currentBox = aBoxSizes;
   1.866 +
   1.867 +    while(currentBox)
   1.868 +    {
   1.869 +      if (!currentBox->collapsed) {
   1.870 +        currentBox->pref = biggestPrefWidth;
   1.871 +        currentBox->min = biggestMinWidth;
   1.872 +        currentBox->max = smallestMaxWidth;
   1.873 +      } else {
   1.874 +        currentBox->pref = 0;
   1.875 +        currentBox->min = 0;
   1.876 +        currentBox->max = 0;
   1.877 +      }
   1.878 +      currentBox = currentBox->next;
   1.879 +    }
   1.880 +  }
   1.881 +
   1.882 +}
   1.883 +
   1.884 +void
   1.885 +nsSprocketLayout::ComputeChildsNextPosition(nsIFrame* aBox, 
   1.886 +                                      const nscoord& aCurX, 
   1.887 +                                      const nscoord& aCurY, 
   1.888 +                                      nscoord& aNextX, 
   1.889 +                                      nscoord& aNextY, 
   1.890 +                                      const nsRect& aCurrentChildSize)
   1.891 +{
   1.892 +  // Get the position along the box axis for the child.
   1.893 +  // The out-of-axis position is not set.
   1.894 +  nsFrameState frameState = nsFrameState(0);
   1.895 +  GetFrameState(aBox, frameState);
   1.896 +
   1.897 +  if (IsHorizontal(aBox)) {
   1.898 +    // horizontal box's children.
   1.899 +    if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
   1.900 +      aNextX = aCurX + aCurrentChildSize.width;
   1.901 +    else
   1.902 +      aNextX = aCurX - aCurrentChildSize.width;
   1.903 +
   1.904 +  } else {
   1.905 +    // vertical box's children.
   1.906 +    if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
   1.907 +      aNextY = aCurY + aCurrentChildSize.height;
   1.908 +    else
   1.909 +      aNextY = aCurY - aCurrentChildSize.height;
   1.910 +  }
   1.911 +}
   1.912 +
   1.913 +void
   1.914 +nsSprocketLayout::AlignChildren(nsIFrame* aBox,
   1.915 +                                nsBoxLayoutState& aState)
   1.916 +{
   1.917 +  nsFrameState frameState = nsFrameState(0);
   1.918 +  GetFrameState(aBox, frameState);
   1.919 +  bool isHorizontal = (frameState & NS_STATE_IS_HORIZONTAL) != 0;
   1.920 +  nsRect clientRect;
   1.921 +  aBox->GetClientRect(clientRect);
   1.922 +
   1.923 +  NS_PRECONDITION(!(frameState & NS_STATE_AUTO_STRETCH),
   1.924 +                  "Only AlignChildren() with non-stretch alignment");
   1.925 +
   1.926 +  // These are only calculated if needed
   1.927 +  nsIFrame::Halignment halign;
   1.928 +  nsIFrame::Valignment valign;
   1.929 +  nscoord maxAscent;
   1.930 +  bool isLTR;
   1.931 +
   1.932 +  if (isHorizontal) {
   1.933 +    valign = aBox->GetVAlign();
   1.934 +    if (valign == nsBoxFrame::vAlign_BaseLine) {
   1.935 +      maxAscent = aBox->GetBoxAscent(aState);
   1.936 +    }
   1.937 +  } else {
   1.938 +    isLTR = GetFrameDirection(aBox) == NS_STYLE_DIRECTION_LTR;
   1.939 +    halign = aBox->GetHAlign();
   1.940 +  }
   1.941 +
   1.942 +  nsIFrame* child = aBox->GetChildBox();
   1.943 +  while (child) {
   1.944 +
   1.945 +    nsMargin margin;
   1.946 +    child->GetMargin(margin);
   1.947 +    nsRect childRect = child->GetRect();
   1.948 +
   1.949 +    if (isHorizontal) {
   1.950 +      const nscoord startAlign = clientRect.y + margin.top;
   1.951 +      const nscoord endAlign =
   1.952 +        clientRect.YMost() - margin.bottom - childRect.height;
   1.953 +
   1.954 +      nscoord y;
   1.955 +      switch (valign) {
   1.956 +        case nsBoxFrame::vAlign_Top:
   1.957 +          y = startAlign;
   1.958 +          break;
   1.959 +        case nsBoxFrame::vAlign_Middle:
   1.960 +          // Should this center the border box?
   1.961 +          // This centers the margin box, the historical behavior.
   1.962 +          y = (startAlign + endAlign) / 2;
   1.963 +          break;
   1.964 +        case nsBoxFrame::vAlign_Bottom:
   1.965 +          y = endAlign;
   1.966 +          break;
   1.967 +        case nsBoxFrame::vAlign_BaseLine:
   1.968 +          // Alignments don't force the box to grow (only sizes do),
   1.969 +          // so keep the children within the box.
   1.970 +          y = maxAscent - child->GetBoxAscent(aState);
   1.971 +          y = std::max(startAlign, y);
   1.972 +          y = std::min(y, endAlign);
   1.973 +          break;
   1.974 +      }
   1.975 +
   1.976 +      childRect.y = y;
   1.977 +
   1.978 +    } else { // vertical box
   1.979 +      const nscoord leftAlign = clientRect.x + margin.left;
   1.980 +      const nscoord rightAlign =
   1.981 +        clientRect.XMost() - margin.right - childRect.width;
   1.982 +
   1.983 +      nscoord x;
   1.984 +      switch (halign) {
   1.985 +        case nsBoxFrame::hAlign_Left: // start
   1.986 +          x = isLTR ? leftAlign : rightAlign;
   1.987 +          break;
   1.988 +        case nsBoxFrame::hAlign_Center:
   1.989 +          x = (leftAlign + rightAlign) / 2;
   1.990 +          break;
   1.991 +        case nsBoxFrame::hAlign_Right: // end
   1.992 +          x = isLTR ? rightAlign : leftAlign;
   1.993 +          break;
   1.994 +      }
   1.995 +
   1.996 +      childRect.x = x;
   1.997 +    }
   1.998 +
   1.999 +    if (childRect.TopLeft() != child->GetPosition()) {
  1.1000 +      child->SetBounds(aState, childRect);
  1.1001 +    }
  1.1002 +
  1.1003 +    child = child->GetNextBox();
  1.1004 +  }
  1.1005 +}
  1.1006 +
  1.1007 +void
  1.1008 +nsSprocketLayout::ChildResized(nsIFrame* aBox,
  1.1009 +                         nsBoxLayoutState& aState, 
  1.1010 +                         nsIFrame* aChild,
  1.1011 +                         nsBoxSize* aChildBoxSize,
  1.1012 +                         nsComputedBoxSize* aChildComputedSize,
  1.1013 +                         nsBoxSize* aBoxSizes, 
  1.1014 +                         nsComputedBoxSize* aComputedBoxSizes, 
  1.1015 +                         const nsRect& aChildLayoutRect, 
  1.1016 +                         nsRect& aChildActualRect, 
  1.1017 +                         nsRect& aContainingRect,
  1.1018 +                         int32_t aFlexes, 
  1.1019 +                         bool& aFinished)
  1.1020 +                         
  1.1021 +{
  1.1022 +      nsRect childCurrentRect(aChildLayoutRect);
  1.1023 +
  1.1024 +      bool isHorizontal = IsHorizontal(aBox);
  1.1025 +      nscoord childLayoutWidth  = GET_WIDTH(aChildLayoutRect,isHorizontal);
  1.1026 +      nscoord& childActualWidth  = GET_WIDTH(aChildActualRect,isHorizontal);
  1.1027 +      nscoord& containingWidth   = GET_WIDTH(aContainingRect,isHorizontal);   
  1.1028 +      
  1.1029 +      //nscoord childLayoutHeight = GET_HEIGHT(aChildLayoutRect,isHorizontal);
  1.1030 +      nscoord& childActualHeight = GET_HEIGHT(aChildActualRect,isHorizontal);
  1.1031 +      nscoord& containingHeight  = GET_HEIGHT(aContainingRect,isHorizontal);
  1.1032 +
  1.1033 +      bool recompute = false;
  1.1034 +
  1.1035 +      // if we are a horizontal box see if the child will fit inside us.
  1.1036 +      if ( childActualHeight > containingHeight) {
  1.1037 +            // if we are a horizontal box and the child is bigger than our height
  1.1038 +
  1.1039 +            // ok if the height changed then we need to reflow everyone but us at the new height
  1.1040 +            // so we will set the changed index to be us. And signal that we need a new pass.
  1.1041 +
  1.1042 +            nsSize min = aChild->GetMinSize(aState);            
  1.1043 +            nsSize max = nsBox::BoundsCheckMinMax(min, aChild->GetMaxSize(aState));
  1.1044 +            AddMargin(aChild, max);
  1.1045 +
  1.1046 +            if (isHorizontal)
  1.1047 +              childActualHeight = max.height < childActualHeight ? max.height : childActualHeight;
  1.1048 +            else
  1.1049 +              childActualHeight = max.width < childActualHeight ? max.width : childActualHeight;
  1.1050 +
  1.1051 +            // only set if it changes
  1.1052 +            if (childActualHeight > containingHeight) {
  1.1053 +                 containingHeight = childActualHeight;
  1.1054 +
  1.1055 +              // remember we do not need to clear the resized list because changing the height of a horizontal box
  1.1056 +              // will not affect the width of any of its children because block flow left to right, top to bottom. Just trust me
  1.1057 +              // on this one.
  1.1058 +              aFinished = false;
  1.1059 +
  1.1060 +              // only recompute if there are flexes.
  1.1061 +              if (aFlexes > 0) {
  1.1062 +                // relayout everything
  1.1063 +                recompute = true;
  1.1064 +                InvalidateComputedSizes(aComputedBoxSizes);
  1.1065 +                nsComputedBoxSize* node = aComputedBoxSizes;
  1.1066 +
  1.1067 +                while(node) {
  1.1068 +                  node->resized = false;
  1.1069 +                  node = node->next;
  1.1070 +                }
  1.1071 +
  1.1072 +              }              
  1.1073 +            }
  1.1074 +      } 
  1.1075 +      
  1.1076 +      if (childActualWidth > childLayoutWidth) {
  1.1077 +            nsSize min = aChild->GetMinSize(aState);
  1.1078 +            nsSize max = nsBox::BoundsCheckMinMax(min, aChild->GetMaxSize(aState));
  1.1079 +            
  1.1080 +            AddMargin(aChild, max);
  1.1081 +
  1.1082 +            // our width now becomes the new size
  1.1083 +
  1.1084 +            if (isHorizontal)
  1.1085 +              childActualWidth = max.width < childActualWidth ? max.width : childActualWidth;
  1.1086 +            else
  1.1087 +              childActualWidth = max.height < childActualWidth ? max.height : childActualWidth;
  1.1088 +
  1.1089 +            if (childActualWidth > childLayoutWidth) {
  1.1090 +               aChildComputedSize->size = childActualWidth;
  1.1091 +               aChildBoxSize->min = childActualWidth;
  1.1092 +               if (aChildBoxSize->pref < childActualWidth)
  1.1093 +                  aChildBoxSize->pref = childActualWidth;
  1.1094 +               if (aChildBoxSize->max < childActualWidth)
  1.1095 +                  aChildBoxSize->max = childActualWidth;
  1.1096 +
  1.1097 +              // if we have flexible elements with us then reflex things. Otherwise we can skip doing it.
  1.1098 +              if (aFlexes > 0) {
  1.1099 +                InvalidateComputedSizes(aComputedBoxSizes);
  1.1100 +
  1.1101 +                nsComputedBoxSize* node = aComputedBoxSizes;
  1.1102 +                aChildComputedSize->resized = true;
  1.1103 +
  1.1104 +                while(node) {
  1.1105 +                  if (node->resized)
  1.1106 +                      node->valid = true;
  1.1107 +                
  1.1108 +                  node = node->next;
  1.1109 +                }
  1.1110 +
  1.1111 +                recompute = true;
  1.1112 +                aFinished = false;
  1.1113 +              } else {
  1.1114 +                containingWidth += aChildComputedSize->size - childLayoutWidth;
  1.1115 +              }              
  1.1116 +            }
  1.1117 +      }
  1.1118 +
  1.1119 +      if (recompute)
  1.1120 +            ComputeChildSizes(aBox, aState, containingWidth, aBoxSizes, aComputedBoxSizes);
  1.1121 +
  1.1122 +      if (!childCurrentRect.IsEqualInterior(aChildActualRect)) {
  1.1123 +        // the childRect includes the margin
  1.1124 +        // make sure we remove it before setting 
  1.1125 +        // the bounds.
  1.1126 +        nsMargin margin(0,0,0,0);
  1.1127 +        aChild->GetMargin(margin);
  1.1128 +        nsRect rect(aChildActualRect);
  1.1129 +        if (rect.width >= margin.left + margin.right && rect.height >= margin.top + margin.bottom) 
  1.1130 +          rect.Deflate(margin);
  1.1131 +
  1.1132 +        aChild->SetBounds(aState, rect);
  1.1133 +        aChild->Layout(aState);
  1.1134 +      }
  1.1135 +
  1.1136 +}
  1.1137 +
  1.1138 +void
  1.1139 +nsSprocketLayout::InvalidateComputedSizes(nsComputedBoxSize* aComputedBoxSizes)
  1.1140 +{
  1.1141 +  while(aComputedBoxSizes) {
  1.1142 +      aComputedBoxSizes->valid = false;
  1.1143 +      aComputedBoxSizes = aComputedBoxSizes->next;
  1.1144 +  }
  1.1145 +}
  1.1146 +
  1.1147 +void
  1.1148 +nsSprocketLayout::ComputeChildSizes(nsIFrame* aBox,
  1.1149 +                           nsBoxLayoutState& aState, 
  1.1150 +                           nscoord& aGivenSize, 
  1.1151 +                           nsBoxSize* aBoxSizes, 
  1.1152 +                           nsComputedBoxSize*& aComputedBoxSizes)
  1.1153 +{  
  1.1154 +
  1.1155 +  //nscoord onePixel = aState.PresContext()->IntScaledPixelsToTwips(1);
  1.1156 +
  1.1157 +  int32_t sizeRemaining            = aGivenSize;
  1.1158 +  int32_t spacerConstantsRemaining = 0;
  1.1159 +
  1.1160 +   // ----- calculate the spacers constants and the size remaining -----
  1.1161 +
  1.1162 +  if (!aComputedBoxSizes)
  1.1163 +      aComputedBoxSizes = new (aState) nsComputedBoxSize();
  1.1164 +  
  1.1165 +  nsBoxSize*         boxSizes = aBoxSizes;
  1.1166 +  nsComputedBoxSize* computedBoxSizes = aComputedBoxSizes;
  1.1167 +  int32_t count = 0;
  1.1168 +  int32_t validCount = 0;
  1.1169 +
  1.1170 +  while (boxSizes) 
  1.1171 +  {
  1.1172 +
  1.1173 +    NS_ASSERTION((boxSizes->min <= boxSizes->pref && boxSizes->pref <= boxSizes->max),"bad pref, min, max size");
  1.1174 +
  1.1175 +    
  1.1176 +     // ignore collapsed children
  1.1177 +  //  if (boxSizes->collapsed) 
  1.1178 +  //  {
  1.1179 +    //  computedBoxSizes->valid = true;
  1.1180 +    //  computedBoxSizes->size = boxSizes->pref;
  1.1181 +     // validCount++;
  1.1182 +  //      boxSizes->flex = 0;
  1.1183 +   // }// else {
  1.1184 +    
  1.1185 +      if (computedBoxSizes->valid) { 
  1.1186 +        sizeRemaining -= computedBoxSizes->size;
  1.1187 +        validCount++;
  1.1188 +      } else {
  1.1189 +          if (boxSizes->flex == 0)
  1.1190 +          {
  1.1191 +            computedBoxSizes->valid = true;
  1.1192 +            computedBoxSizes->size = boxSizes->pref;
  1.1193 +            validCount++;
  1.1194 +          }
  1.1195 +
  1.1196 +          spacerConstantsRemaining += boxSizes->flex;
  1.1197 +          sizeRemaining -= boxSizes->pref;
  1.1198 +      }
  1.1199 +
  1.1200 +      sizeRemaining -= (boxSizes->left + boxSizes->right);
  1.1201 +
  1.1202 +    //} 
  1.1203 +
  1.1204 +    boxSizes = boxSizes->next;
  1.1205 +
  1.1206 +    if (boxSizes && !computedBoxSizes->next) 
  1.1207 +      computedBoxSizes->next = new (aState) nsComputedBoxSize();
  1.1208 +
  1.1209 +    computedBoxSizes = computedBoxSizes->next;
  1.1210 +    count++;
  1.1211 +  }
  1.1212 +
  1.1213 +  // everything accounted for?
  1.1214 +  if (validCount < count)
  1.1215 +  {
  1.1216 +    // ----- Ok we are give a size to fit into so stretch or squeeze to fit
  1.1217 +    // ----- Make sure we look at our min and max size
  1.1218 +    bool limit = true;
  1.1219 +    for (int pass=1; true == limit; pass++) 
  1.1220 +    {
  1.1221 +      limit = false;
  1.1222 +      boxSizes = aBoxSizes;
  1.1223 +      computedBoxSizes = aComputedBoxSizes;
  1.1224 +
  1.1225 +      while (boxSizes) { 
  1.1226 +
  1.1227 +        // ignore collapsed spacers
  1.1228 +
  1.1229 +   //    if (!boxSizes->collapsed) {
  1.1230 +      
  1.1231 +          nscoord pref = 0;
  1.1232 +          nscoord max  = NS_INTRINSICSIZE;
  1.1233 +          nscoord min  = 0;
  1.1234 +          nscoord flex = 0;
  1.1235 +
  1.1236 +          pref = boxSizes->pref;
  1.1237 +          min  = boxSizes->min;
  1.1238 +          max  = boxSizes->max;
  1.1239 +          flex = boxSizes->flex;
  1.1240 +
  1.1241 +          // ----- look at our min and max limits make sure we aren't too small or too big -----
  1.1242 +          if (!computedBoxSizes->valid) {
  1.1243 +            int32_t newSize = pref + int32_t(int64_t(sizeRemaining) * flex / spacerConstantsRemaining);
  1.1244 +
  1.1245 +            if (newSize<=min) {
  1.1246 +              computedBoxSizes->size = min;
  1.1247 +              computedBoxSizes->valid = true;
  1.1248 +              spacerConstantsRemaining -= flex;
  1.1249 +              sizeRemaining += pref;
  1.1250 +              sizeRemaining -= min;
  1.1251 +              limit = true;
  1.1252 +            } else if (newSize>=max) {
  1.1253 +              computedBoxSizes->size = max;
  1.1254 +              computedBoxSizes->valid = true;
  1.1255 +              spacerConstantsRemaining -= flex;
  1.1256 +              sizeRemaining += pref;
  1.1257 +              sizeRemaining -= max;
  1.1258 +              limit = true;
  1.1259 +            }
  1.1260 +          }
  1.1261 +       // }
  1.1262 +        boxSizes         = boxSizes->next;
  1.1263 +        computedBoxSizes = computedBoxSizes->next;
  1.1264 +      }
  1.1265 +    }
  1.1266 +  }          
  1.1267 +
  1.1268 +  // ---- once we have removed and min and max issues just stretch us out in the remaining space
  1.1269 +  // ---- or shrink us. Depends on the size remaining and the spacer constants
  1.1270 +  aGivenSize = 0;
  1.1271 +  boxSizes = aBoxSizes;
  1.1272 +  computedBoxSizes = aComputedBoxSizes;
  1.1273 +
  1.1274 +  while (boxSizes) { 
  1.1275 +
  1.1276 +    // ignore collapsed spacers
  1.1277 +  //  if (!(boxSizes && boxSizes->collapsed)) {
  1.1278 +    
  1.1279 +      nscoord pref = 0;
  1.1280 +      nscoord flex = 0;
  1.1281 +      pref = boxSizes->pref;
  1.1282 +      flex = boxSizes->flex;
  1.1283 +
  1.1284 +      if (!computedBoxSizes->valid) {
  1.1285 +        computedBoxSizes->size = pref + int32_t(int64_t(sizeRemaining) * flex / spacerConstantsRemaining);
  1.1286 +        computedBoxSizes->valid = true;
  1.1287 +      }
  1.1288 +
  1.1289 +      aGivenSize += (boxSizes->left + boxSizes->right);
  1.1290 +      aGivenSize += computedBoxSizes->size;
  1.1291 +
  1.1292 +   // }
  1.1293 +
  1.1294 +    boxSizes         = boxSizes->next;
  1.1295 +    computedBoxSizes = computedBoxSizes->next;
  1.1296 +  }
  1.1297 +}
  1.1298 +
  1.1299 +
  1.1300 +nsSize
  1.1301 +nsSprocketLayout::GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aState)
  1.1302 +{
  1.1303 +   nsSize vpref (0, 0); 
  1.1304 +   bool isHorizontal = IsHorizontal(aBox);
  1.1305 +
  1.1306 +   nscoord biggestPref = 0;
  1.1307 +
  1.1308 +   // run through all the children and get their min, max, and preferred sizes
  1.1309 +   // return us the size of the box
  1.1310 +
  1.1311 +   nsIFrame* child = aBox->GetChildBox();
  1.1312 +   nsFrameState frameState = nsFrameState(0);
  1.1313 +   GetFrameState(aBox, frameState);
  1.1314 +   bool isEqual = !!(frameState & NS_STATE_EQUAL_SIZE);
  1.1315 +   int32_t count = 0;
  1.1316 +   
  1.1317 +   while (child) 
  1.1318 +   {  
  1.1319 +      // ignore collapsed children
  1.1320 +      if (!child->IsCollapsed())
  1.1321 +      {
  1.1322 +        nsSize pref = child->GetPrefSize(aState);
  1.1323 +        AddMargin(child, pref);
  1.1324 +
  1.1325 +        if (isEqual) {
  1.1326 +          if (isHorizontal)
  1.1327 +          {
  1.1328 +            if (pref.width > biggestPref)
  1.1329 +              biggestPref = pref.width;
  1.1330 +          } else {
  1.1331 +            if (pref.height > biggestPref)
  1.1332 +              biggestPref = pref.height;
  1.1333 +          }
  1.1334 +        }
  1.1335 +
  1.1336 +        AddLargestSize(vpref, pref, isHorizontal);
  1.1337 +        count++;
  1.1338 +      }
  1.1339 +
  1.1340 +      child = child->GetNextBox();
  1.1341 +   }
  1.1342 +
  1.1343 +   if (isEqual) {
  1.1344 +      if (isHorizontal)
  1.1345 +         vpref.width = biggestPref*count;
  1.1346 +      else
  1.1347 +         vpref.height = biggestPref*count;
  1.1348 +   }
  1.1349 +    
  1.1350 +   // now add our border and padding
  1.1351 +   AddBorderAndPadding(aBox, vpref);
  1.1352 +
  1.1353 +  return vpref;
  1.1354 +}
  1.1355 +
  1.1356 +nsSize
  1.1357 +nsSprocketLayout::GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aState)
  1.1358 +{
  1.1359 +   nsSize minSize (0, 0);
  1.1360 +   bool isHorizontal = IsHorizontal(aBox);
  1.1361 +
  1.1362 +   nscoord biggestMin = 0;
  1.1363 +
  1.1364 +
  1.1365 +   // run through all the children and get their min, max, and preferred sizes
  1.1366 +   // return us the size of the box
  1.1367 +
  1.1368 +   nsIFrame* child = aBox->GetChildBox();
  1.1369 +   nsFrameState frameState = nsFrameState(0);
  1.1370 +   GetFrameState(aBox, frameState);
  1.1371 +   bool isEqual = !!(frameState & NS_STATE_EQUAL_SIZE);
  1.1372 +   int32_t count = 0;
  1.1373 +
  1.1374 +   while (child) 
  1.1375 +   {  
  1.1376 +       // ignore collapsed children
  1.1377 +      if (!child->IsCollapsed())
  1.1378 +      {
  1.1379 +        nsSize min = child->GetMinSize(aState);
  1.1380 +        nsSize pref(0,0);
  1.1381 +        
  1.1382 +        // if the child is not flexible then
  1.1383 +        // its min size is its pref size.
  1.1384 +        if (child->GetFlex(aState) == 0) {
  1.1385 +            pref = child->GetPrefSize(aState);
  1.1386 +            if (isHorizontal)
  1.1387 +               min.width = pref.width;
  1.1388 +            else
  1.1389 +               min.height = pref.height;
  1.1390 +        }
  1.1391 +
  1.1392 +        if (isEqual) {
  1.1393 +          if (isHorizontal)
  1.1394 +          {
  1.1395 +            if (min.width > biggestMin)
  1.1396 +              biggestMin = min.width;
  1.1397 +          } else {
  1.1398 +            if (min.height > biggestMin)
  1.1399 +              biggestMin = min.height;
  1.1400 +          }
  1.1401 +        }
  1.1402 +
  1.1403 +        AddMargin(child, min);
  1.1404 +        AddLargestSize(minSize, min, isHorizontal);
  1.1405 +        count++;
  1.1406 +      }
  1.1407 +
  1.1408 +      child = child->GetNextBox();
  1.1409 +   }
  1.1410 +
  1.1411 +   
  1.1412 +   if (isEqual) {
  1.1413 +      if (isHorizontal)
  1.1414 +         minSize.width = biggestMin*count;
  1.1415 +      else
  1.1416 +         minSize.height = biggestMin*count;
  1.1417 +   }
  1.1418 +
  1.1419 +  // now add our border and padding
  1.1420 +  AddBorderAndPadding(aBox, minSize);
  1.1421 +
  1.1422 +  return minSize;
  1.1423 +}
  1.1424 +
  1.1425 +nsSize
  1.1426 +nsSprocketLayout::GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aState)
  1.1427 +{
  1.1428 +
  1.1429 +  bool isHorizontal = IsHorizontal(aBox);
  1.1430 +
  1.1431 +   nscoord smallestMax = NS_INTRINSICSIZE;
  1.1432 +   nsSize maxSize (NS_INTRINSICSIZE, NS_INTRINSICSIZE);
  1.1433 +
  1.1434 +   // run through all the children and get their min, max, and preferred sizes
  1.1435 +   // return us the size of the box
  1.1436 +
  1.1437 +   nsIFrame* child = aBox->GetChildBox();
  1.1438 +   nsFrameState frameState = nsFrameState(0);
  1.1439 +   GetFrameState(aBox, frameState);
  1.1440 +   bool isEqual = !!(frameState & NS_STATE_EQUAL_SIZE);
  1.1441 +   int32_t count = 0;
  1.1442 +
  1.1443 +   while (child) 
  1.1444 +   {  
  1.1445 +      // ignore collapsed children
  1.1446 +      if (!child->IsCollapsed())
  1.1447 +      {
  1.1448 +        // if completely redefined don't even ask our child for its size.
  1.1449 +        nsSize min = child->GetMinSize(aState);
  1.1450 +        nsSize max = nsBox::BoundsCheckMinMax(min, child->GetMaxSize(aState));
  1.1451 +
  1.1452 +        AddMargin(child, max);
  1.1453 +        AddSmallestSize(maxSize, max, isHorizontal);
  1.1454 +
  1.1455 +        if (isEqual) {
  1.1456 +          if (isHorizontal)
  1.1457 +          {
  1.1458 +            if (max.width < smallestMax)
  1.1459 +              smallestMax = max.width;
  1.1460 +          } else {
  1.1461 +            if (max.height < smallestMax)
  1.1462 +              smallestMax = max.height;
  1.1463 +          }
  1.1464 +        }
  1.1465 +        count++;
  1.1466 +      }
  1.1467 +
  1.1468 +      child = child->GetNextBox();
  1.1469 +   }
  1.1470 +
  1.1471 +   if (isEqual) {
  1.1472 +     if (isHorizontal) {
  1.1473 +         if (smallestMax != NS_INTRINSICSIZE)
  1.1474 +            maxSize.width = smallestMax*count;
  1.1475 +         else
  1.1476 +            maxSize.width = NS_INTRINSICSIZE;
  1.1477 +     } else {
  1.1478 +         if (smallestMax != NS_INTRINSICSIZE)
  1.1479 +            maxSize.height = smallestMax*count;
  1.1480 +         else
  1.1481 +            maxSize.height = NS_INTRINSICSIZE;
  1.1482 +     }
  1.1483 +   }
  1.1484 +
  1.1485 +  // now add our border and padding
  1.1486 +  AddBorderAndPadding(aBox, maxSize);
  1.1487 +
  1.1488 +  return maxSize;
  1.1489 +}
  1.1490 +
  1.1491 +
  1.1492 +nscoord
  1.1493 +nsSprocketLayout::GetAscent(nsIFrame* aBox, nsBoxLayoutState& aState)
  1.1494 +{
  1.1495 +   nscoord vAscent = 0;
  1.1496 +
  1.1497 +   bool isHorizontal = IsHorizontal(aBox);
  1.1498 +
  1.1499 +   // run through all the children and get their min, max, and preferred sizes
  1.1500 +   // return us the size of the box
  1.1501 +   
  1.1502 +   nsIFrame* child = aBox->GetChildBox();
  1.1503 +   
  1.1504 +   while (child) 
  1.1505 +   {  
  1.1506 +      // ignore collapsed children
  1.1507 +      //if (!child->IsCollapsed())
  1.1508 +      //{
  1.1509 +        // if completely redefined don't even ask our child for its size.
  1.1510 +        nscoord ascent = child->GetBoxAscent(aState);
  1.1511 +
  1.1512 +        nsMargin margin;
  1.1513 +        child->GetMargin(margin);
  1.1514 +        ascent += margin.top;
  1.1515 +
  1.1516 +        if (isHorizontal)
  1.1517 +        {
  1.1518 +          if (ascent > vAscent)
  1.1519 +            vAscent = ascent;
  1.1520 +        } else {
  1.1521 +          if (vAscent == 0)
  1.1522 +            vAscent = ascent;
  1.1523 +        }
  1.1524 +      //}
  1.1525 +
  1.1526 +      child = child->GetNextBox();      
  1.1527 +   }
  1.1528 +
  1.1529 +   nsMargin borderPadding;
  1.1530 +   aBox->GetBorderAndPadding(borderPadding);
  1.1531 +
  1.1532 +   return vAscent + borderPadding.top;
  1.1533 +}
  1.1534 +
  1.1535 +void
  1.1536 +nsSprocketLayout::SetLargestSize(nsSize& aSize1, const nsSize& aSize2, bool aIsHorizontal)
  1.1537 +{
  1.1538 +  if (aIsHorizontal)
  1.1539 +  {
  1.1540 +    if (aSize1.height < aSize2.height)
  1.1541 +       aSize1.height = aSize2.height;
  1.1542 +  } else {
  1.1543 +    if (aSize1.width < aSize2.width)
  1.1544 +       aSize1.width = aSize2.width;
  1.1545 +  }
  1.1546 +}
  1.1547 +
  1.1548 +void
  1.1549 +nsSprocketLayout::SetSmallestSize(nsSize& aSize1, const nsSize& aSize2, bool aIsHorizontal)
  1.1550 +{
  1.1551 +  if (aIsHorizontal)
  1.1552 +  {
  1.1553 +    if (aSize1.height > aSize2.height)
  1.1554 +       aSize1.height = aSize2.height;
  1.1555 +  } else {
  1.1556 +    if (aSize1.width > aSize2.width)
  1.1557 +       aSize1.width = aSize2.width;
  1.1558 +
  1.1559 +  }
  1.1560 +}
  1.1561 +
  1.1562 +void
  1.1563 +nsSprocketLayout::AddLargestSize(nsSize& aSize, const nsSize& aSizeToAdd, bool aIsHorizontal)
  1.1564 +{
  1.1565 +  if (aIsHorizontal)
  1.1566 +    AddCoord(aSize.width, aSizeToAdd.width);
  1.1567 +  else
  1.1568 +    AddCoord(aSize.height, aSizeToAdd.height);
  1.1569 +
  1.1570 +  SetLargestSize(aSize, aSizeToAdd, aIsHorizontal);
  1.1571 +}
  1.1572 +
  1.1573 +void
  1.1574 +nsSprocketLayout::AddCoord(nscoord& aCoord, nscoord aCoordToAdd)
  1.1575 +{
  1.1576 +  if (aCoord != NS_INTRINSICSIZE) 
  1.1577 +  {
  1.1578 +    if (aCoordToAdd == NS_INTRINSICSIZE)
  1.1579 +      aCoord = aCoordToAdd;
  1.1580 +    else
  1.1581 +      aCoord += aCoordToAdd;
  1.1582 +  }
  1.1583 +}
  1.1584 +void
  1.1585 +nsSprocketLayout::AddSmallestSize(nsSize& aSize, const nsSize& aSizeToAdd, bool aIsHorizontal)
  1.1586 +{
  1.1587 +  if (aIsHorizontal)
  1.1588 +    AddCoord(aSize.width, aSizeToAdd.width);
  1.1589 +  else
  1.1590 +    AddCoord(aSize.height, aSizeToAdd.height);
  1.1591 +    
  1.1592 +  SetSmallestSize(aSize, aSizeToAdd, aIsHorizontal);
  1.1593 +}
  1.1594 +
  1.1595 +bool
  1.1596 +nsSprocketLayout::GetDefaultFlex(int32_t& aFlex)
  1.1597 +{
  1.1598 +    aFlex = 0;
  1.1599 +    return true;
  1.1600 +}
  1.1601 +
  1.1602 +nsComputedBoxSize::nsComputedBoxSize()
  1.1603 +{
  1.1604 +  resized = false;
  1.1605 +  valid = false;
  1.1606 +  size = 0;
  1.1607 +  next = nullptr;
  1.1608 +}
  1.1609 +
  1.1610 +nsBoxSize::nsBoxSize()
  1.1611 +{
  1.1612 +  pref = 0;
  1.1613 +  min = 0;
  1.1614 +  max = NS_INTRINSICSIZE;
  1.1615 +  collapsed = false;
  1.1616 +  left = 0;
  1.1617 +  right = 0;
  1.1618 +  flex = 0;
  1.1619 +  next = nullptr;
  1.1620 +  bogus = false;
  1.1621 +}
  1.1622 +
  1.1623 +
  1.1624 +void* 
  1.1625 +nsBoxSize::operator new(size_t sz, nsBoxLayoutState& aState) CPP_THROW_NEW
  1.1626 +{
  1.1627 +  return mozilla::AutoStackArena::Allocate(sz);
  1.1628 +}
  1.1629 +
  1.1630 +
  1.1631 +void 
  1.1632 +nsBoxSize::operator delete(void* aPtr, size_t sz)
  1.1633 +{
  1.1634 +}
  1.1635 +
  1.1636 +
  1.1637 +void* 
  1.1638 +nsComputedBoxSize::operator new(size_t sz, nsBoxLayoutState& aState) CPP_THROW_NEW
  1.1639 +{
  1.1640 +   return mozilla::AutoStackArena::Allocate(sz);
  1.1641 +}
  1.1642 +
  1.1643 +void 
  1.1644 +nsComputedBoxSize::operator delete(void* aPtr, size_t sz)
  1.1645 +{
  1.1646 +}

mercurial