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