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(),

Reply via email to