1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svtools/unitconv.hxx>
24 void SetFieldUnit( MetricField
& rField
, FieldUnit eUnit
, bool bAll
)
26 sal_Int64 nFirst
= rField
.Denormalize( rField
.GetFirst( FUNIT_TWIP
) );
27 sal_Int64 nLast
= rField
.Denormalize( rField
.GetLast( FUNIT_TWIP
) );
28 sal_Int64 nMin
= rField
.Denormalize( rField
.GetMin( FUNIT_TWIP
) );
29 sal_Int64 nMax
= rField
.Denormalize( rField
.GetMax( FUNIT_TWIP
) );
44 default: ;//prevent warning
47 rField
.SetUnit( eUnit
);
50 // _CHAR and _LINE sets the step of "char" and "line" unit, they are same as FUNIT_MM
54 rField
.SetSpinSize( 50 );
58 rField
.SetSpinSize( 2 );
62 rField
.SetSpinSize( 10 );
65 if ( FUNIT_POINT
== eUnit
)
67 if( rField
.GetDecimalDigits() > 1 )
68 rField
.SetDecimalDigits( 1 );
71 rField
.SetDecimalDigits( 2 );
75 rField
.SetFirst( rField
.Normalize( nFirst
), FUNIT_TWIP
);
76 rField
.SetLast( rField
.Normalize( nLast
), FUNIT_TWIP
);
77 rField
.SetMin( rField
.Normalize( nMin
), FUNIT_TWIP
);
78 rField
.SetMax( rField
.Normalize( nMax
), FUNIT_TWIP
);
84 void SetFieldUnit( MetricBox
& rBox
, FieldUnit eUnit
, bool bAll
)
86 sal_Int64 nMin
= rBox
.Denormalize( rBox
.GetMin( FUNIT_TWIP
) );
87 sal_Int64 nMax
= rBox
.Denormalize( rBox
.GetMax( FUNIT_TWIP
) );
102 default: ;//prevent warning
105 rBox
.SetUnit( eUnit
);
107 if ( FUNIT_POINT
== eUnit
&& rBox
.GetDecimalDigits() > 1 )
108 rBox
.SetDecimalDigits( 1 );
110 rBox
.SetDecimalDigits( 2 );
114 rBox
.SetMin( rBox
.Normalize( nMin
), FUNIT_TWIP
);
115 rBox
.SetMax( rBox
.Normalize( nMax
), FUNIT_TWIP
);
120 void SetMetricValue( MetricField
& rField
, long nCoreValue
, SfxMapUnit eUnit
)
122 sal_Int64 nVal
= OutputDevice::LogicToLogic( nCoreValue
, (MapUnit
)eUnit
, MAP_100TH_MM
);
123 nVal
= rField
.Normalize( nVal
);
124 rField
.SetValue( nVal
, FUNIT_100TH_MM
);
130 long GetCoreValue( const MetricField
& rField
, SfxMapUnit eUnit
)
132 sal_Int64 nVal
= rField
.GetValue( FUNIT_100TH_MM
);
133 // avoid rounding issues
134 const sal_Int64 nSizeMask
= 0xffffffffff000000LL
;
135 bool bRoundBefore
= true;
138 if( (nVal
& nSizeMask
) == 0 )
139 bRoundBefore
= false;
143 if( ((-nVal
) & nSizeMask
) == 0 )
144 bRoundBefore
= false;
147 nVal
= rField
.Denormalize( nVal
);
148 sal_Int64 nUnitVal
= OutputDevice::LogicToLogic( static_cast<long>(nVal
), MAP_100TH_MM
, (MapUnit
)eUnit
);
150 nUnitVal
= rField
.Denormalize( nUnitVal
);
151 return static_cast<long>(nUnitVal
);
156 long CalcToUnit( float nIn
, SfxMapUnit eUnit
)
160 DBG_ASSERT( eUnit
== SFX_MAPUNIT_TWIP
||
161 eUnit
== SFX_MAPUNIT_100TH_MM
||
162 eUnit
== SFX_MAPUNIT_10TH_MM
||
163 eUnit
== SFX_MAPUNIT_MM
||
164 eUnit
== SFX_MAPUNIT_CM
, "this unit is not implemented" );
168 if ( SFX_MAPUNIT_TWIP
!= eUnit
)
169 nTmp
= nIn
* 10 / 567;
173 case SFX_MAPUNIT_100TH_MM
: nTmp
*= 100; break;
174 case SFX_MAPUNIT_10TH_MM
: nTmp
*= 10; break;
175 case SFX_MAPUNIT_MM
: break;
176 case SFX_MAPUNIT_CM
: nTmp
/= 10; break;
177 default: ;//prevent warning
181 long nRet
= (long)nTmp
;
183 //! return (long)(nTmp * 20);
188 long ItemToControl( long nIn
, SfxMapUnit eItem
, FieldUnit eCtrl
)
194 case SFX_MAPUNIT_100TH_MM
:
195 case SFX_MAPUNIT_10TH_MM
:
198 if ( eItem
== SFX_MAPUNIT_10TH_MM
)
200 else if ( eItem
== SFX_MAPUNIT_100TH_MM
)
202 nOut
= TransformMetric( nIn
, FUNIT_MM
, eCtrl
);
208 nOut
= TransformMetric( nIn
, FUNIT_CM
, eCtrl
);
212 case SFX_MAPUNIT_1000TH_INCH
:
213 case SFX_MAPUNIT_100TH_INCH
:
214 case SFX_MAPUNIT_10TH_INCH
:
215 case SFX_MAPUNIT_INCH
:
217 if ( eItem
== SFX_MAPUNIT_10TH_INCH
)
219 else if ( eItem
== SFX_MAPUNIT_100TH_INCH
)
221 else if ( eItem
== SFX_MAPUNIT_1000TH_INCH
)
223 nOut
= TransformMetric( nIn
, FUNIT_INCH
, eCtrl
);
227 case SFX_MAPUNIT_POINT
:
229 nOut
= TransformMetric( nIn
, FUNIT_POINT
, eCtrl
);
233 case SFX_MAPUNIT_TWIP
:
235 nOut
= TransformMetric( nIn
, FUNIT_TWIP
, eCtrl
);
238 default: ;//prevent warning
245 long ControlToItem( long nIn
, FieldUnit eCtrl
, SfxMapUnit eItem
)
247 return ItemToControl( nIn
, eItem
, eCtrl
);
252 FieldUnit
MapToFieldUnit( const SfxMapUnit eUnit
)
256 case SFX_MAPUNIT_100TH_MM
:
257 case SFX_MAPUNIT_10TH_MM
:
264 case SFX_MAPUNIT_1000TH_INCH
:
265 case SFX_MAPUNIT_100TH_INCH
:
266 case SFX_MAPUNIT_10TH_INCH
:
267 case SFX_MAPUNIT_INCH
:
270 case SFX_MAPUNIT_POINT
:
273 case SFX_MAPUNIT_TWIP
:
275 default: ;//prevent warning
282 long CalcToPoint( long nIn
, SfxMapUnit eUnit
, sal_uInt16 nFactor
)
284 DBG_ASSERT( eUnit
== SFX_MAPUNIT_TWIP
||
285 eUnit
== SFX_MAPUNIT_100TH_MM
||
286 eUnit
== SFX_MAPUNIT_10TH_MM
||
287 eUnit
== SFX_MAPUNIT_MM
||
288 eUnit
== SFX_MAPUNIT_CM
, "this unit is not implemented" );
292 if ( SFX_MAPUNIT_TWIP
== eUnit
)
299 case SFX_MAPUNIT_100TH_MM
: nRet
/= 100; break;
300 case SFX_MAPUNIT_10TH_MM
: nRet
/= 10; break;
301 case SFX_MAPUNIT_MM
: break;
302 case SFX_MAPUNIT_CM
: nRet
*= 10; break;
303 default: ;//prevent warning
307 if ( SFX_MAPUNIT_TWIP
!= eUnit
)
310 long nTmp
= nRet
% nMod
;
316 return nRet
* nFactor
/ 20;
321 long CMToTwips( long nIn
)
325 if ( nIn
<= ( LONG_MAX
/ 567 ) && nIn
>= ( LONG_MIN
/ 567 ) )
332 long MMToTwips( long nIn
)
336 if ( nIn
<= ( LONG_MAX
/ 567 ) && nIn
>= ( LONG_MIN
/ 567 ) )
337 nRet
= nIn
* 567 / 10;
343 long InchToTwips( long nIn
)
347 if ( nIn
<= ( LONG_MAX
/ 1440 ) && nIn
>= ( LONG_MIN
/ 1440 ) )
354 long PointToTwips( long nIn
)
358 if ( nIn
<= ( LONG_MAX
/ 20 ) && nIn
>= ( LONG_MIN
/ 20 ) )
365 long PicaToTwips( long nIn
)
369 if ( nIn
<= ( LONG_MAX
/ 240 ) && nIn
>= ( LONG_MIN
/ 240 ) )
376 long TwipsToCM( long nIn
)
378 long nRet
= nIn
/ 567;
384 long InchToCM( long nIn
)
388 if ( nIn
<= ( LONG_MAX
/ 254 ) && nIn
>= ( LONG_MIN
/ 254 ) )
389 nRet
= nIn
* 254 / 100;
395 long MMToCM( long nIn
)
397 long nRet
= nIn
/ 10;
403 long PointToCM( long nIn
)
407 if ( nIn
<= ( LONG_MAX
/ 20 ) && nIn
>= ( LONG_MIN
/ 20 ) )
408 nRet
= nIn
* 20 / 567;
414 long PicaToCM( long nIn
)
418 if ( nIn
<= ( LONG_MAX
/ 12 / 20 ) && nIn
>= ( LONG_MIN
/ 12 / 20 ) )
419 nRet
= nIn
* 12 * 20 / 567;
425 long TwipsToMM( long nIn
)
429 if ( nIn
<= ( LONG_MAX
/ 10 ) && nIn
>= ( LONG_MIN
/ 10 ) )
430 nRet
= nIn
* 10 / 566;
436 long CMToMM( long nIn
)
440 if ( nIn
<= ( LONG_MAX
/ 10 ) && nIn
>= ( LONG_MIN
/ 10 ) )
447 long InchToMM( long nIn
)
451 if ( nIn
<= ( LONG_MAX
/ 254 ) && nIn
>= ( LONG_MIN
/ 254 ) )
452 nRet
= nIn
* 254 / 10;
458 long PointToMM( long nIn
)
462 if ( nIn
<= ( LONG_MAX
/ 200 ) && nIn
>= ( LONG_MIN
/ 200 ) )
463 nRet
= nIn
* 200 / 567;
469 long PicaToMM( long nIn
)
473 if ( nIn
<= ( LONG_MAX
/ 12 / 200 ) && nIn
>= ( LONG_MIN
/ 12 / 200 ) )
474 nRet
= nIn
* 12 * 200 / 567;
480 long TwipsToInch( long nIn
)
482 long nRet
= nIn
/ 1440;
488 long CMToInch( long nIn
)
492 if ( nIn
<= ( LONG_MAX
/ 100 ) && nIn
>= ( LONG_MIN
/ 100 ) )
493 nRet
= nIn
* 100 / 254;
499 long MMToInch( long nIn
)
503 if ( nIn
<= ( LONG_MAX
/ 10 ) && nIn
>= ( LONG_MIN
/ 10 ) )
504 nRet
= nIn
* 10 / 254;
510 long PointToInch( long nIn
)
512 long nRet
= nIn
/ 72;
518 long PicaToInch( long nIn
)
526 long TwipsToPoint( long nIn
)
528 long nRet
= nIn
/ 20;
534 long InchToPoint( long nIn
)
538 if ( nIn
<= ( LONG_MAX
/ 72 ) && nIn
>= ( LONG_MIN
/ 72 ) )
545 long CMToPoint( long nIn
)
549 if ( nIn
<= ( LONG_MAX
/ 567 ) && nIn
>= ( LONG_MIN
/ 567 ) )
550 nRet
= nIn
* 567 / 20;
556 long MMToPoint( long nIn
)
560 if ( nIn
<= ( LONG_MAX
/ 567 ) && nIn
>= ( LONG_MIN
/ 567 ) )
561 nRet
= nIn
* 567 / 200;
567 long PicaToPoint( long nIn
)
569 long nRet
= nIn
/ 12;
575 long TwipsToPica( long nIn
)
577 long nRet
= nIn
/ 240;
583 long InchToPica( long nIn
)
587 if ( nIn
<= ( LONG_MAX
/ 6 ) && nIn
>= ( LONG_MIN
/ 6 ) )
594 long PointToPica( long nIn
)
598 if ( nIn
<= ( LONG_MAX
/ 12 ) && nIn
>= ( LONG_MIN
/ 12 ) )
605 long CMToPica( long nIn
)
609 if ( nIn
<= ( LONG_MAX
/ 567 ) && nIn
>= ( LONG_MIN
/ 567 ) )
610 nRet
= nIn
* 567 / 20 / 12;
616 long MMToPica( long nIn
)
620 if ( nIn
<= ( LONG_MAX
/ 567 ) && nIn
>= ( LONG_MIN
/ 567 ) )
621 nRet
= nIn
* 567 / 200 / 12;
627 long Nothing( long nIn
)
633 FUNC_CONVERT ConvertTable
[6][6] =
635 // CM, MM INCH POINT PICAS=32 TWIPS
636 { Nothing
, CMToMM
, CMToInch
, CMToPoint
, CMToPica
, CMToTwips
},
637 { MMToCM
, Nothing
, MMToInch
, MMToPoint
, MMToPica
, MMToTwips
},
638 { InchToCM
, InchToMM
, Nothing
, InchToPoint
, InchToPica
, InchToTwips
},
639 { PointToCM
, PointToMM
, PointToInch
, Nothing
, PointToPica
, PointToTwips
},
640 { PicaToCM
, PicaToMM
, PicaToInch
, PicaToPoint
, Nothing
, PicaToTwips
},
641 { TwipsToCM
, TwipsToMM
, TwipsToInch
, TwipsToPoint
,TwipsToPica
, Nothing
}
646 long TransformMetric( long nVal
, FieldUnit aOld
, FieldUnit aNew
)
648 if ( aOld
== FUNIT_NONE
|| aNew
== FUNIT_NONE
||
649 aOld
== FUNIT_CUSTOM
|| aNew
== FUNIT_CUSTOM
)
671 default: ;//prevent warning
688 default: ;//prevent warning
690 return ConvertTable
[nOld
][nNew
]( nVal
);
693 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */