From ff91a6fed516111011e228a2df79cb6de5325f6f Mon Sep 17 00:00:00 2001 From: Christopher Sherlock Date: Mon, 13 Apr 2026 05:03:50 +1000 Subject: [PATCH] vcl: add LogicToWindowUnits wrappers to simplify forward pipeline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduces LogicToWindowUnitsX and LogicToWindowUnitsY to the CoordinateMapper API. These master wrappers chain the first two stages of the forward transformation pipeline (LogicUnits -> View -> Window), cleanly stopping before the final physical screen offset is applied. This addition is immediately put to use in map.cxx to refactor OutputDevice::LogicToPixel for both Rectangles and Polygons. It successfully collapses complex, nested inline arithmetic—such as the manual scaling of logical offsets and the explicit addition of internal VCL pixel offsets (mnOutOffOrigX/Y)—into single, highly semantic API calls. OutputDevice is now further isolated from the underlying mechanics of the coordinate mapping math, continuing the encapsulation goals of the mapper refactor. Change-Id: Ifbc49b3c8ba5a84d864fe9a6626dcf587039241d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/203662 Tested-by: Jenkins Reviewed-by: Dan Williams --- vcl/inc/CoordinateMapper.hxx | 4 ++++ vcl/source/outdev/CoordinateMapper.cxx | 19 +++++++++++++++++++ vcl/source/outdev/map.cxx | 13 +++++++------ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/vcl/inc/CoordinateMapper.hxx b/vcl/inc/CoordinateMapper.hxx index deb8951e7768..5fe229259145 100644 --- a/vcl/inc/CoordinateMapper.hxx +++ b/vcl/inc/CoordinateMapper.hxx @@ -174,6 +174,10 @@ public: tools::Long DevicePixelToLogicX(tools::Long nX) const; tools::Long DevicePixelToLogicY(tools::Long nY) const; + // Logic -> Window units + tools::Long LogicToWindowUnitsX(tools::Long nX) const; + tools::Long LogicToWindowUnitsY(tools::Long nY) const; + // Pipeline is: Device -> Window -> View -> LogicUnits // Device <-> Window (Strip/Apply OutputDevice screen origin) diff --git a/vcl/source/outdev/CoordinateMapper.cxx b/vcl/source/outdev/CoordinateMapper.cxx index 0e8adc023448..1105d3d638d8 100644 --- a/vcl/source/outdev/CoordinateMapper.cxx +++ b/vcl/source/outdev/CoordinateMapper.cxx @@ -420,4 +420,23 @@ tools::Long CoordinateMapper::DevicePixelToLogicY(tools::Long nY) const return ViewToLogicUnitsY(nViewY); } +tools::Long CoordinateMapper::LogicToWindowUnitsX(tools::Long nX) const +{ + if (!IsMapModeEnabled()) + return nX; + + const tools::Long nViewX = LogicUnitsToViewUnitsX(nX); + + return ViewToWindowUnitsX(nViewX); +} + +tools::Long CoordinateMapper::LogicToWindowUnitsY(tools::Long nY) const +{ + if (!IsMapModeEnabled()) + return nY; + + const tools::Long nViewY = LogicUnitsToViewUnitsY(nY); + return ViewToWindowUnitsY(nViewY); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/source/outdev/map.cxx b/vcl/source/outdev/map.cxx index a0fa42ee4e42..285460fadd01 100644 --- a/vcl/source/outdev/map.cxx +++ b/vcl/source/outdev/map.cxx @@ -484,10 +484,11 @@ tools::Rectangle OutputDevice::LogicToPixel( const tools::Rectangle& rLogicRect return rLogicRect; tools::Rectangle aRetval( - mpMapper->LogicToViewDistanceX(mpMapper->LogicToOffsetLogicX(rLogicRect.Left())) + mpMapper->GetPixelXOffset(), - mpMapper->LogicToViewDistanceY(mpMapper->LogicToOffsetLogicY(rLogicRect.Top())) + mpMapper->GetPixelYOffset(), - rLogicRect.IsWidthEmpty() ? 0 : mpMapper->LogicToViewDistanceX(mpMapper->LogicToOffsetLogicX(rLogicRect.Right())) + mpMapper->GetPixelXOffset(), - rLogicRect.IsHeightEmpty() ? 0 : mpMapper->LogicToViewDistanceY(mpMapper->LogicToOffsetLogicY(rLogicRect.Bottom())) + mpMapper->GetPixelYOffset()); + mpMapper->LogicToWindowUnitsX(rLogicRect.Left()), + mpMapper->LogicToWindowUnitsY(rLogicRect.Top()), + rLogicRect.IsWidthEmpty() ? 0 : mpMapper->LogicToWindowUnitsX(rLogicRect.Right()), + rLogicRect.IsHeightEmpty() ? 0 : mpMapper->LogicToWindowUnitsY(rLogicRect.Bottom()) + ); if(rLogicRect.IsWidthEmpty()) aRetval.SetWidthEmpty(); @@ -514,8 +515,8 @@ tools::Polygon OutputDevice::LogicToPixel( const tools::Polygon& rLogicPoly ) co { const Point* pPt = &(pPointAry[i]); Point aPt; - aPt.setX(mpMapper->LogicToViewDistanceX(mpMapper->LogicToOffsetLogicX(pPt->X())) + mpMapper->GetPixelXOffset()); - aPt.setY(mpMapper->LogicToViewDistanceY(mpMapper->LogicToOffsetLogicY(pPt->Y())) + mpMapper->GetPixelYOffset()); + aPt.setX(mpMapper->LogicToWindowUnitsX(pPt->X())); + aPt.setY(mpMapper->LogicToWindowUnitsY(pPt->Y())); aPoly[i] = aPt; }