layout/xul/nsSprocketLayout.cpp

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 //
michael@0 7 // Eric Vaughan
michael@0 8 // Netscape Communications
michael@0 9 //
michael@0 10 // See documentation in associated header file
michael@0 11 //
michael@0 12
michael@0 13 #include "nsBoxLayoutState.h"
michael@0 14 #include "nsSprocketLayout.h"
michael@0 15 #include "nsPresContext.h"
michael@0 16 #include "nsCOMPtr.h"
michael@0 17 #include "nsIContent.h"
michael@0 18 #include "nsIPresShell.h"
michael@0 19 #include "nsContainerFrame.h"
michael@0 20 #include "nsBoxFrame.h"
michael@0 21 #include "StackArena.h"
michael@0 22 #include "mozilla/Likely.h"
michael@0 23 #include <algorithm>
michael@0 24
michael@0 25 nsBoxLayout* nsSprocketLayout::gInstance = nullptr;
michael@0 26
michael@0 27 //#define DEBUG_GROW
michael@0 28
michael@0 29 #define DEBUG_SPRING_SIZE 8
michael@0 30 #define DEBUG_BORDER_SIZE 2
michael@0 31 #define COIL_SIZE 8
michael@0 32
michael@0 33
michael@0 34 nsresult
michael@0 35 NS_NewSprocketLayout( nsIPresShell* aPresShell, nsCOMPtr<nsBoxLayout>& aNewLayout)
michael@0 36 {
michael@0 37 if (!nsSprocketLayout::gInstance) {
michael@0 38 nsSprocketLayout::gInstance = new nsSprocketLayout();
michael@0 39 NS_IF_ADDREF(nsSprocketLayout::gInstance);
michael@0 40 }
michael@0 41 // we have not instance variables so just return our static one.
michael@0 42 aNewLayout = nsSprocketLayout::gInstance;
michael@0 43 return NS_OK;
michael@0 44 }
michael@0 45
michael@0 46 /*static*/ void
michael@0 47 nsSprocketLayout::Shutdown()
michael@0 48 {
michael@0 49 NS_IF_RELEASE(gInstance);
michael@0 50 }
michael@0 51
michael@0 52 nsSprocketLayout::nsSprocketLayout()
michael@0 53 {
michael@0 54 }
michael@0 55
michael@0 56 bool
michael@0 57 nsSprocketLayout::IsHorizontal(nsIFrame* aBox)
michael@0 58 {
michael@0 59 return (aBox->GetStateBits() & NS_STATE_IS_HORIZONTAL) != 0;
michael@0 60 }
michael@0 61
michael@0 62 void
michael@0 63 nsSprocketLayout::GetFrameState(nsIFrame* aBox, nsFrameState& aState)
michael@0 64 {
michael@0 65 aState = aBox->GetStateBits();
michael@0 66 }
michael@0 67
michael@0 68 static uint8_t
michael@0 69 GetFrameDirection(nsIFrame* aBox)
michael@0 70 {
michael@0 71 return aBox->StyleVisibility()->mDirection;
michael@0 72 }
michael@0 73
michael@0 74 static void
michael@0 75 HandleBoxPack(nsIFrame* aBox, const nsFrameState& aFrameState, nscoord& aX, nscoord& aY,
michael@0 76 const nsRect& aOriginalRect, const nsRect& aClientRect)
michael@0 77 {
michael@0 78 // In the normal direction we lay out our kids in the positive direction (e.g., |x| will get
michael@0 79 // bigger for a horizontal box, and |y| will get bigger for a vertical box). In the reverse
michael@0 80 // direction, the opposite is true. We'll be laying out each child at a smaller |x| or
michael@0 81 // |y|.
michael@0 82 uint8_t frameDirection = GetFrameDirection(aBox);
michael@0 83
michael@0 84 if (aFrameState & NS_STATE_IS_HORIZONTAL) {
michael@0 85 if (aFrameState & NS_STATE_IS_DIRECTION_NORMAL) {
michael@0 86 // The normal direction. |x| increases as we move through our children.
michael@0 87 aX = aClientRect.x;
michael@0 88 }
michael@0 89 else {
michael@0 90 // The reverse direction. |x| decreases as we move through our children.
michael@0 91 aX = aClientRect.x + aOriginalRect.width;
michael@0 92 }
michael@0 93 // |y| is always in the normal direction in horizontal boxes
michael@0 94 aY = aClientRect.y;
michael@0 95 }
michael@0 96 else {
michael@0 97 // take direction property into account for |x| in vertical boxes
michael@0 98 if (frameDirection == NS_STYLE_DIRECTION_LTR) {
michael@0 99 // The normal direction. |x| increases as we move through our children.
michael@0 100 aX = aClientRect.x;
michael@0 101 }
michael@0 102 else {
michael@0 103 // The reverse direction. |x| decreases as we move through our children.
michael@0 104 aX = aClientRect.x + aOriginalRect.width;
michael@0 105 }
michael@0 106 if (aFrameState & NS_STATE_IS_DIRECTION_NORMAL) {
michael@0 107 // The normal direction. |y| increases as we move through our children.
michael@0 108 aY = aClientRect.y;
michael@0 109 }
michael@0 110 else {
michael@0 111 // The reverse direction. |y| decreases as we move through our children.
michael@0 112 aY = aClientRect.y + aOriginalRect.height;
michael@0 113 }
michael@0 114 }
michael@0 115
michael@0 116 // Get our pack/alignment information.
michael@0 117 nsIFrame::Halignment halign = aBox->GetHAlign();
michael@0 118 nsIFrame::Valignment valign = aBox->GetVAlign();
michael@0 119
michael@0 120 // The following code handles box PACKING. Packing comes into play in the case where the computed size for
michael@0 121 // all of our children (now stored in our client rect) is smaller than the size available for
michael@0 122 // the box (stored in |aOriginalRect|).
michael@0 123 //
michael@0 124 // Here we adjust our |x| and |y| variables accordingly so that we start at the beginning,
michael@0 125 // middle, or end of the box.
michael@0 126 //
michael@0 127 // XXXdwh JUSTIFY needs to be implemented!
michael@0 128 if (aFrameState & NS_STATE_IS_HORIZONTAL) {
michael@0 129 switch(halign) {
michael@0 130 case nsBoxFrame::hAlign_Left:
michael@0 131 break; // Nothing to do. The default initialized us properly.
michael@0 132
michael@0 133 case nsBoxFrame::hAlign_Center:
michael@0 134 if (aFrameState & NS_STATE_IS_DIRECTION_NORMAL)
michael@0 135 aX += (aOriginalRect.width - aClientRect.width)/2;
michael@0 136 else
michael@0 137 aX -= (aOriginalRect.width - aClientRect.width)/2;
michael@0 138 break;
michael@0 139
michael@0 140 case nsBoxFrame::hAlign_Right:
michael@0 141 if (aFrameState & NS_STATE_IS_DIRECTION_NORMAL)
michael@0 142 aX += (aOriginalRect.width - aClientRect.width);
michael@0 143 else
michael@0 144 aX -= (aOriginalRect.width - aClientRect.width);
michael@0 145 break; // Nothing to do for the reverse dir. The default initialized us properly.
michael@0 146 }
michael@0 147 } else {
michael@0 148 switch(valign) {
michael@0 149 case nsBoxFrame::vAlign_Top:
michael@0 150 case nsBoxFrame::vAlign_BaseLine: // This value is technically impossible to specify for pack.
michael@0 151 break; // Don't do anything. We were initialized correctly.
michael@0 152
michael@0 153 case nsBoxFrame::vAlign_Middle:
michael@0 154 if (aFrameState & NS_STATE_IS_DIRECTION_NORMAL)
michael@0 155 aY += (aOriginalRect.height - aClientRect.height)/2;
michael@0 156 else
michael@0 157 aY -= (aOriginalRect.height - aClientRect.height)/2;
michael@0 158 break;
michael@0 159
michael@0 160 case nsBoxFrame::vAlign_Bottom:
michael@0 161 if (aFrameState & NS_STATE_IS_DIRECTION_NORMAL)
michael@0 162 aY += (aOriginalRect.height - aClientRect.height);
michael@0 163 else
michael@0 164 aY -= (aOriginalRect.height - aClientRect.height);
michael@0 165 break;
michael@0 166 }
michael@0 167 }
michael@0 168 }
michael@0 169
michael@0 170 NS_IMETHODIMP
michael@0 171 nsSprocketLayout::Layout(nsIFrame* aBox, nsBoxLayoutState& aState)
michael@0 172 {
michael@0 173 // See if we are collapsed. If we are, then simply iterate over all our
michael@0 174 // children and give them a rect of 0 width and height.
michael@0 175 if (aBox->IsCollapsed()) {
michael@0 176 nsIFrame* child = aBox->GetChildBox();
michael@0 177 while(child)
michael@0 178 {
michael@0 179 nsBoxFrame::LayoutChildAt(aState, child, nsRect(0,0,0,0));
michael@0 180 child = child->GetNextBox();
michael@0 181 }
michael@0 182 return NS_OK;
michael@0 183 }
michael@0 184
michael@0 185 nsBoxLayoutState::AutoReflowDepth depth(aState);
michael@0 186 mozilla::AutoStackArena arena;
michael@0 187
michael@0 188 // ----- figure out our size ----------
michael@0 189 const nsSize originalSize = aBox->GetSize();
michael@0 190
michael@0 191 // -- make sure we remove our border and padding ----
michael@0 192 nsRect clientRect;
michael@0 193 aBox->GetClientRect(clientRect);
michael@0 194
michael@0 195 // |originalClientRect| represents the rect of the entire box (excluding borders
michael@0 196 // and padding). We store it here because we're going to use |clientRect| to hold
michael@0 197 // the required size for all our kids. As an example, consider an hbox with a
michael@0 198 // specified width of 300. If the kids total only 150 pixels of width, then
michael@0 199 // we have 150 pixels left over. |clientRect| is going to hold a width of 150 and
michael@0 200 // is going to be adjusted based off the value of the PACK property. If flexible
michael@0 201 // objects are in the box, then the two rects will match.
michael@0 202 nsRect originalClientRect(clientRect);
michael@0 203
michael@0 204 // The frame state contains cached knowledge about our box, such as our orientation
michael@0 205 // and direction.
michael@0 206 nsFrameState frameState = nsFrameState(0);
michael@0 207 GetFrameState(aBox, frameState);
michael@0 208
michael@0 209 // Build a list of our children's desired sizes and computed sizes
michael@0 210 nsBoxSize* boxSizes = nullptr;
michael@0 211 nsComputedBoxSize* computedBoxSizes = nullptr;
michael@0 212
michael@0 213 nscoord min = 0;
michael@0 214 nscoord max = 0;
michael@0 215 int32_t flexes = 0;
michael@0 216 PopulateBoxSizes(aBox, aState, boxSizes, min, max, flexes);
michael@0 217
michael@0 218 // The |size| variable will hold the total size of children along the axis of
michael@0 219 // the box. Continuing with the example begun in the comment above, size would
michael@0 220 // be 150 pixels.
michael@0 221 nscoord size = clientRect.width;
michael@0 222 if (!IsHorizontal(aBox))
michael@0 223 size = clientRect.height;
michael@0 224 ComputeChildSizes(aBox, aState, size, boxSizes, computedBoxSizes);
michael@0 225
michael@0 226 // After the call to ComputeChildSizes, the |size| variable contains the
michael@0 227 // total required size of all the children. We adjust our clientRect in the
michael@0 228 // appropriate dimension to match this size. In our example, we now assign
michael@0 229 // 150 pixels into the clientRect.width.
michael@0 230 //
michael@0 231 // The variables |min| and |max| hold the minimum required size box must be
michael@0 232 // in the OPPOSITE orientation, e.g., for a horizontal box, |min| is the minimum
michael@0 233 // height we require to enclose our children, and |max| is the maximum height
michael@0 234 // required to enclose our children.
michael@0 235 if (IsHorizontal(aBox)) {
michael@0 236 clientRect.width = size;
michael@0 237 if (clientRect.height < min)
michael@0 238 clientRect.height = min;
michael@0 239
michael@0 240 if (frameState & NS_STATE_AUTO_STRETCH) {
michael@0 241 if (clientRect.height > max)
michael@0 242 clientRect.height = max;
michael@0 243 }
michael@0 244 } else {
michael@0 245 clientRect.height = size;
michael@0 246 if (clientRect.width < min)
michael@0 247 clientRect.width = min;
michael@0 248
michael@0 249 if (frameState & NS_STATE_AUTO_STRETCH) {
michael@0 250 if (clientRect.width > max)
michael@0 251 clientRect.width = max;
michael@0 252 }
michael@0 253 }
michael@0 254
michael@0 255 // With the sizes computed, now it's time to lay out our children.
michael@0 256 bool finished;
michael@0 257 nscoord passes = 0;
michael@0 258
michael@0 259 // We flow children at their preferred locations (along with the appropriate computed flex).
michael@0 260 // After we flow a child, it is possible that the child will change its size. If/when this happens,
michael@0 261 // we have to do another pass. Typically only 2 passes are required, but the code is prepared to
michael@0 262 // do as many passes as are necessary to achieve equilibrium.
michael@0 263 nscoord x = 0;
michael@0 264 nscoord y = 0;
michael@0 265 nscoord origX = 0;
michael@0 266 nscoord origY = 0;
michael@0 267
michael@0 268 // |childResized| lets us know if a child changed its size after we attempted to lay it out at
michael@0 269 // the specified size. If this happens, we usually have to do another pass.
michael@0 270 bool childResized = false;
michael@0 271
michael@0 272 // |passes| stores our number of passes. If for any reason we end up doing more than, say, 10
michael@0 273 // passes, we assert to indicate that something is seriously screwed up.
michael@0 274 passes = 0;
michael@0 275 do
michael@0 276 {
michael@0 277 #ifdef DEBUG_REFLOW
michael@0 278 if (passes > 0) {
michael@0 279 AddIndents();
michael@0 280 printf("ChildResized doing pass: %d\n", passes);
michael@0 281 }
michael@0 282 #endif
michael@0 283
michael@0 284 // Always assume that we're done. This will change if, for example, children don't stay
michael@0 285 // the same size after being flowed.
michael@0 286 finished = true;
michael@0 287
michael@0 288 // Handle box packing.
michael@0 289 HandleBoxPack(aBox, frameState, x, y, originalClientRect, clientRect);
michael@0 290
michael@0 291 // Now that packing is taken care of we set up a few additional
michael@0 292 // tracking variables.
michael@0 293 origX = x;
michael@0 294 origY = y;
michael@0 295
michael@0 296 nscoord nextX = x;
michael@0 297 nscoord nextY = y;
michael@0 298
michael@0 299 // Now we iterate over our box children and our box size lists in
michael@0 300 // parallel. For each child, we look at its sizes and figure out
michael@0 301 // where to place it.
michael@0 302 nsComputedBoxSize* childComputedBoxSize = computedBoxSizes;
michael@0 303 nsBoxSize* childBoxSize = boxSizes;
michael@0 304
michael@0 305 nsIFrame* child = aBox->GetChildBox();
michael@0 306
michael@0 307 int32_t count = 0;
michael@0 308 while (child || (childBoxSize && childBoxSize->bogus))
michael@0 309 {
michael@0 310 // If for some reason, our lists are not the same length, we guard
michael@0 311 // by bailing out of the loop.
michael@0 312 if (childBoxSize == nullptr) {
michael@0 313 NS_NOTREACHED("Lists not the same length.");
michael@0 314 break;
michael@0 315 }
michael@0 316
michael@0 317 nscoord width = clientRect.width;
michael@0 318 nscoord height = clientRect.height;
michael@0 319
michael@0 320 if (!childBoxSize->bogus) {
michael@0 321 // We have a valid box size entry. This entry already contains information about our
michael@0 322 // sizes along the axis of the box (e.g., widths in a horizontal box). If our default
michael@0 323 // ALIGN is not stretch, however, then we also need to know the child's size along the
michael@0 324 // opposite axis.
michael@0 325 if (!(frameState & NS_STATE_AUTO_STRETCH)) {
michael@0 326 nsSize prefSize = child->GetPrefSize(aState);
michael@0 327 nsSize minSize = child->GetMinSize(aState);
michael@0 328 nsSize maxSize = child->GetMaxSize(aState);
michael@0 329 prefSize = nsBox::BoundsCheck(minSize, prefSize, maxSize);
michael@0 330
michael@0 331 AddMargin(child, prefSize);
michael@0 332 width = std::min(prefSize.width, originalClientRect.width);
michael@0 333 height = std::min(prefSize.height, originalClientRect.height);
michael@0 334 }
michael@0 335 }
michael@0 336
michael@0 337 // Obtain the computed size along the axis of the box for this child from the computedBoxSize entry.
michael@0 338 // We store the result in |width| for horizontal boxes and |height| for vertical boxes.
michael@0 339 if (frameState & NS_STATE_IS_HORIZONTAL)
michael@0 340 width = childComputedBoxSize->size;
michael@0 341 else
michael@0 342 height = childComputedBoxSize->size;
michael@0 343
michael@0 344 // Adjust our x/y for the left/right spacing.
michael@0 345 if (frameState & NS_STATE_IS_HORIZONTAL) {
michael@0 346 if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
michael@0 347 x += (childBoxSize->left);
michael@0 348 else
michael@0 349 x -= (childBoxSize->right);
michael@0 350 } else {
michael@0 351 if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
michael@0 352 y += (childBoxSize->left);
michael@0 353 else
michael@0 354 y -= (childBoxSize->right);
michael@0 355 }
michael@0 356
michael@0 357 nextX = x;
michael@0 358 nextY = y;
michael@0 359
michael@0 360 // Now we build a child rect.
michael@0 361 nscoord rectX = x;
michael@0 362 nscoord rectY = y;
michael@0 363 if (!(frameState & NS_STATE_IS_DIRECTION_NORMAL)) {
michael@0 364 if (frameState & NS_STATE_IS_HORIZONTAL)
michael@0 365 rectX -= width;
michael@0 366 else
michael@0 367 rectY -= height;
michael@0 368 }
michael@0 369
michael@0 370 // We now create an accurate child rect based off our computed size information.
michael@0 371 nsRect childRect(rectX, rectY, width, height);
michael@0 372
michael@0 373 // Sanity check against our clientRect. It is possible that a child specified
michael@0 374 // a size that is too large to fit. If that happens, then we have to grow
michael@0 375 // our client rect. Remember, clientRect is not the total rect of the enclosing
michael@0 376 // box. It currently holds our perception of how big the children needed to
michael@0 377 // be.
michael@0 378 if (childRect.width > clientRect.width)
michael@0 379 clientRect.width = childRect.width;
michael@0 380
michael@0 381 if (childRect.height > clientRect.height)
michael@0 382 clientRect.height = childRect.height;
michael@0 383
michael@0 384 // Either |nextX| or |nextY| is updated by this function call, according
michael@0 385 // to our axis.
michael@0 386 ComputeChildsNextPosition(aBox, x, y, nextX, nextY, childRect);
michael@0 387
michael@0 388 // Now we further update our nextX/Y along our axis.
michael@0 389 // We also set childRect.y/x along the opposite axis appropriately for a
michael@0 390 // stretch alignment. (Non-stretch alignment is handled below.)
michael@0 391 if (frameState & NS_STATE_IS_HORIZONTAL) {
michael@0 392 if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
michael@0 393 nextX += (childBoxSize->right);
michael@0 394 else
michael@0 395 nextX -= (childBoxSize->left);
michael@0 396 childRect.y = originalClientRect.y;
michael@0 397 }
michael@0 398 else {
michael@0 399 if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
michael@0 400 nextY += (childBoxSize->right);
michael@0 401 else
michael@0 402 nextY -= (childBoxSize->left);
michael@0 403 childRect.x = originalClientRect.x;
michael@0 404 }
michael@0 405
michael@0 406 // If we encounter a completely bogus box size, we just leave this child completely
michael@0 407 // alone and continue through the loop to the next child.
michael@0 408 if (childBoxSize->bogus)
michael@0 409 {
michael@0 410 childComputedBoxSize = childComputedBoxSize->next;
michael@0 411 childBoxSize = childBoxSize->next;
michael@0 412 count++;
michael@0 413 x = nextX;
michael@0 414 y = nextY;
michael@0 415 continue;
michael@0 416 }
michael@0 417
michael@0 418 nsMargin margin(0,0,0,0);
michael@0 419
michael@0 420 bool layout = true;
michael@0 421
michael@0 422 // Deflate the rect of our child by its margin.
michael@0 423 child->GetMargin(margin);
michael@0 424 childRect.Deflate(margin);
michael@0 425 if (childRect.width < 0)
michael@0 426 childRect.width = 0;
michael@0 427 if (childRect.height < 0)
michael@0 428 childRect.height = 0;
michael@0 429
michael@0 430 // Now we're trying to figure out if we have to lay out this child, i.e., to call
michael@0 431 // the child's Layout method.
michael@0 432 if (passes > 0) {
michael@0 433 layout = false;
michael@0 434 } else {
michael@0 435 // Always perform layout if we are dirty or have dirty children
michael@0 436 if (!NS_SUBTREE_DIRTY(child))
michael@0 437 layout = false;
michael@0 438 }
michael@0 439
michael@0 440 nsRect oldRect(child->GetRect());
michael@0 441
michael@0 442 // Non-stretch alignment will be handled in AlignChildren(), so don't
michael@0 443 // change child out-of-axis positions yet.
michael@0 444 if (!(frameState & NS_STATE_AUTO_STRETCH)) {
michael@0 445 if (frameState & NS_STATE_IS_HORIZONTAL) {
michael@0 446 childRect.y = oldRect.y;
michael@0 447 } else {
michael@0 448 childRect.x = oldRect.x;
michael@0 449 }
michael@0 450 }
michael@0 451
michael@0 452 // We computed a childRect. Now we want to set the bounds of the child to be that rect.
michael@0 453 // If our old rect is different, then we know our size changed and we cache that fact
michael@0 454 // in the |sizeChanged| variable.
michael@0 455
michael@0 456 child->SetBounds(aState, childRect);
michael@0 457 bool sizeChanged = (childRect.width != oldRect.width ||
michael@0 458 childRect.height != oldRect.height);
michael@0 459
michael@0 460 if (sizeChanged) {
michael@0 461 // Our size is different. Sanity check against our maximum allowed size to ensure
michael@0 462 // we didn't exceed it.
michael@0 463 nsSize minSize = child->GetMinSize(aState);
michael@0 464 nsSize maxSize = child->GetMaxSize(aState);
michael@0 465 maxSize = nsBox::BoundsCheckMinMax(minSize, maxSize);
michael@0 466
michael@0 467 // make sure the size is in our max size.
michael@0 468 if (childRect.width > maxSize.width)
michael@0 469 childRect.width = maxSize.width;
michael@0 470
michael@0 471 if (childRect.height > maxSize.height)
michael@0 472 childRect.height = maxSize.height;
michael@0 473
michael@0 474 // set it again
michael@0 475 child->SetBounds(aState, childRect);
michael@0 476 }
michael@0 477
michael@0 478 // If we already determined that layout was required or if our size has changed, then
michael@0 479 // we make sure to call layout on the child, since its children may need to be shifted
michael@0 480 // around as a result of the size change.
michael@0 481 if (layout || sizeChanged)
michael@0 482 child->Layout(aState);
michael@0 483
michael@0 484 // If the child was a block or inline (e.g., HTML) it may have changed its rect *during* layout.
michael@0 485 // We have to check for this.
michael@0 486 nsRect newChildRect(child->GetRect());
michael@0 487
michael@0 488 if (!newChildRect.IsEqualInterior(childRect)) {
michael@0 489 #ifdef DEBUG_GROW
michael@0 490 child->DumpBox(stdout);
michael@0 491 printf(" GREW from (%d,%d) -> (%d,%d)\n", childRect.width, childRect.height, newChildRect.width, newChildRect.height);
michael@0 492 #endif
michael@0 493 newChildRect.Inflate(margin);
michael@0 494 childRect.Inflate(margin);
michael@0 495
michael@0 496 // The child changed size during layout. The ChildResized method handles this
michael@0 497 // scenario.
michael@0 498 ChildResized(aBox,
michael@0 499 aState,
michael@0 500 child,
michael@0 501 childBoxSize,
michael@0 502 childComputedBoxSize,
michael@0 503 boxSizes,
michael@0 504 computedBoxSizes,
michael@0 505 childRect,
michael@0 506 newChildRect,
michael@0 507 clientRect,
michael@0 508 flexes,
michael@0 509 finished);
michael@0 510
michael@0 511 // We note that a child changed size, which means that another pass will be required.
michael@0 512 childResized = true;
michael@0 513
michael@0 514 // Now that a child resized, it's entirely possible that OUR rect is too small. Now we
michael@0 515 // ensure that |originalClientRect| is grown to accommodate the size of |clientRect|.
michael@0 516 if (clientRect.width > originalClientRect.width)
michael@0 517 originalClientRect.width = clientRect.width;
michael@0 518
michael@0 519 if (clientRect.height > originalClientRect.height)
michael@0 520 originalClientRect.height = clientRect.height;
michael@0 521
michael@0 522 if (!(frameState & NS_STATE_IS_DIRECTION_NORMAL)) {
michael@0 523 // Our childRect had its XMost() or YMost() (depending on our layout
michael@0 524 // direction), positioned at a certain point. Ensure that the
michael@0 525 // newChildRect satisfies the same constraint. Note that this is
michael@0 526 // just equivalent to adjusting the x/y by the difference in
michael@0 527 // width/height between childRect and newChildRect. So we don't need
michael@0 528 // to reaccount for the left and right of the box layout state again.
michael@0 529 if (frameState & NS_STATE_IS_HORIZONTAL)
michael@0 530 newChildRect.x = childRect.XMost() - newChildRect.width;
michael@0 531 else
michael@0 532 newChildRect.y = childRect.YMost() - newChildRect.height;
michael@0 533 }
michael@0 534
michael@0 535 // If the child resized then recompute its position.
michael@0 536 ComputeChildsNextPosition(aBox, x, y, nextX, nextY, newChildRect);
michael@0 537
michael@0 538 if (newChildRect.width >= margin.left + margin.right && newChildRect.height >= margin.top + margin.bottom)
michael@0 539 newChildRect.Deflate(margin);
michael@0 540
michael@0 541 if (childRect.width >= margin.left + margin.right && childRect.height >= margin.top + margin.bottom)
michael@0 542 childRect.Deflate(margin);
michael@0 543
michael@0 544 child->SetBounds(aState, newChildRect);
michael@0 545
michael@0 546 // If we are the first box that changed size, then we don't need to do a second pass
michael@0 547 if (count == 0)
michael@0 548 finished = true;
michael@0 549 }
michael@0 550
michael@0 551 // Now update our x/y finally.
michael@0 552 x = nextX;
michael@0 553 y = nextY;
michael@0 554
michael@0 555 // Move to the next child.
michael@0 556 childComputedBoxSize = childComputedBoxSize->next;
michael@0 557 childBoxSize = childBoxSize->next;
michael@0 558
michael@0 559 child = child->GetNextBox();
michael@0 560 count++;
michael@0 561 }
michael@0 562
michael@0 563 // Sanity-checking code to ensure we don't do an infinite # of passes.
michael@0 564 passes++;
michael@0 565 NS_ASSERTION(passes < 10, "A Box's child is constantly growing!!!!!");
michael@0 566 if (passes > 10)
michael@0 567 break;
michael@0 568 } while (false == finished);
michael@0 569
michael@0 570 // Get rid of our size lists.
michael@0 571 while(boxSizes)
michael@0 572 {
michael@0 573 nsBoxSize* toDelete = boxSizes;
michael@0 574 boxSizes = boxSizes->next;
michael@0 575 delete toDelete;
michael@0 576 }
michael@0 577
michael@0 578 while(computedBoxSizes)
michael@0 579 {
michael@0 580 nsComputedBoxSize* toDelete = computedBoxSizes;
michael@0 581 computedBoxSizes = computedBoxSizes->next;
michael@0 582 delete toDelete;
michael@0 583 }
michael@0 584
michael@0 585 if (childResized) {
michael@0 586 // See if one of our children forced us to get bigger
michael@0 587 nsRect tmpClientRect(originalClientRect);
michael@0 588 nsMargin bp(0,0,0,0);
michael@0 589 aBox->GetBorderAndPadding(bp);
michael@0 590 tmpClientRect.Inflate(bp);
michael@0 591
michael@0 592 if (tmpClientRect.width > originalSize.width || tmpClientRect.height > originalSize.height)
michael@0 593 {
michael@0 594 // if it did reset our bounds.
michael@0 595 nsRect bounds(aBox->GetRect());
michael@0 596 if (tmpClientRect.width > originalSize.width)
michael@0 597 bounds.width = tmpClientRect.width;
michael@0 598
michael@0 599 if (tmpClientRect.height > originalSize.height)
michael@0 600 bounds.height = tmpClientRect.height;
michael@0 601
michael@0 602 aBox->SetBounds(aState, bounds);
michael@0 603 }
michael@0 604 }
michael@0 605
michael@0 606 // Because our size grew, we now have to readjust because of box packing. Repack
michael@0 607 // in order to update our x and y to the correct values.
michael@0 608 HandleBoxPack(aBox, frameState, x, y, originalClientRect, clientRect);
michael@0 609
michael@0 610 // Compare against our original x and y and only worry about adjusting the children if
michael@0 611 // we really did have to change the positions because of packing (typically for 'center'
michael@0 612 // or 'end' pack values).
michael@0 613 if (x != origX || y != origY) {
michael@0 614 nsIFrame* child = aBox->GetChildBox();
michael@0 615
michael@0 616 // reposition all our children
michael@0 617 while (child)
michael@0 618 {
michael@0 619 nsRect childRect(child->GetRect());
michael@0 620 childRect.x += (x - origX);
michael@0 621 childRect.y += (y - origY);
michael@0 622 child->SetBounds(aState, childRect);
michael@0 623 child = child->GetNextBox();
michael@0 624 }
michael@0 625 }
michael@0 626
michael@0 627 // Perform out-of-axis alignment for non-stretch alignments
michael@0 628 if (!(frameState & NS_STATE_AUTO_STRETCH)) {
michael@0 629 AlignChildren(aBox, aState);
michael@0 630 }
michael@0 631
michael@0 632 // That's it! If you made it this far without having a nervous breakdown,
michael@0 633 // congratulations! Go get yourself a beer.
michael@0 634 return NS_OK;
michael@0 635 }
michael@0 636
michael@0 637 void
michael@0 638 nsSprocketLayout::PopulateBoxSizes(nsIFrame* aBox, nsBoxLayoutState& aState, nsBoxSize*& aBoxSizes, nscoord& aMinSize, nscoord& aMaxSize, int32_t& aFlexes)
michael@0 639 {
michael@0 640 // used for the equal size flag
michael@0 641 nscoord biggestPrefWidth = 0;
michael@0 642 nscoord biggestMinWidth = 0;
michael@0 643 nscoord smallestMaxWidth = NS_INTRINSICSIZE;
michael@0 644
michael@0 645 nsFrameState frameState = nsFrameState(0);
michael@0 646 GetFrameState(aBox, frameState);
michael@0 647
michael@0 648 //if (frameState & NS_STATE_CURRENTLY_IN_DEBUG)
michael@0 649 // printf("In debug\n");
michael@0 650
michael@0 651 aMinSize = 0;
michael@0 652 aMaxSize = NS_INTRINSICSIZE;
michael@0 653
michael@0 654 bool isHorizontal;
michael@0 655
michael@0 656 if (IsHorizontal(aBox))
michael@0 657 isHorizontal = true;
michael@0 658 else
michael@0 659 isHorizontal = false;
michael@0 660
michael@0 661 // this is a nice little optimization
michael@0 662 // it turns out that if we only have 1 flexable child
michael@0 663 // then it does not matter what its preferred size is
michael@0 664 // there is nothing to flex it relative. This is great
michael@0 665 // because we can avoid asking for a preferred size in this
michael@0 666 // case. Why is this good? Well you might have html inside it
michael@0 667 // and asking html for its preferred size is rather expensive.
michael@0 668 // so we can just optimize it out this way.
michael@0 669
michael@0 670 // set flexes
michael@0 671 nsIFrame* child = aBox->GetChildBox();
michael@0 672
michael@0 673 aFlexes = 0;
michael@0 674 nsBoxSize* currentBox = nullptr;
michael@0 675
michael@0 676 #if 0
michael@0 677 nsBoxSize* start = aBoxSizes;
michael@0 678
michael@0 679 while(child)
michael@0 680 {
michael@0 681 // ok if we started with a list move down the list
michael@0 682 // until we reach the end. Then start looking at childen.
michael@0 683 // This feature is used extensively for Grid.
michael@0 684 nscoord flex = 0;
michael@0 685
michael@0 686 if (!start) {
michael@0 687 if (!currentBox) {
michael@0 688 aBoxSizes = new (aState) nsBoxSize();
michael@0 689 currentBox = aBoxSizes;
michael@0 690 } else {
michael@0 691 currentBox->next = new (aState) nsBoxSize();
michael@0 692 currentBox = currentBox->next;
michael@0 693 }
michael@0 694
michael@0 695
michael@0 696 flex = child->GetFlex(aState);
michael@0 697
michael@0 698 currentBox->flex = flex;
michael@0 699 currentBox->collapsed = child->IsCollapsed();
michael@0 700 } else {
michael@0 701 flex = start->flex;
michael@0 702 start = start->next;
michael@0 703 }
michael@0 704
michael@0 705 if (flex > 0)
michael@0 706 aFlexes++;
michael@0 707
michael@0 708 child = child->GetNextBox();
michael@0 709 }
michael@0 710 #endif
michael@0 711
michael@0 712 // get pref, min, max
michael@0 713 child = aBox->GetChildBox();
michael@0 714 currentBox = aBoxSizes;
michael@0 715 nsBoxSize* last = nullptr;
michael@0 716
michael@0 717 nscoord maxFlex = 0;
michael@0 718 int32_t childCount = 0;
michael@0 719
michael@0 720 while(child)
michael@0 721 {
michael@0 722 while (currentBox && currentBox->bogus) {
michael@0 723 last = currentBox;
michael@0 724 currentBox = currentBox->next;
michael@0 725 }
michael@0 726 ++childCount;
michael@0 727 nsSize pref(0,0);
michael@0 728 nsSize minSize(0,0);
michael@0 729 nsSize maxSize(NS_INTRINSICSIZE,NS_INTRINSICSIZE);
michael@0 730 nscoord ascent = 0;
michael@0 731 bool collapsed = child->IsCollapsed();
michael@0 732
michael@0 733 if (!collapsed) {
michael@0 734 // only one flexible child? Cool we will just make its preferred size
michael@0 735 // 0 then and not even have to ask for it.
michael@0 736 //if (flexes != 1) {
michael@0 737
michael@0 738 pref = child->GetPrefSize(aState);
michael@0 739 minSize = child->GetMinSize(aState);
michael@0 740 maxSize = nsBox::BoundsCheckMinMax(minSize, child->GetMaxSize(aState));
michael@0 741 ascent = child->GetBoxAscent(aState);
michael@0 742 nsMargin margin;
michael@0 743 child->GetMargin(margin);
michael@0 744 ascent += margin.top;
michael@0 745 //}
michael@0 746
michael@0 747 pref = nsBox::BoundsCheck(minSize, pref, maxSize);
michael@0 748
michael@0 749 AddMargin(child, pref);
michael@0 750 AddMargin(child, minSize);
michael@0 751 AddMargin(child, maxSize);
michael@0 752 }
michael@0 753
michael@0 754 if (!currentBox) {
michael@0 755 // create one.
michael@0 756 currentBox = new (aState) nsBoxSize();
michael@0 757 if (!aBoxSizes) {
michael@0 758 aBoxSizes = currentBox;
michael@0 759 last = aBoxSizes;
michael@0 760 } else {
michael@0 761 last->next = currentBox;
michael@0 762 last = currentBox;
michael@0 763 }
michael@0 764
michael@0 765 nscoord minWidth;
michael@0 766 nscoord maxWidth;
michael@0 767 nscoord prefWidth;
michael@0 768
michael@0 769 // get sizes from child
michael@0 770 if (isHorizontal) {
michael@0 771 minWidth = minSize.width;
michael@0 772 maxWidth = maxSize.width;
michael@0 773 prefWidth = pref.width;
michael@0 774 } else {
michael@0 775 minWidth = minSize.height;
michael@0 776 maxWidth = maxSize.height;
michael@0 777 prefWidth = pref.height;
michael@0 778 }
michael@0 779
michael@0 780 nscoord flex = child->GetFlex(aState);
michael@0 781
michael@0 782 // set them if you collapsed you are not flexible.
michael@0 783 if (collapsed) {
michael@0 784 currentBox->flex = 0;
michael@0 785 }
michael@0 786 else {
michael@0 787 if (flex > maxFlex) {
michael@0 788 maxFlex = flex;
michael@0 789 }
michael@0 790 currentBox->flex = flex;
michael@0 791 }
michael@0 792
michael@0 793 // we specified all our children are equal size;
michael@0 794 if (frameState & NS_STATE_EQUAL_SIZE) {
michael@0 795
michael@0 796 if (prefWidth > biggestPrefWidth)
michael@0 797 biggestPrefWidth = prefWidth;
michael@0 798
michael@0 799 if (minWidth > biggestMinWidth)
michael@0 800 biggestMinWidth = minWidth;
michael@0 801
michael@0 802 if (maxWidth < smallestMaxWidth)
michael@0 803 smallestMaxWidth = maxWidth;
michael@0 804 } else { // not we can set our children right now.
michael@0 805 currentBox->pref = prefWidth;
michael@0 806 currentBox->min = minWidth;
michael@0 807 currentBox->max = maxWidth;
michael@0 808 }
michael@0 809
michael@0 810 NS_ASSERTION(minWidth <= prefWidth && prefWidth <= maxWidth,"Bad min, pref, max widths!");
michael@0 811
michael@0 812 }
michael@0 813
michael@0 814 if (!isHorizontal) {
michael@0 815 if (minSize.width > aMinSize)
michael@0 816 aMinSize = minSize.width;
michael@0 817
michael@0 818 if (maxSize.width < aMaxSize)
michael@0 819 aMaxSize = maxSize.width;
michael@0 820
michael@0 821 } else {
michael@0 822 if (minSize.height > aMinSize)
michael@0 823 aMinSize = minSize.height;
michael@0 824
michael@0 825 if (maxSize.height < aMaxSize)
michael@0 826 aMaxSize = maxSize.height;
michael@0 827 }
michael@0 828
michael@0 829 currentBox->collapsed = collapsed;
michael@0 830 aFlexes += currentBox->flex;
michael@0 831
michael@0 832 child = child->GetNextBox();
michael@0 833
michael@0 834 last = currentBox;
michael@0 835 currentBox = currentBox->next;
michael@0 836
michael@0 837 }
michael@0 838
michael@0 839 if (childCount > 0) {
michael@0 840 nscoord maxAllowedFlex = nscoord_MAX / childCount;
michael@0 841
michael@0 842 if (MOZ_UNLIKELY(maxFlex > maxAllowedFlex)) {
michael@0 843 // clamp all the flexes
michael@0 844 currentBox = aBoxSizes;
michael@0 845 while (currentBox) {
michael@0 846 currentBox->flex = std::min(currentBox->flex, maxAllowedFlex);
michael@0 847 currentBox = currentBox->next;
michael@0 848 }
michael@0 849 }
michael@0 850 }
michael@0 851 #ifdef DEBUG
michael@0 852 else {
michael@0 853 NS_ASSERTION(maxFlex == 0, "How did that happen?");
michael@0 854 }
michael@0 855 #endif
michael@0 856
michael@0 857 // we specified all our children are equal size;
michael@0 858 if (frameState & NS_STATE_EQUAL_SIZE) {
michael@0 859 smallestMaxWidth = std::max(smallestMaxWidth, biggestMinWidth);
michael@0 860 biggestPrefWidth = nsBox::BoundsCheck(biggestMinWidth, biggestPrefWidth, smallestMaxWidth);
michael@0 861
michael@0 862 currentBox = aBoxSizes;
michael@0 863
michael@0 864 while(currentBox)
michael@0 865 {
michael@0 866 if (!currentBox->collapsed) {
michael@0 867 currentBox->pref = biggestPrefWidth;
michael@0 868 currentBox->min = biggestMinWidth;
michael@0 869 currentBox->max = smallestMaxWidth;
michael@0 870 } else {
michael@0 871 currentBox->pref = 0;
michael@0 872 currentBox->min = 0;
michael@0 873 currentBox->max = 0;
michael@0 874 }
michael@0 875 currentBox = currentBox->next;
michael@0 876 }
michael@0 877 }
michael@0 878
michael@0 879 }
michael@0 880
michael@0 881 void
michael@0 882 nsSprocketLayout::ComputeChildsNextPosition(nsIFrame* aBox,
michael@0 883 const nscoord& aCurX,
michael@0 884 const nscoord& aCurY,
michael@0 885 nscoord& aNextX,
michael@0 886 nscoord& aNextY,
michael@0 887 const nsRect& aCurrentChildSize)
michael@0 888 {
michael@0 889 // Get the position along the box axis for the child.
michael@0 890 // The out-of-axis position is not set.
michael@0 891 nsFrameState frameState = nsFrameState(0);
michael@0 892 GetFrameState(aBox, frameState);
michael@0 893
michael@0 894 if (IsHorizontal(aBox)) {
michael@0 895 // horizontal box's children.
michael@0 896 if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
michael@0 897 aNextX = aCurX + aCurrentChildSize.width;
michael@0 898 else
michael@0 899 aNextX = aCurX - aCurrentChildSize.width;
michael@0 900
michael@0 901 } else {
michael@0 902 // vertical box's children.
michael@0 903 if (frameState & NS_STATE_IS_DIRECTION_NORMAL)
michael@0 904 aNextY = aCurY + aCurrentChildSize.height;
michael@0 905 else
michael@0 906 aNextY = aCurY - aCurrentChildSize.height;
michael@0 907 }
michael@0 908 }
michael@0 909
michael@0 910 void
michael@0 911 nsSprocketLayout::AlignChildren(nsIFrame* aBox,
michael@0 912 nsBoxLayoutState& aState)
michael@0 913 {
michael@0 914 nsFrameState frameState = nsFrameState(0);
michael@0 915 GetFrameState(aBox, frameState);
michael@0 916 bool isHorizontal = (frameState & NS_STATE_IS_HORIZONTAL) != 0;
michael@0 917 nsRect clientRect;
michael@0 918 aBox->GetClientRect(clientRect);
michael@0 919
michael@0 920 NS_PRECONDITION(!(frameState & NS_STATE_AUTO_STRETCH),
michael@0 921 "Only AlignChildren() with non-stretch alignment");
michael@0 922
michael@0 923 // These are only calculated if needed
michael@0 924 nsIFrame::Halignment halign;
michael@0 925 nsIFrame::Valignment valign;
michael@0 926 nscoord maxAscent;
michael@0 927 bool isLTR;
michael@0 928
michael@0 929 if (isHorizontal) {
michael@0 930 valign = aBox->GetVAlign();
michael@0 931 if (valign == nsBoxFrame::vAlign_BaseLine) {
michael@0 932 maxAscent = aBox->GetBoxAscent(aState);
michael@0 933 }
michael@0 934 } else {
michael@0 935 isLTR = GetFrameDirection(aBox) == NS_STYLE_DIRECTION_LTR;
michael@0 936 halign = aBox->GetHAlign();
michael@0 937 }
michael@0 938
michael@0 939 nsIFrame* child = aBox->GetChildBox();
michael@0 940 while (child) {
michael@0 941
michael@0 942 nsMargin margin;
michael@0 943 child->GetMargin(margin);
michael@0 944 nsRect childRect = child->GetRect();
michael@0 945
michael@0 946 if (isHorizontal) {
michael@0 947 const nscoord startAlign = clientRect.y + margin.top;
michael@0 948 const nscoord endAlign =
michael@0 949 clientRect.YMost() - margin.bottom - childRect.height;
michael@0 950
michael@0 951 nscoord y;
michael@0 952 switch (valign) {
michael@0 953 case nsBoxFrame::vAlign_Top:
michael@0 954 y = startAlign;
michael@0 955 break;
michael@0 956 case nsBoxFrame::vAlign_Middle:
michael@0 957 // Should this center the border box?
michael@0 958 // This centers the margin box, the historical behavior.
michael@0 959 y = (startAlign + endAlign) / 2;
michael@0 960 break;
michael@0 961 case nsBoxFrame::vAlign_Bottom:
michael@0 962 y = endAlign;
michael@0 963 break;
michael@0 964 case nsBoxFrame::vAlign_BaseLine:
michael@0 965 // Alignments don't force the box to grow (only sizes do),
michael@0 966 // so keep the children within the box.
michael@0 967 y = maxAscent - child->GetBoxAscent(aState);
michael@0 968 y = std::max(startAlign, y);
michael@0 969 y = std::min(y, endAlign);
michael@0 970 break;
michael@0 971 }
michael@0 972
michael@0 973 childRect.y = y;
michael@0 974
michael@0 975 } else { // vertical box
michael@0 976 const nscoord leftAlign = clientRect.x + margin.left;
michael@0 977 const nscoord rightAlign =
michael@0 978 clientRect.XMost() - margin.right - childRect.width;
michael@0 979
michael@0 980 nscoord x;
michael@0 981 switch (halign) {
michael@0 982 case nsBoxFrame::hAlign_Left: // start
michael@0 983 x = isLTR ? leftAlign : rightAlign;
michael@0 984 break;
michael@0 985 case nsBoxFrame::hAlign_Center:
michael@0 986 x = (leftAlign + rightAlign) / 2;
michael@0 987 break;
michael@0 988 case nsBoxFrame::hAlign_Right: // end
michael@0 989 x = isLTR ? rightAlign : leftAlign;
michael@0 990 break;
michael@0 991 }
michael@0 992
michael@0 993 childRect.x = x;
michael@0 994 }
michael@0 995
michael@0 996 if (childRect.TopLeft() != child->GetPosition()) {
michael@0 997 child->SetBounds(aState, childRect);
michael@0 998 }
michael@0 999
michael@0 1000 child = child->GetNextBox();
michael@0 1001 }
michael@0 1002 }
michael@0 1003
michael@0 1004 void
michael@0 1005 nsSprocketLayout::ChildResized(nsIFrame* aBox,
michael@0 1006 nsBoxLayoutState& aState,
michael@0 1007 nsIFrame* aChild,
michael@0 1008 nsBoxSize* aChildBoxSize,
michael@0 1009 nsComputedBoxSize* aChildComputedSize,
michael@0 1010 nsBoxSize* aBoxSizes,
michael@0 1011 nsComputedBoxSize* aComputedBoxSizes,
michael@0 1012 const nsRect& aChildLayoutRect,
michael@0 1013 nsRect& aChildActualRect,
michael@0 1014 nsRect& aContainingRect,
michael@0 1015 int32_t aFlexes,
michael@0 1016 bool& aFinished)
michael@0 1017
michael@0 1018 {
michael@0 1019 nsRect childCurrentRect(aChildLayoutRect);
michael@0 1020
michael@0 1021 bool isHorizontal = IsHorizontal(aBox);
michael@0 1022 nscoord childLayoutWidth = GET_WIDTH(aChildLayoutRect,isHorizontal);
michael@0 1023 nscoord& childActualWidth = GET_WIDTH(aChildActualRect,isHorizontal);
michael@0 1024 nscoord& containingWidth = GET_WIDTH(aContainingRect,isHorizontal);
michael@0 1025
michael@0 1026 //nscoord childLayoutHeight = GET_HEIGHT(aChildLayoutRect,isHorizontal);
michael@0 1027 nscoord& childActualHeight = GET_HEIGHT(aChildActualRect,isHorizontal);
michael@0 1028 nscoord& containingHeight = GET_HEIGHT(aContainingRect,isHorizontal);
michael@0 1029
michael@0 1030 bool recompute = false;
michael@0 1031
michael@0 1032 // if we are a horizontal box see if the child will fit inside us.
michael@0 1033 if ( childActualHeight > containingHeight) {
michael@0 1034 // if we are a horizontal box and the child is bigger than our height
michael@0 1035
michael@0 1036 // ok if the height changed then we need to reflow everyone but us at the new height
michael@0 1037 // so we will set the changed index to be us. And signal that we need a new pass.
michael@0 1038
michael@0 1039 nsSize min = aChild->GetMinSize(aState);
michael@0 1040 nsSize max = nsBox::BoundsCheckMinMax(min, aChild->GetMaxSize(aState));
michael@0 1041 AddMargin(aChild, max);
michael@0 1042
michael@0 1043 if (isHorizontal)
michael@0 1044 childActualHeight = max.height < childActualHeight ? max.height : childActualHeight;
michael@0 1045 else
michael@0 1046 childActualHeight = max.width < childActualHeight ? max.width : childActualHeight;
michael@0 1047
michael@0 1048 // only set if it changes
michael@0 1049 if (childActualHeight > containingHeight) {
michael@0 1050 containingHeight = childActualHeight;
michael@0 1051
michael@0 1052 // remember we do not need to clear the resized list because changing the height of a horizontal box
michael@0 1053 // will not affect the width of any of its children because block flow left to right, top to bottom. Just trust me
michael@0 1054 // on this one.
michael@0 1055 aFinished = false;
michael@0 1056
michael@0 1057 // only recompute if there are flexes.
michael@0 1058 if (aFlexes > 0) {
michael@0 1059 // relayout everything
michael@0 1060 recompute = true;
michael@0 1061 InvalidateComputedSizes(aComputedBoxSizes);
michael@0 1062 nsComputedBoxSize* node = aComputedBoxSizes;
michael@0 1063
michael@0 1064 while(node) {
michael@0 1065 node->resized = false;
michael@0 1066 node = node->next;
michael@0 1067 }
michael@0 1068
michael@0 1069 }
michael@0 1070 }
michael@0 1071 }
michael@0 1072
michael@0 1073 if (childActualWidth > childLayoutWidth) {
michael@0 1074 nsSize min = aChild->GetMinSize(aState);
michael@0 1075 nsSize max = nsBox::BoundsCheckMinMax(min, aChild->GetMaxSize(aState));
michael@0 1076
michael@0 1077 AddMargin(aChild, max);
michael@0 1078
michael@0 1079 // our width now becomes the new size
michael@0 1080
michael@0 1081 if (isHorizontal)
michael@0 1082 childActualWidth = max.width < childActualWidth ? max.width : childActualWidth;
michael@0 1083 else
michael@0 1084 childActualWidth = max.height < childActualWidth ? max.height : childActualWidth;
michael@0 1085
michael@0 1086 if (childActualWidth > childLayoutWidth) {
michael@0 1087 aChildComputedSize->size = childActualWidth;
michael@0 1088 aChildBoxSize->min = childActualWidth;
michael@0 1089 if (aChildBoxSize->pref < childActualWidth)
michael@0 1090 aChildBoxSize->pref = childActualWidth;
michael@0 1091 if (aChildBoxSize->max < childActualWidth)
michael@0 1092 aChildBoxSize->max = childActualWidth;
michael@0 1093
michael@0 1094 // if we have flexible elements with us then reflex things. Otherwise we can skip doing it.
michael@0 1095 if (aFlexes > 0) {
michael@0 1096 InvalidateComputedSizes(aComputedBoxSizes);
michael@0 1097
michael@0 1098 nsComputedBoxSize* node = aComputedBoxSizes;
michael@0 1099 aChildComputedSize->resized = true;
michael@0 1100
michael@0 1101 while(node) {
michael@0 1102 if (node->resized)
michael@0 1103 node->valid = true;
michael@0 1104
michael@0 1105 node = node->next;
michael@0 1106 }
michael@0 1107
michael@0 1108 recompute = true;
michael@0 1109 aFinished = false;
michael@0 1110 } else {
michael@0 1111 containingWidth += aChildComputedSize->size - childLayoutWidth;
michael@0 1112 }
michael@0 1113 }
michael@0 1114 }
michael@0 1115
michael@0 1116 if (recompute)
michael@0 1117 ComputeChildSizes(aBox, aState, containingWidth, aBoxSizes, aComputedBoxSizes);
michael@0 1118
michael@0 1119 if (!childCurrentRect.IsEqualInterior(aChildActualRect)) {
michael@0 1120 // the childRect includes the margin
michael@0 1121 // make sure we remove it before setting
michael@0 1122 // the bounds.
michael@0 1123 nsMargin margin(0,0,0,0);
michael@0 1124 aChild->GetMargin(margin);
michael@0 1125 nsRect rect(aChildActualRect);
michael@0 1126 if (rect.width >= margin.left + margin.right && rect.height >= margin.top + margin.bottom)
michael@0 1127 rect.Deflate(margin);
michael@0 1128
michael@0 1129 aChild->SetBounds(aState, rect);
michael@0 1130 aChild->Layout(aState);
michael@0 1131 }
michael@0 1132
michael@0 1133 }
michael@0 1134
michael@0 1135 void
michael@0 1136 nsSprocketLayout::InvalidateComputedSizes(nsComputedBoxSize* aComputedBoxSizes)
michael@0 1137 {
michael@0 1138 while(aComputedBoxSizes) {
michael@0 1139 aComputedBoxSizes->valid = false;
michael@0 1140 aComputedBoxSizes = aComputedBoxSizes->next;
michael@0 1141 }
michael@0 1142 }
michael@0 1143
michael@0 1144 void
michael@0 1145 nsSprocketLayout::ComputeChildSizes(nsIFrame* aBox,
michael@0 1146 nsBoxLayoutState& aState,
michael@0 1147 nscoord& aGivenSize,
michael@0 1148 nsBoxSize* aBoxSizes,
michael@0 1149 nsComputedBoxSize*& aComputedBoxSizes)
michael@0 1150 {
michael@0 1151
michael@0 1152 //nscoord onePixel = aState.PresContext()->IntScaledPixelsToTwips(1);
michael@0 1153
michael@0 1154 int32_t sizeRemaining = aGivenSize;
michael@0 1155 int32_t spacerConstantsRemaining = 0;
michael@0 1156
michael@0 1157 // ----- calculate the spacers constants and the size remaining -----
michael@0 1158
michael@0 1159 if (!aComputedBoxSizes)
michael@0 1160 aComputedBoxSizes = new (aState) nsComputedBoxSize();
michael@0 1161
michael@0 1162 nsBoxSize* boxSizes = aBoxSizes;
michael@0 1163 nsComputedBoxSize* computedBoxSizes = aComputedBoxSizes;
michael@0 1164 int32_t count = 0;
michael@0 1165 int32_t validCount = 0;
michael@0 1166
michael@0 1167 while (boxSizes)
michael@0 1168 {
michael@0 1169
michael@0 1170 NS_ASSERTION((boxSizes->min <= boxSizes->pref && boxSizes->pref <= boxSizes->max),"bad pref, min, max size");
michael@0 1171
michael@0 1172
michael@0 1173 // ignore collapsed children
michael@0 1174 // if (boxSizes->collapsed)
michael@0 1175 // {
michael@0 1176 // computedBoxSizes->valid = true;
michael@0 1177 // computedBoxSizes->size = boxSizes->pref;
michael@0 1178 // validCount++;
michael@0 1179 // boxSizes->flex = 0;
michael@0 1180 // }// else {
michael@0 1181
michael@0 1182 if (computedBoxSizes->valid) {
michael@0 1183 sizeRemaining -= computedBoxSizes->size;
michael@0 1184 validCount++;
michael@0 1185 } else {
michael@0 1186 if (boxSizes->flex == 0)
michael@0 1187 {
michael@0 1188 computedBoxSizes->valid = true;
michael@0 1189 computedBoxSizes->size = boxSizes->pref;
michael@0 1190 validCount++;
michael@0 1191 }
michael@0 1192
michael@0 1193 spacerConstantsRemaining += boxSizes->flex;
michael@0 1194 sizeRemaining -= boxSizes->pref;
michael@0 1195 }
michael@0 1196
michael@0 1197 sizeRemaining -= (boxSizes->left + boxSizes->right);
michael@0 1198
michael@0 1199 //}
michael@0 1200
michael@0 1201 boxSizes = boxSizes->next;
michael@0 1202
michael@0 1203 if (boxSizes && !computedBoxSizes->next)
michael@0 1204 computedBoxSizes->next = new (aState) nsComputedBoxSize();
michael@0 1205
michael@0 1206 computedBoxSizes = computedBoxSizes->next;
michael@0 1207 count++;
michael@0 1208 }
michael@0 1209
michael@0 1210 // everything accounted for?
michael@0 1211 if (validCount < count)
michael@0 1212 {
michael@0 1213 // ----- Ok we are give a size to fit into so stretch or squeeze to fit
michael@0 1214 // ----- Make sure we look at our min and max size
michael@0 1215 bool limit = true;
michael@0 1216 for (int pass=1; true == limit; pass++)
michael@0 1217 {
michael@0 1218 limit = false;
michael@0 1219 boxSizes = aBoxSizes;
michael@0 1220 computedBoxSizes = aComputedBoxSizes;
michael@0 1221
michael@0 1222 while (boxSizes) {
michael@0 1223
michael@0 1224 // ignore collapsed spacers
michael@0 1225
michael@0 1226 // if (!boxSizes->collapsed) {
michael@0 1227
michael@0 1228 nscoord pref = 0;
michael@0 1229 nscoord max = NS_INTRINSICSIZE;
michael@0 1230 nscoord min = 0;
michael@0 1231 nscoord flex = 0;
michael@0 1232
michael@0 1233 pref = boxSizes->pref;
michael@0 1234 min = boxSizes->min;
michael@0 1235 max = boxSizes->max;
michael@0 1236 flex = boxSizes->flex;
michael@0 1237
michael@0 1238 // ----- look at our min and max limits make sure we aren't too small or too big -----
michael@0 1239 if (!computedBoxSizes->valid) {
michael@0 1240 int32_t newSize = pref + int32_t(int64_t(sizeRemaining) * flex / spacerConstantsRemaining);
michael@0 1241
michael@0 1242 if (newSize<=min) {
michael@0 1243 computedBoxSizes->size = min;
michael@0 1244 computedBoxSizes->valid = true;
michael@0 1245 spacerConstantsRemaining -= flex;
michael@0 1246 sizeRemaining += pref;
michael@0 1247 sizeRemaining -= min;
michael@0 1248 limit = true;
michael@0 1249 } else if (newSize>=max) {
michael@0 1250 computedBoxSizes->size = max;
michael@0 1251 computedBoxSizes->valid = true;
michael@0 1252 spacerConstantsRemaining -= flex;
michael@0 1253 sizeRemaining += pref;
michael@0 1254 sizeRemaining -= max;
michael@0 1255 limit = true;
michael@0 1256 }
michael@0 1257 }
michael@0 1258 // }
michael@0 1259 boxSizes = boxSizes->next;
michael@0 1260 computedBoxSizes = computedBoxSizes->next;
michael@0 1261 }
michael@0 1262 }
michael@0 1263 }
michael@0 1264
michael@0 1265 // ---- once we have removed and min and max issues just stretch us out in the remaining space
michael@0 1266 // ---- or shrink us. Depends on the size remaining and the spacer constants
michael@0 1267 aGivenSize = 0;
michael@0 1268 boxSizes = aBoxSizes;
michael@0 1269 computedBoxSizes = aComputedBoxSizes;
michael@0 1270
michael@0 1271 while (boxSizes) {
michael@0 1272
michael@0 1273 // ignore collapsed spacers
michael@0 1274 // if (!(boxSizes && boxSizes->collapsed)) {
michael@0 1275
michael@0 1276 nscoord pref = 0;
michael@0 1277 nscoord flex = 0;
michael@0 1278 pref = boxSizes->pref;
michael@0 1279 flex = boxSizes->flex;
michael@0 1280
michael@0 1281 if (!computedBoxSizes->valid) {
michael@0 1282 computedBoxSizes->size = pref + int32_t(int64_t(sizeRemaining) * flex / spacerConstantsRemaining);
michael@0 1283 computedBoxSizes->valid = true;
michael@0 1284 }
michael@0 1285
michael@0 1286 aGivenSize += (boxSizes->left + boxSizes->right);
michael@0 1287 aGivenSize += computedBoxSizes->size;
michael@0 1288
michael@0 1289 // }
michael@0 1290
michael@0 1291 boxSizes = boxSizes->next;
michael@0 1292 computedBoxSizes = computedBoxSizes->next;
michael@0 1293 }
michael@0 1294 }
michael@0 1295
michael@0 1296
michael@0 1297 nsSize
michael@0 1298 nsSprocketLayout::GetPrefSize(nsIFrame* aBox, nsBoxLayoutState& aState)
michael@0 1299 {
michael@0 1300 nsSize vpref (0, 0);
michael@0 1301 bool isHorizontal = IsHorizontal(aBox);
michael@0 1302
michael@0 1303 nscoord biggestPref = 0;
michael@0 1304
michael@0 1305 // run through all the children and get their min, max, and preferred sizes
michael@0 1306 // return us the size of the box
michael@0 1307
michael@0 1308 nsIFrame* child = aBox->GetChildBox();
michael@0 1309 nsFrameState frameState = nsFrameState(0);
michael@0 1310 GetFrameState(aBox, frameState);
michael@0 1311 bool isEqual = !!(frameState & NS_STATE_EQUAL_SIZE);
michael@0 1312 int32_t count = 0;
michael@0 1313
michael@0 1314 while (child)
michael@0 1315 {
michael@0 1316 // ignore collapsed children
michael@0 1317 if (!child->IsCollapsed())
michael@0 1318 {
michael@0 1319 nsSize pref = child->GetPrefSize(aState);
michael@0 1320 AddMargin(child, pref);
michael@0 1321
michael@0 1322 if (isEqual) {
michael@0 1323 if (isHorizontal)
michael@0 1324 {
michael@0 1325 if (pref.width > biggestPref)
michael@0 1326 biggestPref = pref.width;
michael@0 1327 } else {
michael@0 1328 if (pref.height > biggestPref)
michael@0 1329 biggestPref = pref.height;
michael@0 1330 }
michael@0 1331 }
michael@0 1332
michael@0 1333 AddLargestSize(vpref, pref, isHorizontal);
michael@0 1334 count++;
michael@0 1335 }
michael@0 1336
michael@0 1337 child = child->GetNextBox();
michael@0 1338 }
michael@0 1339
michael@0 1340 if (isEqual) {
michael@0 1341 if (isHorizontal)
michael@0 1342 vpref.width = biggestPref*count;
michael@0 1343 else
michael@0 1344 vpref.height = biggestPref*count;
michael@0 1345 }
michael@0 1346
michael@0 1347 // now add our border and padding
michael@0 1348 AddBorderAndPadding(aBox, vpref);
michael@0 1349
michael@0 1350 return vpref;
michael@0 1351 }
michael@0 1352
michael@0 1353 nsSize
michael@0 1354 nsSprocketLayout::GetMinSize(nsIFrame* aBox, nsBoxLayoutState& aState)
michael@0 1355 {
michael@0 1356 nsSize minSize (0, 0);
michael@0 1357 bool isHorizontal = IsHorizontal(aBox);
michael@0 1358
michael@0 1359 nscoord biggestMin = 0;
michael@0 1360
michael@0 1361
michael@0 1362 // run through all the children and get their min, max, and preferred sizes
michael@0 1363 // return us the size of the box
michael@0 1364
michael@0 1365 nsIFrame* child = aBox->GetChildBox();
michael@0 1366 nsFrameState frameState = nsFrameState(0);
michael@0 1367 GetFrameState(aBox, frameState);
michael@0 1368 bool isEqual = !!(frameState & NS_STATE_EQUAL_SIZE);
michael@0 1369 int32_t count = 0;
michael@0 1370
michael@0 1371 while (child)
michael@0 1372 {
michael@0 1373 // ignore collapsed children
michael@0 1374 if (!child->IsCollapsed())
michael@0 1375 {
michael@0 1376 nsSize min = child->GetMinSize(aState);
michael@0 1377 nsSize pref(0,0);
michael@0 1378
michael@0 1379 // if the child is not flexible then
michael@0 1380 // its min size is its pref size.
michael@0 1381 if (child->GetFlex(aState) == 0) {
michael@0 1382 pref = child->GetPrefSize(aState);
michael@0 1383 if (isHorizontal)
michael@0 1384 min.width = pref.width;
michael@0 1385 else
michael@0 1386 min.height = pref.height;
michael@0 1387 }
michael@0 1388
michael@0 1389 if (isEqual) {
michael@0 1390 if (isHorizontal)
michael@0 1391 {
michael@0 1392 if (min.width > biggestMin)
michael@0 1393 biggestMin = min.width;
michael@0 1394 } else {
michael@0 1395 if (min.height > biggestMin)
michael@0 1396 biggestMin = min.height;
michael@0 1397 }
michael@0 1398 }
michael@0 1399
michael@0 1400 AddMargin(child, min);
michael@0 1401 AddLargestSize(minSize, min, isHorizontal);
michael@0 1402 count++;
michael@0 1403 }
michael@0 1404
michael@0 1405 child = child->GetNextBox();
michael@0 1406 }
michael@0 1407
michael@0 1408
michael@0 1409 if (isEqual) {
michael@0 1410 if (isHorizontal)
michael@0 1411 minSize.width = biggestMin*count;
michael@0 1412 else
michael@0 1413 minSize.height = biggestMin*count;
michael@0 1414 }
michael@0 1415
michael@0 1416 // now add our border and padding
michael@0 1417 AddBorderAndPadding(aBox, minSize);
michael@0 1418
michael@0 1419 return minSize;
michael@0 1420 }
michael@0 1421
michael@0 1422 nsSize
michael@0 1423 nsSprocketLayout::GetMaxSize(nsIFrame* aBox, nsBoxLayoutState& aState)
michael@0 1424 {
michael@0 1425
michael@0 1426 bool isHorizontal = IsHorizontal(aBox);
michael@0 1427
michael@0 1428 nscoord smallestMax = NS_INTRINSICSIZE;
michael@0 1429 nsSize maxSize (NS_INTRINSICSIZE, NS_INTRINSICSIZE);
michael@0 1430
michael@0 1431 // run through all the children and get their min, max, and preferred sizes
michael@0 1432 // return us the size of the box
michael@0 1433
michael@0 1434 nsIFrame* child = aBox->GetChildBox();
michael@0 1435 nsFrameState frameState = nsFrameState(0);
michael@0 1436 GetFrameState(aBox, frameState);
michael@0 1437 bool isEqual = !!(frameState & NS_STATE_EQUAL_SIZE);
michael@0 1438 int32_t count = 0;
michael@0 1439
michael@0 1440 while (child)
michael@0 1441 {
michael@0 1442 // ignore collapsed children
michael@0 1443 if (!child->IsCollapsed())
michael@0 1444 {
michael@0 1445 // if completely redefined don't even ask our child for its size.
michael@0 1446 nsSize min = child->GetMinSize(aState);
michael@0 1447 nsSize max = nsBox::BoundsCheckMinMax(min, child->GetMaxSize(aState));
michael@0 1448
michael@0 1449 AddMargin(child, max);
michael@0 1450 AddSmallestSize(maxSize, max, isHorizontal);
michael@0 1451
michael@0 1452 if (isEqual) {
michael@0 1453 if (isHorizontal)
michael@0 1454 {
michael@0 1455 if (max.width < smallestMax)
michael@0 1456 smallestMax = max.width;
michael@0 1457 } else {
michael@0 1458 if (max.height < smallestMax)
michael@0 1459 smallestMax = max.height;
michael@0 1460 }
michael@0 1461 }
michael@0 1462 count++;
michael@0 1463 }
michael@0 1464
michael@0 1465 child = child->GetNextBox();
michael@0 1466 }
michael@0 1467
michael@0 1468 if (isEqual) {
michael@0 1469 if (isHorizontal) {
michael@0 1470 if (smallestMax != NS_INTRINSICSIZE)
michael@0 1471 maxSize.width = smallestMax*count;
michael@0 1472 else
michael@0 1473 maxSize.width = NS_INTRINSICSIZE;
michael@0 1474 } else {
michael@0 1475 if (smallestMax != NS_INTRINSICSIZE)
michael@0 1476 maxSize.height = smallestMax*count;
michael@0 1477 else
michael@0 1478 maxSize.height = NS_INTRINSICSIZE;
michael@0 1479 }
michael@0 1480 }
michael@0 1481
michael@0 1482 // now add our border and padding
michael@0 1483 AddBorderAndPadding(aBox, maxSize);
michael@0 1484
michael@0 1485 return maxSize;
michael@0 1486 }
michael@0 1487
michael@0 1488
michael@0 1489 nscoord
michael@0 1490 nsSprocketLayout::GetAscent(nsIFrame* aBox, nsBoxLayoutState& aState)
michael@0 1491 {
michael@0 1492 nscoord vAscent = 0;
michael@0 1493
michael@0 1494 bool isHorizontal = IsHorizontal(aBox);
michael@0 1495
michael@0 1496 // run through all the children and get their min, max, and preferred sizes
michael@0 1497 // return us the size of the box
michael@0 1498
michael@0 1499 nsIFrame* child = aBox->GetChildBox();
michael@0 1500
michael@0 1501 while (child)
michael@0 1502 {
michael@0 1503 // ignore collapsed children
michael@0 1504 //if (!child->IsCollapsed())
michael@0 1505 //{
michael@0 1506 // if completely redefined don't even ask our child for its size.
michael@0 1507 nscoord ascent = child->GetBoxAscent(aState);
michael@0 1508
michael@0 1509 nsMargin margin;
michael@0 1510 child->GetMargin(margin);
michael@0 1511 ascent += margin.top;
michael@0 1512
michael@0 1513 if (isHorizontal)
michael@0 1514 {
michael@0 1515 if (ascent > vAscent)
michael@0 1516 vAscent = ascent;
michael@0 1517 } else {
michael@0 1518 if (vAscent == 0)
michael@0 1519 vAscent = ascent;
michael@0 1520 }
michael@0 1521 //}
michael@0 1522
michael@0 1523 child = child->GetNextBox();
michael@0 1524 }
michael@0 1525
michael@0 1526 nsMargin borderPadding;
michael@0 1527 aBox->GetBorderAndPadding(borderPadding);
michael@0 1528
michael@0 1529 return vAscent + borderPadding.top;
michael@0 1530 }
michael@0 1531
michael@0 1532 void
michael@0 1533 nsSprocketLayout::SetLargestSize(nsSize& aSize1, const nsSize& aSize2, bool aIsHorizontal)
michael@0 1534 {
michael@0 1535 if (aIsHorizontal)
michael@0 1536 {
michael@0 1537 if (aSize1.height < aSize2.height)
michael@0 1538 aSize1.height = aSize2.height;
michael@0 1539 } else {
michael@0 1540 if (aSize1.width < aSize2.width)
michael@0 1541 aSize1.width = aSize2.width;
michael@0 1542 }
michael@0 1543 }
michael@0 1544
michael@0 1545 void
michael@0 1546 nsSprocketLayout::SetSmallestSize(nsSize& aSize1, const nsSize& aSize2, bool aIsHorizontal)
michael@0 1547 {
michael@0 1548 if (aIsHorizontal)
michael@0 1549 {
michael@0 1550 if (aSize1.height > aSize2.height)
michael@0 1551 aSize1.height = aSize2.height;
michael@0 1552 } else {
michael@0 1553 if (aSize1.width > aSize2.width)
michael@0 1554 aSize1.width = aSize2.width;
michael@0 1555
michael@0 1556 }
michael@0 1557 }
michael@0 1558
michael@0 1559 void
michael@0 1560 nsSprocketLayout::AddLargestSize(nsSize& aSize, const nsSize& aSizeToAdd, bool aIsHorizontal)
michael@0 1561 {
michael@0 1562 if (aIsHorizontal)
michael@0 1563 AddCoord(aSize.width, aSizeToAdd.width);
michael@0 1564 else
michael@0 1565 AddCoord(aSize.height, aSizeToAdd.height);
michael@0 1566
michael@0 1567 SetLargestSize(aSize, aSizeToAdd, aIsHorizontal);
michael@0 1568 }
michael@0 1569
michael@0 1570 void
michael@0 1571 nsSprocketLayout::AddCoord(nscoord& aCoord, nscoord aCoordToAdd)
michael@0 1572 {
michael@0 1573 if (aCoord != NS_INTRINSICSIZE)
michael@0 1574 {
michael@0 1575 if (aCoordToAdd == NS_INTRINSICSIZE)
michael@0 1576 aCoord = aCoordToAdd;
michael@0 1577 else
michael@0 1578 aCoord += aCoordToAdd;
michael@0 1579 }
michael@0 1580 }
michael@0 1581 void
michael@0 1582 nsSprocketLayout::AddSmallestSize(nsSize& aSize, const nsSize& aSizeToAdd, bool aIsHorizontal)
michael@0 1583 {
michael@0 1584 if (aIsHorizontal)
michael@0 1585 AddCoord(aSize.width, aSizeToAdd.width);
michael@0 1586 else
michael@0 1587 AddCoord(aSize.height, aSizeToAdd.height);
michael@0 1588
michael@0 1589 SetSmallestSize(aSize, aSizeToAdd, aIsHorizontal);
michael@0 1590 }
michael@0 1591
michael@0 1592 bool
michael@0 1593 nsSprocketLayout::GetDefaultFlex(int32_t& aFlex)
michael@0 1594 {
michael@0 1595 aFlex = 0;
michael@0 1596 return true;
michael@0 1597 }
michael@0 1598
michael@0 1599 nsComputedBoxSize::nsComputedBoxSize()
michael@0 1600 {
michael@0 1601 resized = false;
michael@0 1602 valid = false;
michael@0 1603 size = 0;
michael@0 1604 next = nullptr;
michael@0 1605 }
michael@0 1606
michael@0 1607 nsBoxSize::nsBoxSize()
michael@0 1608 {
michael@0 1609 pref = 0;
michael@0 1610 min = 0;
michael@0 1611 max = NS_INTRINSICSIZE;
michael@0 1612 collapsed = false;
michael@0 1613 left = 0;
michael@0 1614 right = 0;
michael@0 1615 flex = 0;
michael@0 1616 next = nullptr;
michael@0 1617 bogus = false;
michael@0 1618 }
michael@0 1619
michael@0 1620
michael@0 1621 void*
michael@0 1622 nsBoxSize::operator new(size_t sz, nsBoxLayoutState& aState) CPP_THROW_NEW
michael@0 1623 {
michael@0 1624 return mozilla::AutoStackArena::Allocate(sz);
michael@0 1625 }
michael@0 1626
michael@0 1627
michael@0 1628 void
michael@0 1629 nsBoxSize::operator delete(void* aPtr, size_t sz)
michael@0 1630 {
michael@0 1631 }
michael@0 1632
michael@0 1633
michael@0 1634 void*
michael@0 1635 nsComputedBoxSize::operator new(size_t sz, nsBoxLayoutState& aState) CPP_THROW_NEW
michael@0 1636 {
michael@0 1637 return mozilla::AutoStackArena::Allocate(sz);
michael@0 1638 }
michael@0 1639
michael@0 1640 void
michael@0 1641 nsComputedBoxSize::operator delete(void* aPtr, size_t sz)
michael@0 1642 {
michael@0 1643 }

mercurial