1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
9 // Netscape Communications
11 // See documentation in associated header file
14 #include "nsBoxLayoutState.h"
15 #include "nsSprocketLayout.h"
16 #include "nsPresContext.h"
18 #include "nsIContent.h"
19 #include "nsContainerFrame.h"
20 #include "nsBoxFrame.h"
21 #include "StackArena.h"
22 #include "mozilla/Likely.h"
23 #include "mozilla/CSSOrderAwareFrameIterator.h"
26 using mozilla::StyleDirection
;
27 using namespace mozilla
;
29 nsBoxLayout
* nsSprocketLayout::gInstance
= nullptr;
31 static Maybe
<CSSOrderAwareFrameIterator
> IterFor(nsIFrame
* aBoxFrame
) {
32 Maybe
<CSSOrderAwareFrameIterator
> ret
;
33 if (aBoxFrame
->IsXULBoxFrame()) {
34 ret
.emplace(aBoxFrame
, mozilla::layout::kPrincipalList
,
35 CSSOrderAwareFrameIterator::ChildFilter::IncludeAll
,
36 CSSOrderAwareFrameIterator::OrderState::Unknown
,
37 CSSOrderAwareFrameIterator::OrderingProperty::BoxOrdinalGroup
);
42 nsresult
NS_NewSprocketLayout(nsCOMPtr
<nsBoxLayout
>& aNewLayout
) {
43 if (!nsSprocketLayout::gInstance
) {
44 nsSprocketLayout::gInstance
= new nsSprocketLayout();
45 NS_IF_ADDREF(nsSprocketLayout::gInstance
);
47 // we have not instance variables so just return our static one.
48 aNewLayout
= nsSprocketLayout::gInstance
;
53 void nsSprocketLayout::Shutdown() { NS_IF_RELEASE(gInstance
); }
55 nsSprocketLayout::nsSprocketLayout() = default;
57 bool nsSprocketLayout::IsXULHorizontal(nsIFrame
* aBox
) {
58 return aBox
->HasAnyStateBits(NS_STATE_IS_HORIZONTAL
);
61 void nsSprocketLayout::GetFrameState(nsIFrame
* aBox
, nsFrameState
& aState
) {
62 aState
= aBox
->GetStateBits();
65 static StyleDirection
GetFrameDirection(nsIFrame
* aBox
) {
66 return aBox
->StyleVisibility()->mDirection
;
69 static void HandleBoxPack(nsIFrame
* aBox
, const nsFrameState
& aFrameState
,
70 nscoord
& aX
, nscoord
& aY
, const nsRect
& aOriginalRect
,
71 const nsRect
& aClientRect
) {
72 // In the normal direction we lay out our kids in the positive direction
73 // (e.g., |x| will get bigger for a horizontal box, and |y| will get bigger
74 // for a vertical box). In the reverse direction, the opposite is true. We'll
75 // be laying out each child at a smaller |x| or |y|.
76 StyleDirection frameDirection
= GetFrameDirection(aBox
);
78 if (aFrameState
& NS_STATE_IS_HORIZONTAL
) {
79 if (aFrameState
& NS_STATE_IS_DIRECTION_NORMAL
) {
80 // The normal direction. |x| increases as we move through our children.
83 // The reverse direction. |x| decreases as we move through our children.
84 aX
= aClientRect
.x
+ aOriginalRect
.width
;
86 // |y| is always in the normal direction in horizontal boxes
89 // take direction property into account for |x| in vertical boxes
90 if (frameDirection
== StyleDirection::Ltr
) {
91 // The normal direction. |x| increases as we move through our children.
94 // The reverse direction. |x| decreases as we move through our children.
95 aX
= aClientRect
.x
+ aOriginalRect
.width
;
97 if (aFrameState
& NS_STATE_IS_DIRECTION_NORMAL
) {
98 // The normal direction. |y| increases as we move through our children.
101 // The reverse direction. |y| decreases as we move through our children.
102 aY
= aClientRect
.y
+ aOriginalRect
.height
;
106 // Get our pack/alignment information.
107 nsIFrame::Halignment halign
= aBox
->GetXULHAlign();
108 nsIFrame::Valignment valign
= aBox
->GetXULVAlign();
110 // The following code handles box PACKING. Packing comes into play in the
111 // case where the computed size for all of our children (now stored in our
112 // client rect) is smaller than the size available for the box (stored in
115 // Here we adjust our |x| and |y| variables accordingly so that we start at
116 // the beginning, middle, or end of the box.
118 // XXXdwh JUSTIFY needs to be implemented!
119 if (aFrameState
& NS_STATE_IS_HORIZONTAL
) {
121 case nsBoxFrame::hAlign_Left
:
122 break; // Nothing to do. The default initialized us properly.
124 case nsBoxFrame::hAlign_Center
:
125 if (aFrameState
& NS_STATE_IS_DIRECTION_NORMAL
)
126 aX
+= (aOriginalRect
.width
- aClientRect
.width
) / 2;
128 aX
-= (aOriginalRect
.width
- aClientRect
.width
) / 2;
131 case nsBoxFrame::hAlign_Right
:
132 if (aFrameState
& NS_STATE_IS_DIRECTION_NORMAL
)
133 aX
+= (aOriginalRect
.width
- aClientRect
.width
);
135 aX
-= (aOriginalRect
.width
- aClientRect
.width
);
136 break; // Nothing to do for the reverse dir. The default initialized
141 case nsBoxFrame::vAlign_Top
:
142 case nsBoxFrame::vAlign_BaseLine
: // This value is technically impossible
143 // to specify for pack.
144 break; // Don't do anything. We were initialized correctly.
146 case nsBoxFrame::vAlign_Middle
:
147 if (aFrameState
& NS_STATE_IS_DIRECTION_NORMAL
)
148 aY
+= (aOriginalRect
.height
- aClientRect
.height
) / 2;
150 aY
-= (aOriginalRect
.height
- aClientRect
.height
) / 2;
153 case nsBoxFrame::vAlign_Bottom
:
154 if (aFrameState
& NS_STATE_IS_DIRECTION_NORMAL
)
155 aY
+= (aOriginalRect
.height
- aClientRect
.height
);
157 aY
-= (aOriginalRect
.height
- aClientRect
.height
);
164 nsSprocketLayout::XULLayout(nsIFrame
* aBox
, nsBoxLayoutState
& aState
) {
165 // See if we are collapsed. If we are, then simply iterate over all our
166 // children and give them a rect of 0 width and height.
167 if (aBox
->IsXULCollapsed()) {
168 for (auto iter
= IterFor(aBox
); iter
&& !iter
->AtEnd(); iter
->Next()) {
169 nsBoxFrame::LayoutChildAt(aState
, iter
->get(), nsRect(0, 0, 0, 0));
174 nsBoxLayoutState::AutoReflowDepth
depth(aState
);
175 mozilla::AutoStackArena arena
;
177 // ----- figure out our size ----------
178 const nsSize originalSize
= aBox
->GetSize();
180 // -- make sure we remove our border and padding ----
182 aBox
->GetXULClientRect(clientRect
);
184 // |originalClientRect| represents the rect of the entire box (excluding
185 // borders and padding). We store it here because we're going to use
186 // |clientRect| to hold the required size for all our kids. As an example,
187 // consider an hbox with a specified width of 300. If the kids total only 150
188 // pixels of width, then we have 150 pixels left over. |clientRect| is going
189 // to hold a width of 150 and is going to be adjusted based off the value of
190 // the PACK property. If flexible objects are in the box, then the two rects
192 nsRect
originalClientRect(clientRect
);
194 // The frame state contains cached knowledge about our box, such as our
195 // orientation and direction.
196 nsFrameState frameState
= nsFrameState(0);
197 GetFrameState(aBox
, frameState
);
199 // Build a list of our children's desired sizes and computed sizes
200 nsBoxSize
* boxSizes
= nullptr;
201 nsComputedBoxSize
* computedBoxSizes
= nullptr;
206 PopulateBoxSizes(aBox
, aState
, boxSizes
, min
, max
, flexes
);
208 // The |size| variable will hold the total size of children along the axis of
209 // the box. Continuing with the example begun in the comment above, size
210 // would be 150 pixels.
211 nscoord size
= clientRect
.width
;
212 if (!IsXULHorizontal(aBox
)) size
= clientRect
.height
;
213 ComputeChildSizes(aBox
, aState
, size
, boxSizes
, computedBoxSizes
);
215 // After the call to ComputeChildSizes, the |size| variable contains the
216 // total required size of all the children. We adjust our clientRect in the
217 // appropriate dimension to match this size. In our example, we now assign
218 // 150 pixels into the clientRect.width.
220 // The variables |min| and |max| hold the minimum required size box must be
221 // in the OPPOSITE orientation, e.g., for a horizontal box, |min| is the
222 // minimum height we require to enclose our children, and |max| is the maximum
223 // height required to enclose our children.
224 if (IsXULHorizontal(aBox
)) {
225 clientRect
.width
= size
;
226 if (clientRect
.height
< min
) clientRect
.height
= min
;
228 if (frameState
& NS_STATE_AUTO_STRETCH
) {
229 if (clientRect
.height
> max
) clientRect
.height
= max
;
232 clientRect
.height
= size
;
233 if (clientRect
.width
< min
) clientRect
.width
= min
;
235 if (frameState
& NS_STATE_AUTO_STRETCH
) {
236 if (clientRect
.width
> max
) clientRect
.width
= max
;
240 // With the sizes computed, now it's time to lay out our children.
244 // We flow children at their preferred locations (along with the appropriate
245 // computed flex). After we flow a child, it is possible that the child will
246 // change its size. If/when this happens, we have to do another pass.
247 // Typically only 2 passes are required, but the code is prepared to do as
248 // many passes as are necessary to achieve equilibrium.
254 // |childResized| lets us know if a child changed its size after we attempted
255 // to lay it out at the specified size. If this happens, we usually have to
257 bool childResized
= false;
259 // |passes| stores our number of passes. If for any reason we end up doing
260 // more than, say, 10 passes, we assert to indicate that something is
261 // seriously screwed up.
264 // Always assume that we're done. This will change if, for example,
265 // children don't stay the same size after being flowed.
268 // Handle box packing.
269 HandleBoxPack(aBox
, frameState
, x
, y
, originalClientRect
, clientRect
);
271 // Now that packing is taken care of we set up a few additional
272 // tracking variables.
276 // Now we iterate over our box children and our box size lists in
277 // parallel. For each child, we look at its sizes and figure out
278 // where to place it.
279 nsComputedBoxSize
* childComputedBoxSize
= computedBoxSizes
;
280 nsBoxSize
* childBoxSize
= boxSizes
;
282 auto iter
= IterFor(aBox
);
284 while ((iter
&& !iter
->AtEnd()) || (childBoxSize
&& childBoxSize
->bogus
)) {
285 // If for some reason, our lists are not the same length, we guard
286 // by bailing out of the loop.
287 if (childBoxSize
== nullptr) {
288 MOZ_ASSERT_UNREACHABLE("Lists not the same length.");
292 nscoord width
= clientRect
.width
;
293 nscoord height
= clientRect
.height
;
295 if (!childBoxSize
->bogus
) {
296 nsIFrame
* child
= iter
->get();
298 // We have a valid box size entry. This entry already contains
299 // information about our sizes along the axis of the box (e.g., widths
300 // in a horizontal box). If our default ALIGN is not stretch, however,
301 // then we also need to know the child's size along the opposite axis.
302 if (!(frameState
& NS_STATE_AUTO_STRETCH
)) {
303 nsSize prefSize
= child
->GetXULPrefSize(aState
);
304 nsSize minSize
= child
->GetXULMinSize(aState
);
305 nsSize maxSize
= child
->GetXULMaxSize(aState
);
306 prefSize
= nsIFrame::XULBoundsCheck(minSize
, prefSize
, maxSize
);
308 AddXULMargin(child
, prefSize
);
309 width
= std::min(prefSize
.width
, originalClientRect
.width
);
310 height
= std::min(prefSize
.height
, originalClientRect
.height
);
314 // Obtain the computed size along the axis of the box for this child from
315 // the computedBoxSize entry. We store the result in |width| for
316 // horizontal boxes and |height| for vertical boxes.
317 if (frameState
& NS_STATE_IS_HORIZONTAL
)
318 width
= childComputedBoxSize
->size
;
320 height
= childComputedBoxSize
->size
;
322 // Adjust our x/y for the left/right spacing.
323 if (frameState
& NS_STATE_IS_HORIZONTAL
) {
324 if (frameState
& NS_STATE_IS_DIRECTION_NORMAL
)
325 x
+= (childBoxSize
->left
);
327 x
-= (childBoxSize
->right
);
329 if (frameState
& NS_STATE_IS_DIRECTION_NORMAL
)
330 y
+= (childBoxSize
->left
);
332 y
-= (childBoxSize
->right
);
335 // Now we build a child rect.
338 if (!(frameState
& NS_STATE_IS_DIRECTION_NORMAL
)) {
339 if (frameState
& NS_STATE_IS_HORIZONTAL
)
345 // We now create an accurate child rect based off our computed size
347 nsRect
childRect(rectX
, rectY
, width
, height
);
349 // Sanity check against our clientRect. It is possible that a child
350 // specified a size that is too large to fit. If that happens, then we
351 // have to grow our client rect. Remember, clientRect is not the total
352 // rect of the enclosing box. It currently holds our perception of how
353 // big the children needed to be.
354 if (childRect
.width
> clientRect
.width
)
355 clientRect
.width
= childRect
.width
;
357 if (childRect
.height
> clientRect
.height
)
358 clientRect
.height
= childRect
.height
;
360 // Either |nextX| or |nextY| is updated by this function call, according
365 ComputeChildsNextPosition(aBox
, x
, y
, nextX
, nextY
, childRect
);
367 // Now we further update our nextX/Y along our axis.
368 // We also set childRect.y/x along the opposite axis appropriately for a
369 // stretch alignment. (Non-stretch alignment is handled below.)
370 if (frameState
& NS_STATE_IS_HORIZONTAL
) {
371 if (frameState
& NS_STATE_IS_DIRECTION_NORMAL
)
372 nextX
+= (childBoxSize
->right
);
374 nextX
-= (childBoxSize
->left
);
375 childRect
.y
= originalClientRect
.y
;
377 if (frameState
& NS_STATE_IS_DIRECTION_NORMAL
)
378 nextY
+= (childBoxSize
->right
);
380 nextY
-= (childBoxSize
->left
);
381 if (GetFrameDirection(aBox
) == StyleDirection::Ltr
) {
382 childRect
.x
= originalClientRect
.x
;
384 // keep the right edge of the box the same
386 clientRect
.x
+ originalClientRect
.width
- childRect
.width
;
390 // If we encounter a completely bogus box size, we just leave this child
391 // completely alone and continue through the loop to the next child.
392 if (childBoxSize
->bogus
) {
393 childComputedBoxSize
= childComputedBoxSize
->next
;
394 childBoxSize
= childBoxSize
->next
;
398 // FIXME(emilio): shouldn't this update `child` / `iter`? This looks
403 nsIFrame
* child
= iter
->get();
404 nsMargin
margin(0, 0, 0, 0);
408 // Deflate the rect of our child by its margin.
409 child
->GetXULMargin(margin
);
410 childRect
.Deflate(margin
);
411 if (childRect
.width
< 0) childRect
.width
= 0;
412 if (childRect
.height
< 0) childRect
.height
= 0;
414 // Now we're trying to figure out if we have to lay out this child, i.e.,
415 // to call the child's XULLayout method.
419 // Always perform layout if we are dirty or have dirty children
420 if (!child
->IsSubtreeDirty()) {
425 nsRect
oldRect(child
->GetRect());
427 // Non-stretch alignment will be handled in AlignChildren(), so don't
428 // change child out-of-axis positions yet.
429 if (!(frameState
& NS_STATE_AUTO_STRETCH
)) {
430 if (frameState
& NS_STATE_IS_HORIZONTAL
) {
431 childRect
.y
= oldRect
.y
;
433 childRect
.x
= oldRect
.x
;
437 // We computed a childRect. Now we want to set the bounds of the child to
438 // be that rect. If our old rect is different, then we know our size
439 // changed and we cache that fact in the |sizeChanged| variable.
441 child
->SetXULBounds(aState
, childRect
);
442 bool sizeChanged
= (childRect
.width
!= oldRect
.width
||
443 childRect
.height
!= oldRect
.height
);
446 // Our size is different. Sanity check against our maximum allowed size
447 // to ensure we didn't exceed it.
448 nsSize minSize
= child
->GetXULMinSize(aState
);
449 nsSize maxSize
= child
->GetXULMaxSize(aState
);
450 maxSize
= nsIFrame::XULBoundsCheckMinMax(minSize
, maxSize
);
452 // make sure the size is in our max size.
453 if (childRect
.width
> maxSize
.width
) childRect
.width
= maxSize
.width
;
455 if (childRect
.height
> maxSize
.height
)
456 childRect
.height
= maxSize
.height
;
459 child
->SetXULBounds(aState
, childRect
);
462 // If we already determined that layout was required or if our size has
463 // changed, then we make sure to call layout on the child, since its
464 // children may need to be shifted around as a result of the size change.
465 if (layout
|| sizeChanged
) child
->XULLayout(aState
);
467 // If the child was a block or inline (e.g., HTML) it may have changed its
468 // rect *during* layout. We have to check for this.
469 nsRect
newChildRect(child
->GetRect());
471 if (!newChildRect
.IsEqualInterior(childRect
)) {
473 printf(" GREW from (%d,%d) -> (%d,%d)\n", childRect
.width
,
474 childRect
.height
, newChildRect
.width
, newChildRect
.height
);
476 newChildRect
.Inflate(margin
);
477 childRect
.Inflate(margin
);
479 // The child changed size during layout. The ChildResized method
480 // handles this scenario.
481 ChildResized(aBox
, aState
, child
, childBoxSize
, childComputedBoxSize
,
482 boxSizes
, computedBoxSizes
, childRect
, newChildRect
,
483 clientRect
, flexes
, finished
);
485 // We note that a child changed size, which means that another pass will
489 // Now that a child resized, it's entirely possible that OUR rect is too
490 // small. Now we ensure that |originalClientRect| is grown to
491 // accommodate the size of |clientRect|.
492 if (clientRect
.width
> originalClientRect
.width
)
493 originalClientRect
.width
= clientRect
.width
;
495 if (clientRect
.height
> originalClientRect
.height
)
496 originalClientRect
.height
= clientRect
.height
;
498 if (!(frameState
& NS_STATE_IS_DIRECTION_NORMAL
)) {
499 // Our childRect had its XMost() or YMost() (depending on our layout
500 // direction), positioned at a certain point. Ensure that the
501 // newChildRect satisfies the same constraint. Note that this is
502 // just equivalent to adjusting the x/y by the difference in
503 // width/height between childRect and newChildRect. So we don't need
504 // to reaccount for the left and right of the box layout state again.
505 if (frameState
& NS_STATE_IS_HORIZONTAL
)
506 newChildRect
.x
= childRect
.XMost() - newChildRect
.width
;
508 newChildRect
.y
= childRect
.YMost() - newChildRect
.height
;
511 if (!(frameState
& NS_STATE_IS_HORIZONTAL
)) {
512 if (GetFrameDirection(aBox
) != StyleDirection::Ltr
) {
513 // keep the right edge the same
514 newChildRect
.x
= childRect
.XMost() - newChildRect
.width
;
518 // If the child resized then recompute its position.
519 ComputeChildsNextPosition(aBox
, x
, y
, nextX
, nextY
, newChildRect
);
521 if (newChildRect
.width
>= margin
.left
+ margin
.right
&&
522 newChildRect
.height
>= margin
.top
+ margin
.bottom
)
523 newChildRect
.Deflate(margin
);
525 if (childRect
.width
>= margin
.left
+ margin
.right
&&
526 childRect
.height
>= margin
.top
+ margin
.bottom
)
527 childRect
.Deflate(margin
);
529 child
->SetXULBounds(aState
, newChildRect
);
531 // If we are the first box that changed size, then we don't need to do a
533 if (count
== 0) finished
= true;
536 // Now update our x/y finally.
540 // Move to the next child.
541 childComputedBoxSize
= childComputedBoxSize
->next
;
542 childBoxSize
= childBoxSize
->next
;
548 // Sanity-checking code to ensure we don't do an infinite # of passes.
550 NS_ASSERTION(passes
< 10, "A Box's child is constantly growing!!!!!");
551 if (passes
>= 10) break;
552 } while (false == finished
);
554 // Get rid of our size lists.
556 nsBoxSize
* toDelete
= boxSizes
;
557 boxSizes
= boxSizes
->next
;
561 while (computedBoxSizes
) {
562 nsComputedBoxSize
* toDelete
= computedBoxSizes
;
563 computedBoxSizes
= computedBoxSizes
->next
;
568 // See if one of our children forced us to get bigger
569 nsRect
tmpClientRect(originalClientRect
);
570 nsMargin
bp(0, 0, 0, 0);
571 aBox
->GetXULBorderAndPadding(bp
);
572 tmpClientRect
.Inflate(bp
);
574 if (tmpClientRect
.width
> originalSize
.width
||
575 tmpClientRect
.height
> originalSize
.height
) {
576 // if it did reset our bounds.
577 nsRect
bounds(aBox
->GetRect());
578 if (tmpClientRect
.width
> originalSize
.width
)
579 bounds
.width
= tmpClientRect
.width
;
581 if (tmpClientRect
.height
> originalSize
.height
)
582 bounds
.height
= tmpClientRect
.height
;
584 aBox
->SetXULBounds(aState
, bounds
);
588 // Because our size grew, we now have to readjust because of box packing.
589 // Repack in order to update our x and y to the correct values.
590 HandleBoxPack(aBox
, frameState
, x
, y
, originalClientRect
, clientRect
);
592 // Compare against our original x and y and only worry about adjusting the
593 // children if we really did have to change the positions because of packing
594 // (typically for 'center' or 'end' pack values).
595 if (x
!= origX
|| y
!= origY
) {
596 // reposition all our children
597 for (auto iter
= IterFor(aBox
); iter
&& !iter
->AtEnd(); iter
->Next()) {
598 nsIFrame
* child
= iter
->get();
599 nsRect
childRect(child
->GetRect());
600 childRect
.x
+= (x
- origX
);
601 childRect
.y
+= (y
- origY
);
602 child
->SetXULBounds(aState
, childRect
);
606 // Perform out-of-axis alignment for non-stretch alignments
607 if (!(frameState
& NS_STATE_AUTO_STRETCH
)) {
608 AlignChildren(aBox
, aState
);
611 // That's it! If you made it this far without having a nervous breakdown,
612 // congratulations! Go get yourself a beer.
616 void nsSprocketLayout::PopulateBoxSizes(nsIFrame
* aBox
,
617 nsBoxLayoutState
& aState
,
618 nsBoxSize
*& aBoxSizes
,
619 nscoord
& aMinSize
, nscoord
& aMaxSize
,
621 // used for the equal size flag
622 nscoord biggestPrefWidth
= 0;
623 nscoord biggestMinWidth
= 0;
624 nscoord smallestMaxWidth
= NS_UNCONSTRAINEDSIZE
;
626 nsFrameState frameState
= nsFrameState(0);
627 GetFrameState(aBox
, frameState
);
630 aMaxSize
= NS_UNCONSTRAINEDSIZE
;
634 if (IsXULHorizontal(aBox
))
637 isHorizontal
= false;
639 // this is a nice little optimization
640 // it turns out that if we only have 1 flexable child
641 // then it does not matter what its preferred size is
642 // there is nothing to flex it relative. This is great
643 // because we can avoid asking for a preferred size in this
644 // case. Why is this good? Well you might have html inside it
645 // and asking html for its preferred size is rather expensive.
646 // so we can just optimize it out this way.
650 nsBoxSize
* currentBox
= aBoxSizes
;
651 nsBoxSize
* last
= nullptr;
654 int32_t childCount
= 0;
656 for (auto iter
= IterFor(aBox
); iter
&& !iter
->AtEnd(); iter
->Next()) {
657 nsIFrame
* child
= iter
->get();
658 while (currentBox
&& currentBox
->bogus
) {
660 currentBox
= currentBox
->next
;
664 nsSize
minSize(0, 0);
665 nsSize
maxSize(NS_UNCONSTRAINEDSIZE
, NS_UNCONSTRAINEDSIZE
);
666 bool collapsed
= child
->IsXULCollapsed();
669 // only one flexible child? Cool we will just make its preferred size
670 // 0 then and not even have to ask for it.
671 // if (flexes != 1) {
673 pref
= child
->GetXULPrefSize(aState
);
674 minSize
= child
->GetXULMinSize(aState
);
676 nsIFrame::XULBoundsCheckMinMax(minSize
, child
->GetXULMaxSize(aState
));
677 child
->GetXULBoxAscent(aState
);
680 pref
= nsIFrame::XULBoundsCheck(minSize
, pref
, maxSize
);
682 AddXULMargin(child
, pref
);
683 AddXULMargin(child
, minSize
);
684 AddXULMargin(child
, maxSize
);
689 currentBox
= new (aState
) nsBoxSize();
691 aBoxSizes
= currentBox
;
694 last
->next
= currentBox
;
702 // get sizes from child
704 minWidth
= minSize
.width
;
705 maxWidth
= maxSize
.width
;
706 prefWidth
= pref
.width
;
708 minWidth
= minSize
.height
;
709 maxWidth
= maxSize
.height
;
710 prefWidth
= pref
.height
;
713 nscoord flex
= child
->GetXULFlex();
715 // set them if you collapsed you are not flexible.
717 currentBox
->flex
= 0;
719 if (flex
> maxFlex
) {
722 currentBox
->flex
= flex
;
725 // we specified all our children are equal size;
726 if (frameState
& NS_STATE_EQUAL_SIZE
) {
727 if (prefWidth
> biggestPrefWidth
) biggestPrefWidth
= prefWidth
;
729 if (minWidth
> biggestMinWidth
) biggestMinWidth
= minWidth
;
731 if (maxWidth
< smallestMaxWidth
) smallestMaxWidth
= maxWidth
;
732 } else { // not we can set our children right now.
733 currentBox
->pref
= prefWidth
;
734 currentBox
->min
= minWidth
;
735 currentBox
->max
= maxWidth
;
738 NS_ASSERTION(minWidth
<= prefWidth
&& prefWidth
<= maxWidth
,
739 "Bad min, pref, max widths!");
743 if (minSize
.width
> aMinSize
) aMinSize
= minSize
.width
;
745 if (maxSize
.width
< aMaxSize
) aMaxSize
= maxSize
.width
;
748 if (minSize
.height
> aMinSize
) aMinSize
= minSize
.height
;
750 if (maxSize
.height
< aMaxSize
) aMaxSize
= maxSize
.height
;
753 currentBox
->collapsed
= collapsed
;
754 aFlexes
+= currentBox
->flex
;
757 currentBox
= currentBox
->next
;
760 if (childCount
> 0) {
761 nscoord maxAllowedFlex
= nscoord_MAX
/ childCount
;
763 if (MOZ_UNLIKELY(maxFlex
> maxAllowedFlex
)) {
764 // clamp all the flexes
765 currentBox
= aBoxSizes
;
767 currentBox
->flex
= std::min(currentBox
->flex
, maxAllowedFlex
);
768 currentBox
= currentBox
->next
;
774 NS_ASSERTION(maxFlex
== 0, "How did that happen?");
778 // we specified all our children are equal size;
779 if (frameState
& NS_STATE_EQUAL_SIZE
) {
780 smallestMaxWidth
= std::max(smallestMaxWidth
, biggestMinWidth
);
781 biggestPrefWidth
= nsIFrame::XULBoundsCheck(
782 biggestMinWidth
, biggestPrefWidth
, smallestMaxWidth
);
784 currentBox
= aBoxSizes
;
787 if (!currentBox
->collapsed
) {
788 currentBox
->pref
= biggestPrefWidth
;
789 currentBox
->min
= biggestMinWidth
;
790 currentBox
->max
= smallestMaxWidth
;
792 currentBox
->pref
= 0;
796 currentBox
= currentBox
->next
;
801 void nsSprocketLayout::ComputeChildsNextPosition(
802 nsIFrame
* aBox
, const nscoord
& aCurX
, const nscoord
& aCurY
, nscoord
& aNextX
,
803 nscoord
& aNextY
, const nsRect
& aCurrentChildSize
) {
804 // Get the position along the box axis for the child.
805 // The out-of-axis position is not set.
806 nsFrameState frameState
= nsFrameState(0);
807 GetFrameState(aBox
, frameState
);
809 if (IsXULHorizontal(aBox
)) {
810 // horizontal box's children.
811 if (frameState
& NS_STATE_IS_DIRECTION_NORMAL
)
812 aNextX
= aCurX
+ aCurrentChildSize
.width
;
814 aNextX
= aCurX
- aCurrentChildSize
.width
;
817 // vertical box's children.
818 if (frameState
& NS_STATE_IS_DIRECTION_NORMAL
)
819 aNextY
= aCurY
+ aCurrentChildSize
.height
;
821 aNextY
= aCurY
- aCurrentChildSize
.height
;
825 void nsSprocketLayout::AlignChildren(nsIFrame
* aBox
, nsBoxLayoutState
& aState
) {
826 nsFrameState frameState
= nsFrameState(0);
827 GetFrameState(aBox
, frameState
);
828 bool isHorizontal
= (frameState
& NS_STATE_IS_HORIZONTAL
) != 0;
830 aBox
->GetXULClientRect(clientRect
);
832 MOZ_ASSERT(!(frameState
& NS_STATE_AUTO_STRETCH
),
833 "Only AlignChildren() with non-stretch alignment");
835 // These are only calculated if needed
836 nsIFrame::Halignment halign
;
837 nsIFrame::Valignment valign
;
838 nscoord maxAscent
= 0;
842 valign
= aBox
->GetXULVAlign();
843 if (valign
== nsBoxFrame::vAlign_BaseLine
) {
844 maxAscent
= aBox
->GetXULBoxAscent(aState
);
847 isLTR
= GetFrameDirection(aBox
) == StyleDirection::Ltr
;
848 halign
= aBox
->GetXULHAlign();
851 for (auto iter
= IterFor(aBox
); iter
&& !iter
->AtEnd(); iter
->Next()) {
852 nsIFrame
* child
= iter
->get();
854 child
->GetXULMargin(margin
);
855 nsRect childRect
= child
->GetRect();
858 const nscoord startAlign
= clientRect
.y
+ margin
.top
;
859 const nscoord endAlign
=
860 clientRect
.YMost() - margin
.bottom
- childRect
.height
;
864 case nsBoxFrame::vAlign_Top
:
867 case nsBoxFrame::vAlign_Middle
:
868 // Should this center the border box?
869 // This centers the margin box, the historical behavior.
870 y
= (startAlign
+ endAlign
) / 2;
872 case nsBoxFrame::vAlign_Bottom
:
875 case nsBoxFrame::vAlign_BaseLine
:
876 // Alignments don't force the box to grow (only sizes do),
877 // so keep the children within the box.
878 y
= maxAscent
- child
->GetXULBoxAscent(aState
);
879 y
= std::max(startAlign
, y
);
880 y
= std::min(y
, endAlign
);
886 } else { // vertical box
887 const nscoord leftAlign
= clientRect
.x
+ margin
.left
;
888 const nscoord rightAlign
=
889 clientRect
.XMost() - margin
.right
- childRect
.width
;
893 case nsBoxFrame::hAlign_Left
: // start
894 x
= isLTR
? leftAlign
: rightAlign
;
896 case nsBoxFrame::hAlign_Center
:
897 x
= (leftAlign
+ rightAlign
) / 2;
899 case nsBoxFrame::hAlign_Right
: // end
900 x
= isLTR
? rightAlign
: leftAlign
;
907 if (childRect
.TopLeft() != child
->GetPosition()) {
908 child
->SetXULBounds(aState
, childRect
);
913 void nsSprocketLayout::ChildResized(
914 nsIFrame
* aBox
, nsBoxLayoutState
& aState
, nsIFrame
* aChild
,
915 nsBoxSize
* aChildBoxSize
, nsComputedBoxSize
* aChildComputedSize
,
916 nsBoxSize
* aBoxSizes
, nsComputedBoxSize
* aComputedBoxSizes
,
917 const nsRect
& aChildLayoutRect
, nsRect
& aChildActualRect
,
918 nsRect
& aContainingRect
, int32_t aFlexes
, bool& aFinished
)
921 nsRect
childCurrentRect(aChildLayoutRect
);
923 bool isHorizontal
= IsXULHorizontal(aBox
);
924 nscoord childLayoutWidth
= GET_WIDTH(aChildLayoutRect
, isHorizontal
);
925 nscoord
& childActualWidth
= GET_WIDTH(aChildActualRect
, isHorizontal
);
926 nscoord
& containingWidth
= GET_WIDTH(aContainingRect
, isHorizontal
);
928 // nscoord childLayoutHeight = GET_HEIGHT(aChildLayoutRect,isHorizontal);
929 nscoord
& childActualHeight
= GET_HEIGHT(aChildActualRect
, isHorizontal
);
930 nscoord
& containingHeight
= GET_HEIGHT(aContainingRect
, isHorizontal
);
932 bool recompute
= false;
934 // if we are a horizontal box see if the child will fit inside us.
935 if (childActualHeight
> containingHeight
) {
936 // if we are a horizontal box and the child is bigger than our height
938 // ok if the height changed then we need to reflow everyone but us at the
939 // new height so we will set the changed index to be us. And signal that we
942 nsSize min
= aChild
->GetXULMinSize(aState
);
944 nsIFrame::XULBoundsCheckMinMax(min
, aChild
->GetXULMaxSize(aState
));
945 AddXULMargin(aChild
, max
);
949 max
.height
< childActualHeight
? max
.height
: childActualHeight
;
952 max
.width
< childActualHeight
? max
.width
: childActualHeight
;
954 // only set if it changes
955 if (childActualHeight
> containingHeight
) {
956 containingHeight
= childActualHeight
;
958 // remember we do not need to clear the resized list because changing the
959 // height of a horizontal box will not affect the width of any of its
960 // children because block flow left to right, top to bottom. Just trust me
964 // only recompute if there are flexes.
966 // relayout everything
968 InvalidateComputedSizes(aComputedBoxSizes
);
969 nsComputedBoxSize
* node
= aComputedBoxSizes
;
972 node
->resized
= false;
979 if (childActualWidth
> childLayoutWidth
) {
980 nsSize min
= aChild
->GetXULMinSize(aState
);
982 nsIFrame::XULBoundsCheckMinMax(min
, aChild
->GetXULMaxSize(aState
));
984 AddXULMargin(aChild
, max
);
986 // our width now becomes the new size
990 max
.width
< childActualWidth
? max
.width
: childActualWidth
;
993 max
.height
< childActualWidth
? max
.height
: childActualWidth
;
995 if (childActualWidth
> childLayoutWidth
) {
996 aChildComputedSize
->size
= childActualWidth
;
997 aChildBoxSize
->min
= childActualWidth
;
998 if (aChildBoxSize
->pref
< childActualWidth
)
999 aChildBoxSize
->pref
= childActualWidth
;
1000 if (aChildBoxSize
->max
< childActualWidth
)
1001 aChildBoxSize
->max
= childActualWidth
;
1003 // if we have flexible elements with us then reflex things. Otherwise we
1004 // can skip doing it.
1006 InvalidateComputedSizes(aComputedBoxSizes
);
1008 nsComputedBoxSize
* node
= aComputedBoxSizes
;
1009 aChildComputedSize
->resized
= true;
1012 if (node
->resized
) node
->valid
= true;
1020 containingWidth
+= aChildComputedSize
->size
- childLayoutWidth
;
1026 ComputeChildSizes(aBox
, aState
, containingWidth
, aBoxSizes
,
1029 if (!childCurrentRect
.IsEqualInterior(aChildActualRect
)) {
1030 // the childRect includes the margin
1031 // make sure we remove it before setting
1033 nsMargin
margin(0, 0, 0, 0);
1034 aChild
->GetXULMargin(margin
);
1035 nsRect
rect(aChildActualRect
);
1036 if (rect
.width
>= margin
.left
+ margin
.right
&&
1037 rect
.height
>= margin
.top
+ margin
.bottom
)
1038 rect
.Deflate(margin
);
1040 aChild
->SetXULBounds(aState
, rect
);
1041 aChild
->XULLayout(aState
);
1045 void nsSprocketLayout::InvalidateComputedSizes(
1046 nsComputedBoxSize
* aComputedBoxSizes
) {
1047 while (aComputedBoxSizes
) {
1048 aComputedBoxSizes
->valid
= false;
1049 aComputedBoxSizes
= aComputedBoxSizes
->next
;
1053 void nsSprocketLayout::ComputeChildSizes(
1054 nsIFrame
* aBox
, nsBoxLayoutState
& aState
, nscoord
& aGivenSize
,
1055 nsBoxSize
* aBoxSizes
, nsComputedBoxSize
*& aComputedBoxSizes
) {
1056 // nscoord onePixel = aState.PresContext()->IntScaledPixelsToTwips(1);
1058 int32_t sizeRemaining
= aGivenSize
;
1059 int32_t spacerConstantsRemaining
= 0;
1061 // ----- calculate the spacers constants and the size remaining -----
1063 if (!aComputedBoxSizes
) aComputedBoxSizes
= new (aState
) nsComputedBoxSize();
1065 nsBoxSize
* boxSizes
= aBoxSizes
;
1066 nsComputedBoxSize
* computedBoxSizes
= aComputedBoxSizes
;
1068 int32_t validCount
= 0;
1072 (boxSizes
->min
<= boxSizes
->pref
&& boxSizes
->pref
<= boxSizes
->max
),
1073 "bad pref, min, max size");
1075 // ignore collapsed children
1076 // if (boxSizes->collapsed)
1078 // computedBoxSizes->valid = true;
1079 // computedBoxSizes->size = boxSizes->pref;
1081 // boxSizes->flex = 0;
1084 if (computedBoxSizes
->valid
) {
1085 sizeRemaining
-= computedBoxSizes
->size
;
1088 if (boxSizes
->flex
== 0) {
1089 computedBoxSizes
->valid
= true;
1090 computedBoxSizes
->size
= boxSizes
->pref
;
1094 spacerConstantsRemaining
+= boxSizes
->flex
;
1095 sizeRemaining
-= boxSizes
->pref
;
1098 sizeRemaining
-= (boxSizes
->left
+ boxSizes
->right
);
1102 boxSizes
= boxSizes
->next
;
1104 if (boxSizes
&& !computedBoxSizes
->next
)
1105 computedBoxSizes
->next
= new (aState
) nsComputedBoxSize();
1107 computedBoxSizes
= computedBoxSizes
->next
;
1111 // everything accounted for?
1112 if (validCount
< count
) {
1113 // ----- Ok we are give a size to fit into so stretch or squeeze to fit
1114 // ----- Make sure we look at our min and max size
1118 boxSizes
= aBoxSizes
;
1119 computedBoxSizes
= aComputedBoxSizes
;
1122 // ignore collapsed spacers
1124 // if (!boxSizes->collapsed) {
1127 nscoord max
= NS_UNCONSTRAINEDSIZE
;
1131 pref
= boxSizes
->pref
;
1132 min
= boxSizes
->min
;
1133 max
= boxSizes
->max
;
1134 flex
= boxSizes
->flex
;
1136 // ----- look at our min and max limits make sure we aren't too small or
1138 if (!computedBoxSizes
->valid
) {
1139 int32_t newSize
= pref
+ int32_t(int64_t(sizeRemaining
) * flex
/
1140 spacerConstantsRemaining
);
1142 if (newSize
<= min
) {
1143 computedBoxSizes
->size
= min
;
1144 computedBoxSizes
->valid
= true;
1145 spacerConstantsRemaining
-= flex
;
1146 sizeRemaining
+= pref
;
1147 sizeRemaining
-= min
;
1149 } else if (newSize
>= max
) {
1150 computedBoxSizes
->size
= max
;
1151 computedBoxSizes
->valid
= true;
1152 spacerConstantsRemaining
-= flex
;
1153 sizeRemaining
+= pref
;
1154 sizeRemaining
-= max
;
1159 boxSizes
= boxSizes
->next
;
1160 computedBoxSizes
= computedBoxSizes
->next
;
1165 // ---- once we have removed and min and max issues just stretch us out in the
1167 // ---- or shrink us. Depends on the size remaining and the spacer constants
1169 boxSizes
= aBoxSizes
;
1170 computedBoxSizes
= aComputedBoxSizes
;
1173 // ignore collapsed spacers
1174 // if (!(boxSizes && boxSizes->collapsed)) {
1178 pref
= boxSizes
->pref
;
1179 flex
= boxSizes
->flex
;
1181 if (!computedBoxSizes
->valid
) {
1182 computedBoxSizes
->size
= pref
+ int32_t(int64_t(sizeRemaining
) * flex
/
1183 spacerConstantsRemaining
);
1184 computedBoxSizes
->valid
= true;
1187 aGivenSize
+= (boxSizes
->left
+ boxSizes
->right
);
1188 aGivenSize
+= computedBoxSizes
->size
;
1192 boxSizes
= boxSizes
->next
;
1193 computedBoxSizes
= computedBoxSizes
->next
;
1197 nsSize
nsSprocketLayout::GetXULPrefSize(nsIFrame
* aBox
,
1198 nsBoxLayoutState
& aState
) {
1200 bool isHorizontal
= IsXULHorizontal(aBox
);
1202 nscoord biggestPref
= 0;
1204 // run through all the children and get their min, max, and preferred sizes
1205 // return us the size of the box
1207 nsFrameState frameState
= nsFrameState(0);
1208 GetFrameState(aBox
, frameState
);
1209 bool isEqual
= !!(frameState
& NS_STATE_EQUAL_SIZE
);
1212 for (auto iter
= IterFor(aBox
); iter
&& !iter
->AtEnd(); iter
->Next()) {
1213 nsIFrame
* child
= iter
->get();
1214 // ignore collapsed children
1215 if (child
->IsXULCollapsed()) {
1218 nsSize pref
= child
->GetXULPrefSize(aState
);
1219 AddXULMargin(child
, pref
);
1223 if (pref
.width
> biggestPref
) biggestPref
= pref
.width
;
1225 if (pref
.height
> biggestPref
) biggestPref
= pref
.height
;
1229 AddLargestSize(vpref
, pref
, isHorizontal
);
1235 vpref
.width
= biggestPref
* count
;
1237 vpref
.height
= biggestPref
* count
;
1240 // now add our border and padding
1241 AddXULBorderAndPadding(aBox
, vpref
);
1246 nsSize
nsSprocketLayout::GetXULMinSize(nsIFrame
* aBox
,
1247 nsBoxLayoutState
& aState
) {
1248 nsSize
minSize(0, 0);
1249 bool isHorizontal
= IsXULHorizontal(aBox
);
1251 nscoord biggestMin
= 0;
1253 // run through all the children and get their min, max, and preferred sizes
1254 // return us the size of the box
1256 nsFrameState frameState
= nsFrameState(0);
1257 GetFrameState(aBox
, frameState
);
1258 bool isEqual
= !!(frameState
& NS_STATE_EQUAL_SIZE
);
1261 for (auto iter
= IterFor(aBox
); iter
&& !iter
->AtEnd(); iter
->Next()) {
1262 nsIFrame
* child
= iter
->get();
1264 // ignore collapsed children
1265 if (child
->IsXULCollapsed()) {
1269 nsSize min
= child
->GetXULMinSize(aState
);
1272 // if the child is not flexible then
1273 // its min size is its pref size.
1274 if (child
->GetXULFlex() == 0) {
1275 pref
= child
->GetXULPrefSize(aState
);
1277 min
.width
= pref
.width
;
1279 min
.height
= pref
.height
;
1284 if (min
.width
> biggestMin
) biggestMin
= min
.width
;
1286 if (min
.height
> biggestMin
) biggestMin
= min
.height
;
1290 AddXULMargin(child
, min
);
1291 AddLargestSize(minSize
, min
, isHorizontal
);
1297 minSize
.width
= biggestMin
* count
;
1299 minSize
.height
= biggestMin
* count
;
1302 // now add our border and padding
1303 AddXULBorderAndPadding(aBox
, minSize
);
1308 nsSize
nsSprocketLayout::GetXULMaxSize(nsIFrame
* aBox
,
1309 nsBoxLayoutState
& aState
) {
1310 bool isHorizontal
= IsXULHorizontal(aBox
);
1312 nscoord smallestMax
= NS_UNCONSTRAINEDSIZE
;
1313 nsSize
maxSize(NS_UNCONSTRAINEDSIZE
, NS_UNCONSTRAINEDSIZE
);
1315 // run through all the children and get their min, max, and preferred sizes
1316 // return us the size of the box
1318 nsFrameState frameState
= nsFrameState(0);
1319 GetFrameState(aBox
, frameState
);
1320 bool isEqual
= !!(frameState
& NS_STATE_EQUAL_SIZE
);
1323 for (auto iter
= IterFor(aBox
); iter
&& !iter
->AtEnd(); iter
->Next()) {
1324 nsIFrame
* child
= iter
->get();
1326 // ignore collapsed children
1327 if (child
->IsXULCollapsed()) {
1330 // if completely redefined don't even ask our child for its size.
1331 nsSize min
= child
->GetXULMinSize(aState
);
1333 nsIFrame::XULBoundsCheckMinMax(min
, child
->GetXULMaxSize(aState
));
1335 AddXULMargin(child
, max
);
1336 AddSmallestSize(maxSize
, max
, isHorizontal
);
1340 if (max
.width
< smallestMax
) smallestMax
= max
.width
;
1342 if (max
.height
< smallestMax
) smallestMax
= max
.height
;
1350 if (smallestMax
!= NS_UNCONSTRAINEDSIZE
)
1351 maxSize
.width
= smallestMax
* count
;
1353 maxSize
.width
= NS_UNCONSTRAINEDSIZE
;
1355 if (smallestMax
!= NS_UNCONSTRAINEDSIZE
)
1356 maxSize
.height
= smallestMax
* count
;
1358 maxSize
.height
= NS_UNCONSTRAINEDSIZE
;
1362 // now add our border and padding
1363 AddXULBorderAndPadding(aBox
, maxSize
);
1368 nscoord
nsSprocketLayout::GetAscent(nsIFrame
* aBox
, nsBoxLayoutState
& aState
) {
1369 nscoord vAscent
= 0;
1371 bool isHorizontal
= IsXULHorizontal(aBox
);
1373 // run through all the children and get their min, max, and preferred sizes
1374 // return us the size of the box
1376 for (auto iter
= IterFor(aBox
); iter
&& !iter
->AtEnd(); iter
->Next()) {
1377 nsIFrame
* child
= iter
->get();
1379 // ignore collapsed children
1380 // if (!child->IsXULCollapsed())
1382 // if completely redefined don't even ask our child for its size.
1383 nscoord ascent
= child
->GetXULBoxAscent(aState
);
1386 child
->GetXULMargin(margin
);
1387 ascent
+= margin
.top
;
1390 if (ascent
> vAscent
) vAscent
= ascent
;
1392 if (vAscent
== 0) vAscent
= ascent
;
1396 child
= nsIFrame::GetNextXULBox(child
);
1399 nsMargin borderPadding
;
1400 aBox
->GetXULBorderAndPadding(borderPadding
);
1402 return vAscent
+ borderPadding
.top
;
1405 void nsSprocketLayout::SetLargestSize(nsSize
& aSize1
, const nsSize
& aSize2
,
1406 bool aIsHorizontal
) {
1407 if (aIsHorizontal
) {
1408 if (aSize1
.height
< aSize2
.height
) aSize1
.height
= aSize2
.height
;
1410 if (aSize1
.width
< aSize2
.width
) aSize1
.width
= aSize2
.width
;
1414 void nsSprocketLayout::SetSmallestSize(nsSize
& aSize1
, const nsSize
& aSize2
,
1415 bool aIsHorizontal
) {
1416 if (aIsHorizontal
) {
1417 if (aSize1
.height
> aSize2
.height
) aSize1
.height
= aSize2
.height
;
1419 if (aSize1
.width
> aSize2
.width
) aSize1
.width
= aSize2
.width
;
1423 void nsSprocketLayout::AddLargestSize(nsSize
& aSize
, const nsSize
& aSizeToAdd
,
1424 bool aIsHorizontal
) {
1426 AddCoord(aSize
.width
, aSizeToAdd
.width
);
1428 AddCoord(aSize
.height
, aSizeToAdd
.height
);
1430 SetLargestSize(aSize
, aSizeToAdd
, aIsHorizontal
);
1433 void nsSprocketLayout::AddCoord(nscoord
& aCoord
, nscoord aCoordToAdd
) {
1434 if (aCoord
!= NS_UNCONSTRAINEDSIZE
) {
1435 if (aCoordToAdd
== NS_UNCONSTRAINEDSIZE
)
1436 aCoord
= aCoordToAdd
;
1438 aCoord
+= aCoordToAdd
;
1441 void nsSprocketLayout::AddSmallestSize(nsSize
& aSize
, const nsSize
& aSizeToAdd
,
1442 bool aIsHorizontal
) {
1444 AddCoord(aSize
.width
, aSizeToAdd
.width
);
1446 AddCoord(aSize
.height
, aSizeToAdd
.height
);
1448 SetSmallestSize(aSize
, aSizeToAdd
, aIsHorizontal
);
1451 bool nsSprocketLayout::GetDefaultFlex(int32_t& aFlex
) {
1456 nsComputedBoxSize::nsComputedBoxSize() {
1463 nsBoxSize::nsBoxSize() {
1466 max
= NS_UNCONSTRAINEDSIZE
;
1475 void* nsBoxSize::operator new(size_t sz
,
1476 nsBoxLayoutState
& aState
) noexcept(true) {
1477 return mozilla::AutoStackArena::Allocate(sz
);
1480 void nsBoxSize::operator delete(void* aPtr
, size_t sz
) {}
1482 void* nsComputedBoxSize::operator new(size_t sz
,
1483 nsBoxLayoutState
& aState
) noexcept(true) {
1484 return mozilla::AutoStackArena::Allocate(sz
);
1487 void nsComputedBoxSize::operator delete(void* aPtr
, size_t sz
) {}