diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2022-06-16 18:21:10 +0200 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2022-06-17 06:16:28 +0200 |
commit | 8a5beccc19b4fdffb7b82ba5fd26f4cf316d9811 (patch) | |
tree | 8c394005bd0374d1af9e419aa9cda80e7e606d63 | |
parent | 9ace7e3a6c2ebb8311a8277e05564953480aa3bc (diff) |
handle GC* pixmap functions on Mac reading past pixmap (tdf#145843)
The code passes adjusted position for pixel data in order to create
a sub-rect of the pixmap without copying, but at least on Intel Mac
the GC* functions then try to read the entire pixel row even though
it shouldn't be necessary. Since that may cause reading past the
pixmap data if the last line is involved, use entire pixmap width
to avoid that.
Change-Id: Ia08059b363d39dd465b2cadde5138ee045628f59
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136003
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
-rw-r--r-- | vcl/skia/osx/gdiimpl.cxx | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/vcl/skia/osx/gdiimpl.cxx b/vcl/skia/osx/gdiimpl.cxx index 0c9ac5e9c14b..f8bcdd68352e 100644 --- a/vcl/skia/osx/gdiimpl.cxx +++ b/vcl/skia/osx/gdiimpl.cxx @@ -139,6 +139,18 @@ void AquaSkiaSalGraphicsImpl::flushSurfaceToScreenCG() // This creates the bitmap context from the cropped part, writable_addr32() will get // the first pixel of mDirtyRect.topLeft(), and using pixmap.rowBytes() ensures the following // pixel lines will be read from correct positions. + if (pixmap.bounds() != mDirtyRect && pixmap.bounds().bottom() == mDirtyRect.bottom()) + { + // HACK for tdf#145843: If mDirtyRect includes the last line but not the first pixel of it, + // then the rowBytes() trick would lead to the GC* functions thinking that even pixels after + // the pixmap data belong to the area (since the shifted x()+rowBytes() points there) and + // at least on Intel Mac they would actually read those data, even though I see no good reason + // to do that, as that's beyond the x()+width() for the last line. That could be handled + // by creating a subset SkImage (which as is said above copies data), or set the x coordinate + // to 0, which will then make rowBytes() match the actual data. + mDirtyRect.fLeft = 0; + assert(mDirtyRect.width() == pixmap.bounds().width()); + } CGContextRef context = CGBitmapContextCreate( pixmap.writable_addr32(mDirtyRect.x() * mScaling, mDirtyRect.y() * mScaling), mDirtyRect.width() * mScaling, mDirtyRect.height() * mScaling, 8, pixmap.rowBytes(), |