borderline: Simplified BorderLinePrimitive

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

Change-Id: Iac9d9ae64874fea38fd6e2a04221698481cc0d0e
diff --git a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
index a9822d6..724ba87 100644
--- a/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/borderlineprimitive2d.cxx
@@ -37,119 +37,136 @@ namespace drawinglayer
{
    namespace primitive2d
    {
        BorderLine::BorderLine(
            double fWidth,
            const basegfx::BColor& rRGBColor,
            double fExtendStart,
            double fExtendEnd)
        :   mfWidth(fWidth),
            maRGBColor(rRGBColor),
            mfExtendStart(fExtendStart),
            mfExtendEnd(fExtendEnd)
        {
        }

        bool BorderLine::operator==(const BorderLine& rBorderLine) const
        {
            return getWidth() == rBorderLine.getWidth()
                && getRGBColor() == rBorderLine.getRGBColor()
                && getExtendStart() == rBorderLine.getExtendStart()
                && getExtendEnd() == rBorderLine.getExtendEnd();
        }

        // helper to add a centered, maybe stroked line primitive to rContainer
        void addPolygonStrokePrimitive2D(
            Primitive2DContainer& rContainer,
            const basegfx::B2DPoint& rStart,
            const basegfx::B2DPoint& rEnd,
            const basegfx::BColor& rColor,
            double fWidth,
            SvxBorderLineStyle aStyle,
            double fPatternScale)
            const attribute::LineAttribute& rLineAttribute,
            const attribute::StrokeAttribute & rStrokeAttribute)
        {
            basegfx::B2DPolygon aPolygon;

            aPolygon.append(rStart);
            aPolygon.append(rEnd);

            const attribute::LineAttribute aLineAttribute(rColor, fWidth);
            static double fPatScFact(10.0); // 10.0 multiply, see old code
            const std::vector<double> aDashing(svtools::GetLineDashing(aStyle, fPatternScale * fPatScFact));

            if (aDashing.empty())
            if (rStrokeAttribute.isDefault())
            {
                rContainer.push_back(
                    new PolygonStrokePrimitive2D(
                        aPolygon,
                        aLineAttribute));
                        rLineAttribute));
            }
            else
            {
                const attribute::StrokeAttribute aStrokeAttribute(aDashing);

                rContainer.push_back(
                    new PolygonStrokePrimitive2D(
                        aPolygon,
                        aLineAttribute,
                        aStrokeAttribute));
                        rLineAttribute,
                        rStrokeAttribute));
            }
        }

        void BorderLinePrimitive2D::create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& /*rViewInformation*/) const
        {
            if (!getStart().equal(getEnd()) && (isInsideUsed() || isOutsideUsed()))
            if (!getStart().equal(getEnd()))
            {
                // get data and vectors
                basegfx::B2DVector aVector(getEnd() - getStart());
                aVector.normalize();
                const basegfx::B2DVector aPerpendicular(basegfx::getPerpendicular(aVector));
                static double fPatScFact(10.0); // 10.0 multiply, see old code
                const std::vector<double> aDashing(svtools::GetLineDashing(getStyle(), getPatternScale() * fPatScFact));
                const attribute::StrokeAttribute aStrokeAttribute(aDashing);

                if (isOutsideUsed() && isInsideUsed())
                if (3 == getBorderLines().size())
                {
                    // double line with gap. Use mfDiscreteDistance (see get2DDecomposition) as distance.
                    // double line with gap. Use mfDiscreteGapDistance (see get2DDecomposition) as distance.
                    // That value is prepared to be at least one pixel (discrete unit) so that the
                    // decomposition is view-dependent in this cases
                    if (isInsideUsed())
                    {
                        // inside line (left). Create stroke primitive centered on line width
                        const double fDeltaY((mfDiscreteDistance + getLeftWidth()) * 0.5);
                        // inside line (left of vector). Create stroke primitive centered on line width
                        const BorderLine& rLeft(getBorderLines()[0]);
                        const double fDeltaY((mfDiscreteGapDistance + rLeft.getWidth()) * 0.5);
                        const basegfx::B2DVector aDeltaY(aPerpendicular * fDeltaY);
                        const basegfx::B2DPoint aStart(getStart() - (aVector * getExtendLeftStart()) - aDeltaY);
                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * getExtendLeftEnd()) - aDeltaY);
                        const basegfx::B2DPoint aStart(getStart() - (aVector * rLeft.getExtendStart()) - aDeltaY);
                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * rLeft.getExtendEnd()) - aDeltaY);
                        const attribute::LineAttribute aLineAttribute(rLeft.getRGBColor(), rLeft.getWidth());

                        addPolygonStrokePrimitive2D(
                            rContainer,
                            aStart,
                            aEnd,
                            getRGBColorLeft(),
                            getLeftWidth(),
                            getStyle(),
                            getPatternScale());
                            aLineAttribute,
                            aStrokeAttribute);
                    }

                    if (hasGapColor() && isDistanceUsed())
                    if (hasGapColor())
                    {
                        // gap (if visible, found no practical usage).
                        // gap (if visible, found practical usage in Writer MultiColorBorderLines).
                        // Create stroke primitive on vector with given color
                        addPolygonStrokePrimitive2D(
                            rContainer,
                            getStart(),
                            getEnd(),
                            getRGBColorGap(),
                            mfDiscreteDistance,
                            getStyle(),
                            getPatternScale());
                    }

                    if (isOutsideUsed())
                    {
                        // outside line (right). Create stroke primitive centered on line width
                        const double fDeltaY((mfDiscreteDistance + getRightWidth()) * 0.5);
                        const basegfx::B2DVector aDeltaY(aPerpendicular * fDeltaY);
                        const basegfx::B2DPoint aStart(getStart() - (aVector * getExtendRightStart()) + aDeltaY);
                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * getExtendRightEnd()) + aDeltaY);
                        const BorderLine& rGap(getBorderLines()[1]);
                        const basegfx::B2DPoint aStart(getStart() - (aVector * rGap.getExtendStart()));
                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * rGap.getExtendEnd()));
                        const attribute::LineAttribute aLineAttribute(rGap.getRGBColor(), mfDiscreteGapDistance);

                        addPolygonStrokePrimitive2D(
                            rContainer,
                            aStart,
                            aEnd,
                            getRGBColorRight(),
                            getRightWidth(),
                            getStyle(),
                            getPatternScale());
                            aLineAttribute,
                            aStrokeAttribute);
                    }

                    {
                        // outside line (right of vector). Create stroke primitive centered on line width
                        const BorderLine& rRight(getBorderLines()[2]);
                        const double fDeltaY((mfDiscreteGapDistance + rRight.getWidth()) * 0.5);
                        const basegfx::B2DVector aDeltaY(aPerpendicular * fDeltaY);
                        const basegfx::B2DPoint aStart(getStart() - (aVector * rRight.getExtendStart()) + aDeltaY);
                        const basegfx::B2DPoint aEnd(getEnd() + (aVector * rRight.getExtendEnd()) + aDeltaY);
                        const attribute::LineAttribute aLineAttribute(rRight.getRGBColor(), rRight.getWidth());

                        addPolygonStrokePrimitive2D(
                            rContainer,
                            aStart,
                            aEnd,
                            aLineAttribute,
                            aStrokeAttribute);
                    }
                }
                else if(isInsideUsed())
                else
                {
                    // single line, only inside values used, no vertical offsets
                    const BorderLine& rBorderLine(getBorderLines()[0]);
                    const attribute::LineAttribute aLineAttribute(rBorderLine.getRGBColor(), rBorderLine.getWidth());

                    addPolygonStrokePrimitive2D(
                        rContainer,
                        getStart() - (aVector * getExtendLeftStart()),
                        getEnd() + (aVector * getExtendLeftEnd()),
                        getRGBColorLeft(),
                        getLeftWidth(),
                        getStyle(),
                        getPatternScale());
                        getStart() - (aVector * rBorderLine.getExtendStart()),
                        getEnd() + (aVector * rBorderLine.getExtendEnd()),
                        aLineAttribute,
                        aStrokeAttribute);
                }
            }
        }
@@ -170,37 +187,42 @@ namespace drawinglayer
        BorderLinePrimitive2D::BorderLinePrimitive2D(
            const basegfx::B2DPoint& rStart,
            const basegfx::B2DPoint& rEnd,
            double fLeftWidth,
            double fDistance,
            double fRightWidth,
            double fExtendLeftStart,
            double fExtendLeftEnd,
            double fExtendRightStart,
            double fExtendRightEnd,
            const basegfx::BColor& rRGBColorRight,
            const basegfx::BColor& rRGBColorLeft,
            const basegfx::BColor& rRGBColorGap,
            const BorderLine& rBorderLine,
            SvxBorderLineStyle nStyle,
            double fPatternScale)
        :   BufferedDecompositionPrimitive2D(),
            maStart(rStart),
            maEnd(rEnd),
            maBorderLines(),
            mbHasGapColor(false),
            mnStyle(nStyle),
            mfPatternScale(fPatternScale),
            mfDiscreteGapDistance(0.0)
        {
            maBorderLines.push_back(rBorderLine);
        }

        BorderLinePrimitive2D::BorderLinePrimitive2D(
            const basegfx::B2DPoint& rStart,
            const basegfx::B2DPoint& rEnd,
            const BorderLine& rLeft,
            const BorderLine& rGap,
            const BorderLine& rRight,
            bool bHasGapColor,
            SvxBorderLineStyle nStyle,
            double fPatternScale)
        :   BufferedDecompositionPrimitive2D(),
            maStart(rStart),
            maEnd(rEnd),
            mfLeftWidth(fLeftWidth),
            mfDistance(fDistance),
            mfRightWidth(fRightWidth),
            mfExtendLeftStart(fExtendLeftStart),
            mfExtendLeftEnd(fExtendLeftEnd),
            mfExtendRightStart(fExtendRightStart),
            mfExtendRightEnd(fExtendRightEnd),
            maRGBColorRight(rRGBColorRight),
            maRGBColorLeft(rRGBColorLeft),
            maRGBColorGap(rRGBColorGap),
            maBorderLines(),
            mbHasGapColor(bHasGapColor),
            mnStyle(nStyle),
            mfPatternScale(fPatternScale),
            mfDiscreteDistance(0.0)
            mfDiscreteGapDistance(0.0)
        {
            maBorderLines.push_back(rLeft);
            maBorderLines.push_back(rGap);
            maBorderLines.push_back(rRight);
        }

        bool BorderLinePrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
@@ -209,21 +231,23 @@ namespace drawinglayer
            {
                const BorderLinePrimitive2D& rCompare = static_cast<const BorderLinePrimitive2D&>(rPrimitive);

                return (getStart() == rCompare.getStart()
                if (getStart() == rCompare.getStart()
                    && getEnd() == rCompare.getEnd()
                    && getLeftWidth() == rCompare.getLeftWidth()
                    && getDistance() == rCompare.getDistance()
                    && getRightWidth() == rCompare.getRightWidth()
                    && getExtendLeftStart() == rCompare.getExtendLeftStart()
                    && getExtendLeftEnd() == rCompare.getExtendLeftEnd()
                    && getExtendRightStart() == rCompare.getExtendRightStart()
                    && getExtendRightEnd() == rCompare.getExtendRightEnd()
                    && getRGBColorRight() == rCompare.getRGBColorRight()
                    && getRGBColorLeft() == rCompare.getRGBColorLeft()
                    && getRGBColorGap() == rCompare.getRGBColorGap()
                    && hasGapColor() == rCompare.hasGapColor()
                    && getStyle() == rCompare.getStyle()
                    && getPatternScale() == rCompare.getPatternScale());
                    && getPatternScale() == rCompare.getPatternScale())
                {
                    if (getBorderLines().size() == rCompare.getBorderLines().size())
                    {
                        for (size_t a(0); a < getBorderLines().size(); a++)
                        {
                            if (!(getBorderLines()[a] == rCompare.getBorderLines()[a]))
                            {
                                return false;
                            }
                        }
                    }
                }
            }

            return false;
@@ -233,7 +257,7 @@ namespace drawinglayer
        {
            ::osl::MutexGuard aGuard(m_aMutex);

            if (!getStart().equal(getEnd()) && isOutsideUsed() && isInsideUsed())
            if (!getStart().equal(getEnd()) && 3 == getBorderLines().size())
            {
                // Double line with gap. In this case, we want to be view-dependent.
                // Get the current DiscreteUnit, look at X and Y and use the maximum
@@ -246,9 +270,10 @@ namespace drawinglayer
                // This can also be done using DiscreteMetricDependentPrimitive2D as base class
                // for this class, but specialization is better here for later buffering (only
                // do this when 'double line with gap')
                const double fNewDiscreteDistance(std::max(fDiscreteUnit, getDistance()));
                const double fDistance(getBorderLines()[1].getWidth());
                const double fNewDiscreteDistance(std::max(fDiscreteUnit, fDistance));

                if (!rtl::math::approxEqual(fNewDiscreteDistance, mfDiscreteDistance))
                if (!rtl::math::approxEqual(fNewDiscreteDistance, mfDiscreteGapDistance))
                {
                    if (!getBuffered2DDecomposition().empty())
                    {
@@ -257,7 +282,7 @@ namespace drawinglayer
                    }

                    // remember value for usage in create2DDecomposition
                    const_cast< BorderLinePrimitive2D* >(this)->mfDiscreteDistance = fNewDiscreteDistance;
                    const_cast< BorderLinePrimitive2D* >(this)->mfDiscreteGapDistance = fNewDiscreteDistance;
                }
            }

diff --git a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
index 4645bde..3108a81 100644
--- a/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/borderlineprimitive2d.hxx
@@ -33,14 +33,49 @@ namespace drawinglayer
{
    namespace primitive2d
    {
        /** BorderLine class
        Helper class holding the style definition for a single part of a full BNorderLine definition
        */
        class DRAWINGLAYER_DLLPUBLIC BorderLine
        {
        private:
            // line width
            double              mfWidth;

            // line color
            basegfx::BColor     maRGBColor;

            // line extends
            double              mfExtendStart;
            double              mfExtendEnd;

            // not implemented
            virtual bool operator!=(const BorderLine& rBorderLine) const = delete;

        public:
            BorderLine(
                double fWidth,
                const basegfx::BColor& rRGBColor,
                double fExtendStart = 0.0,
                double fExtendEnd = 0.0);

            double getWidth() const { return mfWidth; }
            const basegfx::BColor& getRGBColor() const { return maRGBColor; }
            double getExtendStart() const { return mfExtendStart; }
            double getExtendEnd() const { return mfExtendEnd; }

            /// compare operator
            virtual bool operator==(const BorderLine& rBorderLine) const;
        };

        /** BorderLinePrimitive2D class

            This is the basic primitive to build frames around objects, e.g. tables.
            It defines a single or double line from Start to End using the LeftWidth,
            Distance and RightWidth definitions.
            The LineStart/End overlap is defined by the Extend(Left|Right)(Start|End)
            definitions.
         */
        This is the basic primitive to build frames around objects, e.g. tables.
        It defines a single or double line from Start to End using the LeftWidth,
        Distance and RightWidth definitions.
        The LineStart/End overlap is defined by the Extend(Left|Right)(Start|End)
        definitions.
        */
        class DRAWINGLAYER_DLLPUBLIC BorderLinePrimitive2D : public BufferedDecompositionPrimitive2D
        {
        private:
@@ -48,84 +83,49 @@ namespace drawinglayer
            basegfx::B2DPoint                               maStart;
            basegfx::B2DPoint                               maEnd;

            /// the widths of single/double line
            double                                          mfLeftWidth;
            double                                          mfDistance;
            double                                          mfRightWidth;
            /// the single BorderLine style definition(s), one or three allowed (see constructors)
            std::vector< BorderLine >                       maBorderLines;

            /// edge overlap sizes
            double                                          mfExtendLeftStart;
            double                                          mfExtendLeftEnd;
            double                                          mfExtendRightStart;
            double                                          mfExtendRightEnd;

            /// the line colors
            basegfx::BColor                                 maRGBColorRight;
            basegfx::BColor                                 maRGBColorLeft;
            basegfx::BColor                                 maRGBColorGap;
            bool                                            mbHasGapColor;

            /// common style definitions
            SvxBorderLineStyle                              mnStyle;
            double                                          mfPatternScale;

            // for view dependent decomposition in the case with distance (gap),
            // remember the last used concrete mfDistance, see get2DDecomposition
            // implementation
            double                                          mfDiscreteDistance;

            /// local helpers
            bool isInsideUsed() const
            {
                return !basegfx::fTools::equalZero(mfLeftWidth);
            }

            bool isDistanceUsed() const
            {
                return !basegfx::fTools::equalZero(mfDistance);
            }

            bool isOutsideUsed() const
            {
                return !basegfx::fTools::equalZero(mfRightWidth);
            }
            double                                          mfDiscreteGapDistance;

            /// create local decomposition
            virtual void create2DDecomposition(Primitive2DContainer& rContainer, const geometry::ViewInformation2D& rViewInformation) const override;

        public:
            /// constructor
            /// simplified constructor for BorderLine with single edge
            BorderLinePrimitive2D(
                const basegfx::B2DPoint& rStart,
                const basegfx::B2DPoint& rEnd,
                double fLeftWidth,
                double fDistance,
                double fRightWidth,
                double fExtendLeftStart,
                double fExtendLeftEnd,
                double fExtendRightStart,
                double fExtendRightEnd,
                const basegfx::BColor& rRGBColorRight,
                const basegfx::BColor& rRGBColorLeft,
                const basegfx::BColor& rRGBColorGap,
                const BorderLine& rBorderLine,
                SvxBorderLineStyle nStyle,
                double fPatternScale = 1.0);

            /// constructor for full-fledged BorderLine with two edges and gap
            BorderLinePrimitive2D(
                const basegfx::B2DPoint& rStart,
                const basegfx::B2DPoint& rEnd,
                const BorderLine& rLeft,
                const BorderLine& rGap,
                const BorderLine& rRight,
                bool bHasGapColor,
                SvxBorderLineStyle nStyle,
                double fPatternScale = 1.0 );
                double fPatternScale = 1.0);

            /// data read access
            const basegfx::B2DPoint& getStart() const { return maStart; }
            const basegfx::B2DPoint& getEnd() const { return maEnd; }
            double getLeftWidth() const { return mfLeftWidth; }
            double getDistance() const { return mfDistance; }
            double getRightWidth() const { return mfRightWidth; }
            double getExtendLeftStart() const { return mfExtendLeftStart; }
            double getExtendLeftEnd() const { return mfExtendLeftEnd; }
            double getExtendRightStart() const { return mfExtendRightStart; }
            double getExtendRightEnd() const { return mfExtendRightEnd; }
            const basegfx::BColor& getRGBColorRight () const { return maRGBColorRight; }
            const basegfx::BColor& getRGBColorLeft () const { return maRGBColorLeft; }
            const basegfx::BColor& getRGBColorGap () const { return maRGBColorGap; }
            bool hasGapColor( ) const { return mbHasGapColor; }
            SvxBorderLineStyle getStyle () const { return mnStyle; }
            const std::vector< BorderLine >& getBorderLines() const { return maBorderLines; }
            bool hasGapColor() const { return mbHasGapColor; }
            SvxBorderLineStyle getStyle() const { return mnStyle; }
            double getPatternScale() const { return mfPatternScale; }

            /// helper to decide if AntiAliasing should be used
diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index de93c93..e5b6abb 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -510,9 +510,7 @@ void CreateBorderPrimitives(
    const DiagStyle& /*rRFromBL*/,
    const Color* pForceColor)
{
    static bool bCheckNewStuff(true);

    if (bCheckNewStuff && rBorder.Prim())
    if (rBorder.Prim())
    {
        double mfExtendLeftStart(0.0);
        double mfExtendLeftEnd(0.0);
@@ -523,6 +521,30 @@ void CreateBorderPrimitives(
        const basegfx::B2DVector aPerpendX(basegfx::getNormalizedPerpendicular(rX));
        const double fLength(rX.getLength());

        // do not forget RefMode offset, primitive will assume RefMode::Centered
        basegfx::B2DVector aRefModeOffset;

        if (RefMode::Centered != rBorder.GetRefMode())
        {
            const basegfx::B2DVector aPerpendX(basegfx::getNormalizedPerpendicular(rX));
            const double fHalfWidth(rBorder.GetWidth() * 0.5);

            if (RefMode::Begin == rBorder.GetRefMode())
            {
                // move aligned below vector
                aRefModeOffset = aPerpendX * fHalfWidth;
            }
            else if (RefMode::End == rBorder.GetRefMode())
            {
                // move aligned above vector
                aRefModeOffset = aPerpendX * -fHalfWidth;
            }
        }

        // create start/end for RefMode::Centered
        const basegfx::B2DPoint aStart(rOrigin + aRefModeOffset);
        const basegfx::B2DPoint aEnd(aStart + rX);

        if (2 == myOffsets.size())
        {
            std::vector< std::vector< double >> myCutsS(myOffsets.size());
@@ -537,6 +559,18 @@ void CreateBorderPrimitives(
            std::vector< double > nMinCutsE(getMinMaxCuts(false, myCutsE));
            mfExtendLeftEnd = ((nMinCutsE[0] + nMinCutsE[1]) * 0.5) * fLength;

            rTarget.append(
                drawinglayer::primitive2d::Primitive2DReference(
                    new drawinglayer::primitive2d::BorderLinePrimitive2D(
                        aStart,
                        aEnd,
                        drawinglayer::primitive2d::BorderLine(
                            rBorder.Prim(),
                            (pForceColor ? *pForceColor : rBorder.GetColorPrim()).getBColor(),
                            mfExtendLeftStart,
                            mfExtendLeftEnd),
                        rBorder.Type(),
                        rBorder.PatternScale())));
        }
        else if (4 == myOffsets.size())
        {
@@ -615,74 +649,31 @@ void CreateBorderPrimitives(

                mfExtendRightEnd = ((nMinCutsE[0] + nMinCutsE[1]) * 0.5) * fLength;
            }

            rTarget.append(
                drawinglayer::primitive2d::Primitive2DReference(
                    new drawinglayer::primitive2d::BorderLinePrimitive2D(
                        aStart,
                        aEnd,
                        drawinglayer::primitive2d::BorderLine(
                            rBorder.Prim(),
                            (pForceColor ? *pForceColor : rBorder.GetColorPrim()).getBColor(),
                            mfExtendLeftStart,
                            mfExtendLeftEnd),
                        drawinglayer::primitive2d::BorderLine(
                            rBorder.Dist(),
                            (pForceColor ? *pForceColor : rBorder.GetColorGap()).getBColor(),
                            (mfExtendLeftStart + mfExtendRightStart) * 0.5,
                            (mfExtendLeftEnd + mfExtendRightEnd) * 0.5),
                        drawinglayer::primitive2d::BorderLine(
                            rBorder.Secn(),
                            (pForceColor ? *pForceColor : rBorder.GetColorSecn()).getBColor(),
                            mfExtendRightStart,
                            mfExtendRightEnd),
                        rBorder.UseGapColor(),
                        rBorder.Type(),
                        rBorder.PatternScale())));
        }

        // do not forget RefMode offset, primitive will assume RefMode::Centered
        basegfx::B2DVector aRefModeOffset;

        if (RefMode::Centered != rBorder.GetRefMode())
        {
            const basegfx::B2DVector aPerpendX(basegfx::getNormalizedPerpendicular(rX));
            const double fHalfWidth(rBorder.GetWidth() * 0.5);

            if (RefMode::Begin == rBorder.GetRefMode())
            {
                // move aligned below vector
                aRefModeOffset = aPerpendX * fHalfWidth;
            }
            else if (RefMode::End == rBorder.GetRefMode())
            {
                // move aligned above vector
                aRefModeOffset = aPerpendX * -fHalfWidth;
            }
        }

        // create start/end for RefMode::Centered
        const basegfx::B2DPoint aStart(rOrigin + aRefModeOffset);
        const basegfx::B2DPoint aEnd(aStart + rX);

        rTarget.append(
            drawinglayer::primitive2d::Primitive2DReference(
                new drawinglayer::primitive2d::BorderLinePrimitive2D(
                    aStart,
                    aEnd,
                    rBorder.Prim(),
                    rBorder.Dist(),
                    rBorder.Secn(),
                    mfExtendLeftStart,
                    mfExtendLeftEnd,
                    mfExtendRightStart,
                    mfExtendRightEnd,
                    (pForceColor ? *pForceColor : rBorder.GetColorSecn()).getBColor(),
                    (pForceColor ? *pForceColor : rBorder.GetColorPrim()).getBColor(),
                    (pForceColor ? *pForceColor : rBorder.GetColorGap()).getBColor(),
                    rBorder.UseGapColor(),
                    rBorder.Type(),
                    rBorder.PatternScale())));
    }

    if (!bCheckNewStuff && (rBorder.Prim() || rBorder.Secn()))
    {
        basegfx::B2DPoint aStart(rOrigin);
        basegfx::B2DPoint aEnd(rOrigin + rX);
        const long nRotateT = 9000; /// Angle of the top slanted frames in 100th of degree
        const long nRotateB = 9000; /// Angle of the bottom slanted frames in 100th of degree

        rTarget.append(
            drawinglayer::primitive2d::Primitive2DReference(
                new drawinglayer::primitive2d::BorderLinePrimitive2D(
                    aStart, aEnd,
                    rBorder.Prim(),
                    rBorder.Dist(),
                    rBorder.Secn(),
                    lcl_GetExtent(rBorder, rLFromT, rLFromB, nRotateT, -nRotateB, true, false),                  // top-left, so left for rBorder and right for left outer
                    lcl_GetExtent(rBorder, rRFromT, rRFromB, 18000 - nRotateT, nRotateB - 18000, true, true),     // top-right
                    lcl_GetExtent(rBorder, rLFromB, rLFromT, nRotateB, -nRotateT, false, false),                 // bottom-left
                    lcl_GetExtent(rBorder, rRFromB, rRFromT, 18000 - nRotateB, nRotateT - 18000, false, true),    // bottom-right
                    (pForceColor ? *pForceColor : rBorder.GetColorSecn()).getBColor(),
                    (pForceColor ? *pForceColor : rBorder.GetColorPrim()).getBColor(),
                    (pForceColor ? *pForceColor : rBorder.GetColorGap()).getBColor(),
                    rBorder.UseGapColor(), rBorder.Type(), rBorder.PatternScale())));
    }
}

@@ -742,45 +733,57 @@ void CreateDiagFrameBorderPrimitives(
    if (rTLBR.Prim())
    {
        // top-left to bottom-right
        rTarget.append(
            new drawinglayer::primitive2d::BorderLinePrimitive2D(
                rOrigin,
                rOrigin + rXAxis + rYAxis,
                rTLBR.Prim(),
                rTLBR.Dist(),
                rTLBR.Secn(),
                0.0,
                0.0,
                0.0,
                0.0,
                (pForceColor ? *pForceColor : rTLBR.GetColorSecn()).getBColor(),
                (pForceColor ? *pForceColor : rTLBR.GetColorPrim()).getBColor(),
                (pForceColor ? *pForceColor : rTLBR.GetColorGap()).getBColor(),
                rTLBR.UseGapColor(),
                rTLBR.Type(),
                rTLBR.PatternScale()));
        if (basegfx::fTools::equalZero(rTLBR.Secn()))
        {
            rTarget.append(
                new drawinglayer::primitive2d::BorderLinePrimitive2D(
                    rOrigin,
                    rOrigin + rXAxis + rYAxis,
                    drawinglayer::primitive2d::BorderLine(rTLBR.Prim(), (pForceColor ? *pForceColor : rTLBR.GetColorPrim()).getBColor()),
                    rTLBR.Type(),
                    rTLBR.PatternScale()));
        }
        else
        {
            rTarget.append(
                new drawinglayer::primitive2d::BorderLinePrimitive2D(
                    rOrigin,
                    rOrigin + rXAxis + rYAxis,
                    drawinglayer::primitive2d::BorderLine(rTLBR.Prim(), (pForceColor ? *pForceColor : rTLBR.GetColorPrim()).getBColor()),
                    drawinglayer::primitive2d::BorderLine(rTLBR.Dist(), (pForceColor ? *pForceColor : rTLBR.GetColorGap()).getBColor()),
                    drawinglayer::primitive2d::BorderLine(rTLBR.Secn(), (pForceColor ? *pForceColor : rTLBR.GetColorSecn()).getBColor()),
                    rTLBR.UseGapColor(),
                    rTLBR.Type(),
                    rTLBR.PatternScale()));
        }
    }

    if (rBLTR.Prim())
    {
        // bottom-left to top-right
        rTarget.append(
            new drawinglayer::primitive2d::BorderLinePrimitive2D(
                rOrigin + rYAxis,
                rOrigin + rXAxis,
                rBLTR.Prim(),
                rBLTR.Dist(),
                rBLTR.Secn(),
                0.0,
                0.0,
                0.0,
                0.0,
                (pForceColor ? *pForceColor : rBLTR.GetColorSecn()).getBColor(),
                (pForceColor ? *pForceColor : rBLTR.GetColorPrim()).getBColor(),
                (pForceColor ? *pForceColor : rBLTR.GetColorGap()).getBColor(),
                rBLTR.UseGapColor(),
                rBLTR.Type(),
                rBLTR.PatternScale()));
        if (basegfx::fTools::equalZero(rTLBR.Secn()))
        {
            rTarget.append(
                new drawinglayer::primitive2d::BorderLinePrimitive2D(
                    rOrigin + rYAxis,
                    rOrigin + rXAxis,
                    drawinglayer::primitive2d::BorderLine(rTLBR.Prim(), (pForceColor ? *pForceColor : rTLBR.GetColorPrim()).getBColor()),
                    rBLTR.Type(),
                    rBLTR.PatternScale()));
        }
        else
        {
            rTarget.append(
                new drawinglayer::primitive2d::BorderLinePrimitive2D(
                    rOrigin + rYAxis,
                    rOrigin + rXAxis,
                    drawinglayer::primitive2d::BorderLine(rTLBR.Prim(), (pForceColor ? *pForceColor : rTLBR.GetColorPrim()).getBColor()),
                    drawinglayer::primitive2d::BorderLine(rTLBR.Dist(), (pForceColor ? *pForceColor : rTLBR.GetColorGap()).getBColor()),
                    drawinglayer::primitive2d::BorderLine(rTLBR.Secn(), (pForceColor ? *pForceColor : rTLBR.GetColorSecn()).getBColor()),
                    rBLTR.UseGapColor(),
                    rBLTR.Type(),
                    rBLTR.PatternScale()));
        }
    }
}
}
diff --git a/svx/source/table/viewcontactoftableobj.cxx b/svx/source/table/viewcontactoftableobj.cxx
index 27409ce..5ec9b6c 100644
--- a/svx/source/table/viewcontactoftableobj.cxx
+++ b/svx/source/table/viewcontactoftableobj.cxx
@@ -295,24 +295,31 @@ namespace drawinglayer
                {
                    const double fExtendIS(getExtend(getTopLine(), maTopFromLLine));
                    const double fExtendIE(getExtend(getBottomLine(), maBottomFromLLine));
                    const double fExtendOS(getExtend(maTopFromLLine, getTopLine()));
                    const double fExtendOE(getExtend(maBottomFromLLine, getBottomLine()));

                    rContainer.push_back(new BorderLinePrimitive2D(
                        aStart,
                        aEnd,
                        getChangedValue(getLeftLine().GetOutWidth(), true/*InTwips*/),
                        getChangedValue(getLeftLine().GetDistance(), true/*InTwips*/),
                        getChangedValue(getLeftLine().GetInWidth(), true/*InTwips*/),
                        fExtendIS * fTwipsToMM,
                        fExtendIE * fTwipsToMM,
                        fExtendOS * fTwipsToMM,
                        fExtendOE * fTwipsToMM,
                        getLeftLine().GetColorOut().getBColor(),
                        getLeftLine().GetColorIn().getBColor(),
                        getLeftLine().GetColorGap().getBColor(),
                        getLeftLine().HasGapColor(),
                        getLeftLine().GetBorderLineStyle()));
                    if (basegfx::fTools::equalZero(getLeftLine().GetInWidth()))
                    {
                        rContainer.push_back(
                            new BorderLinePrimitive2D(
                                aStart,
                                aEnd,
                                BorderLine(getChangedValue(getLeftLine().GetOutWidth(), true/*InTwips*/), getLeftLine().GetColorOut().getBColor(), fExtendIS * fTwipsToMM, fExtendIE * fTwipsToMM),
                                getLeftLine().GetBorderLineStyle()));
                    }
                    else
                    {
                        const double fExtendOS(getExtend(maTopFromLLine, getTopLine()));
                        const double fExtendOE(getExtend(maBottomFromLLine, getBottomLine()));

                        rContainer.push_back(
                            new BorderLinePrimitive2D(
                                aStart,
                                aEnd,
                                BorderLine(getChangedValue(getLeftLine().GetOutWidth(), true/*InTwips*/), getLeftLine().GetColorOut().getBColor(), fExtendIS * fTwipsToMM, fExtendIE * fTwipsToMM),
                                BorderLine(getChangedValue(getLeftLine().GetDistance(), true/*InTwips*/), getLeftLine().GetColorGap().getBColor()),
                                BorderLine(getChangedValue(getLeftLine().GetInWidth(), true/*InTwips*/), getLeftLine().GetColorIn().getBColor(), fExtendOS * fTwipsToMM, fExtendOE * fTwipsToMM),
                                getLeftLine().HasGapColor(),
                                getLeftLine().GetBorderLineStyle()));
                    }
                }
            }

@@ -326,24 +333,31 @@ namespace drawinglayer
                {
                    const double fExtendIS(getExtend(getLeftLine(), maLeftFromBLine ));
                    const double fExtendIE(getExtend(getRightLine(), maRightFromBLine));
                    const double fExtendOS(getExtend(maLeftFromBLine, getLeftLine()));
                    const double fExtendOE(getExtend(maRightFromBLine, getRightLine()));

                    rContainer.push_back(new BorderLinePrimitive2D(
                        aStart,
                        aEnd,
                        getChangedValue(getBottomLine().GetOutWidth(), true/*InTwips*/),
                        getChangedValue(getBottomLine().GetDistance(), true/*InTwips*/),
                        getChangedValue(getBottomLine().GetInWidth(), true/*InTwips*/),
                        fExtendIS * fTwipsToMM,
                        fExtendIE * fTwipsToMM,
                        fExtendOS * fTwipsToMM,
                        fExtendOE * fTwipsToMM,
                        getBottomLine().GetColorOut(false).getBColor(),
                        getBottomLine().GetColorIn(false).getBColor(),
                        getBottomLine().GetColorGap().getBColor(),
                        getBottomLine().HasGapColor(),
                        getBottomLine().GetBorderLineStyle()));
                    if (basegfx::fTools::equalZero(getBottomLine().GetInWidth()))
                    {
                        rContainer.push_back(
                            new BorderLinePrimitive2D(
                                aStart,
                                aEnd,
                                BorderLine(getChangedValue(getBottomLine().GetOutWidth(), true/*InTwips*/), getBottomLine().GetColorOut(false).getBColor(), fExtendIS * fTwipsToMM, fExtendIE * fTwipsToMM),
                                getBottomLine().GetBorderLineStyle()));
                    }
                    else
                    {
                        const double fExtendOS(getExtend(maLeftFromBLine, getLeftLine()));
                        const double fExtendOE(getExtend(maRightFromBLine, getRightLine()));

                        rContainer.push_back(
                            new BorderLinePrimitive2D(
                                aStart,
                                aEnd,
                                BorderLine(getChangedValue(getBottomLine().GetOutWidth(), true/*InTwips*/), getBottomLine().GetColorOut(false).getBColor(), fExtendIS * fTwipsToMM, fExtendIE * fTwipsToMM),
                                BorderLine(getChangedValue(getBottomLine().GetDistance(), true/*InTwips*/), getBottomLine().GetColorGap().getBColor()),
                                BorderLine(getChangedValue(getBottomLine().GetInWidth(), true/*InTwips*/), getBottomLine().GetColorIn(false).getBColor(), fExtendOS * fTwipsToMM, fExtendOE * fTwipsToMM),
                                getBottomLine().HasGapColor(),
                                getBottomLine().GetBorderLineStyle()));
                    }
                }
            }

@@ -355,26 +369,33 @@ namespace drawinglayer

                if(!aStart.equal(aEnd))
                {
                    const double fExtendIS(getExtend(getTopLine(), maTopFromRLine));
                    const double fExtendIE(getExtend(getBottomLine(), maBottomFromRLine));
                    const double fExtendOS(getExtend(maTopFromRLine, getTopLine()));
                    const double fExtendOE(getExtend(maBottomFromRLine, getBottomLine()));

                    rContainer.push_back(new BorderLinePrimitive2D(
                        aStart,
                        aEnd,
                        getChangedValue(getRightLine().GetOutWidth(), true/*InTwips*/),
                        getChangedValue(getRightLine().GetDistance(), true/*InTwips*/),
                        getChangedValue(getRightLine().GetInWidth(), true/*InTwips*/),
                        fExtendOS * fTwipsToMM,
                        fExtendOE * fTwipsToMM,
                        fExtendIS * fTwipsToMM,
                        fExtendIE * fTwipsToMM,
                        getRightLine().GetColorOut().getBColor(),
                        getRightLine().GetColorIn().getBColor(),
                        getRightLine().GetColorGap().getBColor(),
                        getRightLine().HasGapColor(),
                        getRightLine().GetBorderLineStyle()));
                    if (basegfx::fTools::equalZero(getRightLine().GetInWidth()))
                    {
                        rContainer.push_back(
                            new BorderLinePrimitive2D(
                                aStart,
                                aEnd,
                                BorderLine(getChangedValue(getRightLine().GetOutWidth(), true/*InTwips*/), getRightLine().GetColorOut().getBColor(), fExtendOS * fTwipsToMM, fExtendOE * fTwipsToMM),
                                getRightLine().GetBorderLineStyle()));
                    }
                    else
                    {
                        const double fExtendIS(getExtend(getTopLine(), maTopFromRLine));
                        const double fExtendIE(getExtend(getBottomLine(), maBottomFromRLine));

                        rContainer.push_back(
                            new BorderLinePrimitive2D(
                                aStart,
                                aEnd,
                                BorderLine(getChangedValue(getRightLine().GetOutWidth(), true/*InTwips*/), getRightLine().GetColorOut().getBColor(), fExtendOS * fTwipsToMM, fExtendOE * fTwipsToMM),
                                BorderLine(getChangedValue(getRightLine().GetDistance(), true/*InTwips*/), getRightLine().GetColorGap().getBColor()),
                                BorderLine(getChangedValue(getRightLine().GetInWidth(), true/*InTwips*/), getRightLine().GetColorIn().getBColor(), fExtendIS * fTwipsToMM, fExtendIE * fTwipsToMM),
                                getRightLine().HasGapColor(),
                                getRightLine().GetBorderLineStyle()));
                    }
                }
            }

@@ -391,26 +412,33 @@ namespace drawinglayer

                if(!aStart.equal(aEnd))
                {
                    const double fExtendIS(getExtend(getLeftLine(), maLeftFromTLine));
                    const double fExtendIE(getExtend(getRightLine(), maRightFromTLine));
                    const double fExtendOS(getExtend(maLeftFromTLine, getLeftLine()));
                    const double fExtendOE(getExtend(maRightFromTLine, getRightLine()));

                    rContainer.push_back(new BorderLinePrimitive2D(
                        aStart,
                        aEnd,
                        getChangedValue(getTopLine().GetOutWidth(), true/*InTwips*/),
                        getChangedValue(getTopLine().GetDistance(), true/*InTwips*/),
                        getChangedValue(getTopLine().GetInWidth(), true/*InTwips*/),
                        fExtendOS * fTwipsToMM,
                        fExtendOE * fTwipsToMM,
                        fExtendIS * fTwipsToMM,
                        fExtendIE * fTwipsToMM,
                        getTopLine().GetColorOut(false).getBColor(),
                        getTopLine().GetColorIn(false).getBColor(),
                        getTopLine().GetColorGap().getBColor(),
                        getTopLine().HasGapColor(),
                        getTopLine().GetBorderLineStyle()));
                    if (basegfx::fTools::equalZero(getTopLine().GetInWidth()))
                    {
                        rContainer.push_back(
                            new BorderLinePrimitive2D(
                                aStart,
                                aEnd,
                                BorderLine(getChangedValue(getTopLine().GetOutWidth(), true/*InTwips*/), getTopLine().GetColorOut(false).getBColor(), fExtendOS * fTwipsToMM, fExtendOE * fTwipsToMM),
                                getTopLine().GetBorderLineStyle()));
                    }
                    else
                    {
                        const double fExtendIS(getExtend(getLeftLine(), maLeftFromTLine));
                        const double fExtendIE(getExtend(getRightLine(), maRightFromTLine));

                        rContainer.push_back(
                            new BorderLinePrimitive2D(
                                aStart,
                                aEnd,
                                BorderLine(getChangedValue(getTopLine().GetOutWidth(), true/*InTwips*/), getTopLine().GetColorOut(false).getBColor(), fExtendOS * fTwipsToMM, fExtendOE * fTwipsToMM),
                                BorderLine(getChangedValue(getTopLine().GetDistance(), true/*InTwips*/), getTopLine().GetColorGap().getBColor()),
                                BorderLine(getChangedValue(getTopLine().GetInWidth(), true/*InTwips*/), getTopLine().GetColorIn(false).getBColor(), fExtendIS * fTwipsToMM, fExtendIE * fTwipsToMM),
                                getTopLine().HasGapColor(),
                                getTopLine().GetBorderLineStyle()));
                    }
                }
            }
        }
diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx
index cbb9ed9..20c362b 100644
--- a/sw/source/core/layout/paintfrm.cxx
+++ b/sw/source/core/layout/paintfrm.cxx
@@ -110,6 +110,7 @@
using namespace ::editeng;
using namespace ::com::sun::star;
using ::drawinglayer::primitive2d::BorderLinePrimitive2D;
using ::drawinglayer::primitive2d::BorderLine;
using std::pair;
using std::make_pair;

@@ -512,22 +513,38 @@ static sal_uInt8 lcl_TryMergeLines(
**/
static rtl::Reference<BorderLinePrimitive2D>
lcl_MergeBorderLines(
    BorderLinePrimitive2D const& rLine, BorderLinePrimitive2D const& rOther,
    basegfx::B2DPoint const& rStart, basegfx::B2DPoint const& rEnd)
    BorderLinePrimitive2D const& rLine,
    BorderLinePrimitive2D const& rOther,
    basegfx::B2DPoint const& rStart,
    basegfx::B2DPoint const& rEnd)
{
    return new BorderLinePrimitive2D(rStart, rEnd,
                rLine.getLeftWidth(),
                rLine.getDistance(),
                rLine.getRightWidth(),
                rLine.getExtendLeftStart(),
                rOther.getExtendLeftEnd(),
                rLine.getExtendRightStart(),
                rOther.getExtendRightEnd(),
                rLine.getRGBColorLeft(),
                rLine.getRGBColorGap(),
                rLine.getRGBColorRight(),
                rLine.hasGapColor(),
                rLine.getStyle());
    const BorderLine& rLineLeft = rLine.getBorderLines()[0];
    const BorderLine& rOtherLeft(rOther.getBorderLines()[0]);

    if (1 == rLine.getBorderLines().size())
    {
        return new BorderLinePrimitive2D(
            rStart,
            rEnd,
            BorderLine(rLineLeft.getWidth(), rLineLeft.getRGBColor(), rLineLeft.getExtendStart(), rOtherLeft.getExtendEnd()),
            rLine.getStyle());
    }
    else
    {
        const BorderLine& rLineGap(rLine.getBorderLines()[1]);
        // const BorderLine& rOtherGap(rOther.getBorderLines()[1]);
        const BorderLine& rLineRight(rLine.getBorderLines()[2]);
        const BorderLine& rOtherRight(rOther.getBorderLines()[2]);

        return new BorderLinePrimitive2D(
            rStart,
            rEnd,
            BorderLine(rLineLeft.getWidth(), rLineLeft.getRGBColor(), rLineLeft.getExtendStart(), rOtherLeft.getExtendEnd()),
            BorderLine(rLineGap.getWidth(), rLineGap.getRGBColor()),
            BorderLine(rLineRight.getWidth(), rLineRight.getRGBColor(), rLineRight.getExtendStart(), rOtherRight.getExtendEnd()),
            rLine.hasGapColor(),
            rLine.getStyle());
    }
}

/**
@@ -547,21 +564,51 @@ lcl_TryMergeBorderLine(BorderLinePrimitive2D const& rThis,
    assert(rThis.getEnd().getY() >= rThis.getStart().getY());
    assert(rOther.getEnd().getX() >= rOther.getStart().getX());
    assert(rOther.getEnd().getY() >= rOther.getStart().getY());
    const bool bSameEdgeNumber(rThis.getBorderLines().size() == rOther.getBorderLines().size());

    if (!bSameEdgeNumber)
    {
        return nullptr;
    }

    double thisHeight = rThis.getEnd().getY() - rThis.getStart().getY();
    double thisWidth  = rThis.getEnd().getX() - rThis.getStart().getX();
    double otherHeight = rOther.getEnd().getY() -  rOther.getStart().getY();
    double otherWidth  = rOther.getEnd().getX() -  rOther.getStart().getX();

    // check for same orientation, same line width, same style and matching colors
    if (    ((thisHeight > thisWidth) == (otherHeight > otherWidth))
        &&  (rtl::math::approxEqual(rThis.getLeftWidth(),  rOther.getLeftWidth()))
        &&  (rtl::math::approxEqual(rThis.getDistance(),   rOther.getDistance()))
        &&  (rtl::math::approxEqual(rThis.getRightWidth(), rOther.getRightWidth()))
        &&  (rThis.getStyle()         == rOther.getStyle())
        &&  (rThis.getRGBColorLeft()  == rOther.getRGBColorLeft())
        &&  (rThis.getRGBColorRight() == rOther.getRGBColorRight())
        &&  (rThis.hasGapColor()      == rOther.hasGapColor())
        &&  (!rThis.hasGapColor() ||
             (rThis.getRGBColorGap()  == rOther.getRGBColorGap())))
    bool bSameStuff(false);
    const BorderLine& rThisLeft(rThis.getBorderLines()[0]);
    const BorderLine& rOtherLeft(rOther.getBorderLines()[0]);

    if (1 == rThis.getBorderLines().size())
    {
        bSameStuff = ((thisHeight > thisWidth) == (otherHeight > otherWidth))
            && (rtl::math::approxEqual(rThisLeft.getWidth(), rOtherLeft.getWidth()))
            && (rThis.getStyle() == rOther.getStyle())
            && (rThisLeft.getRGBColor() == rOtherLeft.getRGBColor());
    }
    else
    {
        const BorderLine& rThisGap(rThis.getBorderLines()[1]);
        const BorderLine& rOtherGap(rOther.getBorderLines()[1]);
        const BorderLine& rThisRight(rThis.getBorderLines()[2]);
        const BorderLine& rOtherRight(rOther.getBorderLines()[2]);

        bSameStuff = ((thisHeight > thisWidth) == (otherHeight > otherWidth))
            && (rtl::math::approxEqual(rThisLeft.getWidth(), rOtherLeft.getWidth()))
            && (rtl::math::approxEqual(rThisGap.getWidth(), rOtherGap.getWidth()))
            && (rtl::math::approxEqual(rThisRight.getWidth(), rOtherRight.getWidth()))
            && (rThis.getStyle() == rOther.getStyle())
            && (rThisLeft.getRGBColor() == rOtherLeft.getRGBColor())
            && (rThisRight.getRGBColor() == rOtherRight.getRGBColor())
            && (rThis.hasGapColor() == rOther.hasGapColor())
            && (!rThis.hasGapColor() ||
            (rThisGap.getRGBColor() == rOtherGap.getRGBColor()));
    }


    if (bSameStuff)
    {
        int nRet = 0;
        if (thisHeight > thisWidth) // vertical line
@@ -4923,14 +4970,28 @@ static void lcl_MakeBorderLine(SwRect const& rRect,
    Color const aLeftColor = rBorder.GetColorOut(isLeftOrTopBorder);
    Color const aRightColor = rBorder.GetColorIn(isLeftOrTopBorder);

    rtl::Reference<BorderLinePrimitive2D> const xLine =
        new BorderLinePrimitive2D(
            aStart, aEnd, nLeftWidth, rBorder.GetDistance(), nRightWidth,
            nExtentLeftStart, nExtentLeftEnd,
            nExtentRightStart, nExtentRightEnd,
            aLeftColor.getBColor(), aRightColor.getBColor(),
            rBorder.GetColorGap().getBColor(), rBorder.HasGapColor(),
            rBorder.GetBorderLineStyle() );
    rtl::Reference<BorderLinePrimitive2D> xLine;

    if (basegfx::fTools::equalZero(nRightWidth))
    {
        xLine = new BorderLinePrimitive2D(
            aStart,
            aEnd,
            BorderLine(nLeftWidth, aLeftColor.getBColor(), nExtentLeftStart, nExtentLeftEnd),
            rBorder.GetBorderLineStyle());
    }
    else
    {
        xLine = new BorderLinePrimitive2D(
            aStart,
            aEnd,
            BorderLine(nLeftWidth, aLeftColor.getBColor(), nExtentLeftStart, nExtentLeftEnd),
            BorderLine(rBorder.GetDistance(), rBorder.GetColorGap().getBColor()),
            BorderLine(nRightWidth, aRightColor.getBColor(), nExtentRightStart, nExtentRightEnd),
            rBorder.HasGapColor(),
            rBorder.GetBorderLineStyle());
    }

    properties.pBLines->AddBorderLine(xLine.get(), properties);
}