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.

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

mercurial