svx/source/dialog/framelinkarray.cxx |  217 +++++++++++++++++++++++------------
 1 file changed, 143 insertions(+), 74 deletions(-)

New commits:
commit e038ef76c1ef205143c853a3666fb56ca831750d
Author:     Armin Le Grand (Allotropia) <armin.le.gr...@me.com>
AuthorDate: Fri Dec 24 16:12:52 2021 +0100
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Mon Dec 27 11:42:05 2021 +0100

    tdf#126269 Handle diagonal borderline better for merged cells
    
    Change-Id: I04776bbd237dc1fa881385bfe9be7f034b58e35a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127431
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <armin.le.gr...@me.com>

diff --git a/svx/source/dialog/framelinkarray.cxx 
b/svx/source/dialog/framelinkarray.cxx
index 5d146de5868d..46d9629bf233 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -225,6 +225,8 @@ struct ArrayImpl
     bool                IsColInClipRange( sal_Int32 nCol ) const;
     bool                IsRowInClipRange( sal_Int32 nRow ) const;
 
+    bool                OverlapsClipRange(sal_Int32 nFirstCol, sal_Int32 
nFirstRow, sal_Int32 nLastCol, sal_Int32 nLastRow) const;
+
     sal_Int32           GetMirrorCol( sal_Int32 nCol ) const { return mnWidth 
- nCol - 1; }
 
     sal_Int32           GetColPosition( sal_Int32 nCol ) const;
@@ -328,6 +330,23 @@ bool ArrayImpl::IsRowInClipRange( sal_Int32 nRow ) const
     return (mnFirstClipRow <= nRow) && (nRow <= mnLastClipRow);
 }
 
+bool ArrayImpl::OverlapsClipRange(sal_Int32 nFirstCol, sal_Int32 nFirstRow, 
sal_Int32 nLastCol, sal_Int32 nLastRow) const
+{
+    if(nLastCol < mnFirstClipCol)
+        return false;
+
+    if(nFirstCol > mnLastClipCol)
+        return false;
+
+    if(nLastRow < mnFirstClipRow)
+        return false;
+
+    if(nFirstRow > mnLastClipRow)
+        return false;
+
+    return true;
+}
+
 bool ArrayImpl::IsInClipRange( sal_Int32 nCol, sal_Int32 nRow ) const
 {
     return IsColInClipRange( nCol ) && IsRowInClipRange( nRow );
@@ -1020,6 +1039,84 @@ static void HelperCreateVerticalEntry(
     rInstance.addSdrConnectStyleData(false, rEndFromTL, -rY - rX, true);
 }
 
+static void HelperCreateTLBREntry(
+    const Array& rArray,
+    const Style& rStyle,
+    drawinglayer::primitive2d::SdrFrameBorderDataVector& rData,
+    const basegfx::B2DPoint& rOrigin,
+    const basegfx::B2DVector& rX,
+    const basegfx::B2DVector& rY,
+    sal_Int32 nColLeft,
+    sal_Int32 nColRight,
+    sal_Int32 nRowTop,
+    sal_Int32 nRowBottom,
+    const Color* pForceColor)
+{
+    if(rStyle.IsUsed())
+    {
+        /// top-left and bottom-right Style Tables
+        rData.emplace_back(
+            rOrigin,
+            rX + rY,
+            rStyle,
+            pForceColor);
+        drawinglayer::primitive2d::SdrFrameBorderData& rInstance(rData.back());
+
+        /// Fill top-left Style Table
+        const Style& rTLFromRight(rArray.GetCellStyleTop(nColLeft, nRowTop));
+        const Style& rTLFromBottom(rArray.GetCellStyleLeft(nColLeft, nRowTop));
+
+        rInstance.addSdrConnectStyleData(true, rTLFromRight, rX, false);
+        rInstance.addSdrConnectStyleData(true, rTLFromBottom, rY, false);
+
+        /// Fill bottom-right Style Table
+        const Style& rBRFromBottom(rArray.GetCellStyleRight(nColRight, 
nRowBottom));
+        const Style& rBRFromLeft(rArray.GetCellStyleBottom(nColRight, 
nRowBottom));
+
+        rInstance.addSdrConnectStyleData(false, rBRFromBottom, -rY, true);
+        rInstance.addSdrConnectStyleData(false, rBRFromLeft, -rX, true);
+    }
+}
+
+static void HelperCreateBLTREntry(
+    const Array& rArray,
+    const Style& rStyle,
+    drawinglayer::primitive2d::SdrFrameBorderDataVector& rData,
+    const basegfx::B2DPoint& rOrigin,
+    const basegfx::B2DVector& rX,
+    const basegfx::B2DVector& rY,
+    sal_Int32 nColLeft,
+    sal_Int32 nColRight,
+    sal_Int32 nRowTop,
+    sal_Int32 nRowBottom,
+    const Color* pForceColor)
+{
+    if(rStyle.IsUsed())
+    {
+        /// bottom-left and top-right Style Tables
+        rData.emplace_back(
+            rOrigin + rY,
+            rX - rY,
+            rStyle,
+            pForceColor);
+        drawinglayer::primitive2d::SdrFrameBorderData& rInstance(rData.back());
+
+        /// Fill bottom-left Style Table
+        const Style& rBLFromTop(rArray.GetCellStyleLeft(nColLeft, nRowBottom));
+        const Style& rBLFromBottom(rArray.GetCellStyleBottom(nColLeft, 
nRowBottom));
+
+        rInstance.addSdrConnectStyleData(true, rBLFromTop, -rY, true);
+        rInstance.addSdrConnectStyleData(true, rBLFromBottom, rX, false);
+
+        /// Fill top-right Style Table
+        const Style& rTRFromLeft(rArray.GetCellStyleTop(nColRight, nRowTop));
+        const Style& rTRFromBottom(rArray.GetCellStyleRight(nColRight, 
nRowTop));
+
+        rInstance.addSdrConnectStyleData(false, rTRFromLeft, -rX, true);
+        rInstance.addSdrConnectStyleData(false, rTRFromBottom, rY, false);
+    }
+}
+
 drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
     sal_Int32 nFirstCol, sal_Int32 nFirstRow, sal_Int32 nLastCol, sal_Int32 
nLastRow,
     const Color* pForceColor ) const
