[Libreoffice-commits] core.git: Branch 'private/swe/libreoffice-5-2+backports' - 6 commits - drawinglayer/qa drawinglayer/source include/drawinglayer include/svx sc/source svx/source sw/Library_swui.mk sw/source

Armin Le Grand Armin.Le.Grand at cib.de
Wed Aug 16 13:27:41 UTC 2017


 drawinglayer/qa/unit/border.cxx                            |   29 
 drawinglayer/source/primitive2d/borderlineprimitive2d.cxx  |  209 -
 include/drawinglayer/primitive2d/borderlineprimitive2d.hxx |  127 -
 include/svx/framelink.hxx                                  |  257 --
 include/svx/framelinkarray.hxx                             |   28 
 sc/source/core/data/fillinfo.cxx                           |    1 
 sc/source/ui/inc/output.hxx                                |    5 
 sc/source/ui/miscdlgs/autofmt.cxx                          |   21 
 sc/source/ui/view/gridwin4.cxx                             |    4 
 sc/source/ui/view/output.cxx                               |  326 --
 sc/source/ui/view/output2.cxx                              |    4 
 svx/source/dialog/framelink.cxx                            | 1643 +++----------
 svx/source/dialog/framelinkarray.cxx                       |  766 ++----
 svx/source/dialog/frmsel.cxx                               |   48 
 svx/source/table/viewcontactoftableobj.cxx                 |  174 -
 sw/Library_swui.mk                                         |    2 
 sw/source/core/layout/paintfrm.cxx                         |  320 +-
 sw/source/ui/table/tautofmt.cxx                            |   22 
 18 files changed, 1437 insertions(+), 2549 deletions(-)

New commits:
commit d40d63030d965df16d428660635d0bb945dd36b2
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Thu Jul 27 16:03:48 2017 +0200

    borderline: corrections for calc and writer
    
    Made corrections/finetuning for Calc and Writer.
    Had to remove some former code which tried to do
    corrections.
    
    Change-Id: Id9fc687b9a709d250faaad76c37ecfda8d8feb9b

diff --git a/drawinglayer/qa/unit/border.cxx b/drawinglayer/qa/unit/border.cxx
index c80d89c6f1b9..7727e44e3935 100644
--- a/drawinglayer/qa/unit/border.cxx
+++ b/drawinglayer/qa/unit/border.cxx
@@ -57,9 +57,17 @@ void DrawinglayerBorderTest::testDoubleDecompositionSolid()
     basegfx::BColor aColorRight;
     basegfx::BColor aColorLeft;
     basegfx::BColor aColorGap;
-    bool bHasGapColor = false;
-    sal_Int16 nStyle = table::BorderLineStyle::DOUBLE;
-    rtl::Reference<drawinglayer::primitive2d::BorderLinePrimitive2D> aBorder(new drawinglayer::primitive2d::BorderLinePrimitive2D(aStart, aEnd, fLeftWidth, fDistance, fRightWidth, fExtendLeftStart, fExtendLeftEnd, fExtendRightStart, fExtendRightEnd, aColorRight, aColorLeft, aColorGap, bHasGapColor, nStyle));
+    bool const bHasGapColor = false;
+    const sal_Int16 nStyle = table::BorderLineStyle::DOUBLE;
+    rtl::Reference<drawinglayer::primitive2d::BorderLinePrimitive2D> aBorder(
+        new drawinglayer::primitive2d::BorderLinePrimitive2D(
+            aStart,
+            aEnd,
+            drawinglayer::primitive2d::BorderLine(fLeftWidth, aColorLeft, fExtendLeftStart, fExtendLeftEnd),
+            drawinglayer::primitive2d::BorderLine(fDistance, aColorGap),
+            drawinglayer::primitive2d::BorderLine(fRightWidth, aColorRight, fExtendRightStart, fExtendRightEnd),
+            bHasGapColor,
+            nStyle));
 
     // Decompose it into polygons.
     drawinglayer::geometry::ViewInformation2D aView;
@@ -104,9 +112,18 @@ void DrawinglayerBorderTest::testDoublePixelProcessing()
     basegfx::BColor aColorRight;
     basegfx::BColor aColorLeft;
     basegfx::BColor aColorGap;
-    bool bHasGapColor = false;
-    sal_Int16 nStyle = table::BorderLineStyle::DOUBLE;
-    rtl::Reference<drawinglayer::primitive2d::BorderLinePrimitive2D> xBorder(new drawinglayer::primitive2d::BorderLinePrimitive2D(aStart, aEnd, fLeftWidth, fDistance, fRightWidth, fExtendLeftStart, fExtendLeftEnd, fExtendRightStart, fExtendRightEnd, aColorRight, aColorLeft, aColorGap, bHasGapColor, nStyle));
+    bool const bHasGapColor = false;
+    const sal_Int16 nStyle = table::BorderLineStyle::DOUBLE;
+    rtl::Reference<drawinglayer::primitive2d::BorderLinePrimitive2D> xBorder(
+        new drawinglayer::primitive2d::BorderLinePrimitive2D(
+            aStart,
+            aEnd,
+            drawinglayer::primitive2d::BorderLine(fLeftWidth, aColorLeft, fExtendLeftStart, fExtendLeftEnd),
+            drawinglayer::primitive2d::BorderLine(fDistance, aColorGap),
+            drawinglayer::primitive2d::BorderLine(fRightWidth, aColorRight, fExtendRightStart, fExtendRightEnd),
+            bHasGapColor,
+            nStyle));
+
     drawinglayer::primitive2d::Primitive2DContainer aPrimitives;
     aPrimitives.push_back(drawinglayer::primitive2d::Primitive2DReference(xBorder.get()));
 
diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index 9961c5f5a8b0..d577fe41ff21 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -57,6 +57,10 @@ namespace drawinglayer
         {
         }
 
+        BorderLine::~BorderLine()
+        {
+        }
+
         bool BorderLine::operator==(const BorderLine& rBorderLine) const
         {
             return getWidth() == rBorderLine.getWidth()
@@ -114,13 +118,17 @@ namespace drawinglayer
                     // double line with gap. Use mfDiscreteGapDistance (see get2DDecomposition) as distance.
                     // That value is prepared to be at least one pixel (discrete unit) so that the
                     // decomposition is view-dependent in this cases
+                    const BorderLine& rLeft(getBorderLines()[0]);
+                    const BorderLine& rGap(getBorderLines()[1]);
+                    const BorderLine& rRight(getBorderLines()[2]);
+                    const double fFullWidth(rLeft.getWidth() + mfDiscreteGapDistance + rRight.getWidth());
+
                     {
-                        // inside line (left of vector). Create stroke primitive centered on line width
-                        const BorderLine& rLeft(getBorderLines()[0]);
-                        const double fDeltaY((mfDiscreteGapDistance + rLeft.getWidth()) * 0.5);
+                        // inside line (left of vector). Create stroke primitive centered on left line width
+                        const double fDeltaY((rLeft.getWidth() - fFullWidth) * 0.5);
                         const basegfx::B2DVector aDeltaY(aPerpendicular * fDeltaY);
-                        const basegfx::B2DPoint aStart(getStart() - (aVector * rLeft.getExtendStart()) - aDeltaY);
-                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * rLeft.getExtendEnd()) - aDeltaY);
+                        const basegfx::B2DPoint aStart(getStart() - (aVector * rLeft.getExtendStart()) + aDeltaY);
+                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * rLeft.getExtendEnd()) + aDeltaY);
                         const attribute::LineAttribute aLineAttribute(rLeft.getRGBColor(), rLeft.getWidth());
 
                         addPolygonStrokePrimitive2D(
@@ -134,10 +142,11 @@ namespace drawinglayer
                     if (hasGapColor())
                     {
                         // gap (if visible, found practical usage in Writer MultiColorBorderLines).
-                        // Create stroke primitive on vector with given color
-                        const BorderLine& rGap(getBorderLines()[1]);
-                        const basegfx::B2DPoint aStart(getStart() - (aVector * rGap.getExtendStart()));
-                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * rGap.getExtendEnd()));
+                        // Create stroke primitive on vector with given color centered on gap position
+                        const double fDeltaY(((fFullWidth - mfDiscreteGapDistance) * 0.5) - rRight.getWidth());
+                        const basegfx::B2DVector aDeltaY(aPerpendicular * fDeltaY);
+                        const basegfx::B2DPoint aStart(getStart() - (aVector * rGap.getExtendStart()) + aDeltaY);
+                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * rGap.getExtendEnd()) + aDeltaY);
                         const attribute::LineAttribute aLineAttribute(rGap.getRGBColor(), mfDiscreteGapDistance);
 
                         addPolygonStrokePrimitive2D(
@@ -149,9 +158,8 @@ namespace drawinglayer
                     }
 
                     {
-                        // outside line (right of vector). Create stroke primitive centered on line width
-                        const BorderLine& rRight(getBorderLines()[2]);
-                        const double fDeltaY((mfDiscreteGapDistance + rRight.getWidth()) * 0.5);
+                        // outside line (right of vector). Create stroke primitive centered on right line width
+                        const double fDeltaY((fFullWidth - rRight.getWidth()) * 0.5);
                         const basegfx::B2DVector aDeltaY(aPerpendicular * fDeltaY);
                         const basegfx::B2DPoint aStart(getStart() - (aVector * rRight.getExtendStart()) + aDeltaY);
                         const basegfx::B2DPoint aEnd(getEnd() + (aVector * rRight.getExtendEnd()) + aDeltaY);
diff --git a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
index 0696a30e7f12..185a49d55731 100644
--- a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
@@ -59,6 +59,7 @@ namespace drawinglayer
                 const basegfx::BColor& rRGBColor,
                 double fExtendStart = 0.0,
                 double fExtendEnd = 0.0);
+            virtual ~BorderLine();
 
             double getWidth() const { return mfWidth; }
             const basegfx::BColor& getRGBColor() const { return maRGBColor; }
diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx
index 5be7859a2929..d2c5d171e3bc 100644
--- a/sc/source/ui/inc/output.hxx
+++ b/sc/source/ui/inc/output.hxx
@@ -237,7 +237,7 @@ private:
 
     double          GetStretch();
 
-    void            DrawRotatedFrame(vcl::RenderContext& rRenderContext, const Color* pForceColor);       // pixel
+    void            DrawRotatedFrame(vcl::RenderContext& rRenderContext);       // pixel
 
     drawinglayer::processor2d::BaseProcessor2D*  CreateProcessor2D( );
 
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index 4c91c222758e..9dba72bf1c19 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -1369,7 +1369,7 @@ void ScOutputData::DrawFrame(vcl::RenderContext& rRenderContext)
 
     if (mrTabInfo.maArray.HasCellRotation())
     {
-        DrawRotatedFrame(rRenderContext, pForceColor);        // removes the lines that must not be painted here
+        DrawRotatedFrame(rRenderContext);        // removes the lines that must not be painted here
     }
 
     long nInitPosX = nScrX;
@@ -1456,74 +1456,7 @@ void ScOutputData::DrawFrame(vcl::RenderContext& rRenderContext)
     rRenderContext.SetDrawMode(nOldDrawMode);
 }
 
-// Line below the cell
-
-static const ::editeng::SvxBorderLine* lcl_FindHorLine( ScDocument* pDoc,
-                        SCCOL nCol, SCROW nRow, SCTAB nTab, sal_uInt16 nRotDir,
-                        bool bTopLine )
-{
-    if ( nRotDir != SC_ROTDIR_LEFT && nRotDir != SC_ROTDIR_RIGHT )
-        return nullptr;
-
-    bool bFound = false;
-    while (!bFound)
-    {
-        if ( nRotDir == SC_ROTDIR_LEFT )
-        {
-            // text to the left -> line from the right
-            if ( nCol < MAXCOL )
-                ++nCol;
-            else
-                return nullptr; // couldn't find it
-        }
-        else
-        {
-            // text to the right -> line from the left
-            if ( nCol > 0 )
-                --nCol;
-            else
-                return nullptr; // couldn't find it
-        }
-        const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
-        const SfxItemSet* pCondSet = pDoc->GetCondResult( nCol, nRow, nTab );
-        if ( !pPattern->GetRotateVal( pCondSet ) ||
-                static_cast<const SvxRotateModeItem&>(pPattern->GetItem(
-                    ATTR_ROTATE_MODE, pCondSet)).GetValue() == SVX_ROTATE_MODE_STANDARD )
-            bFound = true;
-    }
-
-    if (bTopLine)
-        --nRow;
-    const ::editeng::SvxBorderLine* pThisBottom;
-    if ( ValidRow(nRow) )
-        pThisBottom = static_cast<const SvxBoxItem*>(pDoc->GetAttr( nCol, nRow, nTab, ATTR_BORDER ))->GetBottom();
-    else
-        pThisBottom = nullptr;
-    const ::editeng::SvxBorderLine* pNextTop;
-    if ( nRow < MAXROW )
-        pNextTop = static_cast<const SvxBoxItem*>(pDoc->GetAttr( nCol, nRow+1, nTab, ATTR_BORDER ))->GetTop();
-    else
-        pNextTop = nullptr;
-
-    if ( ScHasPriority( pThisBottom, pNextTop ) )
-        return pThisBottom;
-    else
-        return pNextTop;
-}
-
-static long lcl_getRotate( ScDocument* pDoc, SCTAB nTab, SCCOL nX, SCROW nY )
-{
-    long nRotate = 0;
-
-    const ScPatternAttr* pPattern = pDoc->GetPattern( nX, nY, nTab );
-    const SfxItemSet* pCondSet = pDoc->GetCondResult( nX, nY, nTab );
-
-    nRotate = pPattern->GetRotateVal( pCondSet );
-
-    return nRotate;
-}
-
-void ScOutputData::DrawRotatedFrame(vcl::RenderContext& rRenderContext, const Color* pForceColor)
+void ScOutputData::DrawRotatedFrame(vcl::RenderContext& rRenderContext)
 {
     //! save nRotMax
     SCCOL nRotMax = nX2;
@@ -1537,8 +1470,6 @@ void ScOutputData::DrawRotatedFrame(vcl::RenderContext& rRenderContext, const Co
     const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
     bool bCellContrast = mbUseStyleColor && rStyleSettings.GetHighContrastMode();
 
-    // color (pForceColor) is determined externally, including DrawMode changes
-
     long nInitPosX = nScrX;
     if ( bLayoutRTL )
     {
@@ -1557,9 +1488,7 @@ void ScOutputData::DrawRotatedFrame(vcl::RenderContext& rRenderContext, const Co
     else
         rRenderContext.SetClipRegion( vcl::Region( aClipRect ) );
 
-    svx::frame::Array& rArray = mrTabInfo.maArray;
     std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> pProcessor(CreateProcessor2D( ));
-
     long nPosY = nScrY;
     for (SCSIZE nArrY=1; nArrY<nArrCount; nArrY++)
     {
@@ -1569,8 +1498,6 @@ void ScOutputData::DrawRotatedFrame(vcl::RenderContext& rRenderContext, const Co
         RowInfo& rThisRowInfo = pRowInfo[nArrY];
         RowInfo& rNextRowInfo = pRowInfo[nArrY+1];
 
-        size_t nRow = static_cast< size_t >( nArrY );
-
         long nRowHeight = rThisRowInfo.nHeight;
         if ( rThisRowInfo.nRotMaxCol != SC_ROTMAX_NONE &&
              ( rThisRowInfo.bChanged || rPrevRowInfo.bChanged ||
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index 769ca425916f..a36f7bab2a8b 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -278,73 +278,6 @@ bool CheckFrameBorderConnectable( const Style& rLBorder, const Style& rRBorder,
 
 
 // Drawing functions
-// get offset to center of line in question
-double lcl_getCenterOfLineOffset(const Style& rBorder, bool bLeftEdge)
-{
-    const bool bPrimUsed(!basegfx::fTools::equalZero(rBorder.Prim())); // left
-    const bool bDistUsed(!basegfx::fTools::equalZero(rBorder.Dist())); // distance
-    const bool bSecnUsed(!basegfx::fTools::equalZero(rBorder.Secn())); // right
-
-    if (bDistUsed || bSecnUsed)
-    {
-        // double line, get center by adding half ditance and half line width.
-        // bLeftEdge defines which line to use
-        return (rBorder.Dist() + (bLeftEdge ? rBorder.Prim() : rBorder.Secn())) * 0.5;
-    }
-    else if (bPrimUsed)
-    {
-        // single line, get center
-        return rBorder.Prim() * 0.5;
-    }
-
-    // no line width at all, stay on unit vector
-    return 0.0;
-}
-
-double lcl_GetExtent(
-    const Style& rBorder, const Style& rSide, const Style& rOpposite,
-    long nAngleSide, long nAngleOpposite,
-    bool bLeftEdge,     // left or right of rBorder
-    bool bOtherLeft )   // left or right of rSide/rOpposite
-{
-    Style aOtherBorder = rSide;
-    long nOtherAngle = nAngleSide;
-    if ( rSide.GetWidth() == 0 && rOpposite.GetWidth() > 0 )
-    {
-        nOtherAngle = nAngleOpposite;
-        aOtherBorder = rOpposite;
-    }
-    else if ( rSide.GetWidth() == 0 && rOpposite.GetWidth() == 0 )
-    {
-        if ( ( nAngleOpposite % 18000 ) == 0 )
-            nOtherAngle = nAngleSide;
-        else if ( ( nAngleSide % 18000 ) == 0 )
-            nOtherAngle = nAngleOpposite;
-    }
-
-    // Let's assume the border we are drawing is horizontal and compute all the angles / distances from this
-    basegfx::B2DVector aBaseVector( 1.0, 0.0 );
-    // added support to get the distances to the centers of the line, *not* the outre edge
-    basegfx::B2DPoint aBasePoint(0.0, lcl_getCenterOfLineOffset(rBorder, bLeftEdge));
-
-    basegfx::B2DHomMatrix aRotation;
-    aRotation.rotate( double( nOtherAngle ) * M_PI / 18000.0 );
-
-    basegfx::B2DVector aOtherVector = aRotation * aBaseVector;
-    // Compute a line shifted by half the width of the other border
-    basegfx::B2DVector aPerpendicular = basegfx::getNormalizedPerpendicular( aOtherVector );
-    // added support to get the distances to the centers of the line, *not* the outre edge
-    basegfx::B2DPoint aOtherPoint = basegfx::B2DPoint() + aPerpendicular * lcl_getCenterOfLineOffset(aOtherBorder, bOtherLeft);
-
-    // Find the cut between the two lines
-    double nCut = 0.0;
-    basegfx::tools::findCut(
-            aBasePoint, aBaseVector, aOtherPoint, aOtherVector,
-            CutFlagValue::ALL, &nCut );
-
-    return nCut;
-}
-
 struct OffsetPair
 {
     double          mfLeft;
@@ -523,7 +456,14 @@ double getSimpleExtendedLineValues(
 
     if (pResult)
     {
-        return (pResult->mfLeftRight + pResult->mfRightRight) * 0.5 * (bEdgeStart ? -fLength : fLength);
+        if (bEdgeStart)
+        {
+            return (pResult->mfLeftRight + pResult->mfRightRight) * -0.5 * fLength;
+        }
+        else
+        {
+            return (pResult->mfLeftLeft + pResult->mfRightLeft) * 0.5 * fLength;
+        }
     }
 
     return 0.0;
@@ -552,7 +492,14 @@ double getComplexExtendedLineValues(
 
     if (pResult)
     {
-        return (pResult->mfLeftRight + pResult->mfRightRight) * 0.5 * (bEdgeStart ? -fLength : fLength);
+        if (bEdgeStart)
+        {
+            return (pResult->mfLeftRight + pResult->mfRightRight) * 0.5 * -fLength;
+        }
+        else
+        {
+            return (pResult->mfLeftLeft + pResult->mfRightLeft) * 0.5 * fLength;
+        }
     }
 
     return 0.0;
@@ -638,7 +585,10 @@ void CreateBorderPrimitives(
         else if (2 == myOffsets.size())
         {
             // we are a double edge, calculate cuts with edges coming from above/below
-            // for both edges to detect the line start/end extensions
+            // for both edges to detect the line start/end extensions. In the furure this
+            // needs to be extended to use two values per extension, getComplexExtendedLineValues
+            // internally prepares these already. drawinglayer::primitive2d::BorderLine will
+            // then need to take these double entries (maybe a pair) and use them internally.
             double mfExtendLeftStart(0.0);
             double mfExtendLeftEnd(0.0);
             double mfExtendRightStart(0.0);
@@ -673,8 +623,12 @@ void CreateBorderPrimitives(
                         drawinglayer::primitive2d::BorderLine(
                             rBorder.Dist(),
                             (pForceColor ? *pForceColor : rBorder.GetColorGap()).getBColor(),
-                            (mfExtendLeftStart + mfExtendRightStart) * 0.5,
-                            (mfExtendLeftEnd + mfExtendRightEnd) * 0.5),
+                            // needs to be determined in detail later, for now use the max prolongation
+                            // from left/right, butz do not less than half (0.0). This works decently,
+                            // but not perfect (see Writer, use three-color-style, look at upper/lower#
+                            // connections)
+                            std::max(0.0, std::max(mfExtendLeftStart, mfExtendRightStart)),
+                            std::max(0.0, std::max(mfExtendLeftEnd, mfExtendRightEnd))),
                         drawinglayer::primitive2d::BorderLine(
                             rBorder.Secn(),
                             (pForceColor ? *pForceColor : rBorder.GetColorSecn()).getBColor(),
diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx
index f0e63c594b7f..3f0beb847f2a 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -132,8 +132,6 @@ void lclSetMergedRange( CellVec& rCells, size_t nWidth, size_t nFirstCol, size_t
 static const Style OBJ_STYLE_NONE;
 static const Cell OBJ_CELL_NONE;
 
-const bool DIAG_DBL_CLIP_DEFAULT = false;
-
 struct ArrayImpl
 {
     CellVec             maCells;
diff --git a/svx/source/dialog/frmsel.cxx b/svx/source/dialog/frmsel.cxx
index 416da00e44fa..e0d5bcb9b334 100644
--- a/svx/source/dialog/frmsel.cxx
+++ b/svx/source/dialog/frmsel.cxx
@@ -655,9 +655,6 @@ void FrameSelectorImpl::DrawAllFrameBorders()
         for( size_t nRow = 0; nRow < maArray.GetRowCount(); ++nRow )
             maArray.SetCellStyleDiag( nCol, nRow, maTLBR.GetUIStyle(), maBLTR.GetUIStyle() );
 
-    // Let the helper array draw itself
-    static bool bUsePrimitives(true);
-
     // This is used in the dialog/control for 'Border' attributes. When using
     // the original paint below instead of primitives, the advantage currently
     // is the correct visualization of diagonal line(s) including overlaying,
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 19fe8e4c48bb..eac84838a538 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -2446,11 +2446,6 @@ struct SwLineEntry
     SwTwips mnKey;
     SwTwips mnStartPos;
     SwTwips mnEndPos;
-    SwTwips mnOffset;
-
-    bool mbOffsetPerp;
-    bool mbOffsetStart;
-    bool mbOffsetEnd;
 
     svx::frame::Style maAttribute;
 
@@ -2472,10 +2467,6 @@ SwLineEntry::SwLineEntry( SwTwips nKey,
     :   mnKey( nKey ),
         mnStartPos( nStartPos ),
         mnEndPos( nEndPos ),
-        mnOffset( 0 ),
-        mbOffsetPerp(false),
-        mbOffsetStart(false),
-        mbOffsetEnd(false),
         maAttribute( rAttribute )
 {
 }
@@ -2554,8 +2545,6 @@ class SwTabFramePainter
                             svx::frame::Style*,
                             bool bHori ) const;
 
-    void AdjustTopLeftFrames();
-
 public:
     explicit SwTabFramePainter( const SwTabFrame& rTabFrame );
 
@@ -2566,7 +2555,6 @@ SwTabFramePainter::SwTabFramePainter( const SwTabFrame& rTabFrame )
     : mrTabFrame( rTabFrame )
 {
     HandleFrame( rTabFrame );
-    AdjustTopLeftFrames();
 }
 
 void SwTabFramePainter::HandleFrame( const SwLayoutFrame& rLayoutFrame )
@@ -2664,42 +2652,6 @@ void SwTabFramePainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) cons
             svx::frame::Style aStyles[ 7 ];
             aStyles[ 0 ] = rEntryStyle;
             FindStylesForLine( aStart, aEnd, aStyles, bHori );
-
-            // Account for double line thicknesses for the top- and left-most borders.
-            if (rEntry.mnOffset)
-            {
-                if (bHori)
-                {
-                    if (rEntry.mbOffsetPerp)
-                    {
-                        // Apply offset in perpendicular direction.
-                        aStart.Y() -= rEntry.mnOffset;
-                        aEnd.Y() -= rEntry.mnOffset;
-                    }
-                    if (rEntry.mbOffsetStart)
-                        // Apply offset at the start of a border.
-                        aStart.X() -= rEntry.mnOffset;
-                    if (rEntry.mbOffsetEnd)
-                        // Apply offset at the end of a border.
-                        aEnd.X() += rEntry.mnOffset;
-                }
-                else
-                {
-                    if (rEntry.mbOffsetPerp)
-                    {
-                        // Apply offset in perpendicular direction.
-                        aStart.X() -= rEntry.mnOffset;
-                        aEnd.X() -= rEntry.mnOffset;
-                    }
-                    if (rEntry.mbOffsetStart)
-                        // Apply offset at the start of a border.
-                        aStart.Y() -= rEntry.mnOffset;
-                    if (rEntry.mbOffsetEnd)
-                        // Apply offset at the end of a border.
-                        aEnd.Y() += rEntry.mnOffset;
-                }
-            }
-
             SwRect aRepaintRect( aStart, aEnd );
 
             // the repaint rectangle has to be moved a bit for the centered lines:
@@ -2767,35 +2719,6 @@ void SwTabFramePainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) cons
                     aPaintEnd.Y() = aUpperAligned.Bottom_();
             }
 
-            // logically vertical lines are painted centered on the line,
-            // logically horizontal lines are painted "below" the line
-            //
-            // This does not need to be done here, it is set in SwTabFramePainter::Insert
-            // already using SetRefMode(...) as property of the BorderLine Style, see there.
-            // When additionally adding the offset here manually, it will be applied
-            // double and will be rendered wrong. This did not happen before because
-            // the setting of the svx::frame::RefMode at svx::frame::Style was ignored there.
-            //
-            // bool const isBelow((mrTabFrame.IsVertical()) ? !bHori : bHori);
-            // double const offsetStart = (isBelow)
-            //     ?   aStyles[0].GetWidth() / 2.0
-            //     :   std::max<double>(aStyles[1].GetWidth(),
-            //             aStyles[3].GetWidth()) / 2.0;
-            // double const offsetEnd = (isBelow)
-            //     ?   aStyles[0].GetWidth() / 2.0
-            //     :   std::max<double>(aStyles[4].GetWidth(),
-            //             aStyles[6].GetWidth()) / 2.0;
-            // if (mrTabFrame.IsVertical())
-            // {
-            //     aPaintStart.X() -= static_cast<long>(offsetStart + 0.5);
-            //     aPaintEnd.X()   -= static_cast<long>(offsetEnd   + 0.5);
-            // }
-            // else
-            // {
-            //     aPaintStart.Y() += static_cast<long>(offsetStart + 0.5);
-            //     aPaintEnd.Y()   += static_cast<long>(offsetEnd   + 0.5);
-            // }
-
             if (bHori)
             {
                 const basegfx::B2DPoint aOrigin(aPaintStart.X(), aPaintStart.Y());
@@ -2807,7 +2730,14 @@ void SwTabFramePainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) cons
                     aSequence,
                     aOrigin,
                     aX,
-                    aY,
+
+                    // Writer creates it's vertical BorderLines bottom-to-top (see below).
+                    // To make the horizontal lines correctly 'guess' the line extensions
+                    // for the then mirrored svx::frame::Style for irregular double lines,
+                    // hand over the for that case correct orientatoin of the 'other'
+                    // incoming edges
+                    -aY,
+
                     aStyles[ 0 ],   // current style
                     aStyles[ 1 ],   // aLFromT
                     aStyles[ 2 ],   // aLFromL
@@ -2952,58 +2882,6 @@ void SwTabFramePainter::FindStylesForLine( const Point& rStartPoint,
     }
 }
 
-namespace {
-
-void calcOffsetForDoubleLine( SwLineEntryMap& rLines )
-{
-    SwLineEntryMap aNewLines;
-    SwLineEntryMap::iterator it = rLines.begin(), itEnd = rLines.end();
-    bool bFirst = true;
-    for (; it != itEnd; ++it)
-    {
-        if (bFirst)
-        {
-            // First line needs to be offset to account for double line thickness.
-            SwLineEntrySet aNewSet;
-            const SwLineEntrySet& rSet = it->second;
-            SwLineEntrySet::iterator itSet = rSet.begin(), itSetEnd = rSet.end();
-            size_t nEntryCount = rSet.size();
-            for (size_t i = 0; itSet != itSetEnd; ++itSet, ++i)
-            {
-                SwLineEntry aLine = *itSet;
-                if (aLine.maAttribute.Secn())
-                {
-                    // Apply offset only for double lines.
-                    aLine.mnOffset = static_cast<SwTwips>(aLine.maAttribute.Dist());
-                    aLine.mbOffsetPerp = true;
-
-                    if (i == 0)
-                        aLine.mbOffsetStart = true;
-                    if (i == nEntryCount - 1)
-                        aLine.mbOffsetEnd = true;
-                }
-
-                aNewSet.insert(aLine);
-            }
-
-            aNewLines.insert(SwLineEntryMap::value_type(it->first, aNewSet));
-        }
-        else
-            aNewLines.insert(SwLineEntryMap::value_type(it->first, it->second));
-
-        bFirst = false;
-    }
-    rLines.swap(aNewLines);
-}
-
-}
-
-void SwTabFramePainter::AdjustTopLeftFrames()
-{
-    calcOffsetForDoubleLine(maHoriLines);
-    calcOffsetForDoubleLine(maVertLines);
-}
-
 /**
  * Special case: #i9860#
  * first line in follow table without repeated headlines
commit 0da8ee8262ad5c3c0cb06ee331c806ac85f097dd
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Wed Jul 26 16:34:52 2017 +0200

    borderline: Unified primitive creation
    
    Overhauled the edge extension calculations to better
    use all existing cuts, for cases with single and double
    lines. Also a preparation for more complex edge cuts.
    Changed BorderLine paint in Writer, it was setting the
    svx::frame::RefMode attribute at the Style *and*
    was manually moving the geometry which lead to a
    double applying of the offsets
    
    Change-Id: I446d04632050272849f43accb8dcbde574d10cf4

diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index ad8f67d29d28..769ca425916f 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -345,7 +345,53 @@ double lcl_GetExtent(
     return nCut;
 }
 
-void getOffsetsFromStyle(const Style& rStyle, std::vector< double >& offsets)
+struct OffsetPair
+{
+    double          mfLeft;
+    double          mfRight;
+
+    OffsetPair(double a, double b) : mfLeft(a), mfRight(b) {}
+};
+
+struct OffsetCutSet
+{
+    double          mfLeftLeft;
+    double          mfRightLeft;
+    double          mfLeftRight;
+    double          mfRightRight;
+};
+
+const OffsetCutSet* getMinMaxCutSet(bool bMin, const std::vector< OffsetCutSet >& myCutSets)
+{
+    if (myCutSets.empty())
+    {
+        return nullptr;
+    }
+
+    if (1 == myCutSets.size())
+    {
+        return &myCutSets[0];
+    }
+
+    const OffsetCutSet* pRetval = &myCutSets[0];
+    double fRetval(pRetval->mfLeftLeft + pRetval->mfLeftRight + pRetval->mfRightLeft + pRetval->mfRightRight);
+
+    for (size_t a(1); a < myCutSets.size(); a++)
+    {
+        const OffsetCutSet* pCandidate = &myCutSets[a];
+        const double fCandidate(pCandidate->mfLeftLeft + pCandidate->mfLeftRight + pCandidate->mfRightLeft + pCandidate->mfRightRight);
+
+        if ((bMin && fCandidate < fRetval) || (!bMin && fCandidate > fRetval))
+        {
+            pRetval = pCandidate;
+            fRetval = fCandidate;
+        }
+    }
+
+    return pRetval;
+}
+
+void getOffsetPairsFromStyle(const Style& rStyle, std::vector< OffsetPair >& offsets)
 {
     if (rStyle.Prim())
     {
@@ -357,25 +403,21 @@ void getOffsetsFromStyle(const Style& rStyle, std::vector< double >& offsets)
             case REFMODE_CENTERED:
             {
                 const double fHalfFullWidth(rStyle.GetWidth() * 0.5);
-                offsets.push_back(-fHalfFullWidth);
-                offsets.push_back(rStyle.Prim() - fHalfFullWidth);
-                offsets.push_back((rStyle.Prim() + rStyle.Dist()) - fHalfFullWidth);
-                offsets.push_back(fHalfFullWidth);
+                offsets.push_back(OffsetPair(-fHalfFullWidth, rStyle.Prim() - fHalfFullWidth));
+                offsets.push_back(OffsetPair((rStyle.Prim() + rStyle.Dist()) - fHalfFullWidth, fHalfFullWidth));
                 break;
             }
             case REFMODE_BEGIN:
-                offsets.push_back(0.0);
-                offsets.push_back(rStyle.Prim());
-                offsets.push_back(rStyle.Prim() + rStyle.Dist());
-                offsets.push_back(rStyle.GetWidth());
+            {
+                offsets.push_back(OffsetPair(0.0, rStyle.Prim()));
+                offsets.push_back(OffsetPair(rStyle.Prim() + rStyle.Dist(), rStyle.GetWidth()));
                 break;
+            }
             default: // case RefMode::End:
             {
                 const double fFullWidth(rStyle.GetWidth());
-                offsets.push_back(-fFullWidth);
-                offsets.push_back(rStyle.Prim() - fFullWidth);
-                offsets.push_back((rStyle.Prim() + rStyle.Dist()) - fFullWidth);
-                offsets.push_back(0.0);
+                offsets.push_back(OffsetPair(-fFullWidth, rStyle.Prim() - fFullWidth));
+                offsets.push_back(OffsetPair((rStyle.Prim() + rStyle.Dist()) - fFullWidth, 0.0));
                 break;
             }
             }
@@ -386,110 +428,134 @@ void getOffsetsFromStyle(const Style& rStyle, std::vector< double >& offsets)
             switch (rStyle.GetRefMode())
             {
             case REFMODE_CENTERED:
-                offsets.push_back(rStyle.Prim() * -0.5);
-                offsets.push_back(rStyle.Prim() * 0.5);
+                offsets.push_back(OffsetPair(rStyle.Prim() * -0.5, rStyle.Prim() * 0.5));
                 break;
             case REFMODE_BEGIN:
-                offsets.push_back(0.0);
-                offsets.push_back(rStyle.Prim());
+                offsets.push_back(OffsetPair(0.0, rStyle.Prim()));
                 break;
             default: // case RefMode::End:
-                offsets.push_back(-rStyle.Prim());
-                offsets.push_back(0.0);
+                offsets.push_back(OffsetPair(-rStyle.Prim(), 0.0));
                 break;
             }
         }
     }
 }
 
-void compareToStyle(
+void createCutsWithStyle(
     const basegfx::B2DPoint& rOrigin,
     const basegfx::B2DVector& rOtherVector,
     const basegfx::B2DVector& rOtherUnifiedPerpendicular,
-    const std::vector< double >& rOtherOffsets,
+    const OffsetPair& rOtherOffsets,
     const Style& rStyle,
     const basegfx::B2DVector& rMyVector,
-    std::vector< std::vector< double >>& rOtherCuts)
+    std::vector< OffsetCutSet>& rOtherCuts)
 {
     if (rStyle.Prim())
     {
-        std::vector< double > myOffsets;
+        // get values dependent on source vector
+        const basegfx::B2DVector aMyUnifiedPerpendicular(basegfx::getNormalizedPerpendicular(rMyVector));
+        const basegfx::B2DPoint aOtherPosLeft(rOrigin + (rOtherUnifiedPerpendicular * rOtherOffsets.mfLeft));
+        const basegfx::B2DPoint aOtherPosRight(rOrigin + (rOtherUnifiedPerpendicular * rOtherOffsets.mfRight));
+        std::vector< OffsetPair > myOffsets;
 
-        // get offsets from outer to inner (two or four, depending on style)
-        getOffsetsFromStyle(rStyle, myOffsets);
+        // get offsets from outer to inner from target style (one or two)
+        getOffsetPairsFromStyle(rStyle, myOffsets);
 
-        if (!myOffsets.empty())
+        for (const auto& myOffset : myOffsets)
         {
-            const basegfx::B2DVector aMyUnifiedPerpendicular(basegfx::getNormalizedPerpendicular(rMyVector));
-
-            for (size_t a(0); a < rOtherOffsets.size(); a++)
-            {
-                const basegfx::B2DPoint aOtherPos(rOrigin + (rOtherUnifiedPerpendicular * rOtherOffsets[a]));
-
-                for (size_t b(0); b < myOffsets.size(); b++)
-                {
-                    const basegfx::B2DPoint aMyPos(rOrigin + (aMyUnifiedPerpendicular * myOffsets[b]));
-                    double fCut(0.0);
-                    basegfx::tools::findCut(
-                        aOtherPos,
-                        rOtherVector,
-                        aMyPos,
-                        rMyVector,
-                        CutFlagValue::LINE,
-                        &fCut);
-
-                    rOtherCuts[a].push_back(fCut);
-                }
-            }
+            // get values for new vectors and create all four cuts
+            const basegfx::B2DPoint aMyPosLeft(rOrigin + (aMyUnifiedPerpendicular * myOffset.mfLeft));
+            const basegfx::B2DPoint aMyPosRight(rOrigin + (aMyUnifiedPerpendicular * myOffset.mfRight));
+            OffsetCutSet aNewCuts;
+
+            basegfx::tools::findCut(
+                aOtherPosLeft,
+                rOtherVector,
+                aMyPosLeft,
+                rMyVector,
+                CutFlagValue::LINE,
+                &aNewCuts.mfLeftLeft);
+
+            basegfx::tools::findCut(
+                aOtherPosLeft,
+                rOtherVector,
+                aMyPosRight,
+                rMyVector,
+                CutFlagValue::LINE,
+                &aNewCuts.mfLeftRight);
+
+            basegfx::tools::findCut(
+                aOtherPosRight,
+                rOtherVector,
+                aMyPosLeft,
+                rMyVector,
+                CutFlagValue::LINE,
+                &aNewCuts.mfRightLeft);
+
+            basegfx::tools::findCut(
+                aOtherPosRight,
+                rOtherVector,
+                aMyPosRight,
+                rMyVector,
+                CutFlagValue::LINE,
+                &aNewCuts.mfRightRight);
+
+            rOtherCuts.push_back(aNewCuts);
         }
     }
 }
 
-double getMinMaxCut(bool bMin, const std::vector< double >& rVector)
+double getSimpleExtendedLineValues(
+    const basegfx::B2DPoint& rOrigin,
+    const basegfx::B2DVector& rX,
+    const basegfx::B2DVector& rY,
+    const basegfx::B2DVector& rPerpendX,
+    const OffsetPair& myOffset,
+    const Style& rFirst,
+    const Style& rSecond,
+    bool bEdgeStart,
+    double fLength)
 {
-    if (rVector.empty())
-    {
-        return 0.0;
-    }
-
-    if (1 == rVector.size())
-    {
-        return rVector[0];
-    }
-
-    double fRetval(rVector[0]);
+    std::vector< OffsetCutSet > myCutSets;
+    createCutsWithStyle(rOrigin, rX, rPerpendX, myOffset, rFirst, rY, myCutSets);
+    createCutsWithStyle(rOrigin, rX, rPerpendX, myOffset, rSecond, rY, myCutSets);
+    const OffsetCutSet* pResult = getMinMaxCutSet(bEdgeStart, myCutSets);
 
-    for (size_t a(1); a < rVector.size(); a++)
+    if (pResult)
     {
-        fRetval = bMin ? std::min(fRetval, rVector[a]) : std::max(fRetval, rVector[a]);
+        return (pResult->mfLeftRight + pResult->mfRightRight) * 0.5 * (bEdgeStart ? -fLength : fLength);
     }
 
-    return fRetval;
+    return 0.0;
 }
 
-std::vector< double > getMinMaxCuts(bool bMin, const std::vector< std::vector< double >>& rCuts)
+double getComplexExtendedLineValues(
+    const basegfx::B2DPoint& rOrigin,
+    const basegfx::B2DVector& rX,
+    const basegfx::B2DVector& rY,
+    const basegfx::B2DVector& rPerpendX,
+    const OffsetPair& myOffset,
+    const Style& rFirst,
+    const Style& rSecond,
+    bool bEdgeStart,
+    double fLength)
 {
-    std::vector< double > aRetval(rCuts.size());
+    std::vector< OffsetCutSet > myCutSets;
+    createCutsWithStyle(rOrigin, rX, rPerpendX, myOffset, rFirst, rY, myCutSets);
+    const OffsetCutSet* pResult = getMinMaxCutSet(!bEdgeStart, myCutSets);
 
-    for (size_t a(0); a < rCuts.size(); a++)
+    if (!pResult)
     {
-        aRetval[a] = getMinMaxCut(bMin, rCuts[a]);
+        createCutsWithStyle(rOrigin, rX, rPerpendX, myOffset, rSecond, rY, myCutSets);
+        pResult = getMinMaxCutSet(bEdgeStart, myCutSets);
     }
 
-    return aRetval;
-}
-
-bool areCutsEmpty(std::vector< std::vector< double >>& rCuts)
-{
-    for (const auto& rVec : rCuts)
+    if (pResult)
     {
-        if (!rVec.empty())
-        {
-            return false;
-        }
+        return (pResult->mfLeftRight + pResult->mfRightRight) * 0.5 * (bEdgeStart ? -fLength : fLength);
     }
 
-    return true;
+    return 0.0;
 }
 
 void CreateBorderPrimitives(
@@ -512,12 +578,6 @@ void CreateBorderPrimitives(
 {
     if (rBorder.Prim())
     {
-        double mfExtendLeftStart(0.0);
-        double mfExtendLeftEnd(0.0);
-        double mfExtendRightStart(0.0);
-        double mfExtendRightEnd(0.0);
-        std::vector< double > myOffsets;
-        getOffsetsFromStyle(rBorder, myOffsets);
         const basegfx::B2DVector aPerpendX(basegfx::getNormalizedPerpendicular(rX));
         const double fLength(rX.getLength());
 
@@ -526,7 +586,6 @@ void CreateBorderPrimitives(
 
         if (REFMODE_CENTERED != rBorder.GetRefMode())
         {
-            const basegfx::B2DVector aPerpendX(basegfx::getNormalizedPerpendicular(rX));
             const double fHalfWidth(rBorder.GetWidth() * 0.5);
 
             if (REFMODE_BEGIN == rBorder.GetRefMode())
@@ -541,23 +600,27 @@ void CreateBorderPrimitives(
             }
         }
 
-        // create start/end for RefMode::Centered
+        // create start/end (use RefMode)
         const basegfx::B2DPoint aStart(rOrigin + aRefModeOffset);
         const basegfx::B2DPoint aEnd(aStart + rX);
 
-        if (2 == myOffsets.size())
+        // get offsets for my style (one or two)
+        std::vector< OffsetPair > myOffsets;
+        getOffsetPairsFromStyle(rBorder, myOffsets);
+
+        if (1 == myOffsets.size())
         {
-            std::vector< std::vector< double >> myCutsS(myOffsets.size());
-            compareToStyle(rOrigin, rX, aPerpendX, myOffsets, rLFromT, rY, myCutsS);
-            compareToStyle(rOrigin, rX, aPerpendX, myOffsets, rLFromB, rY, myCutsS);
-            std::vector< double > nMinCutsS(getMinMaxCuts(true, myCutsS));
-            mfExtendLeftStart = ((nMinCutsS[0] + nMinCutsS[1]) * 0.5) * -1.0 * fLength;
-
-            std::vector< std::vector< double >> myCutsE(myOffsets.size());
-            compareToStyle(rOrigin, rX, aPerpendX, myOffsets, rRFromT, rY, myCutsE);
-            compareToStyle(rOrigin, rX, aPerpendX, myOffsets, rRFromB, rY, myCutsE);
-            std::vector< double > nMinCutsE(getMinMaxCuts(false, myCutsE));
-            mfExtendLeftEnd = ((nMinCutsE[0] + nMinCutsE[1]) * 0.5) * fLength;
+            // we are a single edge, calculate cuts with edges coming from above/below
+            // to detect the line start/end extensions
+            const OffsetPair& myOffset(myOffsets[0]);
+            double mfExtendStart(0.0);
+            double mfExtendEnd(0.0);
+
+            // for start: get cuts with all left target styles and use the minimum
+            mfExtendStart = getSimpleExtendedLineValues(rOrigin, rX, rY, aPerpendX, myOffset, rLFromT, rLFromB, true, fLength);
+
+            // for end: get cuts with all right target styles and use the maximum
+            mfExtendEnd = getSimpleExtendedLineValues(rOrigin, rX, rY, aPerpendX, myOffset, rRFromT, rRFromB, false, fLength);
 
             rTarget.push_back(
                 drawinglayer::primitive2d::Primitive2DReference(
@@ -567,88 +630,35 @@ void CreateBorderPrimitives(
                         drawinglayer::primitive2d::BorderLine(
                             rBorder.Prim(),
                             (pForceColor ? *pForceColor : rBorder.GetColorPrim()).getBColor(),
-                            mfExtendLeftStart,
-                            mfExtendLeftEnd),
+                            mfExtendStart,
+                            mfExtendEnd),
                         rBorder.Type(),
                         rBorder.PatternScale())));
         }
-        else if (4 == myOffsets.size())
+        else if (2 == myOffsets.size())
         {
-            {
-                std::vector< double > myOffsetsA;
-                myOffsetsA.push_back(myOffsets[0]);
-                myOffsetsA.push_back(myOffsets[1]);
+            // we are a double edge, calculate cuts with edges coming from above/below
+            // for both edges to detect the line start/end extensions
+            double mfExtendLeftStart(0.0);
+            double mfExtendLeftEnd(0.0);
+            double mfExtendRightStart(0.0);
+            double mfExtendRightEnd(0.0);
 
-                std::vector< std::vector< double >> myCutsS(myOffsetsA.size());
-                std::vector< double > nMinCutsS;
-                compareToStyle(rOrigin, rX, aPerpendX, myOffsetsA, rLFromT, rY, myCutsS);
+            // for start of first edge, get cuts with left targets. Start with upper and take maximum when
+            // cut exists. Else use lower and take minimum when cut exists
+            mfExtendLeftStart = getComplexExtendedLineValues(rOrigin, rX, rY, aPerpendX, myOffsets[0], rLFromT, rLFromB, true, fLength);
 
-                if (!areCutsEmpty(myCutsS))
-                {
-                    nMinCutsS = getMinMaxCuts(false, myCutsS);
-                }
-                else
-                {
-                    compareToStyle(rOrigin, rX, aPerpendX, myOffsetsA, rLFromB, rY, myCutsS);
-                    nMinCutsS = getMinMaxCuts(true, myCutsS);
-                }
-
-                mfExtendLeftStart = ((nMinCutsS[0] + nMinCutsS[1]) * 0.5) * -1.0 * fLength;
+            // for end of first edge, get cuts with right targets. Start with upper and take minimum when
+            // cut exists. Else use lower and take maximum when cut exists
+            mfExtendLeftEnd = getComplexExtendedLineValues(rOrigin, rX, rY, aPerpendX, myOffsets[0], rRFromT, rRFromB, false, fLength);
 
-                std::vector< std::vector< double >> myCutsE(myOffsetsA.size());
-                std::vector< double > nMinCutsE;
-                compareToStyle(rOrigin, rX, aPerpendX, myOffsetsA, rRFromT, rY, myCutsE);
+            // for start of second edge, get cuts with left targets. Start with lower and take maximum when
+            // cut exists. Else use upper and take minimum when cut exists
+            mfExtendRightStart = getComplexExtendedLineValues(rOrigin, rX, rY, aPerpendX, myOffsets[1], rLFromB, rLFromT, true, fLength);
 
-                if (!areCutsEmpty(myCutsE))
-                {
-                    nMinCutsE = getMinMaxCuts(true, myCutsE);
-                }
-                else
-                {
-                    compareToStyle(rOrigin, rX, aPerpendX, myOffsetsA, rRFromB, rY, myCutsE);
-                    nMinCutsE = getMinMaxCuts(false, myCutsE);
-                }
-
-                mfExtendLeftEnd = ((nMinCutsE[0] + nMinCutsE[1]) * 0.5) * fLength;
-            }
-
-            {
-                std::vector< double > myOffsetsB;
-                myOffsetsB.push_back(myOffsets[2]);
-                myOffsetsB.push_back(myOffsets[3]);
-
-                std::vector< std::vector< double >> myCutsS(myOffsetsB.size());
-                std::vector< double > nMinCutsS;
-                compareToStyle(rOrigin, rX, aPerpendX, myOffsetsB, rLFromB, rY, myCutsS);
-
-                if (!areCutsEmpty(myCutsS))
-                {
-                    nMinCutsS = getMinMaxCuts(false, myCutsS);
-                }
-                else
-                {
-                    compareToStyle(rOrigin, rX, aPerpendX, myOffsetsB, rLFromT, rY, myCutsS);
-                    nMinCutsS = getMinMaxCuts(true, myCutsS);
-                }
-
-                mfExtendRightStart = ((nMinCutsS[0] + nMinCutsS[1]) * 0.5) * -1.0 * fLength;
-
-                std::vector< std::vector< double >> myCutsE(myOffsetsB.size());
-                std::vector< double > nMinCutsE;
-                compareToStyle(rOrigin, rX, aPerpendX, myOffsetsB, rRFromB, rY, myCutsE);
-
-                if (!areCutsEmpty(myCutsE))
-                {
-                    nMinCutsE = getMinMaxCuts(true, myCutsE);
-                }
-                else
-                {
-                    compareToStyle(rOrigin, rX, aPerpendX, myOffsetsB, rRFromT, rY, myCutsE);
-                    nMinCutsE = getMinMaxCuts(false, myCutsE);
-                }
-
-                mfExtendRightEnd = ((nMinCutsE[0] + nMinCutsE[1]) * 0.5) * fLength;
-            }
+            // for end of second edge, get cuts with right targets. Start with lower and take minimum when
+            // cut exists. Else use upper and take maximum when cut exists
+            mfExtendRightEnd = getComplexExtendedLineValues(rOrigin, rX, rY, aPerpendX, myOffsets[1], rRFromB, rRFromT, false, fLength);
 
             rTarget.push_back(
                 drawinglayer::primitive2d::Primitive2DReference(
@@ -720,16 +730,19 @@ void CreateDiagFrameBorderPrimitives(
     const basegfx::B2DVector& rYAxis,
     const Style& rTLBR,
     const Style& rBLTR,
-    const Style& rTLFromB,
-    const Style& rTLFromR,
-    const Style& rBRFromT,
-    const Style& rBRFromL,
-    const Style& rBLFromT,
-    const Style& rBLFromR,
-    const Style& rTRFromB,
-    const Style& rTRFromL,
+    const Style& /*rTLFromB*/,
+    const Style& /*rTLFromR*/,
+    const Style& /*rBRFromT*/,
+    const Style& /*rBRFromL*/,
+    const Style& /*rBLFromT*/,
+    const Style& /*rBLFromR*/,
+    const Style& /*rTRFromB*/,
+    const Style& /*rTRFromL*/,
     const Color* pForceColor)
 {
+    // currently the diagonal edges are just added as-is without cutting them against the incoming
+    // edges. This needs to be improved in the future, so please do *not* remove the currently unused
+    // parameters from above
     if (rTLBR.Prim())
     {
         // top-left to bottom-right
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 000eb192ed2f..19fe8e4c48bb 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -2769,25 +2769,32 @@ void SwTabFramePainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) cons
 
             // logically vertical lines are painted centered on the line,
             // logically horizontal lines are painted "below" the line
-            bool const isBelow((mrTabFrame.IsVertical()) ? !bHori : bHori);
-            double const offsetStart = (isBelow)
-                ?   aStyles[0].GetWidth() / 2.0
-                :   std::max<double>(aStyles[1].GetWidth(),
-                        aStyles[3].GetWidth()) / 2.0;
-            double const offsetEnd = (isBelow)
-                ?   aStyles[0].GetWidth() / 2.0
-                :   std::max<double>(aStyles[4].GetWidth(),
-                        aStyles[6].GetWidth()) / 2.0;
-            if (mrTabFrame.IsVertical())
-            {
-                aPaintStart.X() -= static_cast<long>(offsetStart + 0.5);
-                aPaintEnd.X()   -= static_cast<long>(offsetEnd   + 0.5);
-            }
-            else
-            {
-                aPaintStart.Y() += static_cast<long>(offsetStart + 0.5);
-                aPaintEnd.Y()   += static_cast<long>(offsetEnd   + 0.5);
-            }
+            //
+            // This does not need to be done here, it is set in SwTabFramePainter::Insert
+            // already using SetRefMode(...) as property of the BorderLine Style, see there.
+            // When additionally adding the offset here manually, it will be applied
+            // double and will be rendered wrong. This did not happen before because
+            // the setting of the svx::frame::RefMode at svx::frame::Style was ignored there.
+            //
+            // bool const isBelow((mrTabFrame.IsVertical()) ? !bHori : bHori);
+            // double const offsetStart = (isBelow)
+            //     ?   aStyles[0].GetWidth() / 2.0
+            //     :   std::max<double>(aStyles[1].GetWidth(),
+            //             aStyles[3].GetWidth()) / 2.0;
+            // double const offsetEnd = (isBelow)
+            //     ?   aStyles[0].GetWidth() / 2.0
+            //     :   std::max<double>(aStyles[4].GetWidth(),
+            //             aStyles[6].GetWidth()) / 2.0;
+            // if (mrTabFrame.IsVertical())
+            // {
+            //     aPaintStart.X() -= static_cast<long>(offsetStart + 0.5);
+            //     aPaintEnd.X()   -= static_cast<long>(offsetEnd   + 0.5);
+            // }
+            // else
+            // {
+            //     aPaintStart.Y() += static_cast<long>(offsetStart + 0.5);
+            //     aPaintEnd.Y()   += static_cast<long>(offsetEnd   + 0.5);
+            // }
 
             if (bHori)
             {
commit 4a71e2e979de740b6ca8d7dec54fa9bf848645d8
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Wed Jul 26 13:19:50 2017 +0200

    borderline: Simplified BorderLinePrimitive
    
    Overhauled BorderLinePrimitive to use two constructors
    offering using one or three edge definitions for
    construction to better refrlect possibilities. Adapted
    usages. Better processing, less memory. Preparation
    for using more decent LineExtend values (four per line
    needed)
    
    Change-Id: Iac9d9ae64874fea38fd6e2a04221698481cc0d0e

diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index 6bf69265661d..9961c5f5a8b0 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -45,41 +45,53 @@ namespace drawinglayer
 {
     namespace primitive2d
     {
+        BorderLine::BorderLine(
+            double fWidth,
+            const basegfx::BColor& rRGBColor,
+            double fExtendStart,
+            double fExtendEnd)
+        :   mfWidth(fWidth),
+            maRGBColor(rRGBColor),
+            mfExtendStart(fExtendStart),
+            mfExtendEnd(fExtendEnd)
+        {
+        }
+
+        bool BorderLine::operator==(const BorderLine& rBorderLine) const
+        {
+            return getWidth() == rBorderLine.getWidth()
+                && getRGBColor() == rBorderLine.getRGBColor()
+                && getExtendStart() == rBorderLine.getExtendStart()
+                && getExtendEnd() == rBorderLine.getExtendEnd();
+        }
+
         // helper to add a centered, maybe stroked line primitive to rContainer
         void addPolygonStrokePrimitive2D(
             Primitive2DContainer& rContainer,
             const basegfx::B2DPoint& rStart,
             const basegfx::B2DPoint& rEnd,
-            const basegfx::BColor& rColor,
-            double fWidth,
-            editeng::SvxBorderStyle aStyle,
-            double fPatternScale)
+            const attribute::LineAttribute& rLineAttribute,
+            const attribute::StrokeAttribute & rStrokeAttribute)
         {
             basegfx::B2DPolygon aPolygon;
 
             aPolygon.append(rStart);
             aPolygon.append(rEnd);
 
-            const attribute::LineAttribute aLineAttribute(rColor, fWidth);
-            static double fPatScFact(10.0); // 10.0 multiply, see old code
-            const std::vector<double> aDashing(svtools::GetLineDashing(aStyle, fPatternScale * fPatScFact));
-
-            if (aDashing.empty())
+            if (rStrokeAttribute.isDefault())
             {
                 rContainer.push_back(
                     new PolygonStrokePrimitive2D(
                         aPolygon,
-                        aLineAttribute));
+                        rLineAttribute));
             }
             else
             {
-                const attribute::StrokeAttribute aStrokeAttribute(aDashing);
-
                 rContainer.push_back(
                     new PolygonStrokePrimitive2D(
                         aPolygon,
-                        aLineAttribute,
-                        aStrokeAttribute));
+                        rLineAttribute,
+                        rStrokeAttribute));
             }
         }
 
@@ -87,79 +99,84 @@ namespace drawinglayer
         {
             Primitive2DContainer aContainer;
 
-            if (!getStart().equal(getEnd()) && (isInsideUsed() || isOutsideUsed()))
+            if (!getStart().equal(getEnd()))
             {
                 // get data and vectors
                 basegfx::B2DVector aVector(getEnd() - getStart());
                 aVector.normalize();
                 const basegfx::B2DVector aPerpendicular(basegfx::getPerpendicular(aVector));
+                static double fPatScFact(10.0); // 10.0 multiply, see old code
+                const std::vector<double> aDashing(svtools::GetLineDashing(getStyle(), getPatternScale() * fPatScFact));
+                const attribute::StrokeAttribute aStrokeAttribute(aDashing);
 
-                if (isOutsideUsed() && isInsideUsed())
+                if (3 == getBorderLines().size())
                 {
-                    // double line with gap. Use mfDiscreteDistance (see get2DDecomposition) as distance.
+                    // double line with gap. Use mfDiscreteGapDistance (see get2DDecomposition) as distance.
                     // That value is prepared to be at least one pixel (discrete unit) so that the
                     // decomposition is view-dependent in this cases
-                    if (isInsideUsed())
                     {
-                        // inside line (left). Create stroke primitive centered on line width
-                        const double fDeltaY((mfDiscreteDistance + getLeftWidth()) * 0.5);
+                        // inside line (left of vector). Create stroke primitive centered on line width
+                        const BorderLine& rLeft(getBorderLines()[0]);
+                        const double fDeltaY((mfDiscreteGapDistance + rLeft.getWidth()) * 0.5);
                         const basegfx::B2DVector aDeltaY(aPerpendicular * fDeltaY);
-                        const basegfx::B2DPoint aStart(getStart() - (aVector * getExtendLeftStart()) - aDeltaY);
-                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * getExtendLeftEnd()) - aDeltaY);
+                        const basegfx::B2DPoint aStart(getStart() - (aVector * rLeft.getExtendStart()) - aDeltaY);
+                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * rLeft.getExtendEnd()) - aDeltaY);
+                        const attribute::LineAttribute aLineAttribute(rLeft.getRGBColor(), rLeft.getWidth());
 
                         addPolygonStrokePrimitive2D(
                             aContainer,
                             aStart,
                             aEnd,
-                            getRGBColorLeft(),
-                            getLeftWidth(),
-                            getStyle(),
-                            getPatternScale());
+                            aLineAttribute,
+                            aStrokeAttribute);
                     }
 
-                    if (hasGapColor() && isDistanceUsed())
+                    if (hasGapColor())
                     {
-                        // gap (if visible, found no practicval usage).
+                        // gap (if visible, found practical usage in Writer MultiColorBorderLines).
                         // Create stroke primitive on vector with given color
+                        const BorderLine& rGap(getBorderLines()[1]);
+                        const basegfx::B2DPoint aStart(getStart() - (aVector * rGap.getExtendStart()));
+                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * rGap.getExtendEnd()));
+                        const attribute::LineAttribute aLineAttribute(rGap.getRGBColor(), mfDiscreteGapDistance);
+
                         addPolygonStrokePrimitive2D(
                             aContainer,
-                            getStart(),
-                            getEnd(),
-                            getRGBColorGap(),
-                            mfDiscreteDistance,
-                            getStyle(),
-                            getPatternScale());
+                            aStart,
+                            aEnd,
+                            aLineAttribute,
+                            aStrokeAttribute);
                     }
 
-                    if (isOutsideUsed())
                     {
-                        // outside line (right). Create stroke primitive centered on line width
-                        const double fDeltaY((mfDiscreteDistance + getRightWidth()) * 0.5);
+                        // outside line (right of vector). Create stroke primitive centered on line width
+                        const BorderLine& rRight(getBorderLines()[2]);
+                        const double fDeltaY((mfDiscreteGapDistance + rRight.getWidth()) * 0.5);
                         const basegfx::B2DVector aDeltaY(aPerpendicular * fDeltaY);
-                        const basegfx::B2DPoint aStart(getStart() - (aVector * getExtendRightStart()) + aDeltaY);
-                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * getExtendRightEnd()) + aDeltaY);
+                        const basegfx::B2DPoint aStart(getStart() - (aVector * rRight.getExtendStart()) + aDeltaY);
+                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * rRight.getExtendEnd()) + aDeltaY);
+                        const attribute::LineAttribute aLineAttribute(rRight.getRGBColor(), rRight.getWidth());
 
                         addPolygonStrokePrimitive2D(
                             aContainer,
                             aStart,
                             aEnd,
-                            getRGBColorRight(),
-                            getRightWidth(),
-                            getStyle(),
-                            getPatternScale());
+                            aLineAttribute,
+                            aStrokeAttribute);
                     }
                 }
-                else if(isInsideUsed())
+                else
                 {
                     // single line, only inside values used, no vertical offsets
+                    const BorderLine& rBorderLine(getBorderLines()[0]);
+                    const attribute::LineAttribute aLineAttribute(rBorderLine.getRGBColor(), rBorderLine.getWidth());
+
                     addPolygonStrokePrimitive2D(
                         aContainer,
-                        getStart() - (aVector * getExtendLeftStart()),
-                        getEnd() + (aVector * getExtendLeftEnd()),
-                        getRGBColorLeft(),
-                        getLeftWidth(),
-                        getStyle(),
-                        getPatternScale());
+                        getStart() - (aVector * rBorderLine.getExtendStart()),
+                        getEnd() + (aVector * rBorderLine.getExtendEnd()),
+                        aLineAttribute,
+                        aStrokeAttribute);
                 }
             }
 
@@ -182,37 +199,42 @@ namespace drawinglayer
         BorderLinePrimitive2D::BorderLinePrimitive2D(
             const basegfx::B2DPoint& rStart,
             const basegfx::B2DPoint& rEnd,
-            double fLeftWidth,
-            double fDistance,
-            double fRightWidth,
-            double fExtendLeftStart,
-            double fExtendLeftEnd,
-            double fExtendRightStart,
-            double fExtendRightEnd,
-            const basegfx::BColor& rRGBColorRight,
-            const basegfx::BColor& rRGBColorLeft,
-            const basegfx::BColor& rRGBColorGap,
+            const BorderLine& rBorderLine,
+            editeng::SvxBorderStyle nStyle,
+            double fPatternScale)
+        :   BufferedDecompositionPrimitive2D(),
+            maStart(rStart),
+            maEnd(rEnd),
+            maBorderLines(),
+            mbHasGapColor(false),
+            mnStyle(nStyle),
+            mfPatternScale(fPatternScale),
+            mfDiscreteGapDistance(0.0)
+        {
+            maBorderLines.push_back(rBorderLine);
+        }
+
+        BorderLinePrimitive2D::BorderLinePrimitive2D(
+            const basegfx::B2DPoint& rStart,
+            const basegfx::B2DPoint& rEnd,
+            const BorderLine& rLeft,
+            const BorderLine& rGap,
+            const BorderLine& rRight,
             bool bHasGapColor,
             const short nStyle,
             double fPatternScale)
         :   BufferedDecompositionPrimitive2D(),
             maStart(rStart),
             maEnd(rEnd),
-            mfLeftWidth(fLeftWidth),
-            mfDistance(fDistance),
-            mfRightWidth(fRightWidth),
-            mfExtendLeftStart(fExtendLeftStart),
-            mfExtendLeftEnd(fExtendLeftEnd),
-            mfExtendRightStart(fExtendRightStart),
-            mfExtendRightEnd(fExtendRightEnd),
-            maRGBColorRight(rRGBColorRight),
-            maRGBColorLeft(rRGBColorLeft),
-            maRGBColorGap(rRGBColorGap),
+            maBorderLines(),
             mbHasGapColor(bHasGapColor),
             mnStyle(nStyle),
             mfPatternScale(fPatternScale),
-            mfDiscreteDistance(0.0)
+            mfDiscreteGapDistance(0.0)
         {
+            maBorderLines.push_back(rLeft);
+            maBorderLines.push_back(rGap);
+            maBorderLines.push_back(rRight);
         }
 
         bool BorderLinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
@@ -221,21 +243,23 @@ namespace drawinglayer
             {
                 const BorderLinePrimitive2D& rCompare = static_cast<const BorderLinePrimitive2D&>(rPrimitive);
 
-                return (getStart() == rCompare.getStart()
+                if (getStart() == rCompare.getStart()
                     && getEnd() == rCompare.getEnd()
-                    && getLeftWidth() == rCompare.getLeftWidth()
-                    && getDistance() == rCompare.getDistance()
-                    && getRightWidth() == rCompare.getRightWidth()
-                    && getExtendLeftStart() == rCompare.getExtendLeftStart()
-                    && getExtendLeftEnd() == rCompare.getExtendLeftEnd()
-                    && getExtendRightStart() == rCompare.getExtendRightStart()
-                    && getExtendRightEnd() == rCompare.getExtendRightEnd()
-                    && getRGBColorRight() == rCompare.getRGBColorRight()
-                    && getRGBColorLeft() == rCompare.getRGBColorLeft()
-                    && getRGBColorGap() == rCompare.getRGBColorGap()
                     && hasGapColor() == rCompare.hasGapColor()
                     && getStyle() == rCompare.getStyle()
-                    && getPatternScale() == rCompare.getPatternScale());
+                    && getPatternScale() == rCompare.getPatternScale())
+                {
+                    if (getBorderLines().size() == rCompare.getBorderLines().size())
+                    {
+                        for (size_t a(0); a < getBorderLines().size(); a++)
+                        {
+                            if (!(getBorderLines()[a] == rCompare.getBorderLines()[a]))
+                            {
+                                return false;
+                            }
+                        }
+                    }
+                }
             }
 
             return false;
