Rebased ref, commits from common ancestor:
commit 10b19636c8466edb5e5147156ffcd6b69e9d1416
Author:     Tamás Zolnai <[email protected]>
AuthorDate: Mon Oct 27 13:37:22 2025 +0100
Commit:     Tamás Zolnai <[email protected]>
CommitDate: Tue Oct 28 12:09:26 2025 +0100

    POC: Better grid in Impress / Draw
    
    Change-Id: I10f6bcdfed296876789f2b1ac89f6f218227ae2e

diff --git a/drawinglayer/source/primitive2d/gridprimitive2d.cxx 
b/drawinglayer/source/primitive2d/gridprimitive2d.cxx
index dd6cca55fad6..c15dc879b5d2 100644
--- a/drawinglayer/source/primitive2d/gridprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/gridprimitive2d.cxx
@@ -24,7 +24,10 @@
 #include <drawinglayer/geometry/viewinformation2d.hxx>
 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <drawinglayer/primitive2d/PolygonHairlinePrimitive2D.hxx>
 #include <utility>
+#include <sal/log.hxx>
+
 
 
 using namespace com::sun::star;
@@ -34,6 +37,7 @@ namespace drawinglayer::primitive2d
 {
         Primitive2DReference GridPrimitive2D::create2DDecomposition(const 
geometry::ViewInformation2D& rViewInformation) const
         {
+            SAL_WARN("GridPrimitive2D", "create2DDecomposition" );
             if(!(!rViewInformation.getViewport().isEmpty() && getWidth() > 0.0 
&& getHeight() > 0.0))
                 return nullptr;
 
@@ -144,7 +148,7 @@ namespace drawinglayer::primitive2d
                     aExtendedViewport.transform(aTrans);
 
                     // crop start/end in X/Y to multiples of logical step width
-                    const double 
fHalfCrossSize((rViewInformation.getInverseObjectToViewTransformation() * 
basegfx::B2DVector(3.0, 0.0)).getLength());
+                    const double 
fHalfCrossSize((rViewInformation.getInverseObjectToViewTransformation() * 
basegfx::B2DVector(20.0, 0.0)).getLength());
                     const double fMinX(floor((aExtendedViewport.getMinX() - 
fHalfCrossSize) / fStepX) * fStepX);
                     const double fMaxX(ceil((aExtendedViewport.getMaxX() + 
fHalfCrossSize) / fStepX) * fStepX);
                     const double fMinY(floor((aExtendedViewport.getMinY() - 
fHalfCrossSize) / fStepY) * fStepY);
@@ -168,17 +172,20 @@ namespace drawinglayer::primitive2d
 
             for(double fX(aExtendedViewport.getMinX()); fX < 
aExtendedViewport.getMaxX(); fX += fStepX)
             {
+                SAL_WARN("GridPrimitive2D", "for(double 
fX(aExtendedViewport.getMinX()); fX < aExtendedViewport.getMaxX(); fX += 
fStepX)" );
                 const bool bXZero(basegfx::fTools::equalZero(fX));
 
                 for(double fY(aExtendedViewport.getMinY()); fY < 
aExtendedViewport.getMaxY(); fY += fStepY)
                 {
+                    SAL_WARN("GridPrimitive2D", "for(double 
fY(aExtendedViewport.getMinY()); fY < aExtendedViewport.getMaxY(); fY += 
fStepY)" );
                     const bool bYZero(basegfx::fTools::equalZero(fY));
 
                     if(!bXZero && !bYZero)
                     {
+                        SAL_WARN("GridPrimitive2D", "if(!bXZero && !bYZero)" );
                         // get discrete position and test against 3x3 area 
surrounding it
                         // since it's a cross
-                        const double fHalfCrossSize(3.0 * 0.5);
+                        const double fHalfCrossSize(20.0 * 0.5);
                         const basegfx::B2DPoint aViewPos(aRST * 
basegfx::B2DPoint(fX, fY));
                         const basegfx::B2DRange aDiscreteRangeCross(
                             aViewPos.getX() - fHalfCrossSize, aViewPos.getY() 
- fHalfCrossSize,
@@ -202,7 +209,7 @@ namespace drawinglayer::primitive2d
                             
if(rViewInformation.getDiscreteViewport().isInside(aViewPos))
                             {
                                 const basegfx::B2DPoint 
aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
-                                aPositionsPoint.push_back(aLogicPos);
+                                aPositionsCross.push_back(aLogicPos);
                             }
                         }
                     }
@@ -218,7 +225,7 @@ namespace drawinglayer::primitive2d
                             
if(rViewInformation.getDiscreteViewport().isInside(aViewPos))
                             {
                                 const basegfx::B2DPoint 
aLogicPos(rViewInformation.getInverseObjectToViewTransformation() * aViewPos);
-                                aPositionsPoint.push_back(aLogicPos);
+                                aPositionsCross.push_back(aLogicPos);
                             }
                         }
                     }
@@ -226,29 +233,35 @@ namespace drawinglayer::primitive2d
             }
 
             // prepare return value
-            const sal_uInt32 nCountPoint(aPositionsPoint.size());
             const sal_uInt32 nCountCross(aPositionsCross.size());
 
             // add PointArrayPrimitive2D if point markers were added
             Primitive2DContainer aContainer;
-            if(nCountPoint)
             {
-                aContainer.push_back(new 
PointArrayPrimitive2D(std::move(aPositionsPoint), getBColor()));
-            }
+                SAL_WARN("GridPrimitive2D", "MarkerArrayPrimitive2D" );
+                for (const basegfx::B2DPoint &aPoint : aPositionsCross)
+                {
+                    SAL_WARN("GridPrimitive2D", "aPoint" );
+                    SAL_WARN("GridPrimitive2D", "fStepX: " << fStepX );
+                    double fHalfCrossSize(std::min(fStepX, fStepY) / 4 / 2);
+                    if(getSubdivisionsX())
+                    {
+                        fHalfCrossSize = std::min(fHalfCrossSize, fSmallStepX 
/ 4 / 2);
+                    }
+                    if(getSubdivisionsY())
+                    {
+                        fHalfCrossSize = std::min(fHalfCrossSize, fSmallStepY 
/ 4 / 2);
+                    }
 
-            // add MarkerArrayPrimitive2D if cross markers were added
-            if(!nCountCross)
-                return new GroupPrimitive2D(std::move(aContainer));
+                    aContainer.push_back(new 
SingleLinePrimitive2D(basegfx::B2DPoint(aPoint.getX() - fHalfCrossSize, 
aPoint.getY()),
+                        basegfx::B2DPoint(aPoint.getX() + fHalfCrossSize, 
aPoint.getY()),
+                        getBColor()));
 
-            if(!getSubdivisionsX() && !getSubdivisionsY())
-            {
-                // no subdivisions, so fall back to points at grid positions, 
no need to
-                // visualize a difference between divisions and sub-divisions
-                aContainer.push_back(new 
PointArrayPrimitive2D(std::move(aPositionsCross), getBColor()));
-            }
-            else
-            {
-                aContainer.push_back(new 
MarkerArrayPrimitive2D(std::move(aPositionsCross), getCrossMarker()));
+
+                    aContainer.push_back(new 
SingleLinePrimitive2D(basegfx::B2DPoint(aPoint.getX(), aPoint.getY() - 
fHalfCrossSize),
+                        basegfx::B2DPoint(aPoint.getX(), aPoint.getY() + 
fHalfCrossSize),
+                        getBColor()));
+                }
             }
             return new GroupPrimitive2D(std::move(aContainer));
         }