@@ -1143,88 +1240,60 @@ drawinglayer::primitive2d::Primitive2DContainer 
Array::CreateB2DPrimitiveRange(
                     }
                 }
 
-                // check for crossed lines, these need special treatment, 
especially
-                // for merged cells, see below
-                const Style& rTLBR(GetCellStyleTLBR(nCol, nRow));
-                const Style& rBLTR(GetCellStyleBLTR(nCol, nRow));
-
-                if(rTLBR.IsUsed() || rBLTR.IsUsed())
+                // tdf#126269 check for crossed lines, these need special 
treatment, especially
+                // for merged cells (see comments in task). Separate treatment 
of merged and
+                // non-merged cells to allow better handling of both types
+                if(rCell.IsMerged())
                 {
-                    bool bContinue(true);
-
-                    if(rCell.IsMerged())
+                    // first check if this merged cell was already handled. To 
do so,
+                    // calculate and use the index of the TopLeft cell
+                    sal_Int32 nColLeft(nCol);
+                    sal_Int32 nRowTop(nRow);
+                    sal_Int32 nColRight(nCol);
+                    sal_Int32 nRowBottom(nRow);
+                    GetMergedRange(nColLeft, nRowTop, nColRight, nRowBottom, 
nCol, nRow);
+                    const sal_Int32 
nIndexOfMergedCell(mxImpl->GetIndex(nColLeft, nRowTop));
+
+                    if(aMergedCells.end() == 
aMergedCells.find(nIndexOfMergedCell))
                     {
-                        // first check if this merged cell was already 
handled. To do so,
-                        // calculate and use the index of the TopLeft cell
-                        const sal_Int32 
_nMergedFirstCol(mxImpl->GetMergedFirstCol(nCol, nRow));
-                        const sal_Int32 
_nMergedFirstRow(mxImpl->GetMergedFirstRow(nCol, nRow));
-                        const sal_Int32 
nIndexOfMergedCell(mxImpl->GetIndex(_nMergedFirstCol, _nMergedFirstRow));
-                        bContinue = (aMergedCells.end() == 
aMergedCells.find(nIndexOfMergedCell));
-
-                        if(bContinue)
+                        // not found, so not yet handled. Add now to mark as 
handled
+                        aMergedCells.insert(nIndexOfMergedCell);
+
+                        // get and check if diagonal styles are used
+                        const Style& rTLBR(GetCellStyleTLBR(nColLeft, 
nRowTop));
+                        const Style& rBLTR(GetCellStyleBLTR(nColLeft, 
nRowTop));
+
+                        if(rTLBR.IsUsed() || rBLTR.IsUsed())
                         {
-                            // not found, add now to mark as handled
-                            aMergedCells.insert(nIndexOfMergedCell);
-
-                            // when merged, get extended coordinate system and 
derived values
-                            // for the full range of this merged cell
-                            aCoordinateSystem = 
rCell.CreateCoordinateSystem(*this, nCol, nRow, true);
-                            aX = basegfx::utils::getColumn(aCoordinateSystem, 
0);
-                            aY = basegfx::utils::getColumn(aCoordinateSystem, 
1);
-                            aOrigin = 
basegfx::utils::getColumn(aCoordinateSystem, 2);
+                            // test for in ClipRange for BottomRight corner of 
merged cell
+                            if(mxImpl->OverlapsClipRange(nColLeft, nRowTop, 
nColRight, nRowBottom))
+                            {
+                                // when merged, get extended coordinate system 
and derived values
+                                // for the full range of this merged cell
+                                aCoordinateSystem = 
rCell.CreateCoordinateSystem(*this, nCol, nRow, true);
+                                aX = 
basegfx::utils::getColumn(aCoordinateSystem, 0);
+                                aY = 
basegfx::utils::getColumn(aCoordinateSystem, 1);
+                                aOrigin = 
basegfx::utils::getColumn(aCoordinateSystem, 2);
+
+                                HelperCreateTLBREntry(*this, rTLBR, *aData, 
aOrigin, aX, aY, nColLeft, nRowTop, nColRight, nRowBottom, pForceColor);
+                                HelperCreateBLTREntry(*this, rBLTR, *aData, 
aOrigin, aX, aY, nColLeft, nRowTop, nColRight, nRowBottom, pForceColor);
+                            }
                         }
                     }
-
-                    if(bContinue)
+                }
+                else
+                {
+                    // must be in clipping range: else not visible
+                    if( mxImpl->IsInClipRange( nCol, nRow ) )
                     {
-                        if(rTLBR.IsUsed())
-                        {
-                            /// top-left and bottom-right Style Tables
-                            aData->emplace_back(
-                                aOrigin,
-                                aX + aY,
-                                rTLBR,
-                                pForceColor);
-                            drawinglayer::primitive2d::SdrFrameBorderData& 
rInstance(aData->back());
-
-                            /// Fill top-left Style Table
-                            const Style& rTLFromRight(GetCellStyleTop(nCol, 
nRow));
-                            const Style& rTLFromBottom(GetCellStyleLeft(nCol, 
nRow));
-
-                            rInstance.addSdrConnectStyleData(true, 
rTLFromRight, aX, false);
-                            rInstance.addSdrConnectStyleData(true, 
rTLFromBottom, aY, false);
-
-                            /// Fill bottom-right Style Table
-                            const Style& rBRFromBottom(GetCellStyleRight(nCol, 
nRow));
-                            const Style& rBRFromLeft(GetCellStyleBottom(nCol, 
nRow));
-
-                            rInstance.addSdrConnectStyleData(false, 
rBRFromBottom, -aY, true);
-                            rInstance.addSdrConnectStyleData(false, 
rBRFromLeft, -aX, true);
-                        }
+                        // get and check if diagonal styles are used
+                        const Style& rTLBR(GetCellStyleTLBR(nCol, nRow));
+                        const Style& rBLTR(GetCellStyleBLTR(nCol, nRow));
 
-                        if(rBLTR.IsUsed())
+                        if(rTLBR.IsUsed() || rBLTR.IsUsed())
                         {
-                            /// bottom-left and top-right Style Tables
-                            aData->emplace_back(
-                                aOrigin + aY,
-                                aX - aY,
-                                rBLTR,
-                                pForceColor);
-                            drawinglayer::primitive2d::SdrFrameBorderData& 
rInstance(aData->back());
-
-                            /// Fill bottom-left Style Table
-                            const Style& rBLFromTop(GetCellStyleLeft(nCol, 
nRow));
-                            const Style& 
rBLFromBottom(GetCellStyleBottom(nCol, nRow));
-
-                            rInstance.addSdrConnectStyleData(true, rBLFromTop, 
-aY, true);
-                            rInstance.addSdrConnectStyleData(true, 
rBLFromBottom, aX, false);
-
-                            /// Fill top-right Style Table
-                            const Style& rTRFromLeft(GetCellStyleTop(nCol, 
nRow));
-                            const Style& rTRFromBottom(GetCellStyleRight(nCol, 
nRow));
-
-                            rInstance.addSdrConnectStyleData(false, 
rTRFromLeft, -aX, true);
-                            rInstance.addSdrConnectStyleData(false, 
rTRFromBottom, aY, false);
+                            HelperCreateTLBREntry(*this, rTLBR, *aData, 
aOrigin, aX, aY, nCol, nRow, nCol, nRow, pForceColor);
+                            HelperCreateBLTREntry(*this, rBLTR, *aData, 
aOrigin, aX, aY, nCol, nRow, nCol, nRow, pForceColor);
                         }
                     }
                 }

Reply via email to