@@ -245,7 +269,7 @@ namespace drawinglayer
         {
             ::osl::MutexGuard aGuard(m_aMutex);
 
-            if (!getStart().equal(getEnd()) && isOutsideUsed() && isInsideUsed())
+            if (!getStart().equal(getEnd()) && 3 == getBorderLines().size())
             {
                 // Double line with gap. In this case, we want to be view-dependent.
                 // Get the current DiscreteUnit, look at X and Y and use the maximum
@@ -258,9 +282,10 @@ namespace drawinglayer
                 // This can also be done using DiscreteMetricDependentPrimitive2D as base class
                 // for this class, but specialization is better here for later buffering (only
                 // do this when 'double line with gap')
-                const double fNewDiscreteDistance(std::max(fDiscreteUnit, getDistance()));
+                const double fDistance(getBorderLines()[1].getWidth());
+                const double fNewDiscreteDistance(std::max(fDiscreteUnit, fDistance));
 
-                if (!rtl::math::approxEqual(fNewDiscreteDistance, mfDiscreteDistance))
+                if (!rtl::math::approxEqual(fNewDiscreteDistance, mfDiscreteGapDistance))
                 {
                     if (!getBuffered2DDecomposition().empty())
                     {
@@ -269,7 +294,7 @@ namespace drawinglayer
                     }
 
                     // remember value for usage in create2DDecomposition
-                    const_cast< BorderLinePrimitive2D* >(this)->mfDiscreteDistance = fNewDiscreteDistance;
+                    const_cast< BorderLinePrimitive2D* >(this)->mfDiscreteGapDistance = fNewDiscreteDistance;
                 }
             }
 
diff --git a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
index 8c7fb25cf87d..0696a30e7f12 100644
--- a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
@@ -34,14 +34,49 @@ namespace drawinglayer
 {
     namespace primitive2d
     {
+        /** BorderLine class
+        Helper class holding the style definition for a single part of a full BNorderLine definition
+        */
+        class DRAWINGLAYER_DLLPUBLIC BorderLine
+        {
+        private:
+            // line width
+            double              mfWidth;
+
+            // line color
+            basegfx::BColor     maRGBColor;
+
+            // line extends
+            double              mfExtendStart;
+            double              mfExtendEnd;
+
+            // not implemented
+            virtual bool operator!=(const BorderLine& rBorderLine) const = delete;
+
+        public:
+            BorderLine(
+                double fWidth,
+                const basegfx::BColor& rRGBColor,
+                double fExtendStart = 0.0,
+                double fExtendEnd = 0.0);
+
+            double getWidth() const { return mfWidth; }
+            const basegfx::BColor& getRGBColor() const { return maRGBColor; }
+            double getExtendStart() const { return mfExtendStart; }
+            double getExtendEnd() const { return mfExtendEnd; }
+
+            /// compare operator
+            virtual bool operator==(const BorderLine& rBorderLine) const;
+        };
+
         /** BorderLinePrimitive2D class
 
-            This is the basic primitive to build frames around objects, e.g. tables.
-            It defines a single or double line from Start to End using the LeftWidth,
-            Distance and RightWidth definitions.
-            The LineStart/End overlap is defined by the Extend(Left|Right)(Start|End)
-            definitions.
-         */
+        This is the basic primitive to build frames around objects, e.g. tables.
+        It defines a single or double line from Start to End using the LeftWidth,
+        Distance and RightWidth definitions.
+        The LineStart/End overlap is defined by the Extend(Left|Right)(Start|End)
+        definitions.
+        */
         class DRAWINGLAYER_DLLPUBLIC BorderLinePrimitive2D : public BufferedDecompositionPrimitive2D
         {
         private:
@@ -49,84 +84,49 @@ namespace drawinglayer
             basegfx::B2DPoint                               maStart;
             basegfx::B2DPoint                               maEnd;
 
-            /// the widths of single/double line
-            double                                          mfLeftWidth;
-            double                                          mfDistance;
-            double                                          mfRightWidth;
-
-            /// edge overlap sizes
-            double                                          mfExtendLeftStart;
-            double                                          mfExtendLeftEnd;
-            double                                          mfExtendRightStart;
-            double                                          mfExtendRightEnd;
-
-            /// the line colors
-            basegfx::BColor                                 maRGBColorRight;
-            basegfx::BColor                                 maRGBColorLeft;
-            basegfx::BColor                                 maRGBColorGap;
+            /// the single BorderLine style definition(s), one or three allowed (see constructors)
+            std::vector< BorderLine >                       maBorderLines;
+
             bool                                            mbHasGapColor;
 
+            /// common style definitions
             editeng::SvxBorderStyle                         mnStyle;
             double                                          mfPatternScale;
 
             // for view dependent decomposition in the case with distance (gap),
             // remember the last used concrete mfDistance, see get2DDecomposition
             // implementation
-            double                                          mfDiscreteDistance;
-
-            /// local helpers
-            bool isInsideUsed() const
-            {
-                return !basegfx::fTools::equalZero(mfLeftWidth);
-            }
-
-            bool isDistanceUsed() const
-            {
-                return !basegfx::fTools::equalZero(mfDistance);
-            }
-
-            bool isOutsideUsed() const
-            {
-                return !basegfx::fTools::equalZero(mfRightWidth);
-            }
+            double                                          mfDiscreteGapDistance;
 
             /// create local decomposition
             virtual Primitive2DContainer create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const override;
 
         public:
-            /// constructor
+            /// simplified constructor for BorderLine with single edge
+            BorderLinePrimitive2D(
+                const basegfx::B2DPoint& rStart,
+                const basegfx::B2DPoint& rEnd,
+                const BorderLine& rBorderLine,
+                editeng::SvxBorderStyle nStyle,
+                double fPatternScale = 1.0);
+
+            /// constructor for full-fledged BorderLine with two edges and gap
             BorderLinePrimitive2D(
                 const basegfx::B2DPoint& rStart,
                 const basegfx::B2DPoint& rEnd,
-                double fLeftWidth,
-                double fDistance,
-                double fRightWidth,
-                double fExtendLeftStart,
-                double fExtendLeftEnd,
-                double fExtendRightStart,
-                double fExtendRightEnd,
-                const basegfx::BColor& rRGBColorRight,
-                const basegfx::BColor& rRGBColorLeft,
-                const basegfx::BColor& rRGBColorGap,
+                const BorderLine& rLeft,
+                const BorderLine& rGap,
+                const BorderLine& rRight,
                 bool bHasGapColor,
-                const short nStyle,
-                double fPatternScale = 1.0 );
+                editeng::SvxBorderStyle nStyle,
+                double fPatternScale = 1.0);
 
             /// data read access
             const basegfx::B2DPoint& getStart() const { return maStart; }
             const basegfx::B2DPoint& getEnd() const { return maEnd; }
-            double getLeftWidth() const { return mfLeftWidth; }
-            double getDistance() const { return mfDistance; }
-            double getRightWidth() const { return mfRightWidth; }
-            double getExtendLeftStart() const { return mfExtendLeftStart; }
-            double getExtendLeftEnd() const { return mfExtendLeftEnd; }
-            double getExtendRightStart() const { return mfExtendRightStart; }
-            double getExtendRightEnd() const { return mfExtendRightEnd; }
-            const basegfx::BColor& getRGBColorRight () const { return maRGBColorRight; }
-            const basegfx::BColor& getRGBColorLeft () const { return maRGBColorLeft; }
-            const basegfx::BColor& getRGBColorGap () const { return maRGBColorGap; }
-            bool hasGapColor( ) const { return mbHasGapColor; }
-            short getStyle () const { return mnStyle; }
+            const std::vector< BorderLine >& getBorderLines() const { return maBorderLines; }
+            bool hasGapColor() const { return mbHasGapColor; }
+            editeng::SvxBorderStyle getStyle() const { return mnStyle; }
             double getPatternScale() const { return mfPatternScale; }
 
             /// helper to decide if AntiAliasing should be used
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index 1a00968f3862..ad8f67d29d28 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -510,9 +510,7 @@ void CreateBorderPrimitives(
     const DiagStyle& /*rRFromBL*/,
     const Color* pForceColor)
 {
-    static bool bCheckNewStuff(true);
-
-    if (bCheckNewStuff && rBorder.Prim())
+    if (rBorder.Prim())
     {
         double mfExtendLeftStart(0.0);
         double mfExtendLeftEnd(0.0);
@@ -523,6 +521,30 @@ void CreateBorderPrimitives(
         const basegfx::B2DVector aPerpendX(basegfx::getNormalizedPerpendicular(rX));
         const double fLength(rX.getLength());
 
+        // do not forget RefMode offset, primitive will assume RefMode::Centered
+        basegfx::B2DVector aRefModeOffset;
+
+        if (REFMODE_CENTERED != rBorder.GetRefMode())
+        {
+            const basegfx::B2DVector aPerpendX(basegfx::getNormalizedPerpendicular(rX));
+            const double fHalfWidth(rBorder.GetWidth() * 0.5);
+
+            if (REFMODE_BEGIN == rBorder.GetRefMode())
+            {
+                // move aligned below vector
+                aRefModeOffset = aPerpendX * fHalfWidth;
+            }
+            else if (REFMODE_END == rBorder.GetRefMode())
+            {
+                // move aligned above vector
+                aRefModeOffset = aPerpendX * -fHalfWidth;
+            }
+        }
+
+        // create start/end for RefMode::Centered
+        const basegfx::B2DPoint aStart(rOrigin + aRefModeOffset);
+        const basegfx::B2DPoint aEnd(aStart + rX);
+
         if (2 == myOffsets.size())
         {
             std::vector< std::vector< double >> myCutsS(myOffsets.size());
@@ -537,6 +559,18 @@ void CreateBorderPrimitives(
             std::vector< double > nMinCutsE(getMinMaxCuts(false, myCutsE));
             mfExtendLeftEnd = ((nMinCutsE[0] + nMinCutsE[1]) * 0.5) * fLength;
 
+            rTarget.push_back(
+                drawinglayer::primitive2d::Primitive2DReference(
+                    new drawinglayer::primitive2d::BorderLinePrimitive2D(
+                        aStart,
+                        aEnd,
+                        drawinglayer::primitive2d::BorderLine(
+                            rBorder.Prim(),
+                            (pForceColor ? *pForceColor : rBorder.GetColorPrim()).getBColor(),
+                            mfExtendLeftStart,
+                            mfExtendLeftEnd),
+                        rBorder.Type(),
+                        rBorder.PatternScale())));
         }
         else if (4 == myOffsets.size())
         {
@@ -615,74 +649,31 @@ void CreateBorderPrimitives(
 
                 mfExtendRightEnd = ((nMinCutsE[0] + nMinCutsE[1]) * 0.5) * fLength;
             }
-        }
 
-        // do not forget RefMode offset, primitive will assume RefMode::Centered
-        basegfx::B2DVector aRefModeOffset;
-
-        if (REFMODE_CENTERED != rBorder.GetRefMode())
-        {
-            const basegfx::B2DVector aPerpendX(basegfx::getNormalizedPerpendicular(rX));
-            const double fHalfWidth(rBorder.GetWidth() * 0.5);
-
-            if (REFMODE_BEGIN == rBorder.GetRefMode())
-            {
-                // move aligned below vector
-                aRefModeOffset = aPerpendX * fHalfWidth;
-            }
-            else if (REFMODE_END == rBorder.GetRefMode())
-            {
-                // move aligned above vector
-                aRefModeOffset = aPerpendX * -fHalfWidth;
-            }
+            rTarget.push_back(
+                drawinglayer::primitive2d::Primitive2DReference(
+                    new drawinglayer::primitive2d::BorderLinePrimitive2D(
+                        aStart,
+                        aEnd,
+                        drawinglayer::primitive2d::BorderLine(
+                            rBorder.Prim(),
+                            (pForceColor ? *pForceColor : rBorder.GetColorPrim()).getBColor(),
+                            mfExtendLeftStart,
+                            mfExtendLeftEnd),
+                        drawinglayer::primitive2d::BorderLine(
+                            rBorder.Dist(),
+                            (pForceColor ? *pForceColor : rBorder.GetColorGap()).getBColor(),
+                            (mfExtendLeftStart + mfExtendRightStart) * 0.5,
+                            (mfExtendLeftEnd + mfExtendRightEnd) * 0.5),
+                        drawinglayer::primitive2d::BorderLine(
+                            rBorder.Secn(),
+                            (pForceColor ? *pForceColor : rBorder.GetColorSecn()).getBColor(),
+                            mfExtendRightStart,
+                            mfExtendRightEnd),
+                        rBorder.UseGapColor(),
+                        rBorder.Type(),
+                        rBorder.PatternScale())));
         }
-
-        // create start/end for RefMode::Centered
-        const basegfx::B2DPoint aStart(rOrigin + aRefModeOffset);
-        const basegfx::B2DPoint aEnd(aStart + rX);
-
-        rTarget.push_back(
-            drawinglayer::primitive2d::Primitive2DReference(
-                new drawinglayer::primitive2d::BorderLinePrimitive2D(
-                    aStart,
-                    aEnd,
-                    rBorder.Prim(),
-                    rBorder.Dist(),
-                    rBorder.Secn(),
-                    mfExtendLeftStart,
-                    mfExtendLeftEnd,
-                    mfExtendRightStart,
-                    mfExtendRightEnd,
-                    (pForceColor ? *pForceColor : rBorder.GetColorSecn()).getBColor(),
-                    (pForceColor ? *pForceColor : rBorder.GetColorPrim()).getBColor(),
-                    (pForceColor ? *pForceColor : rBorder.GetColorGap()).getBColor(),
-                    rBorder.UseGapColor(),
-                    rBorder.Type(),
-                    rBorder.PatternScale())));
-    }
-
-    if (!bCheckNewStuff && (rBorder.Prim() || rBorder.Secn()))
-    {
-        basegfx::B2DPoint aStart(rOrigin);
-        basegfx::B2DPoint aEnd(rOrigin + rX);
-        const long nRotateT = 9000; /// Angle of the top slanted frames in 100th of degree
-        const long nRotateB = 9000; /// Angle of the bottom slanted frames in 100th of degree
-
-        rTarget.push_back(
-            drawinglayer::primitive2d::Primitive2DReference(
-                new drawinglayer::primitive2d::BorderLinePrimitive2D(
-                    aStart, aEnd,
-                    rBorder.Prim(),
-                    rBorder.Dist(),
-                    rBorder.Secn(),
-                    lcl_GetExtent(rBorder, rLFromT, rLFromB, nRotateT, -nRotateB, true, false),                  // top-left, so left for rBorder and right for left outer
-                    lcl_GetExtent(rBorder, rRFromT, rRFromB, 18000 - nRotateT, nRotateB - 18000, true, true),     // top-right
-                    lcl_GetExtent(rBorder, rLFromB, rLFromT, nRotateB, -nRotateT, false, false),                 // bottom-left
-                    lcl_GetExtent(rBorder, rRFromB, rRFromT, 18000 - nRotateB, nRotateT - 18000, false, true),    // bottom-right
-                    (pForceColor ? *pForceColor : rBorder.GetColorSecn()).getBColor(),
-                    (pForceColor ? *pForceColor : rBorder.GetColorPrim()).getBColor(),
-                    (pForceColor ? *pForceColor : rBorder.GetColorGap()).getBColor(),
-                    rBorder.UseGapColor(), rBorder.Type(), rBorder.PatternScale())));
     }
 }
 
@@ -742,45 +733,57 @@ void CreateDiagFrameBorderPrimitives(
     if (rTLBR.Prim())
     {
         // top-left to bottom-right
-        rTarget.push_back(
-            new drawinglayer::primitive2d::BorderLinePrimitive2D(
-                rOrigin,
-                rOrigin + rXAxis + rYAxis,
-                rTLBR.Prim(),
-                rTLBR.Dist(),
-                rTLBR.Secn(),
-                0.0,
-                0.0,
-                0.0,
-                0.0,
-                (pForceColor ? *pForceColor : rTLBR.GetColorSecn()).getBColor(),
-                (pForceColor ? *pForceColor : rTLBR.GetColorPrim()).getBColor(),
-                (pForceColor ? *pForceColor : rTLBR.GetColorGap()).getBColor(),
-                rTLBR.UseGapColor(),
-                rTLBR.Type(),
-                rTLBR.PatternScale()));
+        if (basegfx::fTools::equalZero(rTLBR.Secn()))
+        {
+            rTarget.push_back(
+                new drawinglayer::primitive2d::BorderLinePrimitive2D(
+                    rOrigin,
+                    rOrigin + rXAxis + rYAxis,
+                    drawinglayer::primitive2d::BorderLine(rTLBR.Prim(), (pForceColor ? *pForceColor : rTLBR.GetColorPrim()).getBColor()),
+                    rTLBR.Type(),
+                    rTLBR.PatternScale()));
+        }
+        else
+        {
+            rTarget.push_back(
+                new drawinglayer::primitive2d::BorderLinePrimitive2D(
+                    rOrigin,
+                    rOrigin + rXAxis + rYAxis,
+                    drawinglayer::primitive2d::BorderLine(rTLBR.Prim(), (pForceColor ? *pForceColor : rTLBR.GetColorPrim()).getBColor()),
+                    drawinglayer::primitive2d::BorderLine(rTLBR.Dist(), (pForceColor ? *pForceColor : rTLBR.GetColorGap()).getBColor()),
+                    drawinglayer::primitive2d::BorderLine(rTLBR.Secn(), (pForceColor ? *pForceColor : rTLBR.GetColorSecn()).getBColor()),
+                    rTLBR.UseGapColor(),
+                    rTLBR.Type(),
+                    rTLBR.PatternScale()));
+        }
     }
 
     if (rBLTR.Prim())
     {
         // bottom-left to top-right
-        rTarget.push_back(
-            new drawinglayer::primitive2d::BorderLinePrimitive2D(
-                rOrigin + rYAxis,
-                rOrigin + rXAxis,
-                rBLTR.Prim(),
-                rBLTR.Dist(),
-                rBLTR.Secn(),
-                0.0,
-                0.0,
-                0.0,
-                0.0,
-                (pForceColor ? *pForceColor : rBLTR.GetColorSecn()).getBColor(),
-                (pForceColor ? *pForceColor : rBLTR.GetColorPrim()).getBColor(),
-                (pForceColor ? *pForceColor : rBLTR.GetColorGap()).getBColor(),
-                rBLTR.UseGapColor(),
-                rBLTR.Type(),
-                rBLTR.PatternScale()));
+        if (basegfx::fTools::equalZero(rTLBR.Secn()))
+        {
+            rTarget.push_back(
+                new drawinglayer::primitive2d::BorderLinePrimitive2D(
+                    rOrigin + rYAxis,
+                    rOrigin + rXAxis,
+                    drawinglayer::primitive2d::BorderLine(rTLBR.Prim(), (pForceColor ? *pForceColor : rTLBR.GetColorPrim()).getBColor()),
+                    rBLTR.Type(),
+                    rBLTR.PatternScale()));
+        }
+        else
+        {
+            rTarget.push_back(
+                new drawinglayer::primitive2d::BorderLinePrimitive2D(
+                    rOrigin + rYAxis,
+                    rOrigin + rXAxis,
+                    drawinglayer::primitive2d::BorderLine(rTLBR.Prim(), (pForceColor ? *pForceColor : rTLBR.GetColorPrim()).getBColor()),
+                    drawinglayer::primitive2d::BorderLine(rTLBR.Dist(), (pForceColor ? *pForceColor : rTLBR.GetColorGap()).getBColor()),
+                    drawinglayer::primitive2d::BorderLine(rTLBR.Secn(), (pForceColor ? *pForceColor : rTLBR.GetColorSecn()).getBColor()),
+                    rBLTR.UseGapColor(),
+                    rBLTR.Type(),
+                    rBLTR.PatternScale()));
+        }
     }
 }
 }
diff --git a/svx/source/table/viewcontactoftableobj.cxx b/svx/source/table/viewcontactoftableobj.cxx
index dd8ad87fdc3c..4793c1f20c85 100644
--- a/svx/source/table/viewcontactoftableobj.cxx
+++ b/svx/source/table/viewcontactoftableobj.cxx
@@ -289,8 +289,7 @@ namespace drawinglayer
 
         Primitive2DContainer SdrBorderlinePrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*aViewInformation*/) const
         {
-            Primitive2DContainer xRetval(4);
-            sal_uInt32 nInsert(0);
+            Primitive2DContainer aContainer;
             const double fTwipsToMM(getInTwips() ? (127.0 / 72.0) : 1.0);
 
             if(!getLeftLine().isEmpty())
@@ -308,24 +307,31 @@ namespace drawinglayer
                 {
                     const double fExtendIS(getExtend(getTopLine(), maTopFromLLine));
                     const double fExtendIE(getExtend(getBottomLine(), maBottomFromLLine));
-                    const double fExtendOS(getExtend(maTopFromLLine, getTopLine()));
-                    const double fExtendOE(getExtend(maBottomFromLLine, getBottomLine()));
-
-                    xRetval[nInsert++] = Primitive2DReference(new BorderLinePrimitive2D(
-                        aStart,
-                        aEnd,
-                        getChangedValue(getLeftLine().GetOutWidth(), getInTwips()),
-                        getChangedValue(getLeftLine().GetDistance(), getInTwips()),
-                        getChangedValue(getLeftLine().GetInWidth(), getInTwips()),
-                        fExtendIS * fTwipsToMM,
-                        fExtendIE * fTwipsToMM,
-                        fExtendOS * fTwipsToMM,
-                        fExtendOE * fTwipsToMM,
-                        getLeftLine().GetColorOut().getBColor(),
-                        getLeftLine().GetColorIn().getBColor(),
-                        getLeftLine().GetColorGap().getBColor(),
-                        getLeftLine().HasGapColor(),
-                        getLeftLine().GetBorderLineStyle()));
+
+                    if (basegfx::fTools::equalZero(getLeftLine().GetInWidth()))
+                    {
+                        aContainer.push_back(
+                            new BorderLinePrimitive2D(
+                                aStart,
+                                aEnd,
+                                BorderLine(getChangedValue(getLeftLine().GetOutWidth(), true/*InTwips*/), getLeftLine().GetColorOut().getBColor(), fExtendIS * fTwipsToMM, fExtendIE * fTwipsToMM),
+                                getLeftLine().GetBorderLineStyle()));
+                    }
+                    else
+                    {
+                        const double fExtendOS(getExtend(maTopFromLLine, getTopLine()));
+                        const double fExtendOE(getExtend(maBottomFromLLine, getBottomLine()));
+
+                        aContainer.push_back(
+                            new BorderLinePrimitive2D(
+                                aStart,
+                                aEnd,
+                                BorderLine(getChangedValue(getLeftLine().GetOutWidth(), true/*InTwips*/), getLeftLine().GetColorOut().getBColor(), fExtendIS * fTwipsToMM, fExtendIE * fTwipsToMM),
+                                BorderLine(getChangedValue(getLeftLine().GetDistance(), true/*InTwips*/), getLeftLine().GetColorGap().getBColor()),
+                                BorderLine(getChangedValue(getLeftLine().GetInWidth(), true/*InTwips*/), getLeftLine().GetColorIn().getBColor(), fExtendOS * fTwipsToMM, fExtendOE * fTwipsToMM),
+                                getLeftLine().HasGapColor(),
+                                getLeftLine().GetBorderLineStyle()));
+                    }
                 }
             }
 
@@ -339,24 +345,31 @@ namespace drawinglayer
                 {
                     const double fExtendIS(getExtend(getLeftLine(), maLeftFromBLine ));
                     const double fExtendIE(getExtend(getRightLine(), maRightFromBLine));
-                    const double fExtendOS(getExtend(maLeftFromBLine, getLeftLine()));
-                    const double fExtendOE(getExtend(maRightFromBLine, getRightLine()));
-
-                    xRetval[nInsert++] = Primitive2DReference(new BorderLinePrimitive2D(
-                        aStart,
-                        aEnd,
-                        getChangedValue(getBottomLine().GetOutWidth(), getInTwips()),
-                        getChangedValue(getBottomLine().GetDistance(), getInTwips()),
-                        getChangedValue(getBottomLine().GetInWidth(), getInTwips()),
-                        fExtendIS * fTwipsToMM,
-                        fExtendIE * fTwipsToMM,
-                        fExtendOS * fTwipsToMM,
-                        fExtendOE * fTwipsToMM,
-                        getBottomLine().GetColorOut(false).getBColor(),
-                        getBottomLine().GetColorIn(false).getBColor(),
-                        getBottomLine().GetColorGap().getBColor(),
-                        getBottomLine().HasGapColor(),
-                        getBottomLine().GetBorderLineStyle()));
+
+                    if (basegfx::fTools::equalZero(getBottomLine().GetInWidth()))
+                    {
+                        aContainer.push_back(
+                            new BorderLinePrimitive2D(
+                                aStart,
+                                aEnd,
+                                BorderLine(getChangedValue(getBottomLine().GetOutWidth(), true/*InTwips*/), getBottomLine().GetColorOut(false).getBColor(), fExtendIS * fTwipsToMM, fExtendIE * fTwipsToMM),
+                                getBottomLine().GetBorderLineStyle()));
+                    }
+                    else
+                    {
+                        const double fExtendOS(getExtend(maLeftFromBLine, getLeftLine()));
+                        const double fExtendOE(getExtend(maRightFromBLine, getRightLine()));
+
+                        aContainer.push_back(
+                            new BorderLinePrimitive2D(
+                                aStart,
+                                aEnd,
+                                BorderLine(getChangedValue(getBottomLine().GetOutWidth(), true/*InTwips*/), getBottomLine().GetColorOut(false).getBColor(), fExtendIS * fTwipsToMM, fExtendIE * fTwipsToMM),
+                                BorderLine(getChangedValue(getBottomLine().GetDistance(), true/*InTwips*/), getBottomLine().GetColorGap().getBColor()),
+                                BorderLine(getChangedValue(getBottomLine().GetInWidth(), true/*InTwips*/), getBottomLine().GetColorIn(false).getBColor(), fExtendOS * fTwipsToMM, fExtendOE * fTwipsToMM),
+                                getBottomLine().HasGapColor(),
+                                getBottomLine().GetBorderLineStyle()));
+                    }
                 }
             }
 
@@ -368,26 +381,33 @@ namespace drawinglayer
 
                 if(!aStart.equal(aEnd))
                 {
-                    const double fExtendIS(getExtend(getTopLine(), maTopFromRLine));
-                    const double fExtendIE(getExtend(getBottomLine(), maBottomFromRLine));
                     const double fExtendOS(getExtend(maTopFromRLine, getTopLine()));
                     const double fExtendOE(getExtend(maBottomFromRLine, getBottomLine()));
 
-                    xRetval[nInsert++] = Primitive2DReference(new BorderLinePrimitive2D(
-                        aStart,
-                        aEnd,
-                        getChangedValue(getRightLine().GetOutWidth(), getInTwips()),
-                        getChangedValue(getRightLine().GetDistance(), getInTwips()),
-                        getChangedValue(getRightLine().GetInWidth(), getInTwips()),
-                        fExtendOS * fTwipsToMM,
-                        fExtendOE * fTwipsToMM,
-                        fExtendIS * fTwipsToMM,
-                        fExtendIE * fTwipsToMM,
-                        getRightLine().GetColorOut().getBColor(),
-                        getRightLine().GetColorIn().getBColor(),
-                        getRightLine().GetColorGap().getBColor(),
-                        getRightLine().HasGapColor(),
-                        getRightLine().GetBorderLineStyle()));
+                    if (basegfx::fTools::equalZero(getRightLine().GetInWidth()))
+                    {
+                        aContainer.push_back(
+                            new BorderLinePrimitive2D(
+                                aStart,
+                                aEnd,
+                                BorderLine(getChangedValue(getRightLine().GetOutWidth(), true/*InTwips*/), getRightLine().GetColorOut().getBColor(), fExtendOS * fTwipsToMM, fExtendOE * fTwipsToMM),
+                                getRightLine().GetBorderLineStyle()));
+                    }
+                    else
+                    {
+                        const double fExtendIS(getExtend(getTopLine(), maTopFromRLine));
+                        const double fExtendIE(getExtend(getBottomLine(), maBottomFromRLine));
+
+                        aContainer.push_back(
+                            new BorderLinePrimitive2D(
+                                aStart,
+                                aEnd,
+                                BorderLine(getChangedValue(getRightLine().GetOutWidth(), true/*InTwips*/), getRightLine().GetColorOut().getBColor(), fExtendOS * fTwipsToMM, fExtendOE * fTwipsToMM),
+                                BorderLine(getChangedValue(getRightLine().GetDistance(), true/*InTwips*/), getRightLine().GetColorGap().getBColor()),
+                                BorderLine(getChangedValue(getRightLine().GetInWidth(), true/*InTwips*/), getRightLine().GetColorIn().getBColor(), fExtendIS * fTwipsToMM, fExtendIE * fTwipsToMM),
+                                getRightLine().HasGapColor(),
+                                getRightLine().GetBorderLineStyle()));
+                    }
                 }
             }
 
@@ -404,31 +424,37 @@ namespace drawinglayer
 
                 if(!aStart.equal(aEnd))
                 {
-                    const double fExtendIS(getExtend(getLeftLine(), maLeftFromTLine));
-                    const double fExtendIE(getExtend(getRightLine(), maRightFromTLine));
                     const double fExtendOS(getExtend(maLeftFromTLine, getLeftLine()));
                     const double fExtendOE(getExtend(maRightFromTLine, getRightLine()));
 
-                    xRetval[nInsert++] = Primitive2DReference(new BorderLinePrimitive2D(
-                        aStart,
-                        aEnd,
-                        getChangedValue(getTopLine().GetOutWidth(), getInTwips()),
-                        getChangedValue(getTopLine().GetDistance(), getInTwips()),
-                        getChangedValue(getTopLine().GetInWidth(), getInTwips()),
-                        fExtendOS * fTwipsToMM,
-                        fExtendOE * fTwipsToMM,
-                        fExtendIS * fTwipsToMM,
-                        fExtendIE * fTwipsToMM,
-                        getTopLine().GetColorOut(false).getBColor(),
-                        getTopLine().GetColorIn(false).getBColor(),
-                        getTopLine().GetColorGap().getBColor(),
-                        getTopLine().HasGapColor(),
-                        getTopLine().GetBorderLineStyle()));
+                    if (basegfx::fTools::equalZero(getTopLine().GetInWidth()))
+                    {
+                        aContainer.push_back(
+                            new BorderLinePrimitive2D(
+                                aStart,
+                                aEnd,
+                                BorderLine(getChangedValue(getTopLine().GetOutWidth(), true/*InTwips*/), getTopLine().GetColorOut(false).getBColor(), fExtendOS * fTwipsToMM, fExtendOE * fTwipsToMM),
+                                getTopLine().GetBorderLineStyle()));
+                    }
+                    else
+                    {
+                        const double fExtendIS(getExtend(getLeftLine(), maLeftFromTLine));
+                        const double fExtendIE(getExtend(getRightLine(), maRightFromTLine));
+
+                        aContainer.push_back(
+                            new BorderLinePrimitive2D(
+                                aStart,
+                                aEnd,
+                                BorderLine(getChangedValue(getTopLine().GetOutWidth(), true/*InTwips*/), getTopLine().GetColorOut(false).getBColor(), fExtendOS * fTwipsToMM, fExtendOE * fTwipsToMM),
+                                BorderLine(getChangedValue(getTopLine().GetDistance(), true/*InTwips*/), getTopLine().GetColorGap().getBColor()),

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list