summaryrefslogtreecommitdiffstats
path: root/svtools/source/misc/unitconv.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source/misc/unitconv.cxx')
-rw-r--r--svtools/source/misc/unitconv.cxx618
1 files changed, 618 insertions, 0 deletions
diff --git a/svtools/source/misc/unitconv.cxx b/svtools/source/misc/unitconv.cxx
new file mode 100644
index 000000000..93dab6ada
--- /dev/null
+++ b/svtools/source/misc/unitconv.cxx
@@ -0,0 +1,618 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svtools/unitconv.hxx>
+#include <tools/debug.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/weld.hxx>
+
+void SetFieldUnit(weld::MetricSpinButton& rField, FieldUnit eUnit, bool bAll)
+{
+ int nMin, nMax;
+ rField.get_range(nMin, nMax, FieldUnit::TWIP);
+ int nValue = rField.get_value(FieldUnit::TWIP);
+ nMin = rField.denormalize(nMin);
+ nMax = rField.denormalize(nMax);
+ nValue = rField.denormalize(nValue);
+
+ if (!bAll)
+ {
+ switch (eUnit)
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eUnit = FieldUnit::CM;
+ break;
+ case FieldUnit::FOOT:
+ case FieldUnit::MILE:
+ eUnit = FieldUnit::INCH;
+ break;
+ default: //prevent warning
+ break;
+ }
+ }
+
+ rField.set_unit(eUnit);
+
+ if (FieldUnit::POINT == eUnit)
+ {
+ if (rField.get_digits() > 1)
+ rField.set_digits(1);
+ }
+ else
+ rField.set_digits(2);
+
+ switch (eUnit)
+ {
+ // _CHAR and _LINE sets the step of "char" and "line" unit, they are same as FieldUnit::MM
+ case FieldUnit::CHAR:
+ case FieldUnit::LINE:
+ case FieldUnit::MM:
+ rField.set_increments(50, 500, eUnit);
+ break;
+ case FieldUnit::INCH:
+ rField.set_increments(2, 20, eUnit);
+ break;
+ default:
+ rField.set_increments(10, 100, eUnit);
+ break;
+ }
+
+ if (!bAll)
+ {
+ nMin = rField.normalize(nMin);
+ nMax = rField.normalize(nMax);
+ rField.set_range(nMin, nMax, FieldUnit::TWIP);
+ }
+
+ rField.set_value(rField.normalize(nValue), FieldUnit::TWIP);
+}
+
+void SetMetricValue(weld::MetricSpinButton& rField, int nCoreValue, MapUnit eUnit)
+{
+ auto nVal = OutputDevice::LogicToLogic(nCoreValue, eUnit, MapUnit::Map100thMM);
+ nVal = rField.normalize(nVal);
+ rField.set_value(nVal, FieldUnit::MM_100TH);
+}
+
+int GetCoreValue(const weld::MetricSpinButton& rField, MapUnit eUnit)
+{
+ int nVal = rField.get_value(FieldUnit::MM_100TH);
+ // avoid rounding issues
+ const int nSizeMask = 0xff000000;
+ bool bRoundBefore = true;
+ if( nVal >= 0 )
+ {
+ if( (nVal & nSizeMask) == 0 )
+ bRoundBefore = false;
+ }
+ else
+ {
+ if( ((-nVal) & nSizeMask ) == 0 )
+ bRoundBefore = false;
+ }
+ if( bRoundBefore )
+ nVal = rField.denormalize( nVal );
+ auto nUnitVal = OutputDevice::LogicToLogic(nVal, MapUnit::Map100thMM, eUnit);
+ if (!bRoundBefore)
+ nUnitVal = rField.denormalize(nUnitVal);
+ return nUnitVal;
+}
+
+long CalcToUnit( float nIn, MapUnit eUnit )
+{
+ // nIn is in Points
+
+ DBG_ASSERT( eUnit == MapUnit::MapTwip ||
+ eUnit == MapUnit::Map100thMM ||
+ eUnit == MapUnit::Map10thMM ||
+ eUnit == MapUnit::MapMM ||
+ eUnit == MapUnit::MapCM, "this unit is not implemented" );
+
+ float nTmp = nIn;
+
+ if ( MapUnit::MapTwip != eUnit )
+ nTmp = nIn * 10 / 567;
+
+ switch ( eUnit )
+ {
+ case MapUnit::Map100thMM: nTmp *= 100; break;
+ case MapUnit::Map10thMM: nTmp *= 10; break;
+ case MapUnit::MapMM: break;
+ case MapUnit::MapCM: nTmp /= 10; break;
+ default: ;//prevent warning
+ }
+
+ nTmp *= 20;
+ long nRet = static_cast<long>(nTmp);
+ return nRet;
+//! return (long)(nTmp * 20);
+}
+
+
+long ItemToControl( long nIn, MapUnit eItem, FieldUnit eCtrl )
+{
+ long nOut = 0;
+
+ switch ( eItem )
+ {
+ case MapUnit::Map100thMM:
+ case MapUnit::Map10thMM:
+ case MapUnit::MapMM:
+ {
+ if ( eItem == MapUnit::Map10thMM )
+ nIn /= 10;
+ else if ( eItem == MapUnit::Map100thMM )
+ nIn /= 100;
+ nOut = TransformMetric( nIn, FieldUnit::MM, eCtrl );
+ }
+ break;
+
+ case MapUnit::MapCM:
+ {
+ nOut = TransformMetric( nIn, FieldUnit::CM, eCtrl );
+ }
+ break;
+
+ case MapUnit::Map1000thInch:
+ case MapUnit::Map100thInch:
+ case MapUnit::Map10thInch:
+ case MapUnit::MapInch:
+ {
+ if ( eItem == MapUnit::Map10thInch )
+ nIn /= 10;
+ else if ( eItem == MapUnit::Map100thInch )
+ nIn /= 100;
+ else if ( eItem == MapUnit::Map1000thInch )
+ nIn /= 1000;
+ nOut = TransformMetric( nIn, FieldUnit::INCH, eCtrl );
+ }
+ break;
+
+ case MapUnit::MapPoint:
+ {
+ nOut = TransformMetric( nIn, FieldUnit::POINT, eCtrl );
+ }
+ break;
+
+ case MapUnit::MapTwip:
+ {
+ nOut = TransformMetric( nIn, FieldUnit::TWIP, eCtrl );
+ }
+ break;
+ default: ;//prevent warning
+ }
+ return nOut;
+}
+
+
+long ControlToItem( long nIn, FieldUnit eCtrl, MapUnit eItem )
+{
+ return ItemToControl( nIn, eItem, eCtrl );
+}
+
+
+FieldUnit MapToFieldUnit( const MapUnit eUnit )
+{
+ switch ( eUnit )
+ {
+ case MapUnit::Map100thMM:
+ case MapUnit::Map10thMM:
+ case MapUnit::MapMM:
+ return FieldUnit::MM;
+
+ case MapUnit::MapCM:
+ return FieldUnit::CM;
+
+ case MapUnit::Map1000thInch:
+ case MapUnit::Map100thInch:
+ case MapUnit::Map10thInch:
+ case MapUnit::MapInch:
+ return FieldUnit::INCH;
+
+ case MapUnit::MapPoint:
+ return FieldUnit::POINT;
+
+ case MapUnit::MapTwip:
+ return FieldUnit::TWIP;
+ default: ;//prevent warning
+ }
+ return FieldUnit::NONE;
+}
+
+
+long CalcToPoint( long nIn, MapUnit eUnit, sal_uInt16 nFactor )
+{
+ DBG_ASSERT( eUnit == MapUnit::MapTwip ||
+ eUnit == MapUnit::Map100thMM ||
+ eUnit == MapUnit::Map10thMM ||
+ eUnit == MapUnit::MapMM ||
+ eUnit == MapUnit::MapCM, "this unit is not implemented" );
+
+ long nRet = 0;
+
+ if ( MapUnit::MapTwip == eUnit )
+ nRet = nIn;
+ else
+ nRet = nIn * 567;
+
+ switch ( eUnit )
+ {
+ case MapUnit::Map100thMM: nRet /= 100; break;
+ case MapUnit::Map10thMM: nRet /= 10; break;
+ case MapUnit::MapMM: break;
+ case MapUnit::MapCM: nRet *= 10; break;
+ default: ;//prevent warning
+ }
+
+ // round up if necessary
+ if ( MapUnit::MapTwip != eUnit )
+ {
+ long nTmp = nRet % 10;
+
+ if ( nTmp >= 4 )
+ nRet += 10 - nTmp;
+ nRet /= 10;
+ }
+ return nRet * nFactor / 20;
+}
+
+
+static long CMToTwips( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
+ nRet = nIn * 567;
+ return nRet;
+}
+
+
+static long MMToTwips( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
+ nRet = nIn * 567 / 10;
+ return nRet;
+}
+
+
+static long InchToTwips( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 1440 ) && nIn >= ( LONG_MIN / 1440 ) )
+ nRet = nIn * 1440;
+ return nRet;
+}
+
+
+long PointToTwips( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 20 ) && nIn >= ( LONG_MIN / 20 ) )
+ nRet = nIn * 20;
+ return nRet;
+}
+
+
+static long PicaToTwips( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 240 ) && nIn >= ( LONG_MIN / 240 ) )
+ nRet = nIn * 240;
+ return nRet;
+}
+
+
+static long TwipsToCM( long nIn )
+{
+ long nRet = nIn / 567;
+ return nRet;
+}
+
+
+static long InchToCM( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 254 ) && nIn >= ( LONG_MIN / 254 ) )
+ nRet = nIn * 254 / 100;
+ return nRet;
+}
+
+
+static long MMToCM( long nIn )
+{
+ long nRet = nIn / 10;
+ return nRet;
+}
+
+
+static long PointToCM( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 20 ) && nIn >= ( LONG_MIN / 20 ) )
+ nRet = nIn * 20 / 567;
+ return nRet;
+}
+
+
+static long PicaToCM( long nIn)
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 12 / 20 ) && nIn >= ( LONG_MIN / 12 / 20 ) )
+ nRet = nIn * 12 * 20 / 567;
+ return nRet;
+}
+
+
+static long TwipsToMM( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) )
+ nRet = nIn * 10 / 566;
+ return nRet;
+}
+
+
+static long CMToMM( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) )
+ nRet = nIn * 10;
+ return nRet;
+}
+
+
+static long InchToMM( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 254 ) && nIn >= ( LONG_MIN / 254 ) )
+ nRet = nIn * 254 / 10;
+ return nRet;
+}
+
+
+static long PointToMM( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 200 ) && nIn >= ( LONG_MIN / 200 ) )
+ nRet = nIn * 200 / 567;
+ return nRet;
+}
+
+
+static long PicaToMM( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 12 / 200 ) && nIn >= ( LONG_MIN / 12 / 200 ) )
+ nRet = nIn * 12 * 200 / 567;
+ return nRet;
+}
+
+
+static long TwipsToInch( long nIn )
+{
+ long nRet = nIn / 1440;
+ return nRet;
+}
+
+
+static long CMToInch( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 100 ) && nIn >= ( LONG_MIN / 100 ) )
+ nRet = nIn * 100 / 254;
+ return nRet;
+}
+
+
+static long MMToInch( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) )
+ nRet = nIn * 10 / 254;
+ return nRet;
+}
+
+
+static long PointToInch( long nIn )
+{
+ long nRet = nIn / 72;
+ return nRet;
+}
+
+
+static long PicaToInch( long nIn )
+{
+ long nRet = nIn / 6;
+ return nRet;
+}
+
+
+static long TwipsToPoint( long nIn )
+{
+ long nRet = nIn / 20;
+ return nRet;
+}
+
+
+static long InchToPoint( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 72 ) && nIn >= ( LONG_MIN / 72 ) )
+ nRet = nIn * 72;
+ return nRet;
+}
+
+
+static long CMToPoint( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
+ nRet = nIn * 567 / 20;
+ return nRet;
+}
+
+
+static long MMToPoint( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
+ nRet = nIn * 567 / 200;
+ return nRet;
+}
+
+
+static long PicaToPoint( long nIn )
+{
+ long nRet = nIn / 12;
+ return nRet;
+}
+
+
+static long TwipsToPica( long nIn )
+{
+ long nRet = nIn / 240;
+ return nRet;
+}
+
+
+static long InchToPica( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 6 ) && nIn >= ( LONG_MIN / 6 ) )
+ nRet = nIn * 6;
+ return nRet;
+}
+
+
+static long PointToPica( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 12 ) && nIn >= ( LONG_MIN / 12 ) )
+ nRet = nIn * 12;
+ return nRet;
+}
+
+
+static long CMToPica( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
+ nRet = nIn * 567 / 20 / 12;
+ return nRet;
+}
+
+
+static long MMToPica( long nIn )
+{
+ long nRet = 0;
+
+ if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
+ nRet = nIn * 567 / 200 / 12;
+ return nRet;
+}
+
+
+static long Nothing( long nIn )
+{
+ long nRet = nIn;
+ return nRet;
+}
+
+FUNC_CONVERT const ConvertTable[6][6] =
+{
+// CM, MM INCH POINT PICAS=32 TWIPS
+ { Nothing, CMToMM, CMToInch, CMToPoint, CMToPica, CMToTwips },
+ { MMToCM, Nothing, MMToInch, MMToPoint, MMToPica, MMToTwips },
+ { InchToCM, InchToMM, Nothing, InchToPoint, InchToPica, InchToTwips },
+ { PointToCM, PointToMM, PointToInch, Nothing, PointToPica, PointToTwips },
+ { PicaToCM, PicaToMM, PicaToInch, PicaToPoint, Nothing, PicaToTwips },
+ { TwipsToCM, TwipsToMM, TwipsToInch, TwipsToPoint,TwipsToPica, Nothing }
+};
+
+
+long TransformMetric( long nVal, FieldUnit aOld, FieldUnit aNew )
+{
+ if ( aOld == FieldUnit::NONE || aNew == FieldUnit::NONE ||
+ aOld == FieldUnit::CUSTOM || aNew == FieldUnit::CUSTOM )
+ {
+ return nVal;
+ }
+
+ sal_uInt16 nOld = 0;
+ sal_uInt16 nNew = 0;
+
+ switch ( aOld )
+ {
+ case FieldUnit::CM:
+ nOld = 0; break;
+ case FieldUnit::MM:
+ nOld = 1; break;
+ case FieldUnit::INCH:
+ nOld = 2; break;
+ case FieldUnit::POINT:
+ nOld = 3; break;
+ case FieldUnit::PICA:
+ nOld = 4; break;
+ case FieldUnit::TWIP:
+ nOld = 5; break;
+ default: ;//prevent warning
+ }
+
+ switch ( aNew )
+ {
+ case FieldUnit::CM:
+ nNew = 0; break;
+ case FieldUnit::MM:
+ nNew = 1; break;
+ case FieldUnit::INCH:
+ nNew = 2; break;
+ case FieldUnit::POINT:
+ nNew = 3; break;
+ case FieldUnit::PICA:
+ nNew = 4; break;
+ case FieldUnit::TWIP:
+ nNew = 5; break;
+ default: ;//prevent warning
+ }
+ return ConvertTable[nOld][nNew]( nVal );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */