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