[Libreoffice-commits] core.git: Branch 'feature/SwFrameBorder' - 56 commits - basctl/source basegfx/source basic/source chart2/source compilerplugins/clang connectivity/source cppcanvas/source cppuhelper/source cppu/qa cui/source dbaccess/source desktop/source drawinglayer/qa drawinglayer/source dtrans/source editeng/source emfio/source extensions/source extras/CustomTarget_glade.mk filter/source forms/source framework/inc framework/source helpcontent2 i18npool/inc i18npool/source i18nutil/source include/basegfx include/comphelper include/connectivity include/i18nutil include/oox include/sfx2 include/svx include/test include/toolkit include/unotools include/vcl ios/LibreOfficeLight lingucomponent/source linguistic/source officecfg/registry oox/source pyuno/inc qadevOOo/Jar_OOoRunner.mk qadevOOo/objdsc qadevOOo/tests salhelper/source sal/osl sc/inc sc/qa sc/source sdext/source sd/inc sd/source sd/uiconfig sd/xml sfx2/source shell/Library_localebe.mk shell/source solenv/clang-format solenv/gbuild s oltools/cpp starmath/inc starmath/source svl/source svtools/source svx/source sw/inc sw/qa sw/source sw/uiconfig sysui/productlist.mk test/Library_subsequenttest.mk test/source toolkit/source ucb/source unotools/source vcl/backendtest vcl/inc vcl/opengl vcl/source vcl/unx vcl/workben writerfilter/source writerperfect/source xmlhelp/source xmlsecurity/qa xmlsecurity/source

Armin Le Grand Armin.Le.Grand at cib.de
Thu Dec 7 11:21:17 UTC 2017


Rebased ref, commits from common ancestor:
commit 8b0527ffa953a1050a19cd6cc0b6e98c771e3a17
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Tue Dec 5 19:35:20 2017 +0100

    SwFrameBorder: Converted BorderRectangle functionality
    
    to primitive usage, added a SwBorderRectanglePrimitive2D
    which now encapsulates the four Styles and the transformation
    of a single BorderLineRectangle. This is a preparation for
    later buffered primitive usage at SwFrame level
    
    Change-Id: I6689b94fe996ead8142553e8442e151e53d10e8a

diff --git a/sw/inc/sw_primitivetypes2d.hxx b/sw/inc/sw_primitivetypes2d.hxx
index 4ded8572088b..44509820f72c 100644
--- a/sw/inc/sw_primitivetypes2d.hxx
+++ b/sw/inc/sw_primitivetypes2d.hxx
@@ -25,6 +25,7 @@
 #define PRIMITIVE2D_ID_SWVIRTFLYDRAWOBJPRIMITIVE2D  (PRIMITIVE2D_ID_RANGE_SW| 0)
 #define PRIMITIVE2D_ID_SWSIDEBARANCHORPRIMITIVE     (PRIMITIVE2D_ID_RANGE_SW| 1)
 #define PRIMITIVE2D_ID_SWSIDEBARSHADOWPRIMITIVE     (PRIMITIVE2D_ID_RANGE_SW| 2)
+#define PRIMITIVE2D_ID_SWBORDERRECTANGLERIMITIVE    (PRIMITIVE2D_ID_RANGE_SW| 3)
 
 #endif // INCLUDED_SW_INC_SW_PRIMITIVETYPES2D_HXX
 
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index e6350e131984..30872d45e6f4 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -62,6 +62,8 @@
 #include <bodyfrm.hxx>
 #include <hffrm.hxx>
 #include <colfrm.hxx>
+#include <sw_primitivetypes2d.hxx>
+
 #include <svx/sdr/contact/viewobjectcontactredirector.hxx>
 #include <svx/sdr/contact/viewobjectcontact.hxx>
 #include <svx/sdr/contact/viewcontact.hxx>
@@ -232,7 +234,6 @@ public:
 };
 
 // Default zoom factor
-const static double aMinDistScale = 0.73;
 const static double aEdgeScale = 0.5;
 
 //To optimize the expensive RetouchColor determination
@@ -1180,42 +1181,6 @@ void SwAlignRect( SwRect &rRect, const SwViewShell *pSh, const vcl::RenderContex
 }
 
 /**
- * Helper for twip adjustments on pixel base
- *
- * This method compares the x- or y-pixel position of two twip-points.
- * If the x-/y-pixel positions are the same, the x-/y-pixel position of
- * the second twip point is adjusted by a given amount of pixels
-*/
-static void lcl_CompPxPosAndAdjustPos( const vcl::RenderContext&  _rOut,
-                                const Point&         _rRefPt,
-                                Point&               _rCompPt,
-                                const bool          _bChkXPos,
-                                const sal_Int8       _nPxAdjustment )
-{
-    const Point aRefPxPt = _rOut.LogicToPixel( _rRefPt );
-    Point aCompPxPt = _rOut.LogicToPixel( _rCompPt );
-
-    if ( _bChkXPos )
-    {
-        if ( aCompPxPt.X() == aRefPxPt.X() )
-        {
-            aCompPxPt.X() += _nPxAdjustment ;
-            const Point aAdjustedCompPt = _rOut.PixelToLogic( aCompPxPt );
-            _rCompPt.X() = aAdjustedCompPt.X();
-        }
-    }
-    else
-    {
-        if ( aCompPxPt.Y() == aRefPxPt.Y() )
-        {
-            aCompPxPt.Y() += _nPxAdjustment ;
-            const Point aAdjustedCompPt = _rOut.PixelToLogic( aCompPxPt );
-            _rCompPt.Y() = aAdjustedCompPt.Y();
-        }
-    }
-}
-
-/**
  * Method to pixel-align rectangle for drawing graphic object
  *
  * Because we are drawing graphics from the left-top-corner in conjunction
@@ -1261,13 +1226,6 @@ static long lcl_AlignHeight( const long nHeight, SwPaintProperties const & prope
     return nHeight;
 }
 
-static long lcl_MinHeightDist( const long nDist, SwPaintProperties const & properties )
-{
-    if ( properties.aSScaleX < aMinDistScale || properties.aSScaleY < aMinDistScale )
-        return nDist;
-    return ::lcl_AlignHeight( std::max( nDist, properties.nSMinDistPixelH ), properties);
-}
-
 /**
  * Calculate PrtArea plus surrounding plus shadow
  */
@@ -4490,298 +4448,254 @@ void SwFrame::PaintBorderLine( const SwRect& rRect,
         gProp.pSLines->AddLineRect( aOut, pColor, nStyle, pTab, nSubCol, gProp );
 }
 
-/**
- * @note Only all lines once or all lines twice!
- *
- * OD 29.04.2003 #107169# - method called for left and right border rectangles.
- * For a printer output device perform adjustment for non-overlapping top and
- * bottom border rectangles. Thus, add parameter <_bPrtOutputDev> to indicate
- * printer output device.
- * NOTE: For printer output device left/right border rectangle <_iorRect>
- *        has to be already non-overlapping the outer top/bottom border rectangle.
- */
-static void lcl_SubTopBottom( SwRect&              _iorRect,
-                                   const SvxBoxItem&    _rBox,
-                                   const SwBorderAttrs& _rAttrs,
-                                   const SwFrame&         _rFrame,
-                                   const SwRectFn&      _rRectFn,
-                                   const bool       _bPrtOutputDev,
-                                   SwPaintProperties const & properties )
+namespace drawinglayer
 {
-    const bool bCnt = _rFrame.IsContentFrame();
-    if ( _rBox.GetTop() && _rBox.GetTop()->GetInWidth() &&
-         ( !bCnt || _rAttrs.GetTopLine( _rFrame ) )
-       )
+    namespace primitive2d
     {
-        // subtract distance between outer and inner line.
-        SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetTop()->GetDistance(), properties );
-        // OD 19.05.2003 #109667# - non-overlapping border rectangles:
-        // adjust x-/y-position, if inner top line is a hair line (width = 1)
-        bool bIsInnerTopLineHairline = false;
-        if ( !_bPrtOutputDev )
+        class SW_DLLPUBLIC SwBorderRectanglePrimitive2D : public BufferedDecompositionPrimitive2D
         {
-            // additionally subtract width of top outer line
-            // --> left/right inner/outer line doesn't overlap top outer line.
-            nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetOutWidth(), properties );
-        }
-        else
-        {
-            // OD 29.04.2003 #107169# - additionally subtract width of top inner line
-            // --> left/right inner/outer line doesn't overlap top inner line.
-            nDist += ::lcl_AlignHeight( _rBox.GetTop()->GetInWidth(), properties );
-            bIsInnerTopLineHairline = _rBox.GetTop()->GetInWidth() == 1;
-        }
-        (_iorRect.*_rRectFn->fnSubTop)( -nDist );
-        // OD 19.05.2003 #109667# - adjust calculated border top, if inner top line
-        // is a hair line
-        if ( bIsInnerTopLineHairline )
-        {
-            if ( _rFrame.IsVertical() )
+        private:
+            /// the transformation defining the geometry of this BorderRectangle
+            basegfx::B2DHomMatrix       maB2DHomMatrix;
+
+            /// the four styles to be used
+            svx::frame::Style           maStyleTop;
+            svx::frame::Style           maStyleRight;
+            svx::frame::Style           maStyleBottom;
+            svx::frame::Style           maStyleLeft;
+
+        protected:
+            /// local decomposition.
+            virtual void create2DDecomposition(
+                Primitive2DContainer& rContainer,
+                const geometry::ViewInformation2D& rViewInformation) const override;
+
+        public:
+            /// constructor
+            SwBorderRectanglePrimitive2D(
+                const basegfx::B2DHomMatrix& rB2DHomMatrix,
+                const svx::frame::Style& rStyleTop,
+                const svx::frame::Style& rStyleRight,
+                const svx::frame::Style& rStyleBottom,
+                const svx::frame::Style& rStyleLeft);
+
+            /// data read access
+            const basegfx::B2DHomMatrix& getB2DHomMatrix() const { return maB2DHomMatrix; }
+            const svx::frame::Style& getStyleTop() const { return maStyleTop; }
+            const svx::frame::Style& getStyleRight() const { return maStyleRight; }
+            const svx::frame::Style& getStyleBottom() const { return maStyleBottom; }
+            const svx::frame::Style& getStyleLeft() const { return maStyleLeft; }
+
+            /// compare operator
+            virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
+
+            /// get range
+            virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const override;
+
+            /// provide unique ID
+            DeclPrimitive2DIDBlock()
+        };
+
+        void SwBorderRectanglePrimitive2D::create2DDecomposition(
+            Primitive2DContainer& rContainer,
+            const geometry::ViewInformation2D& /*rViewInformation*/) const
+        {
+            basegfx::B2DPoint aTopLeft(getB2DHomMatrix() * basegfx::B2DPoint(0.0, 0.0));
+            basegfx::B2DPoint aTopRight(getB2DHomMatrix() * basegfx::B2DPoint(1.0, 0.0));
+            basegfx::B2DPoint aBottomLeft(getB2DHomMatrix() * basegfx::B2DPoint(0.0, 1.0));
+            basegfx::B2DPoint aBottomRight(getB2DHomMatrix() * basegfx::B2DPoint(1.0, 1.0));
+
+            if(getStyleTop().IsUsed())
             {
-                // right of border rectangle has to be checked and adjusted
-                Point aCompPt( _iorRect.Right(), 0 );
-                Point aRefPt( aCompPt.X() + 1, aCompPt.Y() );
-                lcl_CompPxPosAndAdjustPos( *(properties.pSGlobalShell->GetOut()),
-                                          aRefPt, aCompPt,
-                                          true, -1 );
-                _iorRect.Right( aCompPt.X() );
+                // move top left/right inwards half border width
+                basegfx::B2DVector aDown(getB2DHomMatrix() * basegfx::B2DVector(0.0, 1.0));
+                aDown.setLength(getStyleTop().GetWidth() * 0.5);
+                aTopLeft += aDown;
+                aTopRight += aDown;
             }
-            else
+
+            if(getStyleBottom().IsUsed())
             {
-                // top of border rectangle has to be checked and adjusted
-                Point aCompPt( 0, _iorRect.Top() );
-                Point aRefPt( aCompPt.X(), aCompPt.Y() - 1 );
-                lcl_CompPxPosAndAdjustPos( *(properties.pSGlobalShell->GetOut()),
-                                          aRefPt, aCompPt,
-                                          false, +1 );
-                _iorRect.Top( aCompPt.Y() );
+                // move bottom left/right inwards half border width
+                basegfx::B2DVector aUp(getB2DHomMatrix() * basegfx::B2DVector(0.0, -1.0));
+                aUp.setLength(getStyleBottom().GetWidth() * 0.5);
+                aBottomLeft += aUp;
+                aBottomRight += aUp;
             }
-        }
-    }
 
