vcl: add LogicToWindowUnits wrappers to simplify forward pipeline

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 <dcbw@libreoffice.org>
This commit is contained in:
Christopher Sherlock
2026-08-24 18:48:36 +02:00
committed by Dan Williams
parent 57dd8e57ca
commit ff91a6fed5
3 changed files with 30 additions and 6 deletions
+4
View File
@@ -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)
+19
View File
@@ -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: */
+7 -6
View File
@@ -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;
}