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