vcl/skia/osx/gdiimpl.cxx | 12 ++++++++++++ 1 file changed, 12 insertions(+)
New commits: commit 8a5beccc19b4fdffb7b82ba5fd26f4cf316d9811 Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Thu Jun 16 18:21:10 2022 +0200 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Fri Jun 17 06:16:28 2022 +0200 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.lu...@collabora.com> 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(),