move the bigint based Scale() implementations to one central place

Picking the best looking one in the process.

Change-Id: I77f9236fcd21f883a23fe2f43f20336f17b44cc6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/108831
Tested-by: Noel Grandin <noel.grandin@collabora.co.uk>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/editeng/source/items/borderline.cxx b/editeng/source/items/borderline.cxx
index 6a33b4b..08261ed 100644
--- a/editeng/source/items/borderline.cxx
+++ b/editeng/source/items/borderline.cxx
@@ -28,6 +28,7 @@
#include <editeng/itemtype.hxx>
#include <editeng/editrids.hrc>
#include <editeng/eerdll.hxx>
#include <tools/bigint.hxx>

using namespace ::com::sun::star::table::BorderLineStyle;

@@ -496,23 +497,23 @@ void SvxBorderLine::GuessLinesWidths( SvxBorderLineStyle nStyle, sal_uInt16 nOut

sal_uInt16 SvxBorderLine::GetOutWidth() const
{
    sal_uInt16 nOut = static_cast<sal_uInt16>(Scale( m_aWidthImpl.GetLine1( m_nWidth ), m_nMult, m_nDiv ));
    sal_uInt16 nOut = static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetLine1( m_nWidth ), m_nMult, m_nDiv ));
    if ( m_bMirrorWidths )
        nOut = static_cast<sal_uInt16>(Scale( m_aWidthImpl.GetLine2( m_nWidth ), m_nMult, m_nDiv ));
        nOut = static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetLine2( m_nWidth ), m_nMult, m_nDiv ));
    return nOut;
}

sal_uInt16 SvxBorderLine::GetInWidth() const
{
    sal_uInt16 nIn = static_cast<sal_uInt16>(Scale( m_aWidthImpl.GetLine2( m_nWidth ), m_nMult, m_nDiv ));
    sal_uInt16 nIn = static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetLine2( m_nWidth ), m_nMult, m_nDiv ));
    if ( m_bMirrorWidths )
        nIn = static_cast<sal_uInt16>(Scale( m_aWidthImpl.GetLine1( m_nWidth ), m_nMult, m_nDiv ));
        nIn = static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetLine1( m_nWidth ), m_nMult, m_nDiv ));
    return nIn;
}

sal_uInt16 SvxBorderLine::GetDistance() const
{
    return static_cast<sal_uInt16>(Scale( m_aWidthImpl.GetGap( m_nWidth ), m_nMult, m_nDiv ));
    return static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetGap( m_nWidth ), m_nMult, m_nDiv ));
}


diff --git a/editeng/source/items/frmitems.cxx b/editeng/source/items/frmitems.cxx
index 4f365da..43a9be8 100644
--- a/editeng/source/items/frmitems.cxx
+++ b/editeng/source/items/frmitems.cxx
@@ -40,6 +40,7 @@
#include <comphelper/processfactory.hxx>
#include <vcl/GraphicObject.hxx>
#include <tools/urlobj.hxx>
#include <tools/bigint.hxx>
#include <svl/memberid.h>
#include <rtl/math.hxx>
#include <rtl/ustring.hxx>
@@ -270,8 +271,8 @@ bool SvxSizeItem::GetPresentation

void SvxSizeItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
{
    m_aSize.setWidth( Scale( m_aSize.Width(), nMult, nDiv ) );
    m_aSize.setHeight( Scale( m_aSize.Height(), nMult, nDiv ) );
    m_aSize.setWidth( BigInt::Scale( m_aSize.Width(), nMult, nDiv ) );
    m_aSize.setHeight( BigInt::Scale( m_aSize.Height(), nMult, nDiv ) );
}


@@ -572,10 +573,10 @@ bool SvxLRSpaceItem::GetPresentation

void SvxLRSpaceItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
{
    nFirstLineOffset = static_cast<short>(Scale( nFirstLineOffset, nMult, nDiv ));
    nTxtLeft = Scale( nTxtLeft, nMult, nDiv );
    nLeftMargin = Scale( nLeftMargin, nMult, nDiv );
    nRightMargin = Scale( nRightMargin, nMult, nDiv );
    nFirstLineOffset = static_cast<short>(BigInt::Scale( nFirstLineOffset, nMult, nDiv ));
    nTxtLeft = BigInt::Scale( nTxtLeft, nMult, nDiv );
    nLeftMargin = BigInt::Scale( nLeftMargin, nMult, nDiv );
    nRightMargin = BigInt::Scale( nRightMargin, nMult, nDiv );
}


@@ -824,8 +825,8 @@ bool SvxULSpaceItem::GetPresentation

void SvxULSpaceItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
{
    nUpper = static_cast<sal_uInt16>(Scale( nUpper, nMult, nDiv ));
    nLower = static_cast<sal_uInt16>(Scale( nLower, nMult, nDiv ));
    nUpper = static_cast<sal_uInt16>(BigInt::Scale( nUpper, nMult, nDiv ));
    nLower = static_cast<sal_uInt16>(BigInt::Scale( nLower, nMult, nDiv ));
}


@@ -1222,7 +1223,7 @@ bool SvxShadowItem::GetPresentation

void SvxShadowItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
{
    nWidth = static_cast<sal_uInt16>(Scale( nWidth, nMult, nDiv ));
    nWidth = static_cast<sal_uInt16>(BigInt::Scale( nWidth, nMult, nDiv ));
}


@@ -1862,10 +1863,10 @@ void SvxBoxItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
    if ( pBottom )  pBottom->ScaleMetrics( nMult, nDiv );
    if ( pLeft )    pLeft->ScaleMetrics( nMult, nDiv );
    if ( pRight )   pRight->ScaleMetrics( nMult, nDiv );
    nTopDist = static_cast<sal_uInt16>(Scale( nTopDist, nMult, nDiv ));
    nBottomDist = static_cast<sal_uInt16>(Scale( nBottomDist, nMult, nDiv ));
    nLeftDist = static_cast<sal_uInt16>(Scale( nLeftDist, nMult, nDiv ));
    nRightDist = static_cast<sal_uInt16>(Scale( nRightDist, nMult, nDiv ));
    nTopDist = static_cast<sal_uInt16>(BigInt::Scale( nTopDist, nMult, nDiv ));
    nBottomDist = static_cast<sal_uInt16>(BigInt::Scale( nBottomDist, nMult, nDiv ));
    nLeftDist = static_cast<sal_uInt16>(BigInt::Scale( nLeftDist, nMult, nDiv ));
    nRightDist = static_cast<sal_uInt16>(BigInt::Scale( nRightDist, nMult, nDiv ));
}


@@ -2162,7 +2163,7 @@ void SvxBoxInfoItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
{
    if ( pHori ) pHori->ScaleMetrics( nMult, nDiv );
    if ( pVert ) pVert->ScaleMetrics( nMult, nDiv );
    nDefDist = static_cast<sal_uInt16>(Scale( nDefDist, nMult, nDiv ));
    nDefDist = static_cast<sal_uInt16>(BigInt::Scale( nDefDist, nMult, nDiv ));
}


diff --git a/editeng/source/items/textitem.cxx b/editeng/source/items/textitem.cxx
index 84cc8e7..dd2205b 100644
--- a/editeng/source/items/textitem.cxx
+++ b/editeng/source/items/textitem.cxx
@@ -33,6 +33,7 @@

#include <editeng/editids.hrc>
#include <editeng/editrids.hrc>
#include <tools/bigint.hxx>
#include <tools/mapunit.hxx>
#include <tools/UnitConversion.hxx>

@@ -835,7 +836,7 @@ bool SvxFontHeightItem::GetPresentation

void SvxFontHeightItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
{
    nHeight = static_cast<sal_uInt32>(Scale( nHeight, nMult, nDiv ));
    nHeight = static_cast<sal_uInt32>(BigInt::Scale( nHeight, nMult, nDiv ));
}


@@ -1496,7 +1497,7 @@ SvxKerningItem* SvxKerningItem::Clone( SfxItemPool * ) const

void SvxKerningItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
{
    SetValue( static_cast<sal_Int16>(Scale( GetValue(), nMult, nDiv )) );
    SetValue( static_cast<sal_Int16>(BigInt::Scale( GetValue(), nMult, nDiv )) );
}


diff --git a/include/editeng/itemtype.hxx b/include/editeng/itemtype.hxx
index 470bd99..4338d1f 100644
--- a/include/editeng/itemtype.hxx
+++ b/include/editeng/itemtype.hxx
@@ -21,7 +21,7 @@

// forward ---------------------------------------------------------------
#include <rtl/ustring.hxx>
#include <tools/bigint.hxx>
#include <tools/long.hxx>
#include <tools/mapunit.hxx>
#include <editeng/editengdllapi.h>

@@ -35,16 +35,6 @@ EDITENG_DLLPUBLIC OUString GetMetricText( tools::Long nVal, MapUnit eSrcUnit, Ma
OUString GetColorString( const Color& rCol );
EDITENG_DLLPUBLIC const char* GetMetricId(MapUnit eUnit);


inline tools::Long Scale( tools::Long nVal, tools::Long nMult, tools::Long nDiv )
{
    BigInt aVal( nVal );
    aVal *= nMult;
    aVal += nDiv/2;
    aVal /= nDiv;
    return aVal;
}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/tools/bigint.hxx b/include/tools/bigint.hxx
index 53f6816..3299d56 100644
--- a/include/tools/bigint.hxx
+++ b/include/tools/bigint.hxx
@@ -106,6 +106,9 @@ public:

    BigInt&         operator  =( sal_Int32 nValue );

    /* Scale and round value */
    static tools::Long Scale(tools::Long nVal, tools::Long nMult, tools::Long nDiv);

    friend inline   BigInt operator +( const BigInt& rVal1, const BigInt& rVal2 );
    friend inline   BigInt operator -( const BigInt& rVal1, const BigInt& rVal2 );
    friend inline   BigInt operator *( const BigInt& rVal1, const BigInt& rVal2 );
diff --git a/svx/source/svdraw/svdattr.cxx b/svx/source/svdraw/svdattr.cxx
index 0342f65..a683704 100644
--- a/svx/source/svdraw/svdattr.cxx
+++ b/svx/source/svdraw/svdattr.cxx
@@ -874,11 +874,7 @@ bool SdrMetricItem::HasMetrics() const
void SdrMetricItem::ScaleMetrics(tools::Long nMul, tools::Long nDiv)
{
    if (GetValue()!=0) {
        BigInt aVal(GetValue());
        aVal*=nMul;
        aVal+=nDiv/2; // to round accurately
        aVal/=nDiv;
        SetValue(tools::Long(aVal));
        SetValue(BigInt::Scale(GetValue(), nMul, nDiv));
    }
}

diff --git a/svx/source/svdraw/svdtrans.cxx b/svx/source/svdraw/svdtrans.cxx
index 6025dee..5b02f99 100644
--- a/svx/source/svdraw/svdtrans.cxx
+++ b/svx/source/svdraw/svdtrans.cxx
@@ -559,19 +559,9 @@ void OrthoDistance4(const Point& rPt0, Point& rPt, bool bBigOrtho)

tools::Long BigMulDiv(tools::Long nVal, tools::Long nMul, tools::Long nDiv)
{
    BigInt aVal(nVal);
    aVal*=nMul;
    if (aVal.IsNeg()!=(nDiv<0)) {
        aVal-=nDiv/2; // to round correctly
    } else {
        aVal+=nDiv/2; // to round correctly
    }
    if(nDiv)
    {
        aVal/=nDiv;
        return tools::Long(aVal);
    }
    return 0x7fffffff;
    if (!nDiv)
        return 0x7fffffff;
    return BigInt::Scale(nVal, nMul, nDiv);
}

// How many eU units fit into a mm, respectively an inch?
diff --git a/svx/source/xoutdev/xattr.cxx b/svx/source/xoutdev/xattr.cxx
index 5d3caa6..79ee536 100644
--- a/svx/source/xoutdev/xattr.cxx
+++ b/svx/source/xoutdev/xattr.cxx
@@ -91,22 +91,6 @@ using namespace ::com::sun::star;

typedef std::map<OUString, OUString> StringMap;

static tools::Long ScaleMetricValue( tools::Long nVal, tools::Long nMul, tools::Long nDiv )
{
    BigInt aVal( nVal );

    aVal *= nMul;

    if ( aVal.IsNeg() != ( nDiv < 0 ) )
        aVal-=nDiv/2; // for correct rounding
    else
        aVal+=nDiv/2; // for correct rounding

    aVal/=nDiv;

    return tools::Long( aVal );
}

NameOrIndex::NameOrIndex(sal_uInt16 _nWhich, sal_Int32 nIndex) :
    SfxStringItem(_nWhich, OUString()),
    nPalIndex(nIndex)
@@ -635,9 +619,9 @@ bool XLineDashItem::HasMetrics() const

void XLineDashItem::ScaleMetrics(tools::Long nMul, tools::Long nDiv)
{
    aDash.SetDotLen( ScaleMetricValue( aDash.GetDotLen(), nMul, nDiv ) );
    aDash.SetDashLen( ScaleMetricValue( aDash.GetDashLen(), nMul, nDiv ) );
    aDash.SetDistance( ScaleMetricValue( aDash.GetDistance(), nMul, nDiv ) );
    aDash.SetDotLen( BigInt::Scale( aDash.GetDotLen(), nMul, nDiv ) );
    aDash.SetDashLen( BigInt::Scale( aDash.GetDashLen(), nMul, nDiv ) );
    aDash.SetDistance( BigInt::Scale( aDash.GetDistance(), nMul, nDiv ) );
}

bool XLineDashItem::QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId ) const
@@ -2634,7 +2618,7 @@ bool XFillHatchItem::HasMetrics() const

void XFillHatchItem::ScaleMetrics(tools::Long nMul, tools::Long nDiv)
{
    aHatch.SetDistance( ScaleMetricValue( aHatch.GetDistance(), nMul, nDiv ) );
    aHatch.SetDistance( BigInt::Scale( aHatch.GetDistance(), nMul, nDiv ) );
}

bool XFillHatchItem::QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId ) const
diff --git a/tools/source/generic/bigint.cxx b/tools/source/generic/bigint.cxx
index 62350a3..6616ef7 100644
--- a/tools/source/generic/bigint.cxx
+++ b/tools/source/generic/bigint.cxx
@@ -843,4 +843,20 @@ bool operator<( const BigInt& rVal1, const BigInt& rVal2 )
    return nA.bIsNeg ? (nA.nNum[i] > nB.nNum[i]) : (nA.nNum[i] < nB.nNum[i]);
}

tools::Long BigInt::Scale( tools::Long nVal, tools::Long nMul, tools::Long nDiv )
{
    BigInt aVal( nVal );

    aVal *= nMul;

    if ( aVal.IsNeg() != ( nDiv < 0 ) )
        aVal -= nDiv / 2; // for correct rounding
    else
        aVal += nDiv / 2; // for correct rounding

    aVal /= nDiv;

    return tools::Long( aVal );
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */