summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArmin Le Grand (Allotropia) <Armin.Le.Grand@me.com>2021-12-24 16:12:52 +0100
committerArmin Le Grand <Armin.Le.Grand@me.com>2021-12-27 12:39:03 +0100
commitf281a0313c2a5544dca378ab094adab2796c4f0b (patch)
tree0a6278f876bc54f42b9b56dc0a834e0f2892ddc6
parenttdf#104823: unittest (diff)
downloadcore-f281a0313c2a5544dca378ab094adab2796c4f0b.tar.gz
core-f281a0313c2a5544dca378ab094adab2796c4f0b.zip
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.Grand@me.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127558 Tested-by: Armin Le Grand <Armin.Le.Grand@me.com>
-rw-r--r--svx/source/dialog/framelinkarray.cxx217
1 files changed, 143 insertions, 74 deletions
diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx
index 49bdb3aeacf6..336d4ed9881f 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -223,6 +223,8 @@ struct ArrayImpl
bool IsColInClipRange( size_t nCol ) const;
bool IsRowInClipRange( size_t nRow ) const;
+ bool OverlapsClipRange(size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow) const;
+
size_t GetMirrorCol( size_t nCol ) const { return mnWidth - nCol - 1; }
long GetColPosition( size_t nCol ) const;
@@ -326,6 +328,23 @@ bool ArrayImpl::IsRowInClipRange( size_t nRow ) const
return (mnFirstClipRow <= nRow) && (nRow <= mnLastClipRow);
}
+bool ArrayImpl::OverlapsClipRange(size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t 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( size_t nCol, size_t nRow ) const
{
return IsColInClipRange( nCol ) && IsRowInClipRange( nRow );
@@ -1015,6 +1034,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(
size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow,
const Color* pForceColor ) const
@@ -1138,88 +1235,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
+ size_t nColLeft(nCol);
+ size_t nRowTop(nRow);
+ size_t nColRight(nCol);
+ size_t 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 size_t _nMergedFirstCol(mxImpl->GetMergedFirstCol(nCol, nRow));
- const size_t _nMergedFirstRow(mxImpl->GetMergedFirstRow(nCol, nRow));
- const size_t 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);
}
}
}