xref: /trunk/main/vcl/source/gdi/outmap.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <limits.h>
32 
33 #include <tools/bigint.hxx>
34 #include <tools/debug.hxx>
35 #include <tools/poly.hxx>
36 
37 #include <vcl/virdev.hxx>
38 #include <vcl/region.hxx>
39 #include <vcl/wrkwin.hxx>
40 #include <vcl/cursor.hxx>
41 #include <vcl/metaact.hxx>
42 #include <vcl/gdimtf.hxx>
43 #include <vcl/lineinfo.hxx>
44 #include <vcl/outdev.hxx>
45 
46 #include <svdata.hxx>
47 #include <region.h>
48 #include <window.h>
49 #include <outdev.h>
50 #include <salgdi.hxx>
51 
52 #include <basegfx/matrix/b2dhommatrix.hxx>
53 #include <basegfx/polygon/b2dpolygon.hxx>
54 #include <basegfx/polygon/b2dpolypolygon.hxx>
55 
56 #define USE_64BIT_INTS
57 
58 // =======================================================================
59 
60 DBG_NAMEEX( OutputDevice )
61 DBG_NAMEEX( Polygon )
62 DBG_NAMEEX( PolyPolygon )
63 DBG_NAMEEX( Region )
64 
65 // =======================================================================
66 
67 static long aImplNumeratorAry[MAP_PIXEL+1] =
68     {    1,   1,   5,  50,    1,   1,  1, 1,  1,    1, 1 };
69 static long aImplDenominatorAry[MAP_PIXEL+1] =
70      { 2540, 254, 127, 127, 1000, 100, 10, 1, 72, 1440, 1 };
71 
72 // -----------------------------------------------------------------------
73 
74 /*
75 Reduziert die Genauigkeit bis eine Fraction draus wird (sollte mal
76 ein Fraction ctor werden) koennte man dann auch mit BigInts machen
77 */
78 
79 static Fraction ImplMakeFraction( long nN1, long nN2, long nD1, long nD2 )
80 {
81     long i = 1;
82 
83     if ( nN1 < 0 ) { i = -i; nN1 = -nN1; }
84     if ( nN2 < 0 ) { i = -i; nN2 = -nN2; }
85     if ( nD1 < 0 ) { i = -i; nD1 = -nD1; }
86     if ( nD2 < 0 ) { i = -i; nD2 = -nD2; }
87     // alle positiv; i Vorzeichen
88 
89     Fraction aF( i*nN1, nD1 );
90     aF *= Fraction( nN2, nD2 );
91 
92     if( nD1 == 0 || nD2 == 0 ) //under these bad circumstances the following while loop will be endless
93     {
94         DBG_ASSERT(false,"Invalid parameter for ImplMakeFraction");
95         return Fraction( 1, 1 );
96     }
97 
98     while ( aF.GetDenominator() == -1 )
99     {
100         if ( nN1 > nN2 )
101             nN1 = (nN1 + 1) / 2;
102         else
103             nN2 = (nN2 + 1) / 2;
104         if ( nD1 > nD2 )
105             nD1 = (nD1 + 1) / 2;
106         else
107             nD2 = (nD2 + 1) / 2;
108 
109         aF = Fraction( i*nN1, nD1 );
110         aF *= Fraction( nN2, nD2 );
111     }
112 
113     return aF;
114 }
115 
116 // -----------------------------------------------------------------------
117 
118 // Fraction.GetNumerator()
119 // Fraction.GetDenominator()    > 0
120 // rOutRes.nPixPerInch?         > 0
121 // rMapRes.nMapScNum?
122 // rMapRes.nMapScDenom?         > 0
123 
124 static void ImplCalcBigIntThreshold( long nDPIX, long nDPIY,
125                                      const ImplMapRes& rMapRes,
126                                      ImplThresholdRes& rThresRes )
127 {
128     if ( nDPIX && (LONG_MAX / nDPIX < Abs( rMapRes.mnMapScNumX ) ) ) // #111139# avoid div by zero
129     {
130         rThresRes.mnThresLogToPixX = 0;
131         rThresRes.mnThresPixToLogX = 0;
132     }
133     else
134     {
135         // Schwellenwerte fuer BigInt Arithmetik berechnen
136         long    nDenomHalfX = rMapRes.mnMapScDenomX / 2;
137         sal_uLong   nDenomX     = rMapRes.mnMapScDenomX;
138         long    nProductX   = nDPIX * rMapRes.mnMapScNumX;
139 
140         if ( !nProductX )
141             rThresRes.mnThresLogToPixX = LONG_MAX;
142         else
143             rThresRes.mnThresLogToPixX = Abs( (LONG_MAX - nDenomHalfX) / nProductX );
144 
145         if ( !nDenomX )
146             rThresRes.mnThresPixToLogX = LONG_MAX;
147         else if ( nProductX >= 0 )
148             rThresRes.mnThresPixToLogX = (long)(((sal_uLong)LONG_MAX - (sal_uLong)( nProductX/2)) / nDenomX);
149         else
150             rThresRes.mnThresPixToLogX = (long)(((sal_uLong)LONG_MAX + (sal_uLong)(-nProductX/2)) / nDenomX);
151     }
152 
153     if ( nDPIY && (LONG_MAX / nDPIY < Abs( rMapRes.mnMapScNumY ) ) ) // #111139# avoid div by zero
154     {
155         rThresRes.mnThresLogToPixY = 0;
156         rThresRes.mnThresPixToLogY = 0;
157     }
158     else
159     {
160         // Schwellenwerte fuer BigInt Arithmetik berechnen
161         long    nDenomHalfY = rMapRes.mnMapScDenomY / 2;
162         sal_uLong   nDenomY     = rMapRes.mnMapScDenomY;
163         long    nProductY   = nDPIY * rMapRes.mnMapScNumY;
164 
165         if ( !nProductY )
166             rThresRes.mnThresLogToPixY = LONG_MAX;
167         else
168             rThresRes.mnThresLogToPixY = Abs( (LONG_MAX - nDenomHalfY) / nProductY );
169 
170         if ( !nDenomY )
171             rThresRes.mnThresPixToLogY = LONG_MAX;
172         else if ( nProductY >= 0 )
173             rThresRes.mnThresPixToLogY = (long)(((sal_uLong)LONG_MAX - (sal_uLong)( nProductY/2)) / nDenomY);
174         else
175             rThresRes.mnThresPixToLogY = (long)(((sal_uLong)LONG_MAX + (sal_uLong)(-nProductY/2)) / nDenomY);
176     }
177 
178 #ifdef USE_64BIT_INTS
179     rThresRes.mnThresLogToPixX /= 2;
180     rThresRes.mnThresLogToPixY /= 2;
181     rThresRes.mnThresPixToLogX /= 2;
182     rThresRes.mnThresPixToLogY /= 2;
183 #endif
184 }
185 
186 // -----------------------------------------------------------------------
187 
188 static void ImplCalcMapResolution( const MapMode& rMapMode,
189                                    long nDPIX, long nDPIY, ImplMapRes& rMapRes )
190 {
191     switch ( rMapMode.GetMapUnit() )
192     {
193         case MAP_RELATIVE:
194             break;
195         case MAP_100TH_MM:
196             rMapRes.mnMapScNumX   = 1;
197             rMapRes.mnMapScDenomX = 2540;
198             rMapRes.mnMapScNumY   = 1;
199             rMapRes.mnMapScDenomY = 2540;
200             break;
201         case MAP_10TH_MM:
202             rMapRes.mnMapScNumX   = 1;
203             rMapRes.mnMapScDenomX = 254;
204             rMapRes.mnMapScNumY   = 1;
205             rMapRes.mnMapScDenomY = 254;
206             break;
207         case MAP_MM:
208             rMapRes.mnMapScNumX   = 5;      // 10
209             rMapRes.mnMapScDenomX = 127;    // 254
210             rMapRes.mnMapScNumY   = 5;      // 10
211             rMapRes.mnMapScDenomY = 127;    // 254
212             break;
213         case MAP_CM:
214             rMapRes.mnMapScNumX   = 50;     // 100
215             rMapRes.mnMapScDenomX = 127;    // 254
216             rMapRes.mnMapScNumY   = 50;     // 100
217             rMapRes.mnMapScDenomY = 127;    // 254
218             break;
219         case MAP_1000TH_INCH:
220             rMapRes.mnMapScNumX   = 1;
221             rMapRes.mnMapScDenomX = 1000;
222             rMapRes.mnMapScNumY   = 1;
223             rMapRes.mnMapScDenomY = 1000;
224             break;
225         case MAP_100TH_INCH:
226             rMapRes.mnMapScNumX   = 1;
227             rMapRes.mnMapScDenomX = 100;
228             rMapRes.mnMapScNumY   = 1;
229             rMapRes.mnMapScDenomY = 100;
230             break;
231         case MAP_10TH_INCH:
232             rMapRes.mnMapScNumX   = 1;
233             rMapRes.mnMapScDenomX = 10;
234             rMapRes.mnMapScNumY   = 1;
235             rMapRes.mnMapScDenomY = 10;
236             break;
237         case MAP_INCH:
238             rMapRes.mnMapScNumX   = 1;
239             rMapRes.mnMapScDenomX = 1;
240             rMapRes.mnMapScNumY   = 1;
241             rMapRes.mnMapScDenomY = 1;
242             break;
243         case MAP_POINT:
244             rMapRes.mnMapScNumX   = 1;
245             rMapRes.mnMapScDenomX = 72;
246             rMapRes.mnMapScNumY   = 1;
247             rMapRes.mnMapScDenomY = 72;
248             break;
249         case MAP_TWIP:
250             rMapRes.mnMapScNumX   = 1;
251             rMapRes.mnMapScDenomX = 1440;
252             rMapRes.mnMapScNumY   = 1;
253             rMapRes.mnMapScDenomY = 1440;
254             break;
255         case MAP_PIXEL:
256             rMapRes.mnMapScNumX   = 1;
257             rMapRes.mnMapScDenomX = nDPIX;
258             rMapRes.mnMapScNumY   = 1;
259             rMapRes.mnMapScDenomY = nDPIY;
260             break;
261         case MAP_SYSFONT:
262         case MAP_APPFONT:
263         case MAP_REALAPPFONT:
264             {
265             ImplSVData* pSVData = ImplGetSVData();
266             if ( !pSVData->maGDIData.mnAppFontX )
267             {
268                 if( pSVData->maWinData.mpFirstFrame )
269                     Window::ImplInitAppFontData( pSVData->maWinData.mpFirstFrame );
270                 else
271                 {
272                     WorkWindow* pWin = new WorkWindow( NULL, 0 );
273                     Window::ImplInitAppFontData( pWin );
274                     delete pWin;
275                 }
276             }
277             if ( rMapMode.GetMapUnit() == MAP_REALAPPFONT )
278                 rMapRes.mnMapScNumX   = pSVData->maGDIData.mnRealAppFontX;
279             else
280                 rMapRes.mnMapScNumX   = pSVData->maGDIData.mnAppFontX;
281             rMapRes.mnMapScDenomX = nDPIX * 40;
282             rMapRes.mnMapScNumY   = pSVData->maGDIData.mnAppFontY;;
283             rMapRes.mnMapScDenomY = nDPIY * 80;
284             }
285             break;
286         default:
287             DBG_ERROR( "unhandled MapUnit" );
288             break;
289     }
290 
291     Fraction aScaleX = rMapMode.GetScaleX();
292     Fraction aScaleY = rMapMode.GetScaleY();
293 
294     // Offset laut MapMode setzen
295     Point aOrigin = rMapMode.GetOrigin();
296     if ( rMapMode.GetMapUnit() != MAP_RELATIVE )
297     {
298         rMapRes.mnMapOfsX = aOrigin.X();
299         rMapRes.mnMapOfsY = aOrigin.Y();
300     }
301     else
302     {
303         BigInt aX( rMapRes.mnMapOfsX );
304         aX *= BigInt( aScaleX.GetDenominator() );
305         if ( rMapRes.mnMapOfsX >= 0 )
306         {
307             if ( aScaleX.GetNumerator() >= 0 )
308                 aX += BigInt( aScaleX.GetNumerator()/2 );
309             else
310                 aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
311         }
312         else
313         {
314             if ( aScaleX.GetNumerator() >= 0 )
315                 aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
316             else
317                 aX += BigInt( aScaleX.GetNumerator()/2 );
318         }
319         aX /= BigInt( aScaleX.GetNumerator() );
320         rMapRes.mnMapOfsX = (long)aX + aOrigin.X();
321         BigInt aY( rMapRes.mnMapOfsY );
322         aY *= BigInt( aScaleY.GetDenominator() );
323         if( rMapRes.mnMapOfsY >= 0 )
324         {
325             if ( aScaleY.GetNumerator() >= 0 )
326                 aY += BigInt( aScaleY.GetNumerator()/2 );
327             else
328                 aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
329         }
330         else
331         {
332             if ( aScaleY.GetNumerator() >= 0 )
333                 aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
334             else
335                 aY += BigInt( aScaleY.GetNumerator()/2 );
336         }
337         aY /= BigInt( aScaleY.GetNumerator() );
338         rMapRes.mnMapOfsY = (long)aY + aOrigin.Y();
339     }
340 
341     // Scaling Faktor laut MapMode einberechnen
342     // aTemp? = rMapRes.mnMapSc? * aScale?
343     Fraction aTempX = ImplMakeFraction( rMapRes.mnMapScNumX,
344                                         aScaleX.GetNumerator(),
345                                         rMapRes.mnMapScDenomX,
346                                         aScaleX.GetDenominator() );
347     Fraction aTempY = ImplMakeFraction( rMapRes.mnMapScNumY,
348                                         aScaleY.GetNumerator(),
349                                         rMapRes.mnMapScDenomY,
350                                         aScaleY.GetDenominator() );
351     rMapRes.mnMapScNumX   = aTempX.GetNumerator();
352     rMapRes.mnMapScDenomX = aTempX.GetDenominator();
353     rMapRes.mnMapScNumY   = aTempY.GetNumerator();
354     rMapRes.mnMapScDenomY = aTempY.GetDenominator();
355 
356     // hack: 0/n ungef"ahr 1/max
357     if ( !rMapRes.mnMapScNumX )
358     {
359         rMapRes.mnMapScNumX = 1;
360         rMapRes.mnMapScDenomX = LONG_MAX;
361     }
362     if ( !rMapRes.mnMapScNumY )
363     {
364         rMapRes.mnMapScNumY = 1;
365         rMapRes.mnMapScDenomY = LONG_MAX;
366     }
367 }
368 
369 // -----------------------------------------------------------------------
370 
371 inline void ImplCalcMapResolution( const MapMode& rMapMode,
372                                    long nDPIX, long nDPIY,
373                                    ImplMapRes& rMapRes,
374                                    ImplThresholdRes& rThresRes )
375 {
376     ImplCalcMapResolution( rMapMode, nDPIX, nDPIY, rMapRes );
377     ImplCalcBigIntThreshold( nDPIX, nDPIY, rMapRes, rThresRes );
378 }
379 
380 // -----------------------------------------------------------------------
381 
382 static long ImplLogicToPixel( long n, long nDPI, long nMapNum, long nMapDenom,
383                               long nThres )
384 {
385     // To "use" it...
386     (void) nThres;
387 #ifdef USE_64BIT_INTS
388 #if (SAL_TYPES_SIZEOFLONG < 8)
389     if( (+n < nThres) && (-n < nThres) )
390     {
391        n *= nMapNum * nDPI;
392        if( nMapDenom != 1 )
393        {
394           n = (2 * n) / nMapDenom;
395           if( n < 0 ) --n; else ++n;
396           n /= 2;
397        }
398     }
399     else
400 #endif
401     {
402        sal_Int64 n64 = n;
403        n64 *= nMapNum;
404        n64 *= nDPI;
405        if( nMapDenom == 1 )
406           n = (long)n64;
407        else
408        {
409           n = (long)(2 * n64 / nMapDenom);
410           if( n < 0 ) --n; else ++n;
411           n /= 2;
412        }
413     }
414     return n;
415 #else // USE_64BIT_INTS
416     if ( Abs( n ) < nThres )
417     {
418         n *= nDPI * nMapNum;
419         n += n >= 0 ? nMapDenom/2 : -((nMapDenom-1)/2);
420                 return (n / nMapDenom);
421     }
422     else
423     {
424         BigInt aTemp( n );
425         aTemp *= BigInt( nDPI );
426         aTemp *= BigInt( nMapNum );
427 
428         if ( aTemp.IsNeg() )
429         {
430             BigInt aMapScDenom2( (nMapDenom-1)/2 );
431             aTemp -= aMapScDenom2;
432         }
433         else
434         {
435             BigInt aMapScDenom2( nMapDenom/2 );
436             aTemp += aMapScDenom2;
437         }
438 
439         aTemp /= BigInt( nMapDenom );
440         return (long)aTemp;
441     }
442 #endif
443 }
444 
445 // -----------------------------------------------------------------------
446 
447 static long ImplPixelToLogic( long n, long nDPI, long nMapNum, long nMapDenom,
448                               long nThres )
449 {
450     // To "use" it...
451    (void) nThres;
452 #ifdef USE_64BIT_INTS
453 #if (SAL_TYPES_SIZEOFLONG < 8)
454     if( (+n < nThres) && (-n < nThres) )
455         n = (2 * n * nMapDenom) / (nDPI * nMapNum);
456     else
457 #endif
458     {
459         sal_Int64 n64 = n;
460         n64 *= nMapDenom;
461         long nDenom  = nDPI * nMapNum;
462         n = (long)(2 * n64 / nDenom);
463     }
464     if( n < 0 ) --n; else ++n;
465     return (n / 2);
466 #else // USE_64BIT_INTS
467     if ( Abs( n ) < nThres )
468     {
469         long nDenom  = nDPI * nMapNum;
470         long nNum    = n * nMapDenom;
471         if( (nNum ^ nDenom) >= 0 )
472             nNum += nDenom/2;
473         else
474             nNum -= nDenom/2;
475         return (nNum / nDenom);
476     }
477     else
478     {
479         BigInt aDenom( nDPI );
480         aDenom *= BigInt( nMapNum );
481 
482         BigInt aNum( n );
483         aNum *= BigInt( nMapDenom );
484 
485         BigInt aDenom2( aDenom );
486         if ( aNum.IsNeg() )
487         {
488             if ( aDenom.IsNeg() )
489             {
490                 aDenom2 /= BigInt(2);
491                 aNum += aDenom2;
492             }
493             else
494             {
495                 aDenom2 -= 1;
496                 aDenom2 /= BigInt(2);
497                 aNum -= aDenom2;
498             }
499         }
500         else
501         {
502             if ( aDenom.IsNeg() )
503             {
504                 aDenom2 += 1;
505                 aDenom2 /= BigInt(2);
506                 aNum -= aDenom2;
507             }
508             else
509             {
510                 aDenom2 /= BigInt(2);
511                 aNum += aDenom2;
512             }
513         }
514 
515         aNum  /= aDenom;
516         return (long)aNum;
517     }
518 #endif
519 }
520 
521 // -----------------------------------------------------------------------
522 
523 long OutputDevice::ImplLogicXToDevicePixel( long nX ) const
524 {
525     if ( !mbMap )
526         return nX+mnOutOffX;
527 
528     return ImplLogicToPixel( nX + maMapRes.mnMapOfsX, mnDPIX,
529                              maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
530                              maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX;
531 }
532 
533 // -----------------------------------------------------------------------
534 
535 long OutputDevice::ImplLogicYToDevicePixel( long nY ) const
536 {
537     if ( !mbMap )
538         return nY+mnOutOffY;
539 
540     return ImplLogicToPixel( nY + maMapRes.mnMapOfsY, mnDPIY,
541                              maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
542                              maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY;
543 }
544 
545 // -----------------------------------------------------------------------
546 
547 long OutputDevice::ImplLogicWidthToDevicePixel( long nWidth ) const
548 {
549     if ( !mbMap )
550         return nWidth;
551 
552     return ImplLogicToPixel( nWidth, mnDPIX,
553                              maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
554                              maThresRes.mnThresLogToPixX );
555 }
556 
557 float OutputDevice::ImplFloatLogicWidthToDevicePixel( float fLogicWidth) const
558 {
559     if( !mbMap)
560         return fLogicWidth;
561     // TODO: consolidate the calculation into one multiplication
562     float fPixelWidth = (fLogicWidth * mnDPIX * maMapRes.mnMapScNumX) / maMapRes.mnMapScDenomX;
563     return fPixelWidth;
564 }
565 
566 // -----------------------------------------------------------------------
567 
568 long OutputDevice::ImplLogicHeightToDevicePixel( long nHeight ) const
569 {
570     if ( !mbMap )
571         return nHeight;
572 
573     return ImplLogicToPixel( nHeight, mnDPIY,
574                              maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
575                              maThresRes.mnThresLogToPixY );
576 }
577 
578 float OutputDevice::ImplFloatLogicHeightToDevicePixel( float fLogicHeight) const
579 {
580     if( !mbMap)
581         return fLogicHeight;
582     float fPixelHeight = (fLogicHeight * mnDPIY * maMapRes.mnMapScNumY) / maMapRes.mnMapScDenomY;
583     return fPixelHeight;
584 }
585 
586 // -----------------------------------------------------------------------
587 
588 long OutputDevice::ImplDevicePixelToLogicWidth( long nWidth ) const
589 {
590     if ( !mbMap )
591         return nWidth;
592 
593     return ImplPixelToLogic( nWidth, mnDPIX,
594                              maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
595                              maThresRes.mnThresPixToLogX );
596 }
597 
598 float OutputDevice::ImplFloatDevicePixelToLogicWidth( float fPixelWidth) const
599 {
600     if( !mbMap)
601         return fPixelWidth;
602     float fLogicHeight = (fPixelWidth * maMapRes.mnMapScDenomX) / (mnDPIX * maMapRes.mnMapScNumX);
603     return fLogicHeight;
604 }
605 
606 // -----------------------------------------------------------------------
607 
608 long OutputDevice::ImplDevicePixelToLogicHeight( long nHeight ) const
609 {
610     if ( !mbMap )
611         return nHeight;
612 
613     return ImplPixelToLogic( nHeight, mnDPIY,
614                              maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
615                              maThresRes.mnThresPixToLogY );
616 }
617 
618 float OutputDevice::ImplFloatDevicePixelToLogicHeight( float fPixelHeight) const
619 {
620     if( !mbMap)
621         return fPixelHeight;
622     float fLogicHeight = (fPixelHeight * maMapRes.mnMapScDenomY) / (mnDPIY * maMapRes.mnMapScNumY);
623     return fLogicHeight;
624 }
625 
626 
627 // -----------------------------------------------------------------------
628 
629 Point OutputDevice::ImplLogicToDevicePixel( const Point& rLogicPt ) const
630 {
631     if ( !mbMap )
632         return Point( rLogicPt.X()+mnOutOffX, rLogicPt.Y()+mnOutOffY );
633 
634     return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
635                                     maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
636                                     maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX,
637                   ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
638                                     maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
639                                     maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY );
640 }
641 
642 // -----------------------------------------------------------------------
643 
644 Size OutputDevice::ImplLogicToDevicePixel( const Size& rLogicSize ) const
645 {
646     if ( !mbMap )
647         return rLogicSize;
648 
649     return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
650                                    maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
651                                    maThresRes.mnThresLogToPixX ),
652                  ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
653                                    maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
654                                    maThresRes.mnThresLogToPixY ) );
655 }
656 
657 // -----------------------------------------------------------------------
658 
659 Rectangle OutputDevice::ImplLogicToDevicePixel( const Rectangle& rLogicRect ) const
660 {
661     if ( rLogicRect.IsEmpty() )
662         return rLogicRect;
663 
664     if ( !mbMap )
665     {
666         return Rectangle( rLogicRect.Left()+mnOutOffX, rLogicRect.Top()+mnOutOffY,
667                           rLogicRect.Right()+mnOutOffX, rLogicRect.Bottom()+mnOutOffY );
668     }
669 
670     return Rectangle( ImplLogicToPixel( rLogicRect.Left()+maMapRes.mnMapOfsX, mnDPIX,
671                                         maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
672                                         maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX,
673                       ImplLogicToPixel( rLogicRect.Top()+maMapRes.mnMapOfsY, mnDPIY,
674                                         maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
675                                         maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY,
676                       ImplLogicToPixel( rLogicRect.Right()+maMapRes.mnMapOfsX, mnDPIX,
677                                         maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
678                                         maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX,
679                       ImplLogicToPixel( rLogicRect.Bottom()+maMapRes.mnMapOfsY, mnDPIY,
680                                         maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
681                                         maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY );
682 }
683 
684 // -----------------------------------------------------------------------
685 
686 Polygon OutputDevice::ImplLogicToDevicePixel( const Polygon& rLogicPoly ) const
687 {
688     if ( !mbMap && !mnOutOffX && !mnOutOffY )
689         return rLogicPoly;
690 
691     sal_uInt16  i;
692     sal_uInt16  nPoints = rLogicPoly.GetSize();
693     Polygon aPoly( rLogicPoly );
694 
695     // Pointer auf das Point-Array holen (Daten werden kopiert)
696     const Point* pPointAry = aPoly.GetConstPointAry();
697 
698     if ( mbMap )
699     {
700         for ( i = 0; i < nPoints; i++ )
701         {
702             const Point* pPt = &(pPointAry[i]);
703             Point aPt;
704             aPt.X() = ImplLogicToPixel( pPt->X()+maMapRes.mnMapOfsX, mnDPIX,
705                                         maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
706                                         maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX;
707             aPt.Y() = ImplLogicToPixel( pPt->Y()+maMapRes.mnMapOfsY, mnDPIY,
708                                         maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
709                                         maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY;
710             aPoly[i] = aPt;
711         }
712     }
713     else
714     {
715         for ( i = 0; i < nPoints; i++ )
716         {
717             Point aPt = pPointAry[i];
718             aPt.X() += mnOutOffX;
719             aPt.Y() += mnOutOffY;
720             aPoly[i] = aPt;
721         }
722     }
723 
724     return aPoly;
725 }
726 
727 // -----------------------------------------------------------------------
728 
729 PolyPolygon OutputDevice::ImplLogicToDevicePixel( const PolyPolygon& rLogicPolyPoly ) const
730 {
731     if ( !mbMap && !mnOutOffX && !mnOutOffY )
732         return rLogicPolyPoly;
733 
734     PolyPolygon aPolyPoly( rLogicPolyPoly );
735     sal_uInt16      nPoly = aPolyPoly.Count();
736     for( sal_uInt16 i = 0; i < nPoly; i++ )
737     {
738         Polygon& rPoly = aPolyPoly[i];
739         rPoly = ImplLogicToDevicePixel( rPoly );
740     }
741     return aPolyPoly;
742 }
743 
744 // -----------------------------------------------------------------------
745 
746 LineInfo OutputDevice::ImplLogicToDevicePixel( const LineInfo& rLineInfo ) const
747 {
748     LineInfo aInfo( rLineInfo );
749 
750     if( aInfo.GetStyle() == LINE_DASH )
751     {
752         if( aInfo.GetDotCount() && aInfo.GetDotLen() )
753             aInfo.SetDotLen( Max( ImplLogicWidthToDevicePixel( aInfo.GetDotLen() ), 1L ) );
754         else
755             aInfo.SetDotCount( 0 );
756 
757         if( aInfo.GetDashCount() && aInfo.GetDashLen() )
758             aInfo.SetDashLen( Max( ImplLogicWidthToDevicePixel( aInfo.GetDashLen() ), 1L ) );
759         else
760             aInfo.SetDashCount( 0 );
761 
762         aInfo.SetDistance( ImplLogicWidthToDevicePixel( aInfo.GetDistance() ) );
763 
764         if( ( !aInfo.GetDashCount() && !aInfo.GetDotCount() ) || !aInfo.GetDistance() )
765             aInfo.SetStyle( LINE_SOLID );
766     }
767 
768     aInfo.SetWidth( ImplLogicWidthToDevicePixel( aInfo.GetWidth() ) );
769 
770     return aInfo;
771 }
772 
773 // -----------------------------------------------------------------------
774 
775 Rectangle OutputDevice::ImplDevicePixelToLogic( const Rectangle& rPixelRect ) const
776 {
777     if ( rPixelRect.IsEmpty() )
778         return rPixelRect;
779 
780     if ( !mbMap )
781     {
782         return Rectangle( rPixelRect.Left()-mnOutOffX, rPixelRect.Top()-mnOutOffY,
783                           rPixelRect.Right()-mnOutOffX, rPixelRect.Bottom()-mnOutOffY );
784     }
785 
786     return Rectangle( ImplPixelToLogic( rPixelRect.Left()-mnOutOffX-mnOutOffOrigX, mnDPIX,
787                                         maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
788                                         maThresRes.mnThresPixToLogX )-maMapRes.mnMapOfsX,
789                       ImplPixelToLogic( rPixelRect.Top()-mnOutOffY-mnOutOffOrigY, mnDPIY,
790                                         maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
791                                         maThresRes.mnThresPixToLogY )-maMapRes.mnMapOfsY,
792                       ImplPixelToLogic( rPixelRect.Right()-mnOutOffX-mnOutOffOrigX, mnDPIX,
793                                         maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
794                                         maThresRes.mnThresPixToLogX )-maMapRes.mnMapOfsX,
795                       ImplPixelToLogic( rPixelRect.Bottom()-mnOutOffY-mnOutOffOrigY, mnDPIY,
796                                         maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
797                                         maThresRes.mnThresPixToLogY )-maMapRes.mnMapOfsY );
798 }
799 
800 // -----------------------------------------------------------------------
801 
802 Region OutputDevice::ImplPixelToDevicePixel( const Region& rRegion ) const
803 {
804     DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
805 
806     if ( !mnOutOffX && !mnOutOffY )
807         return rRegion;
808 
809     Region aRegion( rRegion );
810     aRegion.Move( mnOutOffX+mnOutOffOrigX, mnOutOffY+mnOutOffOrigY );
811     return aRegion;
812 }
813 
814 // -----------------------------------------------------------------------
815 
816 void OutputDevice::EnableMapMode( sal_Bool bEnable )
817 {
818     mbMap = (bEnable != 0);
819 
820     if( mpAlphaVDev )
821         mpAlphaVDev->EnableMapMode( bEnable );
822 }
823 
824 // -----------------------------------------------------------------------
825 
826 void OutputDevice::SetMapMode()
827 {
828     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
829 
830     if ( mpMetaFile )
831         mpMetaFile->AddAction( new MetaMapModeAction( MapMode() ) );
832 
833     if ( mbMap || !maMapMode.IsDefault() )
834     {
835         mbMap       = sal_False;
836         maMapMode   = MapMode();
837 
838         // create new objects (clip region werden nicht neu skaliert)
839         mbNewFont   = sal_True;
840         mbInitFont  = sal_True;
841         if ( GetOutDevType() == OUTDEV_WINDOW )
842         {
843             if ( ((Window*)this)->mpWindowImpl->mpCursor )
844                 ((Window*)this)->mpWindowImpl->mpCursor->ImplNew();
845         }
846 
847         // #106426# Adapt logical offset when changing mapmode
848         mnOutOffLogicX = mnOutOffOrigX; // no mapping -> equal offsets
849         mnOutOffLogicY = mnOutOffOrigY;
850 
851         // #i75163#
852         ImplInvalidateViewTransform();
853     }
854 
855     if( mpAlphaVDev )
856         mpAlphaVDev->SetMapMode();
857 }
858 
859 // -----------------------------------------------------------------------
860 
861 void OutputDevice::SetMapMode( const MapMode& rNewMapMode )
862 {
863     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
864 
865     sal_Bool bRelMap = (rNewMapMode.GetMapUnit() == MAP_RELATIVE);
866 
867     if ( mpMetaFile )
868     {
869         mpMetaFile->AddAction( new MetaMapModeAction( rNewMapMode ) );
870 #ifdef DBG_UTIL
871         if ( GetOutDevType() != OUTDEV_PRINTER )
872             DBG_ASSERTWARNING( bRelMap, "Please record only relative MapModes!" );
873 #endif
874     }
875 
876     // Ist der MapMode der gleiche wie vorher, dann mache nichts
877     if ( maMapMode == rNewMapMode )
878         return;
879 
880     if( mpAlphaVDev )
881         mpAlphaVDev->SetMapMode( rNewMapMode );
882 
883     // Ist Default-MapMode, dann bereche nichts
884     sal_Bool bOldMap = mbMap;
885     mbMap = !rNewMapMode.IsDefault();
886     if ( mbMap )
887     {
888         // Falls nur der Orign umgesetzt wird, dann scaliere nichts neu
889         if ( (rNewMapMode.GetMapUnit() == maMapMode.GetMapUnit()) &&
890              (rNewMapMode.GetScaleX()  == maMapMode.GetScaleX())  &&
891              (rNewMapMode.GetScaleY()  == maMapMode.GetScaleY())  &&
892              (bOldMap                  == mbMap) )
893         {
894             // Offset setzen
895             Point aOrigin = rNewMapMode.GetOrigin();
896             maMapRes.mnMapOfsX = aOrigin.X();
897             maMapRes.mnMapOfsY = aOrigin.Y();
898             maMapMode = rNewMapMode;
899 
900             // #i75163#
901             ImplInvalidateViewTransform();
902 
903             return;
904         }
905         if ( !bOldMap && bRelMap )
906         {
907             maMapRes.mnMapScNumX    = 1;
908             maMapRes.mnMapScNumY    = 1;
909             maMapRes.mnMapScDenomX  = mnDPIX;
910             maMapRes.mnMapScDenomY  = mnDPIY;
911             maMapRes.mnMapOfsX      = 0;
912             maMapRes.mnMapOfsY      = 0;
913         }
914 
915         // Neue MapMode-Aufloesung berechnen
916         ImplCalcMapResolution( rNewMapMode, mnDPIX, mnDPIY, maMapRes, maThresRes );
917     }
918 
919     // Neuen MapMode setzen
920     if ( bRelMap )
921     {
922         Point aOrigin( maMapRes.mnMapOfsX, maMapRes.mnMapOfsY );
923         // aScale? = maMapMode.GetScale?() * rNewMapMode.GetScale?()
924         Fraction aScaleX = ImplMakeFraction( maMapMode.GetScaleX().GetNumerator(),
925                                              rNewMapMode.GetScaleX().GetNumerator(),
926                                              maMapMode.GetScaleX().GetDenominator(),
927                                              rNewMapMode.GetScaleX().GetDenominator() );
928         Fraction aScaleY = ImplMakeFraction( maMapMode.GetScaleY().GetNumerator(),
929                                              rNewMapMode.GetScaleY().GetNumerator(),
930                                              maMapMode.GetScaleY().GetDenominator(),
931                                              rNewMapMode.GetScaleY().GetDenominator() );
932         maMapMode.SetOrigin( aOrigin );
933         maMapMode.SetScaleX( aScaleX );
934         maMapMode.SetScaleY( aScaleY );
935     }
936     else
937         maMapMode = rNewMapMode;
938 
939     // create new objects (clip region werden nicht neu skaliert)
940     mbNewFont   = sal_True;
941     mbInitFont  = sal_True;
942     if ( GetOutDevType() == OUTDEV_WINDOW )
943     {
944         if ( ((Window*)this)->mpWindowImpl->mpCursor )
945             ((Window*)this)->mpWindowImpl->mpCursor->ImplNew();
946     }
947 
948     // #106426# Adapt logical offset when changing mapmode
949     mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
950                                        maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
951                                        maThresRes.mnThresPixToLogX );
952     mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
953                                        maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
954                                        maThresRes.mnThresPixToLogY );
955 
956     // #i75163#
957     ImplInvalidateViewTransform();
958 }
959 
960 // -----------------------------------------------------------------------
961 
962 void OutputDevice::SetRelativeMapMode( const MapMode& rNewMapMode )
963 {
964     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
965 
966     // Ist der MapMode der gleiche wie vorher, dann mache nichts
967     if ( maMapMode == rNewMapMode )
968         return;
969 
970     MapUnit eOld = maMapMode.GetMapUnit();
971     MapUnit eNew = rNewMapMode.GetMapUnit();
972 
973     // a?F = rNewMapMode.GetScale?() / maMapMode.GetScale?()
974     Fraction aXF = ImplMakeFraction( rNewMapMode.GetScaleX().GetNumerator(),
975                                      maMapMode.GetScaleX().GetDenominator(),
976                                      rNewMapMode.GetScaleX().GetDenominator(),
977                                      maMapMode.GetScaleX().GetNumerator() );
978     Fraction aYF = ImplMakeFraction( rNewMapMode.GetScaleY().GetNumerator(),
979                                      maMapMode.GetScaleY().GetDenominator(),
980                                      rNewMapMode.GetScaleY().GetDenominator(),
981                                      maMapMode.GetScaleY().GetNumerator() );
982 
983     Point aPt( LogicToLogic( Point(), NULL, &rNewMapMode ) );
984     if ( eNew != eOld )
985     {
986         if ( eOld > MAP_PIXEL )
987         {
988             DBG_ERRORFILE( "Not implemented MapUnit" );
989         }
990         else if ( eNew > MAP_PIXEL )
991         {
992             DBG_ERRORFILE( "Not implemented MapUnit" );
993         }
994         else
995         {
996             Fraction aF( aImplNumeratorAry[eNew] * aImplDenominatorAry[eOld],
997                          aImplNumeratorAry[eOld] * aImplDenominatorAry[eNew] );
998 
999             // a?F =  a?F * aF
1000             aXF = ImplMakeFraction( aXF.GetNumerator(),   aF.GetNumerator(),
1001                                     aXF.GetDenominator(), aF.GetDenominator() );
1002             aYF = ImplMakeFraction( aYF.GetNumerator(),   aF.GetNumerator(),
1003                                     aYF.GetDenominator(), aF.GetDenominator() );
1004             if ( eOld == MAP_PIXEL )
1005             {
1006                 aXF *= Fraction( mnDPIX, 1 );
1007                 aYF *= Fraction( mnDPIY, 1 );
1008             }
1009             else if ( eNew == MAP_PIXEL )
1010             {
1011                 aXF *= Fraction( 1, mnDPIX );
1012                 aYF *= Fraction( 1, mnDPIY );
1013             }
1014         }
1015     }
1016 
1017     MapMode aNewMapMode( MAP_RELATIVE, Point( -aPt.X(), -aPt.Y() ), aXF, aYF );
1018     SetMapMode( aNewMapMode );
1019 
1020     if ( eNew != eOld )
1021         maMapMode = rNewMapMode;
1022 
1023     // #106426# Adapt logical offset when changing mapmode
1024     mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
1025                                        maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1026                                        maThresRes.mnThresPixToLogX );
1027     mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
1028                                        maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1029                                        maThresRes.mnThresPixToLogY );
1030 
1031     if( mpAlphaVDev )
1032         mpAlphaVDev->SetRelativeMapMode( rNewMapMode );
1033 }
1034 
1035 // -----------------------------------------------------------------------
1036 
1037 // #i75163#
1038 basegfx::B2DHomMatrix OutputDevice::GetViewTransformation() const
1039 {
1040     if(mbMap)
1041     {
1042         // #i82615#
1043         if(!mpOutDevData)
1044         {
1045             const_cast< OutputDevice* >(this)->ImplInitOutDevData();
1046         }
1047 
1048         if(!mpOutDevData->mpViewTransform)
1049         {
1050             mpOutDevData->mpViewTransform = new basegfx::B2DHomMatrix;
1051 
1052             const double fScaleFactorX((double)mnDPIX * (double)maMapRes.mnMapScNumX / (double)maMapRes.mnMapScDenomX);
1053             const double fScaleFactorY((double)mnDPIY * (double)maMapRes.mnMapScNumY / (double)maMapRes.mnMapScDenomY);
1054             const double fZeroPointX(((double)maMapRes.mnMapOfsX * fScaleFactorX) + (double)mnOutOffOrigX);
1055             const double fZeroPointY(((double)maMapRes.mnMapOfsY * fScaleFactorY) + (double)mnOutOffOrigY);
1056 
1057             mpOutDevData->mpViewTransform->set(0, 0, fScaleFactorX);
1058             mpOutDevData->mpViewTransform->set(1, 1, fScaleFactorY);
1059             mpOutDevData->mpViewTransform->set(0, 2, fZeroPointX);
1060             mpOutDevData->mpViewTransform->set(1, 2, fZeroPointY);
1061         }
1062 
1063         return *mpOutDevData->mpViewTransform;
1064     }
1065     else
1066     {
1067         return basegfx::B2DHomMatrix();
1068     }
1069 }
1070 
1071 // -----------------------------------------------------------------------
1072 
1073 // #i75163#
1074 basegfx::B2DHomMatrix OutputDevice::GetInverseViewTransformation() const
1075 {
1076     if(mbMap)
1077     {
1078         // #i82615#
1079         if(!mpOutDevData)
1080         {
1081             const_cast< OutputDevice* >(this)->ImplInitOutDevData();
1082         }
1083 
1084         if(!mpOutDevData->mpInverseViewTransform)
1085         {
1086             GetViewTransformation();
1087             mpOutDevData->mpInverseViewTransform = new basegfx::B2DHomMatrix(*mpOutDevData->mpViewTransform);
1088             mpOutDevData->mpInverseViewTransform->invert();
1089         }
1090 
1091         return *mpOutDevData->mpInverseViewTransform;
1092     }
1093     else
1094     {
1095         return basegfx::B2DHomMatrix();
1096     }
1097 }
1098 
1099 // -----------------------------------------------------------------------
1100 
1101 // #i75163#
1102 basegfx::B2DHomMatrix OutputDevice::GetViewTransformation( const MapMode& rMapMode ) const
1103 {
1104     // #i82615#
1105     ImplMapRes          aMapRes;
1106     ImplThresholdRes    aThresRes;
1107     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1108 
1109     basegfx::B2DHomMatrix aTransform;
1110 
1111     const double fScaleFactorX((double)mnDPIX * (double)aMapRes.mnMapScNumX / (double)aMapRes.mnMapScDenomX);
1112     const double fScaleFactorY((double)mnDPIY * (double)aMapRes.mnMapScNumY / (double)aMapRes.mnMapScDenomY);
1113     const double fZeroPointX(((double)aMapRes.mnMapOfsX * fScaleFactorX) + (double)mnOutOffOrigX);
1114     const double fZeroPointY(((double)aMapRes.mnMapOfsY * fScaleFactorY) + (double)mnOutOffOrigY);
1115 
1116     aTransform.set(0, 0, fScaleFactorX);
1117     aTransform.set(1, 1, fScaleFactorY);
1118     aTransform.set(0, 2, fZeroPointX);
1119     aTransform.set(1, 2, fZeroPointY);
1120 
1121     return aTransform;
1122 }
1123 
1124 // -----------------------------------------------------------------------
1125 
1126 // #i75163#
1127 basegfx::B2DHomMatrix OutputDevice::GetInverseViewTransformation( const MapMode& rMapMode ) const
1128 {
1129     basegfx::B2DHomMatrix aMatrix( GetViewTransformation( rMapMode ) );
1130     aMatrix.invert();
1131     return aMatrix;
1132 }
1133 
1134 // -----------------------------------------------------------------------
1135 
1136 basegfx::B2DHomMatrix OutputDevice::ImplGetDeviceTransformation() const
1137 {
1138     basegfx::B2DHomMatrix aTransformation = GetViewTransformation();
1139     // TODO: is it worth to cache the transformed result?
1140     if( mnOutOffX || mnOutOffY )
1141         aTransformation.translate( mnOutOffX, mnOutOffY );
1142     return aTransformation;
1143 }
1144 
1145 // -----------------------------------------------------------------------
1146 
1147 Point OutputDevice::LogicToPixel( const Point& rLogicPt ) const
1148 {
1149     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1150 
1151     if ( !mbMap )
1152         return rLogicPt;
1153 
1154     return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
1155                                     maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1156                                     maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1157                   ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
1158                                     maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1159                                     maThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1160 }
1161 
1162 // -----------------------------------------------------------------------
1163 
1164 Size OutputDevice::LogicToPixel( const Size& rLogicSize ) const
1165 {
1166     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1167 
1168     if ( !mbMap )
1169         return rLogicSize;
1170 
1171     return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
1172                                    maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1173                                    maThresRes.mnThresLogToPixX ),
1174                  ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
1175                                    maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1176                                    maThresRes.mnThresLogToPixY ) );
1177 }
1178 
1179 // -----------------------------------------------------------------------
1180 
1181 Rectangle OutputDevice::LogicToPixel( const Rectangle& rLogicRect ) const
1182 {
1183     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1184 
1185     if ( !mbMap || rLogicRect.IsEmpty() )
1186         return rLogicRect;
1187 
1188     return Rectangle( ImplLogicToPixel( rLogicRect.Left() + maMapRes.mnMapOfsX, mnDPIX,
1189                                         maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1190                                         maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1191                       ImplLogicToPixel( rLogicRect.Top() + maMapRes.mnMapOfsY, mnDPIY,
1192                                         maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1193                                         maThresRes.mnThresLogToPixY )+mnOutOffOrigY,
1194                       ImplLogicToPixel( rLogicRect.Right() + maMapRes.mnMapOfsX, mnDPIX,
1195                                         maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1196                                         maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1197                       ImplLogicToPixel( rLogicRect.Bottom() + maMapRes.mnMapOfsY, mnDPIY,
1198                                         maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1199                                         maThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1200 }
1201 
1202 // -----------------------------------------------------------------------
1203 
1204 Polygon OutputDevice::LogicToPixel( const Polygon& rLogicPoly ) const
1205 {
1206     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1207     DBG_CHKOBJ( &rLogicPoly, Polygon, NULL );
1208 
1209     if ( !mbMap )
1210         return rLogicPoly;
1211 
1212     sal_uInt16  i;
1213     sal_uInt16  nPoints = rLogicPoly.GetSize();
1214     Polygon aPoly( rLogicPoly );
1215 
1216     // Pointer auf das Point-Array holen (Daten werden kopiert)
1217     const Point* pPointAry = aPoly.GetConstPointAry();
1218 
1219     for ( i = 0; i < nPoints; i++ )
1220     {
1221         const Point* pPt = &(pPointAry[i]);
1222         Point aPt;
1223         aPt.X() = ImplLogicToPixel( pPt->X() + maMapRes.mnMapOfsX, mnDPIX,
1224                                     maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1225                                     maThresRes.mnThresLogToPixX )+mnOutOffOrigX;
1226         aPt.Y() = ImplLogicToPixel( pPt->Y() + maMapRes.mnMapOfsY, mnDPIY,
1227                                     maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1228                                     maThresRes.mnThresLogToPixY )+mnOutOffOrigY;
1229         aPoly[i] = aPt;
1230     }
1231 
1232     return aPoly;
1233 }
1234 
1235 // -----------------------------------------------------------------------
1236 
1237 PolyPolygon OutputDevice::LogicToPixel( const PolyPolygon& rLogicPolyPoly ) const
1238 {
1239     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1240     DBG_CHKOBJ( &rLogicPolyPoly, PolyPolygon, NULL );
1241 
1242     if ( !mbMap )
1243         return rLogicPolyPoly;
1244 
1245     PolyPolygon aPolyPoly( rLogicPolyPoly );
1246     sal_uInt16      nPoly = aPolyPoly.Count();
1247     for( sal_uInt16 i = 0; i < nPoly; i++ )
1248     {
1249         Polygon& rPoly = aPolyPoly[i];
1250         rPoly = LogicToPixel( rPoly );
1251     }
1252     return aPolyPoly;
1253 }
1254 
1255 // -----------------------------------------------------------------------
1256 
1257 basegfx::B2DPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolygon& rLogicPoly ) const
1258 {
1259     basegfx::B2DPolygon aTransformedPoly = rLogicPoly;
1260     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation();
1261     aTransformedPoly.transform( rTransformationMatrix );
1262     return aTransformedPoly;
1263 }
1264 
1265 // -----------------------------------------------------------------------
1266 
1267 basegfx::B2DPolyPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly ) const
1268 {
1269     basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly;
1270     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation();
1271     aTransformedPoly.transform( rTransformationMatrix );
1272     return aTransformedPoly;
1273 }
1274 
1275 // -----------------------------------------------------------------------
1276 
1277 Region OutputDevice::LogicToPixel( const Region& rLogicRegion ) const
1278 {
1279     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1280     DBG_CHKOBJ( &rLogicRegion, Region, ImplDbgTestRegion );
1281 
1282     RegionType eType = rLogicRegion.GetType();
1283 
1284     if ( !mbMap || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
1285         return rLogicRegion;
1286 
1287     Region          aRegion;
1288     const ImplRegion& rImplRegion = *rLogicRegion.ImplGetImplRegion();
1289     const PolyPolygon* pPolyPoly = rImplRegion.mpPolyPoly;
1290     const basegfx::B2DPolyPolygon* pB2DPolyPoly = rImplRegion.mpB2DPolyPoly;
1291 
1292     if ( pPolyPoly )
1293         aRegion = Region( LogicToPixel( *pPolyPoly ) );
1294     else if( pB2DPolyPoly )
1295     {
1296         basegfx::B2DPolyPolygon aTransformedPoly = *pB2DPolyPoly;
1297         const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation();
1298         aTransformedPoly.transform( rTransformationMatrix );
1299         aRegion = Region( aTransformedPoly );
1300     }
1301     else
1302     {
1303         long                nX;
1304         long                nY;
1305         long                nWidth;
1306         long                nHeight;
1307         ImplRegionInfo      aInfo;
1308         sal_Bool                bRegionRect;
1309 
1310         aRegion.ImplBeginAddRect();
1311         bRegionRect = rLogicRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
1312         while ( bRegionRect )
1313         {
1314             Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
1315             aRegion.ImplAddRect( LogicToPixel( aRect ) );
1316             bRegionRect = rLogicRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
1317         }
1318         aRegion.ImplEndAddRect();
1319     }
1320 
1321     return aRegion;
1322 }
1323 
1324 // -----------------------------------------------------------------------
1325 
1326 Point OutputDevice::LogicToPixel( const Point& rLogicPt,
1327                                   const MapMode& rMapMode ) const
1328 {
1329     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1330 
1331     if ( rMapMode.IsDefault() )
1332         return rLogicPt;
1333 
1334     // MapMode-Aufloesung berechnen und Umrechnen
1335     ImplMapRes          aMapRes;
1336     ImplThresholdRes    aThresRes;
1337     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1338 
1339     return Point( ImplLogicToPixel( rLogicPt.X() + aMapRes.mnMapOfsX, mnDPIX,
1340                                     aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1341                                     aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1342                   ImplLogicToPixel( rLogicPt.Y() + aMapRes.mnMapOfsY, mnDPIY,
1343                                     aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1344                                     aThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1345 }
1346 
1347 // -----------------------------------------------------------------------
1348 
1349 Size OutputDevice::LogicToPixel( const Size& rLogicSize,
1350                                  const MapMode& rMapMode ) const
1351 {
1352     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1353 
1354     if ( rMapMode.IsDefault() )
1355         return rLogicSize;
1356 
1357     // MapMode-Aufloesung berechnen und Umrechnen
1358     ImplMapRes          aMapRes;
1359     ImplThresholdRes    aThresRes;
1360     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1361 
1362     return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
1363                                    aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1364                                    aThresRes.mnThresLogToPixX ),
1365                  ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
1366                                    aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1367                                    aThresRes.mnThresLogToPixY ) );
1368 }
1369 
1370 // -----------------------------------------------------------------------
1371 
1372 Rectangle OutputDevice::LogicToPixel( const Rectangle& rLogicRect,
1373                                       const MapMode& rMapMode ) const
1374 {
1375     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1376 
1377     if ( rMapMode.IsDefault() || rLogicRect.IsEmpty() )
1378         return rLogicRect;
1379 
1380     // MapMode-Aufloesung berechnen und Umrechnen
1381     ImplMapRes          aMapRes;
1382     ImplThresholdRes    aThresRes;
1383     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1384 
1385     return Rectangle( ImplLogicToPixel( rLogicRect.Left() + aMapRes.mnMapOfsX, mnDPIX,
1386                                         aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1387                                         aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1388                       ImplLogicToPixel( rLogicRect.Top() + aMapRes.mnMapOfsY, mnDPIY,
1389                                         aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1390                                         aThresRes.mnThresLogToPixY )+mnOutOffOrigY,
1391                       ImplLogicToPixel( rLogicRect.Right() + aMapRes.mnMapOfsX, mnDPIX,
1392                                         aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1393                                         aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1394                       ImplLogicToPixel( rLogicRect.Bottom() + aMapRes.mnMapOfsY, mnDPIY,
1395                                         aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1396                                         aThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1397 }
1398 
1399 // -----------------------------------------------------------------------
1400 
1401 Polygon OutputDevice::LogicToPixel( const Polygon& rLogicPoly,
1402                                     const MapMode& rMapMode ) const
1403 {
1404     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1405     DBG_CHKOBJ( &rLogicPoly, Polygon, NULL );
1406 
1407     if ( rMapMode.IsDefault() )
1408         return rLogicPoly;
1409 
1410     // MapMode-Aufloesung berechnen und Umrechnen
1411     ImplMapRes          aMapRes;
1412     ImplThresholdRes    aThresRes;
1413     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1414 
1415     sal_uInt16  i;
1416     sal_uInt16  nPoints = rLogicPoly.GetSize();
1417     Polygon aPoly( rLogicPoly );
1418 
1419     // Pointer auf das Point-Array holen (Daten werden kopiert)
1420     const Point* pPointAry = aPoly.GetConstPointAry();
1421 
1422     for ( i = 0; i < nPoints; i++ )
1423     {
1424         const Point* pPt = &(pPointAry[i]);
1425         Point aPt;
1426         aPt.X() = ImplLogicToPixel( pPt->X() + aMapRes.mnMapOfsX, mnDPIX,
1427                                     aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1428                                     aThresRes.mnThresLogToPixX )+mnOutOffOrigX;
1429         aPt.Y() = ImplLogicToPixel( pPt->Y() + aMapRes.mnMapOfsY, mnDPIY,
1430                                     aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1431                                     aThresRes.mnThresLogToPixY )+mnOutOffOrigY;
1432         aPoly[i] = aPt;
1433     }
1434 
1435     return aPoly;
1436 }
1437 
1438 // -----------------------------------------------------------------------
1439 
1440 PolyPolygon OutputDevice::LogicToPixel( const PolyPolygon& rLogicPolyPoly,
1441                                         const MapMode& rMapMode ) const
1442 {
1443     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1444     DBG_CHKOBJ( &rLogicPolyPoly, PolyPolygon, NULL );
1445 
1446     if ( rMapMode.IsDefault() )
1447         return rLogicPolyPoly;
1448 
1449     PolyPolygon aPolyPoly( rLogicPolyPoly );
1450     sal_uInt16      nPoly = aPolyPoly.Count();
1451     for( sal_uInt16 i = 0; i < nPoly; i++ )
1452     {
1453         Polygon& rPoly = aPolyPoly[i];
1454         rPoly = LogicToPixel( rPoly, rMapMode );
1455     }
1456     return aPolyPoly;
1457 }
1458 
1459 // -----------------------------------------------------------------------
1460 
1461 basegfx::B2DPolyPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly,
1462                                                     const MapMode& rMapMode ) const
1463 {
1464     basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly;
1465     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation( rMapMode );
1466     aTransformedPoly.transform( rTransformationMatrix );
1467     return aTransformedPoly;
1468 }
1469 
1470 // -----------------------------------------------------------------------
1471 
1472 basegfx::B2DPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolygon& rLogicPoly,
1473                                                 const MapMode& rMapMode ) const
1474 {
1475     basegfx::B2DPolygon aTransformedPoly = rLogicPoly;
1476     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation( rMapMode );
1477     aTransformedPoly.transform( rTransformationMatrix );
1478     return aTransformedPoly;
1479 }
1480 
1481 // -----------------------------------------------------------------------
1482 
1483 Region OutputDevice::LogicToPixel( const Region& rLogicRegion,
1484                                    const MapMode& rMapMode ) const
1485 {
1486     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1487     DBG_CHKOBJ( &rLogicRegion, Region, ImplDbgTestRegion );
1488 
1489     RegionType eType = rLogicRegion.GetType();
1490 
1491     if ( rMapMode.IsDefault() || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
1492         return rLogicRegion;
1493 
1494     Region          aRegion;
1495     PolyPolygon*    pPolyPoly = rLogicRegion.ImplGetImplRegion()->mpPolyPoly;
1496 
1497     if( pPolyPoly )
1498         aRegion = Region( LogicToPixel( *pPolyPoly, rMapMode ) );
1499     else
1500     {
1501         long                nX;
1502         long                nY;
1503         long                nWidth;
1504         long                nHeight;
1505         ImplRegionInfo      aInfo;
1506         sal_Bool                bRegionRect;
1507 
1508         aRegion.ImplBeginAddRect();
1509         bRegionRect = rLogicRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
1510         while ( bRegionRect )
1511         {
1512             Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
1513             aRegion.ImplAddRect( LogicToPixel( aRect, rMapMode ) );
1514             bRegionRect = rLogicRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
1515         }
1516         aRegion.ImplEndAddRect();
1517     }
1518 
1519     return aRegion;
1520 }
1521 
1522 // -----------------------------------------------------------------------
1523 
1524 Point OutputDevice::PixelToLogic( const Point& rDevicePt ) const
1525 {
1526     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1527 
1528     if ( !mbMap )
1529         return rDevicePt;
1530 
1531     return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1532                                     maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1533                                     maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1534                   ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1535                                     maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1536                                     maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY );
1537 }
1538 
1539 // -----------------------------------------------------------------------
1540 
1541 Size OutputDevice::PixelToLogic( const Size& rDeviceSize ) const
1542 {
1543     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1544 
1545     if ( !mbMap )
1546         return rDeviceSize;
1547 
1548     return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1549                                    maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1550                                    maThresRes.mnThresPixToLogX ),
1551                  ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1552                                    maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1553                                    maThresRes.mnThresPixToLogY ) );
1554 }
1555 
1556 // -----------------------------------------------------------------------
1557 
1558 Rectangle OutputDevice::PixelToLogic( const Rectangle& rDeviceRect ) const
1559 {
1560     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1561 
1562     if ( !mbMap || rDeviceRect.IsEmpty() )
1563         return rDeviceRect;
1564 
1565     return Rectangle( ImplPixelToLogic( rDeviceRect.Left(), mnDPIX,
1566                                         maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1567                                         maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1568                       ImplPixelToLogic( rDeviceRect.Top(), mnDPIY,
1569                                         maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1570                                         maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY,
1571                       ImplPixelToLogic( rDeviceRect.Right(), mnDPIX,
1572                                         maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1573                                         maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1574                       ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY,
1575                                         maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1576                                         maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY );
1577 }
1578 
1579 // -----------------------------------------------------------------------
1580 
1581 Polygon OutputDevice::PixelToLogic( const Polygon& rDevicePoly ) const
1582 {
1583     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1584     DBG_CHKOBJ( &rDevicePoly, Polygon, NULL );
1585 
1586     if ( !mbMap )
1587         return rDevicePoly;
1588 
1589     sal_uInt16  i;
1590     sal_uInt16  nPoints = rDevicePoly.GetSize();
1591     Polygon aPoly( rDevicePoly );
1592 
1593     // Pointer auf das Point-Array holen (Daten werden kopiert)
1594     const Point* pPointAry = aPoly.GetConstPointAry();
1595 
1596     for ( i = 0; i < nPoints; i++ )
1597     {
1598         const Point* pPt = &(pPointAry[i]);
1599         Point aPt;
1600         aPt.X() = ImplPixelToLogic( pPt->X(), mnDPIX,
1601                                     maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1602                                     maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX;
1603         aPt.Y() = ImplPixelToLogic( pPt->Y(), mnDPIY,
1604                                     maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1605                                     maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY;
1606         aPoly[i] = aPt;
1607     }
1608 
1609     return aPoly;
1610 }
1611 
1612 // -----------------------------------------------------------------------
1613 
1614 PolyPolygon OutputDevice::PixelToLogic( const PolyPolygon& rDevicePolyPoly ) const
1615 {
1616     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1617     DBG_CHKOBJ( &rDevicePolyPoly, PolyPolygon, NULL );
1618 
1619     if ( !mbMap )
1620         return rDevicePolyPoly;
1621 
1622     PolyPolygon aPolyPoly( rDevicePolyPoly );
1623     sal_uInt16      nPoly = aPolyPoly.Count();
1624     for( sal_uInt16 i = 0; i < nPoly; i++ )
1625     {
1626         Polygon& rPoly = aPolyPoly[i];
1627         rPoly = PixelToLogic( rPoly );
1628     }
1629     return aPolyPoly;
1630 }
1631 
1632 // -----------------------------------------------------------------------
1633 
1634 basegfx::B2DPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolygon& rPixelPoly ) const
1635 {
1636     basegfx::B2DPolygon aTransformedPoly = rPixelPoly;
1637     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation();
1638     aTransformedPoly.transform( rTransformationMatrix );
1639     return aTransformedPoly;
1640 }
1641 
1642 // -----------------------------------------------------------------------
1643 
1644 basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygon& rPixelPolyPoly ) const
1645 {
1646     basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly;
1647     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation();
1648     aTransformedPoly.transform( rTransformationMatrix );
1649     return aTransformedPoly;
1650 }
1651 
1652 // -----------------------------------------------------------------------
1653 
1654 Region OutputDevice::PixelToLogic( const Region& rDeviceRegion ) const
1655 {
1656     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1657     DBG_CHKOBJ( &rDeviceRegion, Region, ImplDbgTestRegion );
1658 
1659     RegionType eType = rDeviceRegion.GetType();
1660 
1661     if ( !mbMap || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
1662         return rDeviceRegion;
1663 
1664     Region          aRegion;
1665     PolyPolygon*    pPolyPoly = rDeviceRegion.ImplGetImplRegion()->mpPolyPoly;
1666 
1667     if ( pPolyPoly )
1668         aRegion = Region( PixelToLogic( *pPolyPoly ) );
1669     else
1670     {
1671         long                nX;
1672         long                nY;
1673         long                nWidth;
1674         long                nHeight;
1675         ImplRegionInfo      aInfo;
1676         sal_Bool                bRegionRect;
1677 
1678         aRegion.ImplBeginAddRect();
1679         bRegionRect = rDeviceRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
1680         while ( bRegionRect )
1681         {
1682             Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
1683             aRegion.ImplAddRect( PixelToLogic( aRect ) );
1684             bRegionRect = rDeviceRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
1685         }
1686         aRegion.ImplEndAddRect();
1687     }
1688 
1689     return aRegion;
1690 }
1691 
1692 // -----------------------------------------------------------------------
1693 
1694 Point OutputDevice::PixelToLogic( const Point& rDevicePt,
1695                                   const MapMode& rMapMode ) const
1696 {
1697     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1698 
1699     // Ist Default-MapMode, dann bereche nichts
1700     if ( rMapMode.IsDefault() )
1701         return rDevicePt;
1702 
1703     // MapMode-Aufloesung berechnen und Umrechnen
1704     ImplMapRes          aMapRes;
1705     ImplThresholdRes    aThresRes;
1706     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1707 
1708     return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1709                                     aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1710                                     aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1711                   ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1712                                     aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1713                                     aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1714 }
1715 
1716 // -----------------------------------------------------------------------
1717 
1718 Size OutputDevice::PixelToLogic( const Size& rDeviceSize,
1719                                  const MapMode& rMapMode ) const
1720 {
1721     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1722 
1723     // Ist Default-MapMode, dann bereche nichts
1724     if ( rMapMode.IsDefault() )
1725         return rDeviceSize;
1726 
1727     // MapMode-Aufloesung berechnen und Umrechnen
1728     ImplMapRes          aMapRes;
1729     ImplThresholdRes    aThresRes;
1730     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1731 
1732     return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1733                                    aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1734                                    aThresRes.mnThresPixToLogX ),
1735                  ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1736                                    aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1737                                    aThresRes.mnThresPixToLogY ) );
1738 }
1739 
1740 // -----------------------------------------------------------------------
1741 
1742 Rectangle OutputDevice::PixelToLogic( const Rectangle& rDeviceRect,
1743                                       const MapMode& rMapMode ) const
1744 {
1745     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1746 
1747     // Ist Default-MapMode, dann bereche nichts
1748     if ( rMapMode.IsDefault() || rDeviceRect.IsEmpty() )
1749         return rDeviceRect;
1750 
1751     // MapMode-Aufloesung berechnen und Umrechnen
1752     ImplMapRes          aMapRes;
1753     ImplThresholdRes    aThresRes;
1754     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1755 
1756     return Rectangle( ImplPixelToLogic( rDeviceRect.Left(), mnDPIX,
1757                                         aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1758                                         aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1759                       ImplPixelToLogic( rDeviceRect.Top(), mnDPIY,
1760                                         aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1761                                         aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY,
1762                       ImplPixelToLogic( rDeviceRect.Right(), mnDPIX,
1763                                         aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1764                                         aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1765                       ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY,
1766                                         aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1767                                         aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1768 }
1769 
1770 // -----------------------------------------------------------------------
1771 
1772 Polygon OutputDevice::PixelToLogic( const Polygon& rDevicePoly,
1773                                     const MapMode& rMapMode ) const
1774 {
1775     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1776     DBG_CHKOBJ( &rDevicePoly, Polygon, NULL );
1777 
1778     // Ist Default-MapMode, dann bereche nichts
1779     if ( rMapMode.IsDefault() )
1780         return rDevicePoly;
1781 
1782     // MapMode-Aufloesung berechnen und Umrechnen
1783     ImplMapRes          aMapRes;
1784     ImplThresholdRes    aThresRes;
1785     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1786 
1787     sal_uInt16  i;
1788     sal_uInt16  nPoints = rDevicePoly.GetSize();
1789     Polygon aPoly( rDevicePoly );
1790 
1791     // Pointer auf das Point-Array holen (Daten werden kopiert)
1792     const Point* pPointAry = aPoly.GetConstPointAry();
1793 
1794     for ( i = 0; i < nPoints; i++ )
1795     {
1796         const Point* pPt = &(pPointAry[i]);
1797         Point aPt;
1798         aPt.X() = ImplPixelToLogic( pPt->X(), mnDPIX,
1799                                     aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1800                                     aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX;
1801         aPt.Y() = ImplPixelToLogic( pPt->Y(), mnDPIY,
1802                                     aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1803                                     aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY;
1804         aPoly[i] = aPt;
1805     }
1806 
1807     return aPoly;
1808 }
1809 
1810 // -----------------------------------------------------------------------
1811 
1812 PolyPolygon OutputDevice::PixelToLogic( const PolyPolygon& rDevicePolyPoly,
1813                                         const MapMode& rMapMode ) const
1814 {
1815     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1816     DBG_CHKOBJ( &rDevicePolyPoly, PolyPolygon, NULL );
1817 
1818     if ( rMapMode.IsDefault() )
1819         return rDevicePolyPoly;
1820 
1821     PolyPolygon aPolyPoly( rDevicePolyPoly );
1822     sal_uInt16      nPoly = aPolyPoly.Count();
1823     for( sal_uInt16 i = 0; i < nPoly; i++ )
1824     {
1825         Polygon& rPoly = aPolyPoly[i];
1826         rPoly = PixelToLogic( rPoly, rMapMode );
1827     }
1828     return aPolyPoly;
1829 }
1830 
1831 // -----------------------------------------------------------------------
1832 
1833 basegfx::B2DPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolygon& rPixelPoly,
1834                                                 const MapMode& rMapMode ) const
1835 {
1836     basegfx::B2DPolygon aTransformedPoly = rPixelPoly;
1837     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation( rMapMode );
1838     aTransformedPoly.transform( rTransformationMatrix );
1839     return aTransformedPoly;
1840 }
1841 
1842 // -----------------------------------------------------------------------
1843 
1844 basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygon& rPixelPolyPoly,
1845                                                     const MapMode& rMapMode ) const
1846 {
1847     basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly;
1848     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation( rMapMode );
1849     aTransformedPoly.transform( rTransformationMatrix );
1850     return aTransformedPoly;
1851 }
1852 
1853 // -----------------------------------------------------------------------
1854 
1855 Region OutputDevice::PixelToLogic( const Region& rDeviceRegion,
1856                                    const MapMode& rMapMode ) const
1857 {
1858     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1859     DBG_CHKOBJ( &rDeviceRegion, Region, ImplDbgTestRegion );
1860 
1861     RegionType eType = rDeviceRegion.GetType();
1862 
1863     if ( rMapMode.IsDefault() || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
1864         return rDeviceRegion;
1865 
1866     Region          aRegion;
1867     PolyPolygon*    pPolyPoly = rDeviceRegion.ImplGetImplRegion()->mpPolyPoly;
1868 
1869     if ( pPolyPoly )
1870         aRegion = Region( PixelToLogic( *pPolyPoly, rMapMode ) );
1871     else
1872     {
1873         long                nX;
1874         long                nY;
1875         long                nWidth;
1876         long                nHeight;
1877         ImplRegionInfo      aInfo;
1878         sal_Bool                bRegionRect;
1879 
1880         aRegion.ImplBeginAddRect();
1881         bRegionRect = rDeviceRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
1882         while ( bRegionRect )
1883         {
1884             Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
1885             aRegion.ImplAddRect( PixelToLogic( aRect, rMapMode ) );
1886             bRegionRect = rDeviceRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
1887         }
1888         aRegion.ImplEndAddRect();
1889     }
1890 
1891     return aRegion;
1892 }
1893 
1894 // -----------------------------------------------------------------------
1895 
1896 #define ENTER0( rSource, pMapModeSource, pMapModeDest )                 \
1897     if ( !pMapModeSource )                                              \
1898         pMapModeSource = &maMapMode;                                    \
1899     if ( !pMapModeDest )                                                \
1900         pMapModeDest = &maMapMode;                                      \
1901     if ( *pMapModeSource == *pMapModeDest )                             \
1902         return rSource
1903 
1904 // -----------------------------------------------------------------------
1905 
1906 #define ENTER1( rSource, pMapModeSource, pMapModeDest )                 \
1907     ENTER0( rSource, pMapModeSource, pMapModeDest );                    \
1908                                                                         \
1909     ImplMapRes aMapResSource;                                           \
1910     ImplMapRes aMapResDest;                                             \
1911                                                                         \
1912     if ( !mbMap || pMapModeSource != &maMapMode )                       \
1913     {                                                                   \
1914         if ( pMapModeSource->GetMapUnit() == MAP_RELATIVE )             \
1915             aMapResSource = maMapRes;                                   \
1916         ImplCalcMapResolution( *pMapModeSource,                         \
1917                                mnDPIX, mnDPIY, aMapResSource );         \
1918     }                                                                   \
1919     else                                                                \
1920         aMapResSource = maMapRes;                                       \
1921     if ( !mbMap || pMapModeDest != &maMapMode )                         \
1922     {                                                                   \
1923         if ( pMapModeDest->GetMapUnit() == MAP_RELATIVE )               \
1924             aMapResDest = maMapRes;                                     \
1925         ImplCalcMapResolution( *pMapModeDest,                           \
1926                                mnDPIX, mnDPIY, aMapResDest );           \
1927     }                                                                   \
1928     else                                                                \
1929         aMapResDest = maMapRes
1930 
1931 // -----------------------------------------------------------------------
1932 
1933 #define ENTER2( eUnitSource, eUnitDest )                                \
1934     DBG_ASSERT( eUnitSource != MAP_SYSFONT                              \
1935                 && eUnitSource != MAP_APPFONT                           \
1936                 && eUnitSource != MAP_RELATIVE,                         \
1937                 "Source MapUnit nicht erlaubt" );                       \
1938     DBG_ASSERT( eUnitDest != MAP_SYSFONT                                \
1939                 && eUnitDest != MAP_APPFONT                             \
1940                 && eUnitDest != MAP_RELATIVE,                           \
1941                 "Destination MapUnit nicht erlaubt" );                  \
1942     DBG_ASSERTWARNING( eUnitSource != MAP_PIXEL,                        \
1943                        "MAP_PIXEL mit 72dpi angenaehert" );             \
1944     DBG_ASSERTWARNING( eUnitDest != MAP_PIXEL,                          \
1945                        "MAP_PIXEL mit 72dpi angenaehert" )
1946 
1947 // -----------------------------------------------------------------------
1948 
1949 #define ENTER3( eUnitSource, eUnitDest )                                \
1950     long nNumerator      = 1;       \
1951     long nDenominator    = 1;       \
1952     DBG_ASSERT( eUnitSource < MAP_LASTENUMDUMMY, "Invalid source map unit");    \
1953     DBG_ASSERT( eUnitDest < MAP_LASTENUMDUMMY, "Invalid destination map unit"); \
1954     if( (eUnitSource < MAP_LASTENUMDUMMY) && (eUnitDest < MAP_LASTENUMDUMMY) )  \
1955     {   \
1956         nNumerator   = aImplNumeratorAry[eUnitSource] *             \
1957                            aImplDenominatorAry[eUnitDest];              \
1958         nDenominator     = aImplNumeratorAry[eUnitDest] *               \
1959                            aImplDenominatorAry[eUnitSource];            \
1960     } \
1961     if ( eUnitSource == MAP_PIXEL )                                     \
1962         nDenominator *= 72;                                             \
1963     else if( eUnitDest == MAP_PIXEL )                                   \
1964         nNumerator *= 72
1965 
1966 // -----------------------------------------------------------------------
1967 
1968 #define ENTER4( rMapModeSource, rMapModeDest )                          \
1969     ImplMapRes aMapResSource;                                           \
1970     ImplMapRes aMapResDest;                                             \
1971                                                                         \
1972     ImplCalcMapResolution( rMapModeSource, 72, 72, aMapResSource );     \
1973     ImplCalcMapResolution( rMapModeDest, 72, 72, aMapResDest )
1974 
1975 // -----------------------------------------------------------------------
1976 
1977 // return (n1 * n2 * n3) / (n4 * n5)
1978 static long fn5( const long n1,
1979                  const long n2,
1980                  const long n3,
1981                  const long n4,
1982                  const long n5 )
1983 {
1984     if ( n1 == 0 || n2 == 0 || n3 == 0 || n4 == 0 || n5 == 0 )
1985         return 0;
1986     if ( LONG_MAX / Abs(n2) < Abs(n3) )
1987     {
1988         // a6 wird "ubersprungen
1989         BigInt a7 = n2;
1990         a7 *= n3;
1991         a7 *= n1;
1992 
1993         if ( LONG_MAX / Abs(n4) < Abs(n5) )
1994         {
1995             BigInt a8 = n4;
1996             a8 *= n5;
1997 
1998             BigInt a9 = a8;
1999             a9 /= 2;
2000             if ( a7.IsNeg() )
2001                 a7 -= a9;
2002             else
2003                 a7 += a9;
2004 
2005             a7 /= a8;
2006         } // of if
2007         else
2008         {
2009             long n8 = n4 * n5;
2010 
2011             if ( a7.IsNeg() )
2012                 a7 -= n8 / 2;
2013             else
2014                 a7 += n8 / 2;
2015 
2016             a7 /= n8;
2017         } // of else
2018         return (long)a7;
2019     } // of if
2020     else
2021     {
2022         long n6 = n2 * n3;
2023 
2024         if ( LONG_MAX / Abs(n1) < Abs(n6) )
2025         {
2026             BigInt a7 = n1;
2027             a7 *= n6;
2028 
2029             if ( LONG_MAX / Abs(n4) < Abs(n5) )
2030             {
2031                 BigInt a8 = n4;
2032                 a8 *= n5;
2033 
2034                 BigInt a9 = a8;
2035                 a9 /= 2;
2036                 if ( a7.IsNeg() )
2037                     a7 -= a9;
2038                 else
2039                     a7 += a9;
2040 
2041                 a7 /= a8;
2042             } // of if
2043             else
2044             {
2045                 long n8 = n4 * n5;
2046 
2047                 if ( a7.IsNeg() )
2048                     a7 -= n8 / 2;
2049                 else
2050                     a7 += n8 / 2;
2051 
2052                 a7 /= n8;
2053             } // of else
2054             return (long)a7;
2055         } // of if
2056         else
2057         {
2058             long n7 = n1 * n6;
2059 
2060             if ( LONG_MAX / Abs(n4) < Abs(n5) )
2061             {
2062                 BigInt a7 = n7;
2063                 BigInt a8 = n4;
2064                 a8 *= n5;
2065 
2066                 BigInt a9 = a8;
2067                 a9 /= 2;
2068                 if ( a7.IsNeg() )
2069                     a7 -= a9;
2070                 else
2071                     a7 += a9;
2072 
2073                 a7 /= a8;
2074                 return (long)a7;
2075             } // of if
2076             else
2077             {
2078                 const long n8 = n4 * n5;
2079                 const long n8_2 = n8 / 2;
2080 
2081                 if( n7 < 0 )
2082                 {
2083                     if( ( n7 - LONG_MIN ) >= n8_2 )
2084                         n7 -= n8_2;
2085                 }
2086                 else if( ( LONG_MAX - n7 ) >= n8_2 )
2087                     n7 += n8_2;
2088 
2089                 return n7 / n8;
2090             } // of else
2091         } // of else
2092     } // of else
2093 }
2094 
2095 // -----------------------------------------------------------------------
2096 
2097 // return (n1 * n2) / n3
2098 static long fn3( const long n1, const long n2, const long n3 )
2099 {
2100     if ( n1 == 0 || n2 == 0 || n3 == 0 )
2101         return 0;
2102     if ( LONG_MAX / Abs(n1) < Abs(n2) )
2103     {
2104         BigInt a4 = n1;
2105         a4 *= n2;
2106 
2107         if ( a4.IsNeg() )
2108             a4 -= n3 / 2;
2109         else
2110             a4 += n3 / 2;
2111 
2112         a4 /= n3;
2113         return (long)a4;
2114     } // of if
2115     else
2116     {
2117         long        n4 = n1 * n2;
2118         const long  n3_2 = n3 / 2;
2119 
2120         if( n4 < 0 )
2121         {
2122             if( ( n4 - LONG_MIN ) >= n3_2 )
2123                 n4 -= n3_2;
2124         }
2125         else if( ( LONG_MAX - n4 ) >= n3_2 )
2126             n4 += n3_2;
2127 
2128         return n4 / n3;
2129     } // of else
2130 }
2131 
2132 // -----------------------------------------------------------------------
2133 
2134 Point OutputDevice::LogicToLogic( const Point& rPtSource,
2135                                   const MapMode* pMapModeSource,
2136                                   const MapMode* pMapModeDest ) const
2137 {
2138     ENTER1( rPtSource, pMapModeSource, pMapModeDest );
2139 
2140     return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
2141                        aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2142                        aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2143                   aMapResDest.mnMapOfsX,
2144                   fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
2145                        aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2146                        aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2147                   aMapResDest.mnMapOfsY );
2148 }
2149 
2150 // -----------------------------------------------------------------------
2151 
2152 Size OutputDevice::LogicToLogic( const Size& rSzSource,
2153                                  const MapMode* pMapModeSource,
2154                                  const MapMode* pMapModeDest ) const
2155 {
2156     ENTER1( rSzSource, pMapModeSource, pMapModeDest );
2157 
2158     return Size( fn5( rSzSource.Width(),
2159                       aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2160                       aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
2161                  fn5( rSzSource.Height(),
2162                       aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2163                       aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
2164 }
2165 
2166 // -----------------------------------------------------------------------
2167 
2168 Rectangle OutputDevice::LogicToLogic( const Rectangle& rRectSource,
2169                                       const MapMode* pMapModeSource,
2170                                       const MapMode* pMapModeDest ) const
2171 {
2172     ENTER1( rRectSource, pMapModeSource, pMapModeDest );
2173 
2174     return Rectangle( fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
2175                            aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2176                            aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2177                       aMapResDest.mnMapOfsX,
2178                       fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
2179                            aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2180                            aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2181                       aMapResDest.mnMapOfsY,
2182                       fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
2183                            aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2184                            aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2185                       aMapResDest.mnMapOfsX,
2186                       fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
2187                            aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2188                            aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2189                       aMapResDest.mnMapOfsY );
2190 }
2191 
2192 // -----------------------------------------------------------------------
2193 
2194 long* OutputDevice::LogicToLogic( long* pX, sal_uInt16 nCount,
2195                                   const MapMode* pMapModeSource,
2196                                   const MapMode* pMapModeDest ) const
2197 {
2198     ENTER1( pX, pMapModeSource, pMapModeDest );
2199 
2200     for( ; nCount; nCount--, pX++ )
2201     {
2202         *pX = fn5( *pX,
2203                    aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2204                    aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX );
2205     }
2206 
2207     return NULL;
2208 }
2209 
2210 // -----------------------------------------------------------------------
2211 
2212 Point OutputDevice::LogicToLogic( const Point& rPtSource,
2213                                   const MapMode& rMapModeSource,
2214                                   const MapMode& rMapModeDest )
2215 {
2216     if ( rMapModeSource == rMapModeDest )
2217         return rPtSource;
2218 
2219     MapUnit eUnitSource = rMapModeSource.GetMapUnit();
2220     MapUnit eUnitDest   = rMapModeDest.GetMapUnit();
2221     ENTER2( eUnitSource, eUnitDest );
2222 
2223     if ( rMapModeSource.mpImplMapMode->mbSimple &&
2224          rMapModeDest.mpImplMapMode->mbSimple )
2225     {
2226         ENTER3( eUnitSource, eUnitDest );
2227 
2228         return Point( fn3( rPtSource.X(), nNumerator, nDenominator ),
2229                       fn3( rPtSource.Y(), nNumerator, nDenominator ) );
2230     }
2231     else
2232     {
2233         ENTER4( rMapModeSource, rMapModeDest );
2234 
2235         return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
2236                            aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2237                            aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2238                       aMapResDest.mnMapOfsX,
2239                       fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
2240                            aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2241                            aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2242                       aMapResDest.mnMapOfsY );
2243     }
2244 }
2245 
2246 // -----------------------------------------------------------------------
2247 
2248 Size OutputDevice::LogicToLogic( const Size& rSzSource,
2249                                  const MapMode& rMapModeSource,
2250                                  const MapMode& rMapModeDest )
2251 {
2252     if ( rMapModeSource == rMapModeDest )
2253         return rSzSource;
2254 
2255     MapUnit eUnitSource = rMapModeSource.GetMapUnit();
2256     MapUnit eUnitDest   = rMapModeDest.GetMapUnit();
2257     ENTER2( eUnitSource, eUnitDest );
2258 
2259     if ( rMapModeSource.mpImplMapMode->mbSimple &&
2260          rMapModeDest.mpImplMapMode->mbSimple )
2261     {
2262         ENTER3( eUnitSource, eUnitDest );
2263 
2264         return Size( fn3( rSzSource.Width(),  nNumerator, nDenominator ),
2265                      fn3( rSzSource.Height(), nNumerator, nDenominator ) );
2266     }
2267     else
2268     {
2269         ENTER4( rMapModeSource, rMapModeDest );
2270 
2271         return Size( fn5( rSzSource.Width(),
2272                           aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2273                           aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
2274                      fn5( rSzSource.Height(),
2275                           aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2276                           aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
2277     }
2278 }
2279 
2280 // -----------------------------------------------------------------------
2281 
2282 basegfx::B2DPolygon OutputDevice::LogicToLogic( const basegfx::B2DPolygon& rPolySource,
2283                                                 const MapMode& rMapModeSource,
2284                                                 const MapMode& rMapModeDest )
2285 {
2286     if ( rMapModeSource == rMapModeDest )
2287         return rPolySource;
2288 
2289     MapUnit eUnitSource = rMapModeSource.GetMapUnit();
2290     MapUnit eUnitDest   = rMapModeDest.GetMapUnit();
2291     ENTER2( eUnitSource, eUnitDest );
2292 
2293     basegfx::B2DHomMatrix aTransform;
2294 
2295     if ( rMapModeSource.mpImplMapMode->mbSimple &&
2296          rMapModeDest.mpImplMapMode->mbSimple )
2297     {
2298         ENTER3( eUnitSource, eUnitDest );
2299 
2300         const double fScaleFactor((double)nNumerator / (double)nDenominator);
2301         aTransform.set(0, 0, fScaleFactor);
2302         aTransform.set(1, 1, fScaleFactor);
2303     }
2304     else
2305     {
2306         ENTER4( rMapModeSource, rMapModeDest );
2307 
2308         const double fScaleFactorX(  (double(aMapResSource.mnMapScNumX) *  double(aMapResDest.mnMapScDenomX))
2309                                    / (double(aMapResSource.mnMapScDenomX) * double(aMapResDest.mnMapScNumX)) );
2310         const double fScaleFactorY(  (double(aMapResSource.mnMapScNumY) *  double(aMapResDest.mnMapScDenomY))
2311                                    / (double(aMapResSource.mnMapScDenomY) * double(aMapResDest.mnMapScNumY)) );
2312         const double fZeroPointX(double(aMapResSource.mnMapOfsX) * fScaleFactorX - double(aMapResDest.mnMapOfsX));
2313         const double fZeroPointY(double(aMapResSource.mnMapOfsY) * fScaleFactorY - double(aMapResDest.mnMapOfsY));
2314 
2315         aTransform.set(0, 0, fScaleFactorX);
2316         aTransform.set(1, 1, fScaleFactorY);
2317         aTransform.set(0, 2, fZeroPointX);
2318         aTransform.set(1, 2, fZeroPointY);
2319     }
2320     basegfx::B2DPolygon aPoly( rPolySource );
2321     aPoly.transform( aTransform );
2322     return aPoly;
2323 }
2324 
2325 // -----------------------------------------------------------------------
2326 
2327 basegfx::B2DPolyPolygon OutputDevice::LogicToLogic( const basegfx::B2DPolyPolygon& rPolySource,
2328                                                     const MapMode& rMapModeSource,
2329                                                     const MapMode& rMapModeDest )
2330 {
2331     if ( rMapModeSource == rMapModeDest )
2332         return rPolySource;
2333 
2334     MapUnit eUnitSource = rMapModeSource.GetMapUnit();
2335     MapUnit eUnitDest   = rMapModeDest.GetMapUnit();
2336     ENTER2( eUnitSource, eUnitDest );
2337 
2338     basegfx::B2DHomMatrix aTransform;
2339 
2340     if ( rMapModeSource.mpImplMapMode->mbSimple &&
2341          rMapModeDest.mpImplMapMode->mbSimple )
2342     {
2343         ENTER3( eUnitSource, eUnitDest );
2344 
2345         const double fScaleFactor((double)nNumerator / (double)nDenominator);
2346         aTransform.set(0, 0, fScaleFactor);
2347         aTransform.set(1, 1, fScaleFactor);
2348     }
2349     else
2350     {
2351         ENTER4( rMapModeSource, rMapModeDest );
2352 
2353         const double fScaleFactorX(  (double(aMapResSource.mnMapScNumX) *  double(aMapResDest.mnMapScDenomX))
2354                                    / (double(aMapResSource.mnMapScDenomX) * double(aMapResDest.mnMapScNumX)) );
2355         const double fScaleFactorY(  (double(aMapResSource.mnMapScNumY) *  double(aMapResDest.mnMapScDenomY))
2356                                    / (double(aMapResSource.mnMapScDenomY) * double(aMapResDest.mnMapScNumY)) );
2357         const double fZeroPointX(double(aMapResSource.mnMapOfsX) * fScaleFactorX - double(aMapResDest.mnMapOfsX));
2358         const double fZeroPointY(double(aMapResSource.mnMapOfsY) * fScaleFactorY - double(aMapResDest.mnMapOfsY));
2359 
2360         aTransform.set(0, 0, fScaleFactorX);
2361         aTransform.set(1, 1, fScaleFactorY);
2362         aTransform.set(0, 2, fZeroPointX);
2363         aTransform.set(1, 2, fZeroPointY);
2364     }
2365     basegfx::B2DPolyPolygon aPoly( rPolySource );
2366     aPoly.transform( aTransform );
2367     return aPoly;
2368 }
2369 
2370 // -----------------------------------------------------------------------
2371 
2372 Rectangle OutputDevice::LogicToLogic( const Rectangle& rRectSource,
2373                                       const MapMode& rMapModeSource,
2374                                       const MapMode& rMapModeDest )
2375 {
2376     if ( rMapModeSource == rMapModeDest )
2377         return rRectSource;
2378 
2379     MapUnit eUnitSource = rMapModeSource.GetMapUnit();
2380     MapUnit eUnitDest   = rMapModeDest.GetMapUnit();
2381     ENTER2( eUnitSource, eUnitDest );
2382 
2383     if ( rMapModeSource.mpImplMapMode->mbSimple &&
2384          rMapModeDest.mpImplMapMode->mbSimple )
2385     {
2386         ENTER3( eUnitSource, eUnitDest );
2387 
2388         return Rectangle( fn3( rRectSource.Left(), nNumerator, nDenominator ),
2389                           fn3( rRectSource.Top(), nNumerator, nDenominator ),
2390                           fn3( rRectSource.Right(), nNumerator, nDenominator ),
2391                           fn3( rRectSource.Bottom(), nNumerator, nDenominator ) );
2392     }
2393     else
2394     {
2395         ENTER4( rMapModeSource, rMapModeDest );
2396 
2397         return Rectangle( fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
2398                                aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2399                                aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2400                           aMapResDest.mnMapOfsX,
2401                           fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
2402                                aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2403                                aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2404                           aMapResDest.mnMapOfsY,
2405                           fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
2406                                aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2407                                aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2408                           aMapResDest.mnMapOfsX,
2409                           fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
2410                                aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2411                                aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2412                           aMapResDest.mnMapOfsY );
2413     }
2414 }
2415 
2416 // -----------------------------------------------------------------------
2417 
2418 long OutputDevice::LogicToLogic( long nLongSource,
2419                                  MapUnit eUnitSource, MapUnit eUnitDest )
2420 {
2421     if ( eUnitSource == eUnitDest )
2422         return nLongSource;
2423 
2424     ENTER2( eUnitSource, eUnitDest );
2425     ENTER3( eUnitSource, eUnitDest );
2426 
2427     return fn3( nLongSource, nNumerator, nDenominator );
2428 }
2429 
2430 // -----------------------------------------------------------------------
2431 
2432 void OutputDevice::SetPixelOffset( const Size& rOffset )
2433 {
2434     mnOutOffOrigX  = rOffset.Width();
2435     mnOutOffOrigY  = rOffset.Height();
2436 
2437     mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
2438                                        maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
2439                                        maThresRes.mnThresPixToLogX );
2440     mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
2441                                        maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
2442                                        maThresRes.mnThresPixToLogY );
2443 
2444     if( mpAlphaVDev )
2445         mpAlphaVDev->SetPixelOffset( rOffset );
2446 }
2447 
2448 // -----------------------------------------------------------------------
2449 
2450 Size OutputDevice::GetPixelOffset() const
2451 {
2452     return Size(mnOutOffOrigX, mnOutOffOrigY);
2453 }
2454 
2455 // -----------------------------------------------------------------------
2456 
2457 long Window::ImplLogicUnitToPixelX( long nX, MapUnit eUnit )
2458 {
2459     if ( eUnit != MAP_PIXEL )
2460     {
2461         ImplFrameData* pFrameData = mpWindowImpl->mpFrameData;
2462 
2463         // Map-Einheit verschieden, dann neu berechnen
2464         if ( pFrameData->meMapUnit != eUnit )
2465         {
2466             pFrameData->meMapUnit = eUnit;
2467             ImplCalcMapResolution( MapMode( eUnit ), mnDPIX, mnDPIY,
2468                                    pFrameData->maMapUnitRes );
2469         }
2470 
2471         // Es wird kein BigInt gebraucht, da diese Funktion nur zur Umrechnung
2472         // von Fensterposition benutzt wird
2473         nX  = nX * mnDPIX * pFrameData->maMapUnitRes.mnMapScNumX;
2474         nX += nX >= 0 ?  (pFrameData->maMapUnitRes.mnMapScDenomX/2) :
2475                         -((pFrameData->maMapUnitRes.mnMapScDenomX-1)/2);
2476         nX /= pFrameData->maMapUnitRes.mnMapScDenomX;
2477     }
2478 
2479     return nX;
2480 }
2481 
2482 // -----------------------------------------------------------------------
2483 
2484 long Window::ImplLogicUnitToPixelY( long nY, MapUnit eUnit )
2485 {
2486     if ( eUnit != MAP_PIXEL )
2487     {
2488         ImplFrameData* pFrameData = mpWindowImpl->mpFrameData;
2489 
2490         // Map-Einheit verschieden, dann neu berechnen
2491         if ( pFrameData->meMapUnit != eUnit )
2492         {
2493             pFrameData->meMapUnit = eUnit;
2494             ImplCalcMapResolution( MapMode( eUnit ), mnDPIX, mnDPIY,
2495                                    pFrameData->maMapUnitRes );
2496         }
2497 
2498         // Es wird kein BigInt gebraucht, da diese Funktion nur zur Umrechnung
2499         // von Fensterposition benutzt wird
2500         nY  = nY * mnDPIY * pFrameData->maMapUnitRes.mnMapScNumY;
2501         nY += nY >= 0 ?  (pFrameData->maMapUnitRes.mnMapScDenomY/2) :
2502                         -((pFrameData->maMapUnitRes.mnMapScDenomY-1)/2);
2503         nY /= pFrameData->maMapUnitRes.mnMapScDenomY;
2504     }
2505 
2506     return nY;
2507 }
2508