gfx/src/nsRect.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

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 #ifndef NSRECT_H
michael@0 8 #define NSRECT_H
michael@0 9
michael@0 10 #include <stdio.h> // for FILE
michael@0 11 #include <stdint.h> // for int32_t, int64_t
michael@0 12 #include <algorithm> // for min/max
michael@0 13 #include "nsDebug.h" // for NS_WARNING
michael@0 14 #include "gfxCore.h" // for NS_GFX
michael@0 15 #include "mozilla/Likely.h" // for MOZ_UNLIKELY
michael@0 16 #include "mozilla/gfx/BaseRect.h" // for BaseRect
michael@0 17 #include "nsCoord.h" // for nscoord, etc
michael@0 18 #include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
michael@0 19 #include "nsPoint.h" // for nsIntPoint, nsPoint
michael@0 20 #include "nsSize.h" // for nsIntSize, nsSize
michael@0 21 #include "nscore.h" // for NS_BUILD_REFCNT_LOGGING
michael@0 22
michael@0 23 struct nsIntRect;
michael@0 24 struct nsMargin;
michael@0 25 struct nsIntMargin;
michael@0 26
michael@0 27 struct NS_GFX nsRect :
michael@0 28 public mozilla::gfx::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> {
michael@0 29 typedef mozilla::gfx::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> Super;
michael@0 30
michael@0 31 static void VERIFY_COORD(nscoord aValue) { ::VERIFY_COORD(aValue); }
michael@0 32
michael@0 33 // Constructors
michael@0 34 nsRect() : Super()
michael@0 35 {
michael@0 36 MOZ_COUNT_CTOR(nsRect);
michael@0 37 }
michael@0 38 nsRect(const nsRect& aRect) : Super(aRect)
michael@0 39 {
michael@0 40 MOZ_COUNT_CTOR(nsRect);
michael@0 41 }
michael@0 42 nsRect(const nsPoint& aOrigin, const nsSize &aSize) : Super(aOrigin, aSize)
michael@0 43 {
michael@0 44 MOZ_COUNT_CTOR(nsRect);
michael@0 45 }
michael@0 46 nsRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight) :
michael@0 47 Super(aX, aY, aWidth, aHeight)
michael@0 48 {
michael@0 49 MOZ_COUNT_CTOR(nsRect);
michael@0 50 }
michael@0 51
michael@0 52 #ifdef NS_BUILD_REFCNT_LOGGING
michael@0 53 ~nsRect() {
michael@0 54 MOZ_COUNT_DTOR(nsRect);
michael@0 55 }
michael@0 56 #endif
michael@0 57
michael@0 58 // We have saturating versions of all the Union methods. These avoid
michael@0 59 // overflowing nscoord values in the 'width' and 'height' fields by
michael@0 60 // clamping the width and height values to nscoord_MAX if necessary.
michael@0 61
michael@0 62 nsRect SaturatingUnion(const nsRect& aRect) const
michael@0 63 {
michael@0 64 if (IsEmpty()) {
michael@0 65 return aRect;
michael@0 66 } else if (aRect.IsEmpty()) {
michael@0 67 return *static_cast<const nsRect*>(this);
michael@0 68 } else {
michael@0 69 return SaturatingUnionEdges(aRect);
michael@0 70 }
michael@0 71 }
michael@0 72
michael@0 73 nsRect SaturatingUnionEdges(const nsRect& aRect) const
michael@0 74 {
michael@0 75 #ifdef NS_COORD_IS_FLOAT
michael@0 76 return UnionEdges(aRect);
michael@0 77 #else
michael@0 78 nsRect result;
michael@0 79 result.x = std::min(aRect.x, x);
michael@0 80 int64_t w = std::max(int64_t(aRect.x) + aRect.width, int64_t(x) + width) - result.x;
michael@0 81 if (MOZ_UNLIKELY(w > nscoord_MAX)) {
michael@0 82 NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord width");
michael@0 83 // Clamp huge negative x to nscoord_MIN / 2 and try again.
michael@0 84 result.x = std::max(result.x, nscoord_MIN / 2);
michael@0 85 w = std::max(int64_t(aRect.x) + aRect.width, int64_t(x) + width) - result.x;
michael@0 86 if (MOZ_UNLIKELY(w > nscoord_MAX)) {
michael@0 87 w = nscoord_MAX;
michael@0 88 }
michael@0 89 }
michael@0 90 result.width = nscoord(w);
michael@0 91
michael@0 92 result.y = std::min(aRect.y, y);
michael@0 93 int64_t h = std::max(int64_t(aRect.y) + aRect.height, int64_t(y) + height) - result.y;
michael@0 94 if (MOZ_UNLIKELY(h > nscoord_MAX)) {
michael@0 95 NS_WARNING("Overflowed nscoord_MAX in conversion to nscoord height");
michael@0 96 // Clamp huge negative y to nscoord_MIN / 2 and try again.
michael@0 97 result.y = std::max(result.y, nscoord_MIN / 2);
michael@0 98 h = std::max(int64_t(aRect.y) + aRect.height, int64_t(y) + height) - result.y;
michael@0 99 if (MOZ_UNLIKELY(h > nscoord_MAX)) {
michael@0 100 h = nscoord_MAX;
michael@0 101 }
michael@0 102 }
michael@0 103 result.height = nscoord(h);
michael@0 104 return result;
michael@0 105 #endif
michael@0 106 }
michael@0 107
michael@0 108 #ifndef NS_COORD_IS_FLOAT
michael@0 109 // Make all nsRect Union methods be saturating.
michael@0 110 nsRect UnionEdges(const nsRect& aRect) const
michael@0 111 {
michael@0 112 return SaturatingUnionEdges(aRect);
michael@0 113 }
michael@0 114 void UnionRectEdges(const nsRect& aRect1, const nsRect& aRect2)
michael@0 115 {
michael@0 116 *this = aRect1.UnionEdges(aRect2);
michael@0 117 }
michael@0 118 nsRect Union(const nsRect& aRect) const
michael@0 119 {
michael@0 120 return SaturatingUnion(aRect);
michael@0 121 }
michael@0 122 void UnionRect(const nsRect& aRect1, const nsRect& aRect2)
michael@0 123 {
michael@0 124 *this = aRect1.Union(aRect2);
michael@0 125 }
michael@0 126 #endif
michael@0 127
michael@0 128 void SaturatingUnionRect(const nsRect& aRect1, const nsRect& aRect2)
michael@0 129 {
michael@0 130 *this = aRect1.SaturatingUnion(aRect2);
michael@0 131 }
michael@0 132 void SaturatingUnionRectEdges(const nsRect& aRect1, const nsRect& aRect2)
michael@0 133 {
michael@0 134 *this = aRect1.SaturatingUnionEdges(aRect2);
michael@0 135 }
michael@0 136
michael@0 137 // Converts this rect from aFromAPP, an appunits per pixel ratio, to aToAPP.
michael@0 138 // In the RoundOut version we make the rect the smallest rect containing the
michael@0 139 // unrounded result. In the RoundIn version we make the rect the largest rect
michael@0 140 // contained in the unrounded result.
michael@0 141 // Note: this can turn an empty rectangle into a non-empty rectangle
michael@0 142 inline nsRect ConvertAppUnitsRoundOut(int32_t aFromAPP, int32_t aToAPP) const;
michael@0 143 inline nsRect ConvertAppUnitsRoundIn(int32_t aFromAPP, int32_t aToAPP) const;
michael@0 144
michael@0 145 inline nsIntRect ScaleToNearestPixels(float aXScale, float aYScale,
michael@0 146 nscoord aAppUnitsPerPixel) const;
michael@0 147 inline nsIntRect ToNearestPixels(nscoord aAppUnitsPerPixel) const;
michael@0 148 // Note: this can turn an empty rectangle into a non-empty rectangle
michael@0 149 inline nsIntRect ScaleToOutsidePixels(float aXScale, float aYScale,
michael@0 150 nscoord aAppUnitsPerPixel) const;
michael@0 151 // Note: this can turn an empty rectangle into a non-empty rectangle
michael@0 152 inline nsIntRect ToOutsidePixels(nscoord aAppUnitsPerPixel) const;
michael@0 153 inline nsIntRect ScaleToInsidePixels(float aXScale, float aYScale,
michael@0 154 nscoord aAppUnitsPerPixel) const;
michael@0 155 inline nsIntRect ToInsidePixels(nscoord aAppUnitsPerPixel) const;
michael@0 156
michael@0 157 // This is here only to keep IPDL-generated code happy. DO NOT USE.
michael@0 158 bool operator==(const nsRect& aRect) const
michael@0 159 {
michael@0 160 return IsEqualEdges(aRect);
michael@0 161 }
michael@0 162 };
michael@0 163
michael@0 164 struct NS_GFX nsIntRect :
michael@0 165 public mozilla::gfx::BaseRect<int32_t, nsIntRect, nsIntPoint, nsIntSize, nsIntMargin> {
michael@0 166 typedef mozilla::gfx::BaseRect<int32_t, nsIntRect, nsIntPoint, nsIntSize, nsIntMargin> Super;
michael@0 167
michael@0 168 // Constructors
michael@0 169 nsIntRect() : Super()
michael@0 170 {
michael@0 171 }
michael@0 172 nsIntRect(const nsIntRect& aRect) : Super(aRect)
michael@0 173 {
michael@0 174 }
michael@0 175 nsIntRect(const nsIntPoint& aOrigin, const nsIntSize &aSize) : Super(aOrigin, aSize)
michael@0 176 {
michael@0 177 }
michael@0 178 nsIntRect(int32_t aX, int32_t aY, int32_t aWidth, int32_t aHeight) :
michael@0 179 Super(aX, aY, aWidth, aHeight)
michael@0 180 {
michael@0 181 }
michael@0 182
michael@0 183 inline nsRect ToAppUnits(nscoord aAppUnitsPerPixel) const;
michael@0 184
michael@0 185 // Returns a special nsIntRect that's used in some places to signify
michael@0 186 // "all available space".
michael@0 187 static const nsIntRect& GetMaxSizedIntRect() {
michael@0 188 static const nsIntRect r(0, 0, INT32_MAX, INT32_MAX);
michael@0 189 return r;
michael@0 190 }
michael@0 191
michael@0 192 // This is here only to keep IPDL-generated code happy. DO NOT USE.
michael@0 193 bool operator==(const nsIntRect& aRect) const
michael@0 194 {
michael@0 195 return IsEqualEdges(aRect);
michael@0 196 }
michael@0 197 };
michael@0 198
michael@0 199 /*
michael@0 200 * App Unit/Pixel conversions
michael@0 201 */
michael@0 202
michael@0 203 inline nsRect
michael@0 204 nsRect::ConvertAppUnitsRoundOut(int32_t aFromAPP, int32_t aToAPP) const
michael@0 205 {
michael@0 206 if (aFromAPP == aToAPP) {
michael@0 207 return *this;
michael@0 208 }
michael@0 209
michael@0 210 nsRect rect;
michael@0 211 nscoord right = NSToCoordCeil(NSCoordScale(XMost(), aFromAPP, aToAPP));
michael@0 212 nscoord bottom = NSToCoordCeil(NSCoordScale(YMost(), aFromAPP, aToAPP));
michael@0 213 rect.x = NSToCoordFloor(NSCoordScale(x, aFromAPP, aToAPP));
michael@0 214 rect.y = NSToCoordFloor(NSCoordScale(y, aFromAPP, aToAPP));
michael@0 215 rect.width = (right - rect.x);
michael@0 216 rect.height = (bottom - rect.y);
michael@0 217
michael@0 218 return rect;
michael@0 219 }
michael@0 220
michael@0 221 inline nsRect
michael@0 222 nsRect::ConvertAppUnitsRoundIn(int32_t aFromAPP, int32_t aToAPP) const
michael@0 223 {
michael@0 224 if (aFromAPP == aToAPP) {
michael@0 225 return *this;
michael@0 226 }
michael@0 227
michael@0 228 nsRect rect;
michael@0 229 nscoord right = NSToCoordFloor(NSCoordScale(XMost(), aFromAPP, aToAPP));
michael@0 230 nscoord bottom = NSToCoordFloor(NSCoordScale(YMost(), aFromAPP, aToAPP));
michael@0 231 rect.x = NSToCoordCeil(NSCoordScale(x, aFromAPP, aToAPP));
michael@0 232 rect.y = NSToCoordCeil(NSCoordScale(y, aFromAPP, aToAPP));
michael@0 233 rect.width = (right - rect.x);
michael@0 234 rect.height = (bottom - rect.y);
michael@0 235
michael@0 236 return rect;
michael@0 237 }
michael@0 238
michael@0 239 // scale the rect but round to preserve centers
michael@0 240 inline nsIntRect
michael@0 241 nsRect::ScaleToNearestPixels(float aXScale, float aYScale,
michael@0 242 nscoord aAppUnitsPerPixel) const
michael@0 243 {
michael@0 244 nsIntRect rect;
michael@0 245 rect.x = NSToIntRoundUp(NSAppUnitsToDoublePixels(x, aAppUnitsPerPixel) * aXScale);
michael@0 246 rect.y = NSToIntRoundUp(NSAppUnitsToDoublePixels(y, aAppUnitsPerPixel) * aYScale);
michael@0 247 rect.width = NSToIntRoundUp(NSAppUnitsToDoublePixels(XMost(),
michael@0 248 aAppUnitsPerPixel) * aXScale) - rect.x;
michael@0 249 rect.height = NSToIntRoundUp(NSAppUnitsToDoublePixels(YMost(),
michael@0 250 aAppUnitsPerPixel) * aYScale) - rect.y;
michael@0 251 return rect;
michael@0 252 }
michael@0 253
michael@0 254 // scale the rect but round to smallest containing rect
michael@0 255 inline nsIntRect
michael@0 256 nsRect::ScaleToOutsidePixels(float aXScale, float aYScale,
michael@0 257 nscoord aAppUnitsPerPixel) const
michael@0 258 {
michael@0 259 nsIntRect rect;
michael@0 260 rect.x = NSToIntFloor(NSAppUnitsToFloatPixels(x, float(aAppUnitsPerPixel)) * aXScale);
michael@0 261 rect.y = NSToIntFloor(NSAppUnitsToFloatPixels(y, float(aAppUnitsPerPixel)) * aYScale);
michael@0 262 rect.width = NSToIntCeil(NSAppUnitsToFloatPixels(XMost(),
michael@0 263 float(aAppUnitsPerPixel)) * aXScale) - rect.x;
michael@0 264 rect.height = NSToIntCeil(NSAppUnitsToFloatPixels(YMost(),
michael@0 265 float(aAppUnitsPerPixel)) * aYScale) - rect.y;
michael@0 266 return rect;
michael@0 267 }
michael@0 268
michael@0 269 // scale the rect but round to largest contained rect
michael@0 270 inline nsIntRect
michael@0 271 nsRect::ScaleToInsidePixels(float aXScale, float aYScale,
michael@0 272 nscoord aAppUnitsPerPixel) const
michael@0 273 {
michael@0 274 nsIntRect rect;
michael@0 275 rect.x = NSToIntCeil(NSAppUnitsToFloatPixels(x, float(aAppUnitsPerPixel)) * aXScale);
michael@0 276 rect.y = NSToIntCeil(NSAppUnitsToFloatPixels(y, float(aAppUnitsPerPixel)) * aYScale);
michael@0 277 rect.width = NSToIntFloor(NSAppUnitsToFloatPixels(XMost(),
michael@0 278 float(aAppUnitsPerPixel)) * aXScale) - rect.x;
michael@0 279 rect.height = NSToIntFloor(NSAppUnitsToFloatPixels(YMost(),
michael@0 280 float(aAppUnitsPerPixel)) * aYScale) - rect.y;
michael@0 281 return rect;
michael@0 282 }
michael@0 283
michael@0 284 inline nsIntRect
michael@0 285 nsRect::ToNearestPixels(nscoord aAppUnitsPerPixel) const
michael@0 286 {
michael@0 287 return ScaleToNearestPixels(1.0f, 1.0f, aAppUnitsPerPixel);
michael@0 288 }
michael@0 289
michael@0 290 inline nsIntRect
michael@0 291 nsRect::ToOutsidePixels(nscoord aAppUnitsPerPixel) const
michael@0 292 {
michael@0 293 return ScaleToOutsidePixels(1.0f, 1.0f, aAppUnitsPerPixel);
michael@0 294 }
michael@0 295
michael@0 296 inline nsIntRect
michael@0 297 nsRect::ToInsidePixels(nscoord aAppUnitsPerPixel) const
michael@0 298 {
michael@0 299 return ScaleToInsidePixels(1.0f, 1.0f, aAppUnitsPerPixel);
michael@0 300 }
michael@0 301
michael@0 302 // app units are integer multiples of pixels, so no rounding needed
michael@0 303 inline nsRect
michael@0 304 nsIntRect::ToAppUnits(nscoord aAppUnitsPerPixel) const
michael@0 305 {
michael@0 306 return nsRect(NSIntPixelsToAppUnits(x, aAppUnitsPerPixel),
michael@0 307 NSIntPixelsToAppUnits(y, aAppUnitsPerPixel),
michael@0 308 NSIntPixelsToAppUnits(width, aAppUnitsPerPixel),
michael@0 309 NSIntPixelsToAppUnits(height, aAppUnitsPerPixel));
michael@0 310 }
michael@0 311
michael@0 312 #ifdef DEBUG
michael@0 313 // Diagnostics
michael@0 314 extern NS_GFX FILE* operator<<(FILE* out, const nsRect& rect);
michael@0 315 #endif // DEBUG
michael@0 316
michael@0 317 #endif /* NSRECT_H */

mercurial