mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-04 22:37:29 +09:00
Merge remote-tracking branch 'origin/tracking' into custom
This commit is contained in:
commit
e8b114fe4f
2 changed files with 79 additions and 10 deletions
|
|
@ -5766,6 +5766,18 @@ inline uint8_t PoisonValue(uint8_t v)
|
||||||
return v + rand() %3 -1;
|
return v + rand() %3 -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
nsresult
|
||||||
CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
|
CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
|
||||||
int32_t aX,
|
int32_t aX,
|
||||||
|
|
@ -5806,9 +5818,11 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntRect srcRect(0, 0, mWidth, mHeight);
|
IntRect dstWriteRect(0, 0, aWidth, aHeight);
|
||||||
IntRect destRect(aX, aY, aWidth, aHeight);
|
IntRect srcReadRect = ClipImageDataTransfer(dstWriteRect,
|
||||||
IntRect srcReadRect = srcRect.Intersect(destRect);
|
IntPoint(aX, aY),
|
||||||
|
IntSize(mWidth, mHeight));
|
||||||
|
|
||||||
RefPtr<DataSourceSurface> readback;
|
RefPtr<DataSourceSurface> readback;
|
||||||
DataSourceSurface::MappedSurface rawData;
|
DataSourceSurface::MappedSurface rawData;
|
||||||
if (!srcReadRect.IsEmpty()) {
|
if (!srcReadRect.IsEmpty()) {
|
||||||
|
|
@ -5836,9 +5850,6 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IntRect dstWriteRect = srcReadRect;
|
|
||||||
dstWriteRect.MoveBy(-aX, -aY);
|
|
||||||
|
|
||||||
JS::AutoCheckCannotGC nogc;
|
JS::AutoCheckCannotGC nogc;
|
||||||
bool isShared;
|
bool isShared;
|
||||||
uint8_t* data = JS_GetUint8ClampedArrayData(darray, &isShared, nogc);
|
uint8_t* data = JS_GetUint8ClampedArrayData(darray, &isShared, nogc);
|
||||||
|
|
@ -6039,10 +6050,10 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t aX, int32_t aY, uint32_t
|
||||||
dirtyRect = imageDataRect;
|
dirtyRect = imageDataRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
dirtyRect.MoveBy(IntPoint(aX, aY));
|
IntRect srcRect = dirtyRect;
|
||||||
dirtyRect = IntRect(0, 0, mWidth, mHeight).Intersect(dirtyRect);
|
dirtyRect = ClipImageDataTransfer(srcRect, IntPoint(aX, aY),
|
||||||
|
IntSize(mWidth, mHeight));
|
||||||
if (dirtyRect.Width() <= 0 || dirtyRect.Height() <= 0) {
|
if (dirtyRect.IsEmpty()) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,10 @@ struct BaseRect {
|
||||||
// (including edges) of *this and aRect. If there are no points in that
|
// (including edges) of *this and aRect. If there are no points in that
|
||||||
// intersection, returns an empty rectangle with x/y set to the std::max of the x/y
|
// intersection, returns an empty rectangle with x/y set to the std::max of the x/y
|
||||||
// of *this and aRect.
|
// of *this and aRect.
|
||||||
|
//
|
||||||
|
// Intersection with an empty Rect may not produce an empty Rect if overflow
|
||||||
|
// occurs. e.g. {INT_MIN, 0, 0, 20} Intersect { 5000, 0, 500, 20 } gives:
|
||||||
|
// the non-emtpy {5000, 0, 500, 20 } instead of {5000, 0, 0, 0}
|
||||||
MOZ_MUST_USE Sub Intersect(const Sub& aRect) const
|
MOZ_MUST_USE Sub Intersect(const Sub& aRect) const
|
||||||
{
|
{
|
||||||
Sub result;
|
Sub result;
|
||||||
|
|
@ -119,6 +123,26 @@ struct BaseRect {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
// Gives the same results as Intersect() but handles integer overflow
|
||||||
|
// better. This comes at a tiny cost in performance.
|
||||||
|
// e.g. {INT_MIN, 0, 0, 20} Intersect { 5000, 0, 500, 20 } gives:
|
||||||
|
// {5000, 0, 0, 0}
|
||||||
|
MOZ_MUST_USE Sub SafeIntersect(const Sub& aRect) const
|
||||||
|
{
|
||||||
|
Sub result;
|
||||||
|
result.x = std::max<T>(x, aRect.x);
|
||||||
|
result.y = std::max<T>(y, aRect.y);
|
||||||
|
T right = std::min<T>(x + width, aRect.x + aRect.width);
|
||||||
|
T bottom = std::min<T>(y + height, aRect.y + aRect.height);
|
||||||
|
if (right < result.x || bottom < result.y) {
|
||||||
|
result.width = 0;
|
||||||
|
result.height = 0;
|
||||||
|
} else {
|
||||||
|
result.width = right - result.x;
|
||||||
|
result.height = bottom - result.y;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
// Sets *this to be the rectangle containing the intersection of the points
|
// Sets *this to be the rectangle containing the intersection of the points
|
||||||
// (including edges) of *this and aRect. If there are no points in that
|
// (including edges) of *this and aRect. If there are no points in that
|
||||||
// intersection, sets *this to be an empty rectangle with x/y set to the std::max
|
// intersection, sets *this to be an empty rectangle with x/y set to the std::max
|
||||||
|
|
@ -211,6 +235,40 @@ struct BaseRect {
|
||||||
void MoveTo(const Point& aPoint) { x = aPoint.x; y = aPoint.y; }
|
void MoveTo(const Point& aPoint) { x = aPoint.x; y = aPoint.y; }
|
||||||
void MoveBy(T aDx, T aDy) { x += aDx; y += aDy; }
|
void MoveBy(T aDx, T aDy) { x += aDx; y += aDy; }
|
||||||
void MoveBy(const Point& aPoint) { x += aPoint.x; y += aPoint.y; }
|
void MoveBy(const Point& aPoint) { x += aPoint.x; y += aPoint.y; }
|
||||||
|
|
||||||
|
// 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 SizeTo(T aWidth, T aHeight) { width = aWidth; height = aHeight; }
|
void SizeTo(T aWidth, T aHeight) { width = aWidth; height = aHeight; }
|
||||||
void SizeTo(const SizeT& aSize) { width = aSize.width; height = aSize.height; }
|
void SizeTo(const SizeT& aSize) { width = aSize.width; height = aSize.height; }
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue