Bump version to 5.0-14
[LibreOffice.git] / svtools / source / misc / unitconv.cxx
blob190cb0f8d05bede16c35c66b1d441e3f850d9cd3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 ) );
31 if ( !bAll )
33 switch ( eUnit )
35 case FUNIT_M:
36 case FUNIT_KM:
37 eUnit = FUNIT_CM;
38 break;
40 case FUNIT_FOOT:
41 case FUNIT_MILE:
42 eUnit = FUNIT_INCH;
43 break;
44 default: ;//prevent warning
47 rField.SetUnit( eUnit );
48 switch( eUnit )
50 // _CHAR and _LINE sets the step of "char" and "line" unit, they are same as FUNIT_MM
51 case FUNIT_CHAR:
52 case FUNIT_LINE:
53 case FUNIT_MM:
54 rField.SetSpinSize( 50 );
55 break;
57 case FUNIT_INCH:
58 rField.SetSpinSize( 2 );
59 break;
61 default:
62 rField.SetSpinSize( 10 );
65 if ( FUNIT_POINT == eUnit )
67 if( rField.GetDecimalDigits() > 1 )
68 rField.SetDecimalDigits( 1 );
70 else
71 rField.SetDecimalDigits( 2 );
73 if ( !bAll )
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 ) );
89 if ( !bAll )
91 switch ( eUnit )
93 case FUNIT_M:
94 case FUNIT_KM:
95 eUnit = FUNIT_CM;
96 break;
98 case FUNIT_FOOT:
99 case FUNIT_MILE:
100 eUnit = FUNIT_INCH;
101 break;
102 default: ;//prevent warning
105 rBox.SetUnit( eUnit );
107 if ( FUNIT_POINT == eUnit && rBox.GetDecimalDigits() > 1 )
108 rBox.SetDecimalDigits( 1 );
109 else
110 rBox.SetDecimalDigits( 2 );
112 if ( !bAll )
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;
136 if( nVal >= 0 )
138 if( (nVal & nSizeMask) == 0 )
139 bRoundBefore = false;
141 else
143 if( ((-nVal) & nSizeMask ) == 0 )
144 bRoundBefore = false;
146 if( bRoundBefore )
147 nVal = rField.Denormalize( nVal );
148 sal_Int64 nUnitVal = OutputDevice::LogicToLogic( static_cast<long>(nVal), MAP_100TH_MM, (MapUnit)eUnit );
149 if( ! bRoundBefore )
150 nUnitVal = rField.Denormalize( nUnitVal );
151 return static_cast<long>(nUnitVal);
156 long CalcToUnit( float nIn, SfxMapUnit eUnit )
158 // nIn ist in Points
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" );
166 float nTmp = nIn;
168 if ( SFX_MAPUNIT_TWIP != eUnit )
169 nTmp = nIn * 10 / 567;
171 switch ( eUnit )
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
180 nTmp *= 20;
181 long nRet = (long)nTmp;
182 return nRet;
183 //! return (long)(nTmp * 20);
188 long ItemToControl( long nIn, SfxMapUnit eItem, FieldUnit eCtrl )
190 long nOut = 0;
192 switch ( eItem )
194 case SFX_MAPUNIT_100TH_MM:
195 case SFX_MAPUNIT_10TH_MM:
196 case SFX_MAPUNIT_MM:
198 if ( eItem == SFX_MAPUNIT_10TH_MM )
199 nIn /= 10;
200 else if ( eItem == SFX_MAPUNIT_100TH_MM )
201 nIn /= 100;
202 nOut = TransformMetric( nIn, FUNIT_MM, eCtrl );
204 break;
206 case SFX_MAPUNIT_CM:
208 nOut = TransformMetric( nIn, FUNIT_CM, eCtrl );
210 break;
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 )
218 nIn /= 10;
219 else if ( eItem == SFX_MAPUNIT_100TH_INCH )
220 nIn /= 100;
221 else if ( eItem == SFX_MAPUNIT_1000TH_INCH )
222 nIn /= 1000;
223 nOut = TransformMetric( nIn, FUNIT_INCH, eCtrl );
225 break;
227 case SFX_MAPUNIT_POINT:
229 nOut = TransformMetric( nIn, FUNIT_POINT, eCtrl );
231 break;
233 case SFX_MAPUNIT_TWIP:
235 nOut = TransformMetric( nIn, FUNIT_TWIP, eCtrl );
237 break;
238 default: ;//prevent warning
240 return nOut;
245 long ControlToItem( long nIn, FieldUnit eCtrl, SfxMapUnit eItem )
247 return ItemToControl( nIn, eItem, eCtrl );
252 FieldUnit MapToFieldUnit( const SfxMapUnit eUnit )
254 switch ( eUnit )
256 case SFX_MAPUNIT_100TH_MM:
257 case SFX_MAPUNIT_10TH_MM:
258 case SFX_MAPUNIT_MM:
259 return FUNIT_MM;
261 case SFX_MAPUNIT_CM:
262 return FUNIT_CM;
264 case SFX_MAPUNIT_1000TH_INCH:
265 case SFX_MAPUNIT_100TH_INCH:
266 case SFX_MAPUNIT_10TH_INCH:
267 case SFX_MAPUNIT_INCH:
268 return FUNIT_INCH;
270 case SFX_MAPUNIT_POINT:
271 return FUNIT_POINT;
273 case SFX_MAPUNIT_TWIP:
274 return FUNIT_TWIP;
275 default: ;//prevent warning
277 return FUNIT_NONE;
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" );
290 long nRet = 0;
292 if ( SFX_MAPUNIT_TWIP == eUnit )
293 nRet = nIn;
294 else
295 nRet = nIn * 567;
297 switch ( 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
306 // ggf. aufrunden
307 if ( SFX_MAPUNIT_TWIP != eUnit )
309 long nMod = 10;
310 long nTmp = nRet % nMod;
312 if ( nTmp >= 4 )
313 nRet += 10 - nTmp;
314 nRet /= 10;
316 return nRet * nFactor / 20;
321 long CMToTwips( long nIn )
323 long nRet = 0;
325 if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
326 nRet = nIn * 567;
327 return nRet;
332 long MMToTwips( long nIn )
334 long nRet = 0;
336 if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
337 nRet = nIn * 567 / 10;
338 return nRet;
343 long InchToTwips( long nIn )
345 long nRet = 0;
347 if ( nIn <= ( LONG_MAX / 1440 ) && nIn >= ( LONG_MIN / 1440 ) )
348 nRet = nIn * 1440;
349 return nRet;
354 long PointToTwips( long nIn )
356 long nRet = 0;
358 if ( nIn <= ( LONG_MAX / 20 ) && nIn >= ( LONG_MIN / 20 ) )
359 nRet = nIn * 20;
360 return nRet;
365 long PicaToTwips( long nIn )
367 long nRet = 0;
369 if ( nIn <= ( LONG_MAX / 240 ) && nIn >= ( LONG_MIN / 240 ) )
370 nRet = nIn * 240;
371 return nRet;
376 long TwipsToCM( long nIn )
378 long nRet = nIn / 567;
379 return nRet;
384 long InchToCM( long nIn )
386 long nRet = 0;
388 if ( nIn <= ( LONG_MAX / 254 ) && nIn >= ( LONG_MIN / 254 ) )
389 nRet = nIn * 254 / 100;
390 return nRet;
395 long MMToCM( long nIn )
397 long nRet = nIn / 10;
398 return nRet;
403 long PointToCM( long nIn )
405 long nRet = 0;
407 if ( nIn <= ( LONG_MAX / 20 ) && nIn >= ( LONG_MIN / 20 ) )
408 nRet = nIn * 20 / 567;
409 return nRet;
414 long PicaToCM( long nIn)
416 long nRet = 0;
418 if ( nIn <= ( LONG_MAX / 12 / 20 ) && nIn >= ( LONG_MIN / 12 / 20 ) )
419 nRet = nIn * 12 * 20 / 567;
420 return nRet;
425 long TwipsToMM( long nIn )
427 long nRet = 0;
429 if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) )
430 nRet = nIn * 10 / 566;
431 return nRet;
436 long CMToMM( long nIn )
438 long nRet = 0;
440 if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) )
441 nRet = nIn * 10;
442 return nRet;
447 long InchToMM( long nIn )
449 long nRet = 0;
451 if ( nIn <= ( LONG_MAX / 254 ) && nIn >= ( LONG_MIN / 254 ) )
452 nRet = nIn * 254 / 10;
453 return nRet;
458 long PointToMM( long nIn )
460 long nRet = 0;
462 if ( nIn <= ( LONG_MAX / 200 ) && nIn >= ( LONG_MIN / 200 ) )
463 nRet = nIn * 200 / 567;
464 return nRet;
469 long PicaToMM( long nIn )
471 long nRet = 0;
473 if ( nIn <= ( LONG_MAX / 12 / 200 ) && nIn >= ( LONG_MIN / 12 / 200 ) )
474 nRet = nIn * 12 * 200 / 567;
475 return nRet;
480 long TwipsToInch( long nIn )
482 long nRet = nIn / 1440;
483 return nRet;
488 long CMToInch( long nIn )
490 long nRet = 0;
492 if ( nIn <= ( LONG_MAX / 100 ) && nIn >= ( LONG_MIN / 100 ) )
493 nRet = nIn * 100 / 254;
494 return nRet;
499 long MMToInch( long nIn )
501 long nRet = 0;
503 if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) )
504 nRet = nIn * 10 / 254;
505 return nRet;
510 long PointToInch( long nIn )
512 long nRet = nIn / 72;
513 return nRet;
518 long PicaToInch( long nIn )
520 long nRet = nIn / 6;
521 return nRet;
526 long TwipsToPoint( long nIn )
528 long nRet = nIn / 20;
529 return nRet;
534 long InchToPoint( long nIn )
536 long nRet = 0;
538 if ( nIn <= ( LONG_MAX / 72 ) && nIn >= ( LONG_MIN / 72 ) )
539 nRet = nIn * 72;
540 return nRet;
545 long CMToPoint( long nIn )
547 long nRet = 0;
549 if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
550 nRet = nIn * 567 / 20;
551 return nRet;
556 long MMToPoint( long nIn )
558 long nRet = 0;
560 if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
561 nRet = nIn * 567 / 200;
562 return nRet;
567 long PicaToPoint( long nIn )
569 long nRet = nIn / 12;
570 return nRet;
575 long TwipsToPica( long nIn )
577 long nRet = nIn / 240;
578 return nRet;
583 long InchToPica( long nIn )
585 long nRet = 0;
587 if ( nIn <= ( LONG_MAX / 6 ) && nIn >= ( LONG_MIN / 6 ) )
588 nRet = nIn * 6;
589 return nRet;
594 long PointToPica( long nIn )
596 long nRet = 0;
598 if ( nIn <= ( LONG_MAX / 12 ) && nIn >= ( LONG_MIN / 12 ) )
599 nRet = nIn * 12;
600 return nRet;
605 long CMToPica( long nIn )
607 long nRet = 0;
609 if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
610 nRet = nIn * 567 / 20 / 12;
611 return nRet;
616 long MMToPica( long nIn )
618 long nRet = 0;
620 if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
621 nRet = nIn * 567 / 200 / 12;
622 return nRet;
627 long Nothing( long nIn )
629 long nRet = nIn;
630 return nRet;
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 )
651 return nVal;
654 sal_uInt16 nOld = 0;
655 sal_uInt16 nNew = 0;
657 switch ( aOld )
659 case FUNIT_CM:
660 nOld = 0; break;
661 case FUNIT_MM:
662 nOld = 1; break;
663 case FUNIT_INCH:
664 nOld = 2; break;
665 case FUNIT_POINT:
666 nOld = 3; break;
667 case FUNIT_PICA:
668 nOld = 4; break;
669 case FUNIT_TWIP:
670 nOld = 5; break;
671 default: ;//prevent warning
674 switch ( aNew )
676 case FUNIT_CM:
677 nNew = 0; break;
678 case FUNIT_MM:
679 nNew = 1; break;
680 case FUNIT_INCH:
681 nNew = 2; break;
682 case FUNIT_POINT:
683 nNew = 3; break;
684 case FUNIT_PICA:
685 nNew = 4; break;
686 case FUNIT_TWIP:
687 nNew = 5; break;
688 default: ;//prevent warning
690 return ConvertTable[nOld][nNew]( nVal );
693 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */