drawinglayer/source/processor2d/hittestprocessor2d.cxx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
New commits: commit 07d80edb0b2cc979510c5f69de2269f315ae0f7a Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Fri Aug 15 14:41:32 2025 +0500 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Fri Aug 15 14:05:49 2025 +0200 Fix relative position to pixel index calculation After commit 7caf45bc06e5b4459aeb173393e5898dff761d50 (BitmapEx->Bitmap in HitTestProcessor2D, 2025-08-15), I saw a crash when hovering mouse over a bitmap on a slide: vcllo.dll!BitmapReadAccess::GetScanline(__int64 nY) Line 50 vcllo.dll!BitmapReadAccess::GetColor(__int64 nY, __int64 nX) Line 100 vcllo.dll!Bitmap::GetPixelColor(long nX, long nY) Line 1894 drawinglayerlo.dll!drawinglayer::processor2d::HitTestProcessor2D::checkBitmapHit(basegfx::B2DRange aRange, const Bitmap & rBitmap, const basegfx::B2DHomMatrix & rTransform) Line 174 drawinglayerlo.dll!drawinglayer::processor2d::HitTestProcessor2D::processBasePrimitive2D(const drawinglayer::primitive2d::BasePrimitive2D & rCandidate) Line 478 drawinglayerlo.dll!drawinglayer::processor2d::BaseProcessor2D::visit(const rtl::Reference<drawinglayer::primitive2d::BasePrimitive2D> & rCandidate) Line 50 drawinglayercorelo.dll!drawinglayer::primitive2d::BufferedDecompositionPrimitive2D::get2DDecomposition(drawinglayer::primitive2d::Primitive2DDecompositionVisitor & rVisitor, const drawinglayer::geometry::ViewInformation2D & rViewInformation) Line 81 drawinglayerlo.dll!drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D::get2DDecomposition(drawinglayer::primitive2d::Primitive2DDecompositionVisitor & rVisitor, const drawinglayer::geometry::ViewInformation2D & rViewInformation) Line 46 drawinglayerlo.dll!drawinglayer::processor2d::BaseProcessor2D::process(const drawinglayer::primitive2d::BasePrimitive2D & rCandidate) Line 43 drawinglayerlo.dll!drawinglayer::processor2d::HitTestProcessor2D::processBasePrimitive2D(const drawinglayer::primitive2d::BasePrimitive2D & rCandidate) Line 553 drawinglayerlo.dll!drawinglayer::processor2d::BaseProcessor2D::process(const drawinglayer::primitive2d::Primitive2DContainer & rSource) Line 67 svxcorelo.dll!sdr::overlay::OverlayObjectList::isHitLogic(const basegfx::B2DPoint & rLogicPosition, double fLogicTolerance) Line 94 svxcorelo.dll!SdrHdl::IsHdlHit(const Point & rPnt) Line 948 svxcorelo.dll!SdrHdlList::IsHdlListHit(const Point & rPnt) Line 2306 svxcorelo.dll!SdrMarkView::PickHandle(const Point & rPnt) Line 2117 svxcorelo.dll!SdrMarkView::MouseMove(const MouseEvent & rMEvt, OutputDevice * pWin) Line 1849 svxcorelo.dll!SdrObjEditView::MouseMove(const MouseEvent & rMEvt, OutputDevice * pWin) Line 2210 svxcorelo.dll!SdrCreateView::MouseMove(const MouseEvent & rMEvt, OutputDevice * pWin) Line 314 svxcorelo.dll!SdrView::MouseMove(const MouseEvent & rMEvt, OutputDevice * pWin) Line 223 sdlo.dll!sd::FuDraw::MouseMove(const MouseEvent & rMEvt) Line 260 sdlo.dll!sd::FuSelection::MouseMove(const MouseEvent & rMEvt) Line 611 sdlo.dll!sd::ViewShell::MouseMove(const MouseEvent & rMEvt, sd::Window * pWin) Line 689 sdlo.dll!sd::DrawViewShell::MouseMove(const MouseEvent & rMEvt, sd::Window * pWin) Line 405 sdlo.dll!sd::Window::MouseMove(const MouseEvent & rMEvt) Line 248 The problem was pre-existing miscalculation of the pixel indices, which were hidden previously by BitmapEx::GetAlpha sanitizing the input. The calculation must not round, but truncate: we are on the first pixel, until we cross the "1/aSizePixel.Width()" boundary. Also, we must handle 1.0 separately in aRelativePoint, because that special case produces bad result: we must either treat it as "outside" (treat aUnitRange as half- open interval), or as "over the last pixel" (implemented here now). Change-Id: Id39dbd889e8d6f3e063962b2a621d0c438a1f90a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189670 Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Tested-by: Jenkins diff --git a/drawinglayer/source/processor2d/hittestprocessor2d.cxx b/drawinglayer/source/processor2d/hittestprocessor2d.cxx index bc363cf74117..488b9ac97781 100644 --- a/drawinglayer/source/processor2d/hittestprocessor2d.cxx +++ b/drawinglayer/source/processor2d/hittestprocessor2d.cxx @@ -168,8 +168,16 @@ namespace drawinglayer::processor2d if(aUnitRange.isInside(aRelativePoint)) { - const sal_Int32 nX(basegfx::fround(aRelativePoint.getX() * aSizePixel.Width())); - const sal_Int32 nY(basegfx::fround(aRelativePoint.getY() * aSizePixel.Height())); + // aRelativePoint.getX() == 0.0 -> 0 + // aRelativePoint.getX() == 0.999... -> aSizePixel.Width() - 1 + // Since isInside includes upper bound (1.0), force also this: + // aRelativePoint.getX() == 1.0 -> aSizePixel.Width() - 1 + sal_Int32 nX(aRelativePoint.getX() * aSizePixel.Width()); + if (nX == aSizePixel.Width()) + --nX; + sal_Int32 nY(aRelativePoint.getY() * aSizePixel.Height()); + if (nY == aSizePixel.Height()) + --nY; mbHit = (0 != rBitmap.GetPixelColor(nX, nY).GetAlpha()); }