summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2020-04-01 11:07:30 +0200
committerLuboš Luňák <l.lunak@collabora.com>2020-04-01 12:49:32 +0200
commit97c468daae242ef8d62edb0942cb52ef4a2a1ebb (patch)
tree7ca45993b2d0102f13f5306ad98b91a7bd215b96 /vcl
parenta0e8c9d27a7a7d5415d8555176c830e56662a95f (diff)
handle weird semantics of SkRect::intersect() (tdf#131721)
If the two rectangles do not intersect, it only returns false and does nothing, which is stupid and confusing. Change-Id: I24de6059807c208c39db4e942ab5624dde788723 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91471 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
Diffstat (limited to 'vcl')
-rw-r--r--vcl/skia/gdiimpl.cxx64
1 files changed, 35 insertions, 29 deletions
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index 390bf521336b..53ccda65c1d5 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -324,44 +324,50 @@ void SkiaSalGraphicsImpl::postDraw()
{
// Make slightly larger, just in case (rounding, antialiasing,...).
mXorExtents.outset(2, 2);
- mXorExtents.intersect(SkRect::MakeXYWH(0, 0, mSurface->width(), mSurface->height()));
+ if (!mXorExtents.intersect(
+ SkRect::MakeXYWH(0, 0, mSurface->width(), mSurface->height())))
+ mXorExtents.setEmpty();
}
SAL_INFO("vcl.skia.trace",
"applyxor(" << this << "): "
<< tools::Rectangle(mXorExtents.left(), mXorExtents.top(),
mXorExtents.right(), mXorExtents.bottom()));
- // Copy the surface contents to another pixmap.
- SkBitmap surfaceBitmap;
- // Use unpremultiplied alpha format, so that we do not have to do the conversions to get
- // the RGB and back (Skia will do it when converting, but it'll be presumably faster at it).
- if (!surfaceBitmap.tryAllocPixels(
- mSurface->imageInfo().makeAlphaType(kUnpremul_SkAlphaType)))
- abort();
- SkPaint paint;
- paint.setBlendMode(SkBlendMode::kSrc); // copy as is
- SkCanvas canvas(surfaceBitmap);
- canvas.drawImageRect(mSurface->makeImageSnapshot(), mXorExtents, mXorExtents, &paint);
- // xor to surfaceBitmap
- assert(surfaceBitmap.info().alphaType() == kUnpremul_SkAlphaType);
- assert(mXorBitmap.info().alphaType() == kUnpremul_SkAlphaType);
- assert(surfaceBitmap.bytesPerPixel() == 4);
- assert(mXorBitmap.bytesPerPixel() == 4);
- for (int y = mXorExtents.top(); y < mXorExtents.bottom(); ++y)
+ if (!mXorExtents.isEmpty()) // the intersection above may be empty
{
- uint8_t* data = static_cast<uint8_t*>(surfaceBitmap.getAddr(mXorExtents.x(), y));
- const uint8_t* xordata = static_cast<uint8_t*>(mXorBitmap.getAddr(mXorExtents.x(), y));
- for (int x = 0; x < mXorExtents.width(); ++x)
+ // Copy the surface contents to another pixmap.
+ SkBitmap surfaceBitmap;
+ // Use unpremultiplied alpha format, so that we do not have to do the conversions to get
+ // the RGB and back (Skia will do it when converting, but it'll be presumably faster at it).
+ if (!surfaceBitmap.tryAllocPixels(
+ mSurface->imageInfo().makeAlphaType(kUnpremul_SkAlphaType)))
+ abort();
+ SkPaint paint;
+ paint.setBlendMode(SkBlendMode::kSrc); // copy as is
+ SkCanvas canvas(surfaceBitmap);
+ canvas.drawImageRect(mSurface->makeImageSnapshot(), mXorExtents, mXorExtents, &paint);
+ // xor to surfaceBitmap
+ assert(surfaceBitmap.info().alphaType() == kUnpremul_SkAlphaType);
+ assert(mXorBitmap.info().alphaType() == kUnpremul_SkAlphaType);
+ assert(surfaceBitmap.bytesPerPixel() == 4);
+ assert(mXorBitmap.bytesPerPixel() == 4);
+ for (int y = mXorExtents.top(); y < mXorExtents.bottom(); ++y)
{
- *data++ ^= *xordata++;
- *data++ ^= *xordata++;
- *data++ ^= *xordata++;
- // alpha is not xor-ed
- data++;
- xordata++;
+ uint8_t* data = static_cast<uint8_t*>(surfaceBitmap.getAddr(mXorExtents.x(), y));
+ const uint8_t* xordata
+ = static_cast<uint8_t*>(mXorBitmap.getAddr(mXorExtents.x(), y));
+ for (int x = 0; x < mXorExtents.width(); ++x)
+ {
+ *data++ ^= *xordata++;
+ *data++ ^= *xordata++;
+ *data++ ^= *xordata++;
+ // alpha is not xor-ed
+ data++;
+ xordata++;
+ }
}
+ surfaceBitmap.notifyPixelsChanged();
+ mSurface->getCanvas()->drawBitmapRect(surfaceBitmap, mXorExtents, mXorExtents, &paint);
}
- surfaceBitmap.notifyPixelsChanged();
- mSurface->getCanvas()->drawBitmapRect(surfaceBitmap, mXorExtents, mXorExtents, &paint);
mXorCanvas.reset();
mXorBitmap.reset();
mXorExtents.setEmpty();