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