update credits
[LibreOffice.git] / vcl / source / gdi / outmap.cxx
blobed02ae0634601c3076373eb708cb3611d05aa719
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <limits.h>
23 #include <tools/bigint.hxx>
24 #include <tools/debug.hxx>
25 #include <tools/poly.hxx>
27 #include <vcl/virdev.hxx>
28 #include <vcl/region.hxx>
29 #include <vcl/wrkwin.hxx>
30 #include <vcl/cursor.hxx>
31 #include <vcl/metaact.hxx>
32 #include <vcl/gdimtf.hxx>
33 #include <vcl/lineinfo.hxx>
34 #include <vcl/outdev.hxx>
36 #include <svdata.hxx>
37 #include <region.h>
38 #include <window.h>
39 #include <outdev.h>
40 #include <salgdi.hxx>
42 #include <basegfx/matrix/b2dhommatrix.hxx>
43 #include <basegfx/polygon/b2dpolygon.hxx>
44 #include <basegfx/polygon/b2dpolypolygon.hxx>
46 // =======================================================================
48 DBG_NAMEEX( OutputDevice )
49 DBG_NAMEEX( Polygon )
50 DBG_NAMEEX( PolyPolygon )
51 DBG_NAMEEX( Region )
53 // =======================================================================
55 static int const s_ImplArySize = MAP_PIXEL+1;
56 static long aImplNumeratorAry[s_ImplArySize] =
57 { 1, 1, 5, 50, 1, 1, 1, 1, 1, 1, 1 };
58 static long aImplDenominatorAry[s_ImplArySize] =
59 { 2540, 254, 127, 127, 1000, 100, 10, 1, 72, 1440, 1 };
61 // -----------------------------------------------------------------------
64 Reduziert die Genauigkeit bis eine Fraction draus wird (sollte mal
65 ein Fraction ctor werden) koennte man dann auch mit BigInts machen
68 static Fraction ImplMakeFraction( long nN1, long nN2, long nD1, long nD2 )
70 long i = 1;
72 if ( nN1 < 0 ) { i = -i; nN1 = -nN1; }
73 if ( nN2 < 0 ) { i = -i; nN2 = -nN2; }
74 if ( nD1 < 0 ) { i = -i; nD1 = -nD1; }
75 if ( nD2 < 0 ) { i = -i; nD2 = -nD2; }
76 // alle positiv; i Vorzeichen
78 Fraction aF( i*nN1, nD1 );
79 aF *= Fraction( nN2, nD2 );
81 if( nD1 == 0 || nD2 == 0 ) //under these bad circumstances the following while loop will be endless
83 DBG_ASSERT(false,"Invalid parameter for ImplMakeFraction");
84 return Fraction( 1, 1 );
87 while ( aF.GetDenominator() == -1 )
89 if ( nN1 > nN2 )
90 nN1 = (nN1 + 1) / 2;
91 else
92 nN2 = (nN2 + 1) / 2;
93 if ( nD1 > nD2 )
94 nD1 = (nD1 + 1) / 2;
95 else
96 nD2 = (nD2 + 1) / 2;
98 aF = Fraction( i*nN1, nD1 );
99 aF *= Fraction( nN2, nD2 );
102 return aF;
105 // -----------------------------------------------------------------------
107 // Fraction.GetNumerator()
108 // Fraction.GetDenominator() > 0
109 // rOutRes.nPixPerInch? > 0
110 // rMapRes.nMapScNum?
111 // rMapRes.nMapScDenom? > 0
113 static void ImplCalcBigIntThreshold( long nDPIX, long nDPIY,
114 const ImplMapRes& rMapRes,
115 ImplThresholdRes& rThresRes )
117 if ( nDPIX && (LONG_MAX / nDPIX < std::abs( rMapRes.mnMapScNumX ) ) ) // #111139# avoid div by zero
119 rThresRes.mnThresLogToPixX = 0;
120 rThresRes.mnThresPixToLogX = 0;
122 else
124 // Schwellenwerte fuer BigInt Arithmetik berechnen
125 long nDenomHalfX = rMapRes.mnMapScDenomX / 2;
126 sal_uLong nDenomX = rMapRes.mnMapScDenomX;
127 long nProductX = nDPIX * rMapRes.mnMapScNumX;
129 if ( !nProductX )
130 rThresRes.mnThresLogToPixX = LONG_MAX;
131 else
132 rThresRes.mnThresLogToPixX = std::abs( (LONG_MAX - nDenomHalfX) / nProductX );
134 if ( !nDenomX )
135 rThresRes.mnThresPixToLogX = LONG_MAX;
136 else if ( nProductX >= 0 )
137 rThresRes.mnThresPixToLogX = (long)(((sal_uLong)LONG_MAX - (sal_uLong)( nProductX/2)) / nDenomX);
138 else
139 rThresRes.mnThresPixToLogX = (long)(((sal_uLong)LONG_MAX + (sal_uLong)(-nProductX/2)) / nDenomX);
142 if ( nDPIY && (LONG_MAX / nDPIY < std::abs( rMapRes.mnMapScNumY ) ) ) // #111139# avoid div by zero
144 rThresRes.mnThresLogToPixY = 0;
145 rThresRes.mnThresPixToLogY = 0;
147 else
149 // Schwellenwerte fuer BigInt Arithmetik berechnen
150 long nDenomHalfY = rMapRes.mnMapScDenomY / 2;
151 sal_uLong nDenomY = rMapRes.mnMapScDenomY;
152 long nProductY = nDPIY * rMapRes.mnMapScNumY;
154 if ( !nProductY )
155 rThresRes.mnThresLogToPixY = LONG_MAX;
156 else
157 rThresRes.mnThresLogToPixY = std::abs( (LONG_MAX - nDenomHalfY) / nProductY );
159 if ( !nDenomY )
160 rThresRes.mnThresPixToLogY = LONG_MAX;
161 else if ( nProductY >= 0 )
162 rThresRes.mnThresPixToLogY = (long)(((sal_uLong)LONG_MAX - (sal_uLong)( nProductY/2)) / nDenomY);
163 else
164 rThresRes.mnThresPixToLogY = (long)(((sal_uLong)LONG_MAX + (sal_uLong)(-nProductY/2)) / nDenomY);
167 rThresRes.mnThresLogToPixX /= 2;
168 rThresRes.mnThresLogToPixY /= 2;
169 rThresRes.mnThresPixToLogX /= 2;
170 rThresRes.mnThresPixToLogY /= 2;
173 // -----------------------------------------------------------------------
175 static void ImplCalcMapResolution( const MapMode& rMapMode,
176 long nDPIX, long nDPIY, ImplMapRes& rMapRes )
178 switch ( rMapMode.GetMapUnit() )
180 case MAP_RELATIVE:
181 break;
182 case MAP_100TH_MM:
183 rMapRes.mnMapScNumX = 1;
184 rMapRes.mnMapScDenomX = 2540;
185 rMapRes.mnMapScNumY = 1;
186 rMapRes.mnMapScDenomY = 2540;
187 break;
188 case MAP_10TH_MM:
189 rMapRes.mnMapScNumX = 1;
190 rMapRes.mnMapScDenomX = 254;
191 rMapRes.mnMapScNumY = 1;
192 rMapRes.mnMapScDenomY = 254;
193 break;
194 case MAP_MM:
195 rMapRes.mnMapScNumX = 5; // 10
196 rMapRes.mnMapScDenomX = 127; // 254
197 rMapRes.mnMapScNumY = 5; // 10
198 rMapRes.mnMapScDenomY = 127; // 254
199 break;
200 case MAP_CM:
201 rMapRes.mnMapScNumX = 50; // 100
202 rMapRes.mnMapScDenomX = 127; // 254
203 rMapRes.mnMapScNumY = 50; // 100
204 rMapRes.mnMapScDenomY = 127; // 254
205 break;
206 case MAP_1000TH_INCH:
207 rMapRes.mnMapScNumX = 1;
208 rMapRes.mnMapScDenomX = 1000;
209 rMapRes.mnMapScNumY = 1;
210 rMapRes.mnMapScDenomY = 1000;
211 break;
212 case MAP_100TH_INCH:
213 rMapRes.mnMapScNumX = 1;
214 rMapRes.mnMapScDenomX = 100;
215 rMapRes.mnMapScNumY = 1;
216 rMapRes.mnMapScDenomY = 100;
217 break;
218 case MAP_10TH_INCH:
219 rMapRes.mnMapScNumX = 1;
220 rMapRes.mnMapScDenomX = 10;
221 rMapRes.mnMapScNumY = 1;
222 rMapRes.mnMapScDenomY = 10;
223 break;
224 case MAP_INCH:
225 rMapRes.mnMapScNumX = 1;
226 rMapRes.mnMapScDenomX = 1;
227 rMapRes.mnMapScNumY = 1;
228 rMapRes.mnMapScDenomY = 1;
229 break;
230 case MAP_POINT:
231 rMapRes.mnMapScNumX = 1;
232 rMapRes.mnMapScDenomX = 72;
233 rMapRes.mnMapScNumY = 1;
234 rMapRes.mnMapScDenomY = 72;
235 break;
236 case MAP_TWIP:
237 rMapRes.mnMapScNumX = 1;
238 rMapRes.mnMapScDenomX = 1440;
239 rMapRes.mnMapScNumY = 1;
240 rMapRes.mnMapScDenomY = 1440;
241 break;
242 case MAP_PIXEL:
243 rMapRes.mnMapScNumX = 1;
244 rMapRes.mnMapScDenomX = nDPIX;
245 rMapRes.mnMapScNumY = 1;
246 rMapRes.mnMapScDenomY = nDPIY;
247 break;
248 case MAP_SYSFONT:
249 case MAP_APPFONT:
250 case MAP_REALAPPFONT:
252 ImplSVData* pSVData = ImplGetSVData();
253 if ( !pSVData->maGDIData.mnAppFontX )
255 if( pSVData->maWinData.mpFirstFrame )
256 Window::ImplInitAppFontData( pSVData->maWinData.mpFirstFrame );
257 else
259 WorkWindow* pWin = new WorkWindow( NULL, 0 );
260 Window::ImplInitAppFontData( pWin );
261 delete pWin;
264 if ( rMapMode.GetMapUnit() == MAP_REALAPPFONT )
265 rMapRes.mnMapScNumX = pSVData->maGDIData.mnRealAppFontX;
266 else
267 rMapRes.mnMapScNumX = pSVData->maGDIData.mnAppFontX;
268 rMapRes.mnMapScDenomX = nDPIX * 40;
269 rMapRes.mnMapScNumY = pSVData->maGDIData.mnAppFontY;
270 rMapRes.mnMapScDenomY = nDPIY * 80;
272 break;
273 default:
274 OSL_FAIL( "unhandled MapUnit" );
275 break;
278 Fraction aScaleX = rMapMode.GetScaleX();
279 Fraction aScaleY = rMapMode.GetScaleY();
281 // Offset laut MapMode setzen
282 Point aOrigin = rMapMode.GetOrigin();
283 if ( rMapMode.GetMapUnit() != MAP_RELATIVE )
285 rMapRes.mnMapOfsX = aOrigin.X();
286 rMapRes.mnMapOfsY = aOrigin.Y();
288 else
290 BigInt aX( rMapRes.mnMapOfsX );
291 aX *= BigInt( aScaleX.GetDenominator() );
292 if ( rMapRes.mnMapOfsX >= 0 )
294 if ( aScaleX.GetNumerator() >= 0 )
295 aX += BigInt( aScaleX.GetNumerator()/2 );
296 else
297 aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
299 else
301 if ( aScaleX.GetNumerator() >= 0 )
302 aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
303 else
304 aX += BigInt( aScaleX.GetNumerator()/2 );
306 aX /= BigInt( aScaleX.GetNumerator() );
307 rMapRes.mnMapOfsX = (long)aX + aOrigin.X();
308 BigInt aY( rMapRes.mnMapOfsY );
309 aY *= BigInt( aScaleY.GetDenominator() );
310 if( rMapRes.mnMapOfsY >= 0 )
312 if ( aScaleY.GetNumerator() >= 0 )
313 aY += BigInt( aScaleY.GetNumerator()/2 );
314 else
315 aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
317 else
319 if ( aScaleY.GetNumerator() >= 0 )
320 aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
321 else
322 aY += BigInt( aScaleY.GetNumerator()/2 );
324 aY /= BigInt( aScaleY.GetNumerator() );
325 rMapRes.mnMapOfsY = (long)aY + aOrigin.Y();
328 // Scaling Faktor laut MapMode einberechnen
329 // aTemp? = rMapRes.mnMapSc? * aScale?
330 Fraction aTempX = ImplMakeFraction( rMapRes.mnMapScNumX,
331 aScaleX.GetNumerator(),
332 rMapRes.mnMapScDenomX,
333 aScaleX.GetDenominator() );
334 Fraction aTempY = ImplMakeFraction( rMapRes.mnMapScNumY,
335 aScaleY.GetNumerator(),
336 rMapRes.mnMapScDenomY,
337 aScaleY.GetDenominator() );
338 rMapRes.mnMapScNumX = aTempX.GetNumerator();
339 rMapRes.mnMapScDenomX = aTempX.GetDenominator();
340 rMapRes.mnMapScNumY = aTempY.GetNumerator();
341 rMapRes.mnMapScDenomY = aTempY.GetDenominator();
343 // hack: 0/n ungef"ahr 1/max
344 if ( !rMapRes.mnMapScNumX )
346 rMapRes.mnMapScNumX = 1;
347 rMapRes.mnMapScDenomX = LONG_MAX;
349 if ( !rMapRes.mnMapScNumY )
351 rMapRes.mnMapScNumY = 1;
352 rMapRes.mnMapScDenomY = LONG_MAX;
356 // -----------------------------------------------------------------------
358 inline void ImplCalcMapResolution( const MapMode& rMapMode,
359 long nDPIX, long nDPIY,
360 ImplMapRes& rMapRes,
361 ImplThresholdRes& rThresRes )
363 ImplCalcMapResolution( rMapMode, nDPIX, nDPIY, rMapRes );
364 ImplCalcBigIntThreshold( nDPIX, nDPIY, rMapRes, rThresRes );
367 // -----------------------------------------------------------------------
369 static long ImplLogicToPixel( long n, long nDPI, long nMapNum, long nMapDenom,
370 long nThres )
372 // To "use" it...
373 (void) nThres;
374 #if (SAL_TYPES_SIZEOFLONG < 8)
375 if( (+n < nThres) && (-n < nThres) )
377 n *= nMapNum * nDPI;
378 if( nMapDenom != 1 )
380 n = (2 * n) / nMapDenom;
381 if( n < 0 ) --n; else ++n;
382 n /= 2;
385 else
386 #endif
388 sal_Int64 n64 = n;
389 n64 *= nMapNum;
390 n64 *= nDPI;
391 if( nMapDenom == 1 )
392 n = (long)n64;
393 else
395 n = (long)(2 * n64 / nMapDenom);
396 if( n < 0 ) --n; else ++n;
397 n /= 2;
400 return n;
403 // -----------------------------------------------------------------------
405 static long ImplPixelToLogic( long n, long nDPI, long nMapNum, long nMapDenom,
406 long nThres )
408 // To "use" it...
409 (void) nThres;
410 #if (SAL_TYPES_SIZEOFLONG < 8)
411 if( (+n < nThres) && (-n < nThres) )
412 n = (2 * n * nMapDenom) / (nDPI * nMapNum);
413 else
414 #endif
416 sal_Int64 n64 = n;
417 n64 *= nMapDenom;
418 long nDenom = nDPI * nMapNum;
419 n = (long)(2 * n64 / nDenom);
421 if( n < 0 ) --n; else ++n;
422 return (n / 2);
425 // -----------------------------------------------------------------------
427 long OutputDevice::ImplLogicXToDevicePixel( long nX ) const
429 if ( !mbMap )
430 return nX+mnOutOffX;
432 return ImplLogicToPixel( nX + maMapRes.mnMapOfsX, mnDPIX,
433 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
434 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX;
437 // -----------------------------------------------------------------------
439 long OutputDevice::ImplLogicYToDevicePixel( long nY ) const
441 if ( !mbMap )
442 return nY+mnOutOffY;
444 return ImplLogicToPixel( nY + maMapRes.mnMapOfsY, mnDPIY,
445 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
446 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY;
449 // -----------------------------------------------------------------------
451 long OutputDevice::ImplLogicWidthToDevicePixel( long nWidth ) const
453 if ( !mbMap )
454 return nWidth;
456 return ImplLogicToPixel( nWidth, mnDPIX,
457 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
458 maThresRes.mnThresLogToPixX );
461 // -----------------------------------------------------------------------
463 long OutputDevice::ImplLogicHeightToDevicePixel( long nHeight ) const
465 if ( !mbMap )
466 return nHeight;
468 return ImplLogicToPixel( nHeight, mnDPIY,
469 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
470 maThresRes.mnThresLogToPixY );
473 float OutputDevice::ImplFloatLogicHeightToDevicePixel( float fLogicHeight) const
475 if( !mbMap)
476 return fLogicHeight;
477 float fPixelHeight = (fLogicHeight * mnDPIY * maMapRes.mnMapScNumY) / maMapRes.mnMapScDenomY;
478 return fPixelHeight;
481 // -----------------------------------------------------------------------
483 long OutputDevice::ImplDevicePixelToLogicWidth( long nWidth ) const
485 if ( !mbMap )
486 return nWidth;
488 return ImplPixelToLogic( nWidth, mnDPIX,
489 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
490 maThresRes.mnThresPixToLogX );
493 // -----------------------------------------------------------------------
495 long OutputDevice::ImplDevicePixelToLogicHeight( long nHeight ) const
497 if ( !mbMap )
498 return nHeight;
500 return ImplPixelToLogic( nHeight, mnDPIY,
501 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
502 maThresRes.mnThresPixToLogY );
505 // -----------------------------------------------------------------------
507 Point OutputDevice::ImplLogicToDevicePixel( const Point& rLogicPt ) const
509 if ( !mbMap )
510 return Point( rLogicPt.X()+mnOutOffX, rLogicPt.Y()+mnOutOffY );
512 return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
513 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
514 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX,
515 ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
516 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
517 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY );
520 // -----------------------------------------------------------------------
522 Size OutputDevice::ImplLogicToDevicePixel( const Size& rLogicSize ) const
524 if ( !mbMap )
525 return rLogicSize;
527 return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
528 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
529 maThresRes.mnThresLogToPixX ),
530 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
531 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
532 maThresRes.mnThresLogToPixY ) );
535 // -----------------------------------------------------------------------
537 Rectangle OutputDevice::ImplLogicToDevicePixel( const Rectangle& rLogicRect ) const
539 if ( rLogicRect.IsEmpty() )
540 return rLogicRect;
542 if ( !mbMap )
544 return Rectangle( rLogicRect.Left()+mnOutOffX, rLogicRect.Top()+mnOutOffY,
545 rLogicRect.Right()+mnOutOffX, rLogicRect.Bottom()+mnOutOffY );
548 return Rectangle( ImplLogicToPixel( rLogicRect.Left()+maMapRes.mnMapOfsX, mnDPIX,
549 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
550 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX,
551 ImplLogicToPixel( rLogicRect.Top()+maMapRes.mnMapOfsY, mnDPIY,
552 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
553 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY,
554 ImplLogicToPixel( rLogicRect.Right()+maMapRes.mnMapOfsX, mnDPIX,
555 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
556 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX,
557 ImplLogicToPixel( rLogicRect.Bottom()+maMapRes.mnMapOfsY, mnDPIY,
558 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
559 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY );
562 // -----------------------------------------------------------------------
564 Polygon OutputDevice::ImplLogicToDevicePixel( const Polygon& rLogicPoly ) const
566 if ( !mbMap && !mnOutOffX && !mnOutOffY )
567 return rLogicPoly;
569 sal_uInt16 i;
570 sal_uInt16 nPoints = rLogicPoly.GetSize();
571 Polygon aPoly( rLogicPoly );
573 // Pointer auf das Point-Array holen (Daten werden kopiert)
574 const Point* pPointAry = aPoly.GetConstPointAry();
576 if ( mbMap )
578 for ( i = 0; i < nPoints; i++ )
580 const Point* pPt = &(pPointAry[i]);
581 Point aPt;
582 aPt.X() = ImplLogicToPixel( pPt->X()+maMapRes.mnMapOfsX, mnDPIX,
583 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
584 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX;
585 aPt.Y() = ImplLogicToPixel( pPt->Y()+maMapRes.mnMapOfsY, mnDPIY,
586 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
587 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY;
588 aPoly[i] = aPt;
591 else
593 for ( i = 0; i < nPoints; i++ )
595 Point aPt = pPointAry[i];
596 aPt.X() += mnOutOffX;
597 aPt.Y() += mnOutOffY;
598 aPoly[i] = aPt;
602 return aPoly;
605 // -----------------------------------------------------------------------
607 PolyPolygon OutputDevice::ImplLogicToDevicePixel( const PolyPolygon& rLogicPolyPoly ) const
609 if ( !mbMap && !mnOutOffX && !mnOutOffY )
610 return rLogicPolyPoly;
612 PolyPolygon aPolyPoly( rLogicPolyPoly );
613 sal_uInt16 nPoly = aPolyPoly.Count();
614 for( sal_uInt16 i = 0; i < nPoly; i++ )
616 Polygon& rPoly = aPolyPoly[i];
617 rPoly = ImplLogicToDevicePixel( rPoly );
619 return aPolyPoly;
622 // -----------------------------------------------------------------------
624 LineInfo OutputDevice::ImplLogicToDevicePixel( const LineInfo& rLineInfo ) const
626 LineInfo aInfo( rLineInfo );
628 if( aInfo.GetStyle() == LINE_DASH )
630 if( aInfo.GetDotCount() && aInfo.GetDotLen() )
631 aInfo.SetDotLen( std::max( ImplLogicWidthToDevicePixel( aInfo.GetDotLen() ), 1L ) );
632 else
633 aInfo.SetDotCount( 0 );
635 if( aInfo.GetDashCount() && aInfo.GetDashLen() )
636 aInfo.SetDashLen( std::max( ImplLogicWidthToDevicePixel( aInfo.GetDashLen() ), 1L ) );
637 else
638 aInfo.SetDashCount( 0 );
640 aInfo.SetDistance( ImplLogicWidthToDevicePixel( aInfo.GetDistance() ) );
642 if( ( !aInfo.GetDashCount() && !aInfo.GetDotCount() ) || !aInfo.GetDistance() )
643 aInfo.SetStyle( LINE_SOLID );
646 aInfo.SetWidth( ImplLogicWidthToDevicePixel( aInfo.GetWidth() ) );
648 return aInfo;
651 // -----------------------------------------------------------------------
653 Rectangle OutputDevice::ImplDevicePixelToLogic( const Rectangle& rPixelRect ) const
655 if ( rPixelRect.IsEmpty() )
656 return rPixelRect;
658 if ( !mbMap )
660 return Rectangle( rPixelRect.Left()-mnOutOffX, rPixelRect.Top()-mnOutOffY,
661 rPixelRect.Right()-mnOutOffX, rPixelRect.Bottom()-mnOutOffY );
664 return Rectangle( ImplPixelToLogic( rPixelRect.Left()-mnOutOffX-mnOutOffOrigX, mnDPIX,
665 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
666 maThresRes.mnThresPixToLogX )-maMapRes.mnMapOfsX,
667 ImplPixelToLogic( rPixelRect.Top()-mnOutOffY-mnOutOffOrigY, mnDPIY,
668 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
669 maThresRes.mnThresPixToLogY )-maMapRes.mnMapOfsY,
670 ImplPixelToLogic( rPixelRect.Right()-mnOutOffX-mnOutOffOrigX, mnDPIX,
671 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
672 maThresRes.mnThresPixToLogX )-maMapRes.mnMapOfsX,
673 ImplPixelToLogic( rPixelRect.Bottom()-mnOutOffY-mnOutOffOrigY, mnDPIY,
674 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
675 maThresRes.mnThresPixToLogY )-maMapRes.mnMapOfsY );
678 // -----------------------------------------------------------------------
680 Region OutputDevice::ImplPixelToDevicePixel( const Region& rRegion ) const
682 DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
684 if ( !mnOutOffX && !mnOutOffY )
685 return rRegion;
687 Region aRegion( rRegion );
688 aRegion.Move( mnOutOffX+mnOutOffOrigX, mnOutOffY+mnOutOffOrigY );
689 return aRegion;
692 // -----------------------------------------------------------------------
694 void OutputDevice::EnableMapMode( sal_Bool bEnable )
696 mbMap = (bEnable != 0);
698 if( mpAlphaVDev )
699 mpAlphaVDev->EnableMapMode( bEnable );
702 // -----------------------------------------------------------------------
704 void OutputDevice::SetMapMode()
706 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
708 if ( mpMetaFile )
709 mpMetaFile->AddAction( new MetaMapModeAction( MapMode() ) );
711 if ( mbMap || !maMapMode.IsDefault() )
713 mbMap = sal_False;
714 maMapMode = MapMode();
716 // create new objects (clip region werden nicht neu skaliert)
717 mbNewFont = sal_True;
718 mbInitFont = sal_True;
719 if ( GetOutDevType() == OUTDEV_WINDOW )
721 if ( ((Window*)this)->mpWindowImpl->mpCursor )
722 ((Window*)this)->mpWindowImpl->mpCursor->ImplNew();
725 // #106426# Adapt logical offset when changing mapmode
726 mnOutOffLogicX = mnOutOffOrigX; // no mapping -> equal offsets
727 mnOutOffLogicY = mnOutOffOrigY;
729 // #i75163#
730 ImplInvalidateViewTransform();
733 if( mpAlphaVDev )
734 mpAlphaVDev->SetMapMode();
737 // -----------------------------------------------------------------------
739 void OutputDevice::SetMapMode( const MapMode& rNewMapMode )
741 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
743 sal_Bool bRelMap = (rNewMapMode.GetMapUnit() == MAP_RELATIVE);
745 if ( mpMetaFile )
747 mpMetaFile->AddAction( new MetaMapModeAction( rNewMapMode ) );
748 #ifdef DBG_UTIL
749 if ( GetOutDevType() != OUTDEV_PRINTER )
750 DBG_ASSERTWARNING( bRelMap, "Please record only relative MapModes!" );
751 #endif
754 // Ist der MapMode der gleiche wie vorher, dann mache nichts
755 if ( maMapMode == rNewMapMode )
756 return;
758 if( mpAlphaVDev )
759 mpAlphaVDev->SetMapMode( rNewMapMode );
761 // Ist Default-MapMode, dann bereche nichts
762 sal_Bool bOldMap = mbMap;
763 mbMap = !rNewMapMode.IsDefault();
764 if ( mbMap )
766 // Falls nur der Orign umgesetzt wird, dann scaliere nichts neu
767 if ( (rNewMapMode.GetMapUnit() == maMapMode.GetMapUnit()) &&
768 (rNewMapMode.GetScaleX() == maMapMode.GetScaleX()) &&
769 (rNewMapMode.GetScaleY() == maMapMode.GetScaleY()) &&
770 (bOldMap == mbMap) )
772 // Offset setzen
773 Point aOrigin = rNewMapMode.GetOrigin();
774 maMapRes.mnMapOfsX = aOrigin.X();
775 maMapRes.mnMapOfsY = aOrigin.Y();
776 maMapMode = rNewMapMode;
778 // #i75163#
779 ImplInvalidateViewTransform();
781 return;
783 if ( !bOldMap && bRelMap )
785 maMapRes.mnMapScNumX = 1;
786 maMapRes.mnMapScNumY = 1;
787 maMapRes.mnMapScDenomX = mnDPIX;
788 maMapRes.mnMapScDenomY = mnDPIY;
789 maMapRes.mnMapOfsX = 0;
790 maMapRes.mnMapOfsY = 0;
793 // Neue MapMode-Aufloesung berechnen
794 ImplCalcMapResolution( rNewMapMode, mnDPIX, mnDPIY, maMapRes, maThresRes );
797 // Neuen MapMode setzen
798 if ( bRelMap )
800 Point aOrigin( maMapRes.mnMapOfsX, maMapRes.mnMapOfsY );
801 // aScale? = maMapMode.GetScale?() * rNewMapMode.GetScale?()
802 Fraction aScaleX = ImplMakeFraction( maMapMode.GetScaleX().GetNumerator(),
803 rNewMapMode.GetScaleX().GetNumerator(),
804 maMapMode.GetScaleX().GetDenominator(),
805 rNewMapMode.GetScaleX().GetDenominator() );
806 Fraction aScaleY = ImplMakeFraction( maMapMode.GetScaleY().GetNumerator(),
807 rNewMapMode.GetScaleY().GetNumerator(),
808 maMapMode.GetScaleY().GetDenominator(),
809 rNewMapMode.GetScaleY().GetDenominator() );
810 maMapMode.SetOrigin( aOrigin );
811 maMapMode.SetScaleX( aScaleX );
812 maMapMode.SetScaleY( aScaleY );
814 else
815 maMapMode = rNewMapMode;
817 // create new objects (clip region werden nicht neu skaliert)
818 mbNewFont = sal_True;
819 mbInitFont = sal_True;
820 if ( GetOutDevType() == OUTDEV_WINDOW )
822 if ( ((Window*)this)->mpWindowImpl->mpCursor )
823 ((Window*)this)->mpWindowImpl->mpCursor->ImplNew();
826 // #106426# Adapt logical offset when changing mapmode
827 mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
828 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
829 maThresRes.mnThresPixToLogX );
830 mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
831 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
832 maThresRes.mnThresPixToLogY );
834 // #i75163#
835 ImplInvalidateViewTransform();
838 // -----------------------------------------------------------------------
840 void OutputDevice::SetRelativeMapMode( const MapMode& rNewMapMode )
842 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
844 // Ist der MapMode der gleiche wie vorher, dann mache nichts
845 if ( maMapMode == rNewMapMode )
846 return;
848 MapUnit eOld = maMapMode.GetMapUnit();
849 MapUnit eNew = rNewMapMode.GetMapUnit();
851 // a?F = rNewMapMode.GetScale?() / maMapMode.GetScale?()
852 Fraction aXF = ImplMakeFraction( rNewMapMode.GetScaleX().GetNumerator(),
853 maMapMode.GetScaleX().GetDenominator(),
854 rNewMapMode.GetScaleX().GetDenominator(),
855 maMapMode.GetScaleX().GetNumerator() );
856 Fraction aYF = ImplMakeFraction( rNewMapMode.GetScaleY().GetNumerator(),
857 maMapMode.GetScaleY().GetDenominator(),
858 rNewMapMode.GetScaleY().GetDenominator(),
859 maMapMode.GetScaleY().GetNumerator() );
861 Point aPt( LogicToLogic( Point(), NULL, &rNewMapMode ) );
862 if ( eNew != eOld )
864 if ( eOld > MAP_PIXEL )
866 SAL_WARN( "vcl.gdi", "Not implemented MapUnit" );
868 else if ( eNew > MAP_PIXEL )
870 SAL_WARN( "vcl.gdi", "Not implemented MapUnit" );
872 else
874 Fraction aF( aImplNumeratorAry[eNew] * aImplDenominatorAry[eOld],
875 aImplNumeratorAry[eOld] * aImplDenominatorAry[eNew] );
877 // a?F = a?F * aF
878 aXF = ImplMakeFraction( aXF.GetNumerator(), aF.GetNumerator(),
879 aXF.GetDenominator(), aF.GetDenominator() );
880 aYF = ImplMakeFraction( aYF.GetNumerator(), aF.GetNumerator(),
881 aYF.GetDenominator(), aF.GetDenominator() );
882 if ( eOld == MAP_PIXEL )
884 aXF *= Fraction( mnDPIX, 1 );
885 aYF *= Fraction( mnDPIY, 1 );
887 else if ( eNew == MAP_PIXEL )
889 aXF *= Fraction( 1, mnDPIX );
890 aYF *= Fraction( 1, mnDPIY );
895 MapMode aNewMapMode( MAP_RELATIVE, Point( -aPt.X(), -aPt.Y() ), aXF, aYF );
896 SetMapMode( aNewMapMode );
898 if ( eNew != eOld )
899 maMapMode = rNewMapMode;
901 // #106426# Adapt logical offset when changing mapmode
902 mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
903 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
904 maThresRes.mnThresPixToLogX );
905 mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
906 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
907 maThresRes.mnThresPixToLogY );
909 if( mpAlphaVDev )
910 mpAlphaVDev->SetRelativeMapMode( rNewMapMode );
913 // -----------------------------------------------------------------------
915 // #i75163#
916 basegfx::B2DHomMatrix OutputDevice::GetViewTransformation() const
918 if(mbMap)
920 // #i82615#
921 if(!mpOutDevData)
923 const_cast< OutputDevice* >(this)->ImplInitOutDevData();
926 if(!mpOutDevData->mpViewTransform)
928 mpOutDevData->mpViewTransform = new basegfx::B2DHomMatrix;
930 const double fScaleFactorX((double)mnDPIX * (double)maMapRes.mnMapScNumX / (double)maMapRes.mnMapScDenomX);
931 const double fScaleFactorY((double)mnDPIY * (double)maMapRes.mnMapScNumY / (double)maMapRes.mnMapScDenomY);
932 const double fZeroPointX(((double)maMapRes.mnMapOfsX * fScaleFactorX) + (double)mnOutOffOrigX);
933 const double fZeroPointY(((double)maMapRes.mnMapOfsY * fScaleFactorY) + (double)mnOutOffOrigY);
935 mpOutDevData->mpViewTransform->set(0, 0, fScaleFactorX);
936 mpOutDevData->mpViewTransform->set(1, 1, fScaleFactorY);
937 mpOutDevData->mpViewTransform->set(0, 2, fZeroPointX);
938 mpOutDevData->mpViewTransform->set(1, 2, fZeroPointY);
941 return *mpOutDevData->mpViewTransform;
943 else
945 return basegfx::B2DHomMatrix();
949 // -----------------------------------------------------------------------
951 // #i75163#
952 basegfx::B2DHomMatrix OutputDevice::GetInverseViewTransformation() const
954 if(mbMap)
956 // #i82615#
957 if(!mpOutDevData)
959 const_cast< OutputDevice* >(this)->ImplInitOutDevData();
962 if(!mpOutDevData->mpInverseViewTransform)
964 GetViewTransformation();
965 mpOutDevData->mpInverseViewTransform = new basegfx::B2DHomMatrix(*mpOutDevData->mpViewTransform);
966 mpOutDevData->mpInverseViewTransform->invert();
969 return *mpOutDevData->mpInverseViewTransform;
971 else
973 return basegfx::B2DHomMatrix();
977 // -----------------------------------------------------------------------
979 // #i75163#
980 basegfx::B2DHomMatrix OutputDevice::GetViewTransformation( const MapMode& rMapMode ) const
982 // #i82615#
983 ImplMapRes aMapRes;
984 ImplThresholdRes aThresRes;
985 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
987 basegfx::B2DHomMatrix aTransform;
989 const double fScaleFactorX((double)mnDPIX * (double)aMapRes.mnMapScNumX / (double)aMapRes.mnMapScDenomX);
990 const double fScaleFactorY((double)mnDPIY * (double)aMapRes.mnMapScNumY / (double)aMapRes.mnMapScDenomY);
991 const double fZeroPointX(((double)aMapRes.mnMapOfsX * fScaleFactorX) + (double)mnOutOffOrigX);
992 const double fZeroPointY(((double)aMapRes.mnMapOfsY * fScaleFactorY) + (double)mnOutOffOrigY);
994 aTransform.set(0, 0, fScaleFactorX);
995 aTransform.set(1, 1, fScaleFactorY);
996 aTransform.set(0, 2, fZeroPointX);
997 aTransform.set(1, 2, fZeroPointY);
999 return aTransform;
1002 // -----------------------------------------------------------------------
1004 // #i75163#
1005 basegfx::B2DHomMatrix OutputDevice::GetInverseViewTransformation( const MapMode& rMapMode ) const
1007 basegfx::B2DHomMatrix aMatrix( GetViewTransformation( rMapMode ) );
1008 aMatrix.invert();
1009 return aMatrix;
1012 // -----------------------------------------------------------------------
1014 basegfx::B2DHomMatrix OutputDevice::ImplGetDeviceTransformation() const
1016 basegfx::B2DHomMatrix aTransformation = GetViewTransformation();
1017 // TODO: is it worth to cache the transformed result?
1018 if( mnOutOffX || mnOutOffY )
1019 aTransformation.translate( mnOutOffX, mnOutOffY );
1020 return aTransformation;
1023 // -----------------------------------------------------------------------
1025 Point OutputDevice::LogicToPixel( const Point& rLogicPt ) const
1027 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1029 if ( !mbMap )
1030 return rLogicPt;
1032 return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
1033 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1034 maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1035 ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
1036 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1037 maThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1040 // -----------------------------------------------------------------------
1042 Size OutputDevice::LogicToPixel( const Size& rLogicSize ) const
1044 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1046 if ( !mbMap )
1047 return rLogicSize;
1049 return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
1050 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1051 maThresRes.mnThresLogToPixX ),
1052 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
1053 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1054 maThresRes.mnThresLogToPixY ) );
1057 // -----------------------------------------------------------------------
1059 Rectangle OutputDevice::LogicToPixel( const Rectangle& rLogicRect ) const
1061 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1063 if ( !mbMap || rLogicRect.IsEmpty() )
1064 return rLogicRect;
1066 return Rectangle( ImplLogicToPixel( rLogicRect.Left() + maMapRes.mnMapOfsX, mnDPIX,
1067 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1068 maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1069 ImplLogicToPixel( rLogicRect.Top() + maMapRes.mnMapOfsY, mnDPIY,
1070 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1071 maThresRes.mnThresLogToPixY )+mnOutOffOrigY,
1072 ImplLogicToPixel( rLogicRect.Right() + maMapRes.mnMapOfsX, mnDPIX,
1073 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1074 maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1075 ImplLogicToPixel( rLogicRect.Bottom() + maMapRes.mnMapOfsY, mnDPIY,
1076 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1077 maThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1080 // -----------------------------------------------------------------------
1082 Polygon OutputDevice::LogicToPixel( const Polygon& rLogicPoly ) const
1084 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1085 DBG_CHKOBJ( &rLogicPoly, Polygon, NULL );
1087 if ( !mbMap )
1088 return rLogicPoly;
1090 sal_uInt16 i;
1091 sal_uInt16 nPoints = rLogicPoly.GetSize();
1092 Polygon aPoly( rLogicPoly );
1094 // Pointer auf das Point-Array holen (Daten werden kopiert)
1095 const Point* pPointAry = aPoly.GetConstPointAry();
1097 for ( i = 0; i < nPoints; i++ )
1099 const Point* pPt = &(pPointAry[i]);
1100 Point aPt;
1101 aPt.X() = ImplLogicToPixel( pPt->X() + maMapRes.mnMapOfsX, mnDPIX,
1102 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1103 maThresRes.mnThresLogToPixX )+mnOutOffOrigX;
1104 aPt.Y() = ImplLogicToPixel( pPt->Y() + maMapRes.mnMapOfsY, mnDPIY,
1105 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1106 maThresRes.mnThresLogToPixY )+mnOutOffOrigY;
1107 aPoly[i] = aPt;
1110 return aPoly;
1113 // -----------------------------------------------------------------------
1115 PolyPolygon OutputDevice::LogicToPixel( const PolyPolygon& rLogicPolyPoly ) const
1117 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1118 DBG_CHKOBJ( &rLogicPolyPoly, PolyPolygon, NULL );
1120 if ( !mbMap )
1121 return rLogicPolyPoly;
1123 PolyPolygon aPolyPoly( rLogicPolyPoly );
1124 sal_uInt16 nPoly = aPolyPoly.Count();
1125 for( sal_uInt16 i = 0; i < nPoly; i++ )
1127 Polygon& rPoly = aPolyPoly[i];
1128 rPoly = LogicToPixel( rPoly );
1130 return aPolyPoly;
1133 // -----------------------------------------------------------------------
1135 Region OutputDevice::LogicToPixel( const Region& rLogicRegion ) const
1137 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1138 DBG_CHKOBJ( &rLogicRegion, Region, ImplDbgTestRegion );
1140 RegionType eType = rLogicRegion.GetType();
1142 if ( !mbMap || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
1143 return rLogicRegion;
1145 Region aRegion;
1146 const ImplRegion& rImplRegion = *rLogicRegion.ImplGetImplRegion();
1147 const PolyPolygon* pPolyPoly = rImplRegion.mpPolyPoly;
1148 const basegfx::B2DPolyPolygon* pB2DPolyPoly = rImplRegion.mpB2DPolyPoly;
1150 if ( pPolyPoly )
1151 aRegion = Region( LogicToPixel( *pPolyPoly ) );
1152 else if( pB2DPolyPoly )
1154 basegfx::B2DPolyPolygon aTransformedPoly = *pB2DPolyPoly;
1155 const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation();
1156 aTransformedPoly.transform( rTransformationMatrix );
1157 aRegion = Region( aTransformedPoly );
1159 else
1161 long nX;
1162 long nY;
1163 long nWidth;
1164 long nHeight;
1165 ImplRegionInfo aInfo;
1166 sal_Bool bRegionRect;
1168 aRegion.ImplBeginAddRect();
1169 bRegionRect = rLogicRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
1170 while ( bRegionRect )
1172 Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
1173 aRegion.ImplAddRect( LogicToPixel( aRect ) );
1174 bRegionRect = rLogicRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
1176 aRegion.ImplEndAddRect();
1179 return aRegion;
1182 // -----------------------------------------------------------------------
1184 Point OutputDevice::LogicToPixel( const Point& rLogicPt,
1185 const MapMode& rMapMode ) const
1187 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1189 if ( rMapMode.IsDefault() )
1190 return rLogicPt;
1192 // MapMode-Aufloesung berechnen und Umrechnen
1193 ImplMapRes aMapRes;
1194 ImplThresholdRes aThresRes;
1195 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1197 return Point( ImplLogicToPixel( rLogicPt.X() + aMapRes.mnMapOfsX, mnDPIX,
1198 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1199 aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1200 ImplLogicToPixel( rLogicPt.Y() + aMapRes.mnMapOfsY, mnDPIY,
1201 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1202 aThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1205 // -----------------------------------------------------------------------
1207 Size OutputDevice::LogicToPixel( const Size& rLogicSize,
1208 const MapMode& rMapMode ) const
1210 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1212 if ( rMapMode.IsDefault() )
1213 return rLogicSize;
1215 // MapMode-Aufloesung berechnen und Umrechnen
1216 ImplMapRes aMapRes;
1217 ImplThresholdRes aThresRes;
1218 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1220 return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
1221 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1222 aThresRes.mnThresLogToPixX ),
1223 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
1224 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1225 aThresRes.mnThresLogToPixY ) );
1228 // -----------------------------------------------------------------------
1230 Rectangle OutputDevice::LogicToPixel( const Rectangle& rLogicRect,
1231 const MapMode& rMapMode ) const
1233 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1235 if ( rMapMode.IsDefault() || rLogicRect.IsEmpty() )
1236 return rLogicRect;
1238 // MapMode-Aufloesung berechnen und Umrechnen
1239 ImplMapRes aMapRes;
1240 ImplThresholdRes aThresRes;
1241 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1243 return Rectangle( ImplLogicToPixel( rLogicRect.Left() + aMapRes.mnMapOfsX, mnDPIX,
1244 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1245 aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1246 ImplLogicToPixel( rLogicRect.Top() + aMapRes.mnMapOfsY, mnDPIY,
1247 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1248 aThresRes.mnThresLogToPixY )+mnOutOffOrigY,
1249 ImplLogicToPixel( rLogicRect.Right() + aMapRes.mnMapOfsX, mnDPIX,
1250 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1251 aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1252 ImplLogicToPixel( rLogicRect.Bottom() + aMapRes.mnMapOfsY, mnDPIY,
1253 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1254 aThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1257 // -----------------------------------------------------------------------
1259 Polygon OutputDevice::LogicToPixel( const Polygon& rLogicPoly,
1260 const MapMode& rMapMode ) const
1262 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1263 DBG_CHKOBJ( &rLogicPoly, Polygon, NULL );
1265 if ( rMapMode.IsDefault() )
1266 return rLogicPoly;
1268 // MapMode-Aufloesung berechnen und Umrechnen
1269 ImplMapRes aMapRes;
1270 ImplThresholdRes aThresRes;
1271 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1273 sal_uInt16 i;
1274 sal_uInt16 nPoints = rLogicPoly.GetSize();
1275 Polygon aPoly( rLogicPoly );
1277 // Pointer auf das Point-Array holen (Daten werden kopiert)
1278 const Point* pPointAry = aPoly.GetConstPointAry();
1280 for ( i = 0; i < nPoints; i++ )
1282 const Point* pPt = &(pPointAry[i]);
1283 Point aPt;
1284 aPt.X() = ImplLogicToPixel( pPt->X() + aMapRes.mnMapOfsX, mnDPIX,
1285 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1286 aThresRes.mnThresLogToPixX )+mnOutOffOrigX;
1287 aPt.Y() = ImplLogicToPixel( pPt->Y() + aMapRes.mnMapOfsY, mnDPIY,
1288 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1289 aThresRes.mnThresLogToPixY )+mnOutOffOrigY;
1290 aPoly[i] = aPt;
1293 return aPoly;
1296 // -----------------------------------------------------------------------
1298 basegfx::B2DPolyPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly,
1299 const MapMode& rMapMode ) const
1301 basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly;
1302 const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation( rMapMode );
1303 aTransformedPoly.transform( rTransformationMatrix );
1304 return aTransformedPoly;
1307 // -----------------------------------------------------------------------
1309 Point OutputDevice::PixelToLogic( const Point& rDevicePt ) const
1311 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1313 if ( !mbMap )
1314 return rDevicePt;
1316 return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1317 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1318 maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1319 ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1320 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1321 maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY );
1324 // -----------------------------------------------------------------------
1326 Size OutputDevice::PixelToLogic( const Size& rDeviceSize ) const
1328 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1330 if ( !mbMap )
1331 return rDeviceSize;
1333 return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1334 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1335 maThresRes.mnThresPixToLogX ),
1336 ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1337 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1338 maThresRes.mnThresPixToLogY ) );
1341 // -----------------------------------------------------------------------
1343 Rectangle OutputDevice::PixelToLogic( const Rectangle& rDeviceRect ) const
1345 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1347 if ( !mbMap || rDeviceRect.IsEmpty() )
1348 return rDeviceRect;
1350 return Rectangle( ImplPixelToLogic( rDeviceRect.Left(), mnDPIX,
1351 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1352 maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1353 ImplPixelToLogic( rDeviceRect.Top(), mnDPIY,
1354 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1355 maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY,
1356 ImplPixelToLogic( rDeviceRect.Right(), mnDPIX,
1357 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1358 maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1359 ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY,
1360 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1361 maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY );
1364 // -----------------------------------------------------------------------
1366 Polygon OutputDevice::PixelToLogic( const Polygon& rDevicePoly ) const
1368 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1369 DBG_CHKOBJ( &rDevicePoly, Polygon, NULL );
1371 if ( !mbMap )
1372 return rDevicePoly;
1374 sal_uInt16 i;
1375 sal_uInt16 nPoints = rDevicePoly.GetSize();
1376 Polygon aPoly( rDevicePoly );
1378 // Pointer auf das Point-Array holen (Daten werden kopiert)
1379 const Point* pPointAry = aPoly.GetConstPointAry();
1381 for ( i = 0; i < nPoints; i++ )
1383 const Point* pPt = &(pPointAry[i]);
1384 Point aPt;
1385 aPt.X() = ImplPixelToLogic( pPt->X(), mnDPIX,
1386 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1387 maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX;
1388 aPt.Y() = ImplPixelToLogic( pPt->Y(), mnDPIY,
1389 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1390 maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY;
1391 aPoly[i] = aPt;
1394 return aPoly;
1397 // -----------------------------------------------------------------------
1399 PolyPolygon OutputDevice::PixelToLogic( const PolyPolygon& rDevicePolyPoly ) const
1401 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1402 DBG_CHKOBJ( &rDevicePolyPoly, PolyPolygon, NULL );
1404 if ( !mbMap )
1405 return rDevicePolyPoly;
1407 PolyPolygon aPolyPoly( rDevicePolyPoly );
1408 sal_uInt16 nPoly = aPolyPoly.Count();
1409 for( sal_uInt16 i = 0; i < nPoly; i++ )
1411 Polygon& rPoly = aPolyPoly[i];
1412 rPoly = PixelToLogic( rPoly );
1414 return aPolyPoly;
1417 basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygon& rPixelPolyPoly ) const
1419 basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly;
1420 const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation();
1421 aTransformedPoly.transform( rTransformationMatrix );
1422 return aTransformedPoly;
1425 // -----------------------------------------------------------------------
1427 Region OutputDevice::PixelToLogic( const Region& rDeviceRegion ) const
1429 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1430 DBG_CHKOBJ( &rDeviceRegion, Region, ImplDbgTestRegion );
1432 RegionType eType = rDeviceRegion.GetType();
1434 if ( !mbMap || (eType == REGION_EMPTY) || (eType == REGION_NULL) )
1435 return rDeviceRegion;
1437 Region aRegion;
1438 basegfx::B2DPolyPolygon* pB2DPolyPoly = rDeviceRegion.ImplGetImplRegion()->mpB2DPolyPoly;
1439 PolyPolygon* pPolyPoly = pB2DPolyPoly ? 0 : rDeviceRegion.ImplGetImplRegion()->mpPolyPoly;
1441 if ( pB2DPolyPoly ) // conversion with B2DPolyPolygon lost polygon-based ClipRegion
1443 aRegion = Region( PixelToLogic( *pB2DPolyPoly ) );
1445 else if ( pPolyPoly )
1447 aRegion = Region( PixelToLogic( *pPolyPoly ) );
1449 else
1451 long nX;
1452 long nY;
1453 long nWidth;
1454 long nHeight;
1455 ImplRegionInfo aInfo;
1456 sal_Bool bRegionRect;
1458 aRegion.ImplBeginAddRect();
1459 bRegionRect = rDeviceRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
1460 while ( bRegionRect )
1462 Rectangle aRect( Point( nX, nY ), Size( nWidth, nHeight ) );
1463 aRegion.ImplAddRect( PixelToLogic( aRect ) );
1464 bRegionRect = rDeviceRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
1466 aRegion.ImplEndAddRect();
1469 return aRegion;
1472 // -----------------------------------------------------------------------
1474 Point OutputDevice::PixelToLogic( const Point& rDevicePt,
1475 const MapMode& rMapMode ) const
1477 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1479 // Ist Default-MapMode, dann bereche nichts
1480 if ( rMapMode.IsDefault() )
1481 return rDevicePt;
1483 // MapMode-Aufloesung berechnen und Umrechnen
1484 ImplMapRes aMapRes;
1485 ImplThresholdRes aThresRes;
1486 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1488 return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1489 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1490 aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1491 ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1492 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1493 aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1496 // -----------------------------------------------------------------------
1498 Size OutputDevice::PixelToLogic( const Size& rDeviceSize,
1499 const MapMode& rMapMode ) const
1501 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1503 // Ist Default-MapMode, dann bereche nichts
1504 if ( rMapMode.IsDefault() )
1505 return rDeviceSize;
1507 // MapMode-Aufloesung berechnen und Umrechnen
1508 ImplMapRes aMapRes;
1509 ImplThresholdRes aThresRes;
1510 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1512 return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1513 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1514 aThresRes.mnThresPixToLogX ),
1515 ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1516 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1517 aThresRes.mnThresPixToLogY ) );
1520 // -----------------------------------------------------------------------
1522 Rectangle OutputDevice::PixelToLogic( const Rectangle& rDeviceRect,
1523 const MapMode& rMapMode ) const
1525 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1527 // Ist Default-MapMode, dann bereche nichts
1528 if ( rMapMode.IsDefault() || rDeviceRect.IsEmpty() )
1529 return rDeviceRect;
1531 // MapMode-Aufloesung berechnen und Umrechnen
1532 ImplMapRes aMapRes;
1533 ImplThresholdRes aThresRes;
1534 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1536 return Rectangle( ImplPixelToLogic( rDeviceRect.Left(), mnDPIX,
1537 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1538 aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1539 ImplPixelToLogic( rDeviceRect.Top(), mnDPIY,
1540 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1541 aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY,
1542 ImplPixelToLogic( rDeviceRect.Right(), mnDPIX,
1543 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1544 aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1545 ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY,
1546 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1547 aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1550 // -----------------------------------------------------------------------
1552 Polygon OutputDevice::PixelToLogic( const Polygon& rDevicePoly,
1553 const MapMode& rMapMode ) const
1555 DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1556 DBG_CHKOBJ( &rDevicePoly, Polygon, NULL );
1558 // Ist Default-MapMode, dann bereche nichts
1559 if ( rMapMode.IsDefault() )
1560 return rDevicePoly;
1562 // MapMode-Aufloesung berechnen und Umrechnen
1563 ImplMapRes aMapRes;
1564 ImplThresholdRes aThresRes;
1565 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1567 sal_uInt16 i;
1568 sal_uInt16 nPoints = rDevicePoly.GetSize();
1569 Polygon aPoly( rDevicePoly );
1571 // Pointer auf das Point-Array holen (Daten werden kopiert)
1572 const Point* pPointAry = aPoly.GetConstPointAry();
1574 for ( i = 0; i < nPoints; i++ )
1576 const Point* pPt = &(pPointAry[i]);
1577 Point aPt;
1578 aPt.X() = ImplPixelToLogic( pPt->X(), mnDPIX,
1579 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1580 aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX;
1581 aPt.Y() = ImplPixelToLogic( pPt->Y(), mnDPIY,
1582 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1583 aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY;
1584 aPoly[i] = aPt;
1587 return aPoly;
1590 // -----------------------------------------------------------------------
1592 basegfx::B2DPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolygon& rPixelPoly,
1593 const MapMode& rMapMode ) const
1595 basegfx::B2DPolygon aTransformedPoly = rPixelPoly;
1596 const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation( rMapMode );
1597 aTransformedPoly.transform( rTransformationMatrix );
1598 return aTransformedPoly;
1601 // -----------------------------------------------------------------------
1603 basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygon& rPixelPolyPoly,
1604 const MapMode& rMapMode ) const
1606 basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly;
1607 const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation( rMapMode );
1608 aTransformedPoly.transform( rTransformationMatrix );
1609 return aTransformedPoly;
1612 // -----------------------------------------------------------------------
1614 #define ENTER0( rSource, pMapModeSource, pMapModeDest ) \
1615 if ( !pMapModeSource ) \
1616 pMapModeSource = &maMapMode; \
1617 if ( !pMapModeDest ) \
1618 pMapModeDest = &maMapMode; \
1619 if ( *pMapModeSource == *pMapModeDest ) \
1620 return rSource
1622 // -----------------------------------------------------------------------
1624 #define ENTER1( rSource, pMapModeSource, pMapModeDest ) \
1625 ENTER0( rSource, pMapModeSource, pMapModeDest ); \
1627 ImplMapRes aMapResSource; \
1628 ImplMapRes aMapResDest; \
1630 if ( !mbMap || pMapModeSource != &maMapMode ) \
1632 if ( pMapModeSource->GetMapUnit() == MAP_RELATIVE ) \
1633 aMapResSource = maMapRes; \
1634 ImplCalcMapResolution( *pMapModeSource, \
1635 mnDPIX, mnDPIY, aMapResSource ); \
1637 else \
1638 aMapResSource = maMapRes; \
1639 if ( !mbMap || pMapModeDest != &maMapMode ) \
1641 if ( pMapModeDest->GetMapUnit() == MAP_RELATIVE ) \
1642 aMapResDest = maMapRes; \
1643 ImplCalcMapResolution( *pMapModeDest, \
1644 mnDPIX, mnDPIY, aMapResDest ); \
1646 else \
1647 aMapResDest = maMapRes
1649 // -----------------------------------------------------------------------
1651 #define ENTER2( eUnitSource, eUnitDest ) \
1652 DBG_ASSERT( eUnitSource != MAP_SYSFONT \
1653 && eUnitSource != MAP_APPFONT \
1654 && eUnitSource != MAP_RELATIVE, \
1655 "Source MapUnit nicht erlaubt" ); \
1656 DBG_ASSERT( eUnitDest != MAP_SYSFONT \
1657 && eUnitDest != MAP_APPFONT \
1658 && eUnitDest != MAP_RELATIVE, \
1659 "Destination MapUnit nicht erlaubt" ); \
1660 DBG_ASSERTWARNING( eUnitSource != MAP_PIXEL, \
1661 "MAP_PIXEL mit 72dpi angenaehert" ); \
1662 DBG_ASSERTWARNING( eUnitDest != MAP_PIXEL, \
1663 "MAP_PIXEL mit 72dpi angenaehert" )
1665 // -----------------------------------------------------------------------
1667 #define ENTER3( eUnitSource, eUnitDest ) \
1668 long nNumerator = 1; \
1669 long nDenominator = 1; \
1670 DBG_ASSERT( eUnitSource < s_ImplArySize, "Invalid source map unit"); \
1671 DBG_ASSERT( eUnitDest < s_ImplArySize, "Invalid destination map unit"); \
1672 if( (eUnitSource < s_ImplArySize) && (eUnitDest < s_ImplArySize) ) \
1674 nNumerator = aImplNumeratorAry[eUnitSource] * \
1675 aImplDenominatorAry[eUnitDest]; \
1676 nDenominator = aImplNumeratorAry[eUnitDest] * \
1677 aImplDenominatorAry[eUnitSource]; \
1679 if ( eUnitSource == MAP_PIXEL ) \
1680 nDenominator *= 72; \
1681 else if( eUnitDest == MAP_PIXEL ) \
1682 nNumerator *= 72
1684 // -----------------------------------------------------------------------
1686 #define ENTER4( rMapModeSource, rMapModeDest ) \
1687 ImplMapRes aMapResSource; \
1688 ImplMapRes aMapResDest; \
1690 ImplCalcMapResolution( rMapModeSource, 72, 72, aMapResSource ); \
1691 ImplCalcMapResolution( rMapModeDest, 72, 72, aMapResDest )
1693 // -----------------------------------------------------------------------
1695 // return (n1 * n2 * n3) / (n4 * n5)
1696 static long fn5( const long n1,
1697 const long n2,
1698 const long n3,
1699 const long n4,
1700 const long n5 )
1702 if ( n1 == 0 || n2 == 0 || n3 == 0 || n4 == 0 || n5 == 0 )
1703 return 0;
1704 if ( LONG_MAX / std::abs(n2) < std::abs(n3) )
1706 // a6 wird "ubersprungen
1707 BigInt a7 = n2;
1708 a7 *= n3;
1709 a7 *= n1;
1711 if ( LONG_MAX / std::abs(n4) < std::abs(n5) )
1713 BigInt a8 = n4;
1714 a8 *= n5;
1716 BigInt a9 = a8;
1717 a9 /= 2;
1718 if ( a7.IsNeg() )
1719 a7 -= a9;
1720 else
1721 a7 += a9;
1723 a7 /= a8;
1724 } // of if
1725 else
1727 long n8 = n4 * n5;
1729 if ( a7.IsNeg() )
1730 a7 -= n8 / 2;
1731 else
1732 a7 += n8 / 2;
1734 a7 /= n8;
1735 } // of else
1736 return (long)a7;
1737 } // of if
1738 else
1740 long n6 = n2 * n3;
1742 if ( LONG_MAX / std::abs(n1) < std::abs(n6) )
1744 BigInt a7 = n1;
1745 a7 *= n6;
1747 if ( LONG_MAX / std::abs(n4) < std::abs(n5) )
1749 BigInt a8 = n4;
1750 a8 *= n5;
1752 BigInt a9 = a8;
1753 a9 /= 2;
1754 if ( a7.IsNeg() )
1755 a7 -= a9;
1756 else
1757 a7 += a9;
1759 a7 /= a8;
1760 } // of if
1761 else
1763 long n8 = n4 * n5;
1765 if ( a7.IsNeg() )
1766 a7 -= n8 / 2;
1767 else
1768 a7 += n8 / 2;
1770 a7 /= n8;
1771 } // of else
1772 return (long)a7;
1773 } // of if
1774 else
1776 long n7 = n1 * n6;
1778 if ( LONG_MAX / std::abs(n4) < std::abs(n5) )
1780 BigInt a7 = n7;
1781 BigInt a8 = n4;
1782 a8 *= n5;
1784 BigInt a9 = a8;
1785 a9 /= 2;
1786 if ( a7.IsNeg() )
1787 a7 -= a9;
1788 else
1789 a7 += a9;
1791 a7 /= a8;
1792 return (long)a7;
1793 } // of if
1794 else
1796 const long n8 = n4 * n5;
1797 const long n8_2 = n8 / 2;
1799 if( n7 < 0 )
1801 if( ( n7 - LONG_MIN ) >= n8_2 )
1802 n7 -= n8_2;
1804 else if( ( LONG_MAX - n7 ) >= n8_2 )
1805 n7 += n8_2;
1807 return n7 / n8;
1808 } // of else
1809 } // of else
1810 } // of else
1813 // -----------------------------------------------------------------------
1815 // return (n1 * n2) / n3
1816 static long fn3( const long n1, const long n2, const long n3 )
1818 if ( n1 == 0 || n2 == 0 || n3 == 0 )
1819 return 0;
1820 if ( LONG_MAX / std::abs(n1) < std::abs(n2) )
1822 BigInt a4 = n1;
1823 a4 *= n2;
1825 if ( a4.IsNeg() )
1826 a4 -= n3 / 2;
1827 else
1828 a4 += n3 / 2;
1830 a4 /= n3;
1831 return (long)a4;
1832 } // of if
1833 else
1835 long n4 = n1 * n2;
1836 const long n3_2 = n3 / 2;
1838 if( n4 < 0 )
1840 if( ( n4 - LONG_MIN ) >= n3_2 )
1841 n4 -= n3_2;
1843 else if( ( LONG_MAX - n4 ) >= n3_2 )
1844 n4 += n3_2;
1846 return n4 / n3;
1847 } // of else
1850 // -----------------------------------------------------------------------
1852 Point OutputDevice::LogicToLogic( const Point& rPtSource,
1853 const MapMode* pMapModeSource,
1854 const MapMode* pMapModeDest ) const
1856 ENTER1( rPtSource, pMapModeSource, pMapModeDest );
1858 return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
1859 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1860 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1861 aMapResDest.mnMapOfsX,
1862 fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
1863 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1864 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1865 aMapResDest.mnMapOfsY );
1868 // -----------------------------------------------------------------------
1870 Size OutputDevice::LogicToLogic( const Size& rSzSource,
1871 const MapMode* pMapModeSource,
1872 const MapMode* pMapModeDest ) const
1874 ENTER1( rSzSource, pMapModeSource, pMapModeDest );
1876 return Size( fn5( rSzSource.Width(),
1877 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1878 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
1879 fn5( rSzSource.Height(),
1880 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1881 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
1884 // -----------------------------------------------------------------------
1886 Rectangle OutputDevice::LogicToLogic( const Rectangle& rRectSource,
1887 const MapMode* pMapModeSource,
1888 const MapMode* pMapModeDest ) const
1890 ENTER1( rRectSource, pMapModeSource, pMapModeDest );
1892 return Rectangle( fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
1893 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1894 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1895 aMapResDest.mnMapOfsX,
1896 fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
1897 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1898 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1899 aMapResDest.mnMapOfsY,
1900 fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
1901 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1902 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1903 aMapResDest.mnMapOfsX,
1904 fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
1905 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1906 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1907 aMapResDest.mnMapOfsY );
1910 // -----------------------------------------------------------------------
1912 Point OutputDevice::LogicToLogic( const Point& rPtSource,
1913 const MapMode& rMapModeSource,
1914 const MapMode& rMapModeDest )
1916 if ( rMapModeSource == rMapModeDest )
1917 return rPtSource;
1919 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1920 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
1921 ENTER2( eUnitSource, eUnitDest );
1923 if ( rMapModeSource.mpImplMapMode->mbSimple &&
1924 rMapModeDest.mpImplMapMode->mbSimple )
1926 ENTER3( eUnitSource, eUnitDest );
1928 return Point( fn3( rPtSource.X(), nNumerator, nDenominator ),
1929 fn3( rPtSource.Y(), nNumerator, nDenominator ) );
1931 else
1933 ENTER4( rMapModeSource, rMapModeDest );
1935 return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
1936 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1937 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1938 aMapResDest.mnMapOfsX,
1939 fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
1940 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1941 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1942 aMapResDest.mnMapOfsY );
1946 // -----------------------------------------------------------------------
1948 Size OutputDevice::LogicToLogic( const Size& rSzSource,
1949 const MapMode& rMapModeSource,
1950 const MapMode& rMapModeDest )
1952 if ( rMapModeSource == rMapModeDest )
1953 return rSzSource;
1955 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1956 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
1957 ENTER2( eUnitSource, eUnitDest );
1959 if ( rMapModeSource.mpImplMapMode->mbSimple &&
1960 rMapModeDest.mpImplMapMode->mbSimple )
1962 ENTER3( eUnitSource, eUnitDest );
1964 return Size( fn3( rSzSource.Width(), nNumerator, nDenominator ),
1965 fn3( rSzSource.Height(), nNumerator, nDenominator ) );
1967 else
1969 ENTER4( rMapModeSource, rMapModeDest );
1971 return Size( fn5( rSzSource.Width(),
1972 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1973 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
1974 fn5( rSzSource.Height(),
1975 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1976 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
1980 // -----------------------------------------------------------------------
1982 basegfx::B2DPolygon OutputDevice::LogicToLogic( const basegfx::B2DPolygon& rPolySource,
1983 const MapMode& rMapModeSource,
1984 const MapMode& rMapModeDest )
1986 if ( rMapModeSource == rMapModeDest )
1987 return rPolySource;
1989 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1990 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
1991 ENTER2( eUnitSource, eUnitDest );
1993 basegfx::B2DHomMatrix aTransform;
1995 if ( rMapModeSource.mpImplMapMode->mbSimple &&
1996 rMapModeDest.mpImplMapMode->mbSimple )
1998 ENTER3( eUnitSource, eUnitDest );
2000 const double fScaleFactor((double)nNumerator / (double)nDenominator);
2001 aTransform.set(0, 0, fScaleFactor);
2002 aTransform.set(1, 1, fScaleFactor);
2004 else
2006 ENTER4( rMapModeSource, rMapModeDest );
2008 const double fScaleFactorX( (double(aMapResSource.mnMapScNumX) * double(aMapResDest.mnMapScDenomX))
2009 / (double(aMapResSource.mnMapScDenomX) * double(aMapResDest.mnMapScNumX)) );
2010 const double fScaleFactorY( (double(aMapResSource.mnMapScNumY) * double(aMapResDest.mnMapScDenomY))
2011 / (double(aMapResSource.mnMapScDenomY) * double(aMapResDest.mnMapScNumY)) );
2012 const double fZeroPointX(double(aMapResSource.mnMapOfsX) * fScaleFactorX - double(aMapResDest.mnMapOfsX));
2013 const double fZeroPointY(double(aMapResSource.mnMapOfsY) * fScaleFactorY - double(aMapResDest.mnMapOfsY));
2015 aTransform.set(0, 0, fScaleFactorX);
2016 aTransform.set(1, 1, fScaleFactorY);
2017 aTransform.set(0, 2, fZeroPointX);
2018 aTransform.set(1, 2, fZeroPointY);
2020 basegfx::B2DPolygon aPoly( rPolySource );
2021 aPoly.transform( aTransform );
2022 return aPoly;
2025 // -----------------------------------------------------------------------
2027 Rectangle OutputDevice::LogicToLogic( const Rectangle& rRectSource,
2028 const MapMode& rMapModeSource,
2029 const MapMode& rMapModeDest )
2031 if ( rMapModeSource == rMapModeDest )
2032 return rRectSource;
2034 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
2035 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
2036 ENTER2( eUnitSource, eUnitDest );
2038 if ( rMapModeSource.mpImplMapMode->mbSimple &&
2039 rMapModeDest.mpImplMapMode->mbSimple )
2041 ENTER3( eUnitSource, eUnitDest );
2043 return Rectangle( fn3( rRectSource.Left(), nNumerator, nDenominator ),
2044 fn3( rRectSource.Top(), nNumerator, nDenominator ),
2045 fn3( rRectSource.Right(), nNumerator, nDenominator ),
2046 fn3( rRectSource.Bottom(), nNumerator, nDenominator ) );
2048 else
2050 ENTER4( rMapModeSource, rMapModeDest );
2052 return Rectangle( fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
2053 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2054 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2055 aMapResDest.mnMapOfsX,
2056 fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
2057 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2058 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2059 aMapResDest.mnMapOfsY,
2060 fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
2061 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2062 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2063 aMapResDest.mnMapOfsX,
2064 fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
2065 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2066 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2067 aMapResDest.mnMapOfsY );
2071 // -----------------------------------------------------------------------
2073 long OutputDevice::LogicToLogic( long nLongSource,
2074 MapUnit eUnitSource, MapUnit eUnitDest )
2076 if ( eUnitSource == eUnitDest )
2077 return nLongSource;
2079 ENTER2( eUnitSource, eUnitDest );
2080 ENTER3( eUnitSource, eUnitDest );
2082 return fn3( nLongSource, nNumerator, nDenominator );
2085 // -----------------------------------------------------------------------
2087 void OutputDevice::SetPixelOffset( const Size& rOffset )
2089 mnOutOffOrigX = rOffset.Width();
2090 mnOutOffOrigY = rOffset.Height();
2092 mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
2093 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
2094 maThresRes.mnThresPixToLogX );
2095 mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
2096 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
2097 maThresRes.mnThresPixToLogY );
2099 if( mpAlphaVDev )
2100 mpAlphaVDev->SetPixelOffset( rOffset );
2103 // -----------------------------------------------------------------------
2105 Size OutputDevice::GetPixelOffset() const
2107 return Size(mnOutOffOrigX, mnOutOffOrigY);
2110 // -----------------------------------------------------------------------
2112 long Window::ImplLogicUnitToPixelX( long nX, MapUnit eUnit )
2114 if ( eUnit != MAP_PIXEL )
2116 ImplFrameData* pFrameData = mpWindowImpl->mpFrameData;
2118 // Map-Einheit verschieden, dann neu berechnen
2119 if ( pFrameData->meMapUnit != eUnit )
2121 pFrameData->meMapUnit = eUnit;
2122 ImplCalcMapResolution( MapMode( eUnit ), mnDPIX, mnDPIY,
2123 pFrameData->maMapUnitRes );
2126 // Es wird kein BigInt gebraucht, da diese Funktion nur zur Umrechnung
2127 // von Fensterposition benutzt wird
2128 nX = nX * mnDPIX * pFrameData->maMapUnitRes.mnMapScNumX;
2129 nX += nX >= 0 ? (pFrameData->maMapUnitRes.mnMapScDenomX/2) :
2130 -((pFrameData->maMapUnitRes.mnMapScDenomX-1)/2);
2131 nX /= pFrameData->maMapUnitRes.mnMapScDenomX;
2134 return nX;
2137 // -----------------------------------------------------------------------
2139 long Window::ImplLogicUnitToPixelY( long nY, MapUnit eUnit )
2141 if ( eUnit != MAP_PIXEL )
2143 ImplFrameData* pFrameData = mpWindowImpl->mpFrameData;
2145 // Map-Einheit verschieden, dann neu berechnen
2146 if ( pFrameData->meMapUnit != eUnit )
2148 pFrameData->meMapUnit = eUnit;
2149 ImplCalcMapResolution( MapMode( eUnit ), mnDPIX, mnDPIY,
2150 pFrameData->maMapUnitRes );
2153 // Es wird kein BigInt gebraucht, da diese Funktion nur zur Umrechnung
2154 // von Fensterposition benutzt wird
2155 nY = nY * mnDPIY * pFrameData->maMapUnitRes.mnMapScNumY;
2156 nY += nY >= 0 ? (pFrameData->maMapUnitRes.mnMapScDenomY/2) :
2157 -((pFrameData->maMapUnitRes.mnMapScDenomY-1)/2);
2158 nY /= pFrameData->maMapUnitRes.mnMapScDenomY;
2161 return nY;
2164 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */