[Libreoffice-commits] core.git: Branch 'feature/borderline3' - drawinglayer/source include/drawinglayer include/svx svx/source sw/source

Armin Le Grand Armin.Le.Grand at cib.de
Tue Sep 12 15:31:18 UTC 2017


 drawinglayer/source/primitive2d/borderlineprimitive2d.cxx  |  112 ++++++
 include/drawinglayer/primitive2d/borderlineprimitive2d.hxx |    7 
 include/svx/framelink.hxx                                  |   59 ---
 svx/source/dialog/framelink.cxx                            |   88 ++--
 svx/source/dialog/framelinkarray.cxx                       |  114 ++++--
 svx/source/table/viewcontactoftableobj.cxx                 |   22 -
 sw/source/core/layout/paintfrm.cxx                         |  235 +------------
 7 files changed, 292 insertions(+), 345 deletions(-)

New commits:
commit 1679a909e383c689cc4af9b699baf0d5a165c281
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Tue Sep 12 17:28:54 2017 +0200

    borderline: merge redefined, mirrored Styles
    
    Redefined merge of BorderlinePrimitives, removed old Writer
    stuff for it. Also added support for handling Styles mirrored
    for extension calculations
    
    Change-Id: Icee5540573c294d3e6c1b98c55e6dda67a82cc16

diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index 9421ed8b249b..5fc3b57fbbda 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -144,7 +144,7 @@ namespace drawinglayer
 
                 for(const auto& candidate : maBorderLines)
                 {
-                    const double fWidth(candidate.getAdaptedWidth(mfSmallestAllowedDiscreteGapDistance) * 0.5);
+                    const double fWidth(candidate.getAdaptedWidth(mfSmallestAllowedDiscreteGapDistance));
 
                     if(!candidate.isGap())
                     {
@@ -369,6 +369,116 @@ namespace drawinglayer
         // provide unique ID
         ImplPrimitive2DIDBlock(BorderLinePrimitive2D, PRIMITIVE2D_ID_BORDERLINEPRIMITIVE2D)
 
+        Primitive2DReference tryMergeBorderLinePrimitive2D(
+            const Primitive2DReference& rCandidateA,
+            const Primitive2DReference& rCandidateB)
+        {
+            // try to cast to BorderLinePrimitive2D
+            const primitive2d::BorderLinePrimitive2D* pCandidateA = dynamic_cast< const primitive2d::BorderLinePrimitive2D* >(rCandidateA.get());
+            const primitive2d::BorderLinePrimitive2D* pCandidateB = dynamic_cast< const primitive2d::BorderLinePrimitive2D* >(rCandidateB.get());
+
+            // we need a comparable BorderLinePrimitive2D
+            if(nullptr == pCandidateA || nullptr == pCandidateB)
+            {
+                return Primitive2DReference();
+            }
+
+            // start of candidate has to match end of this
+            if(!pCandidateA->getEnd().equal(pCandidateB->getStart()))
+            {
+                return Primitive2DReference();
+            }
+
+            // candidate A needs a length
+            if(pCandidateA->getStart().equal(pCandidateA->getEnd()))
+            {
+                return Primitive2DReference();
+            }
+
+            // candidate B needs a length
+            if(pCandidateB->getStart().equal(pCandidateB->getEnd()))
+            {
+                return Primitive2DReference();
+            }
+
+            // StrokeAttribute has to be equal
+            if(!(pCandidateA->getStrokeAttribute() == pCandidateB->getStrokeAttribute()))
+            {
+                return Primitive2DReference();
+            }
+
+            // direction has to be equal -> cross product == 0.0
+            const basegfx::B2DVector aVT(pCandidateA->getEnd() - pCandidateA->getStart());
+            const basegfx::B2DVector aVC(pCandidateB->getEnd() - pCandidateB->getStart());
+            if(!rtl::math::approxEqual(0.0, aVC.cross(aVT)))
+            {
+                return Primitive2DReference();
+            }
+
+            // number BorderLines has to be equal
+            const size_t count(pCandidateA->getBorderLines().size());
+            if(count != pCandidateB->getBorderLines().size())
+            {
+                return Primitive2DReference();
+            }
+
+            for(size_t a(0); a < count; a++)
+            {
+                const BorderLine& rBT(pCandidateA->getBorderLines()[a]);
+                const BorderLine& rBC(pCandidateB->getBorderLines()[a]);
+
+                // LineAttribute has to be the same
+                if(!(rBC.getLineAttribute() == rBT.getLineAttribute()))
+                {
+                    return Primitive2DReference();
+                }
+
+                // isGap has to be the same
+                if(rBC.isGap() != rBT.isGap())
+                {
+                    return Primitive2DReference();
+                }
+
+                if(!rBT.isGap())
+                {
+                    // when not gap, the line extends have at least reach to the center ( > 0.0),
+                    // else there is a extend usage. When > 0.0 they just overlap, no problem
+                    if(rBT.getEndLeft() >= 0.0
+                        && rBT.getEndRight() >= 0.0
+                        && rBC.getStartLeft() >= 0.0
+                        && rBC.getStartRight() >= 0.0)
+                    {
+                        // okay
+                    }
+                    else
+                    {
+                        return Primitive2DReference();
+                    }
+                }
+            }
+
+            // all conditions met, create merged primitive
+            std::vector< BorderLine > aMergedBorderLines;
+
+            for(size_t a(0); a < count; a++)
+            {
+                const BorderLine& rBT(pCandidateA->getBorderLines()[a]);
+                const BorderLine& rBC(pCandidateB->getBorderLines()[a]);
+
+                aMergedBorderLines.push_back(
+                    BorderLine(
+                        rBT.getLineAttribute(),
+                        rBT.getStartLeft(), rBT.getStartRight(),
+                        rBC.getEndLeft(), rBC.getEndRight()));
+            }
+
+            return Primitive2DReference(
+                new BorderLinePrimitive2D(
+                    pCandidateA->getStart(),
+                    pCandidateB->getEnd(),
+                    aMergedBorderLines,
+                    pCandidateA->getStrokeAttribute()));
+        }
     } // end of namespace primitive2d
 } // end of namespace drawinglayer
 
diff --git a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
index 992347c7dc9b..b6634f6ce64e 100644
--- a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
@@ -87,6 +87,13 @@ namespace drawinglayer
             bool operator==(const BorderLine& rBorderLine) const;
         };
 
+        /// helper to try to merge two instances of BorderLinePrimitive2D. If it was possible,
+        /// a merged version is in the returned Primitive2DReference. Lots of preconditions
+        /// have to be met to allow that, see implementation (and maybe even expand)
+        Primitive2DReference DRAWINGLAYER_DLLPUBLIC tryMergeBorderLinePrimitive2D(
+            const Primitive2DReference& rCandidateA,
+            const Primitive2DReference& rCandidateB);
+
         /** BorderLinePrimitive2D class
 
         This is the basic primitive to build frames around objects, e.g. tables.
diff --git a/include/svx/framelink.hxx b/include/svx/framelink.hxx
index 9ebb4c85e5aa..1b130efa7f2f 100644
--- a/include/svx/framelink.hxx
+++ b/include/svx/framelink.hxx
@@ -213,66 +213,27 @@ public:
 
 inline bool operator>( const Style& rL, const Style& rR ) { return rR.operator<(rL); }
 
-// Various helper functions
-
-/** Checks whether two horizontal frame borders are "connectable".
-
-    Two borders are "connectable" in terms of this function, if both can be
-    drawn with only one call of a border drawing function. This means, the two
-    frame borders must have equal style and color, and none of the other
-    vertical and diagonal frame borders break the lines of the two borders in
-    any way (i.e. two vertical double frame borders would break the horizonal
-    frame borders). Of course this function can be used for vertical frame
-    borders as well.
-
-    The following picture shows the meaning of all passed parameters:
-
-                      \      rTFromT      /
-                        \       |       /
-                   rTFromTL     |   rTFromTR
-                            \   |   /
-                              \ | /
-    ======== rLBorder =========   ========== rRBorder =======
-                              / | \
-                            /   |   \
-                   rBFromBL     |   rBFromBR
-                        /       |       \
-                      /      rBFromB      \
-
-    @return
-        True, if rLBorder and rRBorder can be drawn in one step without
-        interruption at their connection point.
- */
-SVX_DLLPUBLIC bool CheckFrameBorderConnectable(
-    const Style&        rLBorder,       /// Style of the left frame border to connect.
-    const Style&        rRBorder,       /// Style of the right frame border to connect.
-
-    const Style&        rTFromTL,       /// Diagonal frame border from top-left to connection point.
-    const Style&        rTFromT,        /// Vertical frame border from top to connection point.
-    const Style&        rTFromTR,       /// Horizontal frame border from top-right to connection point.
-
-    const Style&        rBFromBL,       /// Diagonal frame border from bottom-left to connection point.
-    const Style&        rBFromB,        /// Vertical frame border from bottom to connection point.
-    const Style&        rBFromBR        /// Horizontal frame border from bottom-right to connection point.
-);
-
-
 // Drawing functions
 
 class SAL_WARN_UNUSED SVX_DLLPUBLIC StyleVectorCombination
 {
 private:
     const Style&                mrStyle;
-    const basegfx::B2DVector&   mrB2DVector;
+    const basegfx::B2DVector    maB2DVector;
+    const bool                  mbMirrored;
+
 
 public:
-    StyleVectorCombination(const Style& rStyle, const basegfx::B2DVector& rB2DVector) :
+    StyleVectorCombination(const Style& rStyle, const basegfx::B2DVector& rB2DVector, bool bMirrored) :
         mrStyle(rStyle),
-        mrB2DVector(rB2DVector)
-    {}
+        maB2DVector(rB2DVector),
+        mbMirrored(bMirrored)
+    {
+    }
 
     const Style& getStyle() const { return mrStyle; }
-    const basegfx::B2DVector& getB2DVector() const { return mrB2DVector; }
+    const basegfx::B2DVector& getB2DVector() const { return maB2DVector; }
+    bool isMirrored() const { return mbMirrored; }
 };
 
 typedef std::vector< StyleVectorCombination > StyleVectorTable;
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index ca66b285f8d4..ce7168040228 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -334,29 +334,6 @@ bool Style::operator<( const Style& rOther) const
     return false;
 }
 
-bool CheckFrameBorderConnectable( const Style& rLBorder, const Style& rRBorder,
-        const Style& rTFromTL, const Style& rTFromT, const Style& rTFromTR,
-        const Style& rBFromBL, const Style& rBFromB, const Style& rBFromBR )
-{
-    return      // returns 1 AND (2a OR 2b)
-        // 1) only, if both frame borders are equal
-        (rLBorder == rRBorder)
-        &&
-        (
-            (
-                // 2a) if the borders are not double, at least one of the vertical must not be double
-                !rLBorder.Secn() && (!rTFromT.Secn() || !rBFromB.Secn())
-            )
-            ||
-            (
-                // 2b) if the borders are double, all other borders must not be double
-                rLBorder.Secn() &&
-                !rTFromTL.Secn() && !rTFromT.Secn() && !rTFromTR.Secn() &&
-                !rBFromBL.Secn() && !rBFromB.Secn() && !rBFromBR.Secn()
-            )
-        );
-}
-
 // Drawing functions
 struct OffsetAndHalfWidthAndColor
 {
@@ -387,48 +364,70 @@ struct ExtendSet
     ExtendSet() : mfExtLeft(0.0), mfExtRight(0.0) {}
 };
 
-void getOffsetAndHalfWidthAndColorFromStyle(const Style& rStyle, const Color* pForceColor, std::vector< OffsetAndHalfWidthAndColor >& offsets)
+double getOffsetAndHalfWidthAndColorFromStyle(
+    const Style& rStyle,
+    const Color* pForceColor,
+    bool bMirrored,
+    std::vector< OffsetAndHalfWidthAndColor >& offsets)
 {
+    // do not forget RefMode offset, primitive is free of it
+    double fRefModeOffset(0.0);
+
     if (rStyle.IsUsed())
     {
-        // do not forget RefMode offset, primitive is free of it
-        double fRefModeOffset(0.0);
+        RefMode aRefMode(rStyle.GetRefMode());
+        Color aPrim(rStyle.GetColorPrim());
+        Color aSecn(rStyle.GetColorSecn());
+        double fPrim(rStyle.Prim());
+        double fSecn(rStyle.Secn());
+
+        if(bMirrored)
+        {
+            switch(aRefMode)
+            {
+                case RefMode::Begin: aRefMode = RefMode::End; break;
+                case RefMode::End: aRefMode = RefMode::Begin; break;
+                default: break;
+            }
+            std::swap(aPrim, aSecn);
+            std::swap(fPrim, fSecn);
+        }
 
-        if (RefMode::Centered != rStyle.GetRefMode())
+        if (RefMode::Centered != aRefMode)
         {
             const double fHalfWidth(rStyle.GetWidth() * 0.5);
 
-            if (RefMode::Begin == rStyle.GetRefMode())
+            if (RefMode::Begin == aRefMode)
             {
                 // move aligned below vector
                 fRefModeOffset = fHalfWidth;
             }
-            else if (RefMode::End == rStyle.GetRefMode())
+            else if (RefMode::End == aRefMode)
             {
                 // move aligned above vector
                 fRefModeOffset = -fHalfWidth;
             }
         }
 
-        if (rStyle.Dist() && rStyle.Secn())
+        if (rStyle.Dist() && fSecn)
         {
             // both or all three lines used
             const bool bPrimTransparent(0xff == rStyle.GetColorPrim().GetTransparency());
             const bool bDistTransparent(!rStyle.UseGapColor() || 0xff == rStyle.GetColorGap().GetTransparency());
-            const bool bSecnTransparent(0xff == rStyle.GetColorSecn().GetTransparency());
+            const bool bSecnTransparent(0xff == aSecn.GetTransparency());
 
             if(!bPrimTransparent || !bDistTransparent || !bSecnTransparent)
             {
                 const double a(fRefModeOffset - (rStyle.GetWidth() * 0.5));
-                const double b(a + rStyle.Prim());
+                const double b(a + fPrim);
                 const double c(b + rStyle.Dist());
-                const double d(c + rStyle.Secn());
+                const double d(c + fSecn);
 
                 offsets.push_back(
                     OffsetAndHalfWidthAndColor(
                         (a + b) * 0.5,
-                        rStyle.Prim() * 0.5,
-                        nullptr != pForceColor ? *pForceColor : rStyle.GetColorPrim()));
+                        fPrim * 0.5,
+                        nullptr != pForceColor ? *pForceColor : aPrim));
 
                 offsets.push_back(
                     OffsetAndHalfWidthAndColor(
@@ -441,8 +440,8 @@ void getOffsetAndHalfWidthAndColorFromStyle(const Style& rStyle, const Color* pF
                 offsets.push_back(
                     OffsetAndHalfWidthAndColor(
                         (c + d) * 0.5,
-                        rStyle.Secn() * 0.5,
-                        nullptr != pForceColor ? *pForceColor : rStyle.GetColorSecn()));
+                        fSecn * 0.5,
+                        nullptr != pForceColor ? *pForceColor : aSecn));
             }
         }
         else
@@ -453,11 +452,13 @@ void getOffsetAndHalfWidthAndColorFromStyle(const Style& rStyle, const Color* pF
                 offsets.push_back(
                     OffsetAndHalfWidthAndColor(
                         fRefModeOffset,
-                        rStyle.Prim() * 0.5,
-                        nullptr != pForceColor ? *pForceColor : rStyle.GetColorPrim()));
+                        fPrim * 0.5,
+                        nullptr != pForceColor ? *pForceColor : aPrim));
             }
         }
     }
+
+    return fRefModeOffset;
 }
 
 void getCutSet(
@@ -525,7 +526,7 @@ void getExtends(
             for(const auto& rStyleVectorCombination : rStyleVectorTable)
             {
                 std::vector< OffsetAndHalfWidthAndColor > otherOffsets;
-                getOffsetAndHalfWidthAndColorFromStyle(rStyleVectorCombination.getStyle(), nullptr, otherOffsets);
+                getOffsetAndHalfWidthAndColorFromStyle(rStyleVectorCombination.getStyle(), nullptr, rStyleVectorCombination.isMirrored(), otherOffsets);
 
                 if(!otherOffsets.empty())
                 {
@@ -568,7 +569,7 @@ void CreateBorderPrimitives(
 {
     // get offset color pairs for  style, one per visible line
     std::vector< OffsetAndHalfWidthAndColor > myOffsets;
-    getOffsetAndHalfWidthAndColorFromStyle(rBorder, pForceColor, myOffsets);
+    const double fRefModeOffset(getOffsetAndHalfWidthAndColorFromStyle(rBorder, pForceColor, false, myOffsets));
     const size_t nOffsets(myOffsets.size());
 
     if(nOffsets)
@@ -624,12 +625,13 @@ void CreateBorderPrimitives(
         static double fPatScFact(10.0); // 10.0 multiply, see old code
         const std::vector<double> aDashing(svtools::GetLineDashing(rBorder.Type(), rBorder.PatternScale() * fPatScFact));
         const drawinglayer::attribute::StrokeAttribute aStrokeAttribute(aDashing);
+        const basegfx::B2DPoint aStart(rOrigin + (aPerpendX * fRefModeOffset));
 
         rTarget.append(
             drawinglayer::primitive2d::Primitive2DReference(
                 new drawinglayer::primitive2d::BorderLinePrimitive2D(
-                    rOrigin,
-                    rOrigin + rX,
+                    aStart,
+                    aStart + rX,
                     aBorderlines,
                     aStrokeAttribute)));
     }
diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx
index 6052c23f3e8a..2d81caebd3a7 100644
--- a/svx/source/dialog/framelinkarray.cxx
+++ b/svx/source/dialog/framelinkarray.cxx
@@ -954,11 +954,11 @@ void HelperCreateHorizontalEntry(
     const Style& rStartFromBR(rArray.GetCellStyleTL( col, row ));
     StyleVectorTable aStart;
 
-    if(rStartFromTR.IsUsed()) aStart.push_back(StyleVectorCombination(rStartFromTR, rX - rY));
-    if(rStartLFromT.IsUsed()) aStart.push_back(StyleVectorCombination(rStartLFromT, -rY));
-    if(rStartLFromL.IsUsed()) aStart.push_back(StyleVectorCombination(rStartLFromL, -rX));
-    if(rStartLFromB.IsUsed()) aStart.push_back(StyleVectorCombination(rStartLFromB, rY));
-    if(rStartFromBR.IsUsed()) aStart.push_back(StyleVectorCombination(rStartFromBR, rX + rY));
+    if(rStartFromTR.IsUsed()) aStart.push_back(StyleVectorCombination(rStartFromTR, rX - rY, false));
+    if(rStartLFromT.IsUsed()) aStart.push_back(StyleVectorCombination(rStartLFromT, -rY, true));
+    if(rStartLFromL.IsUsed()) aStart.push_back(StyleVectorCombination(rStartLFromL, -rX, true));
+    if(rStartLFromB.IsUsed()) aStart.push_back(StyleVectorCombination(rStartLFromB, rY, false));
+    if(rStartFromBR.IsUsed()) aStart.push_back(StyleVectorCombination(rStartFromBR, rX + rY, false));
 
     // get involved styles at end
     const Style& rEndFromTL(rArray.GetCellStyleBR( col, row - 1 ));
@@ -968,11 +968,11 @@ void HelperCreateHorizontalEntry(
     const Style& rEndFromBL(rArray.GetCellStyleTR( col, row ));
     StyleVectorTable aEnd;
 
-    if(rEndFromTL.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndFromTL, -rX -rY));
-    if(rEndRFromT.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndRFromT, -rY));
-    if(rEndRFromR.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndRFromR, rX));
-    if(rEndRFromB.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndRFromB, rY));
-    if(rEndFromBL.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndFromBL, rY - rX));
+    if(rEndFromTL.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndFromTL, -rX -rY, true));
+    if(rEndRFromT.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndRFromT, -rY, true));
+    if(rEndRFromR.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndRFromR, rX, false));
+    if(rEndRFromB.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndRFromB, rY, false));
+    if(rEndFromBL.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndFromBL, rY - rX, true));
 
     CreateBorderPrimitives(
         rSequence,
@@ -999,11 +999,11 @@ void HelperCreateVerticalEntry(
     const Style& rStartFromBR(rArray.GetCellStyleTL( col, row ));
     StyleVectorTable aStart;
 
-    if(rStartFromBR.IsUsed()) aStart.push_back(StyleVectorCombination(rStartFromBR, rX + rY));
-    if(rStartTFromR.IsUsed()) aStart.push_back(StyleVectorCombination(rStartTFromR, rX));
-    if(rStartTFromT.IsUsed()) aStart.push_back(StyleVectorCombination(rStartTFromT, rY));
-    if(rStartTFromL.IsUsed()) aStart.push_back(StyleVectorCombination(rStartTFromL, -rX));
-    if(rStartFromBL.IsUsed()) aStart.push_back(StyleVectorCombination(rStartFromBL, rY - rX));
+    if(rStartFromBR.IsUsed()) aStart.push_back(StyleVectorCombination(rStartFromBR, rX + rY, false));
+    if(rStartTFromR.IsUsed()) aStart.push_back(StyleVectorCombination(rStartTFromR, rX, false));
+    if(rStartTFromT.IsUsed()) aStart.push_back(StyleVectorCombination(rStartTFromT, rY, true));
+    if(rStartTFromL.IsUsed()) aStart.push_back(StyleVectorCombination(rStartTFromL, -rX, true));
+    if(rStartFromBL.IsUsed()) aStart.push_back(StyleVectorCombination(rStartFromBL, rY - rX, true));
 
     // get involved styles at end
     const Style& rEndFromTL(rArray.GetCellStyleBR( col - 1, row ));
@@ -1013,11 +1013,11 @@ void HelperCreateVerticalEntry(
     const Style& rEndFromTR(rArray.GetCellStyleBL( col, row ));
     StyleVectorTable aEnd;
 
-    if(rEndFromTR.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndFromTR, rX - rY));
-    if(rEndBFromR.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndBFromR, rX));
-    if(rEndBFromB.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndBFromB, -rY));
-    if(rEndBFromL.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndBFromL, rX));
-    if(rEndFromTL.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndFromTL, rX + rY));
+    if(rEndFromTR.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndFromTR, rX - rY, false));
+    if(rEndBFromR.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndBFromR, rX, false));
+    if(rEndBFromB.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndBFromB, -rY, false));
+    if(rEndBFromL.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndBFromL, rX, true));
+    if(rEndFromTL.IsUsed()) aEnd.push_back(StyleVectorCombination(rEndFromTL, rX + rY, true));
 
     CreateBorderPrimitives(
         rSequence,
@@ -1069,6 +1069,48 @@ void HelperCreateEntry(const Array& rArray, const Style& rStyle, drawinglayer::p
     }
 }
 
+void HelperMergeInB2DPrimitiveArray(
+    const drawinglayer::primitive2d::Primitive2DContainer& rSource,
+    drawinglayer::primitive2d::Primitive2DContainer& rTarget)
+{
+    if(rSource.size() > 1)
+    {
+        drawinglayer::primitive2d::Primitive2DReference aCandidate;
+
+        for(const auto& a : rSource)
+        {
+            if(aCandidate.is())
+            {
+                const drawinglayer::primitive2d::Primitive2DReference aMerge(
+                    drawinglayer::primitive2d::tryMergeBorderLinePrimitive2D(aCandidate, a));
+
+                if(aMerge.is())
+                {
+                    aCandidate = aMerge;
+                }
+                else
+                {
+                    rTarget.append(aCandidate);
+                    aCandidate = a;
+                }
+            }
+            else
+            {
+                aCandidate = a;
+            }
+        }
+
+        if(aCandidate.is())
+        {
+            rTarget.append(aCandidate);
+        }
+    }
+    else
+    {
+        rTarget.append(rSource);
+    }
+}
+
 drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
     size_t nFirstCol, size_t nFirstRow, size_t nLastCol, size_t nLastRow,
     const Color* pForceColor ) const
@@ -1078,7 +1120,7 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
 
     // various primitive sequences to collect the different border types
     drawinglayer::primitive2d::Primitive2DContainer aHorizontalSequence;
-    drawinglayer::primitive2d::Primitive2DContainer aVerticalSequence;
+    std::vector< drawinglayer::primitive2d::Primitive2DContainer > aVerticalSequences(nLastCol - nFirstCol + 1);
     drawinglayer::primitive2d::Primitive2DContainer aCrossSequence;
 
     for (size_t nRow = nFirstRow; nRow <= nLastRow; ++nRow)
@@ -1131,7 +1173,7 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
 
                     if(rLeft.IsUsed())
                     {
-                        HelperCreateEntry(*this, rLeft, aVerticalSequence, pForceColor);
+                        HelperCreateEntry(*this, rLeft, aVerticalSequences[nCol - nFirstCol], pForceColor);
                     }
                 }
 
@@ -1141,7 +1183,7 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
 
                     if(rRight.IsUsed())
                     {
-                        HelperCreateEntry(*this, rRight, aVerticalSequence, pForceColor);
+                        HelperCreateEntry(*this, rRight, aVerticalSequences[nCol - nFirstCol], pForceColor);
                     }
                 }
 
@@ -1156,15 +1198,15 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
 
                         /// Fill top-left Style Table
                         const Style& rTLFromRight(GetCellStyleTop(_nFirstCol, _nFirstRow));
-                        if(rTLFromRight.IsUsed()) aStart.push_back(StyleVectorCombination(rTLFromRight, aX));
+                        if(rTLFromRight.IsUsed()) aStart.push_back(StyleVectorCombination(rTLFromRight, aX, false));
                         const Style& rTLFromBottom(GetCellStyleLeft(_nFirstCol, _nFirstRow));
-                        if(rTLFromBottom.IsUsed()) aStart.push_back(StyleVectorCombination(rTLFromBottom, aY));
+                        if(rTLFromBottom.IsUsed()) aStart.push_back(StyleVectorCombination(rTLFromBottom, aY, false));
 
                         /// Fill bottom-right Style Table
                         const Style& rBRFromBottom(GetCellStyleRight(_nLastCol, _nLastRow));
-                        if(rBRFromBottom.IsUsed()) aEnd.push_back(StyleVectorCombination(rBRFromBottom, -aY));
+                        if(rBRFromBottom.IsUsed()) aEnd.push_back(StyleVectorCombination(rBRFromBottom, -aY, true));
                         const Style& rBRFromLeft(GetCellStyleBottom(_nLastCol, _nLastRow));
-                        if(rBRFromLeft.IsUsed()) aEnd.push_back(StyleVectorCombination(rBRFromLeft, -aX));
+                        if(rBRFromLeft.IsUsed()) aEnd.push_back(StyleVectorCombination(rBRFromLeft, -aX, true));
 
                         CreateBorderPrimitives(
                             aCrossSequence,
@@ -1186,15 +1228,15 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
 
                         /// Fill bottom-left Style Table
                         const Style& rBLFromTop(GetCellStyleLeft(_nFirstCol, _nLastRow));
-                        if(rBLFromTop.IsUsed()) aStart.push_back(StyleVectorCombination(rBLFromTop, -aY));
+                        if(rBLFromTop.IsUsed()) aStart.push_back(StyleVectorCombination(rBLFromTop, -aY, true));
                         const Style& rBLFromBottom(GetCellStyleBottom(_nFirstCol, _nLastRow));
-                        if(rBLFromBottom.IsUsed()) aStart.push_back(StyleVectorCombination(rBLFromBottom, aX));
+                        if(rBLFromBottom.IsUsed()) aStart.push_back(StyleVectorCombination(rBLFromBottom, aX, false));
 
                         /// Fill top-right Style Table
                         const Style& rTRFromBottom(GetCellStyleRight(_nLastCol, _nFirstRow));
-                        if(rTRFromBottom.IsUsed()) aEnd.push_back(StyleVectorCombination(rTRFromBottom, -aY));
+                        if(rTRFromBottom.IsUsed()) aEnd.push_back(StyleVectorCombination(rTRFromBottom, -aY, true));
                         const Style& rTRFromLeft(GetCellStyleTop(_nLastCol, _nFirstRow));
-                        if(rTRFromLeft.IsUsed()) aEnd.push_back(StyleVectorCombination(rTRFromLeft, -aX));
+                        if(rTRFromLeft.IsUsed()) aEnd.push_back(StyleVectorCombination(rTRFromLeft, -aX, false));
 
                         CreateBorderPrimitives(
                             aCrossSequence,
@@ -1211,9 +1253,13 @@ drawinglayer::primitive2d::Primitive2DContainer Array::CreateB2DPrimitiveRange(
         }
     }
 
-    // to stay compatible, create order as it was formally
-    aCrossSequence.append(aHorizontalSequence);
-    aCrossSequence.append(aVerticalSequence);
+    // to stay compatible, create order as it was formally. Also try to
+    // merge primitives as far as possible
+    HelperMergeInB2DPrimitiveArray(aHorizontalSequence, aCrossSequence);
+    for(const auto& aVert : aVerticalSequences)
+    {
+        HelperMergeInB2DPrimitiveArray(aVert, aCrossSequence);
+    }
 
     return aCrossSequence;
 }
diff --git a/svx/source/table/viewcontactoftableobj.cxx b/svx/source/table/viewcontactoftableobj.cxx
index d696569dc329..87f44432713e 100644
--- a/svx/source/table/viewcontactoftableobj.cxx
+++ b/svx/source/table/viewcontactoftableobj.cxx
@@ -197,7 +197,7 @@ namespace sdr
             return svx::frame::Style();
         }
 
-        void createForVector(drawinglayer::primitive2d::Primitive2DContainer& rContainer, const basegfx::B2DPoint& rOrigin, const basegfx::B2DVector& rX,
+        void createForVector(bool bHor, drawinglayer::primitive2d::Primitive2DContainer& rContainer, const basegfx::B2DPoint& rOrigin, const basegfx::B2DVector& rX,
             const svx::frame::Style& rLine,
             const svx::frame::Style& rLeftA, const svx::frame::Style& rLeftB, const svx::frame::Style& rLeftC,
             const svx::frame::Style& rRightA, const svx::frame::Style& rRightB, const svx::frame::Style& rRightC)
@@ -209,14 +209,14 @@ namespace sdr
             const double fTwipsToMM(127.0 / 72.0);
 
             /// Fill top-left Style Table
-            if(rLeftA.IsUsed()) aStart.push_back(svx::frame::StyleVectorCombination(rLeftA, -aY));
-            if(rLeftB.IsUsed()) aStart.push_back(svx::frame::StyleVectorCombination(rLeftB, -rX));
-            if(rLeftC.IsUsed()) aStart.push_back(svx::frame::StyleVectorCombination(rLeftC, aY));
+            if(rLeftA.IsUsed()) aStart.push_back(svx::frame::StyleVectorCombination(rLeftA, -aY, bHor ? true : false));
+            if(rLeftB.IsUsed()) aStart.push_back(svx::frame::StyleVectorCombination(rLeftB, -rX, bHor ? true : true));
+            if(rLeftC.IsUsed()) aStart.push_back(svx::frame::StyleVectorCombination(rLeftC, aY, bHor ? false : true));
 
             /// Fill bottom-right Style Table
-            if(rRightA.IsUsed()) aEnd.push_back(svx::frame::StyleVectorCombination(rRightA, -aY));
-            if(rRightB.IsUsed()) aEnd.push_back(svx::frame::StyleVectorCombination(rRightB, rX));
-            if(rRightC.IsUsed()) aEnd.push_back(svx::frame::StyleVectorCombination(rRightC, aY));
+            if(rRightA.IsUsed()) aEnd.push_back(svx::frame::StyleVectorCombination(rRightA, -aY, bHor ? true : false));
+            if(rRightB.IsUsed()) aEnd.push_back(svx::frame::StyleVectorCombination(rRightB, rX, bHor ? false : false));
+            if(rRightC.IsUsed()) aEnd.push_back(svx::frame::StyleVectorCombination(rRightC, aY, bHor ? false : true));
 
             CreateBorderPrimitives(
                 rContainer,
@@ -354,28 +354,28 @@ namespace sdr
 
                                         if(aLeftLine.IsUsed())
                                         {
-                                            createForVector(aBorderSequence, aOrigin, aY, aLeftLine,
+                                            createForVector(false, aBorderSequence, aOrigin, aY, aLeftLine,
                                                 aTopLine, aLeftFromTLine, aTopFromLLine,
                                                 aBottomLine, aLeftFromBLine, aBottomFromLLine);
                                         }
 
                                         if(aBottomLine.IsUsed())
                                         {
-                                            createForVector(aBorderSequence, aOrigin + aY, aX, aBottomLine,
+                                            createForVector(true, aBorderSequence, aOrigin + aY, aX, aBottomLine,
                                                 aLeftLine, aBottomFromLLine, aLeftFromBLine,
                                                 aRightLine, aBottomFromRLine, aRightFromBLine);
                                         }
 
                                         if(aRightLine.IsUsed())
                                         {
-                                            createForVector(aBorderSequence, aOrigin + aX, aY, aRightLine,
+                                            createForVector(false, aBorderSequence, aOrigin + aX, aY, aRightLine,
                                                 aTopFromRLine, aRightFromTLine, aTopLine,
                                                 aBottomFromRLine, aRightFromBLine, aBottomLine);
                                         }
 
                                         if(aTopLine.IsUsed())
                                         {
-                                            createForVector(aBorderSequence, aOrigin, aX, aTopLine,
+                                            createForVector(true, aBorderSequence, aOrigin, aX, aTopLine,
                                                 aLeftFromTLine, aTopFromLLine, aLeftLine,
                                                 aRightFromTLine, aTopFromRLine, aRightLine);
                                         }
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 9d1928d2bf76..888db6527e77 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -221,7 +221,7 @@ class BorderLines
 {
     drawinglayer::primitive2d::Primitive2DContainer m_Lines;
 public:
-    void AddBorderLine(css::uno::Reference<BorderLinePrimitive2D> const& xLine, SwPaintProperties const & properties);
+    void AddBorderLine(const drawinglayer::primitive2d::Primitive2DReference& rLine);
     drawinglayer::primitive2d::Primitive2DContainer GetBorderLines_Clear()
     {
         drawinglayer::primitive2d::Primitive2DContainer lines;
@@ -472,197 +472,20 @@ SwSavePaintStatics::~SwSavePaintStatics()
     gProp.aSScaleY            = aSScaleY;
 }
 
-/**
- * Check whether the two primitive can be merged
- *
- * @param[in]   mergeA  A primitive start and end position
- * @param[in]   mergeB  B primitive start and end position
- * @return      1       if A and B can be merged to a primite staring with A, ending with B
- *              2       if A and B can be merged to a primite staring with B, ending with A
- *              0       if A and B can't be merged
-**/
-static sal_uInt8 lcl_TryMergeLines(
-    pair<double, double> const& mergeA,
-    pair<double, double> const& mergeB,
-    SwPaintProperties const & properties)
-{
-    double const fMergeGap(properties.nSPixelSzW + properties.nSHalfPixelSzW); // NOT static!
-    // A is above/before B
-    if( mergeA.second <= mergeB.first &&
-        mergeA.second + fMergeGap >= mergeB.first )
-    {
-        return 1;
-    }
-    // B is above/before A
-    else if( mergeB.second <= mergeA.first &&
-             mergeB.second + fMergeGap >= mergeA.first )
-    {
-        return 2;
-    }
-    return 0;
-}
-
-/**
- * Make a new primitive from the two input borderline primitive
- *
- * @param[in]   rLine       starting primitive
- * @param[in]   rOther      ending primitive
- * @param[in]   rStart      starting point of merged primitive
- * @param[in]   rEnd        ending point of merged primitive
- * @return      merged primitive
-**/
-static rtl::Reference<BorderLinePrimitive2D>
-lcl_MergeBorderLines(
-    BorderLinePrimitive2D const& rLine,
-    BorderLinePrimitive2D const& rOther,
-    basegfx::B2DPoint const& rStart,
-    basegfx::B2DPoint const& rEnd)
-{
-    const std::vector< BorderLine >& rLineLeft(rLine.getBorderLines());
-    const std::vector< BorderLine >& rOtherLeft(rOther.getBorderLines());
-    const size_t aSize(std::min(rLineLeft.size(), rOtherLeft.size()));
-    std::vector< BorderLine > aNew;
-
-    for(size_t a(0); a < aSize; a++)
-    {
-        const BorderLine& la(rLineLeft[a]);
-        const BorderLine& lb(rOtherLeft[a]);
-
-        if(la.isGap() || lb.isGap())
-        {
-            aNew.push_back(la);
-        }
-        else
-        {
-            aNew.push_back(
-                BorderLine(
-                    la.getLineAttribute(),
-                    la.getStartLeft(),
-                    la.getStartRight(),
-                    lb.getEndLeft(),
-                    lb.getEndRight()));
-        }
-    }
-
-    return new BorderLinePrimitive2D(
-        rStart,
-        rEnd,
-        aNew,
-        rLine.getStrokeAttribute());
-}
-
-/**
- * Merge the two borderline if possible.
- *
- * @param[in]   rThis   one borderline primitive
- * @param[in]   rOther  other borderline primitive
- * @return      merged borderline including the two input primitive, if they can be merged
- *              0, otherwise
-**/
-static rtl::Reference<BorderLinePrimitive2D>
-lcl_TryMergeBorderLine(BorderLinePrimitive2D const& rThis,
-                       BorderLinePrimitive2D const& rOther,
-                       SwPaintProperties const & properties)
+void BorderLines::AddBorderLine(const drawinglayer::primitive2d::Primitive2DReference& rLine)
 {
-    assert(rThis.getEnd().getX() >= rThis.getStart().getX());
-    assert(rThis.getEnd().getY() >= rThis.getStart().getY());
-    assert(rOther.getEnd().getX() >= rOther.getStart().getX());
-    assert(rOther.getEnd().getY() >= rOther.getStart().getY());
-    const bool bSameEdgeNumber(rThis.getBorderLines().size() == rOther.getBorderLines().size());
-
-    if (!bSameEdgeNumber)
-    {
-        return nullptr;
-    }
-
-    double thisHeight = rThis.getEnd().getY() - rThis.getStart().getY();
-    double thisWidth  = rThis.getEnd().getX() - rThis.getStart().getX();
-    double otherHeight = rOther.getEnd().getY() -  rOther.getStart().getY();
-    double otherWidth  = rOther.getEnd().getX() -  rOther.getStart().getX();
-
-    // check for same orientation, same line width, same style and matching colors
-    bool bSameStuff(
-        ((thisHeight > thisWidth) == (otherHeight > otherWidth))
-        && rThis.getStrokeAttribute() == rOther.getStrokeAttribute());
-
-    if(bSameStuff)
+    for (drawinglayer::primitive2d::Primitive2DContainer::reverse_iterator it = m_Lines.rbegin(); it != m_Lines.rend(); ++it)
     {
-        const std::vector< BorderLine >& rLineLeft(rThis.getBorderLines());
-        const std::vector< BorderLine >& rOtherLeft(rOther.getBorderLines());
-        const size_t aSize(std::min(rLineLeft.size(), rOtherLeft.size()));
-
-        for(size_t a(0); bSameStuff && a < aSize; a++)
-        {
-            const BorderLine& la(rLineLeft[a]);
-            const BorderLine& lb(rOtherLeft[a]);
-
-            bSameStuff = la == lb;
-        }
-    }
-
-    if (bSameStuff)
-    {
-        int nRet = 0;
-        if (thisHeight > thisWidth) // vertical line
-        {
-            if (rtl::math::approxEqual(rThis.getStart().getX(), rOther.getStart().getX()))
-            {
-                assert(rtl::math::approxEqual(rThis.getEnd().getX(), rOther.getEnd().getX()));
-                nRet = lcl_TryMergeLines(
-                    make_pair(rThis.getStart().getY(), rThis.getEnd().getY()),
-                    make_pair(rOther.getStart().getY(),rOther.getEnd().getY()),
-                    properties);
-            }
-        }
-        else // horizontal line
-        {
-            if (rtl::math::approxEqual(rThis.getStart().getY(), rOther.getStart().getY()))
-            {
-                assert(rtl::math::approxEqual(rThis.getEnd().getY(), rOther.getEnd().getY()));
-                nRet = lcl_TryMergeLines(
-                    make_pair(rThis.getStart().getX(), rThis.getEnd().getX()),
-                    make_pair(rOther.getStart().getX(),rOther.getEnd().getX()),
-                    properties);
-            }
-        }
+        const drawinglayer::primitive2d::Primitive2DReference aMerged(drawinglayer::primitive2d::tryMergeBorderLinePrimitive2D(*it, rLine));
 
-        // The merged primitive starts with rThis and ends with rOther
-        if (nRet == 1)
-        {
-            basegfx::B2DPoint const start(
-                rThis.getStart().getX(), rThis.getStart().getY());
-            basegfx::B2DPoint const end(
-                rOther.getEnd().getX(), rOther.getEnd().getY());
-            return lcl_MergeBorderLines(rThis, rOther, start, end).get();
-        }
-        // The merged primitive starts with rOther and ends with rThis
-        else if(nRet == 2)
+        if (aMerged.is())
         {
-            basegfx::B2DPoint const start(
-                rOther.getStart().getX(), rOther.getStart().getY());
-            basegfx::B2DPoint const end(
-                rThis.getEnd().getX(), rThis.getEnd().getY());
-            return lcl_MergeBorderLines(rOther, rThis, start, end).get();
-        }
-    }
-    return nullptr;
-}
-
-void BorderLines::AddBorderLine(
-        css::uno::Reference<BorderLinePrimitive2D> const& xLine, SwPaintProperties const & properties)
-{
-    for (drawinglayer::primitive2d::Primitive2DContainer::reverse_iterator it = m_Lines.rbegin(); it != m_Lines.rend();
-         ++it)
-    {
-        rtl::Reference<BorderLinePrimitive2D> const xMerged(
-            lcl_TryMergeBorderLine(*static_cast<BorderLinePrimitive2D*>((*it).get()), *xLine.get(), properties).get());
-        if (xMerged.is())
-        {
-            *it = xMerged.get(); // replace existing line with merged
+            *it = aMerged; // replace existing line with merged // lcl_TryMergeBorderLine
             return;
         }
     }
-    m_Lines.push_back(xLine);
+
+    m_Lines.append(rLine);
 }
 
 SwLineRect::SwLineRect( const SwRect &rRect, const Color *pCol, const SvxBorderLineStyle nStyl,
@@ -2608,6 +2431,7 @@ void SwTabFramePainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) cons
     aUpper.Pos() += pUpper->Frame().Pos();
     SwRect aUpperAligned( aUpper );
     ::SwAlignRect( aUpperAligned, gProp.pSGlobalShell, &rDev );
+    drawinglayer::primitive2d::Primitive2DContainer aSequence;
 
     while ( true )
     {
@@ -2715,8 +2539,6 @@ void SwTabFramePainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) cons
 
             if(aStyles[0].IsUsed())
             {
-                drawinglayer::primitive2d::Primitive2DContainer aSequence;
-
                 if (bHori)
                 {
                     const basegfx::B2DPoint aOrigin(aPaintStart.X(), aPaintStart.Y());
@@ -2728,13 +2550,13 @@ void SwTabFramePainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) cons
                         svx::frame::StyleVectorTable aStartTable;
                         svx::frame::StyleVectorTable aEndTable;
 
-                        if(aStyles[ 1 ].IsUsed()) aStartTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 1 ], -aY)); // aLFromT
-                        if(aStyles[ 2 ].IsUsed()) aStartTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 2 ], -aX)); // aLFromL
-                        if(aStyles[ 3 ].IsUsed()) aStartTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 3 ], aY)); // aLFromB
+                        if(aStyles[ 1 ].IsUsed()) aStartTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 1 ], -aY, true)); // aLFromT
+                        if(aStyles[ 2 ].IsUsed()) aStartTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 2 ], -aX, true)); // aLFromL
+                        if(aStyles[ 3 ].IsUsed()) aStartTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 3 ], aY, false)); // aLFromB
 
-                        if(aStyles[ 4 ].IsUsed()) aEndTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 4 ], -aY)); // aRFromT
-                        if(aStyles[ 5 ].IsUsed()) aEndTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 5 ], aX)); // aRFromR
-                        if(aStyles[ 6 ].IsUsed()) aEndTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 6 ], aY)); // aRFromB
+                        if(aStyles[ 4 ].IsUsed()) aEndTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 4 ], -aY, true)); // aRFromT
+                        if(aStyles[ 5 ].IsUsed()) aEndTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 5 ], aX, false)); // aRFromR
+                        if(aStyles[ 6 ].IsUsed()) aEndTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 6 ], aY, false)); // aRFromB
 
                         CreateBorderPrimitives(
                             aSequence,
@@ -2743,7 +2565,7 @@ void SwTabFramePainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) cons
                             aStyles[ 0 ],
                             aStartTable,
                             aEndTable,
-                            nullptr
+                            pTmpColor
                         );
                     }
                 }
@@ -2758,13 +2580,13 @@ void SwTabFramePainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) cons
                         svx::frame::StyleVectorTable aStartTable;
                         svx::frame::StyleVectorTable aEndTable;
 
-                        if(aStyles[ 3 ].IsUsed()) aStartTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 3 ], -aY)); // aTFromR
-                        if(aStyles[ 2 ].IsUsed()) aStartTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 2 ], -aX)); // aTFromT
-                        if(aStyles[ 1 ].IsUsed()) aStartTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 1 ], aY)); // aTFromL
+                        if(aStyles[ 3 ].IsUsed()) aStartTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 3 ], -aY, false)); // aTFromR
+                        if(aStyles[ 2 ].IsUsed()) aStartTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 2 ], -aX, true)); // aTFromT
+                        if(aStyles[ 1 ].IsUsed()) aStartTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 1 ], aY, true)); // aTFromL
 
