ReflowOutput.cpp (3023B)
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 /* struct containing the output from nsIFrame::Reflow */ 8 9 #include "mozilla/ReflowOutput.h" 10 11 #include "mozilla/ReflowInput.h" 12 #include "mozilla/WritingModes.h" 13 14 namespace mozilla { 15 16 static bool IsValidOverflowRect(const nsRect& aRect) { 17 // The reason we can't simply use `nsRect::IsEmpty` is that any one dimension 18 // being zero is considered empty by it - On the other hand, an overflow rect 19 // is valid if it has non-negative dimensions and at least one of them is 20 // non-zero. 21 return aRect.Size() != nsSize{0, 0} && aRect.Width() >= 0 && 22 aRect.Height() >= 0; 23 } 24 25 /* static */ 26 nsRect OverflowAreas::GetOverflowClipRect(const nsRect& aRectToClip, 27 const nsRect& aBounds, 28 PhysicalAxes aClipAxes, 29 const nsMargin& aOverflowMargin) { 30 auto inflatedBounds = aBounds; 31 inflatedBounds.Inflate(aOverflowMargin); 32 auto clip = aRectToClip; 33 if (aClipAxes.contains(PhysicalAxis::Vertical)) { 34 clip.y = inflatedBounds.y; 35 clip.height = inflatedBounds.height; 36 } 37 if (aClipAxes.contains(PhysicalAxis::Horizontal)) { 38 clip.x = inflatedBounds.x; 39 clip.width = inflatedBounds.width; 40 } 41 return clip; 42 } 43 44 /* static */ 45 void OverflowAreas::ApplyOverflowClippingOnRect( 46 nsRect& aOverflowRect, const nsRect& aBounds, PhysicalAxes aClipAxes, 47 const nsMargin& aOverflowMargin) { 48 aOverflowRect = aOverflowRect.Intersect( 49 GetOverflowClipRect(aOverflowRect, aBounds, aClipAxes, aOverflowMargin)); 50 } 51 52 void OverflowAreas::UnionWith(const OverflowAreas& aOther) { 53 if (IsValidOverflowRect(aOther.InkOverflow())) { 54 InkOverflow().UnionRect(InkOverflow(), aOther.InkOverflow()); 55 } 56 if (IsValidOverflowRect(aOther.ScrollableOverflow())) { 57 ScrollableOverflow().UnionRect(ScrollableOverflow(), 58 aOther.ScrollableOverflow()); 59 } 60 } 61 62 void OverflowAreas::UnionAllWith(const nsRect& aRect) { 63 if (!IsValidOverflowRect(aRect)) { 64 // Same as `UnionWith()` - avoid losing information. 65 return; 66 } 67 InkOverflow().UnionRect(InkOverflow(), aRect); 68 ScrollableOverflow().UnionRect(ScrollableOverflow(), aRect); 69 } 70 71 void OverflowAreas::SetAllTo(const nsRect& aRect) { 72 InkOverflow() = aRect; 73 ScrollableOverflow() = aRect; 74 } 75 76 ReflowOutput::ReflowOutput(const ReflowInput& aReflowInput) 77 : ReflowOutput(aReflowInput.GetWritingMode()) {} 78 79 void ReflowOutput::SetOverflowAreasToDesiredBounds() { 80 mOverflowAreas.SetAllTo(nsRect(0, 0, Width(), Height())); 81 } 82 83 void ReflowOutput::UnionOverflowAreasWithDesiredBounds() { 84 mOverflowAreas.UnionAllWith(nsRect(0, 0, Width(), Height())); 85 } 86 87 } // namespace mozilla