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