gfx/src/nsRegion.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 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5
michael@0 6 #ifndef nsRegion_h__
michael@0 7 #define nsRegion_h__
michael@0 8
michael@0 9 #include <stddef.h> // for size_t
michael@0 10 #include <stdint.h> // for uint32_t, uint64_t
michael@0 11 #include <sys/types.h> // for int32_t
michael@0 12 #include "gfxCore.h" // for NS_GFX
michael@0 13 #include "nsCoord.h" // for nscoord
michael@0 14 #include "nsError.h" // for nsresult
michael@0 15 #include "nsPoint.h" // for nsIntPoint, nsPoint
michael@0 16 #include "nsRect.h" // for nsIntRect, nsRect
michael@0 17 #include "nsMargin.h" // for nsIntMargin
michael@0 18 #include "nsStringGlue.h" // for nsCString
michael@0 19 #include "xpcom-config.h" // for CPP_THROW_NEW
michael@0 20
michael@0 21 class nsIntRegion;
michael@0 22
michael@0 23 #include "pixman.h"
michael@0 24
michael@0 25 /* For information on the internal representation look at pixman-region.c
michael@0 26 *
michael@0 27 * This replaces an older homebrew implementation of nsRegion. The
michael@0 28 * representation used here may use more rectangles than nsRegion however, the
michael@0 29 * representation is canonical. This means that there's no need for an
michael@0 30 * Optimize() method because for a paticular region there is only one
michael@0 31 * representation. This means that nsIntRegion will have more predictable
michael@0 32 * performance characteristics than the old nsRegion and should not become
michael@0 33 * degenerate.
michael@0 34 *
michael@0 35 * The pixman region code originates from X11 which has spread to a variety of
michael@0 36 * projects including Qt, Gtk, Wine. It should perform reasonably well.
michael@0 37 */
michael@0 38
michael@0 39 class nsRegionRectIterator;
michael@0 40
michael@0 41 class nsRegion
michael@0 42 {
michael@0 43
michael@0 44 friend class nsRegionRectIterator;
michael@0 45
michael@0 46 public:
michael@0 47 nsRegion () { pixman_region32_init(&mImpl); }
michael@0 48 nsRegion (const nsRect& aRect) { pixman_region32_init_rect(&mImpl,
michael@0 49 aRect.x,
michael@0 50 aRect.y,
michael@0 51 aRect.width,
michael@0 52 aRect.height); }
michael@0 53 nsRegion (const nsRegion& aRegion) { pixman_region32_init(&mImpl); pixman_region32_copy(&mImpl,aRegion.Impl()); }
michael@0 54 ~nsRegion () { pixman_region32_fini(&mImpl); }
michael@0 55 nsRegion& operator = (const nsRect& aRect) { Copy (aRect); return *this; }
michael@0 56 nsRegion& operator = (const nsRegion& aRegion) { Copy (aRegion); return *this; }
michael@0 57 bool operator==(const nsRegion& aRgn) const
michael@0 58 {
michael@0 59 return IsEqual(aRgn);
michael@0 60 }
michael@0 61
michael@0 62 void Swap(nsRegion* aOther)
michael@0 63 {
michael@0 64 pixman_region32_t tmp = mImpl;
michael@0 65 mImpl = aOther->mImpl;
michael@0 66 aOther->mImpl = tmp;
michael@0 67 }
michael@0 68
michael@0 69 static
michael@0 70 nsresult InitStatic()
michael@0 71 {
michael@0 72 return NS_OK;
michael@0 73 }
michael@0 74
michael@0 75 static
michael@0 76 void ShutdownStatic() {}
michael@0 77
michael@0 78 nsRegion& And(const nsRegion& aRgn1, const nsRegion& aRgn2)
michael@0 79 {
michael@0 80 pixman_region32_intersect(&mImpl, aRgn1.Impl(), aRgn2.Impl());
michael@0 81 return *this;
michael@0 82 }
michael@0 83 nsRegion& And(const nsRect& aRect, const nsRegion& aRegion)
michael@0 84 {
michael@0 85 return And(aRegion, aRect);
michael@0 86 }
michael@0 87 nsRegion& And(const nsRegion& aRegion, const nsRect& aRect)
michael@0 88 {
michael@0 89 pixman_region32_intersect_rect(&mImpl, aRegion.Impl(), aRect.x, aRect.y, aRect.width, aRect.height);
michael@0 90 return *this;
michael@0 91 }
michael@0 92 nsRegion& And(const nsRect& aRect1, const nsRect& aRect2)
michael@0 93 {
michael@0 94 nsRect TmpRect;
michael@0 95
michael@0 96 TmpRect.IntersectRect(aRect1, aRect2);
michael@0 97 return Copy(TmpRect);
michael@0 98 }
michael@0 99
michael@0 100 nsRegion& Or(const nsRegion& aRgn1, const nsRegion& aRgn2)
michael@0 101 {
michael@0 102 pixman_region32_union(&mImpl, aRgn1.Impl(), aRgn2.Impl());
michael@0 103 return *this;
michael@0 104 }
michael@0 105 nsRegion& Or(const nsRegion& aRegion, const nsRect& aRect)
michael@0 106 {
michael@0 107 pixman_region32_union_rect(&mImpl, aRegion.Impl(), aRect.x, aRect.y, aRect.width, aRect.height);
michael@0 108 return *this;
michael@0 109 }
michael@0 110 nsRegion& Or(const nsRect& aRect, const nsRegion& aRegion)
michael@0 111 {
michael@0 112 return Or(aRegion, aRect);
michael@0 113 }
michael@0 114 nsRegion& Or(const nsRect& aRect1, const nsRect& aRect2)
michael@0 115 {
michael@0 116 Copy (aRect1);
michael@0 117 return Or (*this, aRect2);
michael@0 118 }
michael@0 119
michael@0 120 nsRegion& Xor(const nsRegion& aRgn1, const nsRegion& aRgn2)
michael@0 121 {
michael@0 122 // this could be implemented better if pixman had direct
michael@0 123 // support for xoring regions.
michael@0 124 nsRegion p;
michael@0 125 p.Sub(aRgn1, aRgn2);
michael@0 126 nsRegion q;
michael@0 127 q.Sub(aRgn2, aRgn1);
michael@0 128 return Or(p, q);
michael@0 129 }
michael@0 130 nsRegion& Xor(const nsRegion& aRegion, const nsRect& aRect)
michael@0 131 {
michael@0 132 return Xor(aRegion, nsRegion(aRect));
michael@0 133 }
michael@0 134 nsRegion& Xor(const nsRect& aRect, const nsRegion& aRegion)
michael@0 135 {
michael@0 136 return Xor(nsRegion(aRect), aRegion);
michael@0 137 }
michael@0 138 nsRegion& Xor(const nsRect& aRect1, const nsRect& aRect2)
michael@0 139 {
michael@0 140 return Xor(nsRegion(aRect1), nsRegion(aRect2));
michael@0 141 }
michael@0 142
michael@0 143 nsRegion ToAppUnits (nscoord aAppUnitsPerPixel) const;
michael@0 144 nsRegion& Sub(const nsRegion& aRgn1, const nsRegion& aRgn2)
michael@0 145 {
michael@0 146 pixman_region32_subtract(&mImpl, aRgn1.Impl(), aRgn2.Impl());
michael@0 147 return *this;
michael@0 148 }
michael@0 149 nsRegion& Sub(const nsRegion& aRegion, const nsRect& aRect)
michael@0 150 {
michael@0 151 return Sub(aRegion, nsRegion(aRect));
michael@0 152 }
michael@0 153 nsRegion& Sub(const nsRect& aRect, const nsRegion& aRegion)
michael@0 154 {
michael@0 155 return Sub(nsRegion(aRect), aRegion);
michael@0 156 }
michael@0 157 nsRegion& Sub(const nsRect& aRect1, const nsRect& aRect2)
michael@0 158 {
michael@0 159 Copy(aRect1);
michael@0 160 return Sub(*this, aRect2);
michael@0 161 }
michael@0 162
michael@0 163 bool Contains (const nsRect& aRect) const
michael@0 164 {
michael@0 165 pixman_box32_t box = RectToBox(aRect);
michael@0 166 return pixman_region32_contains_rectangle(Impl(), &box) == PIXMAN_REGION_IN;
michael@0 167 }
michael@0 168 bool Contains (const nsRegion& aRgn) const;
michael@0 169 bool Intersects (const nsRect& aRect) const;
michael@0 170
michael@0 171 void MoveBy (int32_t aXOffset, int32_t aYOffset)
michael@0 172 {
michael@0 173 MoveBy (nsPoint (aXOffset, aYOffset));
michael@0 174 }
michael@0 175 void MoveBy (nsPoint aPt) { pixman_region32_translate(&mImpl, aPt.x, aPt.y); }
michael@0 176 void SetEmpty ()
michael@0 177 {
michael@0 178 pixman_region32_clear(&mImpl);
michael@0 179 }
michael@0 180
michael@0 181 nsRegion MovedBy(int32_t aXOffset, int32_t aYOffset) const
michael@0 182 {
michael@0 183 return MovedBy(nsPoint(aXOffset, aYOffset));
michael@0 184 }
michael@0 185 nsRegion MovedBy(const nsPoint& aPt) const
michael@0 186 {
michael@0 187 nsRegion copy(*this);
michael@0 188 copy.MoveBy(aPt);
michael@0 189 return copy;
michael@0 190 }
michael@0 191
michael@0 192 nsRegion Intersect(const nsRegion& aOther) const
michael@0 193 {
michael@0 194 nsRegion intersection;
michael@0 195 intersection.And(*this, aOther);
michael@0 196 return intersection;
michael@0 197 }
michael@0 198
michael@0 199 void Inflate(const nsMargin& aMargin);
michael@0 200
michael@0 201 nsRegion Inflated(const nsMargin& aMargin) const
michael@0 202 {
michael@0 203 nsRegion copy(*this);
michael@0 204 copy.Inflate(aMargin);
michael@0 205 return copy;
michael@0 206 }
michael@0 207
michael@0 208 bool IsEmpty () const { return !pixman_region32_not_empty(Impl()); }
michael@0 209 bool IsComplex () const { return GetNumRects() > 1; }
michael@0 210 bool IsEqual (const nsRegion& aRegion) const
michael@0 211 {
michael@0 212 return pixman_region32_equal(Impl(), aRegion.Impl());
michael@0 213 }
michael@0 214 uint32_t GetNumRects () const { return pixman_region32_n_rects(Impl()); }
michael@0 215 const nsRect GetBounds () const { return BoxToRect(mImpl.extents); }
michael@0 216 uint64_t Area () const;
michael@0 217 // Converts this region from aFromAPP, an appunits per pixel ratio, to
michael@0 218 // aToAPP. This applies nsRect::ConvertAppUnitsRoundOut/In to each rect of
michael@0 219 // the region.
michael@0 220 nsRegion ConvertAppUnitsRoundOut (int32_t aFromAPP, int32_t aToAPP) const;
michael@0 221 nsRegion ConvertAppUnitsRoundIn (int32_t aFromAPP, int32_t aToAPP) const;
michael@0 222 nsRegion& ScaleRoundOut(float aXScale, float aYScale);
michael@0 223 nsRegion& ScaleInverseRoundOut(float aXScale, float aYScale);
michael@0 224 nsIntRegion ScaleToOutsidePixels (float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const;
michael@0 225 nsIntRegion ScaleToInsidePixels (float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const;
michael@0 226 nsIntRegion ScaleToNearestPixels (float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const;
michael@0 227 nsIntRegion ToOutsidePixels (nscoord aAppUnitsPerPixel) const;
michael@0 228 nsIntRegion ToNearestPixels (nscoord aAppUnitsPerPixel) const;
michael@0 229
michael@0 230 /**
michael@0 231 * Gets the largest rectangle contained in the region.
michael@0 232 * @param aContainingRect if non-empty, we choose a rectangle that
michael@0 233 * maximizes the area intersecting with aContainingRect (and break ties by
michael@0 234 * then choosing the largest rectangle overall)
michael@0 235 */
michael@0 236 nsRect GetLargestRectangle (const nsRect& aContainingRect = nsRect()) const;
michael@0 237
michael@0 238 /**
michael@0 239 * Make sure the region has at most aMaxRects by adding area to it
michael@0 240 * if necessary. The simplified region will be a superset of the
michael@0 241 * original region. The simplified region's bounding box will be
michael@0 242 * the same as for the current region.
michael@0 243 */
michael@0 244 void SimplifyOutward (uint32_t aMaxRects);
michael@0 245 /**
michael@0 246 * Simplify the region by adding at most aThreshold area between spans of
michael@0 247 * rects. The simplified region will be a superset of the original region.
michael@0 248 * The simplified region's bounding box will be the same as for the current
michael@0 249 * region.
michael@0 250 */
michael@0 251 void SimplifyOutwardByArea(uint32_t aThreshold);
michael@0 252 /**
michael@0 253 * Make sure the region has at most aMaxRects by removing area from
michael@0 254 * it if necessary. The simplified region will be a subset of the
michael@0 255 * original region.
michael@0 256 */
michael@0 257 void SimplifyInward (uint32_t aMaxRects);
michael@0 258
michael@0 259 nsCString ToString() const;
michael@0 260 private:
michael@0 261 pixman_region32_t mImpl;
michael@0 262
michael@0 263 nsIntRegion ToPixels(nscoord aAppUnitsPerPixel, bool aOutsidePixels) const;
michael@0 264
michael@0 265 nsRegion& Copy (const nsRegion& aRegion)
michael@0 266 {
michael@0 267 pixman_region32_copy(&mImpl, aRegion.Impl());
michael@0 268 return *this;
michael@0 269 }
michael@0 270
michael@0 271 nsRegion& Copy (const nsRect& aRect)
michael@0 272 {
michael@0 273 // pixman needs to distinguish between an empty region and a region
michael@0 274 // with one rect so that it can return a different number of rectangles.
michael@0 275 // Empty rect: data = empty_box
michael@0 276 // 1 rect: data = null
michael@0 277 // >1 rect: data = rects
michael@0 278 if (aRect.IsEmpty()) {
michael@0 279 pixman_region32_clear(&mImpl);
michael@0 280 } else {
michael@0 281 pixman_box32_t box = RectToBox(aRect);
michael@0 282 pixman_region32_reset(&mImpl, &box);
michael@0 283 }
michael@0 284 return *this;
michael@0 285 }
michael@0 286
michael@0 287 static inline pixman_box32_t RectToBox(const nsRect &aRect)
michael@0 288 {
michael@0 289 pixman_box32_t box = { aRect.x, aRect.y, aRect.XMost(), aRect.YMost() };
michael@0 290 return box;
michael@0 291 }
michael@0 292
michael@0 293 static inline pixman_box32_t RectToBox(const nsIntRect &aRect)
michael@0 294 {
michael@0 295 pixman_box32_t box = { aRect.x, aRect.y, aRect.XMost(), aRect.YMost() };
michael@0 296 return box;
michael@0 297 }
michael@0 298
michael@0 299
michael@0 300 static inline nsRect BoxToRect(const pixman_box32_t &aBox)
michael@0 301 {
michael@0 302 return nsRect(aBox.x1, aBox.y1,
michael@0 303 aBox.x2 - aBox.x1,
michael@0 304 aBox.y2 - aBox.y1);
michael@0 305 }
michael@0 306
michael@0 307 pixman_region32_t* Impl() const
michael@0 308 {
michael@0 309 return const_cast<pixman_region32_t*>(&mImpl);
michael@0 310 }
michael@0 311
michael@0 312 };
michael@0 313
michael@0 314
michael@0 315 class NS_GFX nsRegionRectIterator
michael@0 316 {
michael@0 317 const nsRegion* mRegion;
michael@0 318 int i;
michael@0 319 int n;
michael@0 320 nsRect rect;
michael@0 321 pixman_box32_t *boxes;
michael@0 322
michael@0 323 public:
michael@0 324 nsRegionRectIterator (const nsRegion& aRegion)
michael@0 325 {
michael@0 326 mRegion = &aRegion;
michael@0 327 i = 0;
michael@0 328 boxes = pixman_region32_rectangles(aRegion.Impl(), &n);
michael@0 329 }
michael@0 330
michael@0 331 const nsRect* Next ()
michael@0 332 {
michael@0 333 if (i == n)
michael@0 334 return nullptr;
michael@0 335 rect = nsRegion::BoxToRect(boxes[i]);
michael@0 336 i++;
michael@0 337 return &rect;
michael@0 338 }
michael@0 339
michael@0 340 const nsRect* Prev ()
michael@0 341 {
michael@0 342 if (i == -1)
michael@0 343 return nullptr;
michael@0 344 rect = nsRegion::BoxToRect(boxes[i]);
michael@0 345 i--;
michael@0 346 return &rect;
michael@0 347 }
michael@0 348
michael@0 349 void Reset ()
michael@0 350 {
michael@0 351 i = 0;
michael@0 352 }
michael@0 353 };
michael@0 354
michael@0 355 /**
michael@0 356 * nsIntRegions use int32_t coordinates and nsIntRects.
michael@0 357 */
michael@0 358 class NS_GFX nsIntRegion
michael@0 359 {
michael@0 360 friend class nsIntRegionRectIterator;
michael@0 361 friend class nsRegion;
michael@0 362
michael@0 363 public:
michael@0 364 nsIntRegion () {}
michael@0 365 nsIntRegion (const nsIntRect& aRect) : mImpl (ToRect(aRect)) {}
michael@0 366 nsIntRegion (const nsIntRegion& aRegion) : mImpl (aRegion.mImpl) {}
michael@0 367 nsIntRegion& operator = (const nsIntRect& aRect) { mImpl = ToRect (aRect); return *this; }
michael@0 368 nsIntRegion& operator = (const nsIntRegion& aRegion) { mImpl = aRegion.mImpl; return *this; }
michael@0 369
michael@0 370 bool operator==(const nsIntRegion& aRgn) const
michael@0 371 {
michael@0 372 return IsEqual(aRgn);
michael@0 373 }
michael@0 374
michael@0 375 void Swap(nsIntRegion* aOther)
michael@0 376 {
michael@0 377 mImpl.Swap(&aOther->mImpl);
michael@0 378 }
michael@0 379
michael@0 380 nsIntRegion& And (const nsIntRegion& aRgn1, const nsIntRegion& aRgn2)
michael@0 381 {
michael@0 382 mImpl.And (aRgn1.mImpl, aRgn2.mImpl);
michael@0 383 return *this;
michael@0 384 }
michael@0 385 nsIntRegion& And (const nsIntRegion& aRegion, const nsIntRect& aRect)
michael@0 386 {
michael@0 387 mImpl.And (aRegion.mImpl, ToRect (aRect));
michael@0 388 return *this;
michael@0 389 }
michael@0 390 nsIntRegion& And (const nsIntRect& aRect, const nsIntRegion& aRegion)
michael@0 391 {
michael@0 392 return And (aRegion, aRect);
michael@0 393 }
michael@0 394 nsIntRegion& And (const nsIntRect& aRect1, const nsIntRect& aRect2)
michael@0 395 {
michael@0 396 nsIntRect TmpRect;
michael@0 397
michael@0 398 TmpRect.IntersectRect (aRect1, aRect2);
michael@0 399 mImpl = ToRect (TmpRect);
michael@0 400 return *this;
michael@0 401 }
michael@0 402
michael@0 403 nsIntRegion& Or (const nsIntRegion& aRgn1, const nsIntRegion& aRgn2)
michael@0 404 {
michael@0 405 mImpl.Or (aRgn1.mImpl, aRgn2.mImpl);
michael@0 406 return *this;
michael@0 407 }
michael@0 408 nsIntRegion& Or (const nsIntRegion& aRegion, const nsIntRect& aRect)
michael@0 409 {
michael@0 410 mImpl.Or (aRegion.mImpl, ToRect (aRect));
michael@0 411 return *this;
michael@0 412 }
michael@0 413 nsIntRegion& Or (const nsIntRect& aRect, const nsIntRegion& aRegion)
michael@0 414 {
michael@0 415 return Or (aRegion, aRect);
michael@0 416 }
michael@0 417 nsIntRegion& Or (const nsIntRect& aRect1, const nsIntRect& aRect2)
michael@0 418 {
michael@0 419 mImpl = ToRect (aRect1);
michael@0 420 return Or (*this, aRect2);
michael@0 421 }
michael@0 422
michael@0 423 nsIntRegion& Xor (const nsIntRegion& aRgn1, const nsIntRegion& aRgn2)
michael@0 424 {
michael@0 425 mImpl.Xor (aRgn1.mImpl, aRgn2.mImpl);
michael@0 426 return *this;
michael@0 427 }
michael@0 428 nsIntRegion& Xor (const nsIntRegion& aRegion, const nsIntRect& aRect)
michael@0 429 {
michael@0 430 mImpl.Xor (aRegion.mImpl, ToRect (aRect));
michael@0 431 return *this;
michael@0 432 }
michael@0 433 nsIntRegion& Xor (const nsIntRect& aRect, const nsIntRegion& aRegion)
michael@0 434 {
michael@0 435 return Xor (aRegion, aRect);
michael@0 436 }
michael@0 437 nsIntRegion& Xor (const nsIntRect& aRect1, const nsIntRect& aRect2)
michael@0 438 {
michael@0 439 mImpl = ToRect (aRect1);
michael@0 440 return Xor (*this, aRect2);
michael@0 441 }
michael@0 442
michael@0 443 nsIntRegion& Sub (const nsIntRegion& aRgn1, const nsIntRegion& aRgn2)
michael@0 444 {
michael@0 445 mImpl.Sub (aRgn1.mImpl, aRgn2.mImpl);
michael@0 446 return *this;
michael@0 447 }
michael@0 448 nsIntRegion& Sub (const nsIntRegion& aRegion, const nsIntRect& aRect)
michael@0 449 {
michael@0 450 mImpl.Sub (aRegion.mImpl, ToRect (aRect));
michael@0 451 return *this;
michael@0 452 }
michael@0 453 nsIntRegion& Sub (const nsIntRect& aRect, const nsIntRegion& aRegion)
michael@0 454 {
michael@0 455 return Sub (nsIntRegion (aRect), aRegion);
michael@0 456 }
michael@0 457 nsIntRegion& Sub (const nsIntRect& aRect1, const nsIntRect& aRect2)
michael@0 458 {
michael@0 459 mImpl = ToRect (aRect1);
michael@0 460 return Sub (*this, aRect2);
michael@0 461 }
michael@0 462
michael@0 463 bool Contains (const nsIntRect& aRect) const
michael@0 464 {
michael@0 465 return mImpl.Contains (ToRect (aRect));
michael@0 466 }
michael@0 467 bool Contains (const nsIntRegion& aRgn) const
michael@0 468 {
michael@0 469 return mImpl.Contains (aRgn.mImpl);
michael@0 470 }
michael@0 471 bool Intersects (const nsIntRect& aRect) const
michael@0 472 {
michael@0 473 return mImpl.Intersects (ToRect (aRect));
michael@0 474 }
michael@0 475
michael@0 476 void MoveBy (int32_t aXOffset, int32_t aYOffset)
michael@0 477 {
michael@0 478 MoveBy (nsIntPoint (aXOffset, aYOffset));
michael@0 479 }
michael@0 480 void MoveBy (nsIntPoint aPt)
michael@0 481 {
michael@0 482 mImpl.MoveBy (aPt.x, aPt.y);
michael@0 483 }
michael@0 484 nsIntRegion MovedBy(int32_t aXOffset, int32_t aYOffset) const
michael@0 485 {
michael@0 486 return MovedBy(nsIntPoint(aXOffset, aYOffset));
michael@0 487 }
michael@0 488 nsIntRegion MovedBy(const nsIntPoint& aPt) const
michael@0 489 {
michael@0 490 nsIntRegion copy(*this);
michael@0 491 copy.MoveBy(aPt);
michael@0 492 return copy;
michael@0 493 }
michael@0 494
michael@0 495 nsIntRegion Intersect(const nsIntRegion& aOther) const
michael@0 496 {
michael@0 497 nsIntRegion intersection;
michael@0 498 intersection.And(*this, aOther);
michael@0 499 return intersection;
michael@0 500 }
michael@0 501
michael@0 502 void Inflate(const nsIntMargin& aMargin)
michael@0 503 {
michael@0 504 mImpl.Inflate(nsMargin(aMargin.top, aMargin.right, aMargin.bottom, aMargin.left));
michael@0 505 }
michael@0 506 nsIntRegion Inflated(const nsIntMargin& aMargin) const
michael@0 507 {
michael@0 508 nsIntRegion copy(*this);
michael@0 509 copy.Inflate(aMargin);
michael@0 510 return copy;
michael@0 511 }
michael@0 512
michael@0 513 void SetEmpty ()
michael@0 514 {
michael@0 515 mImpl.SetEmpty ();
michael@0 516 }
michael@0 517
michael@0 518 bool IsEmpty () const { return mImpl.IsEmpty (); }
michael@0 519 bool IsComplex () const { return mImpl.IsComplex (); }
michael@0 520 bool IsEqual (const nsIntRegion& aRegion) const
michael@0 521 {
michael@0 522 return mImpl.IsEqual (aRegion.mImpl);
michael@0 523 }
michael@0 524 uint32_t GetNumRects () const { return mImpl.GetNumRects (); }
michael@0 525 nsIntRect GetBounds () const { return FromRect (mImpl.GetBounds ()); }
michael@0 526 uint64_t Area () const { return mImpl.Area(); }
michael@0 527 nsRegion ToAppUnits (nscoord aAppUnitsPerPixel) const;
michael@0 528 nsIntRect GetLargestRectangle (const nsIntRect& aContainingRect = nsIntRect()) const
michael@0 529 {
michael@0 530 return FromRect (mImpl.GetLargestRectangle( ToRect(aContainingRect) ));
michael@0 531 }
michael@0 532
michael@0 533 nsIntRegion& ScaleRoundOut (float aXScale, float aYScale)
michael@0 534 {
michael@0 535 mImpl.ScaleRoundOut(aXScale, aYScale);
michael@0 536 return *this;
michael@0 537 }
michael@0 538
michael@0 539 /**
michael@0 540 * Make sure the region has at most aMaxRects by adding area to it
michael@0 541 * if necessary. The simplified region will be a superset of the
michael@0 542 * original region. The simplified region's bounding box will be
michael@0 543 * the same as for the current region.
michael@0 544 */
michael@0 545 void SimplifyOutward (uint32_t aMaxRects)
michael@0 546 {
michael@0 547 mImpl.SimplifyOutward (aMaxRects);
michael@0 548 }
michael@0 549 void SimplifyOutwardByArea (uint32_t aThreshold)
michael@0 550 {
michael@0 551 mImpl.SimplifyOutwardByArea (aThreshold);
michael@0 552 }
michael@0 553 /**
michael@0 554 * Make sure the region has at most aMaxRects by removing area from
michael@0 555 * it if necessary. The simplified region will be a subset of the
michael@0 556 * original region.
michael@0 557 */
michael@0 558 void SimplifyInward (uint32_t aMaxRects)
michael@0 559 {
michael@0 560 mImpl.SimplifyInward (aMaxRects);
michael@0 561 }
michael@0 562
michael@0 563 nsCString ToString() const { return mImpl.ToString(); }
michael@0 564
michael@0 565 private:
michael@0 566 nsRegion mImpl;
michael@0 567
michael@0 568 static nsRect ToRect(const nsIntRect& aRect)
michael@0 569 {
michael@0 570 return nsRect (aRect.x, aRect.y, aRect.width, aRect.height);
michael@0 571 }
michael@0 572 static nsIntRect FromRect(const nsRect& aRect)
michael@0 573 {
michael@0 574 return nsIntRect (aRect.x, aRect.y, aRect.width, aRect.height);
michael@0 575 }
michael@0 576 };
michael@0 577
michael@0 578 class NS_GFX nsIntRegionRectIterator
michael@0 579 {
michael@0 580 nsRegionRectIterator mImpl;
michael@0 581 nsIntRect mTmp;
michael@0 582
michael@0 583 public:
michael@0 584 nsIntRegionRectIterator (const nsIntRegion& aRegion) : mImpl (aRegion.mImpl) {}
michael@0 585
michael@0 586 const nsIntRect* Next ()
michael@0 587 {
michael@0 588 const nsRect* r = mImpl.Next();
michael@0 589 if (!r)
michael@0 590 return nullptr;
michael@0 591 mTmp = nsIntRegion::FromRect (*r);
michael@0 592 return &mTmp;
michael@0 593 }
michael@0 594
michael@0 595 const nsIntRect* Prev ()
michael@0 596 {
michael@0 597 const nsRect* r = mImpl.Prev();
michael@0 598 if (!r)
michael@0 599 return nullptr;
michael@0 600 mTmp = nsIntRegion::FromRect (*r);
michael@0 601 return &mTmp;
michael@0 602 }
michael@0 603
michael@0 604 void Reset ()
michael@0 605 {
michael@0 606 mImpl.Reset ();
michael@0 607 }
michael@0 608 };
michael@0 609 #endif

mercurial