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