Bug 1224433 - Part 2: Clamp the invalidation rect to values that fit within nscoord. r=roc

--HG--
extra : rebase_source : 0aaede54d8622786cddaf8365e6bf091d6bff8f8
This commit is contained in:
Matt Woodrow 2016-02-12 11:35:17 +13:00
parent c731d0ed0c
commit 2f1cbec9a2
3 changed files with 31 additions and 20 deletions

View File

@ -545,6 +545,22 @@ struct BaseRect {
return rect;
}
// Returns the largest rectangle that can be represented with 32-bit
// signed integers, centered around a point at 0,0. As BaseRect's represent
// the dimensions as a top-left point with a width and height, the width
// and height will be the largest positive 32-bit value. The top-left
// position coordinate is divided by two to center the rectangle around a
// point at 0,0.
static Sub MaxIntRect()
{
return Sub(
-std::numeric_limits<int32_t>::max() * 0.5,
-std::numeric_limits<int32_t>::max() * 0.5,
std::numeric_limits<int32_t>::max(),
std::numeric_limits<int32_t>::max()
);
};
friend std::ostream& operator<<(std::ostream& stream,
const BaseRect<T, Sub, Point, SizeT, MarginT>& aRect) {
return stream << '(' << aRect.x << ',' << aRect.y << ','

View File

@ -156,22 +156,6 @@ struct RectTyped :
Super(F(rect.x), F(rect.y),
F(rect.width), F(rect.height)) {}
// Returns the largest rectangle that can be represented with 32-bit
// signed integers, centered around a point at 0,0. As BaseRect's represent
// the dimensions as a top-left point with a width and height, the width
// and height will be the largest positive 32-bit value. The top-left
// position coordinate is divided by two to center the rectangle around a
// point at 0,0.
static RectTyped<units, F> MaxIntRect()
{
return RectTyped<units, F>(
-std::numeric_limits<int32_t>::max() * 0.5,
-std::numeric_limits<int32_t>::max() * 0.5,
std::numeric_limits<int32_t>::max(),
std::numeric_limits<int32_t>::max()
);
};
void NudgeToIntegers()
{
NudgeToInteger(&(this->x));

View File

@ -2452,10 +2452,21 @@ nsPresContext::NotifyInvalidation(uint32_t aFlags)
void
nsPresContext::NotifyInvalidation(const nsIntRect& aRect, uint32_t aFlags)
{
nsRect rect(DevPixelsToAppUnits(aRect.x),
DevPixelsToAppUnits(aRect.y),
DevPixelsToAppUnits(aRect.width),
DevPixelsToAppUnits(aRect.height));
// Prevent values from overflow after DevPixelsToAppUnits().
//
// DevPixelsTopAppUnits() will multiple a factor (60) to the value,
// it may make the result value over the edge (overflow) of max or
// min value of int32_t. Compute the max sized dev pixel rect that
// we can support and intersect with it.
nsIntRect clampedRect = nsIntRect::MaxIntRect();
clampedRect.ScaleInverseRoundIn(AppUnitsPerDevPixel());
clampedRect = clampedRect.Intersect(aRect);
nsRect rect(DevPixelsToAppUnits(clampedRect.x),
DevPixelsToAppUnits(clampedRect.y),
DevPixelsToAppUnits(clampedRect.width),
DevPixelsToAppUnits(clampedRect.height));
NotifyInvalidation(rect, aFlags);
}