commit be85ad2a3f7efd534f75ba977139cf403e4be21e
Author:     Tamás Zolnai <[email protected]>
AuthorDate: Thu Oct 23 10:41:11 2025 +0200
Commit:     Tamás Zolnai <[email protected]>
CommitDate: Tue Oct 28 12:09:25 2025 +0100

    POC: Better grid in Writer and Calc.
    
    Change-Id: I34905cc2705bb53deb51cfa8cb4b5058c9b21208

diff --git a/include/vcl/outdev.hxx b/include/vcl/outdev.hxx
index 3cc7d153a53f..3aeb1cd08e47 100644
--- a/include/vcl/outdev.hxx
+++ b/include/vcl/outdev.hxx
@@ -612,6 +612,8 @@ public:
 
     void                        DrawGrid( const tools::Rectangle& rRect, const 
Size& rDist, DrawGridFlags nFlags );
 
+    void                        DrawGridOfCrosses( const tools::Rectangle& 
rRect, const Size& rDist, const tools::Rectangle& rCutRect, const Size& 
rCrossSize);
+
     ///@}
 
     /** @name Invert functions
diff --git a/include/vcl/rendercontext/DrawGridFlags.hxx 
b/include/vcl/rendercontext/DrawGridFlags.hxx
index 4d783e780976..e90c8f05d348 100644
--- a/include/vcl/rendercontext/DrawGridFlags.hxx
+++ b/include/vcl/rendercontext/DrawGridFlags.hxx
@@ -26,11 +26,12 @@ enum class DrawGridFlags
     NONE = 0x0000,
     Dots = 0x0001,
     HorzLines = 0x0002,
-    VertLines = 0x0004
+    VertLines = 0x0004,
+    Crosses = 0x0008
 };
 namespace o3tl
 {
-template <> struct typed_flags<DrawGridFlags> : is_typed_flags<DrawGridFlags, 
0x0007>
+template <> struct typed_flags<DrawGridFlags> : is_typed_flags<DrawGridFlags, 
0x00f>
 {
 };
 }
diff --git a/svx/source/svdraw/svdpagv.cxx b/svx/source/svdraw/svdpagv.cxx
index 41419bc113f1..7e355cb8c8ce 100644
--- a/svx/source/svdraw/svdpagv.cxx
+++ b/svx/source/svdraw/svdpagv.cxx
@@ -461,6 +461,7 @@ void SdrPageView::DrawPageViewGrid(OutputDevice& rOut, 
const tools::Rectangle& r
     sal_uInt16 nGridPaintCnt=1;
     if (pFrames!=nullptr) nGridPaintCnt=pFrames->GetCount();
     for (sal_uInt16 nGridPaintNum=0; nGridPaintNum<nGridPaintCnt; 
nGridPaintNum++) {
+        tools::Rectangle aDrawArea;
         if (pFrames!=nullptr) {
             const SdrPageGridFrame& rGF=(*pFrames)[nGridPaintNum];
             nWrX=rGF.GetPaperRect().Left();
@@ -471,6 +472,11 @@ void SdrPageView::DrawPageViewGrid(OutputDevice& rOut, 
const tools::Rectangle& r
             y2=rGF.GetUserArea().Bottom();
             aOrg=rGF.GetUserArea().TopLeft();
             aOrg-=rGF.GetPaperRect().TopLeft();
+            aDrawArea=rGF.GetUserArea();
+        }
+        else
+        {
+            aDrawArea=tools::Rectangle{maPageOrigin, GetPage()->GetSize()};
         }
         if (!rRect.IsEmpty()) {
             Size a1PixSiz(rOut.PixelToLogic(Size(1,1)));
@@ -500,18 +506,32 @@ void SdrPageView::DrawPageViewGrid(OutputDevice& rOut, 
const tools::Rectangle& r
         {
             if( bHoriLines )
             {
-                DrawGridFlags nGridFlags = ( bHoriSolid ? 
DrawGridFlags::HorzLines : DrawGridFlags::Dots );
                 sal_uInt16 nSteps = sal_uInt16(nx1 / nx2);
                 sal_uInt32 nRestPerStepMul1000 = nSteps ? ( ((nx1 * 1000)/ 
nSteps) - (nx2 * 1000) ) : 0;
                 sal_uInt32 nStepOffset = 0;
                 sal_uInt16 nPointOffset = 0;
+                SAL_WARN("drawGrid", "bHoriSolid: " << (bHoriSolid ? "true" : 
"false"));
+                SAL_WARN("drawGrid", "nSteps: " << nSteps);
+                SAL_WARN("drawGrid", "nRestPerStepMul1000: " << 
nRestPerStepMul1000);
+                SAL_WARN("drawGrid", "nStepOffset: " << nStepOffset);
+                SAL_WARN("drawGrid", "nPointOffset: " << nPointOffset);
 
                 for(sal_uInt16 a=0;a<nSteps;a++)
                 {
                     // draw
-                    rOut.DrawGrid(
-                        tools::Rectangle( xFinOrg + (a * nx2) + nPointOffset, 
yBigOrg, x2, y2 ),
-                        Size( nx1, ny1 ), nGridFlags );
+                    if (false)
+                    {
+                        rOut.DrawGrid(
+                            tools::Rectangle( xFinOrg + (a * nx2) + 
nPointOffset, yBigOrg, x2, y2 ),
+                            Size( nx1, ny1 ), DrawGridFlags::HorzLines );
+                    }
+                    else
+                    {
+                        const tools::Long nCrossSize = 
std::min(GetView().maGridFin.Width(), GetView().maGridFin.Height()) / 4;
+                        rOut.DrawGridOfCrosses(
+                            tools::Rectangle( xFinOrg + (a * nx2) + 
nPointOffset, yBigOrg, x2, y2 ),
+                            Size( nx1, ny1 ), aDrawArea, Size(nCrossSize, 
nCrossSize) );
+                    }
 
                     // do a step
                     nStepOffset += nRestPerStepMul1000;
@@ -525,7 +545,6 @@ void SdrPageView::DrawPageViewGrid(OutputDevice& rOut, 
const tools::Rectangle& r
 
             if( bVertLines )
             {
-                DrawGridFlags nGridFlags = ( bVertSolid ? 
DrawGridFlags::VertLines : DrawGridFlags::Dots );
                 sal_uInt16 nSteps = sal_uInt16(ny1 / ny2);
                 sal_uInt32 nRestPerStepMul1000 = nSteps ? ( ((ny1 * 1000L)/ 
nSteps) - (ny2 * 1000L) ) : 0;
                 sal_uInt32 nStepOffset = 0;
@@ -534,9 +553,19 @@ void SdrPageView::DrawPageViewGrid(OutputDevice& rOut, 
const tools::Rectangle& r
                 for(sal_uInt16 a=0;a<nSteps;a++)
                 {
                     // draw
-                    rOut.DrawGrid(
-                        tools::Rectangle( xBigOrg, yFinOrg + (a * ny2) + 
nPointOffset, x2, y2 ),
-                        Size( nx1, ny1 ), nGridFlags );
+                    if (false)
+                    {
+                        rOut.DrawGrid(
+                            tools::Rectangle( xBigOrg, yFinOrg + (a * ny2) + 
nPointOffset, x2, y2 ),
+                            Size( nx1, ny1 ), DrawGridFlags::VertLines );
+                    }
+                    else
+                    {
+                        const tools::Long nCrossSize = 
std::min(GetView().maGridFin.Width(), GetView().maGridFin.Height()) / 4;
+                        rOut.DrawGridOfCrosses(
+                            tools::Rectangle( xBigOrg, yFinOrg + (a * ny2) + 
nPointOffset, x2, y2 ),
+                            Size( nx1, ny1 ), aDrawArea, Size(nCrossSize, 
nCrossSize) );
+                    }
 
                     // do a step
                     nStepOffset += nRestPerStepMul1000;
diff --git a/vcl/source/outdev/rect.cxx b/vcl/source/outdev/rect.cxx
index c2731237d1cf..2c98faea1f27 100644
--- a/vcl/source/outdev/rect.cxx
+++ b/vcl/source/outdev/rect.cxx
@@ -263,7 +263,7 @@ void OutputDevice::DrawGrid( const tools::Rectangle& rRect, 
const Size& rDist, D
     std::vector< sal_Int32 > aVertBuf;
     std::vector< sal_Int32 > aHorzBuf;
 
-    if( ( nFlags & DrawGridFlags::Dots ) || ( nFlags & 
DrawGridFlags::HorzLines ) )
+    if( ( nFlags & DrawGridFlags::Dots ) || ( nFlags & DrawGridFlags::Crosses 
) ||( nFlags & DrawGridFlags::HorzLines ) )
     {
         aVertBuf.resize( aDstRect.GetHeight() / nDistY + 2 );
         aVertBuf[ nVertCount++ ] = nStartY;
@@ -273,7 +273,7 @@ void OutputDevice::DrawGrid( const tools::Rectangle& rRect, 
const Size& rDist, D
         }
     }
 
-    if( ( nFlags & DrawGridFlags::Dots ) || ( nFlags & 
DrawGridFlags::VertLines ) )
+    if( ( nFlags & DrawGridFlags::Dots ) || ( nFlags & DrawGridFlags::Crosses 
) || ( nFlags & DrawGridFlags::VertLines ) )
     {
         aHorzBuf.resize( aDstRect.GetWidth() / nDistX + 2 );
         aHorzBuf[ nHorzCount++ ] = nStartX;
@@ -302,6 +302,20 @@ void OutputDevice::DrawGrid( const tools::Rectangle& 
rRect, const Size& rDist, D
             }
         }
     }
+    else if( nFlags & DrawGridFlags::Crosses )
+    {
+        for( tools::Long i = 0; i < nVertCount; i++ )
+        {
+            for( tools::Long j = 0, Y = aVertBuf[ i ]; j < nHorzCount; j++ )
+            {
+                tools::Long X = aHorzBuf[ j ];
+                tools::Long crossSizeX = ImplLogicXToDevicePixel( 10 );
+                tools::Long crossSizeY = ImplLogicYToDevicePixel( 10 );
+                mpGraphics->DrawLine( X - crossSizeX, Y, X + crossSizeX, Y, 
*this );
+                mpGraphics->DrawLine( X, Y - crossSizeY, X, Y + crossSizeY, 
*this );
+            }
+        }
+    }
     else
     {
         if( nFlags & DrawGridFlags::HorzLines )
@@ -326,6 +340,95 @@ void OutputDevice::DrawGrid( const tools::Rectangle& 
rRect, const Size& rDist, D
     EnableMapMode( bOldMap );
 }
 
+void OutputDevice::DrawGridOfCrosses( const tools::Rectangle& rRect, const 
Size& rDist, const tools::Rectangle& rCutRect, const Size& rCrossSize )
+{
+    SAL_WARN("drawGrid", "DrawGridOfCrosses");
+    assert(!is_double_buffered_window());
+
+    tools::Rectangle aDstRect( PixelToLogic( Point() ), GetOutputSize() );
+    aDstRect.Intersection( rRect );
+
+    if( aDstRect.IsEmpty() || ImplIsRecordLayout() )
+        return;
+
+    if( !mpGraphics && !AcquireGraphics() )
+        return;
+    assert(mpGraphics);
+
+    if( mbInitClipRegion )
+        InitClipRegion();
+
+    if( mbOutputClipped )
+        return;
+
+    const tools::Long nDistX = std::max( rDist.Width(), tools::Long(1) );
+    const tools::Long nDistY = std::max( rDist.Height(), tools::Long(1) );
+    tools::Long nX = ( rRect.Left() >= aDstRect.Left() ) ? rRect.Left() : ( 
rRect.Left() + ( ( aDstRect.Left() - rRect.Left() ) / nDistX ) * nDistX );
+    tools::Long nY = ( rRect.Top() >= aDstRect.Top() ) ? rRect.Top() : ( 
rRect.Top() + ( ( aDstRect.Top() - rRect.Top() ) / nDistY ) * nDistY );
+    const tools::Long nRight = aDstRect.Right();
+    const tools::Long nBottom = aDstRect.Bottom();
+
+    std::vector< sal_Int32 > aVertBuf;
+    tools::Long nVertCount = 0;
+    aVertBuf.resize( aDstRect.GetHeight() / nDistY + 2 );
+    aVertBuf[ nVertCount++ ] = ImplLogicYToDevicePixel( nY );
+    while( ( nY += nDistY ) <= nBottom )
+    {
+        aVertBuf[ nVertCount++ ] = ImplLogicYToDevicePixel( nY );
+    }
+
+    std::vector< sal_Int32 > aHorzBuf;
+    tools::Long nHorzCount = 0;
+    aHorzBuf.resize( aDstRect.GetWidth() / nDistX + 2 );
+    aHorzBuf[ nHorzCount++ ] = ImplLogicXToDevicePixel( nX );
+    while( ( nX += nDistX ) <= nRight )
+    {
+        aHorzBuf[ nHorzCount++ ] = ImplLogicXToDevicePixel( nX );
+    }
+
+    if( mbInitLineColor )
+        InitLineColor();
+
+    if( mbInitFillColor )
+        InitFillColor();
+
+    for( tools::Long i = 0; i < nVertCount; i++ )
+    {
+        for( tools::Long j = 0; j < nHorzCount; j++ )
+        {
+            const tools::Long nXPixel = aHorzBuf[ j ];
+            const tools::Long nYPixel = aVertBuf[ i ];
+            if (nXPixel < ImplLogicXToDevicePixel(rCutRect.Left()) || nYPixel 
< ImplLogicYToDevicePixel(rCutRect.Top()) ||
+                nXPixel > ImplLogicXToDevicePixel(rCutRect.Right()) || nYPixel 
> ImplLogicYToDevicePixel(rCutRect.Bottom()))
+                continue;
+
+            const tools::Long crossSizeX = 
ImplLogicWidthToDevicePixel(rCrossSize.Width() / 2);
+            const tools::Long crossSizeY = 
ImplLogicHeightToDevicePixel(rCrossSize.Height() / 2);
+            const tools::Long nStartX = std::max(nXPixel - crossSizeX, 
ImplLogicXToDevicePixel(rCutRect.Left()));
+            const tools::Long nEndX = std::min(nXPixel + crossSizeX + 1, 
ImplLogicXToDevicePixel(rCutRect.Right()));
+            const tools::Long nStartY = std::max(nYPixel - crossSizeY, 
ImplLogicYToDevicePixel(rCutRect.Top()));
+            const tools::Long nEndY = std::min(nYPixel + crossSizeY + 1, 
ImplLogicYToDevicePixel(rCutRect.Bottom()));
+
+            const bool bOldMap = mbMap;
+            EnableMapMode( false );
+
+            mpGraphics->DrawLine( nStartX,
+                nYPixel,
+                nEndX,
+                nYPixel, *this );
+            mpGraphics->DrawLine( nXPixel,
+                nStartY,
+                nXPixel,
+                nEndY, *this );
+
+            mpGraphics->DrawPixel( nXPixel, nYPixel, *this );
+
+            EnableMapMode( bOldMap );
+        }
+    }
+
+}
+
 BmpMirrorFlags AdjustTwoRect( SalTwoRect& rTwoRect, const Size& rSizePix )
 {
     BmpMirrorFlags nMirrFlags = BmpMirrorFlags::NONE;

Reply via email to