Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <svtools/unitconv.hxx>
21 :
22 :
23 :
24 0 : void SetFieldUnit( MetricField& rField, FieldUnit eUnit, bool bAll )
25 : {
26 0 : sal_Int64 nFirst = rField.Denormalize( rField.GetFirst( FUNIT_TWIP ) );
27 0 : sal_Int64 nLast = rField.Denormalize( rField.GetLast( FUNIT_TWIP ) );
28 0 : sal_Int64 nMin = rField.Denormalize( rField.GetMin( FUNIT_TWIP ) );
29 0 : sal_Int64 nMax = rField.Denormalize( rField.GetMax( FUNIT_TWIP ) );
30 :
31 0 : if ( !bAll )
32 : {
33 0 : switch ( eUnit )
34 : {
35 : case FUNIT_M:
36 : case FUNIT_KM:
37 0 : eUnit = FUNIT_CM;
38 0 : break;
39 :
40 : case FUNIT_FOOT:
41 : case FUNIT_MILE:
42 0 : eUnit = FUNIT_INCH;
43 0 : break;
44 : default: ;//prevent warning
45 : }
46 : }
47 0 : rField.SetUnit( eUnit );
48 0 : switch( eUnit )
49 : {
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 0 : rField.SetSpinSize( 50 );
55 0 : break;
56 :
57 : case FUNIT_INCH:
58 0 : rField.SetSpinSize( 2 );
59 0 : break;
60 :
61 : default:
62 0 : rField.SetSpinSize( 10 );
63 : }
64 :
65 0 : if ( FUNIT_POINT == eUnit )
66 : {
67 0 : if( rField.GetDecimalDigits() > 1 )
68 0 : rField.SetDecimalDigits( 1 );
69 : }
70 : else
71 0 : rField.SetDecimalDigits( 2 );
72 :
73 0 : if ( !bAll )
74 : {
75 0 : rField.SetFirst( rField.Normalize( nFirst ), FUNIT_TWIP );
76 0 : rField.SetLast( rField.Normalize( nLast ), FUNIT_TWIP );
77 0 : rField.SetMin( rField.Normalize( nMin ), FUNIT_TWIP );
78 0 : rField.SetMax( rField.Normalize( nMax ), FUNIT_TWIP );
79 : }
80 0 : }
81 :
82 :
83 :
84 0 : void SetFieldUnit( MetricBox& rBox, FieldUnit eUnit, bool bAll )
85 : {
86 0 : sal_Int64 nMin = rBox.Denormalize( rBox.GetMin( FUNIT_TWIP ) );
87 0 : sal_Int64 nMax = rBox.Denormalize( rBox.GetMax( FUNIT_TWIP ) );
88 :
89 0 : if ( !bAll )
90 : {
91 0 : switch ( eUnit )
92 : {
93 : case FUNIT_M:
94 : case FUNIT_KM:
95 0 : eUnit = FUNIT_CM;
96 0 : break;
97 :
98 : case FUNIT_FOOT:
99 : case FUNIT_MILE:
100 0 : eUnit = FUNIT_INCH;
101 0 : break;
102 : default: ;//prevent warning
103 : }
104 : }
105 0 : rBox.SetUnit( eUnit );
106 :
107 0 : if ( FUNIT_POINT == eUnit && rBox.GetDecimalDigits() > 1 )
108 0 : rBox.SetDecimalDigits( 1 );
109 : else
110 0 : rBox.SetDecimalDigits( 2 );
111 :
112 0 : if ( !bAll )
113 : {
114 0 : rBox.SetMin( rBox.Normalize( nMin ), FUNIT_TWIP );
115 0 : rBox.SetMax( rBox.Normalize( nMax ), FUNIT_TWIP );
116 : }
117 0 : }
118 :
119 :
120 0 : void SetMetricValue( MetricField& rField, long nCoreValue, SfxMapUnit eUnit )
121 : {
122 0 : sal_Int64 nVal = OutputDevice::LogicToLogic( nCoreValue, (MapUnit)eUnit, MAP_100TH_MM );
123 0 : nVal = rField.Normalize( nVal );
124 0 : rField.SetValue( nVal, FUNIT_100TH_MM );
125 :
126 0 : }
127 :
128 :
129 :
130 0 : long GetCoreValue( const MetricField& rField, SfxMapUnit eUnit )
131 : {
132 0 : sal_Int64 nVal = rField.GetValue( FUNIT_100TH_MM );
133 : // avoid rounding issues
134 0 : const sal_Int64 nSizeMask = 0xffffffffff000000LL;
135 0 : bool bRoundBefore = true;
136 0 : if( nVal >= 0 )
137 : {
138 0 : if( (nVal & nSizeMask) == 0 )
139 0 : bRoundBefore = false;
140 : }
141 : else
142 : {
143 0 : if( ((-nVal) & nSizeMask ) == 0 )
144 0 : bRoundBefore = false;
145 : }
146 0 : if( bRoundBefore )
147 0 : nVal = rField.Denormalize( nVal );
148 0 : sal_Int64 nUnitVal = OutputDevice::LogicToLogic( static_cast<long>(nVal), MAP_100TH_MM, (MapUnit)eUnit );
149 0 : if( ! bRoundBefore )
150 0 : nUnitVal = rField.Denormalize( nUnitVal );
151 0 : return static_cast<long>(nUnitVal);
152 : }
153 :
154 :
155 :
156 0 : long CalcToUnit( float nIn, SfxMapUnit eUnit )
157 : {
158 : // nIn ist in Points
159 :
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" );
165 :
166 0 : float nTmp = nIn;
167 :
168 0 : if ( SFX_MAPUNIT_TWIP != eUnit )
169 0 : nTmp = nIn * 10 / 567;
170 :
171 0 : switch ( eUnit )
172 : {
173 0 : case SFX_MAPUNIT_100TH_MM: nTmp *= 100; break;
174 0 : case SFX_MAPUNIT_10TH_MM: nTmp *= 10; break;
175 0 : case SFX_MAPUNIT_MM: break;
176 0 : case SFX_MAPUNIT_CM: nTmp /= 10; break;
177 : default: ;//prevent warning
178 : }
179 :
180 0 : nTmp *= 20;
181 0 : long nRet = (long)nTmp;
182 0 : return nRet;
183 : //! return (long)(nTmp * 20);
184 : }
185 :
186 :
187 :
188 0 : long ItemToControl( long nIn, SfxMapUnit eItem, SfxFieldUnit eCtrl )
189 : {
190 0 : long nOut = 0;
191 :
192 0 : switch ( eItem )
193 : {
194 : case SFX_MAPUNIT_100TH_MM:
195 : case SFX_MAPUNIT_10TH_MM:
196 : case SFX_MAPUNIT_MM:
197 : {
198 0 : if ( eItem == SFX_MAPUNIT_10TH_MM )
199 0 : nIn /= 10;
200 0 : else if ( eItem == SFX_MAPUNIT_100TH_MM )
201 0 : nIn /= 100;
202 0 : nOut = TransformMetric( nIn, FUNIT_MM, (FieldUnit)eCtrl );
203 : }
204 0 : break;
205 :
206 : case SFX_MAPUNIT_CM:
207 : {
208 0 : nOut = TransformMetric( nIn, FUNIT_CM, (FieldUnit)eCtrl );
209 : }
210 0 : break;
211 :
212 : case SFX_MAPUNIT_1000TH_INCH:
213 : case SFX_MAPUNIT_100TH_INCH:
214 : case SFX_MAPUNIT_10TH_INCH:
215 : case SFX_MAPUNIT_INCH:
216 : {
217 0 : if ( eItem == SFX_MAPUNIT_10TH_INCH )
218 0 : nIn /= 10;
219 0 : else if ( eItem == SFX_MAPUNIT_100TH_INCH )
220 0 : nIn /= 100;
221 0 : else if ( eItem == SFX_MAPUNIT_1000TH_INCH )
222 0 : nIn /= 1000;
223 0 : nOut = TransformMetric( nIn, FUNIT_INCH, (FieldUnit)eCtrl );
224 : }
225 0 : break;
226 :
227 : case SFX_MAPUNIT_POINT:
228 : {
229 0 : nOut = TransformMetric( nIn, FUNIT_POINT, (FieldUnit)eCtrl );
230 : }
231 0 : break;
232 :
233 : case SFX_MAPUNIT_TWIP:
234 : {
235 0 : nOut = TransformMetric( nIn, FUNIT_TWIP, (FieldUnit)eCtrl );
236 : }
237 0 : break;
238 : default: ;//prevent warning
239 : }
240 0 : return nOut;
241 : }
242 :
243 :
244 :
245 0 : long ControlToItem( long nIn, SfxFieldUnit eCtrl, SfxMapUnit eItem )
246 : {
247 0 : return ItemToControl( nIn, eItem, eCtrl );
248 : }
249 :
250 :
251 :
252 0 : FieldUnit MapToFieldUnit( const SfxMapUnit eUnit )
253 : {
254 0 : switch ( eUnit )
255 : {
256 : case SFX_MAPUNIT_100TH_MM:
257 : case SFX_MAPUNIT_10TH_MM:
258 : case SFX_MAPUNIT_MM:
259 0 : return FUNIT_MM;
260 :
261 : case SFX_MAPUNIT_CM:
262 0 : return FUNIT_CM;
263 :
264 : case SFX_MAPUNIT_1000TH_INCH:
265 : case SFX_MAPUNIT_100TH_INCH:
266 : case SFX_MAPUNIT_10TH_INCH:
267 : case SFX_MAPUNIT_INCH:
268 0 : return FUNIT_INCH;
269 :
270 : case SFX_MAPUNIT_POINT:
271 0 : return FUNIT_POINT;
272 :
273 : case SFX_MAPUNIT_TWIP:
274 0 : return FUNIT_TWIP;
275 : default: ;//prevent warning
276 : }
277 0 : return FUNIT_NONE;
278 : }
279 :
280 :
281 :
282 0 : long CalcToPoint( long nIn, SfxMapUnit eUnit, sal_uInt16 nFactor )
283 : {
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" );
289 :
290 0 : long nRet = 0;
291 :
292 0 : if ( SFX_MAPUNIT_TWIP == eUnit )
293 0 : nRet = nIn;
294 : else
295 0 : nRet = nIn * 567;
296 :
297 0 : switch ( eUnit )
298 : {
299 0 : case SFX_MAPUNIT_100TH_MM: nRet /= 100; break;
300 0 : case SFX_MAPUNIT_10TH_MM: nRet /= 10; break;
301 0 : case SFX_MAPUNIT_MM: break;
302 0 : case SFX_MAPUNIT_CM: nRet *= 10; break;
303 : default: ;//prevent warning
304 : }
305 :
306 : // ggf. aufrunden
307 0 : if ( SFX_MAPUNIT_TWIP != eUnit )
308 : {
309 0 : long nMod = 10;
310 0 : long nTmp = nRet % nMod;
311 :
312 0 : if ( nTmp >= 4 )
313 0 : nRet += 10 - nTmp;
314 0 : nRet /= 10;
315 : }
316 0 : return nRet * nFactor / 20;
317 : }
318 :
319 :
320 :
321 0 : long CMToTwips( long nIn )
322 : {
323 0 : long nRet = 0;
324 :
325 0 : if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
326 0 : nRet = nIn * 567;
327 0 : return nRet;
328 : }
329 :
330 :
331 :
332 0 : long MMToTwips( long nIn )
333 : {
334 0 : long nRet = 0;
335 :
336 0 : if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
337 0 : nRet = nIn * 567 / 10;
338 0 : return nRet;
339 : }
340 :
341 :
342 :
343 0 : long InchToTwips( long nIn )
344 : {
345 0 : long nRet = 0;
346 :
347 0 : if ( nIn <= ( LONG_MAX / 1440 ) && nIn >= ( LONG_MIN / 1440 ) )
348 0 : nRet = nIn * 1440;
349 0 : return nRet;
350 : }
351 :
352 :
353 :
354 0 : long PointToTwips( long nIn )
355 : {
356 0 : long nRet = 0;
357 :
358 0 : if ( nIn <= ( LONG_MAX / 20 ) && nIn >= ( LONG_MIN / 20 ) )
359 0 : nRet = nIn * 20;
360 0 : return nRet;
361 : }
362 :
363 :
364 :
365 0 : long PicaToTwips( long nIn )
366 : {
367 0 : long nRet = 0;
368 :
369 0 : if ( nIn <= ( LONG_MAX / 240 ) && nIn >= ( LONG_MIN / 240 ) )
370 0 : nRet = nIn * 240;
371 0 : return nRet;
372 : }
373 :
374 :
375 :
376 0 : long TwipsToCM( long nIn )
377 : {
378 0 : long nRet = nIn / 567;
379 0 : return nRet;
380 : }
381 :
382 :
383 :
384 0 : long InchToCM( long nIn )
385 : {
386 0 : long nRet = 0;
387 :
388 0 : if ( nIn <= ( LONG_MAX / 254 ) && nIn >= ( LONG_MIN / 254 ) )
389 0 : nRet = nIn * 254 / 100;
390 0 : return nRet;
391 : }
392 :
393 :
394 :
395 0 : long MMToCM( long nIn )
396 : {
397 0 : long nRet = nIn / 10;
398 0 : return nRet;
399 : }
400 :
401 :
402 :
403 0 : long PointToCM( long nIn )
404 : {
405 0 : long nRet = 0;
406 :
407 0 : if ( nIn <= ( LONG_MAX / 20 ) && nIn >= ( LONG_MIN / 20 ) )
408 0 : nRet = nIn * 20 / 567;
409 0 : return nRet;
410 : }
411 :
412 :
413 :
414 0 : long PicaToCM( long nIn)
415 : {
416 0 : long nRet = 0;
417 :
418 0 : if ( nIn <= ( LONG_MAX / 12 / 20 ) && nIn >= ( LONG_MIN / 12 / 20 ) )
419 0 : nRet = nIn * 12 * 20 / 567;
420 0 : return nRet;
421 : }
422 :
423 :
424 :
425 0 : long TwipsToMM( long nIn )
426 : {
427 0 : long nRet = 0;
428 :
429 0 : if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) )
430 0 : nRet = nIn * 10 / 566;
431 0 : return nRet;
432 : }
433 :
434 :
435 :
436 0 : long CMToMM( long nIn )
437 : {
438 0 : long nRet = 0;
439 :
440 0 : if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) )
441 0 : nRet = nIn * 10;
442 0 : return nRet;
443 : }
444 :
445 :
446 :
447 0 : long InchToMM( long nIn )
448 : {
449 0 : long nRet = 0;
450 :
451 0 : if ( nIn <= ( LONG_MAX / 254 ) && nIn >= ( LONG_MIN / 254 ) )
452 0 : nRet = nIn * 254 / 10;
453 0 : return nRet;
454 : }
455 :
456 :
457 :
458 0 : long PointToMM( long nIn )
459 : {
460 0 : long nRet = 0;
461 :
462 0 : if ( nIn <= ( LONG_MAX / 200 ) && nIn >= ( LONG_MIN / 200 ) )
463 0 : nRet = nIn * 200 / 567;
464 0 : return nRet;
465 : }
466 :
467 :
468 :
469 0 : long PicaToMM( long nIn )
470 : {
471 0 : long nRet = 0;
472 :
473 0 : if ( nIn <= ( LONG_MAX / 12 / 200 ) && nIn >= ( LONG_MIN / 12 / 200 ) )
474 0 : nRet = nIn * 12 * 200 / 567;
475 0 : return nRet;
476 : }
477 :
478 :
479 :
480 0 : long TwipsToInch( long nIn )
481 : {
482 0 : long nRet = nIn / 1440;
483 0 : return nRet;
484 : }
485 :
486 :
487 :
488 0 : long CMToInch( long nIn )
489 : {
490 0 : long nRet = 0;
491 :
492 0 : if ( nIn <= ( LONG_MAX / 100 ) && nIn >= ( LONG_MIN / 100 ) )
493 0 : nRet = nIn * 100 / 254;
494 0 : return nRet;
495 : }
496 :
497 :
498 :
499 0 : long MMToInch( long nIn )
500 : {
501 0 : long nRet = 0;
502 :
503 0 : if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) )
504 0 : nRet = nIn * 10 / 254;
505 0 : return nRet;
506 : }
507 :
508 :
509 :
510 0 : long PointToInch( long nIn )
511 : {
512 0 : long nRet = nIn / 72;
513 0 : return nRet;
514 : }
515 :
516 :
517 :
518 0 : long PicaToInch( long nIn )
519 : {
520 0 : long nRet = nIn / 6;
521 0 : return nRet;
522 : }
523 :
524 :
525 :
526 0 : long TwipsToPoint( long nIn )
527 : {
528 0 : long nRet = nIn / 20;
529 0 : return nRet;
530 : }
531 :
532 :
533 :
534 0 : long InchToPoint( long nIn )
535 : {
536 0 : long nRet = 0;
537 :
538 0 : if ( nIn <= ( LONG_MAX / 72 ) && nIn >= ( LONG_MIN / 72 ) )
539 0 : nRet = nIn * 72;
540 0 : return nRet;
541 : }
542 :
543 :
544 :
545 0 : long CMToPoint( long nIn )
546 : {
547 0 : long nRet = 0;
548 :
549 0 : if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
550 0 : nRet = nIn * 567 / 20;
551 0 : return nRet;
552 : }
553 :
554 :
555 :
556 0 : long MMToPoint( long nIn )
557 : {
558 0 : long nRet = 0;
559 :
560 0 : if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
561 0 : nRet = nIn * 567 / 200;
562 0 : return nRet;
563 : }
564 :
565 :
566 :
567 0 : long PicaToPoint( long nIn )
568 : {
569 0 : long nRet = nIn / 12;
570 0 : return nRet;
571 : }
572 :
573 :
574 :
575 0 : long TwipsToPica( long nIn )
576 : {
577 0 : long nRet = nIn / 240;
578 0 : return nRet;
579 : }
580 :
581 :
582 :
583 0 : long InchToPica( long nIn )
584 : {
585 0 : long nRet = 0;
586 :
587 0 : if ( nIn <= ( LONG_MAX / 6 ) && nIn >= ( LONG_MIN / 6 ) )
588 0 : nRet = nIn * 6;
589 0 : return nRet;
590 : }
591 :
592 :
593 :
594 0 : long PointToPica( long nIn )
595 : {
596 0 : long nRet = 0;
597 :
598 0 : if ( nIn <= ( LONG_MAX / 12 ) && nIn >= ( LONG_MIN / 12 ) )
599 0 : nRet = nIn * 12;
600 0 : return nRet;
601 : }
602 :
603 :
604 :
605 0 : long CMToPica( long nIn )
606 : {
607 0 : long nRet = 0;
608 :
609 0 : if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
610 0 : nRet = nIn * 567 / 20 / 12;
611 0 : return nRet;
612 : }
613 :
614 :
615 :
616 0 : long MMToPica( long nIn )
617 : {
618 0 : long nRet = 0;
619 :
620 0 : if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) )
621 0 : nRet = nIn * 567 / 200 / 12;
622 0 : return nRet;
623 : }
624 :
625 :
626 :
627 0 : long Nothing( long nIn )
628 : {
629 0 : long nRet = nIn;
630 0 : return nRet;
631 : }
632 :
633 : FUNC_CONVERT ConvertTable[6][6] =
634 : {
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 }
642 : };
643 :
644 :
645 :
646 0 : long TransformMetric( long nVal, FieldUnit aOld, FieldUnit aNew )
647 : {
648 0 : if ( aOld == FUNIT_NONE || aNew == FUNIT_NONE ||
649 0 : aOld == FUNIT_CUSTOM || aNew == FUNIT_CUSTOM )
650 : {
651 0 : return nVal;
652 : }
653 :
654 0 : sal_uInt16 nOld = 0;
655 0 : sal_uInt16 nNew = 0;
656 :
657 0 : switch ( aOld )
658 : {
659 : case FUNIT_CM:
660 0 : nOld = 0; break;
661 : case FUNIT_MM:
662 0 : nOld = 1; break;
663 : case FUNIT_INCH:
664 0 : nOld = 2; break;
665 : case FUNIT_POINT:
666 0 : nOld = 3; break;
667 : case FUNIT_PICA:
668 0 : nOld = 4; break;
669 : case FUNIT_TWIP:
670 0 : nOld = 5; break;
671 : default: ;//prevent warning
672 : }
673 :
674 0 : switch ( aNew )
675 : {
676 : case FUNIT_CM:
677 0 : nNew = 0; break;
678 : case FUNIT_MM:
679 0 : nNew = 1; break;
680 : case FUNIT_INCH:
681 0 : nNew = 2; break;
682 : case FUNIT_POINT:
683 0 : nNew = 3; break;
684 : case FUNIT_PICA:
685 0 : nNew = 4; break;
686 : case FUNIT_TWIP:
687 0 : nNew = 5; break;
688 : default: ;//prevent warning
689 : }
690 0 : return ConvertTable[nOld][nNew]( nVal );
691 : }
692 :
693 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|