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