summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2022-06-16 18:21:10 +0200
committerLuboš Luňák <l.lunak@collabora.com>2022-06-17 06:16:28 +0200
commit8a5beccc19b4fdffb7b82ba5fd26f4cf316d9811 (patch)
tree8c394005bd0374d1af9e419aa9cda80e7e606d63
parent9ace7e3a6c2ebb8311a8277e05564953480aa3bc (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.cxx12
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(),