1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svtools.hxx" 26 27 // include --------------------------------------------------------------- 28 29 #include <svtools/unitconv.hxx> 30 31 // ----------------------------------------------------------------------- 32 33 void SetFieldUnit( MetricField& rField, FieldUnit eUnit, sal_Bool bAll ) 34 { 35 sal_Int64 nFirst = rField.Denormalize( rField.GetFirst( FUNIT_TWIP ) ); 36 sal_Int64 nLast = rField.Denormalize( rField.GetLast( FUNIT_TWIP ) ); 37 sal_Int64 nMin = rField.Denormalize( rField.GetMin( FUNIT_TWIP ) ); 38 sal_Int64 nMax = rField.Denormalize( rField.GetMax( FUNIT_TWIP ) ); 39 40 if ( !bAll ) 41 { 42 switch ( eUnit ) 43 { 44 case FUNIT_M: 45 case FUNIT_KM: 46 eUnit = FUNIT_CM; 47 break; 48 49 case FUNIT_FOOT: 50 case FUNIT_MILE: 51 eUnit = FUNIT_INCH; 52 break; 53 default: ;//prevent warning 54 } 55 } 56 rField.SetUnit( eUnit ); 57 switch( eUnit ) 58 { 59 case FUNIT_MM: 60 rField.SetSpinSize( 50 ); 61 break; 62 63 case FUNIT_INCH: 64 rField.SetSpinSize( 2 ); 65 break; 66 67 default: 68 rField.SetSpinSize( 10 ); 69 } 70 71 if ( FUNIT_POINT == eUnit ) 72 { 73 if( rField.GetDecimalDigits() > 1 ) 74 rField.SetDecimalDigits( 1 ); 75 } 76 else 77 rField.SetDecimalDigits( 2 ); 78 79 if ( !bAll ) 80 { 81 rField.SetFirst( rField.Normalize( nFirst ), FUNIT_TWIP ); 82 rField.SetLast( rField.Normalize( nLast ), FUNIT_TWIP ); 83 rField.SetMin( rField.Normalize( nMin ), FUNIT_TWIP ); 84 rField.SetMax( rField.Normalize( nMax ), FUNIT_TWIP ); 85 } 86 } 87 88 // ----------------------------------------------------------------------- 89 90 void SetFieldUnit( MetricBox& rBox, FieldUnit eUnit, sal_Bool bAll ) 91 { 92 sal_Int64 nMin = rBox.Denormalize( rBox.GetMin( FUNIT_TWIP ) ); 93 sal_Int64 nMax = rBox.Denormalize( rBox.GetMax( FUNIT_TWIP ) ); 94 95 if ( !bAll ) 96 { 97 switch ( eUnit ) 98 { 99 case FUNIT_M: 100 case FUNIT_KM: 101 eUnit = FUNIT_CM; 102 break; 103 104 case FUNIT_FOOT: 105 case FUNIT_MILE: 106 eUnit = FUNIT_INCH; 107 break; 108 default: ;//prevent warning 109 } 110 } 111 rBox.SetUnit( eUnit ); 112 113 if ( FUNIT_POINT == eUnit && rBox.GetDecimalDigits() > 1 ) 114 rBox.SetDecimalDigits( 1 ); 115 else 116 rBox.SetDecimalDigits( 2 ); 117 118 if ( !bAll ) 119 { 120 rBox.SetMin( rBox.Normalize( nMin ), FUNIT_TWIP ); 121 rBox.SetMax( rBox.Normalize( nMax ), FUNIT_TWIP ); 122 } 123 } 124 125 // ----------------------------------------------------------------------- 126 void SetMetricValue( MetricField& rField, long nCoreValue, SfxMapUnit eUnit ) 127 { 128 sal_Int64 nVal = OutputDevice::LogicToLogic( nCoreValue, (MapUnit)eUnit, MAP_100TH_MM ); 129 nVal = rField.Normalize( nVal ); 130 rField.SetValue( nVal, FUNIT_100TH_MM ); 131 132 } 133 134 // ----------------------------------------------------------------------- 135 136 long GetCoreValue( const MetricField& rField, SfxMapUnit eUnit ) 137 { 138 sal_Int64 nVal = rField.GetValue( FUNIT_100TH_MM ); 139 // avoid rounding issues 140 const sal_Int64 nSizeMask = 0xffffffffff000000LL; 141 bool bRoundBefore = true; 142 if( nVal >= 0 ) 143 { 144 if( (nVal & nSizeMask) == 0 ) 145 bRoundBefore = false; 146 } 147 else 148 { 149 if( ((-nVal) & nSizeMask ) == 0 ) 150 bRoundBefore = false; 151 } 152 if( bRoundBefore ) 153 nVal = rField.Denormalize( nVal ); 154 sal_Int64 nUnitVal = OutputDevice::LogicToLogic( static_cast<long>(nVal), MAP_100TH_MM, (MapUnit)eUnit ); 155 if( ! bRoundBefore ) 156 nUnitVal = rField.Denormalize( nUnitVal ); 157 return static_cast<long>(nUnitVal); 158 } 159 160 // ----------------------------------------------------------------------- 161 162 long CalcToUnit( float nIn, SfxMapUnit eUnit ) 163 { 164 // nIn ist in Points 165 166 DBG_ASSERT( eUnit == SFX_MAPUNIT_TWIP || 167 eUnit == SFX_MAPUNIT_100TH_MM || 168 eUnit == SFX_MAPUNIT_10TH_MM || 169 eUnit == SFX_MAPUNIT_MM || 170 eUnit == SFX_MAPUNIT_CM, "this unit is not implemented" ); 171 172 float nTmp = nIn; 173 174 if ( SFX_MAPUNIT_TWIP != eUnit ) 175 nTmp = nIn * 10 / 567; 176 177 switch ( eUnit ) 178 { 179 case SFX_MAPUNIT_100TH_MM: nTmp *= 100; break; 180 case SFX_MAPUNIT_10TH_MM: nTmp *= 10; break; 181 case SFX_MAPUNIT_MM: break; 182 case SFX_MAPUNIT_CM: nTmp /= 10; break; 183 default: ;//prevent warning 184 } 185 186 nTmp *= 20; 187 long nRet = (long)nTmp; 188 return nRet; 189 //! return (long)(nTmp * 20); 190 } 191 192 // ----------------------------------------------------------------------- 193 194 long ItemToControl( long nIn, SfxMapUnit eItem, SfxFieldUnit eCtrl ) 195 { 196 long nOut = 0; 197 198 switch ( eItem ) 199 { 200 case SFX_MAPUNIT_100TH_MM: 201 case SFX_MAPUNIT_10TH_MM: 202 case SFX_MAPUNIT_MM: 203 { 204 if ( eItem == SFX_MAPUNIT_10TH_MM ) 205 nIn /= 10; 206 else if ( eItem == SFX_MAPUNIT_100TH_MM ) 207 nIn /= 100; 208 nOut = TransformMetric( nIn, FUNIT_MM, (FieldUnit)eCtrl ); 209 } 210 break; 211 212 case SFX_MAPUNIT_CM: 213 { 214 nOut = TransformMetric( nIn, FUNIT_CM, (FieldUnit)eCtrl ); 215 } 216 break; 217 218 case SFX_MAPUNIT_1000TH_INCH: 219 case SFX_MAPUNIT_100TH_INCH: 220 case SFX_MAPUNIT_10TH_INCH: 221 case SFX_MAPUNIT_INCH: 222 { 223 if ( eItem == SFX_MAPUNIT_10TH_INCH ) 224 nIn /= 10; 225 else if ( eItem == SFX_MAPUNIT_100TH_INCH ) 226 nIn /= 100; 227 else if ( eItem == SFX_MAPUNIT_1000TH_INCH ) 228 nIn /= 1000; 229 nOut = TransformMetric( nIn, FUNIT_INCH, (FieldUnit)eCtrl ); 230 } 231 break; 232 233 case SFX_MAPUNIT_POINT: 234 { 235 nOut = TransformMetric( nIn, FUNIT_POINT, (FieldUnit)eCtrl ); 236 } 237 break; 238 239 case SFX_MAPUNIT_TWIP: 240 { 241 nOut = TransformMetric( nIn, FUNIT_TWIP, (FieldUnit)eCtrl ); 242 } 243 break; 244 default: ;//prevent warning 245 } 246 return nOut; 247 } 248 249 // ----------------------------------------------------------------------- 250 251 long ControlToItem( long nIn, SfxFieldUnit eCtrl, SfxMapUnit eItem ) 252 { 253 return ItemToControl( nIn, eItem, eCtrl ); 254 } 255 256 // ----------------------------------------------------------------------- 257 258 FieldUnit MapToFieldUnit( const SfxMapUnit eUnit ) 259 { 260 switch ( eUnit ) 261 { 262 case SFX_MAPUNIT_100TH_MM: 263 case SFX_MAPUNIT_10TH_MM: 264 case SFX_MAPUNIT_MM: 265 return FUNIT_MM; 266 267 case SFX_MAPUNIT_CM: 268 return FUNIT_CM; 269 270 case SFX_MAPUNIT_1000TH_INCH: 271 case SFX_MAPUNIT_100TH_INCH: 272 case SFX_MAPUNIT_10TH_INCH: 273 case SFX_MAPUNIT_INCH: 274 return FUNIT_INCH; 275 276 case SFX_MAPUNIT_POINT: 277 return FUNIT_POINT; 278 279 case SFX_MAPUNIT_TWIP: 280 return FUNIT_TWIP; 281 default: ;//prevent warning 282 } 283 return FUNIT_NONE; 284 } 285 286 // ----------------------------------------------------------------------- 287 288 MapUnit FieldToMapUnit( const SfxFieldUnit /*eUnit*/ ) 289 { 290 return MAP_APPFONT; 291 } 292 293 // ----------------------------------------------------------------------- 294 295 long ConvertValueToMap( long nVal, SfxMapUnit eUnit ) 296 { 297 long nNew = nVal; 298 299 switch ( eUnit ) 300 { 301 case SFX_MAPUNIT_10TH_MM: 302 case SFX_MAPUNIT_10TH_INCH: 303 nNew *= 10; 304 break; 305 306 case SFX_MAPUNIT_100TH_MM: 307 case SFX_MAPUNIT_100TH_INCH: 308 nNew *= 100; 309 break; 310 311 case SFX_MAPUNIT_1000TH_INCH: 312 nNew *= 1000; 313 default: ;//prevent warning 314 } 315 return nNew; 316 } 317 318 // ----------------------------------------------------------------------- 319 320 long ConvertValueToUnit( long nVal, SfxMapUnit eUnit ) 321 { 322 long nNew = nVal; 323 324 switch ( eUnit ) 325 { 326 case SFX_MAPUNIT_10TH_MM: 327 case SFX_MAPUNIT_10TH_INCH: 328 nNew /= 10; 329 break; 330 331 case SFX_MAPUNIT_100TH_MM: 332 case SFX_MAPUNIT_100TH_INCH: 333 nNew /= 100; 334 break; 335 336 case SFX_MAPUNIT_1000TH_INCH: 337 nNew /= 1000; 338 break; 339 default: ;//prevent warning 340 } 341 return nNew; 342 } 343 344 // ----------------------------------------------------------------------- 345 346 long CalcToPoint( long nIn, SfxMapUnit eUnit, sal_uInt16 nFaktor ) 347 { 348 DBG_ASSERT( eUnit == SFX_MAPUNIT_TWIP || 349 eUnit == SFX_MAPUNIT_100TH_MM || 350 eUnit == SFX_MAPUNIT_10TH_MM || 351 eUnit == SFX_MAPUNIT_MM || 352 eUnit == SFX_MAPUNIT_CM, "this unit is not implemented" ); 353 354 long nRet = 0; 355 356 if ( SFX_MAPUNIT_TWIP == eUnit ) 357 nRet = nIn; 358 else 359 nRet = nIn * 567; 360 361 switch ( eUnit ) 362 { 363 case SFX_MAPUNIT_100TH_MM: nRet /= 100; break; 364 case SFX_MAPUNIT_10TH_MM: nRet /= 10; break; 365 case SFX_MAPUNIT_MM: break; 366 case SFX_MAPUNIT_CM: nRet *= 10; break; 367 default: ;//prevent warning 368 } 369 370 // ggf. aufrunden 371 if ( SFX_MAPUNIT_TWIP != eUnit ) 372 { 373 long nMod = 10; 374 long nTmp = nRet % nMod; 375 376 if ( nTmp >= 4 ) 377 nRet += 10 - nTmp; 378 nRet /= 10; 379 } 380 return nRet * nFaktor / 20; 381 } 382 383 // ----------------------------------------------------------------------- 384 385 long CMToTwips( long nIn ) 386 { 387 long nRet = 0; 388 389 if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) ) 390 nRet = nIn * 567; 391 return nRet; 392 } 393 394 // ----------------------------------------------------------------------- 395 396 long MMToTwips( long nIn ) 397 { 398 long nRet = 0; 399 400 if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) ) 401 nRet = nIn * 567 / 10; 402 return nRet; 403 } 404 405 // ----------------------------------------------------------------------- 406 407 long InchToTwips( long nIn ) 408 { 409 long nRet = 0; 410 411 if ( nIn <= ( LONG_MAX / 1440 ) && nIn >= ( LONG_MIN / 1440 ) ) 412 nRet = nIn * 1440; 413 return nRet; 414 } 415 416 // ----------------------------------------------------------------------- 417 418 long PointToTwips( long nIn ) 419 { 420 long nRet = 0; 421 422 if ( nIn <= ( LONG_MAX / 20 ) && nIn >= ( LONG_MIN / 20 ) ) 423 nRet = nIn * 20; 424 return nRet; 425 } 426 427 // ----------------------------------------------------------------------- 428 429 long PicaToTwips( long nIn ) 430 { 431 long nRet = 0; 432 433 if ( nIn <= ( LONG_MAX / 240 ) && nIn >= ( LONG_MIN / 240 ) ) 434 nRet = nIn * 240; 435 return nRet; 436 } 437 438 // ----------------------------------------------------------------------- 439 440 long TwipsToCM( long nIn ) 441 { 442 long nRet = nIn / 567; 443 return nRet; 444 } 445 446 // ----------------------------------------------------------------------- 447 448 long InchToCM( long nIn ) 449 { 450 long nRet = 0; 451 452 if ( nIn <= ( LONG_MAX / 254 ) && nIn >= ( LONG_MIN / 254 ) ) 453 nRet = nIn * 254 / 100; 454 return nRet; 455 } 456 457 // ----------------------------------------------------------------------- 458 459 long MMToCM( long nIn ) 460 { 461 long nRet = nIn / 10; 462 return nRet; 463 } 464 465 // ----------------------------------------------------------------------- 466 467 long PointToCM( long nIn ) 468 { 469 long nRet = 0; 470 471 if ( nIn <= ( LONG_MAX / 20 ) && nIn >= ( LONG_MIN / 20 ) ) 472 nRet = nIn * 20 / 567; 473 return nRet; 474 } 475 476 // ----------------------------------------------------------------------- 477 478 long PicaToCM( long nIn) 479 { 480 long nRet = 0; 481 482 if ( nIn <= ( LONG_MAX / 12 / 20 ) && nIn >= ( LONG_MIN / 12 / 20 ) ) 483 nRet = nIn * 12 * 20 / 567; 484 return nRet; 485 } 486 487 // ----------------------------------------------------------------------- 488 489 long TwipsToMM( long nIn ) 490 { 491 long nRet = 0; 492 493 if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) ) 494 nRet = nIn * 10 / 566; 495 return nRet; 496 } 497 498 // ----------------------------------------------------------------------- 499 500 long CMToMM( long nIn ) 501 { 502 long nRet = 0; 503 504 if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) ) 505 nRet = nIn * 10; 506 return nRet; 507 } 508 509 // ----------------------------------------------------------------------- 510 511 long InchToMM( long nIn ) 512 { 513 long nRet = 0; 514 515 if ( nIn <= ( LONG_MAX / 254 ) && nIn >= ( LONG_MIN / 254 ) ) 516 nRet = nIn * 254 / 10; 517 return nRet; 518 } 519 520 // ----------------------------------------------------------------------- 521 522 long PointToMM( long nIn ) 523 { 524 long nRet = 0; 525 526 if ( nIn <= ( LONG_MAX / 200 ) && nIn >= ( LONG_MIN / 200 ) ) 527 nRet = nIn * 200 / 567; 528 return nRet; 529 } 530 531 // ----------------------------------------------------------------------- 532 533 long PicaToMM( long nIn ) 534 { 535 long nRet = 0; 536 537 if ( nIn <= ( LONG_MAX / 12 / 200 ) && nIn >= ( LONG_MIN / 12 / 200 ) ) 538 nRet = nIn * 12 * 200 / 567; 539 return nRet; 540 } 541 542 // ----------------------------------------------------------------------- 543 544 long TwipsToInch( long nIn ) 545 { 546 long nRet = nIn / 1440; 547 return nRet; 548 } 549 550 // ----------------------------------------------------------------------- 551 552 long CMToInch( long nIn ) 553 { 554 long nRet = 0; 555 556 if ( nIn <= ( LONG_MAX / 100 ) && nIn >= ( LONG_MIN / 100 ) ) 557 nRet = nIn * 100 / 254; 558 return nRet; 559 } 560 561 // ----------------------------------------------------------------------- 562 563 long MMToInch( long nIn ) 564 { 565 long nRet = 0; 566 567 if ( nIn <= ( LONG_MAX / 10 ) && nIn >= ( LONG_MIN / 10 ) ) 568 nRet = nIn * 10 / 254; 569 return nRet; 570 } 571 572 // ----------------------------------------------------------------------- 573 574 long PointToInch( long nIn ) 575 { 576 long nRet = nIn / 72; 577 return nRet; 578 } 579 580 // ----------------------------------------------------------------------- 581 582 long PicaToInch( long nIn ) 583 { 584 long nRet = nIn / 6; 585 return nRet; 586 } 587 588 // ----------------------------------------------------------------------- 589 590 long TwipsToPoint( long nIn ) 591 { 592 long nRet = nIn / 20; 593 return nRet; 594 } 595 596 // ----------------------------------------------------------------------- 597 598 long InchToPoint( long nIn ) 599 { 600 long nRet = 0; 601 602 if ( nIn <= ( LONG_MAX / 72 ) && nIn >= ( LONG_MIN / 72 ) ) 603 nRet = nIn * 72; 604 return nRet; 605 } 606 607 // ----------------------------------------------------------------------- 608 609 long CMToPoint( long nIn ) 610 { 611 long nRet = 0; 612 613 if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) ) 614 nRet = nIn * 567 / 20; 615 return nRet; 616 } 617 618 // ----------------------------------------------------------------------- 619 620 long MMToPoint( long nIn ) 621 { 622 long nRet = 0; 623 624 if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) ) 625 nRet = nIn * 567 / 200; 626 return nRet; 627 } 628 629 // ----------------------------------------------------------------------- 630 631 long PicaToPoint( long nIn ) 632 { 633 long nRet = nIn / 12; 634 return nRet; 635 } 636 637 // ----------------------------------------------------------------------- 638 639 long TwipsToPica( long nIn ) 640 { 641 long nRet = nIn / 240; 642 return nRet; 643 } 644 645 // ----------------------------------------------------------------------- 646 647 long InchToPica( long nIn ) 648 { 649 long nRet = 0; 650 651 if ( nIn <= ( LONG_MAX / 6 ) && nIn >= ( LONG_MIN / 6 ) ) 652 nRet = nIn * 6; 653 return nRet; 654 } 655 656 // ----------------------------------------------------------------------- 657 658 long PointToPica( long nIn ) 659 { 660 long nRet = 0; 661 662 if ( nIn <= ( LONG_MAX / 12 ) && nIn >= ( LONG_MIN / 12 ) ) 663 nRet = nIn * 12; 664 return nRet; 665 } 666 667 // ----------------------------------------------------------------------- 668 669 long CMToPica( long nIn ) 670 { 671 long nRet = 0; 672 673 if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) ) 674 nRet = nIn * 567 / 20 / 12; 675 return nRet; 676 } 677 678 // ----------------------------------------------------------------------- 679 680 long MMToPica( long nIn ) 681 { 682 long nRet = 0; 683 684 if ( nIn <= ( LONG_MAX / 567 ) && nIn >= ( LONG_MIN / 567 ) ) 685 nRet = nIn * 567 / 200 / 12; 686 return nRet; 687 } 688 689 // ----------------------------------------------------------------------- 690 691 long Nothing( long nIn ) 692 { 693 long nRet = nIn; 694 return nRet; 695 } 696 697 FUNC_CONVERT ConvertTable[6][6] = 698 { 699 // CM, MM INCH POINT PICAS=32 TWIPS 700 { Nothing, CMToMM, CMToInch, CMToPoint, CMToPica, CMToTwips }, 701 { MMToCM, Nothing, MMToInch, MMToPoint, MMToPica, MMToTwips }, 702 { InchToCM, InchToMM, Nothing, InchToPoint, InchToPica, InchToTwips }, 703 { PointToCM, PointToMM, PointToInch, Nothing, PointToPica, PointToTwips }, 704 { PicaToCM, PicaToMM, PicaToInch, PicaToPoint, Nothing, PicaToTwips }, 705 { TwipsToCM, TwipsToMM, TwipsToInch, TwipsToPoint,TwipsToPica, Nothing } 706 }; 707 708 // ----------------------------------------------------------------------- 709 710 long TransformMetric( long nVal, FieldUnit aOld, FieldUnit aNew ) 711 { 712 if ( aOld == FUNIT_NONE || aNew == FUNIT_NONE || 713 aOld == FUNIT_CUSTOM || aNew == FUNIT_CUSTOM ) 714 { 715 return nVal; 716 } 717 718 sal_uInt16 nOld = 0; 719 sal_uInt16 nNew = 0; 720 721 switch ( aOld ) 722 { 723 case FUNIT_CM: 724 nOld = 0; break; 725 case FUNIT_MM: 726 nOld = 1; break; 727 case FUNIT_INCH: 728 nOld = 2; break; 729 case FUNIT_POINT: 730 nOld = 3; break; 731 case FUNIT_PICA: 732 nOld = 4; break; 733 case FUNIT_TWIP: 734 nOld = 5; break; 735 default: ;//prevent warning 736 } 737 738 switch ( aNew ) 739 { 740 case FUNIT_CM: 741 nNew = 0; break; 742 case FUNIT_MM: 743 nNew = 1; break; 744 case FUNIT_INCH: 745 nNew = 2; break; 746 case FUNIT_POINT: 747 nNew = 3; break; 748 case FUNIT_PICA: 749 nNew = 4; break; 750 case FUNIT_TWIP: 751 nNew = 5; break; 752 default: ;//prevent warning 753 } 754 return ConvertTable[nOld][nNew]( nVal ); 755 } 756 757