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