diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2021-02-13 13:55:22 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2021-02-14 12:50:01 +0100 |
commit | cfff893b9c82843a90aac4ecdb3a3936721b74a0 (patch) | |
tree | 2859340e329ea6dbffe5ae9c7eba0f67a88c57af /vcl/source/control/field.cxx | |
parent | 20305894243e24eb383ab9feefebf4a0e9f2644f (diff) |
Move unit conversion code to o3tl, and unify on that in more places
This also allows to easily add more units, both of length and for other
unit categories.
The conversion for "Line" unit (312 twip) is questionable. Corresponding
entries in aImplFactor in vcl/source/control/field.cxx were inconsistent
(45/11 in; 10/13 pc; 156/10 pt). They were added without explanation in
commit c85db626029fd8a5e0dfcb312937279df32339a0. I haven't found a spec
of the unit (https://en.wikipedia.org/wiki/Line_(unit) is not specific).
I used the definition based on "by pt", "by mm/100", "by char" (they all
were consistent); "by pc" seems inverted; "by twip" was half as much.
This accepted conversion makes unit test for tdf#79236 pass.
Change-Id: Iae5a21d915fa8e934a1f47f8ba9f6df03b79a9fd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110839
Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'vcl/source/control/field.cxx')
-rw-r--r-- | vcl/source/control/field.cxx | 116 |
1 files changed, 22 insertions, 94 deletions
diff --git a/vcl/source/control/field.cxx b/vcl/source/control/field.cxx index f232e50a7c7a..9a42dcb2d8a5 100644 --- a/vcl/source/control/field.cxx +++ b/vcl/source/control/field.cxx @@ -19,12 +19,14 @@ #include <sal/config.h> +#include <cmath> #include <string_view> #include <sal/log.hxx> #include <osl/diagnose.h> #include <comphelper/string.hxx> +#include <tools/UnitConversion.hxx> #include <vcl/builder.hxx> #include <vcl/fieldvalues.hxx> @@ -972,35 +974,6 @@ static FieldUnit ImplMetricGetUnit(const OUString& rStr) return vcl::StringToMetric(aStr); } -#define K *1000L -#define M *1000000LL -#define X *5280L - -// twip in km = 254 / 14 400 000 000 -// expressions too big for default size 32 bit need LL to avoid overflow - -const sal_Int64 aImplFactor[sal_uInt16(FieldUnit::LINE) + 1] - [sal_uInt16(FieldUnit::LINE) + 1] = -{ /* -mm/100 mm cm m km twip point pica inch foot mile char line */ -{ 1, 100, 1 K, 100 K, 100 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X , 53340, 396240}, -{ 1, 1, 10, 1 K, 1 M, 2540, 2540, 2540, 2540,2540*12,2540*12 X , 5334, 396240}, -{ 1, 1, 1, 100, 100 K, 254, 254, 254, 254, 254*12, 254*12 X , 5334, 39624}, -{ 1, 1, 1, 1, 1 K, 254, 254, 254, 254, 254*12, 254*12 X , 533400, 39624}, -{ 1, 1, 1, 1, 1, 254, 254, 254, 254, 254*12, 254*12 X ,533400 K, 39624}, -{ 1440,144 K,144 K,14400 K,14400LL M, 1, 20, 240, 1440,1440*12,1440*12 X , 210, 3120}, -{ 72, 7200, 7200, 720 K, 720 M, 1, 1, 12, 72, 72*12, 72*12 X , 210, 156}, -{ 6, 600, 600, 60 K, 60 M, 1, 1, 1, 6, 6*12, 6*12 X , 210, 10}, -{ 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 12, 12 X , 210, 45}, -{ 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 X , 210, 45}, -{ 1, 100, 100, 10 K, 10 M, 1, 1, 1, 1, 1, 1 , 210, 45}, -{ 144, 1440,14400, 14400, 14400, 1, 20, 240, 1440,1440*12, 1440*12 X, 1, 156 }, -{ 720,72000,72000, 7200 K,7200LL M, 20, 10, 13, 11, 11*12, 11*12 X, 105, 1 } -}; -#undef X -#undef M -#undef K - static FieldUnit ImplMap2FieldUnit( MapUnit meUnit, tools::Long& nDecDigits ) { switch( meUnit ) @@ -1057,7 +1030,7 @@ namespace vcl else if ( nDouble >= double(SAL_MAX_INT64) ) nLong = SAL_MAX_INT64; else - nLong = static_cast<sal_Int64>( nDouble ); + nLong = static_cast<sal_Int64>( std::round(nDouble) ); return nLong; } @@ -1094,20 +1067,11 @@ double convertValue( double nValue, tools::Long nDigits, FieldUnit eInUnit, Fiel if ( eInUnit != eOutUnit ) { - sal_Int64 nDiv = aImplFactor[sal_uInt16(eInUnit)][sal_uInt16(eOutUnit)]; - sal_Int64 nMult = aImplFactor[sal_uInt16(eOutUnit)][sal_uInt16(eInUnit)]; - - SAL_WARN_IF( nMult <= 0, "vcl", "illegal *" ); - SAL_WARN_IF( nDiv <= 0, "vcl", "illegal /" ); - - if ( nMult != 1 && nMult > 0) - nValue *= nMult; - if ( nDiv != 1 && nDiv > 0 ) - { - nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2); - nValue /= nDiv; - } + const o3tl::Length eFrom = FieldToO3tlLength(eInUnit), eTo = FieldToO3tlLength(eOutUnit); + if (eFrom != o3tl::Length::invalid && eTo != o3tl::Length::invalid) + nValue = o3tl::convert(nValue, eFrom, eTo); } + return nValue; } @@ -1143,49 +1107,22 @@ namespace vcl { if ( eInUnit != eOutUnit ) { - sal_Int64 nMult = 1, nDiv = 1; - - if (eInUnit == FieldUnit::PERCENT) + if (eInUnit == FieldUnit::PERCENT && mnBaseValue > 0 && nValue > 0) { - if ( (mnBaseValue <= 0) || (nValue <= 0) ) - return nValue; - nDiv = 100 * ImplPower10(nDecDigits); + sal_Int64 nDiv = 100 * ImplPower10(nDecDigits); - nMult = mnBaseValue; - } - else if ( eOutUnit == FieldUnit::PERCENT || - eOutUnit == FieldUnit::CUSTOM || - eOutUnit == FieldUnit::NONE || - eOutUnit == FieldUnit::DEGREE || - eOutUnit == FieldUnit::SECOND || - eOutUnit == FieldUnit::MILLISECOND || - eOutUnit == FieldUnit::PIXEL || - eInUnit == FieldUnit::CUSTOM || - eInUnit == FieldUnit::NONE || - eInUnit == FieldUnit::DEGREE || - eInUnit == FieldUnit::MILLISECOND || - eInUnit == FieldUnit::PIXEL ) - return nValue; - else - { - if (eOutUnit == FieldUnit::MM_100TH) - eOutUnit = FieldUnit::NONE; - if (eInUnit == FieldUnit::MM_100TH) - eInUnit = FieldUnit::NONE; + if (mnBaseValue != 1) + nValue *= mnBaseValue; - nDiv = aImplFactor[sal_uInt16(eInUnit)][sal_uInt16(eOutUnit)]; - nMult = aImplFactor[sal_uInt16(eOutUnit)][sal_uInt16(eInUnit)]; - - SAL_WARN_IF( nMult <= 0, "vcl", "illegal *" ); - SAL_WARN_IF( nDiv <= 0, "vcl", "illegal /" ); + nValue += nDiv / 2; + nValue /= nDiv; } - - if ( nMult != 1 && nMult > 0 ) - nValue *= nMult; - if ( nDiv != 1 && nDiv > 0 ) + else { - nValue += ( nValue < 0 ) ? (-nDiv/2) : (nDiv/2); - nValue /= nDiv; + const o3tl::Length eFrom = FieldToO3tlLength(eInUnit, o3tl::Length::invalid); + const o3tl::Length eTo = FieldToO3tlLength(eOutUnit, o3tl::Length::invalid); + if (eFrom != o3tl::Length::invalid && eTo != o3tl::Length::invalid) + nValue = o3tl::convert(nValue, eFrom, eTo); } } @@ -1240,19 +1177,10 @@ namespace vcl if ( eFieldUnit != eInUnit ) { - sal_Int64 nDiv = aImplFactor[sal_uInt16(eInUnit)][sal_uInt16(eFieldUnit)]; - sal_Int64 nMult = aImplFactor[sal_uInt16(eFieldUnit)][sal_uInt16(eInUnit)]; - - SAL_WARN_IF( nMult <= 0, "vcl", "illegal *" ); - SAL_WARN_IF( nDiv <= 0, "vcl", "illegal /" ); - - if( nMult != 1 && nMult > 0 ) - nValue *= nMult; - if( nDiv != 1 && nDiv > 0 ) - { - nValue += (nValue < 0) ? (-nDiv/2) : (nDiv/2); - nValue /= nDiv; - } + const o3tl::Length eFrom = FieldToO3tlLength(eInUnit, o3tl::Length::invalid); + const o3tl::Length eTo = FieldToO3tlLength(eFieldUnit, o3tl::Length::invalid); + if (eFrom != o3tl::Length::invalid && eTo != o3tl::Length::invalid) + nValue = o3tl::convert(nValue, eFrom, eTo); } return nValue; } |