diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2020-04-01 11:07:30 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2020-04-01 12:49:32 +0200 |
commit | 97c468daae242ef8d62edb0942cb52ef4a2a1ebb (patch) | |
tree | 7ca45993b2d0102f13f5306ad98b91a7bd215b96 /vcl | |
parent | a0e8c9d27a7a7d5415d8555176c830e56662a95f (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.cxx | 64 |
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(); |