-                        if(aStyles[ 6 ].IsUsed()) aEndTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 6 ], -aY)); // aBFromR
-                        if(aStyles[ 5 ].IsUsed()) aEndTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 5 ], aX)); // aBFromB
-                        if(aStyles[ 4 ].IsUsed()) aEndTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 4 ], aY)); // aBFromL
+                        if(aStyles[ 6 ].IsUsed()) aEndTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 6 ], -aY, false)); // aBFromR
+                        if(aStyles[ 5 ].IsUsed()) aEndTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 5 ], aX, false)); // aBFromB
+                        if(aStyles[ 4 ].IsUsed()) aEndTable.push_back(svx::frame::StyleVectorCombination(aStyles[ 4 ], aY, true)); // aBFromL
 
                         CreateBorderPrimitives(
                             aSequence,
@@ -2773,18 +2595,17 @@ void SwTabFramePainter::PaintLines(OutputDevice& rDev, const SwRect& rRect) cons
                             aStyles[ 0 ],
                             aStartTable,
                             aEndTable,
-                            nullptr
+                            pTmpColor
                         );
                     }
                 }
-
-                mrTabFrame.ProcessPrimitives(aSequence);
             }
         }
-
         ++aIter;
     }
 
+    mrTabFrame.ProcessPrimitives(aSequence);
+
     // restore output device:
     rDev.SetDrawMode( nOldDrawMode );
 }
@@ -4839,7 +4660,7 @@ static void lcl_MakeBorderLine(SwRect const& rRect,
     // When rendering to very small (virtual) devices, like when producing
     // page thumbnails in a mobile device app, the line geometry can end up
     // bogus (negative width or height), so just ignore such border lines.
-    // Otherwise we will run into assertions later in lcl_TryMergeBorderLine()
+    // Otherwise we will run into assertions later in BorderLinePrimitive2D::tryMerge()
     // at least.
     if (aEnd.getX() < aStart.getX() ||
         aEnd.getY() < aStart.getY())
@@ -4894,14 +4715,14 @@ static void lcl_MakeBorderLine(SwRect const& rRect,
                 nExtentRightEnd));
     }
 
-    rtl::Reference<BorderLinePrimitive2D> xLine(
+    drawinglayer::primitive2d::Primitive2DReference aLine(
         new BorderLinePrimitive2D(
             aStart,
             aEnd,
             aBorderlines,
             aStrokeAttribute));
 
-    properties.pBLines->AddBorderLine(xLine.get(), properties);
+    properties.pBLines->AddBorderLine(aLine);
 }
 
 /**


More information about the Libreoffice-commits mailing list