Loading dom/canvas/CanvasRenderingContext2D.cpp +17 −11 Original line number Diff line number Diff line Loading @@ -5044,6 +5044,16 @@ already_AddRefed<ImageData> CanvasRenderingContext2D::GetImageData( return MakeAndAddRef<ImageData>(w, h, *array); } static IntRect ClipImageDataTransfer(IntRect& aSrc, const IntPoint& aDestOffset, const IntSize& aDestBounds) { IntRect dest = aSrc; dest.SafeMoveBy(aDestOffset); dest = IntRect(IntPoint(0, 0), aDestBounds).SafeIntersect(dest); aSrc = aSrc.SafeIntersect(dest - aDestOffset); return aSrc + aDestOffset; } nsresult CanvasRenderingContext2D::GetImageDataArray( JSContext* aCx, int32_t aX, int32_t aY, uint32_t aWidth, uint32_t aHeight, nsIPrincipal& aSubjectPrincipal, JSObject** aRetval) { Loading Loading @@ -5073,9 +5083,9 @@ nsresult CanvasRenderingContext2D::GetImageDataArray( return NS_OK; } IntRect srcRect(0, 0, mWidth, mHeight); IntRect destRect(aX, aY, aWidth, aHeight); IntRect srcReadRect = srcRect.Intersect(destRect); IntRect dstWriteRect(0, 0, aWidth, aHeight); IntRect srcReadRect = ClipImageDataTransfer(dstWriteRect, IntPoint(aX, aY), IntSize(mWidth, mHeight)); if (srcReadRect.IsEmpty()) { *aRetval = darray; return NS_OK; Loading @@ -5100,9 +5110,6 @@ nsresult CanvasRenderingContext2D::GetImageDataArray( return NS_ERROR_OUT_OF_MEMORY; } IntRect dstWriteRect = srcReadRect; dstWriteRect.MoveBy(-aX, -aY); // Check for site-specific permission. This check is not needed if the // canvas was created with a docshell (that is only done for special // internal uses). Loading Loading @@ -5253,10 +5260,10 @@ void CanvasRenderingContext2D::PutImageData_explicit( dirtyRect = imageDataRect; } dirtyRect.MoveBy(IntPoint(aX, aY)); dirtyRect = IntRect(0, 0, mWidth, mHeight).Intersect(dirtyRect); if (dirtyRect.Width() <= 0 || dirtyRect.Height() <= 0) { IntRect srcRect = dirtyRect; dirtyRect = ClipImageDataTransfer(srcRect, IntPoint(aX, aY), IntSize(mWidth, mHeight)); if (dirtyRect.IsEmpty()) { return; } Loading Loading @@ -5311,7 +5318,6 @@ void CanvasRenderingContext2D::PutImageData_explicit( dstFormat = sourceSurface->GetFormat(); } IntRect srcRect = dirtyRect - IntPoint(aX, aY); uint8_t* srcData = arr.Data() + srcRect.y * (width * 4) + srcRect.x * 4; PremultiplyData( Loading gfx/2d/BaseRect.h +33 −0 Original line number Diff line number Diff line Loading @@ -313,6 +313,39 @@ struct BaseRect { height = aSize.height; } // Variant of MoveBy that ensures that even after translation by a point that // the rectangle coordinates will still fit within numeric limits. The origin // and size will be clipped within numeric limits to ensure this. void SafeMoveByX(T aDx) { T x2 = XMost(); if (aDx >= T(0)) { T limit = std::numeric_limits<T>::max(); x = limit - aDx < x ? limit : x + aDx; width = (limit - aDx < x2 ? limit : x2 + aDx) - x; } else { T limit = std::numeric_limits<T>::min(); x = limit - aDx > x ? limit : x + aDx; width = (limit - aDx > x2 ? limit : x2 + aDx) - x; } } void SafeMoveByY(T aDy) { T y2 = YMost(); if (aDy >= T(0)) { T limit = std::numeric_limits<T>::max(); y = limit - aDy < y ? limit : y + aDy; height = (limit - aDy < y2 ? limit : y2 + aDy) - y; } else { T limit = std::numeric_limits<T>::min(); y = limit - aDy > y ? limit : y + aDy; height = (limit - aDy > y2 ? limit : y2 + aDy) - y; } } void SafeMoveBy(T aDx, T aDy) { SafeMoveByX(aDx); SafeMoveByY(aDy); } void SafeMoveBy(const Point& aPoint) { SafeMoveBy(aPoint.x, aPoint.y); } void Inflate(T aD) { Inflate(aD, aD); } void Inflate(T aDx, T aDy) { x -= aDx; Loading Loading
dom/canvas/CanvasRenderingContext2D.cpp +17 −11 Original line number Diff line number Diff line Loading @@ -5044,6 +5044,16 @@ already_AddRefed<ImageData> CanvasRenderingContext2D::GetImageData( return MakeAndAddRef<ImageData>(w, h, *array); } static IntRect ClipImageDataTransfer(IntRect& aSrc, const IntPoint& aDestOffset, const IntSize& aDestBounds) { IntRect dest = aSrc; dest.SafeMoveBy(aDestOffset); dest = IntRect(IntPoint(0, 0), aDestBounds).SafeIntersect(dest); aSrc = aSrc.SafeIntersect(dest - aDestOffset); return aSrc + aDestOffset; } nsresult CanvasRenderingContext2D::GetImageDataArray( JSContext* aCx, int32_t aX, int32_t aY, uint32_t aWidth, uint32_t aHeight, nsIPrincipal& aSubjectPrincipal, JSObject** aRetval) { Loading Loading @@ -5073,9 +5083,9 @@ nsresult CanvasRenderingContext2D::GetImageDataArray( return NS_OK; } IntRect srcRect(0, 0, mWidth, mHeight); IntRect destRect(aX, aY, aWidth, aHeight); IntRect srcReadRect = srcRect.Intersect(destRect); IntRect dstWriteRect(0, 0, aWidth, aHeight); IntRect srcReadRect = ClipImageDataTransfer(dstWriteRect, IntPoint(aX, aY), IntSize(mWidth, mHeight)); if (srcReadRect.IsEmpty()) { *aRetval = darray; return NS_OK; Loading @@ -5100,9 +5110,6 @@ nsresult CanvasRenderingContext2D::GetImageDataArray( return NS_ERROR_OUT_OF_MEMORY; } IntRect dstWriteRect = srcReadRect; dstWriteRect.MoveBy(-aX, -aY); // Check for site-specific permission. This check is not needed if the // canvas was created with a docshell (that is only done for special // internal uses). Loading Loading @@ -5253,10 +5260,10 @@ void CanvasRenderingContext2D::PutImageData_explicit( dirtyRect = imageDataRect; } dirtyRect.MoveBy(IntPoint(aX, aY)); dirtyRect = IntRect(0, 0, mWidth, mHeight).Intersect(dirtyRect); if (dirtyRect.Width() <= 0 || dirtyRect.Height() <= 0) { IntRect srcRect = dirtyRect; dirtyRect = ClipImageDataTransfer(srcRect, IntPoint(aX, aY), IntSize(mWidth, mHeight)); if (dirtyRect.IsEmpty()) { return; } Loading Loading @@ -5311,7 +5318,6 @@ void CanvasRenderingContext2D::PutImageData_explicit( dstFormat = sourceSurface->GetFormat(); } IntRect srcRect = dirtyRect - IntPoint(aX, aY); uint8_t* srcData = arr.Data() + srcRect.y * (width * 4) + srcRect.x * 4; PremultiplyData( Loading
gfx/2d/BaseRect.h +33 −0 Original line number Diff line number Diff line Loading @@ -313,6 +313,39 @@ struct BaseRect { height = aSize.height; } // Variant of MoveBy that ensures that even after translation by a point that // the rectangle coordinates will still fit within numeric limits. The origin // and size will be clipped within numeric limits to ensure this. void SafeMoveByX(T aDx) { T x2 = XMost(); if (aDx >= T(0)) { T limit = std::numeric_limits<T>::max(); x = limit - aDx < x ? limit : x + aDx; width = (limit - aDx < x2 ? limit : x2 + aDx) - x; } else { T limit = std::numeric_limits<T>::min(); x = limit - aDx > x ? limit : x + aDx; width = (limit - aDx > x2 ? limit : x2 + aDx) - x; } } void SafeMoveByY(T aDy) { T y2 = YMost(); if (aDy >= T(0)) { T limit = std::numeric_limits<T>::max(); y = limit - aDy < y ? limit : y + aDy; height = (limit - aDy < y2 ? limit : y2 + aDy) - y; } else { T limit = std::numeric_limits<T>::min(); y = limit - aDy > y ? limit : y + aDy; height = (limit - aDy > y2 ? limit : y2 + aDy) - y; } } void SafeMoveBy(T aDx, T aDy) { SafeMoveByX(aDx); SafeMoveByY(aDy); } void SafeMoveBy(const Point& aPoint) { SafeMoveBy(aPoint.x, aPoint.y); } void Inflate(T aD) { Inflate(aD, aD); } void Inflate(T aDx, T aDy) { x -= aDx; Loading