xref: /AOO41X/main/vcl/source/gdi/outmap.cxx (revision 5443dcac4da55ae8863c5c80e8907938642a7f1b)
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 <window.h>
44 #include <outdev.h>
45 #include <salgdi.hxx>
46 
47 #include <basegfx/matrix/b2dhommatrix.hxx>
48 #include <basegfx/polygon/b2dpolygon.hxx>
49 #include <basegfx/polygon/b2dpolypolygon.hxx>
50 
51 #define USE_64BIT_INTS
52 
53 // =======================================================================
54 
55 DBG_NAMEEX( OutputDevice )
56 DBG_NAMEEX( Polygon )
57 DBG_NAMEEX( PolyPolygon )
58 DBG_NAMEEX( Region )
59 
60 // =======================================================================
61 
62 static int const s_ImplArySize = MAP_PIXEL+1;
63 static long aImplNumeratorAry[s_ImplArySize] =
64     {    1,   1,   5,  50,    1,   1,  1, 1,  1,    1, 1 };
65 static long aImplDenominatorAry[s_ImplArySize] =
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     if ( !mnOutOffX && !mnOutOffY )
801         return rRegion;
802 
803     Region aRegion( rRegion );
804     aRegion.Move( mnOutOffX+mnOutOffOrigX, mnOutOffY+mnOutOffOrigY );
805     return aRegion;
806 }
807 
808 // -----------------------------------------------------------------------
809 
810 void OutputDevice::EnableMapMode( sal_Bool bEnable )
811 {
812     mbMap = (bEnable != 0);
813 
814     if( mpAlphaVDev )
815         mpAlphaVDev->EnableMapMode( bEnable );
816 }
817 
818 // -----------------------------------------------------------------------
819 
820 void OutputDevice::SetMapMode()
821 {
822     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
823 
824     if ( mpMetaFile )
825         mpMetaFile->AddAction( new MetaMapModeAction( MapMode() ) );
826 
827     if ( mbMap || !maMapMode.IsDefault() )
828     {
829         mbMap       = sal_False;
830         maMapMode   = MapMode();
831 
832         // create new objects (clip region werden nicht neu skaliert)
833         mbNewFont   = sal_True;
834         mbInitFont  = sal_True;
835         if ( GetOutDevType() == OUTDEV_WINDOW )
836         {
837             if ( ((Window*)this)->mpWindowImpl->mpCursor )
838                 ((Window*)this)->mpWindowImpl->mpCursor->ImplNew();
839         }
840 
841         // #106426# Adapt logical offset when changing mapmode
842         mnOutOffLogicX = mnOutOffOrigX; // no mapping -> equal offsets
843         mnOutOffLogicY = mnOutOffOrigY;
844 
845         // #i75163#
846         ImplInvalidateViewTransform();
847     }
848 
849     if( mpAlphaVDev )
850         mpAlphaVDev->SetMapMode();
851 }
852 
853 // -----------------------------------------------------------------------
854 
855 void OutputDevice::SetMapMode( const MapMode& rNewMapMode )
856 {
857     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
858 
859     sal_Bool bRelMap = (rNewMapMode.GetMapUnit() == MAP_RELATIVE);
860 
861     if ( mpMetaFile )
862     {
863         mpMetaFile->AddAction( new MetaMapModeAction( rNewMapMode ) );
864 #ifdef DBG_UTIL
865         if ( GetOutDevType() != OUTDEV_PRINTER )
866             DBG_ASSERTWARNING( bRelMap, "Please record only relative MapModes!" );
867 #endif
868     }
869 
870     // Ist der MapMode der gleiche wie vorher, dann mache nichts
871     if ( maMapMode == rNewMapMode )
872         return;
873 
874     if( mpAlphaVDev )
875         mpAlphaVDev->SetMapMode( rNewMapMode );
876 
877     // Ist Default-MapMode, dann bereche nichts
878     bool bOldMap = mbMap;
879     mbMap = !rNewMapMode.IsDefault();
880     if ( mbMap )
881     {
882         // Falls nur der Orign umgesetzt wird, dann scaliere nichts neu
883         if ( (rNewMapMode.GetMapUnit() == maMapMode.GetMapUnit()) &&
884              (rNewMapMode.GetScaleX()  == maMapMode.GetScaleX())  &&
885              (rNewMapMode.GetScaleY()  == maMapMode.GetScaleY())  &&
886              (bOldMap                  == mbMap) )
887         {
888             // Offset setzen
889             Point aOrigin = rNewMapMode.GetOrigin();
890             maMapRes.mnMapOfsX = aOrigin.X();
891             maMapRes.mnMapOfsY = aOrigin.Y();
892             maMapMode = rNewMapMode;
893 
894             // #i75163#
895             ImplInvalidateViewTransform();
896 
897             return;
898         }
899         if ( !bOldMap && bRelMap )
900         {
901             maMapRes.mnMapScNumX    = 1;
902             maMapRes.mnMapScNumY    = 1;
903             maMapRes.mnMapScDenomX  = mnDPIX;
904             maMapRes.mnMapScDenomY  = mnDPIY;
905             maMapRes.mnMapOfsX      = 0;
906             maMapRes.mnMapOfsY      = 0;
907         }
908 
909         // Neue MapMode-Aufloesung berechnen
910         ImplCalcMapResolution( rNewMapMode, mnDPIX, mnDPIY, maMapRes, maThresRes );
911     }
912 
913     // Neuen MapMode setzen
914     if ( bRelMap )
915     {
916         Point aOrigin( maMapRes.mnMapOfsX, maMapRes.mnMapOfsY );
917         // aScale? = maMapMode.GetScale?() * rNewMapMode.GetScale?()
918         Fraction aScaleX = ImplMakeFraction( maMapMode.GetScaleX().GetNumerator(),
919                                              rNewMapMode.GetScaleX().GetNumerator(),
920                                              maMapMode.GetScaleX().GetDenominator(),
921                                              rNewMapMode.GetScaleX().GetDenominator() );
922         Fraction aScaleY = ImplMakeFraction( maMapMode.GetScaleY().GetNumerator(),
923                                              rNewMapMode.GetScaleY().GetNumerator(),
924                                              maMapMode.GetScaleY().GetDenominator(),
925                                              rNewMapMode.GetScaleY().GetDenominator() );
926         maMapMode.SetOrigin( aOrigin );
927         maMapMode.SetScaleX( aScaleX );
928         maMapMode.SetScaleY( aScaleY );
929     }
930     else
931         maMapMode = rNewMapMode;
932 
933     // create new objects (clip region werden nicht neu skaliert)
934     mbNewFont   = sal_True;
935     mbInitFont  = sal_True;
936     if ( GetOutDevType() == OUTDEV_WINDOW )
937     {
938         if ( ((Window*)this)->mpWindowImpl->mpCursor )
939             ((Window*)this)->mpWindowImpl->mpCursor->ImplNew();
940     }
941 
942     // #106426# Adapt logical offset when changing mapmode
943     mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
944                                        maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
945                                        maThresRes.mnThresPixToLogX );
946     mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
947                                        maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
948                                        maThresRes.mnThresPixToLogY );
949 
950     // #i75163#
951     ImplInvalidateViewTransform();
952 }
953 
954 // -----------------------------------------------------------------------
955 
956 void OutputDevice::SetRelativeMapMode( const MapMode& rNewMapMode )
957 {
958     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
959 
960     // Ist der MapMode der gleiche wie vorher, dann mache nichts
961     if ( maMapMode == rNewMapMode )
962         return;
963 
964     MapUnit eOld = maMapMode.GetMapUnit();
965     MapUnit eNew = rNewMapMode.GetMapUnit();
966 
967     // a?F = rNewMapMode.GetScale?() / maMapMode.GetScale?()
968     Fraction aXF = ImplMakeFraction( rNewMapMode.GetScaleX().GetNumerator(),
969                                      maMapMode.GetScaleX().GetDenominator(),
970                                      rNewMapMode.GetScaleX().GetDenominator(),
971                                      maMapMode.GetScaleX().GetNumerator() );
972     Fraction aYF = ImplMakeFraction( rNewMapMode.GetScaleY().GetNumerator(),
973                                      maMapMode.GetScaleY().GetDenominator(),
974                                      rNewMapMode.GetScaleY().GetDenominator(),
975                                      maMapMode.GetScaleY().GetNumerator() );
976 
977     Point aPt( LogicToLogic( Point(), NULL, &rNewMapMode ) );
978     if ( eNew != eOld )
979     {
980         if ( eOld > MAP_PIXEL )
981         {
982             DBG_ERRORFILE( "Not implemented MapUnit" );
983         }
984         else if ( eNew > MAP_PIXEL )
985         {
986             DBG_ERRORFILE( "Not implemented MapUnit" );
987         }
988         else
989         {
990             Fraction aF( aImplNumeratorAry[eNew] * aImplDenominatorAry[eOld],
991                          aImplNumeratorAry[eOld] * aImplDenominatorAry[eNew] );
992 
993             // a?F =  a?F * aF
994             aXF = ImplMakeFraction( aXF.GetNumerator(),   aF.GetNumerator(),
995                                     aXF.GetDenominator(), aF.GetDenominator() );
996             aYF = ImplMakeFraction( aYF.GetNumerator(),   aF.GetNumerator(),
997                                     aYF.GetDenominator(), aF.GetDenominator() );
998             if ( eOld == MAP_PIXEL )
999             {
1000                 aXF *= Fraction( mnDPIX, 1 );
1001                 aYF *= Fraction( mnDPIY, 1 );
1002             }
1003             else if ( eNew == MAP_PIXEL )
1004             {
1005                 aXF *= Fraction( 1, mnDPIX );
1006                 aYF *= Fraction( 1, mnDPIY );
1007             }
1008         }
1009     }
1010 
1011     MapMode aNewMapMode( MAP_RELATIVE, Point( -aPt.X(), -aPt.Y() ), aXF, aYF );
1012     SetMapMode( aNewMapMode );
1013 
1014     if ( eNew != eOld )
1015         maMapMode = rNewMapMode;
1016 
1017     // #106426# Adapt logical offset when changing mapmode
1018     mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
1019                                        maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1020                                        maThresRes.mnThresPixToLogX );
1021     mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
1022                                        maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1023                                        maThresRes.mnThresPixToLogY );
1024 
1025     if( mpAlphaVDev )
1026         mpAlphaVDev->SetRelativeMapMode( rNewMapMode );
1027 }
1028 
1029 // -----------------------------------------------------------------------
1030 
1031 // #i75163#
1032 basegfx::B2DHomMatrix OutputDevice::GetViewTransformation() const
1033 {
1034     if(mbMap)
1035     {
1036         // #i82615#
1037         if(!mpOutDevData)
1038         {
1039             const_cast< OutputDevice* >(this)->ImplInitOutDevData();
1040         }
1041 
1042         if(!mpOutDevData->mpViewTransform)
1043         {
1044             mpOutDevData->mpViewTransform = new basegfx::B2DHomMatrix;
1045 
1046             const double fScaleFactorX((double)mnDPIX * (double)maMapRes.mnMapScNumX / (double)maMapRes.mnMapScDenomX);
1047             const double fScaleFactorY((double)mnDPIY * (double)maMapRes.mnMapScNumY / (double)maMapRes.mnMapScDenomY);
1048             const double fZeroPointX(((double)maMapRes.mnMapOfsX * fScaleFactorX) + (double)mnOutOffOrigX);
1049             const double fZeroPointY(((double)maMapRes.mnMapOfsY * fScaleFactorY) + (double)mnOutOffOrigY);
1050 
1051             mpOutDevData->mpViewTransform->set(0, 0, fScaleFactorX);
1052             mpOutDevData->mpViewTransform->set(1, 1, fScaleFactorY);
1053             mpOutDevData->mpViewTransform->set(0, 2, fZeroPointX);
1054             mpOutDevData->mpViewTransform->set(1, 2, fZeroPointY);
1055         }
1056 
1057         return *mpOutDevData->mpViewTransform;
1058     }
1059     else
1060     {
1061         return basegfx::B2DHomMatrix();
1062     }
1063 }
1064 
1065 // -----------------------------------------------------------------------
1066 
1067 // #i75163#
1068 basegfx::B2DHomMatrix OutputDevice::GetInverseViewTransformation() const
1069 {
1070     if(mbMap)
1071     {
1072         // #i82615#
1073         if(!mpOutDevData)
1074         {
1075             const_cast< OutputDevice* >(this)->ImplInitOutDevData();
1076         }
1077 
1078         if(!mpOutDevData->mpInverseViewTransform)
1079         {
1080             GetViewTransformation();
1081             mpOutDevData->mpInverseViewTransform = new basegfx::B2DHomMatrix(*mpOutDevData->mpViewTransform);
1082             mpOutDevData->mpInverseViewTransform->invert();
1083         }
1084 
1085         return *mpOutDevData->mpInverseViewTransform;
1086     }
1087     else
1088     {
1089         return basegfx::B2DHomMatrix();
1090     }
1091 }
1092 
1093 // -----------------------------------------------------------------------
1094 
1095 // #i75163#
1096 basegfx::B2DHomMatrix OutputDevice::GetViewTransformation( const MapMode& rMapMode ) const
1097 {
1098     // #i82615#
1099     ImplMapRes          aMapRes;
1100     ImplThresholdRes    aThresRes;
1101     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1102 
1103     basegfx::B2DHomMatrix aTransform;
1104 
1105     const double fScaleFactorX((double)mnDPIX * (double)aMapRes.mnMapScNumX / (double)aMapRes.mnMapScDenomX);
1106     const double fScaleFactorY((double)mnDPIY * (double)aMapRes.mnMapScNumY / (double)aMapRes.mnMapScDenomY);
1107     const double fZeroPointX(((double)aMapRes.mnMapOfsX * fScaleFactorX) + (double)mnOutOffOrigX);
1108     const double fZeroPointY(((double)aMapRes.mnMapOfsY * fScaleFactorY) + (double)mnOutOffOrigY);
1109 
1110     aTransform.set(0, 0, fScaleFactorX);
1111     aTransform.set(1, 1, fScaleFactorY);
1112     aTransform.set(0, 2, fZeroPointX);
1113     aTransform.set(1, 2, fZeroPointY);
1114 
1115     return aTransform;
1116 }
1117 
1118 // -----------------------------------------------------------------------
1119 
1120 // #i75163#
1121 basegfx::B2DHomMatrix OutputDevice::GetInverseViewTransformation( const MapMode& rMapMode ) const
1122 {
1123     basegfx::B2DHomMatrix aMatrix( GetViewTransformation( rMapMode ) );
1124     aMatrix.invert();
1125     return aMatrix;
1126 }
1127 
1128 // -----------------------------------------------------------------------
1129 
1130 basegfx::B2DHomMatrix OutputDevice::ImplGetDeviceTransformation() const
1131 {
1132     basegfx::B2DHomMatrix aTransformation = GetViewTransformation();
1133     // TODO: is it worth to cache the transformed result?
1134     if( mnOutOffX || mnOutOffY )
1135         aTransformation.translate( mnOutOffX, mnOutOffY );
1136     return aTransformation;
1137 }
1138 
1139 // -----------------------------------------------------------------------
1140 
1141 Point OutputDevice::LogicToPixel( const Point& rLogicPt ) const
1142 {
1143     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1144 
1145     if ( !mbMap )
1146         return rLogicPt;
1147 
1148     return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
1149                                     maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1150                                     maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1151                   ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
1152                                     maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1153                                     maThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1154 }
1155 
1156 // -----------------------------------------------------------------------
1157 
1158 Size OutputDevice::LogicToPixel( const Size& rLogicSize ) const
1159 {
1160     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1161 
1162     if ( !mbMap )
1163         return rLogicSize;
1164 
1165     return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
1166                                    maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1167                                    maThresRes.mnThresLogToPixX ),
1168                  ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
1169                                    maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1170                                    maThresRes.mnThresLogToPixY ) );
1171 }
1172 
1173 // -----------------------------------------------------------------------
1174 
1175 Rectangle OutputDevice::LogicToPixel( const Rectangle& rLogicRect ) const
1176 {
1177     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1178 
1179     if ( !mbMap || rLogicRect.IsEmpty() )
1180         return rLogicRect;
1181 
1182     return Rectangle( ImplLogicToPixel( rLogicRect.Left() + maMapRes.mnMapOfsX, mnDPIX,
1183                                         maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1184                                         maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1185                       ImplLogicToPixel( rLogicRect.Top() + maMapRes.mnMapOfsY, mnDPIY,
1186                                         maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1187                                         maThresRes.mnThresLogToPixY )+mnOutOffOrigY,
1188                       ImplLogicToPixel( rLogicRect.Right() + maMapRes.mnMapOfsX, mnDPIX,
1189                                         maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1190                                         maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1191                       ImplLogicToPixel( rLogicRect.Bottom() + maMapRes.mnMapOfsY, mnDPIY,
1192                                         maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1193                                         maThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1194 }
1195 
1196 // -----------------------------------------------------------------------
1197 
1198 Polygon OutputDevice::LogicToPixel( const Polygon& rLogicPoly ) const
1199 {
1200     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1201     DBG_CHKOBJ( &rLogicPoly, Polygon, NULL );
1202 
1203     if ( !mbMap )
1204         return rLogicPoly;
1205 
1206     sal_uInt16  i;
1207     sal_uInt16  nPoints = rLogicPoly.GetSize();
1208     Polygon aPoly( rLogicPoly );
1209 
1210     // Pointer auf das Point-Array holen (Daten werden kopiert)
1211     const Point* pPointAry = aPoly.GetConstPointAry();
1212 
1213     for ( i = 0; i < nPoints; i++ )
1214     {
1215         const Point* pPt = &(pPointAry[i]);
1216         Point aPt;
1217         aPt.X() = ImplLogicToPixel( pPt->X() + maMapRes.mnMapOfsX, mnDPIX,
1218                                     maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1219                                     maThresRes.mnThresLogToPixX )+mnOutOffOrigX;
1220         aPt.Y() = ImplLogicToPixel( pPt->Y() + maMapRes.mnMapOfsY, mnDPIY,
1221                                     maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1222                                     maThresRes.mnThresLogToPixY )+mnOutOffOrigY;
1223         aPoly[i] = aPt;
1224     }
1225 
1226     return aPoly;
1227 }
1228 
1229 // -----------------------------------------------------------------------
1230 
1231 PolyPolygon OutputDevice::LogicToPixel( const PolyPolygon& rLogicPolyPoly ) const
1232 {
1233     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1234     DBG_CHKOBJ( &rLogicPolyPoly, PolyPolygon, NULL );
1235 
1236     if ( !mbMap )
1237         return rLogicPolyPoly;
1238 
1239     PolyPolygon aPolyPoly( rLogicPolyPoly );
1240     sal_uInt16      nPoly = aPolyPoly.Count();
1241     for( sal_uInt16 i = 0; i < nPoly; i++ )
1242     {
1243         Polygon& rPoly = aPolyPoly[i];
1244         rPoly = LogicToPixel( rPoly );
1245     }
1246     return aPolyPoly;
1247 }
1248 
1249 // -----------------------------------------------------------------------
1250 
1251 basegfx::B2DPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolygon& rLogicPoly ) const
1252 {
1253     basegfx::B2DPolygon aTransformedPoly = rLogicPoly;
1254     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation();
1255     aTransformedPoly.transform( rTransformationMatrix );
1256     return aTransformedPoly;
1257 }
1258 
1259 // -----------------------------------------------------------------------
1260 
1261 basegfx::B2DPolyPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly ) const
1262 {
1263     basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly;
1264     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation();
1265     aTransformedPoly.transform( rTransformationMatrix );
1266     return aTransformedPoly;
1267 }
1268 
1269 // -----------------------------------------------------------------------
1270 
1271 Region OutputDevice::LogicToPixel( const Region& rLogicRegion ) const
1272 {
1273     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1274 
1275     if(!mbMap || rLogicRegion.IsNull() || rLogicRegion.IsEmpty())
1276     {
1277         return rLogicRegion;
1278     }
1279 
1280     Region aRegion;
1281 
1282     if(rLogicRegion.getB2DPolyPolygon())
1283     {
1284         aRegion = Region(LogicToPixel(*rLogicRegion.getB2DPolyPolygon()));
1285     }
1286     else if(rLogicRegion.getPolyPolygon())
1287     {
1288         aRegion = Region(LogicToPixel(*rLogicRegion.getPolyPolygon()));
1289     }
1290     else if(rLogicRegion.getRegionBand())
1291     {
1292         RectangleVector aRectangles;
1293         rLogicRegion.GetRegionRectangles(aRectangles);
1294         const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
1295 
1296         // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1297         for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); aRectIter++)
1298         {
1299             aRegion.Union(LogicToPixel(*aRectIter));
1300         }
1301 
1302         //long nX(0);
1303         //long nY(0);
1304         //long nWidth(0);
1305         //long nHeight(0);
1306         //ImplRegionInfo aInfo;
1307         //aRegion.ImplBeginAddRect();
1308         //bool bRegionRect(rLogicRegion.ImplGetFirstRect(aInfo, nX, nY, nWidth, nHeight));
1309         //
1310         //while(bRegionRect)
1311         //{
1312         //  const Rectangle aRect(Point(nX, nY), Size(nWidth, nHeight));
1313         //  aRegion.ImplAddRect(LogicToPixel(aRect));
1314         //  bRegionRect = rLogicRegion.ImplGetNextRect(aInfo, nX, nY, nWidth, nHeight);
1315         //}
1316         //
1317         //aRegion.ImplEndAddRect();
1318     }
1319 
1320     return aRegion;
1321 }
1322 
1323 // -----------------------------------------------------------------------
1324 
1325 Point OutputDevice::LogicToPixel( const Point& rLogicPt,
1326                                   const MapMode& rMapMode ) const
1327 {
1328     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1329 
1330     if ( rMapMode.IsDefault() )
1331         return rLogicPt;
1332 
1333     // MapMode-Aufloesung berechnen und Umrechnen
1334     ImplMapRes          aMapRes;
1335     ImplThresholdRes    aThresRes;
1336     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1337 
1338     return Point( ImplLogicToPixel( rLogicPt.X() + aMapRes.mnMapOfsX, mnDPIX,
1339                                     aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1340                                     aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1341                   ImplLogicToPixel( rLogicPt.Y() + aMapRes.mnMapOfsY, mnDPIY,
1342                                     aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1343                                     aThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1344 }
1345 
1346 // -----------------------------------------------------------------------
1347 
1348 Size OutputDevice::LogicToPixel( const Size& rLogicSize,
1349                                  const MapMode& rMapMode ) const
1350 {
1351     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1352 
1353     if ( rMapMode.IsDefault() )
1354         return rLogicSize;
1355 
1356     // MapMode-Aufloesung berechnen und Umrechnen
1357     ImplMapRes          aMapRes;
1358     ImplThresholdRes    aThresRes;
1359     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1360 
1361     return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
1362                                    aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1363                                    aThresRes.mnThresLogToPixX ),
1364                  ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
1365                                    aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1366                                    aThresRes.mnThresLogToPixY ) );
1367 }
1368 
1369 // -----------------------------------------------------------------------
1370 
1371 Rectangle OutputDevice::LogicToPixel( const Rectangle& rLogicRect,
1372                                       const MapMode& rMapMode ) const
1373 {
1374     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1375 
1376     if ( rMapMode.IsDefault() || rLogicRect.IsEmpty() )
1377         return rLogicRect;
1378 
1379     // MapMode-Aufloesung berechnen und Umrechnen
1380     ImplMapRes          aMapRes;
1381     ImplThresholdRes    aThresRes;
1382     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1383 
1384     return Rectangle( ImplLogicToPixel( rLogicRect.Left() + aMapRes.mnMapOfsX, mnDPIX,
1385                                         aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1386                                         aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1387                       ImplLogicToPixel( rLogicRect.Top() + aMapRes.mnMapOfsY, mnDPIY,
1388                                         aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1389                                         aThresRes.mnThresLogToPixY )+mnOutOffOrigY,
1390                       ImplLogicToPixel( rLogicRect.Right() + aMapRes.mnMapOfsX, mnDPIX,
1391                                         aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1392                                         aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1393                       ImplLogicToPixel( rLogicRect.Bottom() + aMapRes.mnMapOfsY, mnDPIY,
1394                                         aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1395                                         aThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1396 }
1397 
1398 // -----------------------------------------------------------------------
1399 
1400 Polygon OutputDevice::LogicToPixel( const Polygon& rLogicPoly,
1401                                     const MapMode& rMapMode ) const
1402 {
1403     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1404     DBG_CHKOBJ( &rLogicPoly, Polygon, NULL );
1405 
1406     if ( rMapMode.IsDefault() )
1407         return rLogicPoly;
1408 
1409     // MapMode-Aufloesung berechnen und Umrechnen
1410     ImplMapRes          aMapRes;
1411     ImplThresholdRes    aThresRes;
1412     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1413 
1414     sal_uInt16  i;
1415     sal_uInt16  nPoints = rLogicPoly.GetSize();
1416     Polygon aPoly( rLogicPoly );
1417 
1418     // Pointer auf das Point-Array holen (Daten werden kopiert)
1419     const Point* pPointAry = aPoly.GetConstPointAry();
1420 
1421     for ( i = 0; i < nPoints; i++ )
1422     {
1423         const Point* pPt = &(pPointAry[i]);
1424         Point aPt;
1425         aPt.X() = ImplLogicToPixel( pPt->X() + aMapRes.mnMapOfsX, mnDPIX,
1426                                     aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1427                                     aThresRes.mnThresLogToPixX )+mnOutOffOrigX;
1428         aPt.Y() = ImplLogicToPixel( pPt->Y() + aMapRes.mnMapOfsY, mnDPIY,
1429                                     aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1430                                     aThresRes.mnThresLogToPixY )+mnOutOffOrigY;
1431         aPoly[i] = aPt;
1432     }
1433 
1434     return aPoly;
1435 }
1436 
1437 // -----------------------------------------------------------------------
1438 
1439 PolyPolygon OutputDevice::LogicToPixel( const PolyPolygon& rLogicPolyPoly,
1440                                         const MapMode& rMapMode ) const
1441 {
1442     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1443     DBG_CHKOBJ( &rLogicPolyPoly, PolyPolygon, NULL );
1444 
1445     if ( rMapMode.IsDefault() )
1446         return rLogicPolyPoly;
1447 
1448     PolyPolygon aPolyPoly( rLogicPolyPoly );
1449     sal_uInt16      nPoly = aPolyPoly.Count();
1450     for( sal_uInt16 i = 0; i < nPoly; i++ )
1451     {
1452         Polygon& rPoly = aPolyPoly[i];
1453         rPoly = LogicToPixel( rPoly, rMapMode );
1454     }
1455     return aPolyPoly;
1456 }
1457 
1458 // -----------------------------------------------------------------------
1459 
1460 basegfx::B2DPolyPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly,
1461                                                     const MapMode& rMapMode ) const
1462 {
1463     basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly;
1464     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation( rMapMode );
1465     aTransformedPoly.transform( rTransformationMatrix );
1466     return aTransformedPoly;
1467 }
1468 
1469 // -----------------------------------------------------------------------
1470 
1471 basegfx::B2DPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolygon& rLogicPoly,
1472                                                 const MapMode& rMapMode ) const
1473 {
1474     basegfx::B2DPolygon aTransformedPoly = rLogicPoly;
1475     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation( rMapMode );
1476     aTransformedPoly.transform( rTransformationMatrix );
1477     return aTransformedPoly;
1478 }
1479 
1480 // -----------------------------------------------------------------------
1481 
1482 Region OutputDevice::LogicToPixel( const Region& rLogicRegion, const MapMode& rMapMode ) const
1483 {
1484     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1485 
1486     if(rMapMode.IsDefault() || rLogicRegion.IsNull() || rLogicRegion.IsEmpty())
1487     {
1488         return rLogicRegion;
1489     }
1490 
1491     Region aRegion;
1492 
1493     if(rLogicRegion.getB2DPolyPolygon())
1494     {
1495         aRegion = Region(LogicToPixel(*rLogicRegion.getB2DPolyPolygon(), rMapMode));
1496     }
1497     else if(rLogicRegion.getPolyPolygon())
1498     {
1499         aRegion = Region(LogicToPixel(*rLogicRegion.getPolyPolygon(), rMapMode));
1500     }
1501     else if(rLogicRegion.getRegionBand())
1502     {
1503         RectangleVector aRectangles;
1504         rLogicRegion.GetRegionRectangles(aRectangles);
1505         const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
1506 
1507         // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1508         for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); aRectIter++)
1509         {
1510             aRegion.Union(LogicToPixel(*aRectIter, rMapMode));
1511         }
1512 
1513         //long nX(0);
1514         //long nY(0);
1515         //long nWidth(0);
1516         //long nHeight(0);
1517         //ImplRegionInfo aInfo;
1518         //aRegion.ImplBeginAddRect();
1519         //bool bRegionRect(rLogicRegion.ImplGetFirstRect(aInfo, nX, nY, nWidth, nHeight));
1520         //
1521         //while(bRegionRect)
1522         //{
1523         //  const Rectangle aRect(Point(nX, nY), Size(nWidth, nHeight));
1524         //  aRegion.ImplAddRect(LogicToPixel(aRect, rMapMode));
1525         //  bRegionRect = rLogicRegion.ImplGetNextRect(aInfo, nX, nY, nWidth, nHeight);
1526         //}
1527         //
1528         //aRegion.ImplEndAddRect();
1529     }
1530 
1531     return aRegion;
1532 }
1533 
1534 // -----------------------------------------------------------------------
1535 
1536 Point OutputDevice::PixelToLogic( const Point& rDevicePt ) const
1537 {
1538     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1539 
1540     if ( !mbMap )
1541         return rDevicePt;
1542 
1543     return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1544                                     maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1545                                     maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1546                   ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1547                                     maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1548                                     maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY );
1549 }
1550 
1551 // -----------------------------------------------------------------------
1552 
1553 Size OutputDevice::PixelToLogic( const Size& rDeviceSize ) const
1554 {
1555     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1556 
1557     if ( !mbMap )
1558         return rDeviceSize;
1559 
1560     return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1561                                    maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1562                                    maThresRes.mnThresPixToLogX ),
1563                  ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1564                                    maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1565                                    maThresRes.mnThresPixToLogY ) );
1566 }
1567 
1568 // -----------------------------------------------------------------------
1569 
1570 Rectangle OutputDevice::PixelToLogic( const Rectangle& rDeviceRect ) const
1571 {
1572     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1573 
1574     if ( !mbMap || rDeviceRect.IsEmpty() )
1575         return rDeviceRect;
1576 
1577     return Rectangle( ImplPixelToLogic( rDeviceRect.Left(), mnDPIX,
1578                                         maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1579                                         maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1580                       ImplPixelToLogic( rDeviceRect.Top(), mnDPIY,
1581                                         maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1582                                         maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY,
1583                       ImplPixelToLogic( rDeviceRect.Right(), mnDPIX,
1584                                         maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1585                                         maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1586                       ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY,
1587                                         maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1588                                         maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY );
1589 }
1590 
1591 // -----------------------------------------------------------------------
1592 
1593 Polygon OutputDevice::PixelToLogic( const Polygon& rDevicePoly ) const
1594 {
1595     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1596     DBG_CHKOBJ( &rDevicePoly, Polygon, NULL );
1597 
1598     if ( !mbMap )
1599         return rDevicePoly;
1600 
1601     sal_uInt16  i;
1602     sal_uInt16  nPoints = rDevicePoly.GetSize();
1603     Polygon aPoly( rDevicePoly );
1604 
1605     // Pointer auf das Point-Array holen (Daten werden kopiert)
1606     const Point* pPointAry = aPoly.GetConstPointAry();
1607 
1608     for ( i = 0; i < nPoints; i++ )
1609     {
1610         const Point* pPt = &(pPointAry[i]);
1611         Point aPt;
1612         aPt.X() = ImplPixelToLogic( pPt->X(), mnDPIX,
1613                                     maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1614                                     maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX;
1615         aPt.Y() = ImplPixelToLogic( pPt->Y(), mnDPIY,
1616                                     maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1617                                     maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY;
1618         aPoly[i] = aPt;
1619     }
1620 
1621     return aPoly;
1622 }
1623 
1624 // -----------------------------------------------------------------------
1625 
1626 PolyPolygon OutputDevice::PixelToLogic( const PolyPolygon& rDevicePolyPoly ) const
1627 {
1628     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1629     DBG_CHKOBJ( &rDevicePolyPoly, PolyPolygon, NULL );
1630 
1631     if ( !mbMap )
1632         return rDevicePolyPoly;
1633 
1634     PolyPolygon aPolyPoly( rDevicePolyPoly );
1635     sal_uInt16      nPoly = aPolyPoly.Count();
1636     for( sal_uInt16 i = 0; i < nPoly; i++ )
1637     {
1638         Polygon& rPoly = aPolyPoly[i];
1639         rPoly = PixelToLogic( rPoly );
1640     }
1641     return aPolyPoly;
1642 }
1643 
1644 // -----------------------------------------------------------------------
1645 
1646 basegfx::B2DPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolygon& rPixelPoly ) const
1647 {
1648     basegfx::B2DPolygon aTransformedPoly = rPixelPoly;
1649     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation();
1650     aTransformedPoly.transform( rTransformationMatrix );
1651     return aTransformedPoly;
1652 }
1653 
1654 // -----------------------------------------------------------------------
1655 
1656 basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygon& rPixelPolyPoly ) const
1657 {
1658     basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly;
1659     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation();
1660     aTransformedPoly.transform( rTransformationMatrix );
1661     return aTransformedPoly;
1662 }
1663 
1664 // -----------------------------------------------------------------------
1665 
1666 Region OutputDevice::PixelToLogic( const Region& rDeviceRegion ) const
1667 {
1668     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1669 
1670     if(!mbMap || rDeviceRegion.IsNull() || rDeviceRegion.IsEmpty())
1671     {
1672         return rDeviceRegion;
1673     }
1674 
1675     Region aRegion;
1676 
1677     if(rDeviceRegion.getB2DPolyPolygon())
1678     {
1679         aRegion = Region(PixelToLogic(*rDeviceRegion.getB2DPolyPolygon()));
1680     }
1681     else if(rDeviceRegion.getPolyPolygon())
1682     {
1683         aRegion = Region(PixelToLogic(*rDeviceRegion.getPolyPolygon()));
1684     }
1685     else if(rDeviceRegion.getRegionBand())
1686     {
1687         RectangleVector aRectangles;
1688         rDeviceRegion.GetRegionRectangles(aRectangles);
1689         const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
1690 
1691         // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1692         for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); aRectIter++)
1693         {
1694             aRegion.Union(PixelToLogic(*aRectIter));
1695         }
1696 
1697         //long nX(0);
1698         //long nY(0);
1699         //long nWidth(0);
1700         //long nHeight(0);
1701         //ImplRegionInfo aInfo;
1702         //aRegion.ImplBeginAddRect();
1703         //bool bRegionRect(rDeviceRegion.ImplGetFirstRect(aInfo, nX, nY, nWidth, nHeight));
1704         //
1705         //while(bRegionRect)
1706         //{
1707         //  const Rectangle aRect(Point(nX, nY), Size(nWidth, nHeight));
1708         //  aRegion.ImplAddRect(PixelToLogic(aRect));
1709         //  bRegionRect = rDeviceRegion.ImplGetNextRect(aInfo, nX, nY, nWidth, nHeight);
1710         //}
1711         //
1712         //aRegion.ImplEndAddRect();
1713     }
1714 
1715     return aRegion;
1716 }
1717 
1718 // -----------------------------------------------------------------------
1719 
1720 Point OutputDevice::PixelToLogic( const Point& rDevicePt,
1721                                   const MapMode& rMapMode ) const
1722 {
1723     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1724 
1725     // Ist Default-MapMode, dann bereche nichts
1726     if ( rMapMode.IsDefault() )
1727         return rDevicePt;
1728 
1729     // MapMode-Aufloesung berechnen und Umrechnen
1730     ImplMapRes          aMapRes;
1731     ImplThresholdRes    aThresRes;
1732     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1733 
1734     return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1735                                     aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1736                                     aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1737                   ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1738                                     aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1739                                     aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1740 }
1741 
1742 // -----------------------------------------------------------------------
1743 
1744 Size OutputDevice::PixelToLogic( const Size& rDeviceSize,
1745                                  const MapMode& rMapMode ) const
1746 {
1747     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1748 
1749     // Ist Default-MapMode, dann bereche nichts
1750     if ( rMapMode.IsDefault() )
1751         return rDeviceSize;
1752 
1753     // MapMode-Aufloesung berechnen und Umrechnen
1754     ImplMapRes          aMapRes;
1755     ImplThresholdRes    aThresRes;
1756     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1757 
1758     return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1759                                    aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1760                                    aThresRes.mnThresPixToLogX ),
1761                  ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1762                                    aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1763                                    aThresRes.mnThresPixToLogY ) );
1764 }
1765 
1766 // -----------------------------------------------------------------------
1767 
1768 Rectangle OutputDevice::PixelToLogic( const Rectangle& rDeviceRect,
1769                                       const MapMode& rMapMode ) const
1770 {
1771     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1772 
1773     // Ist Default-MapMode, dann bereche nichts
1774     if ( rMapMode.IsDefault() || rDeviceRect.IsEmpty() )
1775         return rDeviceRect;
1776 
1777     // MapMode-Aufloesung berechnen und Umrechnen
1778     ImplMapRes          aMapRes;
1779     ImplThresholdRes    aThresRes;
1780     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1781 
1782     return Rectangle( ImplPixelToLogic( rDeviceRect.Left(), mnDPIX,
1783                                         aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1784                                         aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1785                       ImplPixelToLogic( rDeviceRect.Top(), mnDPIY,
1786                                         aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1787                                         aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY,
1788                       ImplPixelToLogic( rDeviceRect.Right(), mnDPIX,
1789                                         aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1790                                         aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1791                       ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY,
1792                                         aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1793                                         aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1794 }
1795 
1796 // -----------------------------------------------------------------------
1797 
1798 Polygon OutputDevice::PixelToLogic( const Polygon& rDevicePoly,
1799                                     const MapMode& rMapMode ) const
1800 {
1801     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1802     DBG_CHKOBJ( &rDevicePoly, Polygon, NULL );
1803 
1804     // Ist Default-MapMode, dann bereche nichts
1805     if ( rMapMode.IsDefault() )
1806         return rDevicePoly;
1807 
1808     // MapMode-Aufloesung berechnen und Umrechnen
1809     ImplMapRes          aMapRes;
1810     ImplThresholdRes    aThresRes;
1811     ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1812 
1813     sal_uInt16  i;
1814     sal_uInt16  nPoints = rDevicePoly.GetSize();
1815     Polygon aPoly( rDevicePoly );
1816 
1817     // Pointer auf das Point-Array holen (Daten werden kopiert)
1818     const Point* pPointAry = aPoly.GetConstPointAry();
1819 
1820     for ( i = 0; i < nPoints; i++ )
1821     {
1822         const Point* pPt = &(pPointAry[i]);
1823         Point aPt;
1824         aPt.X() = ImplPixelToLogic( pPt->X(), mnDPIX,
1825                                     aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1826                                     aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX;
1827         aPt.Y() = ImplPixelToLogic( pPt->Y(), mnDPIY,
1828                                     aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1829                                     aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY;
1830         aPoly[i] = aPt;
1831     }
1832 
1833     return aPoly;
1834 }
1835 
1836 // -----------------------------------------------------------------------
1837 
1838 PolyPolygon OutputDevice::PixelToLogic( const PolyPolygon& rDevicePolyPoly,
1839                                         const MapMode& rMapMode ) const
1840 {
1841     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1842     DBG_CHKOBJ( &rDevicePolyPoly, PolyPolygon, NULL );
1843 
1844     if ( rMapMode.IsDefault() )
1845         return rDevicePolyPoly;
1846 
1847     PolyPolygon aPolyPoly( rDevicePolyPoly );
1848     sal_uInt16      nPoly = aPolyPoly.Count();
1849     for( sal_uInt16 i = 0; i < nPoly; i++ )
1850     {
1851         Polygon& rPoly = aPolyPoly[i];
1852         rPoly = PixelToLogic( rPoly, rMapMode );
1853     }
1854     return aPolyPoly;
1855 }
1856 
1857 // -----------------------------------------------------------------------
1858 
1859 basegfx::B2DPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolygon& rPixelPoly,
1860                                                 const MapMode& rMapMode ) const
1861 {
1862     basegfx::B2DPolygon aTransformedPoly = rPixelPoly;
1863     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation( rMapMode );
1864     aTransformedPoly.transform( rTransformationMatrix );
1865     return aTransformedPoly;
1866 }
1867 
1868 // -----------------------------------------------------------------------
1869 
1870 basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygon& rPixelPolyPoly,
1871                                                     const MapMode& rMapMode ) const
1872 {
1873     basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly;
1874     const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation( rMapMode );
1875     aTransformedPoly.transform( rTransformationMatrix );
1876     return aTransformedPoly;
1877 }
1878 
1879 // -----------------------------------------------------------------------
1880 
1881 Region OutputDevice::PixelToLogic( const Region& rDeviceRegion, const MapMode& rMapMode ) const
1882 {
1883     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1884 
1885     if(rMapMode.IsDefault() || rDeviceRegion.IsNull() || rDeviceRegion.IsEmpty())
1886     {
1887         return rDeviceRegion;
1888     }
1889 
1890     Region aRegion;
1891 
1892     if(rDeviceRegion.getB2DPolyPolygon())
1893     {
1894         aRegion = Region(PixelToLogic(*rDeviceRegion.getB2DPolyPolygon(), rMapMode));
1895     }
1896     else if(rDeviceRegion.getPolyPolygon())
1897     {
1898         aRegion = Region(PixelToLogic(*rDeviceRegion.getPolyPolygon(), rMapMode));
1899     }
1900     else if(rDeviceRegion.getRegionBand())
1901     {
1902         RectangleVector aRectangles;
1903         rDeviceRegion.GetRegionRectangles(aRectangles);
1904         const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
1905 
1906         // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1907         for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); aRectIter++)
1908         {
1909             aRegion.Union(PixelToLogic(*aRectIter, rMapMode));
1910         }
1911 
1912         //long nX(0);
1913         //long nY(0);
1914         //long nWidth(0);
1915         //long nHeight(0);
1916         //ImplRegionInfo aInfo;
1917         //aRegion.ImplBeginAddRect();
1918         //bool bRegionRect(rDeviceRegion.ImplGetFirstRect(aInfo, nX, nY, nWidth, nHeight));
1919         //
1920         //while(bRegionRect)
1921         //{
1922         //  const Rectangle aRect(Point(nX, nY), Size(nWidth, nHeight));
1923         //  aRegion.ImplAddRect(PixelToLogic(aRect, rMapMode));
1924         //  bRegionRect = rDeviceRegion.ImplGetNextRect(aInfo, nX, nY, nWidth, nHeight);
1925         //}
1926         //
1927         //aRegion.ImplEndAddRect();
1928     }
1929 
1930     return aRegion;
1931 }
1932 
1933 // -----------------------------------------------------------------------
1934 
1935 #define ENTER0( rSource, pMapModeSource, pMapModeDest )                 \
1936     if ( !pMapModeSource )                                              \
1937         pMapModeSource = &maMapMode;                                    \
1938     if ( !pMapModeDest )                                                \
1939         pMapModeDest = &maMapMode;                                      \
1940     if ( *pMapModeSource == *pMapModeDest )                             \
1941         return rSource
1942 
1943 // -----------------------------------------------------------------------
1944 
1945 #define ENTER1( rSource, pMapModeSource, pMapModeDest )                 \
1946     ENTER0( rSource, pMapModeSource, pMapModeDest );                    \
1947                                                                         \
1948     ImplMapRes aMapResSource;                                           \
1949     ImplMapRes aMapResDest;                                             \
1950                                                                         \
1951     if ( !mbMap || pMapModeSource != &maMapMode )                       \
1952     {                                                                   \
1953         if ( pMapModeSource->GetMapUnit() == MAP_RELATIVE )             \
1954             aMapResSource = maMapRes;                                   \
1955         ImplCalcMapResolution( *pMapModeSource,                         \
1956                                mnDPIX, mnDPIY, aMapResSource );         \
1957     }                                                                   \
1958     else                                                                \
1959         aMapResSource = maMapRes;                                       \
1960     if ( !mbMap || pMapModeDest != &maMapMode )                         \
1961     {                                                                   \
1962         if ( pMapModeDest->GetMapUnit() == MAP_RELATIVE )               \
1963             aMapResDest = maMapRes;                                     \
1964         ImplCalcMapResolution( *pMapModeDest,                           \
1965                                mnDPIX, mnDPIY, aMapResDest );           \
1966     }                                                                   \
1967     else                                                                \
1968         aMapResDest = maMapRes
1969 
1970 // -----------------------------------------------------------------------
1971 
1972 #define ENTER2( eUnitSource, eUnitDest )                                \
1973     DBG_ASSERT( eUnitSource != MAP_SYSFONT                              \
1974                 && eUnitSource != MAP_APPFONT                           \
1975                 && eUnitSource != MAP_RELATIVE,                         \
1976                 "Source MapUnit nicht erlaubt" );                       \
1977     DBG_ASSERT( eUnitDest != MAP_SYSFONT                                \
1978                 && eUnitDest != MAP_APPFONT                             \
1979                 && eUnitDest != MAP_RELATIVE,                           \
1980                 "Destination MapUnit nicht erlaubt" );                  \
1981     DBG_ASSERTWARNING( eUnitSource != MAP_PIXEL,                        \
1982                        "MAP_PIXEL mit 72dpi angenaehert" );             \
1983     DBG_ASSERTWARNING( eUnitDest != MAP_PIXEL,                          \
1984                        "MAP_PIXEL mit 72dpi angenaehert" )
1985 
1986 // -----------------------------------------------------------------------
1987 
1988 #define ENTER3( eUnitSource, eUnitDest )                                \
1989     long nNumerator      = 1;       \
1990     long nDenominator    = 1;       \
1991     DBG_ASSERT( eUnitSource < s_ImplArySize, "Invalid source map unit");    \
1992     DBG_ASSERT( eUnitDest < s_ImplArySize, "Invalid destination map unit"); \
1993     if( (eUnitSource < s_ImplArySize) && (eUnitDest < s_ImplArySize) )  \
1994     {   \
1995         nNumerator   = aImplNumeratorAry[eUnitSource] *             \
1996                            aImplDenominatorAry[eUnitDest];              \
1997         nDenominator     = aImplNumeratorAry[eUnitDest] *               \
1998                            aImplDenominatorAry[eUnitSource];            \
1999     } \
2000     if ( eUnitSource == MAP_PIXEL )                                     \
2001         nDenominator *= 72;                                             \
2002     else if( eUnitDest == MAP_PIXEL )                                   \
2003         nNumerator *= 72
2004 
2005 // -----------------------------------------------------------------------
2006 
2007 #define ENTER4( rMapModeSource, rMapModeDest )                          \
2008     ImplMapRes aMapResSource;                                           \
2009     ImplMapRes aMapResDest;                                             \
2010                                                                         \
2011     ImplCalcMapResolution( rMapModeSource, 72, 72, aMapResSource );     \
2012     ImplCalcMapResolution( rMapModeDest, 72, 72, aMapResDest )
2013 
2014 // -----------------------------------------------------------------------
2015 
2016 // return (n1 * n2 * n3) / (n4 * n5)
2017 static long fn5( const long n1,
2018                  const long n2,
2019                  const long n3,
2020                  const long n4,
2021                  const long n5 )
2022 {
2023     if ( n1 == 0 || n2 == 0 || n3 == 0 || n4 == 0 || n5 == 0 )
2024         return 0;
2025     if ( LONG_MAX / Abs(n2) < Abs(n3) )
2026     {
2027         // a6 wird "ubersprungen
2028         BigInt a7 = n2;
2029         a7 *= n3;
2030         a7 *= n1;
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 n6 = n2 * n3;
2062 
2063         if ( LONG_MAX / Abs(n1) < Abs(n6) )
2064         {
2065             BigInt a7 = n1;
2066             a7 *= n6;
2067 
2068             if ( LONG_MAX / Abs(n4) < Abs(n5) )
2069             {
2070                 BigInt a8 = n4;
2071                 a8 *= n5;
2072 
2073                 BigInt a9 = a8;
2074                 a9 /= 2;
2075                 if ( a7.IsNeg() )
2076                     a7 -= a9;
2077                 else
2078                     a7 += a9;
2079 
2080                 a7 /= a8;
2081             } // of if
2082             else
2083             {
2084                 long n8 = n4 * n5;
2085 
2086                 if ( a7.IsNeg() )
2087                     a7 -= n8 / 2;
2088                 else
2089                     a7 += n8 / 2;
2090 
2091                 a7 /= n8;
2092             } // of else
2093             return (long)a7;
2094         } // of if
2095         else
2096         {
2097             long n7 = n1 * n6;
2098 
2099             if ( LONG_MAX / Abs(n4) < Abs(n5) )
2100             {
2101                 BigInt a7 = n7;
2102                 BigInt a8 = n4;
2103                 a8 *= n5;
2104 
2105                 BigInt a9 = a8;
2106                 a9 /= 2;
2107                 if ( a7.IsNeg() )
2108                     a7 -= a9;
2109                 else
2110                     a7 += a9;
2111 
2112                 a7 /= a8;
2113                 return (long)a7;
2114             } // of if
2115             else
2116             {
2117                 const long n8 = n4 * n5;
2118                 const long n8_2 = n8 / 2;
2119 
2120                 if( n7 < 0 )
2121                 {
2122                     if( ( n7 - LONG_MIN ) >= n8_2 )
2123                         n7 -= n8_2;
2124                 }
2125                 else if( ( LONG_MAX - n7 ) >= n8_2 )
2126                     n7 += n8_2;
2127 
2128                 return n7 / n8;
2129             } // of else
2130         } // of else
2131     } // of else
2132 }
2133 
2134 // -----------------------------------------------------------------------
2135 
2136 // return (n1 * n2) / n3
2137 static long fn3( const long n1, const long n2, const long n3 )
2138 {
2139     if ( n1 == 0 || n2 == 0 || n3 == 0 )
2140         return 0;
2141     if ( LONG_MAX / Abs(n1) < Abs(n2) )
2142     {
2143         BigInt a4 = n1;
2144         a4 *= n2;
2145 
2146         if ( a4.IsNeg() )
2147             a4 -= n3 / 2;
2148         else
2149             a4 += n3 / 2;
2150 
2151         a4 /= n3;
2152         return (long)a4;
2153     } // of if
2154     else
2155     {
2156         long        n4 = n1 * n2;
2157         const long  n3_2 = n3 / 2;
2158 
2159         if( n4 < 0 )
2160         {
2161             if( ( n4 - LONG_MIN ) >= n3_2 )
2162                 n4 -= n3_2;
2163         }
2164         else if( ( LONG_MAX - n4 ) >= n3_2 )
2165             n4 += n3_2;
2166 
2167         return n4 / n3;
2168     } // of else
2169 }
2170 
2171 // -----------------------------------------------------------------------
2172 
2173 Point OutputDevice::LogicToLogic( const Point& rPtSource,
2174                                   const MapMode* pMapModeSource,
2175                                   const MapMode* pMapModeDest ) const
2176 {
2177     ENTER1( rPtSource, pMapModeSource, pMapModeDest );
2178 
2179     return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
2180                        aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2181                        aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2182                   aMapResDest.mnMapOfsX,
2183                   fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
2184                        aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2185                        aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2186                   aMapResDest.mnMapOfsY );
2187 }
2188 
2189 // -----------------------------------------------------------------------
2190 
2191 Size OutputDevice::LogicToLogic( const Size& rSzSource,
2192                                  const MapMode* pMapModeSource,
2193                                  const MapMode* pMapModeDest ) const
2194 {
2195     ENTER1( rSzSource, pMapModeSource, pMapModeDest );
2196 
2197     return Size( fn5( rSzSource.Width(),
2198                       aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2199                       aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
2200                  fn5( rSzSource.Height(),
2201                       aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2202                       aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
2203 }
2204 
2205 // -----------------------------------------------------------------------
2206 
2207 Rectangle OutputDevice::LogicToLogic( const Rectangle& rRectSource,
2208                                       const MapMode* pMapModeSource,
2209                                       const MapMode* pMapModeDest ) const
2210 {
2211     ENTER1( rRectSource, pMapModeSource, pMapModeDest );
2212 
2213     return Rectangle( fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
2214                            aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2215                            aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2216                       aMapResDest.mnMapOfsX,
2217                       fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
2218                            aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2219                            aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2220                       aMapResDest.mnMapOfsY,
2221                       fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
2222                            aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2223                            aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2224                       aMapResDest.mnMapOfsX,
2225                       fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
2226                            aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2227                            aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2228                       aMapResDest.mnMapOfsY );
2229 }
2230 
2231 // -----------------------------------------------------------------------
2232 
2233 long* OutputDevice::LogicToLogic( long* pX, sal_uInt16 nCount,
2234                                   const MapMode* pMapModeSource,
2235                                   const MapMode* pMapModeDest ) const
2236 {
2237     ENTER1( pX, pMapModeSource, pMapModeDest );
2238 
2239     for( ; nCount; nCount--, pX++ )
2240     {
2241         *pX = fn5( *pX,
2242                    aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2243                    aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX );
2244     }
2245 
2246     return NULL;
2247 }
2248 
2249 // -----------------------------------------------------------------------
2250 
2251 Point OutputDevice::LogicToLogic( const Point& rPtSource,
2252                                   const MapMode& rMapModeSource,
2253                                   const MapMode& rMapModeDest )
2254 {
2255     if ( rMapModeSource == rMapModeDest )
2256         return rPtSource;
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 Point( fn3( rPtSource.X(), nNumerator, nDenominator ),
2268                       fn3( rPtSource.Y(), nNumerator, nDenominator ) );
2269     }
2270     else
2271     {
2272         ENTER4( rMapModeSource, rMapModeDest );
2273 
2274         return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
2275                            aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2276                            aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2277                       aMapResDest.mnMapOfsX,
2278                       fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
2279                            aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2280                            aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2281                       aMapResDest.mnMapOfsY );
2282     }
2283 }
2284 
2285 // -----------------------------------------------------------------------
2286 
2287 Size OutputDevice::LogicToLogic( const Size& rSzSource,
2288                                  const MapMode& rMapModeSource,
2289                                  const MapMode& rMapModeDest )
2290 {
2291     if ( rMapModeSource == rMapModeDest )
2292         return rSzSource;
2293 
2294     MapUnit eUnitSource = rMapModeSource.GetMapUnit();
2295     MapUnit eUnitDest   = rMapModeDest.GetMapUnit();
2296     ENTER2( eUnitSource, eUnitDest );
2297 
2298     if ( rMapModeSource.mpImplMapMode->mbSimple &&
2299          rMapModeDest.mpImplMapMode->mbSimple )
2300     {
2301         ENTER3( eUnitSource, eUnitDest );
2302 
2303         return Size( fn3( rSzSource.Width(),  nNumerator, nDenominator ),
2304                      fn3( rSzSource.Height(), nNumerator, nDenominator ) );
2305     }
2306     else
2307     {
2308         ENTER4( rMapModeSource, rMapModeDest );
2309 
2310         return Size( fn5( rSzSource.Width(),
2311                           aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2312                           aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
2313                      fn5( rSzSource.Height(),
2314                           aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2315                           aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
2316     }
2317 }
2318 
2319 // -----------------------------------------------------------------------
2320 
2321 basegfx::B2DPolygon OutputDevice::LogicToLogic( const basegfx::B2DPolygon& rPolySource,
2322                                                 const MapMode& rMapModeSource,
2323                                                 const MapMode& rMapModeDest )
2324 {
2325     if ( rMapModeSource == rMapModeDest )
2326         return rPolySource;
2327 
2328     MapUnit eUnitSource = rMapModeSource.GetMapUnit();
2329     MapUnit eUnitDest   = rMapModeDest.GetMapUnit();
2330     ENTER2( eUnitSource, eUnitDest );
2331 
2332     basegfx::B2DHomMatrix aTransform;
2333 
2334     if ( rMapModeSource.mpImplMapMode->mbSimple &&
2335          rMapModeDest.mpImplMapMode->mbSimple )
2336     {
2337         ENTER3( eUnitSource, eUnitDest );
2338 
2339         const double fScaleFactor((double)nNumerator / (double)nDenominator);
2340         aTransform.set(0, 0, fScaleFactor);
2341         aTransform.set(1, 1, fScaleFactor);
2342     }
2343     else
2344     {
2345         ENTER4( rMapModeSource, rMapModeDest );
2346 
2347         const double fScaleFactorX(  (double(aMapResSource.mnMapScNumX) *  double(aMapResDest.mnMapScDenomX))
2348                                    / (double(aMapResSource.mnMapScDenomX) * double(aMapResDest.mnMapScNumX)) );
2349         const double fScaleFactorY(  (double(aMapResSource.mnMapScNumY) *  double(aMapResDest.mnMapScDenomY))
2350                                    / (double(aMapResSource.mnMapScDenomY) * double(aMapResDest.mnMapScNumY)) );
2351         const double fZeroPointX(double(aMapResSource.mnMapOfsX) * fScaleFactorX - double(aMapResDest.mnMapOfsX));
2352         const double fZeroPointY(double(aMapResSource.mnMapOfsY) * fScaleFactorY - double(aMapResDest.mnMapOfsY));
2353 
2354         aTransform.set(0, 0, fScaleFactorX);
2355         aTransform.set(1, 1, fScaleFactorY);
2356         aTransform.set(0, 2, fZeroPointX);
2357         aTransform.set(1, 2, fZeroPointY);
2358     }
2359     basegfx::B2DPolygon aPoly( rPolySource );
2360     aPoly.transform( aTransform );
2361     return aPoly;
2362 }
2363 
2364 // -----------------------------------------------------------------------
2365 
2366 basegfx::B2DPolyPolygon OutputDevice::LogicToLogic( const basegfx::B2DPolyPolygon& rPolySource,
2367                                                     const MapMode& rMapModeSource,
2368                                                     const MapMode& rMapModeDest )
2369 {
2370     if ( rMapModeSource == rMapModeDest )
2371         return rPolySource;
2372 
2373     MapUnit eUnitSource = rMapModeSource.GetMapUnit();
2374     MapUnit eUnitDest   = rMapModeDest.GetMapUnit();
2375     ENTER2( eUnitSource, eUnitDest );
2376 
2377     basegfx::B2DHomMatrix aTransform;
2378 
2379     if ( rMapModeSource.mpImplMapMode->mbSimple &&
2380          rMapModeDest.mpImplMapMode->mbSimple )
2381     {
2382         ENTER3( eUnitSource, eUnitDest );
2383 
2384         const double fScaleFactor((double)nNumerator / (double)nDenominator);
2385         aTransform.set(0, 0, fScaleFactor);
2386         aTransform.set(1, 1, fScaleFactor);
2387     }
2388     else
2389     {
2390         ENTER4( rMapModeSource, rMapModeDest );
2391 
2392         const double fScaleFactorX(  (double(aMapResSource.mnMapScNumX) *  double(aMapResDest.mnMapScDenomX))
2393                                    / (double(aMapResSource.mnMapScDenomX) * double(aMapResDest.mnMapScNumX)) );
2394         const double fScaleFactorY(  (double(aMapResSource.mnMapScNumY) *  double(aMapResDest.mnMapScDenomY))
2395                                    / (double(aMapResSource.mnMapScDenomY) * double(aMapResDest.mnMapScNumY)) );
2396         const double fZeroPointX(double(aMapResSource.mnMapOfsX) * fScaleFactorX - double(aMapResDest.mnMapOfsX));
2397         const double fZeroPointY(double(aMapResSource.mnMapOfsY) * fScaleFactorY - double(aMapResDest.mnMapOfsY));
2398 
2399         aTransform.set(0, 0, fScaleFactorX);
2400         aTransform.set(1, 1, fScaleFactorY);
2401         aTransform.set(0, 2, fZeroPointX);
2402         aTransform.set(1, 2, fZeroPointY);
2403     }
2404     basegfx::B2DPolyPolygon aPoly( rPolySource );
2405     aPoly.transform( aTransform );
2406     return aPoly;
2407 }
2408 
2409 // -----------------------------------------------------------------------
2410 
2411 Rectangle OutputDevice::LogicToLogic( const Rectangle& rRectSource,
2412                                       const MapMode& rMapModeSource,
2413                                       const MapMode& rMapModeDest )
2414 {
2415     if ( rMapModeSource == rMapModeDest )
2416         return rRectSource;
2417 
2418     MapUnit eUnitSource = rMapModeSource.GetMapUnit();
2419     MapUnit eUnitDest   = rMapModeDest.GetMapUnit();
2420     ENTER2( eUnitSource, eUnitDest );
2421 
2422     if ( rMapModeSource.mpImplMapMode->mbSimple &&
2423          rMapModeDest.mpImplMapMode->mbSimple )
2424     {
2425         ENTER3( eUnitSource, eUnitDest );
2426 
2427         return Rectangle( fn3( rRectSource.Left(), nNumerator, nDenominator ),
2428                           fn3( rRectSource.Top(), nNumerator, nDenominator ),
2429                           fn3( rRectSource.Right(), nNumerator, nDenominator ),
2430                           fn3( rRectSource.Bottom(), nNumerator, nDenominator ) );
2431     }
2432     else
2433     {
2434         ENTER4( rMapModeSource, rMapModeDest );
2435 
2436         return Rectangle( fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
2437                                aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2438                                aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2439                           aMapResDest.mnMapOfsX,
2440                           fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
2441                                aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2442                                aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2443                           aMapResDest.mnMapOfsY,
2444                           fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
2445                                aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2446                                aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2447                           aMapResDest.mnMapOfsX,
2448                           fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
2449                                aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2450                                aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2451                           aMapResDest.mnMapOfsY );
2452     }
2453 }
2454 
2455 // -----------------------------------------------------------------------
2456 
2457 long OutputDevice::LogicToLogic( long nLongSource,
2458                                  MapUnit eUnitSource, MapUnit eUnitDest )
2459 {
2460     if ( eUnitSource == eUnitDest )
2461         return nLongSource;
2462 
2463     ENTER2( eUnitSource, eUnitDest );
2464     ENTER3( eUnitSource, eUnitDest );
2465 
2466     return fn3( nLongSource, nNumerator, nDenominator );
2467 }
2468 
2469 // -----------------------------------------------------------------------
2470 
2471 void OutputDevice::SetPixelOffset( const Size& rOffset )
2472 {
2473     mnOutOffOrigX  = rOffset.Width();
2474     mnOutOffOrigY  = rOffset.Height();
2475 
2476     mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
2477                                        maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
2478                                        maThresRes.mnThresPixToLogX );
2479     mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
2480                                        maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
2481                                        maThresRes.mnThresPixToLogY );
2482 
2483     if( mpAlphaVDev )
2484         mpAlphaVDev->SetPixelOffset( rOffset );
2485 }
2486 
2487 // -----------------------------------------------------------------------
2488 
2489 Size OutputDevice::GetPixelOffset() const
2490 {
2491     return Size(mnOutOffOrigX, mnOutOffOrigY);
2492 }
2493 
2494 // -----------------------------------------------------------------------
2495 
2496 long Window::ImplLogicUnitToPixelX( long nX, MapUnit eUnit )
2497 {
2498     if ( eUnit != MAP_PIXEL )
2499     {
2500         ImplFrameData* pFrameData = mpWindowImpl->mpFrameData;
2501 
2502         // Map-Einheit verschieden, dann neu berechnen
2503         if ( pFrameData->meMapUnit != eUnit )
2504         {
2505             pFrameData->meMapUnit = eUnit;
2506             ImplCalcMapResolution( MapMode( eUnit ), mnDPIX, mnDPIY,
2507                                    pFrameData->maMapUnitRes );
2508         }
2509 
2510         // Es wird kein BigInt gebraucht, da diese Funktion nur zur Umrechnung
2511         // von Fensterposition benutzt wird
2512         nX  = nX * mnDPIX * pFrameData->maMapUnitRes.mnMapScNumX;
2513         nX += nX >= 0 ?  (pFrameData->maMapUnitRes.mnMapScDenomX/2) :
2514                         -((pFrameData->maMapUnitRes.mnMapScDenomX-1)/2);
2515         nX /= pFrameData->maMapUnitRes.mnMapScDenomX;
2516     }
2517 
2518     return nX;
2519 }
2520 
2521 // -----------------------------------------------------------------------
2522 
2523 long Window::ImplLogicUnitToPixelY( long nY, MapUnit eUnit )
2524 {
2525     if ( eUnit != MAP_PIXEL )
2526     {
2527         ImplFrameData* pFrameData = mpWindowImpl->mpFrameData;
2528 
2529         // Map-Einheit verschieden, dann neu berechnen
2530         if ( pFrameData->meMapUnit != eUnit )
2531         {
2532             pFrameData->meMapUnit = eUnit;
2533             ImplCalcMapResolution( MapMode( eUnit ), mnDPIX, mnDPIY,
2534                                    pFrameData->maMapUnitRes );
2535         }
2536 
2537         // Es wird kein BigInt gebraucht, da diese Funktion nur zur Umrechnung
2538         // von Fensterposition benutzt wird
2539         nY  = nY * mnDPIY * pFrameData->maMapUnitRes.mnMapScNumY;
2540         nY += nY >= 0 ?  (pFrameData->maMapUnitRes.mnMapScDenomY/2) :
2541                         -((pFrameData->maMapUnitRes.mnMapScDenomY-1)/2);
2542         nY /= pFrameData->maMapUnitRes.mnMapScDenomY;
2543     }
2544 
2545     return nY;
2546 }
2547