better drawing support for borders of different width, fdo#33634
diff --git a/drawinglayer/inc/drawinglayer/primitive2d/borderlineprimitive2d.hxx b/drawinglayer/inc/drawinglayer/primitive2d/borderlineprimitive2d.hxx
index 1449e2b..6ca9643 100644
--- a/drawinglayer/inc/drawinglayer/primitive2d/borderlineprimitive2d.hxx
+++ b/drawinglayer/inc/drawinglayer/primitive2d/borderlineprimitive2d.hxx
@@ -85,17 +85,17 @@ namespace drawinglayer
            /// local helpers
            double getCorrectedLeftWidth() const
            {
                return basegfx::fTools::equal(1.0, mfLeftWidth) ? 0.0 : mfLeftWidth;
                return mfLeftWidth <= 0.1 ? 0.0 : mfLeftWidth;
            }

            double getCorrectedDistance() const
            {
                return basegfx::fTools::equal(1.0, mfDistance) ? 0.0 : mfDistance;
                return mfDistance <= 0.1 ? 0.0 : mfDistance;
            }

            double getCorrectedRightWidth() const
            {
                return basegfx::fTools::equal(1.0, mfRightWidth) ? 0.0 : mfRightWidth;
                return mfRightWidth <= 0.1 ? 0.0 : mfRightWidth;
            }

            double getWidth() const
@@ -105,12 +105,12 @@ namespace drawinglayer

            bool leftIsHairline() const
            {
                return basegfx::fTools::equal(1.0, mfLeftWidth);
                return 0 < mfLeftWidth && mfLeftWidth <= 0.1;
            }

            bool rightIsHairline() const
            {
                return basegfx::fTools::equal(1.0, mfRightWidth);
                return 0 < mfRightWidth && mfRightWidth <= 0.1;
            }

            bool isSolidLine() const
diff --git a/svx/inc/svx/framelink.hxx b/svx/inc/svx/framelink.hxx
index 218ae56..c2edbb4 100644
--- a/svx/inc/svx/framelink.hxx
+++ b/svx/inc/svx/framelink.hxx
@@ -118,12 +118,12 @@ public:
    /** Constructs an invisible frame style. */
    inline explicit     Style() : meRefMode( REFMODE_CENTERED ), mnType( editeng::SOLID ) { Clear(); }
    /** Constructs a frame style with passed line widths. */
    inline explicit     Style( sal_uInt16 nP, sal_uInt16 nD, sal_uInt16 nS, editeng::SvxBorderStyle nType ) :
    inline explicit     Style( double nP, double nD, double nS, editeng::SvxBorderStyle nType ) :
                            meRefMode( REFMODE_CENTERED ), mnType( nType )
                            { Clear(); Set( nP, nD, nS ); }
    /** Constructs a frame style with passed color and line widths. */
    inline explicit     Style( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor,
                            sal_uInt16 nP, sal_uInt16 nD, sal_uInt16 nS, editeng::SvxBorderStyle nType ) :
                            double nP, double nD, double nS, editeng::SvxBorderStyle nType ) :
                            meRefMode( REFMODE_CENTERED ), mnType( nType )
                            { Set( rColorPrim, rColorSecn, rColorGap, bUseGapColor, nP, nD, nS ); }
    /** Constructs a frame style from the passed SvxBorderLine struct. */
@@ -138,21 +138,21 @@ public:
    inline const Color& GetColorSecn() const { return maColorSecn; }
    inline const Color& GetColorGap() const { return maColorGap; }
    inline bool         UseGapColor() const { return mbUseGapColor; }
    inline sal_uInt16   Prim() const { return mnPrim; }
    inline sal_uInt16   Dist() const { return mnDist; }
    inline sal_uInt16   Secn() const { return mnSecn; }
    inline double       Prim() const { return mnPrim; }
    inline double       Dist() const { return mnDist; }
    inline double       Secn() const { return mnSecn; }
    inline editeng::SvxBorderStyle Type() const { return mnType; }

    /** Returns the total width of this frame style. */
    inline sal_uInt16   GetWidth() const { return mnPrim + mnDist + mnSecn; }
    inline double       GetWidth() const { return mnPrim + mnDist + mnSecn; }

    /** Sets the frame style to invisible state. */
    void                Clear();
    /** Sets the frame style to the passed line widths. */
    void                Set( sal_uInt16 nP, sal_uInt16 nD, sal_uInt16 nS );
    void                Set( double nP, double nD, double nS );
    /** Sets the frame style to the passed line widths. */
    void                Set( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor,
                            sal_uInt16 nP, sal_uInt16 nD, sal_uInt16 nS );
                            double nP, double nD, double nS );
    /** Sets the frame style to the passed SvxBorderLine struct. */
    void                Set( const editeng::SvxBorderLine& rBorder, double fScale = 1.0, sal_uInt16 nMaxWidth = SAL_MAX_UINT16 );
    /** Sets the frame style to the passed SvxBorderLine struct. Clears the style, if pBorder is 0. */
@@ -178,9 +178,9 @@ private:
    Color               maColorGap;
    bool                mbUseGapColor;
    RefMode             meRefMode;  /// Reference point handling for this frame border.
    sal_uInt16          mnPrim;     /// Width of primary (single, left, or top) line.
    sal_uInt16          mnDist;     /// Distance between primary and secondary line.
    sal_uInt16          mnSecn;     /// Width of secondary (right or bottom) line.
    double              mnPrim;     /// Width of primary (single, left, or top) line.
    double              mnDist;     /// Distance between primary and secondary line.
    double              mnSecn;     /// Width of secondary (right or bottom) line.
    editeng::SvxBorderStyle      mnType;
};

diff --git a/svx/source/dialog/framelink.cxx b/svx/source/dialog/framelink.cxx
index a933b97..cf43a41 100644
--- a/svx/source/dialog/framelink.cxx
+++ b/svx/source/dialog/framelink.cxx
@@ -215,12 +215,9 @@ inline long lclD2L( double fValue )
}

/** Converts a width in twips to a width in another map unit (specified by fScale). */
sal_uInt16 lclScaleValue( long nValue, double fScale, sal_uInt16 nMaxWidth )
double lclScaleValue( double nValue, double fScale, sal_uInt16 nMaxWidth )
{
    // convert any width except 0 to at least 1 unit
    // #i61324# 1 twip must scale to 1/100mm
    return nValue ? static_cast< sal_uInt16 >( std::min< long >( std::max(
        static_cast< long >( nValue * fScale ), 1L ), nMaxWidth ) ) : 0;
    return std::min<double>(nValue * fScale, nMaxWidth);
}

// ----------------------------------------------------------------------------
@@ -1154,7 +1151,7 @@ void Style::Clear()
    Set( Color(), Color(), Color(), false, 0, 0, 0 );
}

void Style::Set( sal_uInt16 nP, sal_uInt16 nD, sal_uInt16 nS )
void Style::Set( double nP, double nD, double nS )
{
    /*  nP  nD  nS  ->  mnPrim  mnDist  mnSecn
        --------------------------------------
@@ -1163,12 +1160,12 @@ void Style::Set( sal_uInt16 nP, sal_uInt16 nD, sal_uInt16 nS )
        >0  0   >0      nP      0       0
        >0  >0  >0      nP      nD      nS
     */
    mnPrim = nP ? nP : nS;
    mnDist = (nP && nS) ? nD : 0;
    mnSecn = (nP && nD) ? nS : 0;
    mnPrim = rtl::math::round(nP ? nP : nS, 2);
    mnDist = rtl::math::round((nP && nS) ? nD : 0, 2);
    mnSecn = rtl::math::round((nP && nD) ? nS : 0, 2);
}

void Style::Set( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor, sal_uInt16 nP, sal_uInt16 nD, sal_uInt16 nS )
void Style::Set( const Color& rColorPrim, const Color& rColorSecn, const Color& rColorGap, bool bUseGapColor, double nP, double nD, double nS )
{
    maColorPrim = rColorPrim;
    maColorSecn = rColorSecn;
@@ -1197,7 +1194,7 @@ void Style::Set( const SvxBorderLine& rBorder, double fScale, sal_uInt16 nMaxWid
    {
        Set( SCALEVALUE( nPrim ), SCALEVALUE( nDist ), SCALEVALUE( nSecn ) );
        // Enlarge the style if distance is too small due to rounding losses.
        sal_uInt16 nPixWidth = SCALEVALUE( nPrim + nDist + nSecn );
        double nPixWidth = SCALEVALUE( nPrim + nDist + nSecn );
        if( nPixWidth > GetWidth() )
            mnDist = nPixWidth - mnPrim - mnSecn;
        // Shrink the style if it is too thick for the control.
@@ -1209,7 +1206,7 @@ void Style::Set( const SvxBorderLine& rBorder, double fScale, sal_uInt16 nMaxWid
            // Still too thick? Decrease the line widths.
            if( GetWidth() > nMaxWidth )
            {
                if( mnPrim && (mnPrim == mnSecn) )
                if( rtl::math::approxEqual(mnPrim, 0.0) && rtl::math::approxEqual(mnPrim, mnSecn) )
                {
                    // Both lines equal - decrease both to keep symmetry.
                    --mnPrim;
@@ -1220,7 +1217,7 @@ void Style::Set( const SvxBorderLine& rBorder, double fScale, sal_uInt16 nMaxWid
                    // Decrease each line for itself
                    if( mnPrim )
                        --mnPrim;
                    if( (GetWidth() > nMaxWidth) && mnSecn )
                    if( (GetWidth() > nMaxWidth) && !rtl::math::approxEqual(mnSecn, 0.0) )
                        --mnSecn;
                }
            }
@@ -1264,8 +1261,8 @@ bool operator==( const Style& rL, const Style& rR )
bool operator<( const Style& rL, const Style& rR )
{
    // different total widths -> rL<rR, if rL is thinner
    sal_uInt16 nLW = rL.GetWidth();
    sal_uInt16 nRW = rR.GetWidth();
    double nLW = rL.GetWidth();
    double nRW = rR.GetWidth();
    if( nLW != nRW ) return nLW < nRW;

    // one line double, the other single -> rL<rR, if rL is single