nsContainerFrameInlines.h (4074B)
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/. */ 6 7 #ifndef nsContainerFrameInlines_h___ 8 #define nsContainerFrameInlines_h___ 9 10 #include "nsContainerFrame.h" 11 12 template <typename ISizeData, typename F> 13 void nsContainerFrame::DoInlineIntrinsicISize(ISizeData* aData, 14 F& aHandleChildren) { 15 using namespace mozilla; 16 17 auto GetMargin = [](const AnchorResolvedMargin& aCoord) -> nscoord { 18 if (!aCoord->IsLengthPercentage()) { 19 MOZ_ASSERT(aCoord->IsAuto(), "Didn't resolve anchor functions first?"); 20 return 0; 21 } 22 return aCoord->AsLengthPercentage().Resolve(0); 23 }; 24 25 if (GetPrevInFlow()) { 26 return; // Already added. 27 } 28 29 WritingMode wm = GetWritingMode(); 30 Side startSide = wm.PhysicalSideForInlineAxis(LogicalEdge::Start); 31 Side endSide = wm.PhysicalSideForInlineAxis(LogicalEdge::End); 32 33 const nsStylePadding* stylePadding = StylePadding(); 34 const nsStyleBorder* styleBorder = StyleBorder(); 35 const nsStyleMargin* styleMargin = StyleMargin(); 36 const auto anchorResolutionParams = AnchorPosResolutionParams::From(this); 37 38 // This goes at the beginning no matter how things are broken and how 39 // messy the bidi situations are, since per CSS2.1 section 8.6 40 // (implemented in bug 328168), the startSide border is always on the 41 // first line. 42 // This frame is a first-in-flow, but it might have a previous bidi 43 // continuation, in which case that continuation should handle the startSide 44 // border. 45 // For box-decoration-break:clone we setup clonePBM = startPBM + endPBM and 46 // add that to each line. For box-decoration-break:slice clonePBM is zero. 47 nscoord clonePBM = 0; // PBM = PaddingBorderMargin 48 const bool sliceBreak = 49 styleBorder->mBoxDecorationBreak == StyleBoxDecorationBreak::Slice; 50 if (!GetPrevContinuation() || MOZ_UNLIKELY(!sliceBreak)) { 51 nscoord startPBM = 52 // clamp negative calc() to 0 53 std::max(stylePadding->mPadding.Get(startSide).Resolve(0), 0) + 54 styleBorder->GetComputedBorderWidth(startSide) + 55 GetMargin(styleMargin->GetMargin(startSide, anchorResolutionParams)); 56 if (MOZ_LIKELY(sliceBreak)) { 57 aData->mCurrentLine += startPBM; 58 } else { 59 clonePBM = startPBM; 60 } 61 } 62 63 nscoord endPBM = 64 // clamp negative calc() to 0 65 std::max(stylePadding->mPadding.Get(endSide).Resolve(0), 0) + 66 styleBorder->GetComputedBorderWidth(endSide) + 67 GetMargin(styleMargin->GetMargin(endSide, anchorResolutionParams)); 68 if (MOZ_UNLIKELY(!sliceBreak)) { 69 clonePBM += endPBM; 70 aData->mCurrentLine += clonePBM; 71 } 72 73 const LineListIterator* savedLine = aData->mLine; 74 nsIFrame* const savedLineContainer = aData->LineContainer(); 75 76 nsContainerFrame* lastInFlow; 77 for (nsContainerFrame* nif = this; nif; 78 nif = static_cast<nsContainerFrame*>(nif->GetNextInFlow())) { 79 if (aData->mCurrentLine == 0) { 80 aData->mCurrentLine = clonePBM; 81 } 82 aHandleChildren(nif, aData); 83 84 // After we advance to our next-in-flow, the stored line and line container 85 // may no longer be correct. Just forget them. 86 aData->mLine = nullptr; 87 aData->SetLineContainer(nullptr); 88 89 lastInFlow = nif; 90 } 91 92 aData->mLine = savedLine; 93 aData->SetLineContainer(savedLineContainer); 94 95 // This goes at the end no matter how things are broken and how 96 // messy the bidi situations are, since per CSS2.1 section 8.6 97 // (implemented in bug 328168), the endSide border is always on the 98 // last line. 99 // We reached the last-in-flow, but it might have a next bidi 100 // continuation, in which case that continuation should handle 101 // the endSide border. 102 if (MOZ_LIKELY(!lastInFlow->GetNextContinuation() && sliceBreak)) { 103 aData->mCurrentLine += endPBM; 104 } 105 } 106 107 #endif // nsContainerFrameInlines_h___