tdf#153306 prevent subpixel shifting of X coordinate

HACK: for some unknown reason, if the X coordinate of the
path's bounds is more than 1024, SkBlendMode::kExclusion will
shift by about a half a pixel to the right with Skia/Metal on
a Retina display. Weirdly, if the same polygon is repeatedly
drawn, the total shift is cumulative so if the drawn polygon
is more than a few pixels wide, the blinking cursor in Writer
will exhibit this bug but only for one thin vertical slice at
a time. Apparently, shifting drawing a very tiny amount to
the left seems to be enough to quell this runaway cumulative
X coordinate shift.

Change-Id: Iabe9078e416b0dde003ee61c88817ff970cc8d39
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/166721
Tested-by: Patrick Luby <guibomacdev@gmail.com>
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Reviewed-by: Patrick Luby <guibomacdev@gmail.com>
Reviewed-by: Ilmari Lauhakangas <ilmari.lauhakangas@libreoffice.org>
diff --git a/vcl/skia/gdiimpl.cxx b/vcl/skia/gdiimpl.cxx
index a6e0309..eb6faea 100644
--- a/vcl/skia/gdiimpl.cxx
+++ b/vcl/skia/gdiimpl.cxx
@@ -1489,6 +1489,26 @@ void SkiaSalGraphicsImpl::invert(basegfx::B2DPolygon const& rPoly, SalInvert eFl
            aPaint.setShader(
                aBitmap.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, SkSamplingOptions()));
        }

#ifdef SK_METAL
        // tdf#153306 prevent subpixel shifting of X coordinate
        // HACK: for some unknown reason, if the X coordinate of the
        // path's bounds is more than 1024, SkBlendMode::kExclusion will
        // shift by about a half a pixel to the right with Skia/Metal on
        // a Retina display. Weirdly, if the same polygon is repeatedly
        // drawn, the total shift is cumulative so if the drawn polygon
        // is more than a few pixels wide, the blinking cursor in Writer
        // will exhibit this bug but only for one thin vertical slice at
        // a time. Apparently, shifting drawing a very tiny amount to
        // the left seems to be enough to quell this runaway cumulative
        // X coordinate shift.
        if (isGPU())
        {
            SkMatrix aMatrix;
            aMatrix.set(SkMatrix::kMTransX, -0.25);
            getDrawCanvas()->concat(aMatrix);
        }
#endif
    }
    getDrawCanvas()->drawPath(aPath, aPaint);
    postDraw();