-    if ( _rBox.GetBottom() && _rBox.GetBottom()->GetInWidth() &&
-         ( !bCnt || _rAttrs.GetBottomLine( _rFrame ) )
-       )
-    {
-        // subtract distance between outer and inner line.
-        SwTwips nDist = ::lcl_MinHeightDist( _rBox.GetBottom()->GetDistance(), properties );
-        // OD 19.05.2003 #109667# - non-overlapping border rectangles:
-        // adjust x-/y-position, if inner bottom line is a hair line (width = 1)
-        bool bIsInnerBottomLineHairline = false;
-        if ( !_bPrtOutputDev )
-        {
-            // additionally subtract width of bottom outer line
-            // --> left/right inner/outer line doesn't overlap bottom outer line.
-            nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetOutWidth(), properties );
-        }
-        else
-        {
-            // OD 29.04.2003 #107169# - additionally subtract width of bottom inner line
-            // --> left/right inner/outer line doesn't overlap bottom inner line.
-            nDist += ::lcl_AlignHeight( _rBox.GetBottom()->GetInWidth(), properties );
-            bIsInnerBottomLineHairline = _rBox.GetBottom()->GetInWidth() == 1;
-        }
-        (_iorRect.*_rRectFn->fnAddBottom)( -nDist );
-        // OD 19.05.2003 #109667# - adjust calculated border bottom, if inner
-        // bottom line is a hair line.
-        if ( bIsInnerBottomLineHairline )
-        {
-            if ( _rFrame.IsVertical() )
+            if(getStyleLeft().IsUsed())
             {
-                // left of border rectangle has to be checked and adjusted
-                Point aCompPt( _iorRect.Left(), 0 );
-                Point aRefPt( aCompPt.X() - 1, aCompPt.Y() );
-                lcl_CompPxPosAndAdjustPos( *(properties.pSGlobalShell->GetOut()),
-                                          aRefPt, aCompPt,
-                                          true, +1 );
-                _iorRect.Left( aCompPt.X() );
+                // move left top/bottom inwards half border width
+                basegfx::B2DVector aRight(getB2DHomMatrix() * basegfx::B2DVector(1.0, 0.0));
+                aRight.setLength(getStyleLeft().GetWidth() * 0.5);
+                aTopLeft += aRight;
+                aBottomLeft += aRight;
             }
-            else
+
+            if(getStyleRight().IsUsed())
             {
-                // bottom of border rectangle has to be checked and adjusted
-                Point aCompPt( 0, _iorRect.Bottom() );
-                Point aRefPt( aCompPt.X(), aCompPt.Y() + 1 );
-                lcl_CompPxPosAndAdjustPos( *(properties.pSGlobalShell->GetOut()),
-                                          aRefPt, aCompPt,
-                                          false, -1 );
-                _iorRect.Bottom( aCompPt.Y() );
+                // move right top/bottom inwards half border width
+                basegfx::B2DVector aLeft(getB2DHomMatrix() * basegfx::B2DVector(-1.0, 0.0));
+                aLeft.setLength(getStyleRight().GetWidth() * 0.5);
+                aTopRight += aLeft;
+                aBottomRight += aLeft;
             }
-        }
-    }
-}
-
-static sal_uInt16 lcl_GetLineWidth( const SvxBorderLine* pLine )
-{
-    if ( pLine != nullptr )
-        return pLine->GetScaledWidth();
-
-    return 0;
-}
-
-static double lcl_GetExtent( const SvxBorderLine* pSideLine, const SvxBorderLine* pOppositeLine )
-{
-    double nExtent = 0.0;
 
-    if ( pSideLine && !pSideLine->isEmpty() )
-        nExtent = -lcl_GetLineWidth( pSideLine ) / 2.0;
-    else if ( pOppositeLine )
-        nExtent = lcl_GetLineWidth( pOppositeLine ) / 2.0;
+            // go round-robin, from TopLeft to TopRight, down, left and back up. That
+            // way, the borders will not need to be mirrored in any way
+            if(getStyleTop().IsUsed())
+            {
+                // create BorderPrimitive(s) for top border
+                const basegfx::B2DVector aVector(aTopRight - aTopLeft);
+                svx::frame::StyleVectorTable aStartStyleVectorTable;
+                svx::frame::StyleVectorTable aEndStyleVectorTable;
 
-    return nExtent;
-}
+                if(getStyleLeft().IsUsed())
+                {
+                    aStartStyleVectorTable.add(getStyleLeft(), aVector, basegfx::B2DVector(aBottomLeft - aTopLeft), false);
+                }
 
-namespace
-{
-    void CreateBorderLinePrimitivesForRectangle(
-        drawinglayer::primitive2d::Primitive2DContainer& rBorderLineTarget,
-        const svx::frame::Style& rStyleTop,
-        const svx::frame::Style& rStyleRight,
-        const svx::frame::Style& rStyleBottom,
-        const svx::frame::Style& rStyleLeft,
-        basegfx::B2DPoint aTopLeft,
-        basegfx::B2DPoint aTopRight,
-        basegfx::B2DPoint aBottomLeft,
-        basegfx::B2DPoint aBottomRight)
-    {
-        if(rStyleTop.IsUsed())
-        {
-            // move top left/right inwards half border width
-            aTopLeft.setY(aTopLeft.getY() + (rStyleTop.GetWidth() * 0.5));
-            aTopRight.setY(aTopRight.getY() + (rStyleTop.GetWidth() * 0.5));
-        }
+                if(getStyleRight().IsUsed())
+                {
+                    aEndStyleVectorTable.add(getStyleRight(), -aVector, basegfx::B2DVector(aBottomRight - aTopRight), false);
+                }
 
-        if(rStyleBottom.IsUsed())
-        {
-            // move bottom left/right inwards half border width
-            aBottomLeft.setY(aBottomLeft.getY() - (rStyleBottom.GetWidth() * 0.5));
-            aBottomRight.setY(aBottomRight.getY() - (rStyleBottom.GetWidth() * 0.5));
-        }
+                CreateBorderPrimitives(
+                    rContainer,
+                    aTopLeft,
+                    aVector,
+                    getStyleTop(),
+                    aStartStyleVectorTable,
+                    aEndStyleVectorTable,
+                    nullptr);
+            }
 
-        if(rStyleLeft.IsUsed())
-        {
-            // move left top/bottom inwards half border width
-            aTopLeft.setX(aTopLeft.getX() + (rStyleLeft.GetWidth() * 0.5));
-            aBottomLeft.setX(aBottomLeft.getX() + (rStyleLeft.GetWidth() * 0.5));
-        }
+            if(getStyleRight().IsUsed())
+            {
+                // create BorderPrimitive(s) for right border
+                const basegfx::B2DVector aVector(aBottomRight - aTopRight);
+                svx::frame::StyleVectorTable aStartStyleVectorTable;
+                svx::frame::StyleVectorTable aEndStyleVectorTable;
 
-        if(rStyleRight.IsUsed())
-        {
-            // move right top/bottom inwards half border width
-            aTopRight.setX(aTopRight.getX() - (rStyleRight.GetWidth() * 0.5));
-            aBottomRight.setX(aBottomRight.getX() - (rStyleRight.GetWidth() * 0.5));
-        }
+                if(getStyleTop().IsUsed())
+                {
+                    aStartStyleVectorTable.add(getStyleTop(), aVector, basegfx::B2DVector(aTopLeft - aTopRight), false);
+                }
 
-        // go round-robin, from TopLeft to TopRight, down, left and back up. That
-        // way, the borders will not need to be mirrored in any way
-        if(rStyleTop.IsUsed())
-        {
-            // create BorderPrimitive(s) for top border
-            const basegfx::B2DVector aVector(aTopRight - aTopLeft);
-            svx::frame::StyleVectorTable aStartStyleVectorTable;
-            svx::frame::StyleVectorTable aEndStyleVectorTable;
+                if(getStyleBottom().IsUsed())
+                {
+                    aEndStyleVectorTable.add(getStyleBottom(), -aVector, basegfx::B2DVector(aBottomLeft - aBottomRight), false);
+                }
 
-            if(rStyleLeft.IsUsed())
-            {
-                aStartStyleVectorTable.add(rStyleLeft, aVector, basegfx::B2DVector(aBottomLeft - aTopLeft), false);
+                CreateBorderPrimitives(
+                    rContainer,
+                    aTopRight,
+                    aVector,
+                    getStyleRight(),
+                    aStartStyleVectorTable,
+                    aEndStyleVectorTable,
+                    nullptr);
             }
 
-            if(rStyleRight.IsUsed())
+            if(getStyleBottom().IsUsed())
             {
-                aEndStyleVectorTable.add(rStyleRight, -aVector, basegfx::B2DVector(aBottomRight - aTopRight), false);
-            }
+                // create BorderPrimitive(s) for bottom border
+                const basegfx::B2DVector aVector(aBottomLeft - aBottomRight);
+                svx::frame::StyleVectorTable aStartStyleVectorTable;
+                svx::frame::StyleVectorTable aEndStyleVectorTable;
 
-            CreateBorderPrimitives(
-                rBorderLineTarget,
-                aTopLeft,
-                aVector,
-                rStyleTop,
-                aStartStyleVectorTable,
-                aEndStyleVectorTable,
-                nullptr);
-        }
+                if(getStyleRight().IsUsed())
+                {
+                    aStartStyleVectorTable.add(getStyleRight(), aVector, basegfx::B2DVector(aTopRight - aBottomRight), false);
+                }
 
-        if(rStyleRight.IsUsed())
-        {
-            // create BorderPrimitive(s) for right border
-            const basegfx::B2DVector aVector(aBottomRight - aTopRight);
-            svx::frame::StyleVectorTable aStartStyleVectorTable;
-            svx::frame::StyleVectorTable aEndStyleVectorTable;
+                if(getStyleLeft().IsUsed())
+                {
+                    aEndStyleVectorTable.add(getStyleLeft(), -aVector, basegfx::B2DVector(aTopLeft - aBottomLeft), false);
+                }
 
-            if(rStyleTop.IsUsed())
-            {
-                aStartStyleVectorTable.add(rStyleTop, aVector, basegfx::B2DVector(aTopLeft - aTopRight), false);
+                CreateBorderPrimitives(
+                    rContainer,
+                    aBottomRight,
+                    aVector,
+                    getStyleBottom(),
+                    aStartStyleVectorTable,
+                    aEndStyleVectorTable,
+                    nullptr);
             }
 
-            if(rStyleBottom.IsUsed())
+            if(getStyleLeft().IsUsed())
             {
-                aEndStyleVectorTable.add(rStyleBottom, -aVector, basegfx::B2DVector(aBottomLeft - aBottomRight), false);
-            }
+                // create BorderPrimitive(s) for left border
+                const basegfx::B2DVector aVector(aTopLeft - aBottomLeft);
+                svx::frame::StyleVectorTable aStartStyleVectorTable;
+                svx::frame::StyleVectorTable aEndStyleVectorTable;
+
+                if(getStyleBottom().IsUsed())
+                {
+                    aStartStyleVectorTable.add(getStyleBottom(), aVector, basegfx::B2DVector(aBottomRight - aBottomLeft), false);
+                }
 
-            CreateBorderPrimitives(
-                rBorderLineTarget,
-                aTopRight,
-                aVector,
-                rStyleRight,
-                aStartStyleVectorTable,
-                aEndStyleVectorTable,
-                nullptr);
+                if(getStyleTop().IsUsed())
+                {
+                    aEndStyleVectorTable.add(getStyleTop(), -aVector, basegfx::B2DVector(aTopRight - aTopLeft), false);
+                }
+
+                CreateBorderPrimitives(
+                    rContainer,
+                    aBottomLeft,
+                    aVector,
+                    getStyleLeft(),
+                    aStartStyleVectorTable,
+                    aEndStyleVectorTable,
+                    nullptr);
+            }
         }
 
-        if(rStyleBottom.IsUsed())
+        SwBorderRectanglePrimitive2D::SwBorderRectanglePrimitive2D(
+            const basegfx::B2DHomMatrix& rB2DHomMatrix,
+            const svx::frame::Style& rStyleTop,
+            const svx::frame::Style& rStyleRight,
+            const svx::frame::Style& rStyleBottom,
+            const svx::frame::Style& rStyleLeft)
+        :   BufferedDecompositionPrimitive2D(),
+            maB2DHomMatrix(rB2DHomMatrix),
+            maStyleTop(rStyleTop),
+            maStyleRight(rStyleRight),
+            maStyleBottom(rStyleBottom),
+            maStyleLeft(rStyleLeft)
         {
-            // create BorderPrimitive(s) for bottom border
-            const basegfx::B2DVector aVector(aBottomLeft - aBottomRight);
-            svx::frame::StyleVectorTable aStartStyleVectorTable;
-            svx::frame::StyleVectorTable aEndStyleVectorTable;
+        }
 
-            if(rStyleRight.IsUsed())
+        bool SwBorderRectanglePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+        {
+            if(BasePrimitive2D::operator==(rPrimitive))
             {
-                aStartStyleVectorTable.add(rStyleRight, aVector, basegfx::B2DVector(aTopRight - aBottomRight), false);
-            }
+                const SwBorderRectanglePrimitive2D& rCompare = static_cast<const SwBorderRectanglePrimitive2D&>(rPrimitive);
 
-            if(rStyleLeft.IsUsed())
-            {
-                aEndStyleVectorTable.add(rStyleLeft, -aVector, basegfx::B2DVector(aTopLeft - aBottomLeft), false);
+                return (getB2DHomMatrix() == rCompare.getB2DHomMatrix() &&
+                    getStyleTop() == rCompare.getStyleTop() &&
+                    getStyleRight() == rCompare.getStyleRight() &&
+                    getStyleBottom() == rCompare.getStyleBottom() &&
+                    getStyleLeft() == rCompare.getStyleLeft());
             }
 
-            CreateBorderPrimitives(
-                rBorderLineTarget,
-                aBottomRight,
-                aVector,
-                rStyleBottom,
-                aStartStyleVectorTable,
-                aEndStyleVectorTable,
-                nullptr);
+            return false;
         }
 
-        if(rStyleLeft.IsUsed())
+        basegfx::B2DRange SwBorderRectanglePrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
         {
-            // create BorderPrimitive(s) for left border
-            const basegfx::B2DVector aVector(aTopLeft - aBottomLeft);
-            svx::frame::StyleVectorTable aStartStyleVectorTable;
-            svx::frame::StyleVectorTable aEndStyleVectorTable;
+            basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
 
-            if(rStyleBottom.IsUsed())
-            {
-                aStartStyleVectorTable.add(rStyleBottom, aVector, basegfx::B2DVector(aBottomRight - aBottomLeft), false);
-            }
+            aRetval.transform(getB2DHomMatrix());
+            return aRetval;
+        }
 
-            if(rStyleTop.IsUsed())
-            {
-                aEndStyleVectorTable.add(rStyleTop, -aVector, basegfx::B2DVector(aTopRight - aTopLeft), false);
-            }
+        // provide unique ID
+        ImplPrimitive2DIDBlock(SwBorderRectanglePrimitive2D, PRIMITIVE2D_ID_SWBORDERRECTANGLERIMITIVE)
 
-            CreateBorderPrimitives(
-                rBorderLineTarget,
-                aBottomLeft,
-                aVector,
-                rStyleLeft,
-                aStartStyleVectorTable,
-                aEndStyleVectorTable,
-                nullptr);
-        }
-    }
-} // end of anonymous namespace
+    } // end of namespace primitive2d
+} // end of namespace drawinglayer
 
 void PaintCharacterBorder(
     const SwFont& rFont,
@@ -4831,20 +4745,24 @@ void PaintCharacterBorder(
         }
     }
 
+    const basegfx::B2DHomMatrix aBorderTransform(
+        basegfx::utils::createScaleTranslateB2DHomMatrix(
+            aAlignedRect.Width(), aAlignedRect.Height(),
+            aAlignedRect.Left(), aAlignedRect.Top()));
+    const svx::frame::Style aStyleTop(bTop ? rFont.GetAbsTopBorder(bVerticalLayout).get_ptr() : nullptr, 1.0);
+    const svx::frame::Style aStyleRight(bRight ? rFont.GetAbsRightBorder(bVerticalLayout).get_ptr() : nullptr, 1.0);
+    const svx::frame::Style aStyleBottom(bBottom ? rFont.GetAbsBottomBorder(bVerticalLayout).get_ptr() : nullptr, 1.0);
+    const svx::frame::Style aStyleLeft(bLeft ? rFont.GetAbsLeftBorder(bVerticalLayout).get_ptr() : nullptr, 1.0);
     drawinglayer::primitive2d::Primitive2DContainer aBorderLineTarget;
-    CreateBorderLinePrimitivesForRectangle(
-        aBorderLineTarget,
-        svx::frame::Style(bTop ? rFont.GetAbsTopBorder(bVerticalLayout).get_ptr() : nullptr, 1.0),
-        svx::frame::Style(bRight ? rFont.GetAbsRightBorder(bVerticalLayout).get_ptr() : nullptr, 1.0),
-        svx::frame::Style(bBottom ? rFont.GetAbsBottomBorder(bVerticalLayout).get_ptr() : nullptr, 1.0),
-        svx::frame::Style(bLeft ? rFont.GetAbsLeftBorder(bVerticalLayout).get_ptr() : nullptr, 1.0),
-        basegfx::B2DPoint(aAlignedRect.Left(), aAlignedRect.Top()),
-        basegfx::B2DPoint(aAlignedRect.Right(), aAlignedRect.Top()),
-        basegfx::B2DPoint(aAlignedRect.Left(), aAlignedRect.Bottom()),
-        basegfx::B2DPoint(aAlignedRect.Right(), aAlignedRect.Bottom()));
-
-    // no need to use AddBorderLine and try to merge BorderLinePrimitives, in this combination
-    // tis cannot happen
+
+    aBorderLineTarget.append(
+        drawinglayer::primitive2d::Primitive2DReference(
+            new drawinglayer::primitive2d::SwBorderRectanglePrimitive2D(
+                aBorderTransform,
+                aStyleTop,
+                aStyleRight,
+                aStyleBottom,
+                aStyleLeft)));
     gProp.pBLines->AddBorderLines(aBorderLineTarget);
 }
 
@@ -5199,21 +5117,24 @@ void SwFrame::PaintSwFrameShadowAndBorder(
         if(nullptr != pLeftBorder || nullptr != pRightBorder || nullptr != pTopBorder || nullptr != pBottomBorder)
         {
             // now we have all SvxBorderLine(s) sorted out, create geometry
+            const basegfx::B2DHomMatrix aBorderTransform(
+                basegfx::utils::createScaleTranslateB2DHomMatrix(
+                    aRect.Width(), aRect.Height(),
+                    aRect.Left(), aRect.Top()));
+            const svx::frame::Style aStyleTop(pTopBorder, 1.0);
+            const svx::frame::Style aStyleRight(pRightBorder, 1.0);
+            const svx::frame::Style aStyleBottom(pBottomBorder, 1.0);
+            const svx::frame::Style aStyleLeft(pLeftBorder, 1.0);
             drawinglayer::primitive2d::Primitive2DContainer aBorderLineTarget;
 
-            CreateBorderLinePrimitivesForRectangle(
-                aBorderLineTarget,
-                svx::frame::Style(pTopBorder, 1.0),
-                svx::frame::Style(pRightBorder, 1.0),
-                svx::frame::Style(pBottomBorder, 1.0),
-                svx::frame::Style(pLeftBorder, 1.0),
-                basegfx::B2DPoint(aRect.Left(), aRect.Top()),       // TopLeft
-                basegfx::B2DPoint(aRect.Right(), aRect.Top()),      // TopRight
-                basegfx::B2DPoint(aRect.Left(), aRect.Bottom()),    // BottomLeft
-                basegfx::B2DPoint(aRect.Right(), aRect.Bottom()));  // BottomRight
-
-            // no need to use AddBorderLine and try to merge BorderLinePrimitives, in this combination
-            // tis cannot happen
+            aBorderLineTarget.append(
+                drawinglayer::primitive2d::Primitive2DReference(
+                    new drawinglayer::primitive2d::SwBorderRectanglePrimitive2D(
+                        aBorderTransform,
+                        aStyleTop,
+                        aStyleRight,
+                        aStyleBottom,
+                        aStyleLeft)));
             gProp.pBLines->AddBorderLines(aBorderLineTarget);
         }
     }
commit 63f3fee4eb944000b792966634d3bb7a7f8eb511
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Tue Dec 5 15:28:08 2017 +0100

    SwFrameBorder: Use enhanced FrameBorders for Character
    
    Adapted PaintCharacterBorder to also use new, enhanced
    FrameBorders. Adapted some places, cleaned up old code,
    enhanced tooling method CreateBorderLinePrimitivesForRectangle,
    tested including PDF, Pint, PrintPreview.
    
    Change-Id: If7b793b6520e899bde6f4211c993847af21ce7b9

diff --git a/include/svx/framelink.hxx b/include/svx/framelink.hxx
index be442e4103da..efbf27dc30af 100644
--- a/include/svx/framelink.hxx
+++ b/include/svx/framelink.hxx
@@ -275,6 +275,41 @@ public:
     const std::vector< StyleVectorCombination >& getEntries() const{ return maEntries; }
 };
 
+/**
+ *  Helper method to create the correct drawinglayer::primitive2d::BorderLinePrimitive2D
+ *  for the given data, especially the correct drawinglayer::primitive2d::BorderLine entries
+ *  including the correctly solved/created LineStartEnd extends
+ *
+ *  rTarget : Here the evtl. created BorderLinePrimitive2D will be appended
+ *  rOrigin : StartPoint of the Borderline
+ *  rX      : Vector of the Borderline
+ *  rBorder : svx::frame::Style of the of the Borderline
+ *  rStartStyleVectorTable : All other Borderlines which have to be taken into account because
+ *      they have the same StartPoint as the current Borderline. These will be used to calculate
+ *      the correct LineStartEnd extends tor the BorderLinePrimitive2D. The definition should be
+ *      built up using svx::frame::StyleVectorTable and StyleVectorTable::add and includes:
+ *          rStyle      : the svx::frame::Style of one other BorderLine
+ *          rMyVector   : the Vector of the *new* to-be-defined BorderLine, identical to rX
+ *          rOtherVector: the Vector of one other BorderLine (may be, but does not need to be normalized),
+ *                        always *pointing away* from the common StartPoint rOrigin
+ *          bMirrored   : define if rStyle of one other BorderLine shall be mirrored (e.g. bottom-right edges)
+ *      With multiple BorderLines the definitions have to be CounterClockWise. This will be
+ *      ensured by StyleVectorTable sorting the entries, but knowing this may allow more efficcient
+ *      data creation.
+ *  rEndStyleVectorTable: All other BorderLines that have the same EndPoint. There are differences to
+ *      the Start definitions:
+ *          - do not forget to consequently use -rX for rMyVector
+ *          - definitions have to be ClockWise for the EndBorderLines, will be ensured by sorting
+ *
+ *  If you take all this into account, you will gett correctly extended BorderLinePrimitive2D
+ *  reprsentations for the new to be defined BorderLine. That extensions will overlap nicely
+ *  with the corresponding BordreLines and take all multiple line definitions in the ::Style into
+ *  account.
+ *  The internal solver is *not limitied* to ::Style(s) with three parts (Left/Gap/Right), this is
+ *  just due to svx::frame::Style's definitions. A new solver based on this one can be created
+ *  anytime using more mulötiple borders based on the more flexible
+ *  std::vector< drawinglayer::primitive2d::BorderLine > if needed.
+ */
 SVX_DLLPUBLIC void CreateBorderPrimitives(
     drawinglayer::primitive2d::Primitive2DContainer&    rTarget,        /// target for created primitives
     const basegfx::B2DPoint&    rOrigin,                /// start point of borderline
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index 448504994a69..827def10ed2f 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -263,6 +263,8 @@ Style& Style::MirrorSelf()
     if (pTarget->mfSecn)
     {
         std::swap( pTarget->mfPrim, pTarget->mfSecn );
+        // also need to swap colors
+        std::swap( pTarget->maColorPrim, pTarget->maColorSecn );
     }
 
     if( pTarget->meRefMode != RefMode::Centered )
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index aaff5532ee09..684a9e13a3d0 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -529,8 +529,10 @@ public:
     // #i28701# - change purpose of method and adjust its name
     void InvalidateObjs( const bool _bNoInvaOfAsCharAnchoredObjs = true );
 
-    virtual void PaintSwFrameShadowAndBorder( const SwRect&, const SwPageFrame *pPage,
-                              const SwBorderAttrs & ) const;
+    virtual void PaintSwFrameShadowAndBorder(
+        const SwRect&,
+        const SwPageFrame* pPage,
+        const SwBorderAttrs&) const;
     void PaintBaBo( const SwRect&, const SwPageFrame *pPage,
                     const bool bOnlyTextBackground = false) const;
     void PaintSwFrameBackground( const SwRect&, const SwPageFrame *pPage,
diff --git a/sw/source/core/inc/ftnfrm.hxx b/sw/source/core/inc/ftnfrm.hxx
index 6ba563cd3f31..7f964d654d4d 100644
--- a/sw/source/core/inc/ftnfrm.hxx
+++ b/sw/source/core/inc/ftnfrm.hxx
@@ -43,8 +43,10 @@ public:
     virtual SwTwips ShrinkFrame( SwTwips, bool bTst = false, bool bInfo = false ) override;
     virtual SwTwips GrowFrame  ( SwTwips, bool bTst = false, bool bInfo = false ) override;
     virtual void    Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr ) override;
-    virtual void    PaintSwFrameShadowAndBorder( const SwRect &, const SwPageFrame *pPage,
-                                 const SwBorderAttrs & ) const override;
+    virtual void    PaintSwFrameShadowAndBorder(
+        const SwRect&,
+        const SwPageFrame* pPage,
+        const SwBorderAttrs&) const override;
     virtual void PaintSubsidiaryLines( const SwPageFrame*, const SwRect& ) const override;
             void    PaintLine( const SwRect &, const SwPageFrame * ) const;
 };
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index 882c9a48fc9d..e6350e131984 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -222,7 +222,7 @@ class BorderLines
 {
     drawinglayer::primitive2d::Primitive2DContainer m_Lines;
 public:
-    void AddBorderLine(const drawinglayer::primitive2d::Primitive2DReference& rLine);
+    void AddBorderLines(const drawinglayer::primitive2d::Primitive2DContainer& rContainer);
     drawinglayer::primitive2d::Primitive2DContainer GetBorderLines_Clear()
     {
         drawinglayer::primitive2d::Primitive2DContainer lines;
@@ -473,20 +473,12 @@ SwSavePaintStatics::~SwSavePaintStatics()
     gProp.aSScaleY            = aSScaleY;
 }
 
-void BorderLines::AddBorderLine(const drawinglayer::primitive2d::Primitive2DReference& rLine)
+void BorderLines::AddBorderLines(const drawinglayer::primitive2d::Primitive2DContainer& rContainer)
 {
-    for (drawinglayer::primitive2d::Primitive2DContainer::reverse_iterator it = m_Lines.rbegin(); it != m_Lines.rend(); ++it)
+    if(!rContainer.empty())
     {
-        const drawinglayer::primitive2d::Primitive2DReference aMerged(drawinglayer::primitive2d::tryMergeBorderLinePrimitive2D(*it, rLine));
-
-        if (aMerged.is())
-        {
-            *it = aMerged; // replace existing line with merged // lcl_TryMergeBorderLine
-            return;
-        }
+        m_Lines.append(rContainer);
     }
-
-    m_Lines.append(rLine);
 }
 
 SwLineRect::SwLineRect( const SwRect &rRect, const Color *pCol, const SvxBorderLineStyle nStyl,
@@ -4085,7 +4077,7 @@ void SwFlyFrame::PaintSwFrame(vcl::RenderContext& rRenderContext, SwRect const&
 
             // OD 06.08.2002 #99657# - paint border before painting background
             // paint border
-            PaintSwFrameShadowAndBorder( rRect, pPage, rAttrs );
+            PaintSwFrameShadowAndBorder(rRect, pPage, rAttrs);
 
             rRenderContext.Pop();
         }
@@ -4638,119 +4630,158 @@ static double lcl_GetExtent( const SvxBorderLine* pSideLine, const SvxBorderLine
     return nExtent;
 }
 
-static void lcl_MakeBorderLine(SwRect const& rRect,
-        bool const isVerticalInModel,
-        bool const isLeftOrTopBorderInModel,
-        bool const isVertical,
-        SvxBorderLine const& rBorder,
-        SvxBorderLine const*const pLeftOrTopNeighbour,
-        SvxBorderLine const*const pRightOrBottomNeighbour,
-        SwPaintProperties& properties)
+namespace
 {
-    bool const isLeftOrTopBorder((isVerticalInModel == isVertical)
-            ? isLeftOrTopBorderInModel
-            : (isLeftOrTopBorderInModel != isVertical));
-    SvxBorderLine const*const pStartNeighbour(
-            (!isVertical && isVerticalInModel)
-            ? pRightOrBottomNeighbour : pLeftOrTopNeighbour);
-    SvxBorderLine const*const pEndNeighbour(
-            (pStartNeighbour == pLeftOrTopNeighbour)
-            ? pRightOrBottomNeighbour : pLeftOrTopNeighbour);
-
-    basegfx::B2DPoint aStart;
-    basegfx::B2DPoint aEnd;
-    if (isVertical)
-    {   // fdo#38635: always from outer edge
-        double const fStartX( isLeftOrTopBorder
-                ? rRect.Left()  + (rRect.Width() / 2.0)
-                : rRect.Right() - (rRect.Width() / 2.0));
-        aStart.setX(fStartX);
-        aStart.setY(rRect.Top() +
-                lcl_AlignHeight(lcl_GetLineWidth(pStartNeighbour), properties)/2.0);
-        aEnd.setX(fStartX);
-        aEnd.setY(rRect.Bottom() -
-                lcl_AlignHeight(lcl_GetLineWidth(pEndNeighbour), properties)/2.0);
-    }
-    else
-    {   // fdo#38635: always from outer edge
-        double const fStartY( isLeftOrTopBorder
-                ? rRect.Top()    + (rRect.Height() / 2.0)
-                : rRect.Bottom() - (rRect.Height() / 2.0));
-        aStart.setX(rRect.Left() +
-                lcl_AlignWidth(lcl_GetLineWidth(pStartNeighbour), properties)/2.0);
-        aStart.setY(fStartY);
-        aEnd.setX(rRect.Right() -
-                lcl_AlignWidth(lcl_GetLineWidth(pEndNeighbour), properties)/2.0);
-        aEnd.setY(fStartY);
-    }
-
-    // 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 BorderLinePrimitive2D::tryMerge()
-    // at least.
-    if (aEnd.getX() < aStart.getX() ||
-        aEnd.getY() < aStart.getY())
-        return;
+    void CreateBorderLinePrimitivesForRectangle(
+        drawinglayer::primitive2d::Primitive2DContainer& rBorderLineTarget,
+        const svx::frame::Style& rStyleTop,
+        const svx::frame::Style& rStyleRight,
+        const svx::frame::Style& rStyleBottom,
+        const svx::frame::Style& rStyleLeft,
+        basegfx::B2DPoint aTopLeft,
+        basegfx::B2DPoint aTopRight,
+        basegfx::B2DPoint aBottomLeft,
+        basegfx::B2DPoint aBottomRight)
+    {
+        if(rStyleTop.IsUsed())
+        {
+            // move top left/right inwards half border width
+            aTopLeft.setY(aTopLeft.getY() + (rStyleTop.GetWidth() * 0.5));
+            aTopRight.setY(aTopRight.getY() + (rStyleTop.GetWidth() * 0.5));
+        }
 
-    double const nExtentLeftStart = (isLeftOrTopBorder == isVertical)
-        ?   lcl_GetExtent(pStartNeighbour, nullptr)
-        :   lcl_GetExtent(nullptr, pStartNeighbour);
-    double const nExtentLeftEnd = (isLeftOrTopBorder == isVertical)
-        ?   lcl_GetExtent(pEndNeighbour, nullptr)
-        :   lcl_GetExtent(nullptr, pEndNeighbour);
-    double const nExtentRightStart = (isLeftOrTopBorder == isVertical)
-        ?   lcl_GetExtent(nullptr, pStartNeighbour)
-        :   lcl_GetExtent(pStartNeighbour, nullptr);
-    double const nExtentRightEnd = (isLeftOrTopBorder == isVertical)
-        ?   lcl_GetExtent(nullptr, pEndNeighbour)
-        :   lcl_GetExtent(pEndNeighbour, nullptr);
-
-    double const nLeftWidth = rBorder.GetOutWidth();
-    double const nRightWidth = rBorder.GetInWidth();
-    Color const aLeftColor = rBorder.GetColorOut(isLeftOrTopBorder);
-    Color const aRightColor = rBorder.GetColorIn(isLeftOrTopBorder);
-    const std::vector<double> aDashing(svtools::GetLineDashing(rBorder.GetBorderLineStyle(), 10.0));
-    const drawinglayer::attribute::StrokeAttribute aStrokeAttribute(aDashing);
-    std::vector< drawinglayer::primitive2d::BorderLine > aBorderlines;
-
-    aBorderlines.push_back(
-        drawinglayer::primitive2d::BorderLine(
-            drawinglayer::attribute::LineAttribute(
-                aLeftColor.getBColor(),
-                nLeftWidth),
-            nExtentLeftStart,
-            nExtentLeftStart,
-            nExtentLeftEnd,
-            nExtentLeftEnd));
-
-    if (!basegfx::fTools::equalZero(nRightWidth))
-    {
-        drawinglayer::primitive2d::BorderLine(
-            drawinglayer::attribute::LineAttribute(
-                rBorder.GetColorGap().getBColor(),
-                rBorder.GetDistance()));
-
-        aBorderlines.push_back(
-            drawinglayer::primitive2d::BorderLine(
-                drawinglayer::attribute::LineAttribute(
-                    aRightColor.getBColor(),
-                    nRightWidth),
-                nExtentRightStart,
-                nExtentRightStart,
-                nExtentRightEnd,
-                nExtentRightEnd));
-    }
-
-    drawinglayer::primitive2d::Primitive2DReference aLine(
-        new BorderLinePrimitive2D(
-            aStart,
-            aEnd,
-            aBorderlines,
-            aStrokeAttribute));
-
-    properties.pBLines->AddBorderLine(aLine);
-}
+        if(rStyleBottom.IsUsed())
+        {
+            // move bottom left/right inwards half border width
+            aBottomLeft.setY(aBottomLeft.getY() - (rStyleBottom.GetWidth() * 0.5));
+            aBottomRight.setY(aBottomRight.getY() - (rStyleBottom.GetWidth() * 0.5));
+        }
+
+        if(rStyleLeft.IsUsed())
+        {
+            // move left top/bottom inwards half border width
+            aTopLeft.setX(aTopLeft.getX() + (rStyleLeft.GetWidth() * 0.5));
+            aBottomLeft.setX(aBottomLeft.getX() + (rStyleLeft.GetWidth() * 0.5));
+        }
+
+        if(rStyleRight.IsUsed())
+        {
+            // move right top/bottom inwards half border width
+            aTopRight.setX(aTopRight.getX() - (rStyleRight.GetWidth() * 0.5));
+            aBottomRight.setX(aBottomRight.getX() - (rStyleRight.GetWidth() * 0.5));
+        }
+
+        // go round-robin, from TopLeft to TopRight, down, left and back up. That
+        // way, the borders will not need to be mirrored in any way
+        if(rStyleTop.IsUsed())
+        {
+            // create BorderPrimitive(s) for top border
+            const basegfx::B2DVector aVector(aTopRight - aTopLeft);
+            svx::frame::StyleVectorTable aStartStyleVectorTable;
+            svx::frame::StyleVectorTable aEndStyleVectorTable;
+
+            if(rStyleLeft.IsUsed())
+            {
+                aStartStyleVectorTable.add(rStyleLeft, aVector, basegfx::B2DVector(aBottomLeft - aTopLeft), false);
+            }
+
+            if(rStyleRight.IsUsed())
+            {
+                aEndStyleVectorTable.add(rStyleRight, -aVector, basegfx::B2DVector(aBottomRight - aTopRight), false);
+            }
+
+            CreateBorderPrimitives(
+                rBorderLineTarget,
+                aTopLeft,
+                aVector,
+                rStyleTop,
+                aStartStyleVectorTable,
+                aEndStyleVectorTable,
+                nullptr);
+        }
+
+        if(rStyleRight.IsUsed())
+        {
+            // create BorderPrimitive(s) for right border
+            const basegfx::B2DVector aVector(aBottomRight - aTopRight);
+            svx::frame::StyleVectorTable aStartStyleVectorTable;
+            svx::frame::StyleVectorTable aEndStyleVectorTable;
+
+            if(rStyleTop.IsUsed())
+            {
+                aStartStyleVectorTable.add(rStyleTop, aVector, basegfx::B2DVector(aTopLeft - aTopRight), false);
+            }
+
+            if(rStyleBottom.IsUsed())
+            {
+                aEndStyleVectorTable.add(rStyleBottom, -aVector, basegfx::B2DVector(aBottomLeft - aBottomRight), false);
+            }
+
+            CreateBorderPrimitives(
+                rBorderLineTarget,
+                aTopRight,
+                aVector,
+                rStyleRight,
+                aStartStyleVectorTable,
+                aEndStyleVectorTable,
+                nullptr);
+        }
+
+        if(rStyleBottom.IsUsed())
+        {
+            // create BorderPrimitive(s) for bottom border
+            const basegfx::B2DVector aVector(aBottomLeft - aBottomRight);
+            svx::frame::StyleVectorTable aStartStyleVectorTable;
+            svx::frame::StyleVectorTable aEndStyleVectorTable;
+
+            if(rStyleRight.IsUsed())
+            {
+                aStartStyleVectorTable.add(rStyleRight, aVector, basegfx::B2DVector(aTopRight - aBottomRight), false);
+            }
+
+            if(rStyleLeft.IsUsed())
+            {
+                aEndStyleVectorTable.add(rStyleLeft, -aVector, basegfx::B2DVector(aTopLeft - aBottomLeft), false);
+            }
+
+            CreateBorderPrimitives(
+                rBorderLineTarget,
+                aBottomRight,
+                aVector,
+                rStyleBottom,
+                aStartStyleVectorTable,
+                aEndStyleVectorTable,
+                nullptr);
+        }
+
+        if(rStyleLeft.IsUsed())
+        {
+            // create BorderPrimitive(s) for left border
+            const basegfx::B2DVector aVector(aTopLeft - aBottomLeft);
+            svx::frame::StyleVectorTable aStartStyleVectorTable;
+            svx::frame::StyleVectorTable aEndStyleVectorTable;
+
+            if(rStyleBottom.IsUsed())
+            {
+                aStartStyleVectorTable.add(rStyleBottom, aVector, basegfx::B2DVector(aBottomRight - aBottomLeft), false);
+            }
+
+            if(rStyleTop.IsUsed())
+            {
+                aEndStyleVectorTable.add(rStyleTop, -aVector, basegfx::B2DVector(aTopRight - aTopLeft), false);
+            }
+
+            CreateBorderPrimitives(
+                rBorderLineTarget,
+                aBottomLeft,
+                aVector,
+                rStyleLeft,
+                aStartStyleVectorTable,
+                aEndStyleVectorTable,
+                nullptr);
+        }
+    }
+} // end of anonymous namespace
 
 void PaintCharacterBorder(
     const SwFont& rFont,
@@ -4800,98 +4831,21 @@ void PaintCharacterBorder(
         }
     }
 
-    // Init borders, after this initialization top, bottom, right and left means the
-    // absolute position
-    boost::optional<editeng::SvxBorderLine> aTopBorder =
-        (bTop ? rFont.GetAbsTopBorder(bVerticalLayout) : boost::none);
-    boost::optional<editeng::SvxBorderLine> aBottomBorder =
-        (bBottom ? rFont.GetAbsBottomBorder(bVerticalLayout) : boost::none);
-    boost::optional<editeng::SvxBorderLine> aLeftBorder =
-        (bLeft ? rFont.GetAbsLeftBorder(bVerticalLayout) : boost::none);
-    boost::optional<editeng::SvxBorderLine> aRightBorder =
-        (bRight ? rFont.GetAbsRightBorder(bVerticalLayout) : boost::none);
-
-    if( aTopBorder )
-    {
-        const sal_uInt16 nOffset = aTopBorder->GetDistance();
-
-        Point aLeftTop(
-            aAlignedRect.Left() - nOffset,
-            aAlignedRect.Top() - nOffset);
-        Point aRightBottom(
-            aAlignedRect.Right() + nOffset,
-            aAlignedRect.Top() - nOffset + aTopBorder->GetScaledWidth());
-
-        lcl_MakeBorderLine(
-            SwRect(aLeftTop, aRightBottom),
-            false, true, false,
-            aTopBorder.get(),
-            aLeftBorder.get_ptr(),
-            aRightBorder.get_ptr(),
-            gProp);
-    }
-
-    if( aBottomBorder )
-    {
-        if( aBottomBorder->isDouble() )
-            aBottomBorder->SetMirrorWidths();
-
-        Point aLeftTop(
-            aAlignedRect.Left(),
-            aAlignedRect.Bottom() - aBottomBorder.get().GetScaledWidth());
-        Point aRightBottom(
-            aAlignedRect.Right(),
-            aAlignedRect.Bottom());
-
-        lcl_MakeBorderLine(
-            SwRect(aLeftTop, aRightBottom),
-            false, false, false,
-            aBottomBorder.get(),
-            aLeftBorder.get_ptr(),
-            aRightBorder.get_ptr(),
-            gProp );
-    }
-
-    if( aLeftBorder )
-    {
-        const sal_uInt16 nOffset = aLeftBorder->GetDistance();
-
-        Point aLeftTop(
-            aAlignedRect.Left() - nOffset,
-            aAlignedRect.Top() - nOffset);
-        Point aRightBottom(
-            aAlignedRect.Left() - nOffset + aLeftBorder->GetScaledWidth(),
-            aAlignedRect.Bottom() + nOffset);
-
-        lcl_MakeBorderLine(
-            SwRect(aLeftTop, aRightBottom),
-            true, true, true,
-            aLeftBorder.get(),
-            aTopBorder.get_ptr(),
-            aBottomBorder.get_ptr(),
-            gProp );
-    }
-
-    if( aRightBorder )
-    {
-        if( aRightBorder->isDouble() )
-            aRightBorder->SetMirrorWidths();
-
-        Point aLeftTop(
-            aAlignedRect.Right() - aRightBorder.get().GetScaledWidth(),
-            aAlignedRect.Top());
-        Point aRightBottom(
-            aAlignedRect.Right(),
-            aAlignedRect.Bottom());
+    drawinglayer::primitive2d::Primitive2DContainer aBorderLineTarget;
+    CreateBorderLinePrimitivesForRectangle(
+        aBorderLineTarget,
+        svx::frame::Style(bTop ? rFont.GetAbsTopBorder(bVerticalLayout).get_ptr() : nullptr, 1.0),
+        svx::frame::Style(bRight ? rFont.GetAbsRightBorder(bVerticalLayout).get_ptr() : nullptr, 1.0),
+        svx::frame::Style(bBottom ? rFont.GetAbsBottomBorder(bVerticalLayout).get_ptr() : nullptr, 1.0),
+        svx::frame::Style(bLeft ? rFont.GetAbsLeftBorder(bVerticalLayout).get_ptr() : nullptr, 1.0),
+        basegfx::B2DPoint(aAlignedRect.Left(), aAlignedRect.Top()),
+        basegfx::B2DPoint(aAlignedRect.Right(), aAlignedRect.Top()),
+        basegfx::B2DPoint(aAlignedRect.Left(), aAlignedRect.Bottom()),
+        basegfx::B2DPoint(aAlignedRect.Right(), aAlignedRect.Bottom()));
 
-        lcl_MakeBorderLine(
-            SwRect(aLeftTop, aRightBottom),
-            true, false, true,
-            aRightBorder.get(),
-            aTopBorder.get_ptr(),
-            aBottomBorder.get_ptr(),
-            gProp );
-    }
+    // no need to use AddBorderLine and try to merge BorderLinePrimitives, in this combination
+    // tis cannot happen
+    gProp.pBLines->AddBorderLines(aBorderLineTarget);
 }
 
 /// #i15844#
@@ -5103,162 +5057,11 @@ void SwFrame::ProcessPrimitives( const drawinglayer::primitive2d::Primitive2DCon
     }
 }
 
-namespace
-{
-    void CreateBorderLinePrimitivesForRectangle(
-        drawinglayer::primitive2d::Primitive2DContainer& rBorderLineTarget,
-        const svx::frame::Style& rStyleLeft,
-        const svx::frame::Style& rStyleRight,
-        const svx::frame::Style& rStyleTop,
-        const svx::frame::Style& rStyleBottom,
-        basegfx::B2DPoint aTopLeft,
-        basegfx::B2DPoint aTopRight,
-        basegfx::B2DPoint aBottomLeft,
-        basegfx::B2DPoint aBottomRight)
-    {
-        if(rStyleTop.IsUsed())
-        {
-            // move top left/right inwards half border width
-            aTopLeft.setY(aTopLeft.getY() + (rStyleTop.GetWidth() * 0.5));
-            aTopRight.setY(aTopRight.getY() + (rStyleTop.GetWidth() * 0.5));
-        }
-
-        if(rStyleBottom.IsUsed())
-        {
-            // move bottom left/right inwards half border width
-            aBottomLeft.setY(aBottomLeft.getY() - (rStyleBottom.GetWidth() * 0.5));
-            aBottomRight.setY(aBottomRight.getY() - (rStyleBottom.GetWidth() * 0.5));
-        }
-
-        if(rStyleLeft.IsUsed())
-        {
-            // move left top/bottom inwards half border width
-            aTopLeft.setX(aTopLeft.getX() + (rStyleLeft.GetWidth() * 0.5));
-            aBottomLeft.setX(aBottomLeft.getX() + (rStyleLeft.GetWidth() * 0.5));
-        }
-
-        if(rStyleRight.IsUsed())
-        {
-            // move right top/bottom inwards half border width
-            aTopRight.setX(aTopRight.getX() - (rStyleRight.GetWidth() * 0.5));
-            aBottomRight.setX(aBottomRight.getX() - (rStyleRight.GetWidth() * 0.5));
-        }
-
-        if(rStyleTop.IsUsed())
-        {
-            // create BorderPrimitive(s) for top border
-            const basegfx::B2DVector aVector(aTopRight - aTopLeft);
-            svx::frame::StyleVectorTable aStartStyleVectorTable;
-            svx::frame::StyleVectorTable aEndStyleVectorTable;
-
-            if(rStyleLeft.IsUsed())
-            {
-                aStartStyleVectorTable.add(rStyleLeft, aVector, basegfx::B2DVector(aBottomLeft - aTopLeft), false);
-            }
-
-            if(rStyleRight.IsUsed())
-            {
-                aEndStyleVectorTable.add(rStyleRight, -aVector, basegfx::B2DVector(aBottomRight - aTopRight), false);
-            }
-
-            CreateBorderPrimitives(
-                rBorderLineTarget,
-                aTopLeft,
-                aVector,
-                rStyleTop,
-                aStartStyleVectorTable,
-                aEndStyleVectorTable,
-                nullptr);
-        }
-
-        if(rStyleBottom.IsUsed())
-        {
-            // create BorderPrimitive(s) for bottom border
-            const basegfx::B2DVector aVector(aBottomRight - aBottomLeft);
-            svx::frame::StyleVectorTable aStartStyleVectorTable;
-            svx::frame::StyleVectorTable aEndStyleVectorTable;
-
-            if(rStyleLeft.IsUsed())
-            {
-                aStartStyleVectorTable.add(rStyleLeft, aVector, basegfx::B2DVector(aTopLeft - aBottomLeft), true);
-            }
-
-            if(rStyleRight.IsUsed())
-            {
-                aEndStyleVectorTable.add(rStyleRight, -aVector, basegfx::B2DVector(aTopRight - aBottomRight), true);
-            }
-
-            CreateBorderPrimitives(
-                rBorderLineTarget,
-                aBottomLeft,
-                aVector,
-                rStyleBottom,
-                aStartStyleVectorTable,
-                aEndStyleVectorTable,
-                nullptr);
-        }
-
-        if(rStyleLeft.IsUsed())
-        {
-            // create BorderPrimitive(s) for left border
-            const basegfx::B2DVector aVector(aBottomLeft - aTopLeft);
-            svx::frame::StyleVectorTable aStartStyleVectorTable;
-            svx::frame::StyleVectorTable aEndStyleVectorTable;
-
-            if(rStyleTop.IsUsed())
-            {
-                aStartStyleVectorTable.add(rStyleTop, aVector, basegfx::B2DVector(aTopRight - aTopLeft), false);
-            }
-
-            if(rStyleBottom.IsUsed())
-            {
-                aEndStyleVectorTable.add(rStyleBottom, -aVector, basegfx::B2DVector(aBottomRight - aBottomLeft), false);
-            }
-
-            CreateBorderPrimitives(
-                rBorderLineTarget,
-                aTopLeft,
-                aVector,
-                rStyleLeft,
-                aStartStyleVectorTable,
-                aEndStyleVectorTable,
-                nullptr);
-        }
-
-        if(rStyleRight.IsUsed())
-        {
-            // create BorderPrimitive(s) for right border
-            const basegfx::B2DVector aVector(aBottomRight - aTopRight);
-            svx::frame::StyleVectorTable aStartStyleVectorTable;
-            svx::frame::StyleVectorTable aEndStyleVectorTable;
-
-            if(rStyleTop.IsUsed())
-            {
-                aStartStyleVectorTable.add(rStyleTop, aVector, basegfx::B2DVector(aTopLeft - aTopRight), true);
-            }
-
-            if(rStyleBottom.IsUsed())
-            {
-                aEndStyleVectorTable.add(rStyleBottom, -aVector, basegfx::B2DVector(aBottomLeft - aBottomRight), true);
-            }
-
-            CreateBorderPrimitives(
-                rBorderLineTarget,
-                aTopRight,
-                aVector,
-                rStyleRight,
-                aStartStyleVectorTable,
-                aEndStyleVectorTable,
-                nullptr);
-        }
-    }
-} // end of anonymous namespace
-
 /// Paints shadows and borders
 void SwFrame::PaintSwFrameShadowAndBorder(
     const SwRect& rRect,
-    const SwPageFrame *pPage,
-    const SwBorderAttrs &rAttrs) const
+    const SwPageFrame* /*pPage*/,
+    const SwBorderAttrs& rAttrs) const
 {
     // There's nothing (Row,Body,Footnote,Root,Column,NoText) need to do here
     if (GetType() & (SwFrameType::NoTxt|SwFrameType::Row|SwFrameType::Body|SwFrameType::Ftn|SwFrameType::Column|SwFrameType::Root))
@@ -5396,32 +5199,22 @@ void SwFrame::PaintSwFrameShadowAndBorder(
         if(nullptr != pLeftBorder || nullptr != pRightBorder || nullptr != pTopBorder || nullptr != pBottomBorder)
         {
             // now we have all SvxBorderLine(s) sorted out, create geometry
-            const svx::frame::Style aStyleLeft(pLeftBorder, 1.0);
-            const svx::frame::Style aStyleRight(pRightBorder, 1.0);
-            const svx::frame::Style aStyleTop(pTopBorder, 1.0);
-            const svx::frame::Style aStyleBottom(pBottomBorder, 1.0);
             drawinglayer::primitive2d::Primitive2DContainer aBorderLineTarget;
 
             CreateBorderLinePrimitivesForRectangle(
                 aBorderLineTarget,
-                aStyleLeft,
-                aStyleRight,
-                aStyleTop,
-                aStyleBottom,
+                svx::frame::Style(pTopBorder, 1.0),
+                svx::frame::Style(pRightBorder, 1.0),
+                svx::frame::Style(pBottomBorder, 1.0),
+                svx::frame::Style(pLeftBorder, 1.0),
                 basegfx::B2DPoint(aRect.Left(), aRect.Top()),       // TopLeft
                 basegfx::B2DPoint(aRect.Right(), aRect.Top()),      // TopRight
                 basegfx::B2DPoint(aRect.Left(), aRect.Bottom()),    // BottomLeft
                 basegfx::B2DPoint(aRect.Right(), aRect.Bottom()));  // BottomRight
 
-            if(!aBorderLineTarget.empty())
-            {
-                for(drawinglayer::primitive2d::Primitive2DContainer::const_iterator it(aBorderLineTarget.begin()); it != aBorderLineTarget.end(); ++it)
-                {
-                    gProp.pBLines->AddBorderLine(*it);
-                }
-            }
-
-            bool bBla = true;
+            // no need to use AddBorderLine and try to merge BorderLinePrimitives, in this combination
+            // tis cannot happen
+            gProp.pBLines->AddBorderLines(aBorderLineTarget);
         }
     }
 
@@ -5434,8 +5227,10 @@ void SwFrame::PaintSwFrameShadowAndBorder(
  * Currently only the top frame needs to be taken into account
  * Other lines and shadows are set aside
  */
-void SwFootnoteContFrame::PaintSwFrameShadowAndBorder( const SwRect& rRect, const SwPageFrame *pPage,
-                                const SwBorderAttrs & ) const
+void SwFootnoteContFrame::PaintSwFrameShadowAndBorder(
+    const SwRect& rRect,
+    const SwPageFrame* pPage,
+    const SwBorderAttrs&) const
 {
     //If the rectangle is completely inside the PrtArea, no border needs to
     //be painted.
@@ -6325,9 +6120,13 @@ void SwFrame::PaintBaBo( const SwRect& rRect, const SwPageFrame *pPage,
     if (!bOnlyTextBackground)
     {
         SwRect aRect( rRect );
+
         if( IsPageFrame() )
+        {
             static_cast<const SwPageFrame*>(this)->PaintGrid( pOut, aRect );
-        PaintSwFrameShadowAndBorder( aRect, pPage, rAttrs );
+        }
+
+        PaintSwFrameShadowAndBorder(aRect, pPage, rAttrs);
     }
 
     pOut->Pop();
commit 386aae1723aabd42a9903016e1f44c85c078740c
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Fri Dec 1 16:08:10 2017 +0100

    SwFrameBorder: Replaced BorderGeometry creation partially
    
    Replaced BorderGeometry creation in SwFrame::PaintSwFrameShadowAndBorder,
    moved to tooling method CreateBorderLinePrimitivesForRectangle. Preparing
    using that tooling method also in PaintCharacterBorder to make borders
    work in TextPassages, too
    
    Change-Id: I73fe3d04597bd0e6dc83ac719548a44d0637b622

diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index ad733b8ab63e..882c9a48fc9d 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -4752,143 +4752,6 @@ static void lcl_MakeBorderLine(SwRect const& rRect,
     properties.pBLines->AddBorderLine(aLine);
 }
 
-/**
- * OD 19.05.2003 #109667# - merge <lcl_PaintLeftLine> and <lcl_PaintRightLine>
- * into new method <lcl_PaintLeftRightLine(..)>
- */
-static void lcl_PaintLeftRightLine( const bool         _bLeft,
-                             const SwFrame&           _rFrame,
-                             const SwRect&          _rOutRect,
-                             const SwBorderAttrs&   _rAttrs,
-                             const SwRectFn&        _rRectFn,
-                             SwPaintProperties& properties)
-{
-    const SvxBoxItem& rBox = _rAttrs.GetBox();
-    const bool bR2L = _rFrame.IsCellFrame() && _rFrame.IsRightToLeft();
-    const SvxBorderLine* pLeftRightBorder = nullptr;
-    const SvxBorderLine* pTopBorder = rBox.GetTop();
-    const SvxBorderLine* pBottomBorder = rBox.GetBottom();
-
-    if ( _bLeft )
-    {
-        pLeftRightBorder = bR2L ? rBox.GetRight() : rBox.GetLeft();
-    }
-    else
-    {
-        pLeftRightBorder = bR2L ? rBox.GetLeft() : rBox.GetRight();
-    }
-
-    if ( !pLeftRightBorder )
-    {
-        return;
-    }
-
-    SwRect aRect( _rOutRect );
-    if ( _bLeft )
-    {
-        (aRect.*_rRectFn->fnAddRight)( ::lcl_AlignWidth( lcl_GetLineWidth( pLeftRightBorder ), properties ) -
-                                       (aRect.*_rRectFn->fnGetWidth)() );
-
-        // Shift the left border to the left.
-        Point aCurPos = aRect.Pos();
-        const sal_uInt16 nOffset = pLeftRightBorder->GetDistance();
-        aCurPos.X() -= nOffset;
-        aCurPos.Y() -= nOffset;
-        aRect.Pos(aCurPos);
-        Size aCurSize = aRect.SSize();
-        aCurSize.Height() += nOffset * 2;
-        aRect.SSize(aCurSize);
-    }
-    else
-    {
-        (aRect.*_rRectFn->fnSubLeft)( ::lcl_AlignWidth( lcl_GetLineWidth( pLeftRightBorder ), properties ) -
-                                      (aRect.*_rRectFn->fnGetWidth)() );
-    }
-
-    if ( _rFrame.IsContentFrame() )
-    {
-        ::lcl_ExtendLeftAndRight( aRect, _rFrame, _rAttrs, _rRectFn );
-
-        // No Top / bottom borders for joint borders
-        if ( _rAttrs.JoinedWithPrev( _rFrame ) ) pTopBorder = nullptr;
-        if ( _rAttrs.JoinedWithNext( _rFrame ) ) pBottomBorder = nullptr;
-    }
-
-    if ( !pLeftRightBorder->GetInWidth() )
-    {
-        // OD 06.05.2003 #107169# - init boolean indicating printer output device.
-        const bool bPrtOutputDev =
-                ( OUTDEV_PRINTER == properties.pSGlobalShell->GetOut()->GetOutDevType() );
-
-        // OD 06.05.2003 #107169# - add 6th parameter
-        ::lcl_SubTopBottom( aRect, rBox, _rAttrs, _rFrame, _rRectFn, bPrtOutputDev, properties);
-    }
-
-    if ( lcl_GetLineWidth( pLeftRightBorder ) > 0 )
-    {
-        lcl_MakeBorderLine(
-            aRect, true, _bLeft, aRect.Height() > aRect.Width(),
-            *pLeftRightBorder, pTopBorder, pBottomBorder, properties);
-    }
-}
-
-/**
- * OD 19.05.2003 #109667# - merge <lcl_PaintTopLine> and <lcl_PaintBottomLine>
- * into <lcl_PaintTopLine>
- */
-static void lcl_PaintTopBottomLine( const bool         _bTop,
-                             const SwRect&          _rOutRect,
-                             const SwBorderAttrs&   _rAttrs,
-                             const SwRectFn&        _rRectFn,
-                             SwPaintProperties& properties)
-{
-    const SvxBoxItem& rBox = _rAttrs.GetBox();
-    const SvxBorderLine* pTopBottomBorder = nullptr;
-
-    if ( _bTop )
-    {
-        pTopBottomBorder = rBox.GetTop();
-    }
-    else
-    {
-        pTopBottomBorder = rBox.GetBottom();
-    }
-
-    if ( !pTopBottomBorder )
-    {
-        return;
-    }
-
-    SwRect aRect( _rOutRect );
-    if ( _bTop )
-    {
-        (aRect.*_rRectFn->fnAddBottom)( ::lcl_AlignHeight( lcl_GetLineWidth( pTopBottomBorder ), properties ) -
-                                        (aRect.*_rRectFn->fnGetHeight)() );
-
-        // Push the top border up a bit.
-        const sal_uInt16 nOffset = pTopBottomBorder->GetDistance();
-        Point aCurPos = aRect.Pos();
-        aCurPos.X() -= nOffset;
-        aCurPos.Y() -= nOffset;
-        aRect.Pos(aCurPos);
-        Size aCurSize = aRect.SSize();
-        aCurSize.Width() += nOffset * 2;
-        aRect.SSize(aCurSize);
-    }
-    else
-    {
-        (aRect.*_rRectFn->fnSubTop)( ::lcl_AlignHeight( lcl_GetLineWidth( pTopBottomBorder ), properties ) -
-                                     (aRect.*_rRectFn->fnGetHeight)() );
-    }
-
-    if ( lcl_GetLineWidth( pTopBottomBorder ) > 0 )
-    {
-        lcl_MakeBorderLine(
-            aRect, false, _bTop, aRect.Height() > aRect.Width(),
-            *pTopBottomBorder, rBox.GetLeft(), rBox.GetRight(), properties);
-    }
-}
-
 void PaintCharacterBorder(
     const SwFont& rFont,
     const SwRect& rPaintArea,
@@ -5240,9 +5103,162 @@ void SwFrame::ProcessPrimitives( const drawinglayer::primitive2d::Primitive2DCon
     }
 }
 
+namespace
+{
+    void CreateBorderLinePrimitivesForRectangle(
+        drawinglayer::primitive2d::Primitive2DContainer& rBorderLineTarget,
+        const svx::frame::Style& rStyleLeft,
+        const svx::frame::Style& rStyleRight,
+        const svx::frame::Style& rStyleTop,
+        const svx::frame::Style& rStyleBottom,
+        basegfx::B2DPoint aTopLeft,
+        basegfx::B2DPoint aTopRight,
+        basegfx::B2DPoint aBottomLeft,
+        basegfx::B2DPoint aBottomRight)
+    {
+        if(rStyleTop.IsUsed())
+        {
+            // move top left/right inwards half border width
+            aTopLeft.setY(aTopLeft.getY() + (rStyleTop.GetWidth() * 0.5));
+            aTopRight.setY(aTopRight.getY() + (rStyleTop.GetWidth() * 0.5));
+        }
+
+        if(rStyleBottom.IsUsed())
+        {
+            // move bottom left/right inwards half border width
+            aBottomLeft.setY(aBottomLeft.getY() - (rStyleBottom.GetWidth() * 0.5));
+            aBottomRight.setY(aBottomRight.getY() - (rStyleBottom.GetWidth() * 0.5));
+        }
+
+        if(rStyleLeft.IsUsed())
+        {
+            // move left top/bottom inwards half border width
+            aTopLeft.setX(aTopLeft.getX() + (rStyleLeft.GetWidth() * 0.5));
+            aBottomLeft.setX(aBottomLeft.getX() + (rStyleLeft.GetWidth() * 0.5));
+        }
+
+        if(rStyleRight.IsUsed())
+        {
+            // move right top/bottom inwards half border width
+            aTopRight.setX(aTopRight.getX() - (rStyleRight.GetWidth() * 0.5));
+            aBottomRight.setX(aBottomRight.getX() - (rStyleRight.GetWidth() * 0.5));
+        }
+
+        if(rStyleTop.IsUsed())
+        {
+            // create BorderPrimitive(s) for top border
+            const basegfx::B2DVector aVector(aTopRight - aTopLeft);
+            svx::frame::StyleVectorTable aStartStyleVectorTable;
+            svx::frame::StyleVectorTable aEndStyleVectorTable;
+
+            if(rStyleLeft.IsUsed())
+            {
+                aStartStyleVectorTable.add(rStyleLeft, aVector, basegfx::B2DVector(aBottomLeft - aTopLeft), false);
+            }
+
+            if(rStyleRight.IsUsed())
+            {
+                aEndStyleVectorTable.add(rStyleRight, -aVector, basegfx::B2DVector(aBottomRight - aTopRight), false);
+            }
+
+            CreateBorderPrimitives(
+                rBorderLineTarget,
+                aTopLeft,
+                aVector,
+                rStyleTop,
+                aStartStyleVectorTable,
+                aEndStyleVectorTable,
+                nullptr);
+        }
+
+        if(rStyleBottom.IsUsed())
+        {
+            // create BorderPrimitive(s) for bottom border
+            const basegfx::B2DVector aVector(aBottomRight - aBottomLeft);
+            svx::frame::StyleVectorTable aStartStyleVectorTable;
+            svx::frame::StyleVectorTable aEndStyleVectorTable;
+
+            if(rStyleLeft.IsUsed())
+            {
+                aStartStyleVectorTable.add(rStyleLeft, aVector, basegfx::B2DVector(aTopLeft - aBottomLeft), true);
+            }
+
+            if(rStyleRight.IsUsed())
+            {
+                aEndStyleVectorTable.add(rStyleRight, -aVector, basegfx::B2DVector(aTopRight - aBottomRight), true);
+            }
+
+            CreateBorderPrimitives(
+                rBorderLineTarget,
+                aBottomLeft,
+                aVector,
+                rStyleBottom,
+                aStartStyleVectorTable,
+                aEndStyleVectorTable,
+                nullptr);
+        }
+
+        if(rStyleLeft.IsUsed())
+        {
+            // create BorderPrimitive(s) for left border
+            const basegfx::B2DVector aVector(aBottomLeft - aTopLeft);
+            svx::frame::StyleVectorTable aStartStyleVectorTable;
+            svx::frame::StyleVectorTable aEndStyleVectorTable;
+
+            if(rStyleTop.IsUsed())
+            {
+                aStartStyleVectorTable.add(rStyleTop, aVector, basegfx::B2DVector(aTopRight - aTopLeft), false);
+            }
+
+            if(rStyleBottom.IsUsed())
+            {
+                aEndStyleVectorTable.add(rStyleBottom, -aVector, basegfx::B2DVector(aBottomRight - aBottomLeft), false);
+            }
+
+            CreateBorderPrimitives(
+                rBorderLineTarget,
+                aTopLeft,
+                aVector,
+                rStyleLeft,
+                aStartStyleVectorTable,
+                aEndStyleVectorTable,
+                nullptr);
+        }
+
+        if(rStyleRight.IsUsed())
+        {
+            // create BorderPrimitive(s) for right border
+            const basegfx::B2DVector aVector(aBottomRight - aTopRight);
+            svx::frame::StyleVectorTable aStartStyleVectorTable;
+            svx::frame::StyleVectorTable aEndStyleVectorTable;
+
+            if(rStyleTop.IsUsed())
+            {
+                aStartStyleVectorTable.add(rStyleTop, aVector, basegfx::B2DVector(aTopLeft - aTopRight), true);
+            }
+
+            if(rStyleBottom.IsUsed())
+            {
+                aEndStyleVectorTable.add(rStyleBottom, -aVector, basegfx::B2DVector(aBottomLeft - aBottomRight), true);
+            }
+
+            CreateBorderPrimitives(
+                rBorderLineTarget,
+                aTopRight,
+                aVector,
+                rStyleRight,
+                aStartStyleVectorTable,
+                aEndStyleVectorTable,
+                nullptr);
+        }
+    }
+} // end of anonymous namespace
+
 /// Paints shadows and borders
-void SwFrame::PaintSwFrameShadowAndBorder( const SwRect& rRect, const SwPageFrame *pPage,
-                         const SwBorderAttrs &rAttrs ) const
+void SwFrame::PaintSwFrameShadowAndBorder(
+    const SwRect& rRect,
+    const SwPageFrame *pPage,
+    const SwBorderAttrs &rAttrs) const
 {
     // There's nothing (Row,Body,Footnote,Root,Column,NoText) need to do here
     if (GetType() & (SwFrameType::NoTxt|SwFrameType::Row|SwFrameType::Body|SwFrameType::Ftn|SwFrameType::Column|SwFrameType::Root))
@@ -5320,61 +5336,96 @@ void SwFrame::PaintSwFrameShadowAndBorder( const SwRect& rRect, const SwPageFram
         }
     }
 
-    if ( !pPage )
-        pPage = FindPageFrame();
-
     ::lcl_CalcBorderRect( aRect, this, rAttrs, true, gProp );
     rAttrs.SetGetCacheLine( true );
-    if ( bShadow )
-        PaintShadow( rRect, aRect, rAttrs );
+
+    if(bShadow)
+    {
+        PaintShadow(rRect, aRect, rAttrs);
+    }
+
     // OD 27.09.2002 #103636# - suspend drawing of border
     // add condition < NOT bDrawOnlyShadowForTransparentFrame > - see above
     // - add condition <bFoundCellForTopOrBorderAttrs>
     //-hack.
-    if ( ( bLine || bFoundCellForTopOrBorderAttrs ) &&
-         !bDrawOnlyShadowForTransparentFrame )
-    {
-        const SwFrame* pDirRefFrame = IsCellFrame() ? FindTabFrame() : this;
-        SwRectFnSet aRectFnSet(pDirRefFrame);
-        ::lcl_PaintLeftRightLine ( true, *(this), aRect, rAttrs, aRectFnSet.FnRect(), gProp);
-        ::lcl_PaintLeftRightLine ( false, *(this), aRect, rAttrs, aRectFnSet.FnRect(), gProp);
-        if ( !IsContentFrame() || rAttrs.GetTopLine( *(this) ) )
-        {
-            // -
-            //-hack
-            // paint is found, paint its top border.
-            if ( IsCellFrame() && pCellFrameForTopBorderAttrs != this )
+    if((bLine || bFoundCellForTopOrBorderAttrs) && !bDrawOnlyShadowForTransparentFrame)
+    {
+        // define SvxBorderLine(s) to use
+        const SvxBoxItem& rBox(rAttrs.GetBox());
+        const SvxBorderLine* pLeftBorder(rBox.GetLeft());
+        const SvxBorderLine* pRightBorder(rBox.GetRight());
+        const SvxBorderLine* pTopBorder(rBox.GetTop());
+        const SvxBorderLine* pBottomBorder(rBox.GetBottom());
+
+        // if R2L, exchange Right/Left
+        const bool bR2L(IsCellFrame() && IsRightToLeft());
+
+        if(bR2L)
+        {
+            std::swap(pLeftBorder, pRightBorder);
+        }
+
+        // if ContentFrame and joined Prev/Next, reset top/bottom as needed
+        if(IsContentFrame())
+        {
+            if(rAttrs.JoinedWithPrev(*this))
             {
-                SwBorderAttrAccess aAccess( SwFrame::GetCache(),
-                                            pCellFrameForTopBorderAttrs );
-                const SwBorderAttrs &rTopAttrs = *aAccess.Get();
-                ::lcl_PaintTopBottomLine( true, aRect, rTopAttrs, aRectFnSet.FnRect(), gProp);
+                    pTopBorder = nullptr;
             }
-            else
+
+            if(rAttrs.JoinedWithNext(*this))
             {
-                ::lcl_PaintTopBottomLine( true, aRect, rAttrs, aRectFnSet.FnRect(), gProp );
+                    pBottomBorder = nullptr;
             }
         }
-        if ( !IsContentFrame() || rAttrs.GetBottomLine( *(this) ) )
+
+        // necessary to replace TopBorder?
+        if((!IsContentFrame() || rAttrs.GetTopLine(*this)) && IsCellFrame() && pCellFrameForTopBorderAttrs != this)
         {
-            // -
-            //-hack
-            // paint is found, paint its bottom border.
-            if ( IsCellFrame() && pCellFrameForBottomBorderAttrs != this )
-            {
-                SwBorderAttrAccess aAccess( SwFrame::GetCache(),
-                                            pCellFrameForBottomBorderAttrs );
-                const SwBorderAttrs &rBottomAttrs = *aAccess.Get();
-                ::lcl_PaintTopBottomLine(false, aRect, rBottomAttrs, aRectFnSet.FnRect(), gProp);
-            }
-            else
+            SwBorderAttrAccess aAccess(SwFrame::GetCache(), pCellFrameForTopBorderAttrs);
+            pTopBorder = aAccess.Get()->GetBox().GetTop();
+        }
+
+        // necessary to replace BottomBorder?
+        if((!IsContentFrame() || rAttrs.GetBottomLine(*this)) && IsCellFrame() && pCellFrameForBottomBorderAttrs != this)
+        {
+            SwBorderAttrAccess aAccess(SwFrame::GetCache(), pCellFrameForBottomBorderAttrs);
+            pBottomBorder = aAccess.Get()->GetBox().GetBottom();
+        }
+
+        if(nullptr != pLeftBorder || nullptr != pRightBorder || nullptr != pTopBorder || nullptr != pBottomBorder)
+        {
+            // now we have all SvxBorderLine(s) sorted out, create geometry
+            const svx::frame::Style aStyleLeft(pLeftBorder, 1.0);
+            const svx::frame::Style aStyleRight(pRightBorder, 1.0);
+            const svx::frame::Style aStyleTop(pTopBorder, 1.0);
+            const svx::frame::Style aStyleBottom(pBottomBorder, 1.0);
+            drawinglayer::primitive2d::Primitive2DContainer aBorderLineTarget;
+
+            CreateBorderLinePrimitivesForRectangle(
+                aBorderLineTarget,
+                aStyleLeft,
+                aStyleRight,
+                aStyleTop,
+                aStyleBottom,
+                basegfx::B2DPoint(aRect.Left(), aRect.Top()),       // TopLeft
+                basegfx::B2DPoint(aRect.Right(), aRect.Top()),      // TopRight
+                basegfx::B2DPoint(aRect.Left(), aRect.Bottom()),    // BottomLeft
+                basegfx::B2DPoint(aRect.Right(), aRect.Bottom()));  // BottomRight
+
+            if(!aBorderLineTarget.empty())
             {
-                ::lcl_PaintTopBottomLine(false, aRect, rAttrs, aRectFnSet.FnRect(), gProp);
+                for(drawinglayer::primitive2d::Primitive2DContainer::const_iterator it(aBorderLineTarget.begin()); it != aBorderLineTarget.end(); ++it)
+                {
+                    gProp.pBLines->AddBorderLine(*it);
+                }
             }
+
+            bool bBla = true;
         }
     }
-    rAttrs.SetGetCacheLine( false );
 
+    rAttrs.SetGetCacheLine( false );
 }
 
 /**
commit 59c5c769eb24d6b16147093c0026b175803a1629
Author: Armin Le Grand <Armin.Le.Grand at cib.de>
Date:   Thu Nov 30 17:13:12 2017 +0100

    SwFrameBorder: Removed IsInverse() from SwFrame
    
    IsInverse was always false and never set, elliminating it
    from SwFrame makes the code cleaner and reduces cases for
    SwRectFnSet from 5 to 3, making it also more understandable.
    Cleaned up all the code using it, ran all UnitTests, works
    well. In question, this single commit can be re-applied.
    
    Change-Id: If077c65a6dacd83de61d259cddbb3cd4c5e25a2f

diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index b1bbc0cc629b..aaff5532ee09 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -382,8 +382,6 @@ protected:
     SwFrameType mnFrameType;  //Who am I?
 
     bool mbInDtor      : 1;
-    bool mbReverse     : 1; // Next line above/at the right side instead
-                                 // under/at the left side of the previous line
     bool mbInvalidR2L  : 1;
     bool mbDerivedR2L  : 1;
     bool mbRightToLeft : 1;
@@ -583,9 +581,7 @@ public:
 
     bool IsInBalancedSection() const;
 
-    bool IsReverse() const { return mbReverse; }
     inline bool IsVertical() const;
-
     inline bool IsVertLR() const;
 
     void SetDerivedVert( bool bNew ){ mbDerivedVert = bNew; }
@@ -1291,31 +1287,24 @@ struct SwRectFnCollection
 typedef SwRectFnCollection* SwRectFn;
 
 // This class allows to use proper methods regardless of orientation (LTR/RTL, horizontal or vertical)
-extern SwRectFn fnRectHori, fnRectVert, fnRectB2T, fnRectVL2R, fnRectVertL2R;
+extern SwRectFn fnRectHori, fnRectVert, fnRectVertL2R;
 class SwRectFnSet {
 public:
     explicit SwRectFnSet(const SwFrame *pFrame)
         : m_bVert(pFrame->IsVertical())
-        , m_bRev(pFrame->IsReverse())
         , m_bVertL2R(pFrame->IsVertLR())
     {
-        m_fnRect = m_bVert ?
-            (m_bRev ? fnRectVL2R : (m_bVertL2R ? fnRectVertL2R : fnRectVert)) :
-            (m_bRev ? fnRectB2T : fnRectHori);
+        m_fnRect = m_bVert ? (m_bVertL2R ? fnRectVertL2R : fnRectVert) : fnRectHori;
     }
 
     void Refresh(const SwFrame *pFrame)
     {
         m_bVert = pFrame->IsVertical();
-        m_bRev = pFrame->IsReverse();
         m_bVertL2R = pFrame->IsVertLR();
-        m_fnRect = m_bVert ?
-            (m_bRev ? fnRectVL2R : (m_bVertL2R ? fnRectVertL2R : fnRectVert)) :
-            (m_bRev ? fnRectB2T : fnRectHori);
+        m_fnRect = m_bVert ? (m_bVertL2R ? fnRectVertL2R : fnRectVert) : fnRectHori;
     }
 
     bool IsVert() const    { return m_bVert; }
-    bool IsRev() const     { return m_bRev; }
     bool IsVertL2R() const { return m_bVertL2R; }
     SwRectFn FnRect() const { return m_fnRect; }
 
@@ -1380,7 +1369,6 @@ public:
 
 private:
     bool m_bVert;
-    bool m_bRev;
     bool m_bVertL2R;
     SwRectFn m_fnRect;
 };
diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx
index 00703c236c16..6057b2115b28 100644
--- a/sw/source/core/layout/calcmove.cxx
+++ b/sw/source/core/layout/calcmove.cxx
@@ -519,27 +519,20 @@ void SwFrame::MakePos()
                 }
 
                 // cells may now leave their uppers
-                if( aRectFnSet.IsVert() && SwFrameType::Cell & nMyType && !mbReverse )
+                if( aRectFnSet.IsVert() && SwFrameType::Cell & nMyType )
                 {
                     aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width() + pPrv->getFrameArea().Width());
                 }
             }
             else if( aRectFnSet.IsVert() && FRM_NOTE_VERT & nMyType )
             {
-                if( mbReverse )
+                if ( aRectFnSet.IsVertL2R() )
                 {
                     aFrm.Pos().setX(aFrm.Pos().getX() + pPrv->getFrameArea().Width());
                 }
                 else
                 {
-                    if ( aRectFnSet.IsVertL2R() )
-                    {
-                        aFrm.Pos().setX(aFrm.Pos().getX() + pPrv->getFrameArea().Width());
-                    }
-                    else
-                    {
-                        aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width());
-                    }
+                    aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width());
                 }
             }
             else
@@ -588,21 +581,14 @@ void SwFrame::MakePos()
                     }
 
                     // cells may now leave their uppers
-                    if( aRectFnSet.IsVert() && SwFrameType::Cell & nMyType && !mbReverse )
+                    if( aRectFnSet.IsVert() && SwFrameType::Cell & nMyType )
                     {
                         aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width() + pPrv->getFrameArea().Width());
                     }
                 }
                 else if( aRectFnSet.IsVert() && FRM_NOTE_VERT & nMyType )
                 {
-                    if( mbReverse )
-                    {
-                        aFrm.Pos().setX(aFrm.Pos().getX() + pPrv->getFrameArea().Width());
-                    }
-                    else
-                    {
-                        aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width());
-                    }
+                    aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width());
                 }
                 else
                 {
@@ -634,7 +620,7 @@ void SwFrame::MakePos()
                         aFrm.Pos().setX(aFrm.Pos().getX() + GetUpper()->getFramePrintArea().Width() - aFrm.Width());
                     }
                 }
-                else if( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() && FRM_NOTE_VERT & nMyType && !mbReverse )
+                else if( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() && FRM_NOTE_VERT & nMyType )
                 {
                     aFrm.Pos().setX(aFrm.Pos().getX() - aFrm.Width() + GetUpper()->getFramePrintArea().Width());
                 }
@@ -647,7 +633,7 @@ void SwFrame::MakePos()
             aFrm.Pos().setY(0);
         }
 
-        if( IsBodyFrame() && aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() && !mbReverse && GetUpper() )
+        if( IsBodyFrame() && aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() && GetUpper() )
         {
             SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
             aFrm.Pos().setX(aFrm.Pos().getX() + GetUpper()->getFramePrintArea().Width() - aFrm.Width());
@@ -1138,7 +1124,7 @@ bool SwContentFrame::MakePrtArea( const SwBorderAttrs &rAttrs )
 
             {
                 SwFrameAreaDefinition::FramePrintAreaWriteAccess aPrt(*this);
-                aRectFnSet.SetPosY( aPrt, (!aRectFnSet.IsVert() || mbReverse) ? nUpper : nLower);
+                aRectFnSet.SetPosY( aPrt, !aRectFnSet.IsVert() ? nUpper : nLower);
             }
 
             nUpper += nLower;
diff --git a/sw/source/core/layout/findfrm.cxx b/sw/source/core/layout/findfrm.cxx
index 3a3607934481..73d4a86c0bce 100644
--- a/sw/source/core/layout/findfrm.cxx
+++ b/sw/source/core/layout/findfrm.cxx
@@ -1399,8 +1399,6 @@ void SwFrame::SetDirFlags( bool bVert )
             if( pAsk )
             {
                 mbVertical = pAsk->IsVertical();
-                mbReverse  = pAsk->IsReverse();
-
                 mbVertLR  = pAsk->IsVertLR();
 
                 if ( !pAsk->mbInvalidVert )
diff --git a/sw/source/core/layout/flyincnt.cxx b/sw/source/core/layout/flyincnt.cxx
index b8164d674a3d..af87a79ea1bd 100644
--- a/sw/source/core/layout/flyincnt.cxx
+++ b/sw/source/core/layout/flyincnt.cxx
@@ -36,7 +36,7 @@ SwFlyInContentFrame::SwFlyInContentFrame( SwFlyFrameFormat *pFormat, SwFrame* pS
     // OD 2004-05-27 #i26791# - member <aRelPos> moved to <SwAnchoredObject>
     Point aRelPos;
     if( pAnch && pAnch->IsVertical() )
-        aRelPos.setX(pAnch->IsReverse() ? nRel : -nRel);
+        aRelPos.setX(-nRel);
     else
         aRelPos.setY(nRel);
     SetCurrRelPos( aRelPos );
@@ -163,11 +163,8 @@ void SwFlyInContentFrame::MakeObjPos()
         //Update the current values in the format if needed, during this we of
         //course must not send any Modify.
         const bool bVert = GetAnchorFrame()->IsVertical();
-        const bool bRev = GetAnchorFrame()->IsReverse();
         SwTwips nOld = rVert.GetPos();
         SwTwips nAct = bVert ? -GetCurrRelPos().X() : GetCurrRelPos().Y();
-        if( bRev )
-            nAct = -nAct;
         if( nAct != nOld )
         {
             SwFormatVertOrient aVert( rVert );
diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx
index 23fd2a19c624..eb9212d3fff8 100644
--- a/sw/source/core/layout/ftnfrm.cxx
+++ b/sw/source/core/layout/ftnfrm.cxx
@@ -340,7 +340,7 @@ SwTwips SwFootnoteContFrame::GrowFrame( SwTwips nDist, bool bTst, bool )
         SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
         aRectFnSet.SetHeight( aFrm, aRectFnSet.GetHeight(aFrm) + nDist );
 
-        if( IsVertical() && !IsVertLR() && !IsReverse() )
+        if( IsVertical() && !IsVertLR() )
         {
             aFrm.Pos().X() -= nDist;
         }
@@ -387,7 +387,7 @@ SwTwips SwFootnoteContFrame::GrowFrame( SwTwips nDist, bool bTst, bool )
             SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
             aFrm.SSize().Height() -= nDist;
 
-            if( IsVertical() && !IsVertLR() && !IsReverse() )
+            if( IsVertical() && !IsVertLR() )
             {
                 aFrm.Pos().X() += nDist;
             }
diff --git a/sw/source/core/layout/newfrm.cxx b/sw/source/core/layout/newfrm.cxx
index 9adafe9ee72a..0c4af5d82def 100644
--- a/sw/source/core/layout/newfrm.cxx
+++ b/sw/source/core/layout/newfrm.cxx
@@ -167,116 +167,6 @@ static SwRectFnCollection aVertical = {
     /*.fnSetTopAndHeight =*/&SwRect::SetRightAndWidth
 };
 
-static SwRectFnCollection aBottomToTop = {
-    /*.fnGetTop =*/&SwRect::Bottom_,
-    /*.fnGetBottom =*/&SwRect::Top_,
-    /*.fnGetLeft =*/&SwRect::Left_,
-    /*.fnGetRight =*/&SwRect::Right_,
-    /*.fnGetWidth =*/&SwRect::Width_,
-    /*.fnGetHeight =*/&SwRect::Height_,
-    /*.fnGetPos =*/&SwRect::BottomLeft,
-    /*.fnGetSize =*/&SwRect::Size_,
-
-    /*.fnSetTop =*/&SwRect::Bottom_,
-    /*.fnSetBottom =*/&SwRect::Top_,
-    /*.fnSetLeft =*/&SwRect::Left_,
-    /*.fnSetRight =*/&SwRect::Right_,
-    /*.fnSetWidth =*/&SwRect::Width_,
-    /*.fnSetHeight =*/&SwRect::Height_,
-
-    /*.fnSubTop =*/&SwRect::AddBottom,
-    /*.fnAddBottom =*/&SwRect::SubTop,
-    /*.fnSubLeft =*/&SwRect::SubLeft,
-    /*.fnAddRight =*/&SwRect::AddRight,
-    /*.fnAddWidth =*/&SwRect::AddWidth,
-    /*.fnAddHeight =*/&SwRect::AddHeight,
-
-    /*.fnSetPosX =*/&SwRect::SetPosX,
-    /*.fnSetPosY =*/&SwRect::SetPosY,
-
-    /*.fnGetTopMargin =*/&SwFrame::GetBottomMargin,
-    /*.fnGetBottomMargin =*/&SwFrame::GetTopMargin,
-    /*.fnGetLeftMargin =*/&SwFrame::GetLeftMargin,
-    /*.fnGetRightMargin =*/&SwFrame::GetRightMargin,
-    /*.fnSetXMargins =*/&SwFrame::SetLeftRightMargins,
-    /*.fnSetYMargins =*/&SwFrame::SetBottomTopMargins,
-    /*.fnGetPrtTop =*/&SwFrame::GetPrtBottom,
-    /*.fnGetPrtBottom =*/&SwFrame::GetPrtTop,
-    /*.fnGetPrtLeft =*/&SwFrame::GetPrtLeft,
-    /*.fnGetPrtRight =*/&SwFrame::GetPrtRight,
-    /*.fnTopDist =*/&SwRect::GetBottomDistance,
-    /*.fnBottomDist =*/&SwRect::GetTopDistance,
-    /*.fnLeftDist =*/&SwRect::GetLeftDistance,
-    /*.fnRightDist =*/&SwRect::GetRightDistance,
-    /*.fnSetLimit =*/&SwFrame::SetMinTop,
-    /*.fnOverStep =*/&SwRect::OverStepTop,
-
-    /*.fnSetPos =*/&SwRect::SetLowerLeftCorner,
-    /*.fnMakePos =*/&SwFrame::MakeUpperPos,
-    /*.fnXDiff =*/&FirstMinusSecond,
-    /*.fnYDiff =*/&SecondMinusFirst,
-    /*.fnXInc =*/&SwIncrement,
-    /*.fnYInc =*/&SwDecrement,
-
-    /*.fnSetLeftAndWidth =*/&SwRect::SetLeftAndWidth,
-    /*.fnSetTopAndHeight =*/&SwRect::SetBottomAndHeight
-};
-
-static SwRectFnCollection aVerticalRightToLeft = {
-    /*.fnGetTop =*/&SwRect::Left_,
-    /*.fnGetBottom =*/&SwRect::Right_,
-    /*.fnGetLeft =*/&SwRect::Top_,
-    /*.fnGetRight =*/&SwRect::Bottom_,
-    /*.fnGetWidth =*/&SwRect::Height_,
-    /*.fnGetHeight =*/&SwRect::Width_,
-    /*.fnGetPos =*/&SwRect::BottomRight,
-    /*.fnGetSize =*/&SwRect::SwappedSize,
-
-    /*.fnSetTop =*/&SwRect::Left_,
-    /*.fnSetBottom =*/&SwRect::Right_,
-    /*.fnSetLeft =*/&SwRect::Top_,
-    /*.fnSetRight =*/&SwRect::Bottom_,
-    /*.fnSetWidth =*/&SwRect::Height_,
-    /*.fnSetHeight =*/&SwRect::Width_,
-
-    /*.fnSubTop =*/&SwRect::SubLeft,
-    /*.fnAddBottom =*/&SwRect::AddRight,
-    /*.fnSubLeft =*/&SwRect::SubTop,
-    /*.fnAddRight =*/&SwRect::AddBottom,
-    /*.fnAddWidth =*/&SwRect::AddHeight,
-    /*.fnAddHeight =*/&SwRect::AddWidth,
-
-    /*.fnSetPosX =*/&SwRect::SetPosY,
-    /*.fnSetPosY =*/&SwRect::SetPosX,
-
-    /*.fnGetTopMargin =*/&SwFrame::GetLeftMargin,
-    /*.fnGetBottomMargin =*/&SwFrame::GetRightMargin,
-    /*.fnGetLeftMargin =*/&SwFrame::GetTopMargin,
-    /*.fnGetRightMargin =*/&SwFrame::GetBottomMargin,
-    /*.fnSetXMargins =*/&SwFrame::SetTopBottomMargins,
-    /*.fnSetYMargins =*/&SwFrame::SetLeftRightMargins,
-    /*.fnGetPrtTop =*/&SwFrame::GetPrtLeft,
-    /*.fnGetPrtBottom =*/&SwFrame::GetPrtRight,
-    /*.fnGetPrtLeft =*/&SwFrame::GetPrtBottom,
-    /*.fnGetPrtRight =*/&SwFrame::GetPrtTop,
-    /*.fnTopDist =*/&SwRect::GetLeftDistance,
-    /*.fnBottomDist =*/&SwRect::GetRightDistance,
-    /*.fnLeftDist =*/&SwRect::GetBottomDistance,
-    /*.fnRightDist =*/&SwRect::GetTopDistance,
-    /*.fnSetLimit =*/&SwFrame::SetMaxRight,
-    /*.fnOverStep =*/&SwRect::OverStepRight,
-
-    /*.fnSetPos =*/&SwRect::SetLowerLeftCorner,
-    /*.fnMakePos =*/&SwFrame::MakeRightPos,
-    /*.fnXDiff =*/&FirstMinusSecond,
-    /*.fnYDiff =*/&FirstMinusSecond,
-    /*.fnXInc =*/&SwDecrement,
-    /*.fnYInc =*/&SwIncrement,
-
-    /*.fnSetLeftAndWidth =*/&SwRect::SetBottomAndHeight,
-    /*.fnSetTopAndHeight =*/&SwRect::SetLeftAndWidth
-};
-
 static SwRectFnCollection aVerticalLeftToRight = {
     /*.fnGetTop =*/&SwRect::Left_,
     /*.fnGetBottom =*/&SwRect::Right_,
@@ -334,12 +224,8 @@ static SwRectFnCollection aVerticalLeftToRight = {
 
 SwRectFn fnRectHori = &aHorizontal;
 SwRectFn fnRectVert = &aVertical;
-
 SwRectFn fnRectVertL2R = &aVerticalLeftToRight;
 
-SwRectFn fnRectB2T = &aBottomToTop;
-SwRectFn fnRectVL2R = &aVerticalRightToLeft;
-
 // #i65250#
 sal_uInt32 SwFrame::mnLastFrameId=0;
 
diff --git a/sw/source/core/layout/pagechg.cxx b/sw/source/core/layout/pagechg.cxx
index b35a5e1e1e40..68dfd632b5ec 100644
--- a/sw/source/core/layout/pagechg.cxx
+++ b/sw/source/core/layout/pagechg.cxx
@@ -99,7 +99,7 @@ void SwBodyFrame::Format( vcl::RenderContext* /*pRenderContext*/, const SwBorder
         SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
         aFrm.Height( nHeight );
 
-        if( IsVertical() && !IsVertLR() && !IsReverse() && nWidth != aFrm.Width() )
+        if( IsVertical() && !IsVertLR() && nWidth != aFrm.Width() )
         {
             aFrm.Pos().setX(aFrm.Pos().getX() + aFrm.Width() - nWidth);
         }
@@ -353,7 +353,6 @@ void SwPageFrame::CheckDirection( bool bVert )
             }
         }
 
-        mbReverse = false;
         mbInvalidVert = false;
     }
     else
diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx
index 2b6def165059..0e9e657933a8 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -1041,7 +1041,7 @@ void SwSectionFrame::CheckClipping( bool bGrow, bool bMaximize )
         if( nDiff > 0 )
         {
             long nAdd = GetUpper()->Grow( nDiff );
-            if( aRectFnSet.IsVert() && !aRectFnSet.IsRev() )
+            if( aRectFnSet.IsVert() )
                 nDeadLine -= nAdd;
             else
                 nDeadLine += nAdd;
diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
index ef7067aae000..0e4695dd2c56 100644
--- a/sw/source/core/layout/ssfrm.cxx
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -232,13 +232,12 @@ void SwFrame::SetRightLeftMargins( long nRight, long nLeft)
 void SwFrame::CheckDirChange()
 {
     bool bOldVert = mbVertical;
-    bool bOldRev = IsReverse();
     bool bOldR2L = mbRightToLeft;
     SetInvalidVert( true );
     mbInvalidR2L = true;
     bool bChg = bOldR2L != IsRightToLeft();
     bool bOldVertL2R = IsVertLR();
-    if( ( IsVertical() != bOldVert ) || bChg || IsReverse() != bOldRev || bOldVertL2R != IsVertLR() )
+    if( ( IsVertical() != bOldVert ) || bChg || bOldVertL2R != IsVertLR() )
     {
         InvalidateAll();
         if( IsLayoutFrame() )
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index 6a4654d7e5e8..0a8dd42e7079 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -4502,7 +4502,7 @@ SwTwips SwRowFrame::ShrinkFrame( SwTwips nDist, bool bTst, bool bInfo )
             SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
             aRectFnSet.SetHeight( aFrm, nHeight - nReal );
 
-            if( IsVertical() && !IsVertLR() && !aRectFnSet.IsRev() )
+            if( IsVertical() && !IsVertLR() )
             {
                 aFrm.Pos().X() += nReal;
             }
@@ -4521,7 +4521,7 @@ SwTwips SwRowFrame::ShrinkFrame( SwTwips nDist, bool bTst, bool bInfo )
                 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
                 aRectFnSet.SetHeight( aFrm, nHeight + nReal );
 
-                if( IsVertical() && !IsVertLR() && !aRectFnSet.IsRev() )
+                if( IsVertical() && !IsVertLR() )
                 {
                     aFrm.Pos().X() -= nReal;
                 }
diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx
index 01952039d9ee..f26626d7d746 100644
--- a/sw/source/core/layout/wsfrm.cxx
+++ b/sw/source/core/layout/wsfrm.cxx
@@ -300,7 +300,6 @@ SwFrame::SwFrame( SwModify *pMod, SwFrame* pSib )
     mpDrawObjs(nullptr),
     mnFrameType(SwFrameType::None),
     mbInDtor(false),
-    mbReverse(false),
     mbInvalidR2L(true),
     mbDerivedR2L(false),
     mbRightToLeft(false),
@@ -1787,7 +1786,7 @@ SwTwips SwFrame::AdjustNeighbourhood( SwTwips nDiff, bool bTst )
                         SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pFrame->GetNext());
                         aRectFnSet.SetHeight(aFrm, nAddMax-nAdd);
 
-                        if( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() && !aRectFnSet.IsRev() )
+                        if( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() )
                         {
                             aFrm.Pos().X() += nAdd;
                         }
@@ -1812,7 +1811,7 @@ SwTwips SwFrame::AdjustNeighbourhood( SwTwips nDiff, bool bTst )
             SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*pFrame);
             aRectFnSet.SetHeight( aFrm, nTmp - nReal );
 
-            if( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() && !aRectFnSet.IsRev() )
+            if( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() )
             {
                 aFrm.Pos().X() += nReal;
             }
@@ -2047,7 +2046,7 @@ SwTwips SwContentFrame::GrowFrame( SwTwips nDist, bool bTst, bool bInfo )
                 SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
                 aRectFnSet.SetHeight( aFrm, nFrameHeight + nDist );
 
-                if( IsVertical() && !IsVertLR() && !IsReverse() )
+                if( IsVertical() && !IsVertLR() )
                 {
                     aFrm.Pos().X() -= nDist;
                 }
@@ -2087,7 +2086,7 @@ SwTwips SwContentFrame::GrowFrame( SwTwips nDist, bool bTst, bool bInfo )
 
             aRectFnSet.SetHeight( aFrm, nOld + nDist );
 
-            if( IsVertical()&& !IsVertLR() && !IsReverse() )
+            if( IsVertical()&& !IsVertLR() )
             {
                 aFrm.Pos().X() -= nDist;
             }
@@ -2574,7 +2573,7 @@ SwTwips SwLayoutFrame::GrowFrame( SwTwips nDist, bool bTst, bool bInfo )
     SwRect aOldFrame( getFrameArea() );
     bool bMoveAccFrame = false;
 
-    bool bChgPos = IsVertical() && !IsReverse();
+    bool bChgPos = IsVertical();
     if ( !bTst )
     {
         SwFrameAreaDefinition::FrameAreaWriteAccess aFrm(*this);
@@ -2745,7 +2744,7 @@ SwTwips SwLayoutFrame::ShrinkFrame( SwTwips nDist, bool bTst, bool bInfo )
         nDist = nFrameHeight;
 
     SwTwips nMin = 0;
-    bool bChgPos = IsVertical() && !IsReverse();
+    bool bChgPos = IsVertical();
     if ( Lower() )
     {
         if( !Lower()->IsNeighbourFrame() )

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list