merge the formfield patch from ooo-build
[ooovba.git] / vcl / source / gdi / outmap.cxx
blob3a3d8fec31317cbb640653793f3365a5342de8a5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: outmap.cxx,v $
10 * $Revision: 1.29 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #include <limits.h>
36 #ifndef _SV_SVSYS_HXX
37 #include <svsys.h>
38 #endif
39 #include <tools/bigint.hxx>
40 #include <tools/debug.hxx>
41 #include <vcl/virdev.hxx>
42 #include <vcl/svdata.hxx>
43 #include <tools/poly.hxx>
44 #include <vcl/region.hxx>
45 #include <vcl/region.h>
46 #include <vcl/window.h>
47 #include <vcl/wrkwin.hxx>
48 #include <vcl/cursor.hxx>
49 #include <vcl/metaact.hxx>
50 #include <vcl/gdimtf.hxx>
51 #include <vcl/lineinfo.hxx>
52 #include <vcl/outdev.hxx>
53 #include <vcl/outdev.h>
54 #include <vcl/salgdi.hxx>
55 #include <basegfx/matrix/b2dhommatrix.hxx>
56 #include <basegfx/polygon/b2dpolypolygon.hxx>
58 #define USE_64BIT_INTS
60 // =======================================================================
62 DBG_NAMEEX( OutputDevice )
63 DBG_NAMEEX( Polygon )
64 DBG_NAMEEX( PolyPolygon )
65 DBG_NAMEEX( Region )
67 // =======================================================================
69 static long aImplNumeratorAry[MAP_PIXEL+1] =
70 { 1, 1, 5, 50, 1, 1, 1, 1, 1, 1, 1 };
71 static long aImplDenominatorAry[MAP_PIXEL+1] =
72 { 2540, 254, 127, 127, 1000, 100, 10, 1, 72, 1440, 1 };
74 // -----------------------------------------------------------------------
77 Reduziert die Genauigkeit bis eine Fraction draus wird (sollte mal
78 ein Fraction ctor werden) koennte man dann auch mit BigInts machen
81 static Fraction ImplMakeFraction( long nN1, long nN2, long nD1, long nD2 )
83 long i = 1;
85 if ( nN1 < 0 ) { i = -i; nN1 = -nN1; }
86 if ( nN2 < 0 ) { i = -i; nN2 = -nN2; }
87 if ( nD1 < 0 ) { i = -i; nD1 = -nD1; }
88 if ( nD2 < 0 ) { i = -i; nD2 = -nD2; }
89 // alle positiv; i Vorzeichen
91 Fraction aF( i*nN1, nD1 );
92 aF *= Fraction( nN2, nD2 );
94 if( nD1 == 0 || nD2 == 0 ) //under these bad circumstances the following while loop will be endless
96 DBG_ASSERT(false,"Invalid parameter for ImplMakeFraction");
97 return Fraction( 1, 1 );
100 while ( aF.GetDenominator() == -1 )
102 if ( nN1 > nN2 )
103 nN1 = (nN1 + 1) / 2;
104 else
105 nN2 = (nN2 + 1) / 2;
106 if ( nD1 > nD2 )
107 nD1 = (nD1 + 1) / 2;
108 else
109 nD2 = (nD2 + 1) / 2;
111 aF = Fraction( i*nN1, nD1 );
112 aF *= Fraction( nN2, nD2 );
115 return aF;
118 // -----------------------------------------------------------------------
120 // Fraction.GetNumerator()
121 // Fraction.GetDenominator() > 0
122 // rOutRes.nPixPerInch? > 0
123 // rMapRes.nMapScNum?
124 // rMapRes.nMapScDenom? > 0
126 static void ImplCalcBigIntThreshold( long nDPIX, long nDPIY,
127 const ImplMapRes& rMapRes,
128 ImplThresholdRes& rThresRes )
130 if ( nDPIX && (LONG_MAX / nDPIX < Abs( rMapRes.mnMapScNumX ) ) ) // #111139# avoid div by zero
132 rThresRes.mnThresLogToPixX = 0;
133 rThresRes.mnThresPixToLogX = 0;
135 else
137 // Schwellenwerte fuer BigInt Arithmetik berechnen
138 long nDenomHalfX = rMapRes.mnMapScDenomX / 2;
139 ULONG nDenomX = rMapRes.mnMapScDenomX;
140 long nProductX = nDPIX * rMapRes.mnMapScNumX;
142 if ( !nProductX )
143 rThresRes.mnThresLogToPixX = LONG_MAX;
144 else
145 rThresRes.mnThresLogToPixX = Abs( (LONG_MAX - nDenomHalfX) / nProductX );
147 if ( !nDenomX )
148 rThresRes.mnThresPixToLogX = LONG_MAX;
149 else if ( nProductX >= 0 )
150 rThresRes.mnThresPixToLogX = (long)(((ULONG)LONG_MAX - (ULONG)( nProductX/2)) / nDenomX);
151 else
152 rThresRes.mnThresPixToLogX = (long)(((ULONG)LONG_MAX + (ULONG)(-nProductX/2)) / nDenomX);
155 if ( nDPIY && (LONG_MAX / nDPIY < Abs( rMapRes.mnMapScNumY ) ) ) // #111139# avoid div by zero
157 rThresRes.mnThresLogToPixY = 0;
158 rThresRes.mnThresPixToLogY = 0;
160 else
162 // Schwellenwerte fuer BigInt Arithmetik berechnen
163 long nDenomHalfY = rMapRes.mnMapScDenomY / 2;
164 ULONG nDenomY = rMapRes.mnMapScDenomY;
165 long nProductY = nDPIY * rMapRes.mnMapScNumY;
167 if ( !nProductY )
168 rThresRes.mnThresLogToPixY = LONG_MAX;
169 else
170 rThresRes.mnThresLogToPixY = Abs( (LONG_MAX - nDenomHalfY) / nProductY );
172 if ( !nDenomY )
173 rThresRes.mnThresPixToLogY = LONG_MAX;
174 else if ( nProductY >= 0 )
175 rThresRes.mnThresPixToLogY = (long)(((ULONG)LONG_MAX - (ULONG)( nProductY/2)) / nDenomY);
176 else
177 rThresRes.mnThresPixToLogY = (long)(((ULONG)LONG_MAX + (ULONG)(-nProductY/2)) / nDenomY);
180 #ifdef USE_64BIT_INTS
181 rThresRes.mnThresLogToPixX /= 2;
182 rThresRes.mnThresLogToPixY /= 2;
183 rThresRes.mnThresPixToLogX /= 2;
184 rThresRes.mnThresPixToLogY /= 2;
185 #endif
188 // -----------------------------------------------------------------------
190 static void ImplCalcMapResolution( const MapMode& rMapMode,
191 long nDPIX, long nDPIY, ImplMapRes& rMapRes )
193 switch ( rMapMode.GetMapUnit() )
195 case MAP_RELATIVE:
196 break;
197 case MAP_100TH_MM:
198 rMapRes.mnMapScNumX = 1;
199 rMapRes.mnMapScDenomX = 2540;
200 rMapRes.mnMapScNumY = 1;
201 rMapRes.mnMapScDenomY = 2540;
202 break;
203 case MAP_10TH_MM:
204 rMapRes.mnMapScNumX = 1;
205 rMapRes.mnMapScDenomX = 254;
206 rMapRes.mnMapScNumY = 1;
207 rMapRes.mnMapScDenomY = 254;
208 break;
209 case MAP_MM:
210 rMapRes.mnMapScNumX = 5; // 10
211 rMapRes.mnMapScDenomX = 127; // 254
212 rMapRes.mnMapScNumY = 5; // 10
213 rMapRes.mnMapScDenomY = 127; // 254
214 break;
215 case MAP_CM:
216 rMapRes.mnMapScNumX = 50; // 100
217 rMapRes.mnMapScDenomX = 127; // 254
218 rMapRes.mnMapScNumY = 50; // 100
219 rMapRes.mnMapScDenomY = 127; // 254
220 break;
221 case MAP_1000TH_INCH:
222 rMapRes.mnMapScNumX = 1;
223 rMapRes.mnMapScDenomX = 1000;
224 rMapRes.mnMapScNumY = 1;
225 rMapRes.mnMapScDenomY = 1000;
226 break;
227 case MAP_100TH_INCH:
228 rMapRes.mnMapScNumX = 1;
229 rMapRes.mnMapScDenomX = 100;
230 rMapRes.mnMapScNumY = 1;
231 rMapRes.mnMapScDenomY = 100;
232 break;
233 case MAP_10TH_INCH:
234 rMapRes.mnMapScNumX = 1;
235 rMapRes.mnMapScDenomX = 10;
236 rMapRes.mnMapScNumY = 1;
237 rMapRes.mnMapScDenomY = 10;
238 break;
239 case MAP_INCH:
240 rMapRes.mnMapScNumX = 1;
241 rMapRes.mnMapScDenomX = 1;
242 rMapRes.mnMapScNumY = 1;
243 rMapRes.mnMapScDenomY = 1;
244 break;
245 case MAP_POINT:
246 rMapRes.mnMapScNumX = 1;
247 rMapRes.mnMapScDenomX = 72;
248 rMapRes.mnMapScNumY = 1;
249 rMapRes.mnMapScDenomY = 72;
250 break;
251 case MAP_TWIP:
252 rMapRes.mnMapScNumX = 1;
253 rMapRes.mnMapScDenomX = 1440;
254 rMapRes.mnMapScNumY = 1;
255 rMapRes.mnMapScDenomY = 1440;
256 break;
257 case MAP_PIXEL:
258 rMapRes.mnMapScNumX = 1;
259 rMapRes.mnMapScDenomX = nDPIX;
260 rMapRes.mnMapScNumY = 1;
261 rMapRes.mnMapScDenomY = nDPIY;
262 break;
263 case MAP_SYSFONT:
264 case MAP_APPFONT:
265 case MAP_REALAPPFONT:
267 ImplSVData* pSVData = ImplGetSVData();
268 if ( !pSVData->maGDIData.mnAppFontX )
270 if( pSVData->maWinData.mpFirstFrame )
271 Window::ImplInitAppFontData( pSVData->maWinData.mpFirstFrame );
272 else
274 WorkWindow* pWin = new WorkWindow( NULL, 0 );
275 Window::ImplInitAppFontData( pWin );
276 delete pWin;
279 if ( rMapMode.GetMapUnit() == MAP_REALAPPFONT )
280 rMapRes.mnMapScNumX = pSVData->maGDIData.mnRealAppFontX;
281 else
282 rMapRes.mnMapScNumX = pSVData->maGDIData.mnAppFontX;
283 rMapRes.mnMapScDenomX = nDPIX * 40;
284 rMapRes.mnMapScNumY = pSVData->maGDIData.mnAppFontY;;
285 rMapRes.mnMapScDenomY = nDPIY * 80;
287 break;
288 default:
289 DBG_ERROR( "unhandled MapUnit" );
290 break;
293 Fraction aScaleX = rMapMode.GetScaleX();
294 Fraction aScaleY = rMapMode.GetScaleY();
296 // Offset laut MapMode setzen
297 Point aOrigin = rMapMode.GetOrigin();
298 if ( rMapMode.GetMapUnit() != MAP_RELATIVE )
300 rMapRes.mnMapOfsX = aOrigin.X();
301 rMapRes.mnMapOfsY = aOrigin.Y();
303 else
305 BigInt aX( rMapRes.mnMapOfsX );
306 aX *= BigInt( aScaleX.GetDenominator() );
307 if ( rMapRes.mnMapOfsX >= 0 )
309 if ( aScaleX.GetNumerator() >= 0 )
310 aX += BigInt( aScaleX.GetNumerator()/2 );
311 else
312 aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
314 else
316 if ( aScaleX.GetNumerator() >= 0 )
317 aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
318 else
319 aX += BigInt( aScaleX.GetNumerator()/2 );
321 aX /= BigInt( aScaleX.GetNumerator() );
322 rMapRes.mnMapOfsX = (long)aX + aOrigin.X();
323 BigInt aY( rMapRes.mnMapOfsY );
324 aY *= BigInt( aScaleY.GetDenominator() );
325 if( rMapRes.mnMapOfsY >= 0 )
327 if ( aScaleY.GetNumerator() >= 0 )
328 aY += BigInt( aScaleY.GetNumerator()/2 );
329 else
330 aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
332 else
334 if ( aScaleY.GetNumerator() >= 0 )
335 aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
336 else
337 aY += BigInt( aScaleY.GetNumerator()/2 );
339 aY /= BigInt( aScaleY.GetNumerator() );
340 rMapRes.mnMapOfsY = (long)aY + aOrigin.Y();
343 // Scaling Faktor laut MapMode einberechnen
344 // aTemp? = rMapRes.mnMapSc? * aScale?
345 Fraction aTempX = ImplMakeFraction( rMapRes.mnMapScNumX,
346 aScaleX.GetNumerator(),
347 rMapRes.mnMapScDenomX,
348 aScaleX.GetDenominator() );
349 Fraction aTempY = ImplMakeFraction( rMapRes.mnMapScNumY,
350 aScaleY.GetNumerator(),
351 rMapRes.mnMapScDenomY,
352 aScaleY.GetDenominator() );
353 rMapRes.mnMapScNumX = aTempX.GetNumerator();
354 rMapRes.mnMapScDenomX = aTempX.GetDenominator();
355 rMapRes.mnMapScNumY = aTempY.GetNumerator();
356 rMapRes.mnMapScDenomY = aTempY.GetDenominator();
358 // hack: 0/n ungef"ahr 1/max
359 if ( !rMapRes.mnMapScNumX )
361 rMapRes.mnMapScNumX = 1;
362 rMapRes.mnMapScDenomX = LONG_MAX;
364 if ( !rMapRes.mnMapScNumY )
366 rMapRes.mnMapScNumY = 1;
367 rMapRes.mnMapScDenomY = LONG_MAX;
371 // -----------------------------------------------------------------------
373 inline void ImplCalcMapResolution( const MapMode& rMapMode,
374 long nDPIX, long nDPIY,
375 ImplMapRes& rMapRes,
376 ImplThresholdRes& rThresRes )
378 ImplCalcMapResolution( rMapMode, nDPIX, nDPIY, rMapRes );
379 ImplCalcBigIntThreshold( nDPIX, nDPIY, rMapRes, rThresRes );
382 // -----------------------------------------------------------------------
384 static long ImplLogicToPixel( long n, long nDPI, long nMapNum, long nMapDenom,
385 long nThres )
387 // To "use" it...
388 (void) nThres;
389 #ifdef USE_64BIT_INTS
390 #if (SAL_TYPES_SIZEOFLONG < 8)
391 if( (+n < nThres) && (-n < nThres) )
393 n *= nMapNum * nDPI;
394 if( nMapDenom != 1 )
396 n = (2 * n) / nMapDenom;
397 if( n < 0 ) --n; else ++n;
398 n /= 2;
401 else
402 #endif
404 sal_Int64 n64 = n;
405 n64 *= nMapNum;
406 n64 *= nDPI;
407 if( nMapDenom == 1 )
408 n = (long)n64;
409 else
411 n = (long)(2 * n64 / nMapDenom);
412 if( n < 0 ) --n; else ++n;
413 n /= 2;
416 return n;
417 #else // USE_64BIT_INTS
418 if ( Abs( n ) < nThres )
420 n *= nDPI * nMapNum;
421 n += n >= 0 ? nMapDenom/2 : -((nMapDenom-1)/2);
422 return (n / nMapDenom);
424 else
426 BigInt aTemp( n );
427 aTemp *= BigInt( nDPI );
428 aTemp *= BigInt( nMapNum );
430 if ( aTemp.IsNeg() )
432 BigInt aMapScDenom2( (nMapDenom-1)/2 );
433 aTemp -= aMapScDenom2;
435 else
437 BigInt aMapScDenom2( nMapDenom/2 );
438 aTemp += aMapScDenom2;
441 aTemp /= BigInt( nMapDenom );
442 return (long)aTemp;
444 #endif
447 // -----------------------------------------------------------------------
449 static long ImplPixelToLogic( long n, long nDPI, long nMapNum, long nMapDenom,
450 long nThres )
452 // To "use" it...
453 (void) nThres;
454 #ifdef USE_64BIT_INTS
455 #if (SAL_TYPES_SIZEOFLONG < 8)
456 if( (+n < nThres) && (-n < nThres) )
457 n = (2 * n * nMapDenom) / (nDPI * nMapNum);
458 else
459 #endif
461 sal_Int64 n64 = n;
462 n64 *= nMapDenom;
463 long nDenom = nDPI * nMapNum;
464 n = (long)(2 * n64 / nDenom);
466 if( n < 0 ) --n; else ++n;
467 return (n / 2);
468 #else // USE_64BIT_INTS
469 if ( Abs( n ) < nThres )
471 long nDenom = nDPI * nMapNum;
472 long nNum = n * nMapDenom;
473 if( (nNum ^ nDenom) >= 0 )
474 nNum += nDenom/2;
475 else
476 nNum -= nDenom/2;
477 return (nNum / nDenom);
479 else
481 BigInt aDenom( nDPI );
482 aDenom *= BigInt( nMapNum );
484 BigInt aNum( n );
485 aNum *= BigInt( nMapDenom );
487 BigInt aDenom2( aDenom );
488 if ( aNum.IsNeg() )
490 if ( aDenom.IsNeg() )
492 aDenom2 /= BigInt(2);
493 aNum += aDenom2;
495 else
497 aDenom2 -= 1;
498 aDenom2 /= BigInt(2);
499 aNum -= aDenom2;
502 else
504 if ( aDenom.IsNeg() )
506 aDenom2 += 1;
507 aDenom2 /= BigInt(2);
508 aNum -= aDenom2;
510 else
512 aDenom2 /= BigInt(2);
513 aNum += aDenom2;
517 aNum /= aDenom;
518 return (long)aNum;
520 #endif
523 // -----------------------------------------------------------------------
525 long OutputDevice::ImplLogicXToDevicePixel( long nX ) const
527 if ( !mbMap )
528 return nX+mnOutOffX;
530 return ImplLogicToPixel( nX + maMapRes.mnMapOfsX, mnDPIX,
531 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
532 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX;
535 // -----------------------------------------------------------------------
537 long OutputDevice::ImplLogicYToDevicePixel( long nY ) const
539 if ( !mbMap )
540 return nY+mnOutOffY;
542 return ImplLogicToPixel( nY + maMapRes.mnMapOfsY, mnDPIY,
543 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
544 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY;
547 // -----------------------------------------------------------------------
549 long OutputDevice::ImplLogicWidthToDevicePixel( long nWidth ) const
551 if ( !mbMap )
552 return nWidth;
554 return ImplLogicToPixel( nWidth, mnDPIX,
555 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
556 maThresRes.mnThresLogToPixX );
559 float OutputDevice::ImplFloatLogicWidthToDevicePixel( float fLogicWidth) const
561 if( !mbMap)
562 return fLogicWidth;
563 // TODO: consolidate the calculation into one multiplication
564 float fPixelWidth = (fLogicWidth * mnDPIX * maMapRes.mnMapScNumX) / maMapRes.mnMapScDenomX;
565 return fPixelWidth;
568 // -----------------------------------------------------------------------
570 long OutputDevice::ImplLogicHeightToDevicePixel( long nHeight ) const
572 if ( !mbMap )
573 return nHeight;
575 return ImplLogicToPixel( nHeight, mnDPIY,
576 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
577 maThresRes.mnThresLogToPixY );
580 float OutputDevice::ImplFloatLogicHeightToDevicePixel( float fLogicHeight) const
582 if( !mbMap)
583 return fLogicHeight;
584 float fPixelHeight = (fLogicHeight * mnDPIY * maMapRes.mnMapScNumY) / maMapRes.mnMapScDenomY;
585 return fPixelHeight;
588 // -----------------------------------------------------------------------
590 long OutputDevice::ImplDevicePixelToLogicWidth( long nWidth ) const
592 if ( !mbMap )
593 return nWidth;
595 return ImplPixelToLogic( nWidth, mnDPIX,
596 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
597 maThresRes.mnThresPixToLogX );
600 float OutputDevice::ImplFloatDevicePixelToLogicWidth( float fPixelWidth) const
602 if( !mbMap)
603 return fPixelWidth;
604 float fLogicHeight = (fPixelWidth * maMapRes.mnMapScDenomX) / (mnDPIX * maMapRes.mnMapScNumX);
605 return fLogicHeight;
608 // -----------------------------------------------------------------------
610 long OutputDevice::ImplDevicePixelToLogicHeight( long nHeight ) const
612 if ( !mbMap )
613 return nHeight;
615 return ImplPixelToLogic( nHeight, mnDPIY,
616 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
617 maThresRes.mnThresPixToLogY );
620 float OutputDevice::ImplFloatDevicePixelToLogicHeight( float fPixelHeight) const
622 if( !mbMap)
623 return fPixelHeight;
624 float fLogicHeight = (fPixelHeight * maMapRes.mnMapScDenomY) / (mnDPIY * maMapRes.mnMapScNumY);
625 return fLogicHeight;
629 // -----------------------------------------------------------------------
631 Point OutputDevice::ImplLogicToDevicePixel( const Point& rLogicPt ) const
633 if ( !mbMap )
634 return Point( rLogicPt.X()+mnOutOffX, rLogicPt.Y()+mnOutOffY );
636 return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
637 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
638 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX,
639 ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
640 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
641 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY );
644 // -----------------------------------------------------------------------
646 Size OutputDevice::ImplLogicToDevicePixel( const Size& rLogicSize ) const
648 if ( !mbMap )
649 return rLogicSize;
651 return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
652 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
653 maThresRes.mnThresLogToPixX ),
654 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
655 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
656 maThresRes.mnThresLogToPixY ) );
659 // -----------------------------------------------------------------------
661 Rectangle OutputDevice::ImplLogicToDevicePixel( const Rectangle& rLogicRect ) const
663 if ( rLogicRect.IsEmpty() )
664 return rLogicRect;
666 if ( !mbMap )
668 return Rectangle( rLogicRect.Left()+mnOutOffX, rLogicRect.Top()+mnOutOffY,
669 rLogicRect.Right()+mnOutOffX, rLogicRect.Bottom()+mnOutOffY );
672 return Rectangle( ImplLogicToPixel( rLogicRect.Left()+maMapRes.mnMapOfsX, mnDPIX,
673 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
674 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX,
675 ImplLogicToPixel( rLogicRect.Top()+maMapRes.mnMapOfsY, mnDPIY,
676 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
677 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY,
678 ImplLogicToPixel( rLogicRect.Right()+maMapRes.mnMapOfsX, mnDPIX,
679 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
680 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX,
681 ImplLogicToPixel( rLogicRect.Bottom()+maMapRes.mnMapOfsY, mnDPIY,
682 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
683 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY );
686 // -----------------------------------------------------------------------
688 Polygon OutputDevice::ImplLogicToDevicePixel( const Polygon& rLogicPoly ) const
690 if ( !mbMap && !mnOutOffX && !mnOutOffY )
691 return rLogicPoly;
693 USHORT i;
694 USHORT nPoints = rLogicPoly.GetSize();
695 Polygon aPoly( rLogicPoly );
697 // Pointer auf das Point-Array holen (Daten werden kopiert)
698 const Point* pPointAry = aPoly.GetConstPointAry();
700 if ( mbMap )
702 for ( i = 0; i < nPoints; i++ )
704 const Point* pPt = &(pPointAry[i]);
705 Point aPt;
706 aPt.X() = ImplLogicToPixel( pPt->X()+maMapRes.mnMapOfsX, mnDPIX,
707 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
708 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX;
709 aPt.Y() = ImplLogicToPixel( pPt->Y()+maMapRes.mnMapOfsY, mnDPIY,
710 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
711 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY;
712 aPoly[i] = aPt;
715 else
717 for ( i = 0; i < nPoints; i++ )
719 Point aPt = pPointAry[i];
720 aPt.X() += mnOutOffX;
721 aPt.Y() += mnOutOffY;
722 aPoly[i] = aPt;
726 return aPoly;
729 // -----------------------------------------------------------------------
731 PolyPolygon OutputDevice::ImplLogicToDevicePixel( const PolyPolygon& rLogicPolyPoly ) const
733 if ( !mbMap && !mnOutOffX && !mnOutOffY )
734 return rLogicPolyPoly;
736 PolyPolygon aPolyPoly( rLogicPolyPoly );
737 USHORT nPoly = aPolyPoly.Count();
738 for( USHORT i = 0; i < nPoly; i++ )
740 Polygon& rPoly = aPolyPoly[i];
741 rPoly = ImplLogicToDevicePixel( rPoly );
743 return aPolyPoly;
746 // -----------------------------------------------------------------------
748 LineInfo OutputDevice::ImplLogicToDevicePixel( const LineInfo& rLineInfo ) const
750 LineInfo aInfo( rLineInfo );
752 if( aInfo.GetStyle() == LINE_DASH )
754 if( aInfo.GetDotCount() && aInfo.GetDotLen() )
755 aInfo.SetDotLen( Max( ImplLogicWidthToDevicePixel( aInfo.GetDotLen() ), 1L ) );
756 else
757 aInfo.SetDotCount( 0 );
759 if( aInfo.GetDashCount() && aInfo.GetDashLen() )
760 aInfo.SetDashLen( Max( ImplLogicWidthToDevicePixel( aInfo.GetDashLen() ), 1L ) );
761 else
762 aInfo.SetDashCount( 0 );
764 aInfo.SetDistance( ImplLogicWidthToDevicePixel( aInfo.GetDistance() ) );
766 if( ( !aInfo.GetDashCount() && !aInfo.GetDotCount() ) || !aInfo.GetDistance() )
767 aInfo.SetStyle( LINE_SOLID );
770 aInfo.SetWidth( ImplLogicWidthToDevicePixel( aInfo.GetWidth() ) );
772 return aInfo;
775 // -----------------------------------------------------------------------
777 Rectangle OutputDevice::ImplDevicePixelToLogic( const Rectangle& rPixelRect ) const
779 if ( rPixelRect.IsEmpty() )
780 return rPixelRect;
782 if ( !mbMap )
784 return Rectangle( rPixelRect.Left()-mnOutOffX, rPixelRect.Top()-mnOutOffY,
785 rPixelRect.Right()-mnOutOffX, rPixelRect.Bottom()-mnOutOffY );
788 return Rectangle( ImplPixelToLogic( rPixelRect.Left()-mnOutOffX-mnOutOffOrigX, mnDPIX,
789 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
790 maThresRes.mnThresPixToLogX )-maMapRes.mnMapOfsX,
791 ImplPixelToLogic( rPixelRect.Top()-mnOutOffY-mnOutOffOrigY, mnDPIY,
792 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
793 maThresRes.mnThresPixToLogY )-maMapRes.mnMapOfsY,
794 ImplPixelToLogic( rPixelRect.Right()-mnOutOffX-mnOutOffOrigX, mnDPIX,
795 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
796 maThresRes.mnThresPixToLogX )-maMapRes.mnMapOfsX,
797 ImplPixelToLogic( rPixelRect.Bottom()-mnOutOffY-mnOutOffOrigY, mnDPIY,
798 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
799 maThresRes.mnThresPixToLogY )-maMapRes.mnMapOfsY );
802 // -----------------------------------------------------------------------
804 Region OutputDevice::ImplPixelToDevicePixel( const Region& rRegion ) const
806 DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
808 if ( !mnOutOffX && !mnOutOffY )
809 return rRegion;
811 Region aRegion( rRegion );
812 aRegion.Move( mnOutOffX+mnOutOffOrigX, mnOutOffY+mnOutOffOrigY );
813 return aRegion;
816 // -----------------------------------------------------------------------
818 void OutputDevice::EnableMapMode( BOOL bEnable )
820 mbMap = (bEnable != 0);
822 if( mpAlphaVDev )
823 mpAlphaVDev->EnableMapMode( bEnable );
826 // -----------------------------------------------------------------------
828 void OutputDevice::SetMapMode()
830 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
832 if ( mpMetaFile )
833 mpMetaFile->AddAction( new MetaMapModeAction( MapMode() ) );
835 if ( mbMap || !maMapMode.IsDefault() )
837 mbMap = FALSE;
838 maMapMode = MapMode();
840 // create new objects (clip region werden nicht neu skaliert)
841 mbNewFont = TRUE;
842 mbInitFont = TRUE;
843 if ( GetOutDevType() == OUTDEV_WINDOW )
845 if ( ((Window*)this)->mpWindowImpl->mpCursor )
846 ((Window*)this)->mpWindowImpl->mpCursor->ImplNew();
849 // #106426# Adapt logical offset when changing mapmode
850 mnOutOffLogicX = mnOutOffOrigX; // no mapping -> equal offsets
851 mnOutOffLogicY = mnOutOffOrigY;
853 // #i75163#
854 ImplInvalidateViewTransform();
857 if( mpAlphaVDev )
858 mpAlphaVDev->SetMapMode();
861 // -----------------------------------------------------------------------
863 void OutputDevice::SetMapMode( const MapMode& rNewMapMode )
865 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
867 BOOL bRelMap = (rNewMapMode.GetMapUnit() == MAP_RELATIVE);
869 if ( mpMetaFile )
871 mpMetaFile->AddAction( new MetaMapModeAction( rNewMapMode ) );
872 #ifdef DBG_UTIL
873 if ( GetOutDevType() != OUTDEV_PRINTER )
874 DBG_ASSERTWARNING( bRelMap, "Please record only relative MapModes!" );
875 #endif
878 // Ist der MapMode der gleiche wie vorher, dann mache nichts
879 if ( maMapMode == rNewMapMode )
880 return;
882 if( mpAlphaVDev )
883 mpAlphaVDev->SetMapMode( rNewMapMode );
885 // Ist Default-MapMode, dann bereche nichts
886 BOOL bOldMap = mbMap;
887 mbMap = !rNewMapMode.IsDefault();
888 if ( mbMap )
890 // Falls nur der Orign umgesetzt wird, dann scaliere nichts neu
891 if ( (rNewMapMode.GetMapUnit() == maMapMode.GetMapUnit()) &&
892 (rNewMapMode.GetScaleX() == maMapMode.GetScaleX()) &&
893 (rNewMapMode.GetScaleY() == maMapMode.GetScaleY()) &&
894 (bOldMap == mbMap) )
896 // Offset setzen
897 Point aOrigin = rNewMapMode.GetOrigin();
898 maMapRes.mnMapOfsX = aOrigin.X();
899 maMapRes.mnMapOfsY = aOrigin.Y();
900 maMapMode = rNewMapMode;
902 // #i75163#
903 ImplInvalidateViewTransform();
905 return;
907 if ( !bOldMap && bRelMap )
909 maMapRes.mnMapScNumX = 1;
910 maMapRes.mnMapScNumY = 1;
911 maMapRes.mnMapScDenomX = mnDPIX;
912 maMapRes.mnMapScDenomY = mnDPIY;
913 maMapRes.mnMapOfsX = 0;
914 maMapRes.mnMapOfsY = 0;
917 // Neue MapMode-Aufloesung berechnen
918 ImplCalcMapResolution( rNewMapMode, mnDPIX, mnDPIY, maMapRes, maThresRes );
921 // Neuen MapMode setzen
922 if ( bRelMap )
924 Point aOrigin( maMapRes.mnMapOfsX, maMapRes.mnMapOfsY );
925 // aScale? = maMapMode.GetScale?() * rNewMapMode.GetScale?()
926 Fraction aScaleX = ImplMakeFraction( maMapMode.GetScaleX().GetNumerator(),
927 rNewMapMode.GetScaleX().GetNumerator(),
928 maMapMode.GetScaleX().GetDenominator(),
929 rNewMapMode.GetScaleX().GetDenominator() );
930 Fraction aScaleY = ImplMakeFraction( maMapMode.GetScaleY().GetNumerator(),
931 rNewMapMode.GetScaleY().GetNumerator(),
932 maMapMode.GetScaleY().GetDenominator(),
933 rNewMapMode.GetScaleY().GetDenominator() );
934 maMapMode.SetOrigin( aOrigin );
935 maMapMode.SetScaleX( aScaleX );
936 maMapMode.SetScaleY( aScaleY );
938 else
939 maMapMode = rNewMapMode;
941 // create new objects (clip region werden nicht neu skaliert)
942 mbNewFont = TRUE;
943 mbInitFont = TRUE;
944 if ( GetOutDevType() == OUTDEV_WINDOW )
946 if ( ((Window*)this)->mpWindowImpl->mpCursor )
947 ((Window*)this)->mpWindowImpl->mpCursor->ImplNew();
950 // #106426# Adapt logical offset when changing mapmode
951 mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
952 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
953 maThresRes.mnThresPixToLogX );
954 mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
955 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
956 maThresRes.mnThresPixToLogY );
958 // #i75163#
959 ImplInvalidateViewTransform();
962 // -----------------------------------------------------------------------
964 void OutputDevice::SetRelativeMapMode( const MapMode& rNewMapMode )
966 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
968 // Ist der MapMode der gleiche wie vorher, dann mache nichts
969 if ( maMapMode == rNewMapMode )
970 return;
972 MapUnit eOld = maMapMode.GetMapUnit();
973 MapUnit eNew = rNewMapMode.GetMapUnit();
975 // a?F = rNewMapMode.GetScale?() / maMapMode.GetScale?()
976 Fraction aXF = ImplMakeFraction( rNewMapMode.GetScaleX().GetNumerator(),
977 maMapMode.GetScaleX().GetDenominator(),
978 rNewMapMode.GetScaleX().GetDenominator(),
979 maMapMode.GetScaleX().GetNumerator() );
980 Fraction aYF = ImplMakeFraction( rNewMapMode.GetScaleY().GetNumerator(),
981 maMapMode.GetScaleY().GetDenominator(),
982 rNewMapMode.GetScaleY().GetDenominator(),
983 maMapMode.GetScaleY().GetNumerator() );
985 Point aPt( LogicToLogic( Point(), NULL, &rNewMapMode ) );
986 if ( eNew != eOld )
988 if ( eOld > MAP_PIXEL )
990 DBG_ERRORFILE( "Not implemented MapUnit" );
992 else if ( eNew > MAP_PIXEL )
994 DBG_ERRORFILE( "Not implemented MapUnit" );
996 else
998 Fraction aF( aImplNumeratorAry[eNew] * aImplDenominatorAry[eOld],
999 aImplNumeratorAry[eOld] * aImplDenominatorAry[eNew] );
1001 // a?F = a?F * aF
1002 aXF = ImplMakeFraction( aXF.GetNumerator(), aF.GetNumerator(),
1003 aXF.GetDenominator(), aF.GetDenominator() );
1004 aYF = ImplMakeFraction( aYF.GetNumerator(), aF.GetNumerator(),
1005 aYF.GetDenominator(), aF.GetDenominator() );
1006 if ( eOld == MAP_PIXEL )
1008 aXF *= Fraction( mnDPIX, 1 );
1009 aYF *= Fraction( mnDPIY, 1 );
1011 else if ( eNew == MAP_PIXEL )
1013 aXF *= Fraction( 1, mnDPIX );
1014 aYF *= Fraction( 1, mnDPIY );
1019 MapMode aNewMapMode( MAP_RELATIVE, Point( -aPt.X(), -aPt.Y() ), aXF, aYF );
1020 SetMapMode( aNewMapMode );
1022 if ( eNew != eOld )
1023 maMapMode = rNewMapMode;
1025 // #106426# Adapt logical offset when changing mapmode
1026 mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
1027 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1028 maThresRes.mnThresPixToLogX );
1029 mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
1030 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1031 maThresRes.mnThresPixToLogY );
1033 if( mpAlphaVDev )
1034 mpAlphaVDev->SetRelativeMapMode( rNewMapMode );
1037 // -----------------------------------------------------------------------
1039 // #i75163#
1040 basegfx::B2DHomMatrix OutputDevice::GetViewTransformation() const
1042 if(mbMap)
1044 // #i82615#
1045 if(!mpOutDevData)
1047 const_cast< OutputDevice* >(this)->ImplInitOutDevData();
1050 if(!mpOutDevData->mpViewTransform)
1052 mpOutDevData->mpViewTransform = new basegfx::B2DHomMatrix;
1054 const double fScaleFactorX((double)mnDPIX * (double)maMapRes.mnMapScNumX / (double)maMapRes.mnMapScDenomX);
1055 const double fScaleFactorY((double)mnDPIY * (double)maMapRes.mnMapScNumY / (double)maMapRes.mnMapScDenomY);
1056 const double fZeroPointX(((double)maMapRes.mnMapOfsX * fScaleFactorX) + (double)mnOutOffOrigX);
1057 const double fZeroPointY(((double)maMapRes.mnMapOfsY * fScaleFactorY) + (double)mnOutOffOrigY);
1059 mpOutDevData->mpViewTransform->set(0, 0, fScaleFactorX);
1060 mpOutDevData->mpViewTransform->set(1, 1, fScaleFactorY);
1061 mpOutDevData->mpViewTransform->set(0, 2, fZeroPointX);
1062 mpOutDevData->mpViewTransform->set(1, 2, fZeroPointY);
1065 return *mpOutDevData->mpViewTransform;
1067 else
1069 return basegfx::B2DHomMatrix();
1073 // -----------------------------------------------------------------------
1075 // #i75163#
1076 basegfx::B2DHomMatrix OutputDevice::GetInverseViewTransformation() const
1078 if(mbMap)
1080 // #i82615#
1081 if(!mpOutDevData)
1083 const_cast< OutputDevice* >(this)->ImplInitOutDevData();
1086 if(!mpOutDevData->mpInverseViewTransform)
1088 GetViewTransformation();
1089 mpOutDevData->mpInverseViewTransform = new basegfx::B2DHomMatrix(*mpOutDevData->mpViewTransform);
1090 mpOutDevData->mpInverseViewTransform->invert();
1093 return *mpOutDevData->mpInverseViewTransform;
1095 else
1097 return basegfx::B2DHomMatrix();
1101 // -----------------------------------------------------------------------
1103 basegfx::B2DHomMatrix OutputDevice::ImplGetDeviceTransformation() const
1105 basegfx::B2DHomMatrix aTransformation = GetViewTransformation();
1106 // TODO: is it worth to cache the transformed result?
1107 if( mnOutOffX || mnOutOffY )
1108 aTransformation.translate( mnOutOffX, mnOutOffY );
1109 return aTransformation;
1112 // -----------------------------------------------------------------------
1114 Point OutputDevice::LogicToPixel( const Point& rLogicPt ) const
1116 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1118 if ( !mbMap )
1119 return rLogicPt;
1121 return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
1122 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1123 maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1124 ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
1125 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1126 maThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1129 // -----------------------------------------------------------------------
1131 Size OutputDevice::LogicToPixel( const Size& rLogicSize ) const
1133 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1135 if ( !mbMap )
1136 return rLogicSize;
1138 return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
1139 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1140 maThresRes.mnThresLogToPixX ),
1141 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
1142 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1143 maThresRes.mnThresLogToPixY ) );
1146 // -----------------------------------------------------------------------
1148 Rectangle OutputDevice::LogicToPixel( const Rectangle& rLogicRect ) const
1150 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1152 if ( !mbMap || rLogicRect.IsEmpty() )
1153 return rLogicRect;
1155 return Rectangle( ImplLogicToPixel( rLogicRect.Left() + maMapRes.mnMapOfsX, mnDPIX,
1156 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1157 maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1158 ImplLogicToPixel( rLogicRect.Top() + maMapRes.mnMapOfsY, mnDPIY,
1159 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1160 maThresRes.mnThresLogToPixY )+mnOutOffOrigY,
1161 ImplLogicToPixel( rLogicRect.Right() + maMapRes.mnMapOfsX, mnDPIX,
1162 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1163 maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1164 ImplLogicToPixel( rLogicRect.Bottom() + maMapRes.mnMapOfsY, mnDPIY,
1165 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1166 maThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1169 // -----------------------------------------------------------------------
1171 Polygon OutputDevice::LogicToPixel( const Polygon& rLogicPoly ) const
1173 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1174 DBG_CHKOBJ( &rLogicPoly, Polygon, NULL );
1176 if ( !mbMap )
1177 return rLogicPoly;
1179 USHORT i;
1180 USHORT nPoints = rLogicPoly.GetSize();
1181 Polygon aPoly( rLogicPoly );
1183 // Pointer auf das Point-Array holen (Daten werden kopiert)
1184 const Point* pPointAry = aPoly.GetConstPointAry();
1186 for ( i = 0; i < nPoints; i++ )
1188 const Point* pPt = &(pPointAry[i]);
1189 Point aPt;
1190 aPt.X() = ImplLogicToPixel( pPt->X() + maMapRes.mnMapOfsX, mnDPIX,
1191 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1192 maThresRes.mnThresLogToPixX )+mnOutOffOrigX;
1193 aPt.Y() = ImplLogicToPixel( pPt->Y() + maMapRes.mnMapOfsY, mnDPIY,
1194 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1195 maThresRes.mnThresLogToPixY )+mnOutOffOrigY;
1196 aPoly[i] = aPt;
1199 return aPoly;
1202 // -----------------------------------------------------------------------
1204 PolyPolygon OutputDevice::LogicToPixel( const PolyPolygon& rLogicPolyPoly ) const
1206 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1207 DBG_CHKOBJ( &rLogicPolyPoly, PolyPolygon, NULL );
1209 if ( !mbMap )
1210 return rLogicPolyPoly;
1212 PolyPolygon aPolyPoly( rLogicPolyPoly );
1213 USHORT nPoly = aPolyPoly.Count();
1214 for( USHORT i = 0; i < nPoly; i++ )
1216 Polygon& rPoly = aPolyPoly[i];
1217 rPoly = LogicToPixel( rPoly );
1219 return aPolyPoly;
1222 // -----------------------------------------------------------------------
1224 Region OutputDevice::LogicToPixel( const Region& rLogicRegion ) const
1226 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1227 DBG_CHKOBJ( &rLogicRegion, Region, ImplDbgTestRegion );
1229 RegionType eType = rLogicRegion.GetType();
1231 if ( !mbMap || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
1232 return rLogicRegion;
1234 Region aRegion;
1235 const ImplRegion& rImplRegion = *rLogicRegion.ImplGetImplRegion();
1236 const PolyPolygon* pPolyPoly = rImplRegion.mpPolyPoly;
1237 const basegfx::B2DPolyPolygon* pB2DPolyPoly = rImplRegion.mpB2DPolyPoly;
1239 if ( pPolyPoly )
1240 aRegion = Region( LogicToPixel( *pPolyPoly ) );
1241 else if( pB2DPolyPoly )
1243 basegfx::B2DPolyPolygon aTransformedPoly = *pB2DPolyPoly;
1244 const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation();
1245 aTransformedPoly.transform( rTransformationMatrix );
1246 aRegion = Region( aTransformedPoly );
1248 else
1250 long nX;
1251 long nY;
1252 long nWidth;
1253 long nHeight;
1254 ImplRegionInfo aInfo;
1255 BOOL bRegionRect;
1257 aRegion.ImplBeginAddRect();
1258 bRegionRect = rLogicRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
1259 while ( bRegionRect )
1261 Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
1262 aRegion.ImplAddRect( LogicToPixel( aRect ) );
1263 bRegionRect = rLogicRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
1265 aRegion.ImplEndAddRect();
1268 return aRegion;
1271 // -----------------------------------------------------------------------
1273 Point OutputDevice::LogicToPixel( const Point& rLogicPt,
1274 const MapMode& rMapMode ) const
1276 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1278 if ( rMapMode.IsDefault() )
1279 return rLogicPt;
1281 // MapMode-Aufloesung berechnen und Umrechnen
1282 ImplMapRes aMapRes;
1283 ImplThresholdRes aThresRes;
1284 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1286 return Point( ImplLogicToPixel( rLogicPt.X() + aMapRes.mnMapOfsX, mnDPIX,
1287 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1288 aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1289 ImplLogicToPixel( rLogicPt.Y() + aMapRes.mnMapOfsY, mnDPIY,
1290 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1291 aThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1294 // -----------------------------------------------------------------------
1296 Size OutputDevice::LogicToPixel( const Size& rLogicSize,
1297 const MapMode& rMapMode ) const
1299 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1301 if ( rMapMode.IsDefault() )
1302 return rLogicSize;
1304 // MapMode-Aufloesung berechnen und Umrechnen
1305 ImplMapRes aMapRes;
1306 ImplThresholdRes aThresRes;
1307 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1309 return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
1310 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1311 aThresRes.mnThresLogToPixX ),
1312 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
1313 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1314 aThresRes.mnThresLogToPixY ) );
1317 // -----------------------------------------------------------------------
1319 Rectangle OutputDevice::LogicToPixel( const Rectangle& rLogicRect,
1320 const MapMode& rMapMode ) const
1322 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1324 if ( rMapMode.IsDefault() || rLogicRect.IsEmpty() )
1325 return rLogicRect;
1327 // MapMode-Aufloesung berechnen und Umrechnen
1328 ImplMapRes aMapRes;
1329 ImplThresholdRes aThresRes;
1330 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1332 return Rectangle( ImplLogicToPixel( rLogicRect.Left() + aMapRes.mnMapOfsX, mnDPIX,
1333 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1334 aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1335 ImplLogicToPixel( rLogicRect.Top() + aMapRes.mnMapOfsY, mnDPIY,
1336 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1337 aThresRes.mnThresLogToPixY )+mnOutOffOrigY,
1338 ImplLogicToPixel( rLogicRect.Right() + aMapRes.mnMapOfsX, mnDPIX,
1339 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1340 aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1341 ImplLogicToPixel( rLogicRect.Bottom() + aMapRes.mnMapOfsY, mnDPIY,
1342 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1343 aThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1346 // -----------------------------------------------------------------------
1348 Polygon OutputDevice::LogicToPixel( const Polygon& rLogicPoly,
1349 const MapMode& rMapMode ) const
1351 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1352 DBG_CHKOBJ( &rLogicPoly, Polygon, NULL );
1354 if ( rMapMode.IsDefault() )
1355 return rLogicPoly;
1357 // MapMode-Aufloesung berechnen und Umrechnen
1358 ImplMapRes aMapRes;
1359 ImplThresholdRes aThresRes;
1360 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1362 USHORT i;
1363 USHORT nPoints = rLogicPoly.GetSize();
1364 Polygon aPoly( rLogicPoly );
1366 // Pointer auf das Point-Array holen (Daten werden kopiert)
1367 const Point* pPointAry = aPoly.GetConstPointAry();
1369 for ( i = 0; i < nPoints; i++ )
1371 const Point* pPt = &(pPointAry[i]);
1372 Point aPt;
1373 aPt.X() = ImplLogicToPixel( pPt->X() + aMapRes.mnMapOfsX, mnDPIX,
1374 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1375 aThresRes.mnThresLogToPixX )+mnOutOffOrigX;
1376 aPt.Y() = ImplLogicToPixel( pPt->Y() + aMapRes.mnMapOfsY, mnDPIY,
1377 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1378 aThresRes.mnThresLogToPixY )+mnOutOffOrigY;
1379 aPoly[i] = aPt;
1382 return aPoly;
1385 // -----------------------------------------------------------------------
1387 PolyPolygon OutputDevice::LogicToPixel( const PolyPolygon& rLogicPolyPoly,
1388 const MapMode& rMapMode ) const
1390 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1391 DBG_CHKOBJ( &rLogicPolyPoly, PolyPolygon, NULL );
1393 if ( rMapMode.IsDefault() )
1394 return rLogicPolyPoly;
1396 PolyPolygon aPolyPoly( rLogicPolyPoly );
1397 USHORT nPoly = aPolyPoly.Count();
1398 for( USHORT i = 0; i < nPoly; i++ )
1400 Polygon& rPoly = aPolyPoly[i];
1401 rPoly = LogicToPixel( rPoly, rMapMode );
1403 return aPolyPoly;
1406 // -----------------------------------------------------------------------
1408 Region OutputDevice::LogicToPixel( const Region& rLogicRegion,
1409 const MapMode& rMapMode ) const
1411 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1412 DBG_CHKOBJ( &rLogicRegion, Region, ImplDbgTestRegion );
1414 RegionType eType = rLogicRegion.GetType();
1416 if ( rMapMode.IsDefault() || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
1417 return rLogicRegion;
1419 Region aRegion;
1420 PolyPolygon* pPolyPoly = rLogicRegion.ImplGetImplRegion()->mpPolyPoly;
1422 if( pPolyPoly )
1423 aRegion = Region( LogicToPixel( *pPolyPoly, rMapMode ) );
1424 else
1426 long nX;
1427 long nY;
1428 long nWidth;
1429 long nHeight;
1430 ImplRegionInfo aInfo;
1431 BOOL bRegionRect;
1433 aRegion.ImplBeginAddRect();
1434 bRegionRect = rLogicRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
1435 while ( bRegionRect )
1437 Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
1438 aRegion.ImplAddRect( LogicToPixel( aRect, rMapMode ) );
1439 bRegionRect = rLogicRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
1441 aRegion.ImplEndAddRect();
1444 return aRegion;
1447 // -----------------------------------------------------------------------
1449 Point OutputDevice::PixelToLogic( const Point& rDevicePt ) const
1451 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1453 if ( !mbMap )
1454 return rDevicePt;
1456 return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1457 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1458 maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1459 ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1460 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1461 maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY );
1464 // -----------------------------------------------------------------------
1466 Size OutputDevice::PixelToLogic( const Size& rDeviceSize ) const
1468 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1470 if ( !mbMap )
1471 return rDeviceSize;
1473 return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1474 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1475 maThresRes.mnThresPixToLogX ),
1476 ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1477 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1478 maThresRes.mnThresPixToLogY ) );
1481 // -----------------------------------------------------------------------
1483 Rectangle OutputDevice::PixelToLogic( const Rectangle& rDeviceRect ) const
1485 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1487 if ( !mbMap || rDeviceRect.IsEmpty() )
1488 return rDeviceRect;
1490 return Rectangle( ImplPixelToLogic( rDeviceRect.Left(), mnDPIX,
1491 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1492 maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1493 ImplPixelToLogic( rDeviceRect.Top(), mnDPIY,
1494 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1495 maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY,
1496 ImplPixelToLogic( rDeviceRect.Right(), mnDPIX,
1497 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1498 maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1499 ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY,
1500 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1501 maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY );
1504 // -----------------------------------------------------------------------
1506 Polygon OutputDevice::PixelToLogic( const Polygon& rDevicePoly ) const
1508 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1509 DBG_CHKOBJ( &rDevicePoly, Polygon, NULL );
1511 if ( !mbMap )
1512 return rDevicePoly;
1514 USHORT i;
1515 USHORT nPoints = rDevicePoly.GetSize();
1516 Polygon aPoly( rDevicePoly );
1518 // Pointer auf das Point-Array holen (Daten werden kopiert)
1519 const Point* pPointAry = aPoly.GetConstPointAry();
1521 for ( i = 0; i < nPoints; i++ )
1523 const Point* pPt = &(pPointAry[i]);
1524 Point aPt;
1525 aPt.X() = ImplPixelToLogic( pPt->X(), mnDPIX,
1526 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1527 maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX;
1528 aPt.Y() = ImplPixelToLogic( pPt->Y(), mnDPIY,
1529 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1530 maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY;
1531 aPoly[i] = aPt;
1534 return aPoly;
1537 // -----------------------------------------------------------------------
1539 PolyPolygon OutputDevice::PixelToLogic( const PolyPolygon& rDevicePolyPoly ) const
1541 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1542 DBG_CHKOBJ( &rDevicePolyPoly, PolyPolygon, NULL );
1544 if ( !mbMap )
1545 return rDevicePolyPoly;
1547 PolyPolygon aPolyPoly( rDevicePolyPoly );
1548 USHORT nPoly = aPolyPoly.Count();
1549 for( USHORT i = 0; i < nPoly; i++ )
1551 Polygon& rPoly = aPolyPoly[i];
1552 rPoly = PixelToLogic( rPoly );
1554 return aPolyPoly;
1557 // -----------------------------------------------------------------------
1559 Region OutputDevice::PixelToLogic( const Region& rDeviceRegion ) const
1561 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1562 DBG_CHKOBJ( &rDeviceRegion, Region, ImplDbgTestRegion );
1564 RegionType eType = rDeviceRegion.GetType();
1566 if ( !mbMap || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
1567 return rDeviceRegion;
1569 Region aRegion;
1570 PolyPolygon* pPolyPoly = rDeviceRegion.ImplGetImplRegion()->mpPolyPoly;
1572 if ( pPolyPoly )
1573 aRegion = Region( PixelToLogic( *pPolyPoly ) );
1574 else
1576 long nX;
1577 long nY;
1578 long nWidth;
1579 long nHeight;
1580 ImplRegionInfo aInfo;
1581 BOOL bRegionRect;
1583 aRegion.ImplBeginAddRect();
1584 bRegionRect = rDeviceRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
1585 while ( bRegionRect )
1587 Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
1588 aRegion.ImplAddRect( PixelToLogic( aRect ) );
1589 bRegionRect = rDeviceRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
1591 aRegion.ImplEndAddRect();
1594 return aRegion;
1597 // -----------------------------------------------------------------------
1599 Point OutputDevice::PixelToLogic( const Point& rDevicePt,
1600 const MapMode& rMapMode ) const
1602 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1604 // Ist Default-MapMode, dann bereche nichts
1605 if ( rMapMode.IsDefault() )
1606 return rDevicePt;
1608 // MapMode-Aufloesung berechnen und Umrechnen
1609 ImplMapRes aMapRes;
1610 ImplThresholdRes aThresRes;
1611 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1613 return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1614 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1615 aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1616 ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1617 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1618 aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1621 // -----------------------------------------------------------------------
1623 Size OutputDevice::PixelToLogic( const Size& rDeviceSize,
1624 const MapMode& rMapMode ) const
1626 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1628 // Ist Default-MapMode, dann bereche nichts
1629 if ( rMapMode.IsDefault() )
1630 return rDeviceSize;
1632 // MapMode-Aufloesung berechnen und Umrechnen
1633 ImplMapRes aMapRes;
1634 ImplThresholdRes aThresRes;
1635 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1637 return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1638 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1639 aThresRes.mnThresPixToLogX ),
1640 ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1641 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1642 aThresRes.mnThresPixToLogY ) );
1645 // -----------------------------------------------------------------------
1647 Rectangle OutputDevice::PixelToLogic( const Rectangle& rDeviceRect,
1648 const MapMode& rMapMode ) const
1650 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1652 // Ist Default-MapMode, dann bereche nichts
1653 if ( rMapMode.IsDefault() || rDeviceRect.IsEmpty() )
1654 return rDeviceRect;
1656 // MapMode-Aufloesung berechnen und Umrechnen
1657 ImplMapRes aMapRes;
1658 ImplThresholdRes aThresRes;
1659 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1661 return Rectangle( ImplPixelToLogic( rDeviceRect.Left(), mnDPIX,
1662 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1663 aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1664 ImplPixelToLogic( rDeviceRect.Top(), mnDPIY,
1665 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1666 aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY,
1667 ImplPixelToLogic( rDeviceRect.Right(), mnDPIX,
1668 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1669 aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1670 ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY,
1671 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1672 aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1675 // -----------------------------------------------------------------------
1677 Polygon OutputDevice::PixelToLogic( const Polygon& rDevicePoly,
1678 const MapMode& rMapMode ) const
1680 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1681 DBG_CHKOBJ( &rDevicePoly, Polygon, NULL );
1683 // Ist Default-MapMode, dann bereche nichts
1684 if ( rMapMode.IsDefault() )
1685 return rDevicePoly;
1687 // MapMode-Aufloesung berechnen und Umrechnen
1688 ImplMapRes aMapRes;
1689 ImplThresholdRes aThresRes;
1690 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1692 USHORT i;
1693 USHORT nPoints = rDevicePoly.GetSize();
1694 Polygon aPoly( rDevicePoly );
1696 // Pointer auf das Point-Array holen (Daten werden kopiert)
1697 const Point* pPointAry = aPoly.GetConstPointAry();
1699 for ( i = 0; i < nPoints; i++ )
1701 const Point* pPt = &(pPointAry[i]);
1702 Point aPt;
1703 aPt.X() = ImplPixelToLogic( pPt->X(), mnDPIX,
1704 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1705 aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX;
1706 aPt.Y() = ImplPixelToLogic( pPt->Y(), mnDPIY,
1707 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1708 aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY;
1709 aPoly[i] = aPt;
1712 return aPoly;
1715 // -----------------------------------------------------------------------
1717 PolyPolygon OutputDevice::PixelToLogic( const PolyPolygon& rDevicePolyPoly,
1718 const MapMode& rMapMode ) const
1720 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1721 DBG_CHKOBJ( &rDevicePolyPoly, PolyPolygon, NULL );
1723 if ( rMapMode.IsDefault() )
1724 return rDevicePolyPoly;
1726 PolyPolygon aPolyPoly( rDevicePolyPoly );
1727 USHORT nPoly = aPolyPoly.Count();
1728 for( USHORT i = 0; i < nPoly; i++ )
1730 Polygon& rPoly = aPolyPoly[i];
1731 rPoly = PixelToLogic( rPoly, rMapMode );
1733 return aPolyPoly;
1736 // -----------------------------------------------------------------------
1738 Region OutputDevice::PixelToLogic( const Region& rDeviceRegion,
1739 const MapMode& rMapMode ) const
1741 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1742 DBG_CHKOBJ( &rDeviceRegion, Region, ImplDbgTestRegion );
1744 RegionType eType = rDeviceRegion.GetType();
1746 if ( rMapMode.IsDefault() || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
1747 return rDeviceRegion;
1749 Region aRegion;
1750 PolyPolygon* pPolyPoly = rDeviceRegion.ImplGetImplRegion()->mpPolyPoly;
1752 if ( pPolyPoly )
1753 aRegion = Region( PixelToLogic( *pPolyPoly, rMapMode ) );
1754 else
1756 long nX;
1757 long nY;
1758 long nWidth;
1759 long nHeight;
1760 ImplRegionInfo aInfo;
1761 BOOL bRegionRect;
1763 aRegion.ImplBeginAddRect();
1764 bRegionRect = rDeviceRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
1765 while ( bRegionRect )
1767 Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
1768 aRegion.ImplAddRect( PixelToLogic( aRect, rMapMode ) );
1769 bRegionRect = rDeviceRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
1771 aRegion.ImplEndAddRect();
1774 return aRegion;
1777 // -----------------------------------------------------------------------
1779 #define ENTER0( rSource, pMapModeSource, pMapModeDest ) \
1780 if ( !pMapModeSource ) \
1781 pMapModeSource = &maMapMode; \
1782 if ( !pMapModeDest ) \
1783 pMapModeDest = &maMapMode; \
1784 if ( *pMapModeSource == *pMapModeDest ) \
1785 return rSource
1787 // -----------------------------------------------------------------------
1789 #define ENTER1( rSource, pMapModeSource, pMapModeDest ) \
1790 ENTER0( rSource, pMapModeSource, pMapModeDest ); \
1792 ImplMapRes aMapResSource; \
1793 ImplMapRes aMapResDest; \
1795 if ( !mbMap || pMapModeSource != &maMapMode ) \
1797 if ( pMapModeSource->GetMapUnit() == MAP_RELATIVE ) \
1798 aMapResSource = maMapRes; \
1799 ImplCalcMapResolution( *pMapModeSource, \
1800 mnDPIX, mnDPIY, aMapResSource ); \
1802 else \
1803 aMapResSource = maMapRes; \
1804 if ( !mbMap || pMapModeDest != &maMapMode ) \
1806 if ( pMapModeDest->GetMapUnit() == MAP_RELATIVE ) \
1807 aMapResDest = maMapRes; \
1808 ImplCalcMapResolution( *pMapModeDest, \
1809 mnDPIX, mnDPIY, aMapResDest ); \
1811 else \
1812 aMapResDest = maMapRes
1814 // -----------------------------------------------------------------------
1816 #define ENTER2( eUnitSource, eUnitDest ) \
1817 DBG_ASSERT( eUnitSource != MAP_SYSFONT \
1818 && eUnitSource != MAP_APPFONT \
1819 && eUnitSource != MAP_RELATIVE, \
1820 "Source MapUnit nicht erlaubt" ); \
1821 DBG_ASSERT( eUnitDest != MAP_SYSFONT \
1822 && eUnitDest != MAP_APPFONT \
1823 && eUnitDest != MAP_RELATIVE, \
1824 "Destination MapUnit nicht erlaubt" ); \
1825 DBG_ASSERTWARNING( eUnitSource != MAP_PIXEL, \
1826 "MAP_PIXEL mit 72dpi angenaehert" ); \
1827 DBG_ASSERTWARNING( eUnitDest != MAP_PIXEL, \
1828 "MAP_PIXEL mit 72dpi angenaehert" )
1830 // -----------------------------------------------------------------------
1832 #define ENTER3( eUnitSource, eUnitDest ) \
1833 long nNumerator = 1; \
1834 long nDenominator = 1; \
1835 DBG_ASSERT( eUnitSource < MAP_LASTENUMDUMMY, "Invalid source map unit"); \
1836 DBG_ASSERT( eUnitDest < MAP_LASTENUMDUMMY, "Invalid destination map unit"); \
1837 if( (eUnitSource < MAP_LASTENUMDUMMY) && (eUnitDest < MAP_LASTENUMDUMMY) ) \
1839 nNumerator = aImplNumeratorAry[eUnitSource] * \
1840 aImplDenominatorAry[eUnitDest]; \
1841 nDenominator = aImplNumeratorAry[eUnitDest] * \
1842 aImplDenominatorAry[eUnitSource]; \
1844 if ( eUnitSource == MAP_PIXEL ) \
1845 nDenominator *= 72; \
1846 else if( eUnitDest == MAP_PIXEL ) \
1847 nNumerator *= 72
1849 // -----------------------------------------------------------------------
1851 #define ENTER4( rMapModeSource, rMapModeDest ) \
1852 ImplMapRes aMapResSource; \
1853 ImplMapRes aMapResDest; \
1855 ImplCalcMapResolution( rMapModeSource, 72, 72, aMapResSource ); \
1856 ImplCalcMapResolution( rMapModeDest, 72, 72, aMapResDest )
1858 // -----------------------------------------------------------------------
1860 // return (n1 * n2 * n3) / (n4 * n5)
1861 static long fn5( const long n1,
1862 const long n2,
1863 const long n3,
1864 const long n4,
1865 const long n5 )
1867 if ( n1 == 0 || n2 == 0 || n3 == 0 || n4 == 0 || n5 == 0 )
1868 return 0;
1869 if ( LONG_MAX / Abs(n2) < Abs(n3) )
1871 // a6 wird "ubersprungen
1872 BigInt a7 = n2;
1873 a7 *= n3;
1874 a7 *= n1;
1876 if ( LONG_MAX / Abs(n4) < Abs(n5) )
1878 BigInt a8 = n4;
1879 a8 *= n5;
1881 BigInt a9 = a8;
1882 a9 /= 2;
1883 if ( a7.IsNeg() )
1884 a7 -= a9;
1885 else
1886 a7 += a9;
1888 a7 /= a8;
1889 } // of if
1890 else
1892 long n8 = n4 * n5;
1894 if ( a7.IsNeg() )
1895 a7 -= n8 / 2;
1896 else
1897 a7 += n8 / 2;
1899 a7 /= n8;
1900 } // of else
1901 return (long)a7;
1902 } // of if
1903 else
1905 long n6 = n2 * n3;
1907 if ( LONG_MAX / Abs(n1) < Abs(n6) )
1909 BigInt a7 = n1;
1910 a7 *= n6;
1912 if ( LONG_MAX / Abs(n4) < Abs(n5) )
1914 BigInt a8 = n4;
1915 a8 *= n5;
1917 BigInt a9 = a8;
1918 a9 /= 2;
1919 if ( a7.IsNeg() )
1920 a7 -= a9;
1921 else
1922 a7 += a9;
1924 a7 /= a8;
1925 } // of if
1926 else
1928 long n8 = n4 * n5;
1930 if ( a7.IsNeg() )
1931 a7 -= n8 / 2;
1932 else
1933 a7 += n8 / 2;
1935 a7 /= n8;
1936 } // of else
1937 return (long)a7;
1938 } // of if
1939 else
1941 long n7 = n1 * n6;
1943 if ( LONG_MAX / Abs(n4) < Abs(n5) )
1945 BigInt a7 = n7;
1946 BigInt a8 = n4;
1947 a8 *= n5;
1949 BigInt a9 = a8;
1950 a9 /= 2;
1951 if ( a7.IsNeg() )
1952 a7 -= a9;
1953 else
1954 a7 += a9;
1956 a7 /= a8;
1957 return (long)a7;
1958 } // of if
1959 else
1961 const long n8 = n4 * n5;
1962 const long n8_2 = n8 / 2;
1964 if( n7 < 0 )
1966 if( ( n7 - LONG_MIN ) >= n8_2 )
1967 n7 -= n8_2;
1969 else if( ( LONG_MAX - n7 ) >= n8_2 )
1970 n7 += n8_2;
1972 return n7 / n8;
1973 } // of else
1974 } // of else
1975 } // of else
1978 // -----------------------------------------------------------------------
1980 // return (n1 * n2) / n3
1981 static long fn3( const long n1, const long n2, const long n3 )
1983 if ( n1 == 0 || n2 == 0 || n3 == 0 )
1984 return 0;
1985 if ( LONG_MAX / Abs(n1) < Abs(n2) )
1987 BigInt a4 = n1;
1988 a4 *= n2;
1990 if ( a4.IsNeg() )
1991 a4 -= n3 / 2;
1992 else
1993 a4 += n3 / 2;
1995 a4 /= n3;
1996 return (long)a4;
1997 } // of if
1998 else
2000 long n4 = n1 * n2;
2001 const long n3_2 = n3 / 2;
2003 if( n4 < 0 )
2005 if( ( n4 - LONG_MIN ) >= n3_2 )
2006 n4 -= n3_2;
2008 else if( ( LONG_MAX - n4 ) >= n3_2 )
2009 n4 += n3_2;
2011 return n4 / n3;
2012 } // of else
2015 // -----------------------------------------------------------------------
2017 Point OutputDevice::LogicToLogic( const Point& rPtSource,
2018 const MapMode* pMapModeSource,
2019 const MapMode* pMapModeDest ) const
2021 ENTER1( rPtSource, pMapModeSource, pMapModeDest );
2023 return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
2024 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2025 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2026 aMapResDest.mnMapOfsX,
2027 fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
2028 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2029 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2030 aMapResDest.mnMapOfsY );
2033 // -----------------------------------------------------------------------
2035 Size OutputDevice::LogicToLogic( const Size& rSzSource,
2036 const MapMode* pMapModeSource,
2037 const MapMode* pMapModeDest ) const
2039 ENTER1( rSzSource, pMapModeSource, pMapModeDest );
2041 return Size( fn5( rSzSource.Width(),
2042 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2043 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
2044 fn5( rSzSource.Height(),
2045 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2046 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
2049 // -----------------------------------------------------------------------
2051 Rectangle OutputDevice::LogicToLogic( const Rectangle& rRectSource,
2052 const MapMode* pMapModeSource,
2053 const MapMode* pMapModeDest ) const
2055 ENTER1( rRectSource, pMapModeSource, pMapModeDest );
2057 return Rectangle( fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
2058 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2059 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2060 aMapResDest.mnMapOfsX,
2061 fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
2062 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2063 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2064 aMapResDest.mnMapOfsY,
2065 fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
2066 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2067 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2068 aMapResDest.mnMapOfsX,
2069 fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
2070 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2071 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2072 aMapResDest.mnMapOfsY );
2075 // -----------------------------------------------------------------------
2077 long* OutputDevice::LogicToLogic( long* pX, USHORT nCount,
2078 const MapMode* pMapModeSource,
2079 const MapMode* pMapModeDest ) const
2081 ENTER1( pX, pMapModeSource, pMapModeDest );
2083 for( ; nCount; nCount--, pX++ )
2085 *pX = fn5( *pX,
2086 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2087 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX );
2090 return NULL;
2093 // -----------------------------------------------------------------------
2095 Point OutputDevice::LogicToLogic( const Point& rPtSource,
2096 const MapMode& rMapModeSource,
2097 const MapMode& rMapModeDest )
2099 if ( rMapModeSource == rMapModeDest )
2100 return rPtSource;
2102 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
2103 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
2104 ENTER2( eUnitSource, eUnitDest );
2106 if ( rMapModeSource.mpImplMapMode->mbSimple &&
2107 rMapModeDest.mpImplMapMode->mbSimple )
2109 ENTER3( eUnitSource, eUnitDest );
2111 return Point( fn3( rPtSource.X(), nNumerator, nDenominator ),
2112 fn3( rPtSource.Y(), nNumerator, nDenominator ) );
2114 else
2116 ENTER4( rMapModeSource, rMapModeDest );
2118 return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
2119 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2120 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2121 aMapResDest.mnMapOfsX,
2122 fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
2123 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2124 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2125 aMapResDest.mnMapOfsY );
2129 // -----------------------------------------------------------------------
2131 Size OutputDevice::LogicToLogic( const Size& rSzSource,
2132 const MapMode& rMapModeSource,
2133 const MapMode& rMapModeDest )
2135 if ( rMapModeSource == rMapModeDest )
2136 return rSzSource;
2138 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
2139 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
2140 ENTER2( eUnitSource, eUnitDest );
2142 if ( rMapModeSource.mpImplMapMode->mbSimple &&
2143 rMapModeDest.mpImplMapMode->mbSimple )
2145 ENTER3( eUnitSource, eUnitDest );
2147 return Size( fn3( rSzSource.Width(), nNumerator, nDenominator ),
2148 fn3( rSzSource.Height(), nNumerator, nDenominator ) );
2150 else
2152 ENTER4( rMapModeSource, rMapModeDest );
2154 return Size( fn5( rSzSource.Width(),
2155 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2156 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
2157 fn5( rSzSource.Height(),
2158 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2159 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
2163 // -----------------------------------------------------------------------
2165 Rectangle OutputDevice::LogicToLogic( const Rectangle& rRectSource,
2166 const MapMode& rMapModeSource,
2167 const MapMode& rMapModeDest )
2169 if ( rMapModeSource == rMapModeDest )
2170 return rRectSource;
2172 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
2173 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
2174 ENTER2( eUnitSource, eUnitDest );
2176 if ( rMapModeSource.mpImplMapMode->mbSimple &&
2177 rMapModeDest.mpImplMapMode->mbSimple )
2179 ENTER3( eUnitSource, eUnitDest );
2181 return Rectangle( fn3( rRectSource.Left(), nNumerator, nDenominator ),
2182 fn3( rRectSource.Top(), nNumerator, nDenominator ),
2183 fn3( rRectSource.Right(), nNumerator, nDenominator ),
2184 fn3( rRectSource.Bottom(), nNumerator, nDenominator ) );
2186 else
2188 ENTER4( rMapModeSource, rMapModeDest );
2190 return Rectangle( fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
2191 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2192 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2193 aMapResDest.mnMapOfsX,
2194 fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
2195 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2196 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2197 aMapResDest.mnMapOfsY,
2198 fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
2199 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2200 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2201 aMapResDest.mnMapOfsX,
2202 fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
2203 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2204 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2205 aMapResDest.mnMapOfsY );
2209 // -----------------------------------------------------------------------
2211 long OutputDevice::LogicToLogic( long nLongSource,
2212 MapUnit eUnitSource, MapUnit eUnitDest )
2214 if ( eUnitSource == eUnitDest )
2215 return nLongSource;
2217 ENTER2( eUnitSource, eUnitDest );
2218 ENTER3( eUnitSource, eUnitDest );
2220 return fn3( nLongSource, nNumerator, nDenominator );
2223 // -----------------------------------------------------------------------
2225 void OutputDevice::SetPixelOffset( const Size& rOffset )
2227 mnOutOffOrigX = rOffset.Width();
2228 mnOutOffOrigY = rOffset.Height();
2230 mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
2231 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
2232 maThresRes.mnThresPixToLogX );
2233 mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
2234 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
2235 maThresRes.mnThresPixToLogY );
2237 if( mpAlphaVDev )
2238 mpAlphaVDev->SetPixelOffset( rOffset );
2241 // -----------------------------------------------------------------------
2243 Size OutputDevice::GetPixelOffset() const
2245 return Size(mnOutOffOrigX, mnOutOffOrigY);
2248 // -----------------------------------------------------------------------
2250 long Window::ImplLogicUnitToPixelX( long nX, MapUnit eUnit )
2252 if ( eUnit != MAP_PIXEL )
2254 ImplFrameData* pFrameData = mpWindowImpl->mpFrameData;
2256 // Map-Einheit verschieden, dann neu berechnen
2257 if ( pFrameData->meMapUnit != eUnit )
2259 pFrameData->meMapUnit = eUnit;
2260 ImplCalcMapResolution( MapMode( eUnit ), mnDPIX, mnDPIY,
2261 pFrameData->maMapUnitRes );
2264 // Es wird kein BigInt gebraucht, da diese Funktion nur zur Umrechnung
2265 // von Fensterposition benutzt wird
2266 nX = nX * mnDPIX * pFrameData->maMapUnitRes.mnMapScNumX;
2267 nX += nX >= 0 ? (pFrameData->maMapUnitRes.mnMapScDenomX/2) :
2268 -((pFrameData->maMapUnitRes.mnMapScDenomX-1)/2);
2269 nX /= pFrameData->maMapUnitRes.mnMapScDenomX;
2272 return nX;
2275 // -----------------------------------------------------------------------
2277 long Window::ImplLogicUnitToPixelY( long nY, MapUnit eUnit )
2279 if ( eUnit != MAP_PIXEL )
2281 ImplFrameData* pFrameData = mpWindowImpl->mpFrameData;
2283 // Map-Einheit verschieden, dann neu berechnen
2284 if ( pFrameData->meMapUnit != eUnit )
2286 pFrameData->meMapUnit = eUnit;
2287 ImplCalcMapResolution( MapMode( eUnit ), mnDPIX, mnDPIY,
2288 pFrameData->maMapUnitRes );
2291 // Es wird kein BigInt gebraucht, da diese Funktion nur zur Umrechnung
2292 // von Fensterposition benutzt wird
2293 nY = nY * mnDPIY * pFrameData->maMapUnitRes.mnMapScNumY;
2294 nY += nY >= 0 ? (pFrameData->maMapUnitRes.mnMapScDenomY/2) :
2295 -((pFrameData->maMapUnitRes.mnMapScDenomY-1)/2);
2296 nY /= pFrameData->maMapUnitRes.mnMapScDenomY;
2299 return nY;