update emoji autocorrect entries from po-files
[LibreOffice.git] / vcl / source / outdev / map.cxx
bloba33ef24d4373afd7e164b6d169ad3d8f59a0b594
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 .
20 #include <sal/config.h>
22 #include <cstdlib>
23 #include <limits.h>
25 #include <o3tl/numeric.hxx>
26 #include <tools/bigint.hxx>
28 #include <vcl/virdev.hxx>
29 #include <vcl/wrkwin.hxx>
30 #include <vcl/outdev.hxx>
31 #include <vcl/cursor.hxx>
33 #include <svdata.hxx>
34 #include <window.h>
35 #include <outdev.h>
37 #include <basegfx/matrix/b2dhommatrix.hxx>
39 static int const s_ImplArySize = MAP_PIXEL+1;
40 static const long aImplNumeratorAry[s_ImplArySize] =
41 { 1, 1, 5, 50, 1, 1, 1, 1, 1, 1, 1 };
42 static const long aImplDenominatorAry[s_ImplArySize] =
43 { 2540, 254, 127, 127, 1000, 100, 10, 1, 72, 1440, 1 };
46 Reduces accuracy until it is a fraction (should become
47 ctor fraction once); we could also do this with BigInts
50 static Fraction ImplMakeFraction( long nN1, long nN2, long nD1, long nD2 )
52 if( nD1 == 0 || nD2 == 0 ) //under these bad circumstances the following while loop will be endless
54 DBG_ASSERT(false,"Invalid parameter for ImplMakeFraction");
55 return Fraction( 1, 1 );
58 long i = 1;
60 if ( nN1 < 0 ) { i = -i; nN1 = -nN1; }
61 if ( nN2 < 0 ) { i = -i; nN2 = -nN2; }
62 if ( nD1 < 0 ) { i = -i; nD1 = -nD1; }
63 if ( nD2 < 0 ) { i = -i; nD2 = -nD2; }
64 // all positive; i sign
66 Fraction aF = Fraction( i*nN1, nD1 ) * Fraction( nN2, nD2 );
68 while ( !aF.IsValid() ) {
69 if ( nN1 > nN2 )
70 nN1 = (nN1 + 1) / 2;
71 else
72 nN2 = (nN2 + 1) / 2;
73 if ( nD1 > nD2 )
74 nD1 = (nD1 + 1) / 2;
75 else
76 nD2 = (nD2 + 1) / 2;
78 aF = Fraction( i*nN1, nD1 ) * Fraction( nN2, nD2 );
81 aF.ReduceInaccurate(32);
82 return aF;
85 // Fraction.GetNumerator()
86 // Fraction.GetDenominator() > 0
87 // rOutRes.nPixPerInch? > 0
88 // rMapRes.nMapScNum?
89 // rMapRes.nMapScDenom? > 0
91 static void ImplCalcBigIntThreshold( long nDPIX, long nDPIY,
92 const ImplMapRes& rMapRes,
93 ImplThresholdRes& rThresRes )
95 if ( nDPIX && (LONG_MAX / nDPIX < std::abs( rMapRes.mnMapScNumX ) ) ) // #111139# avoid div by zero
97 rThresRes.mnThresLogToPixX = 0;
98 rThresRes.mnThresPixToLogX = 0;
100 else
102 // calculate thresholds for BigInt arithmetic
103 long nDenomHalfX = rMapRes.mnMapScDenomX / 2;
104 sal_uLong nDenomX = rMapRes.mnMapScDenomX;
105 long nProductX = nDPIX * rMapRes.mnMapScNumX;
107 if ( !nProductX )
108 rThresRes.mnThresLogToPixX = LONG_MAX;
109 else
110 rThresRes.mnThresLogToPixX = std::abs( (LONG_MAX - nDenomHalfX) / nProductX );
112 if ( !nDenomX )
113 rThresRes.mnThresPixToLogX = LONG_MAX;
114 else if ( nProductX >= 0 )
115 rThresRes.mnThresPixToLogX = (long)(((sal_uLong)LONG_MAX - (sal_uLong)( nProductX/2)) / nDenomX);
116 else
117 rThresRes.mnThresPixToLogX = (long)(((sal_uLong)LONG_MAX + (sal_uLong)(-nProductX/2)) / nDenomX);
120 if ( nDPIY && (LONG_MAX / nDPIY < std::abs( rMapRes.mnMapScNumY ) ) ) // #111139# avoid div by zero
122 rThresRes.mnThresLogToPixY = 0;
123 rThresRes.mnThresPixToLogY = 0;
125 else
127 // calculate thresholds for BigInt arithmetic
128 long nDenomHalfY = rMapRes.mnMapScDenomY / 2;
129 sal_uLong nDenomY = rMapRes.mnMapScDenomY;
130 long nProductY = nDPIY * rMapRes.mnMapScNumY;
132 if ( !nProductY )
133 rThresRes.mnThresLogToPixY = LONG_MAX;
134 else
135 rThresRes.mnThresLogToPixY = std::abs( (LONG_MAX - nDenomHalfY) / nProductY );
137 if ( !nDenomY )
138 rThresRes.mnThresPixToLogY = LONG_MAX;
139 else if ( nProductY >= 0 )
140 rThresRes.mnThresPixToLogY = (long)(((sal_uLong)LONG_MAX - (sal_uLong)( nProductY/2)) / nDenomY);
141 else
142 rThresRes.mnThresPixToLogY = (long)(((sal_uLong)LONG_MAX + (sal_uLong)(-nProductY/2)) / nDenomY);
145 rThresRes.mnThresLogToPixX /= 2;
146 rThresRes.mnThresLogToPixY /= 2;
147 rThresRes.mnThresPixToLogX /= 2;
148 rThresRes.mnThresPixToLogY /= 2;
151 static void ImplCalcMapResolution( const MapMode& rMapMode,
152 long nDPIX, long nDPIY, ImplMapRes& rMapRes )
154 rMapRes.mfScaleX = 1.0;
155 rMapRes.mfScaleY = 1.0;
156 switch ( rMapMode.GetMapUnit() )
158 case MAP_RELATIVE:
159 break;
160 case MAP_100TH_MM:
161 rMapRes.mnMapScNumX = 1;
162 rMapRes.mnMapScDenomX = 2540;
163 rMapRes.mnMapScNumY = 1;
164 rMapRes.mnMapScDenomY = 2540;
165 break;
166 case MAP_10TH_MM:
167 rMapRes.mnMapScNumX = 1;
168 rMapRes.mnMapScDenomX = 254;
169 rMapRes.mnMapScNumY = 1;
170 rMapRes.mnMapScDenomY = 254;
171 break;
172 case MAP_MM:
173 rMapRes.mnMapScNumX = 5; // 10
174 rMapRes.mnMapScDenomX = 127; // 254
175 rMapRes.mnMapScNumY = 5; // 10
176 rMapRes.mnMapScDenomY = 127; // 254
177 break;
178 case MAP_CM:
179 rMapRes.mnMapScNumX = 50; // 100
180 rMapRes.mnMapScDenomX = 127; // 254
181 rMapRes.mnMapScNumY = 50; // 100
182 rMapRes.mnMapScDenomY = 127; // 254
183 break;
184 case MAP_1000TH_INCH:
185 rMapRes.mnMapScNumX = 1;
186 rMapRes.mnMapScDenomX = 1000;
187 rMapRes.mnMapScNumY = 1;
188 rMapRes.mnMapScDenomY = 1000;
189 break;
190 case MAP_100TH_INCH:
191 rMapRes.mnMapScNumX = 1;
192 rMapRes.mnMapScDenomX = 100;
193 rMapRes.mnMapScNumY = 1;
194 rMapRes.mnMapScDenomY = 100;
195 break;
196 case MAP_10TH_INCH:
197 rMapRes.mnMapScNumX = 1;
198 rMapRes.mnMapScDenomX = 10;
199 rMapRes.mnMapScNumY = 1;
200 rMapRes.mnMapScDenomY = 10;
201 break;
202 case MAP_INCH:
203 rMapRes.mnMapScNumX = 1;
204 rMapRes.mnMapScDenomX = 1;
205 rMapRes.mnMapScNumY = 1;
206 rMapRes.mnMapScDenomY = 1;
207 break;
208 case MAP_POINT:
209 rMapRes.mnMapScNumX = 1;
210 rMapRes.mnMapScDenomX = 72;
211 rMapRes.mnMapScNumY = 1;
212 rMapRes.mnMapScDenomY = 72;
213 break;
214 case MAP_TWIP:
215 rMapRes.mnMapScNumX = 1;
216 rMapRes.mnMapScDenomX = 1440;
217 rMapRes.mnMapScNumY = 1;
218 rMapRes.mnMapScDenomY = 1440;
219 break;
220 case MAP_PIXEL:
221 rMapRes.mnMapScNumX = 1;
222 rMapRes.mnMapScDenomX = nDPIX;
223 rMapRes.mnMapScNumY = 1;
224 rMapRes.mnMapScDenomY = nDPIY;
225 break;
226 case MAP_SYSFONT:
227 case MAP_APPFONT:
229 ImplSVData* pSVData = ImplGetSVData();
230 if ( !pSVData->maGDIData.mnAppFontX )
232 if( pSVData->maWinData.mpFirstFrame )
233 vcl::Window::ImplInitAppFontData( pSVData->maWinData.mpFirstFrame );
234 else
236 ScopedVclPtrInstance<WorkWindow> pWin( nullptr, 0 );
237 vcl::Window::ImplInitAppFontData( pWin );
240 rMapRes.mnMapScNumX = pSVData->maGDIData.mnAppFontX;
241 rMapRes.mnMapScDenomX = nDPIX * 40;
242 rMapRes.mnMapScNumY = pSVData->maGDIData.mnAppFontY;
243 rMapRes.mnMapScDenomY = nDPIY * 80;
245 break;
246 default:
247 OSL_FAIL( "unhandled MapUnit" );
248 break;
251 Fraction aScaleX = rMapMode.GetScaleX();
252 Fraction aScaleY = rMapMode.GetScaleY();
254 // set offset according to MapMode
255 Point aOrigin = rMapMode.GetOrigin();
256 if ( rMapMode.GetMapUnit() != MAP_RELATIVE )
258 rMapRes.mnMapOfsX = aOrigin.X();
259 rMapRes.mnMapOfsY = aOrigin.Y();
260 rMapRes.mfOffsetX = aOrigin.X();
261 rMapRes.mfOffsetY = aOrigin.Y();
263 else
265 if (!aScaleX.GetNumerator() || !aScaleY.GetNumerator())
266 throw o3tl::divide_by_zero();
268 rMapRes.mfOffsetX *= aScaleX.GetDenominator();
269 rMapRes.mfOffsetX /= aScaleX.GetNumerator();
270 rMapRes.mfOffsetX += aOrigin.X();
271 rMapRes.mfOffsetY *= aScaleY.GetDenominator();
272 rMapRes.mfOffsetY /= aScaleY.GetNumerator();
273 rMapRes.mfOffsetY += aOrigin.Y();
275 BigInt aX( rMapRes.mnMapOfsX );
276 aX *= BigInt( aScaleX.GetDenominator() );
277 if ( rMapRes.mnMapOfsX >= 0 )
279 if ( aScaleX.GetNumerator() >= 0 )
280 aX += BigInt( aScaleX.GetNumerator()/2 );
281 else
282 aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
284 else
286 if ( aScaleX.GetNumerator() >= 0 )
287 aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
288 else
289 aX += BigInt( aScaleX.GetNumerator()/2 );
291 aX /= BigInt( aScaleX.GetNumerator() );
292 rMapRes.mnMapOfsX = (long)aX + aOrigin.X();
293 BigInt aY( rMapRes.mnMapOfsY );
294 aY *= BigInt( aScaleY.GetDenominator() );
295 if( rMapRes.mnMapOfsY >= 0 )
297 if ( aScaleY.GetNumerator() >= 0 )
298 aY += BigInt( aScaleY.GetNumerator()/2 );
299 else
300 aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
302 else
304 if ( aScaleY.GetNumerator() >= 0 )
305 aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
306 else
307 aY += BigInt( aScaleY.GetNumerator()/2 );
309 aY /= BigInt( aScaleY.GetNumerator() );
310 rMapRes.mnMapOfsY = (long)aY + aOrigin.Y();
313 rMapRes.mfScaleX *= (double)rMapRes.mnMapScNumX * (double)aScaleX.GetNumerator() /
314 ((double)rMapRes.mnMapScDenomX * (double)aScaleX.GetDenominator());
315 rMapRes.mfScaleY *= (double)rMapRes.mnMapScNumY * (double)aScaleY.GetNumerator() /
316 ((double)rMapRes.mnMapScDenomY * (double)aScaleY.GetDenominator());
318 // calculate scaling factor according to MapMode
319 // aTemp? = rMapRes.mnMapSc? * aScale?
320 Fraction aTempX = ImplMakeFraction( rMapRes.mnMapScNumX,
321 aScaleX.GetNumerator(),
322 rMapRes.mnMapScDenomX,
323 aScaleX.GetDenominator() );
324 Fraction aTempY = ImplMakeFraction( rMapRes.mnMapScNumY,
325 aScaleY.GetNumerator(),
326 rMapRes.mnMapScDenomY,
327 aScaleY.GetDenominator() );
328 rMapRes.mnMapScNumX = aTempX.GetNumerator();
329 rMapRes.mnMapScDenomX = aTempX.GetDenominator();
330 rMapRes.mnMapScNumY = aTempY.GetNumerator();
331 rMapRes.mnMapScDenomY = aTempY.GetDenominator();
334 inline void ImplCalcMapResolution( const MapMode& rMapMode,
335 long nDPIX, long nDPIY,
336 ImplMapRes& rMapRes,
337 ImplThresholdRes& rThresRes )
339 ImplCalcMapResolution( rMapMode, nDPIX, nDPIY, rMapRes );
340 ImplCalcBigIntThreshold( nDPIX, nDPIY, rMapRes, rThresRes );
343 // #i75163#
344 void OutputDevice::ImplInvalidateViewTransform()
346 if(!mpOutDevData)
347 return;
349 if(mpOutDevData->mpViewTransform)
351 delete mpOutDevData->mpViewTransform;
352 mpOutDevData->mpViewTransform = NULL;
355 if(mpOutDevData->mpInverseViewTransform)
357 delete mpOutDevData->mpInverseViewTransform;
358 mpOutDevData->mpInverseViewTransform = NULL;
362 static long ImplLogicToPixel( long n, long nDPI, long nMapNum, long nMapDenom,
363 long nThres )
365 // To "use" it...
366 (void) nThres;
367 #if (SAL_TYPES_SIZEOFLONG < 8)
368 if( (+n < nThres) && (-n < nThres) )
370 n *= nMapNum * nDPI;
371 if( nMapDenom != 1 )
373 n = (2 * n) / nMapDenom;
374 if( n < 0 ) --n; else ++n;
375 n /= 2;
378 else
379 #else
380 assert(nMapNum >= 0);
381 assert(nDPI > 0);
382 assert(nMapNum == 0 || std::abs(n) < std::numeric_limits<long>::max() / nMapNum / nDPI); //detect overflows
383 #endif
385 sal_Int64 n64 = n;
386 n64 *= nMapNum;
387 n64 *= nDPI;
388 if( nMapDenom == 1 )
389 n = (long)n64;
390 else
392 n = (long)(2 * n64 / nMapDenom);
393 if( n < 0 ) --n; else ++n;
394 n /= 2;
397 return n;
400 static long ImplPixelToLogic( long n, long nDPI, long nMapNum, long nMapDenom,
401 long nThres )
403 // To "use" it...
404 (void) nThres;
405 if (nMapNum == 0)
407 return 0;
409 #if (SAL_TYPES_SIZEOFLONG < 8)
410 if( (+n < nThres) && (-n < nThres) )
411 n = (2 * n * nMapDenom) / (nDPI * nMapNum);
412 else
413 #endif
415 sal_Int64 n64 = n;
416 n64 *= nMapDenom;
417 long nDenom = nDPI * nMapNum;
418 n = (long)(2 * n64 / nDenom);
420 if( n < 0 ) --n; else ++n;
421 return (n / 2);
424 long OutputDevice::ImplLogicXToDevicePixel( long nX ) const
426 if ( !mbMap )
427 return nX+mnOutOffX;
429 return ImplLogicToPixel( nX + maMapRes.mnMapOfsX, mnDPIX,
430 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
431 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX;
434 long OutputDevice::ImplLogicYToDevicePixel( long nY ) const
436 if ( !mbMap )
437 return nY+mnOutOffY;
439 return ImplLogicToPixel( nY + maMapRes.mnMapOfsY, mnDPIY,
440 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
441 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY;
444 long OutputDevice::ImplLogicWidthToDevicePixel( long nWidth ) const
446 if ( !mbMap )
447 return nWidth;
449 return ImplLogicToPixel( nWidth, mnDPIX,
450 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
451 maThresRes.mnThresLogToPixX );
454 long OutputDevice::ImplLogicHeightToDevicePixel( long nHeight ) const
456 if ( !mbMap )
457 return nHeight;
459 return ImplLogicToPixel( nHeight, mnDPIY,
460 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
461 maThresRes.mnThresLogToPixY );
464 float OutputDevice::ImplFloatLogicHeightToDevicePixel( float fLogicHeight) const
466 if( !mbMap)
467 return fLogicHeight;
468 float fPixelHeight = (fLogicHeight * mnDPIY * maMapRes.mnMapScNumY) / maMapRes.mnMapScDenomY;
469 return fPixelHeight;
472 long OutputDevice::ImplDevicePixelToLogicWidth( long nWidth ) const
474 if ( !mbMap )
475 return nWidth;
477 return ImplPixelToLogic( nWidth, mnDPIX,
478 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
479 maThresRes.mnThresPixToLogX );
482 long OutputDevice::ImplDevicePixelToLogicHeight( long nHeight ) const
484 if ( !mbMap )
485 return nHeight;
487 return ImplPixelToLogic( nHeight, mnDPIY,
488 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
489 maThresRes.mnThresPixToLogY );
492 Point OutputDevice::ImplLogicToDevicePixel( const Point& rLogicPt ) const
494 if ( !mbMap )
495 return Point( rLogicPt.X()+mnOutOffX, rLogicPt.Y()+mnOutOffY );
497 return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
498 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
499 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX,
500 ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
501 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
502 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY );
505 Size OutputDevice::ImplLogicToDevicePixel( const Size& rLogicSize ) const
507 if ( !mbMap )
508 return rLogicSize;
510 return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
511 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
512 maThresRes.mnThresLogToPixX ),
513 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
514 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
515 maThresRes.mnThresLogToPixY ) );
518 Rectangle OutputDevice::ImplLogicToDevicePixel( const Rectangle& rLogicRect ) const
520 if ( rLogicRect.IsEmpty() )
521 return rLogicRect;
523 if ( !mbMap )
525 return Rectangle( rLogicRect.Left()+mnOutOffX, rLogicRect.Top()+mnOutOffY,
526 rLogicRect.Right()+mnOutOffX, rLogicRect.Bottom()+mnOutOffY );
529 return Rectangle( ImplLogicToPixel( rLogicRect.Left()+maMapRes.mnMapOfsX, mnDPIX,
530 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
531 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX,
532 ImplLogicToPixel( rLogicRect.Top()+maMapRes.mnMapOfsY, mnDPIY,
533 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
534 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY,
535 ImplLogicToPixel( rLogicRect.Right()+maMapRes.mnMapOfsX, mnDPIX,
536 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
537 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX,
538 ImplLogicToPixel( rLogicRect.Bottom()+maMapRes.mnMapOfsY, mnDPIY,
539 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
540 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY );
543 Polygon OutputDevice::ImplLogicToDevicePixel( const Polygon& rLogicPoly ) const
545 if ( !mbMap && !mnOutOffX && !mnOutOffY )
546 return rLogicPoly;
548 sal_uInt16 i;
549 sal_uInt16 nPoints = rLogicPoly.GetSize();
550 Polygon aPoly( rLogicPoly );
552 // get pointer to Point-array (copy data)
553 const Point* pPointAry = aPoly.GetConstPointAry();
555 if ( mbMap )
557 for ( i = 0; i < nPoints; i++ )
559 const Point* pPt = &(pPointAry[i]);
560 Point aPt;
561 aPt.X() = ImplLogicToPixel( pPt->X()+maMapRes.mnMapOfsX, mnDPIX,
562 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
563 maThresRes.mnThresLogToPixX )+mnOutOffX+mnOutOffOrigX;
564 aPt.Y() = ImplLogicToPixel( pPt->Y()+maMapRes.mnMapOfsY, mnDPIY,
565 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
566 maThresRes.mnThresLogToPixY )+mnOutOffY+mnOutOffOrigY;
567 aPoly[i] = aPt;
570 else
572 for ( i = 0; i < nPoints; i++ )
574 Point aPt = pPointAry[i];
575 aPt.X() += mnOutOffX;
576 aPt.Y() += mnOutOffY;
577 aPoly[i] = aPt;
581 return aPoly;
584 tools::PolyPolygon OutputDevice::ImplLogicToDevicePixel( const tools::PolyPolygon& rLogicPolyPoly ) const
586 if ( !mbMap && !mnOutOffX && !mnOutOffY )
587 return rLogicPolyPoly;
589 tools::PolyPolygon aPolyPoly( rLogicPolyPoly );
590 sal_uInt16 nPoly = aPolyPoly.Count();
591 for( sal_uInt16 i = 0; i < nPoly; i++ )
593 Polygon& rPoly = aPolyPoly[i];
594 rPoly = ImplLogicToDevicePixel( rPoly );
596 return aPolyPoly;
599 LineInfo OutputDevice::ImplLogicToDevicePixel( const LineInfo& rLineInfo ) const
601 LineInfo aInfo( rLineInfo );
603 if( aInfo.GetStyle() == LINE_DASH )
605 if( aInfo.GetDotCount() && aInfo.GetDotLen() )
606 aInfo.SetDotLen( std::max( ImplLogicWidthToDevicePixel( aInfo.GetDotLen() ), 1L ) );
607 else
608 aInfo.SetDotCount( 0 );
610 if( aInfo.GetDashCount() && aInfo.GetDashLen() )
611 aInfo.SetDashLen( std::max( ImplLogicWidthToDevicePixel( aInfo.GetDashLen() ), 1L ) );
612 else
613 aInfo.SetDashCount( 0 );
615 aInfo.SetDistance( ImplLogicWidthToDevicePixel( aInfo.GetDistance() ) );
617 if( ( !aInfo.GetDashCount() && !aInfo.GetDotCount() ) || !aInfo.GetDistance() )
618 aInfo.SetStyle( LINE_SOLID );
621 aInfo.SetWidth( ImplLogicWidthToDevicePixel( aInfo.GetWidth() ) );
623 return aInfo;
626 Rectangle OutputDevice::ImplDevicePixelToLogic( const Rectangle& rPixelRect ) const
628 if ( rPixelRect.IsEmpty() )
629 return rPixelRect;
631 if ( !mbMap )
633 return Rectangle( rPixelRect.Left()-mnOutOffX, rPixelRect.Top()-mnOutOffY,
634 rPixelRect.Right()-mnOutOffX, rPixelRect.Bottom()-mnOutOffY );
637 return Rectangle( ImplPixelToLogic( rPixelRect.Left()-mnOutOffX-mnOutOffOrigX, mnDPIX,
638 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
639 maThresRes.mnThresPixToLogX )-maMapRes.mnMapOfsX,
640 ImplPixelToLogic( rPixelRect.Top()-mnOutOffY-mnOutOffOrigY, mnDPIY,
641 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
642 maThresRes.mnThresPixToLogY )-maMapRes.mnMapOfsY,
643 ImplPixelToLogic( rPixelRect.Right()-mnOutOffX-mnOutOffOrigX, mnDPIX,
644 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
645 maThresRes.mnThresPixToLogX )-maMapRes.mnMapOfsX,
646 ImplPixelToLogic( rPixelRect.Bottom()-mnOutOffY-mnOutOffOrigY, mnDPIY,
647 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
648 maThresRes.mnThresPixToLogY )-maMapRes.mnMapOfsY );
651 vcl::Region OutputDevice::ImplPixelToDevicePixel( const vcl::Region& rRegion ) const
653 if ( !mnOutOffX && !mnOutOffY )
654 return rRegion;
656 vcl::Region aRegion( rRegion );
657 aRegion.Move( mnOutOffX+mnOutOffOrigX, mnOutOffY+mnOutOffOrigY );
658 return aRegion;
661 void OutputDevice::EnableMapMode( bool bEnable )
663 mbMap = bEnable;
665 if( mpAlphaVDev )
666 mpAlphaVDev->EnableMapMode( bEnable );
669 void OutputDevice::SetMapMode()
672 if ( mpMetaFile )
673 mpMetaFile->AddAction( new MetaMapModeAction( MapMode() ) );
675 if ( mbMap || !maMapMode.IsDefault() )
677 mbMap = false;
678 maMapMode = MapMode();
680 // create new objects (clip region are not re-scaled)
681 mbNewFont = true;
682 mbInitFont = true;
683 if ( GetOutDevType() == OUTDEV_WINDOW )
685 if ( static_cast<vcl::Window*>(this)->mpWindowImpl->mpCursor )
686 static_cast<vcl::Window*>(this)->mpWindowImpl->mpCursor->ImplNew();
689 // #106426# Adapt logical offset when changing mapmode
690 mnOutOffLogicX = mnOutOffOrigX; // no mapping -> equal offsets
691 mnOutOffLogicY = mnOutOffOrigY;
693 // #i75163#
694 ImplInvalidateViewTransform();
697 if( mpAlphaVDev )
698 mpAlphaVDev->SetMapMode();
701 void OutputDevice::SetMapMode( const MapMode& rNewMapMode )
704 bool bRelMap = (rNewMapMode.GetMapUnit() == MAP_RELATIVE);
706 if ( mpMetaFile )
708 mpMetaFile->AddAction( new MetaMapModeAction( rNewMapMode ) );
709 #ifdef DBG_UTIL
710 if ( GetOutDevType() != OUTDEV_PRINTER )
711 DBG_ASSERTWARNING( bRelMap, "Please record only relative MapModes!" );
712 #endif
715 // do nothing if MapMode was not changed
716 if ( maMapMode == rNewMapMode )
717 return;
719 if( mpAlphaVDev )
720 mpAlphaVDev->SetMapMode( rNewMapMode );
722 // if default MapMode calculate nothing
723 bool bOldMap = mbMap;
724 mbMap = !rNewMapMode.IsDefault();
725 if ( mbMap )
727 // if only the origin is converted, do not scale new
728 if ( (rNewMapMode.GetMapUnit() == maMapMode.GetMapUnit()) &&
729 (rNewMapMode.GetScaleX() == maMapMode.GetScaleX()) &&
730 (rNewMapMode.GetScaleY() == maMapMode.GetScaleY()) &&
731 (bOldMap == mbMap) )
733 // set offset
734 Point aOrigin = rNewMapMode.GetOrigin();
735 maMapRes.mnMapOfsX = aOrigin.X();
736 maMapRes.mnMapOfsY = aOrigin.Y();
737 maMapRes.mfOffsetX = aOrigin.X();
738 maMapRes.mfOffsetY = aOrigin.Y();
739 maMapMode = rNewMapMode;
741 // #i75163#
742 ImplInvalidateViewTransform();
744 return;
746 if ( !bOldMap && bRelMap )
748 maMapRes.mnMapScNumX = 1;
749 maMapRes.mnMapScNumY = 1;
750 maMapRes.mnMapScDenomX = mnDPIX;
751 maMapRes.mnMapScDenomY = mnDPIY;
752 maMapRes.mnMapOfsX = 0;
753 maMapRes.mnMapOfsY = 0;
754 maMapRes.mfOffsetX = 0.0;
755 maMapRes.mfOffsetY = 0.0;
756 maMapRes.mfScaleX = (double)1/(double)mnDPIX;
757 maMapRes.mfScaleY = (double)1/(double)mnDPIY;
760 // calculate new MapMode-resolution
761 ImplCalcMapResolution( rNewMapMode, mnDPIX, mnDPIY, maMapRes, maThresRes );
764 // set new MapMode
765 if ( bRelMap )
767 Point aOrigin( maMapRes.mnMapOfsX, maMapRes.mnMapOfsY );
768 // aScale? = maMapMode.GetScale?() * rNewMapMode.GetScale?()
769 Fraction aScaleX = ImplMakeFraction( maMapMode.GetScaleX().GetNumerator(),
770 rNewMapMode.GetScaleX().GetNumerator(),
771 maMapMode.GetScaleX().GetDenominator(),
772 rNewMapMode.GetScaleX().GetDenominator() );
773 Fraction aScaleY = ImplMakeFraction( maMapMode.GetScaleY().GetNumerator(),
774 rNewMapMode.GetScaleY().GetNumerator(),
775 maMapMode.GetScaleY().GetDenominator(),
776 rNewMapMode.GetScaleY().GetDenominator() );
777 maMapMode.SetOrigin( aOrigin );
778 maMapMode.SetScaleX( aScaleX );
779 maMapMode.SetScaleY( aScaleY );
781 else
782 maMapMode = rNewMapMode;
784 // create new objects (clip region are not re-scaled)
785 mbNewFont = true;
786 mbInitFont = true;
787 if ( GetOutDevType() == OUTDEV_WINDOW )
789 if ( static_cast<vcl::Window*>(this)->mpWindowImpl->mpCursor )
790 static_cast<vcl::Window*>(this)->mpWindowImpl->mpCursor->ImplNew();
793 // #106426# Adapt logical offset when changing mapmode
794 mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
795 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
796 maThresRes.mnThresPixToLogX );
797 mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
798 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
799 maThresRes.mnThresPixToLogY );
801 // #i75163#
802 ImplInvalidateViewTransform();
805 void OutputDevice::SetRelativeMapMode( const MapMode& rNewMapMode )
807 // do nothing if MapMode did not change
808 if ( maMapMode == rNewMapMode )
809 return;
811 MapUnit eOld = maMapMode.GetMapUnit();
812 MapUnit eNew = rNewMapMode.GetMapUnit();
814 // a?F = rNewMapMode.GetScale?() / maMapMode.GetScale?()
815 Fraction aXF = ImplMakeFraction( rNewMapMode.GetScaleX().GetNumerator(),
816 maMapMode.GetScaleX().GetDenominator(),
817 rNewMapMode.GetScaleX().GetDenominator(),
818 maMapMode.GetScaleX().GetNumerator() );
819 Fraction aYF = ImplMakeFraction( rNewMapMode.GetScaleY().GetNumerator(),
820 maMapMode.GetScaleY().GetDenominator(),
821 rNewMapMode.GetScaleY().GetDenominator(),
822 maMapMode.GetScaleY().GetNumerator() );
824 Point aPt( LogicToLogic( Point(), NULL, &rNewMapMode ) );
825 if ( eNew != eOld )
827 if ( eOld > MAP_PIXEL )
829 SAL_WARN( "vcl.gdi", "Not implemented MapUnit" );
831 else if ( eNew > MAP_PIXEL )
833 SAL_WARN( "vcl.gdi", "Not implemented MapUnit" );
835 else
837 Fraction aF( aImplNumeratorAry[eNew] * aImplDenominatorAry[eOld],
838 aImplNumeratorAry[eOld] * aImplDenominatorAry[eNew] );
840 // a?F = a?F * aF
841 aXF = ImplMakeFraction( aXF.GetNumerator(), aF.GetNumerator(),
842 aXF.GetDenominator(), aF.GetDenominator() );
843 aYF = ImplMakeFraction( aYF.GetNumerator(), aF.GetNumerator(),
844 aYF.GetDenominator(), aF.GetDenominator() );
845 if ( eOld == MAP_PIXEL )
847 aXF *= Fraction( mnDPIX, 1 );
848 aYF *= Fraction( mnDPIY, 1 );
850 else if ( eNew == MAP_PIXEL )
852 aXF *= Fraction( 1, mnDPIX );
853 aYF *= Fraction( 1, mnDPIY );
858 MapMode aNewMapMode( MAP_RELATIVE, Point( -aPt.X(), -aPt.Y() ), aXF, aYF );
859 SetMapMode( aNewMapMode );
861 if ( eNew != eOld )
862 maMapMode = rNewMapMode;
864 // #106426# Adapt logical offset when changing MapMode
865 mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
866 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
867 maThresRes.mnThresPixToLogX );
868 mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
869 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
870 maThresRes.mnThresPixToLogY );
872 if( mpAlphaVDev )
873 mpAlphaVDev->SetRelativeMapMode( rNewMapMode );
876 // #i75163#
877 basegfx::B2DHomMatrix OutputDevice::GetViewTransformation() const
879 if(mbMap)
881 if(!mpOutDevData->mpViewTransform)
883 mpOutDevData->mpViewTransform = new basegfx::B2DHomMatrix;
885 const double fScaleFactorX((double)mnDPIX * (double)maMapRes.mnMapScNumX / (double)maMapRes.mnMapScDenomX);
886 const double fScaleFactorY((double)mnDPIY * (double)maMapRes.mnMapScNumY / (double)maMapRes.mnMapScDenomY);
887 const double fZeroPointX(((double)maMapRes.mnMapOfsX * fScaleFactorX) + (double)mnOutOffOrigX);
888 const double fZeroPointY(((double)maMapRes.mnMapOfsY * fScaleFactorY) + (double)mnOutOffOrigY);
890 mpOutDevData->mpViewTransform->set(0, 0, fScaleFactorX);
891 mpOutDevData->mpViewTransform->set(1, 1, fScaleFactorY);
892 mpOutDevData->mpViewTransform->set(0, 2, fZeroPointX);
893 mpOutDevData->mpViewTransform->set(1, 2, fZeroPointY);
896 return *mpOutDevData->mpViewTransform;
898 else
900 return basegfx::B2DHomMatrix();
904 // #i75163#
905 basegfx::B2DHomMatrix OutputDevice::GetInverseViewTransformation() const
907 if(mbMap)
909 if(!mpOutDevData->mpInverseViewTransform)
911 GetViewTransformation();
912 mpOutDevData->mpInverseViewTransform = new basegfx::B2DHomMatrix(*mpOutDevData->mpViewTransform);
913 mpOutDevData->mpInverseViewTransform->invert();
916 return *mpOutDevData->mpInverseViewTransform;
918 else
920 return basegfx::B2DHomMatrix();
924 // #i75163#
925 basegfx::B2DHomMatrix OutputDevice::GetViewTransformation( const MapMode& rMapMode ) const
927 // #i82615#
928 ImplMapRes aMapRes;
929 ImplThresholdRes aThresRes;
930 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
932 basegfx::B2DHomMatrix aTransform;
934 const double fScaleFactorX((double)mnDPIX * (double)aMapRes.mnMapScNumX / (double)aMapRes.mnMapScDenomX);
935 const double fScaleFactorY((double)mnDPIY * (double)aMapRes.mnMapScNumY / (double)aMapRes.mnMapScDenomY);
936 const double fZeroPointX(((double)aMapRes.mnMapOfsX * fScaleFactorX) + (double)mnOutOffOrigX);
937 const double fZeroPointY(((double)aMapRes.mnMapOfsY * fScaleFactorY) + (double)mnOutOffOrigY);
939 aTransform.set(0, 0, fScaleFactorX);
940 aTransform.set(1, 1, fScaleFactorY);
941 aTransform.set(0, 2, fZeroPointX);
942 aTransform.set(1, 2, fZeroPointY);
944 return aTransform;
947 // #i75163#
948 basegfx::B2DHomMatrix OutputDevice::GetInverseViewTransformation( const MapMode& rMapMode ) const
950 basegfx::B2DHomMatrix aMatrix( GetViewTransformation( rMapMode ) );
951 aMatrix.invert();
952 return aMatrix;
955 basegfx::B2DHomMatrix OutputDevice::ImplGetDeviceTransformation() const
957 basegfx::B2DHomMatrix aTransformation = GetViewTransformation();
958 // TODO: is it worth to cache the transformed result?
959 if( mnOutOffX || mnOutOffY )
960 aTransformation.translate( mnOutOffX, mnOutOffY );
961 return aTransformation;
964 Point OutputDevice::LogicToPixel( const Point& rLogicPt ) const
967 if ( !mbMap )
968 return rLogicPt;
970 return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
971 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
972 maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
973 ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
974 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
975 maThresRes.mnThresLogToPixY )+mnOutOffOrigY );
978 Size OutputDevice::LogicToPixel( const Size& rLogicSize ) const
981 if ( !mbMap )
982 return rLogicSize;
984 return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
985 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
986 maThresRes.mnThresLogToPixX ),
987 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
988 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
989 maThresRes.mnThresLogToPixY ) );
992 Rectangle OutputDevice::LogicToPixel( const Rectangle& rLogicRect ) const
995 if ( !mbMap || rLogicRect.IsEmpty() )
996 return rLogicRect;
998 return Rectangle( ImplLogicToPixel( rLogicRect.Left() + maMapRes.mnMapOfsX, mnDPIX,
999 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1000 maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1001 ImplLogicToPixel( rLogicRect.Top() + maMapRes.mnMapOfsY, mnDPIY,
1002 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1003 maThresRes.mnThresLogToPixY )+mnOutOffOrigY,
1004 ImplLogicToPixel( rLogicRect.Right() + maMapRes.mnMapOfsX, mnDPIX,
1005 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1006 maThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1007 ImplLogicToPixel( rLogicRect.Bottom() + maMapRes.mnMapOfsY, mnDPIY,
1008 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1009 maThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1012 Polygon OutputDevice::LogicToPixel( const Polygon& rLogicPoly ) const
1015 if ( !mbMap )
1016 return rLogicPoly;
1018 sal_uInt16 i;
1019 sal_uInt16 nPoints = rLogicPoly.GetSize();
1020 Polygon aPoly( rLogicPoly );
1022 // get pointer to Point-array (copy data)
1023 const Point* pPointAry = aPoly.GetConstPointAry();
1025 for ( i = 0; i < nPoints; i++ )
1027 const Point* pPt = &(pPointAry[i]);
1028 Point aPt;
1029 aPt.X() = ImplLogicToPixel( pPt->X() + maMapRes.mnMapOfsX, mnDPIX,
1030 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1031 maThresRes.mnThresLogToPixX )+mnOutOffOrigX;
1032 aPt.Y() = ImplLogicToPixel( pPt->Y() + maMapRes.mnMapOfsY, mnDPIY,
1033 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1034 maThresRes.mnThresLogToPixY )+mnOutOffOrigY;
1035 aPoly[i] = aPt;
1038 return aPoly;
1041 tools::PolyPolygon OutputDevice::LogicToPixel( const tools::PolyPolygon& rLogicPolyPoly ) const
1044 if ( !mbMap )
1045 return rLogicPolyPoly;
1047 tools::PolyPolygon aPolyPoly( rLogicPolyPoly );
1048 sal_uInt16 nPoly = aPolyPoly.Count();
1049 for( sal_uInt16 i = 0; i < nPoly; i++ )
1051 Polygon& rPoly = aPolyPoly[i];
1052 rPoly = LogicToPixel( rPoly );
1054 return aPolyPoly;
1057 basegfx::B2DPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolygon& rLogicPoly ) const
1059 basegfx::B2DPolygon aTransformedPoly = rLogicPoly;
1060 const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation();
1061 aTransformedPoly.transform( rTransformationMatrix );
1062 return aTransformedPoly;
1065 basegfx::B2DPolyPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly ) const
1067 basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly;
1068 const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation();
1069 aTransformedPoly.transform( rTransformationMatrix );
1070 return aTransformedPoly;
1073 vcl::Region OutputDevice::LogicToPixel( const vcl::Region& rLogicRegion ) const
1076 if(!mbMap || rLogicRegion.IsNull() || rLogicRegion.IsEmpty())
1078 return rLogicRegion;
1081 vcl::Region aRegion;
1083 if(rLogicRegion.getB2DPolyPolygon())
1085 aRegion = vcl::Region(LogicToPixel(*rLogicRegion.getB2DPolyPolygon()));
1087 else if(rLogicRegion.getPolyPolygon())
1089 aRegion = vcl::Region(LogicToPixel(*rLogicRegion.getPolyPolygon()));
1091 else if(rLogicRegion.getRegionBand())
1093 RectangleVector aRectangles;
1094 rLogicRegion.GetRegionRectangles(aRectangles);
1095 const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
1097 // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1098 for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); ++aRectIter)
1100 aRegion.Union(LogicToPixel(*aRectIter));
1104 return aRegion;
1107 Point OutputDevice::LogicToPixel( const Point& rLogicPt,
1108 const MapMode& rMapMode ) const
1111 if ( rMapMode.IsDefault() )
1112 return rLogicPt;
1114 // convert MapMode resolution and convert
1115 ImplMapRes aMapRes;
1116 ImplThresholdRes aThresRes;
1117 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1119 return Point( ImplLogicToPixel( rLogicPt.X() + aMapRes.mnMapOfsX, mnDPIX,
1120 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1121 aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1122 ImplLogicToPixel( rLogicPt.Y() + aMapRes.mnMapOfsY, mnDPIY,
1123 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1124 aThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1127 Size OutputDevice::LogicToPixel( const Size& rLogicSize,
1128 const MapMode& rMapMode ) const
1131 if ( rMapMode.IsDefault() )
1132 return rLogicSize;
1134 // convert MapMode resolution and convert
1135 ImplMapRes aMapRes;
1136 ImplThresholdRes aThresRes;
1137 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1139 return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
1140 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1141 aThresRes.mnThresLogToPixX ),
1142 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
1143 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1144 aThresRes.mnThresLogToPixY ) );
1147 Rectangle OutputDevice::LogicToPixel( const Rectangle& rLogicRect,
1148 const MapMode& rMapMode ) const
1151 if ( rMapMode.IsDefault() || rLogicRect.IsEmpty() )
1152 return rLogicRect;
1154 // convert MapMode resolution and convert
1155 ImplMapRes aMapRes;
1156 ImplThresholdRes aThresRes;
1157 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1159 return Rectangle( ImplLogicToPixel( rLogicRect.Left() + aMapRes.mnMapOfsX, mnDPIX,
1160 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1161 aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1162 ImplLogicToPixel( rLogicRect.Top() + aMapRes.mnMapOfsY, mnDPIY,
1163 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1164 aThresRes.mnThresLogToPixY )+mnOutOffOrigY,
1165 ImplLogicToPixel( rLogicRect.Right() + aMapRes.mnMapOfsX, mnDPIX,
1166 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1167 aThresRes.mnThresLogToPixX )+mnOutOffOrigX,
1168 ImplLogicToPixel( rLogicRect.Bottom() + aMapRes.mnMapOfsY, mnDPIY,
1169 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1170 aThresRes.mnThresLogToPixY )+mnOutOffOrigY );
1173 Polygon OutputDevice::LogicToPixel( const Polygon& rLogicPoly,
1174 const MapMode& rMapMode ) const
1177 if ( rMapMode.IsDefault() )
1178 return rLogicPoly;
1180 // convert MapMode resolution and convert
1181 ImplMapRes aMapRes;
1182 ImplThresholdRes aThresRes;
1183 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1185 sal_uInt16 i;
1186 sal_uInt16 nPoints = rLogicPoly.GetSize();
1187 Polygon aPoly( rLogicPoly );
1189 // get pointer to Point-array (copy data)
1190 const Point* pPointAry = aPoly.GetConstPointAry();
1192 for ( i = 0; i < nPoints; i++ )
1194 const Point* pPt = &(pPointAry[i]);
1195 Point aPt;
1196 aPt.X() = ImplLogicToPixel( pPt->X() + aMapRes.mnMapOfsX, mnDPIX,
1197 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1198 aThresRes.mnThresLogToPixX )+mnOutOffOrigX;
1199 aPt.Y() = ImplLogicToPixel( pPt->Y() + aMapRes.mnMapOfsY, mnDPIY,
1200 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1201 aThresRes.mnThresLogToPixY )+mnOutOffOrigY;
1202 aPoly[i] = aPt;
1205 return aPoly;
1208 tools::PolyPolygon OutputDevice::LogicToPixel( const tools::PolyPolygon& rLogicPolyPoly,
1209 const MapMode& rMapMode ) const
1212 if ( rMapMode.IsDefault() )
1213 return rLogicPolyPoly;
1215 tools::PolyPolygon aPolyPoly( rLogicPolyPoly );
1216 sal_uInt16 nPoly = aPolyPoly.Count();
1217 for( sal_uInt16 i = 0; i < nPoly; i++ )
1219 Polygon& rPoly = aPolyPoly[i];
1220 rPoly = LogicToPixel( rPoly, rMapMode );
1222 return aPolyPoly;
1225 basegfx::B2DPolyPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon& rLogicPolyPoly,
1226 const MapMode& rMapMode ) const
1228 basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly;
1229 const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation( rMapMode );
1230 aTransformedPoly.transform( rTransformationMatrix );
1231 return aTransformedPoly;
1234 basegfx::B2DPolygon OutputDevice::LogicToPixel( const basegfx::B2DPolygon& rLogicPoly,
1235 const MapMode& rMapMode ) const
1237 basegfx::B2DPolygon aTransformedPoly = rLogicPoly;
1238 const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation( rMapMode );
1239 aTransformedPoly.transform( rTransformationMatrix );
1240 return aTransformedPoly;
1243 vcl::Region OutputDevice::LogicToPixel( const vcl::Region& rLogicRegion, const MapMode& rMapMode ) const
1246 if(rMapMode.IsDefault() || rLogicRegion.IsNull() || rLogicRegion.IsEmpty())
1248 return rLogicRegion;
1251 vcl::Region aRegion;
1253 if(rLogicRegion.getB2DPolyPolygon())
1255 aRegion = vcl::Region(LogicToPixel(*rLogicRegion.getB2DPolyPolygon(), rMapMode));
1257 else if(rLogicRegion.getPolyPolygon())
1259 aRegion = vcl::Region(LogicToPixel(*rLogicRegion.getPolyPolygon(), rMapMode));
1261 else if(rLogicRegion.getRegionBand())
1263 RectangleVector aRectangles;
1264 rLogicRegion.GetRegionRectangles(aRectangles);
1265 const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
1267 // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1268 for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); ++aRectIter)
1270 aRegion.Union(LogicToPixel(*aRectIter, rMapMode));
1274 return aRegion;
1277 Point OutputDevice::PixelToLogic( const Point& rDevicePt ) const
1280 if ( !mbMap )
1281 return rDevicePt;
1283 return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1284 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1285 maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1286 ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1287 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1288 maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY );
1291 Size OutputDevice::PixelToLogic( const Size& rDeviceSize ) const
1294 if ( !mbMap )
1295 return rDeviceSize;
1297 return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1298 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1299 maThresRes.mnThresPixToLogX ),
1300 ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1301 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1302 maThresRes.mnThresPixToLogY ) );
1305 Rectangle OutputDevice::PixelToLogic( const Rectangle& rDeviceRect ) const
1308 if ( !mbMap || rDeviceRect.IsEmpty() )
1309 return rDeviceRect;
1311 return Rectangle( ImplPixelToLogic( rDeviceRect.Left(), mnDPIX,
1312 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1313 maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1314 ImplPixelToLogic( rDeviceRect.Top(), mnDPIY,
1315 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1316 maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY,
1317 ImplPixelToLogic( rDeviceRect.Right(), mnDPIX,
1318 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1319 maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX,
1320 ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY,
1321 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1322 maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY );
1325 Polygon OutputDevice::PixelToLogic( const Polygon& rDevicePoly ) const
1328 if ( !mbMap )
1329 return rDevicePoly;
1331 sal_uInt16 i;
1332 sal_uInt16 nPoints = rDevicePoly.GetSize();
1333 Polygon aPoly( rDevicePoly );
1335 // get pointer to Point-array (copy data)
1336 const Point* pPointAry = aPoly.GetConstPointAry();
1338 for ( i = 0; i < nPoints; i++ )
1340 const Point* pPt = &(pPointAry[i]);
1341 Point aPt;
1342 aPt.X() = ImplPixelToLogic( pPt->X(), mnDPIX,
1343 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
1344 maThresRes.mnThresPixToLogX ) - maMapRes.mnMapOfsX - mnOutOffLogicX;
1345 aPt.Y() = ImplPixelToLogic( pPt->Y(), mnDPIY,
1346 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
1347 maThresRes.mnThresPixToLogY ) - maMapRes.mnMapOfsY - mnOutOffLogicY;
1348 aPoly[i] = aPt;
1351 return aPoly;
1354 tools::PolyPolygon OutputDevice::PixelToLogic( const tools::PolyPolygon& rDevicePolyPoly ) const
1357 if ( !mbMap )
1358 return rDevicePolyPoly;
1360 tools::PolyPolygon aPolyPoly( rDevicePolyPoly );
1361 sal_uInt16 nPoly = aPolyPoly.Count();
1362 for( sal_uInt16 i = 0; i < nPoly; i++ )
1364 Polygon& rPoly = aPolyPoly[i];
1365 rPoly = PixelToLogic( rPoly );
1367 return aPolyPoly;
1370 basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygon& rPixelPolyPoly ) const
1372 basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly;
1373 const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation();
1374 aTransformedPoly.transform( rTransformationMatrix );
1375 return aTransformedPoly;
1378 vcl::Region OutputDevice::PixelToLogic( const vcl::Region& rDeviceRegion ) const
1381 if(!mbMap || rDeviceRegion.IsNull() || rDeviceRegion.IsEmpty())
1383 return rDeviceRegion;
1386 vcl::Region aRegion;
1388 if(rDeviceRegion.getB2DPolyPolygon())
1390 aRegion = vcl::Region(PixelToLogic(*rDeviceRegion.getB2DPolyPolygon()));
1392 else if(rDeviceRegion.getPolyPolygon())
1394 aRegion = vcl::Region(PixelToLogic(*rDeviceRegion.getPolyPolygon()));
1396 else if(rDeviceRegion.getRegionBand())
1398 RectangleVector aRectangles;
1399 rDeviceRegion.GetRegionRectangles(aRectangles);
1400 const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
1402 // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1403 for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); ++aRectIter)
1405 aRegion.Union(PixelToLogic(*aRectIter));
1409 return aRegion;
1412 Point OutputDevice::PixelToLogic( const Point& rDevicePt,
1413 const MapMode& rMapMode ) const
1416 // calculate nothing if default-MapMode
1417 if ( rMapMode.IsDefault() )
1418 return rDevicePt;
1420 // calculate MapMode-resolution and convert
1421 ImplMapRes aMapRes;
1422 ImplThresholdRes aThresRes;
1423 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1425 return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1426 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1427 aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1428 ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1429 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1430 aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1433 Size OutputDevice::PixelToLogic( const Size& rDeviceSize,
1434 const MapMode& rMapMode ) const
1437 // calculate nothing if default-MapMode
1438 if ( rMapMode.IsDefault() )
1439 return rDeviceSize;
1441 // calculate MapMode-resolution and convert
1442 ImplMapRes aMapRes;
1443 ImplThresholdRes aThresRes;
1444 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1446 return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1447 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1448 aThresRes.mnThresPixToLogX ),
1449 ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1450 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1451 aThresRes.mnThresPixToLogY ) );
1454 Rectangle OutputDevice::PixelToLogic( const Rectangle& rDeviceRect,
1455 const MapMode& rMapMode ) const
1458 // calculate nothing if default-MapMode
1459 if ( rMapMode.IsDefault() || rDeviceRect.IsEmpty() )
1460 return rDeviceRect;
1462 // calculate MapMode-resolution and convert
1463 ImplMapRes aMapRes;
1464 ImplThresholdRes aThresRes;
1465 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1467 return Rectangle( ImplPixelToLogic( rDeviceRect.Left(), mnDPIX,
1468 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1469 aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1470 ImplPixelToLogic( rDeviceRect.Top(), mnDPIY,
1471 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1472 aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY,
1473 ImplPixelToLogic( rDeviceRect.Right(), mnDPIX,
1474 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1475 aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1476 ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY,
1477 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1478 aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1481 Polygon OutputDevice::PixelToLogic( const Polygon& rDevicePoly,
1482 const MapMode& rMapMode ) const
1485 // calculate nothing if default-MapMode
1486 if ( rMapMode.IsDefault() )
1487 return rDevicePoly;
1489 // calculate MapMode-resolution and convert
1490 ImplMapRes aMapRes;
1491 ImplThresholdRes aThresRes;
1492 ImplCalcMapResolution( rMapMode, mnDPIX, mnDPIY, aMapRes, aThresRes );
1494 sal_uInt16 i;
1495 sal_uInt16 nPoints = rDevicePoly.GetSize();
1496 Polygon aPoly( rDevicePoly );
1498 // get pointer to Point-array (copy data)
1499 const Point* pPointAry = aPoly.GetConstPointAry();
1501 for ( i = 0; i < nPoints; i++ )
1503 const Point* pPt = &(pPointAry[i]);
1504 Point aPt;
1505 aPt.X() = ImplPixelToLogic( pPt->X(), mnDPIX,
1506 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX,
1507 aThresRes.mnThresPixToLogX ) - aMapRes.mnMapOfsX - mnOutOffLogicX;
1508 aPt.Y() = ImplPixelToLogic( pPt->Y(), mnDPIY,
1509 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY,
1510 aThresRes.mnThresPixToLogY ) - aMapRes.mnMapOfsY - mnOutOffLogicY;
1511 aPoly[i] = aPt;
1514 return aPoly;
1517 tools::PolyPolygon OutputDevice::PixelToLogic( const tools::PolyPolygon& rDevicePolyPoly,
1518 const MapMode& rMapMode ) const
1521 if ( rMapMode.IsDefault() )
1522 return rDevicePolyPoly;
1524 tools::PolyPolygon aPolyPoly( rDevicePolyPoly );
1525 sal_uInt16 nPoly = aPolyPoly.Count();
1526 for( sal_uInt16 i = 0; i < nPoly; i++ )
1528 Polygon& rPoly = aPolyPoly[i];
1529 rPoly = PixelToLogic( rPoly, rMapMode );
1531 return aPolyPoly;
1534 basegfx::B2DPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolygon& rPixelPoly,
1535 const MapMode& rMapMode ) const
1537 basegfx::B2DPolygon aTransformedPoly = rPixelPoly;
1538 const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation( rMapMode );
1539 aTransformedPoly.transform( rTransformationMatrix );
1540 return aTransformedPoly;
1543 basegfx::B2DPolyPolygon OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygon& rPixelPolyPoly,
1544 const MapMode& rMapMode ) const
1546 basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly;
1547 const ::basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation( rMapMode );
1548 aTransformedPoly.transform( rTransformationMatrix );
1549 return aTransformedPoly;
1552 vcl::Region OutputDevice::PixelToLogic( const vcl::Region& rDeviceRegion, const MapMode& rMapMode ) const
1555 if(rMapMode.IsDefault() || rDeviceRegion.IsNull() || rDeviceRegion.IsEmpty())
1557 return rDeviceRegion;
1560 vcl::Region aRegion;
1562 if(rDeviceRegion.getB2DPolyPolygon())
1564 aRegion = vcl::Region(PixelToLogic(*rDeviceRegion.getB2DPolyPolygon(), rMapMode));
1566 else if(rDeviceRegion.getPolyPolygon())
1568 aRegion = vcl::Region(PixelToLogic(*rDeviceRegion.getPolyPolygon(), rMapMode));
1570 else if(rDeviceRegion.getRegionBand())
1572 RectangleVector aRectangles;
1573 rDeviceRegion.GetRegionRectangles(aRectangles);
1574 const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
1576 // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1577 for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); ++aRectIter)
1579 aRegion.Union(PixelToLogic(*aRectIter, rMapMode));
1583 return aRegion;
1586 #define ENTER1( rSource, pMapModeSource, pMapModeDest ) \
1587 if ( !pMapModeSource ) \
1588 pMapModeSource = &maMapMode; \
1589 if ( !pMapModeDest ) \
1590 pMapModeDest = &maMapMode; \
1591 if ( *pMapModeSource == *pMapModeDest ) \
1592 return rSource; \
1594 ImplMapRes aMapResSource; \
1595 aMapResSource.mnMapOfsX = 0; \
1596 aMapResSource.mnMapOfsY = 0; \
1597 aMapResSource.mnMapScNumX = 1; \
1598 aMapResSource.mnMapScNumY = 1; \
1599 aMapResSource.mnMapScDenomX = 1; \
1600 aMapResSource.mnMapScDenomY = 1; \
1601 aMapResSource.mfOffsetX = 0.0; \
1602 aMapResSource.mfOffsetY = 0.0; \
1603 aMapResSource.mfScaleX = 1.0; \
1604 aMapResSource.mfScaleY = 1.0; \
1605 ImplMapRes aMapResDest(aMapResSource); \
1607 if ( !mbMap || pMapModeSource != &maMapMode ) \
1609 if ( pMapModeSource->GetMapUnit() == MAP_RELATIVE ) \
1610 aMapResSource = maMapRes; \
1611 ImplCalcMapResolution( *pMapModeSource, \
1612 mnDPIX, mnDPIY, aMapResSource ); \
1614 else \
1615 aMapResSource = maMapRes; \
1616 if ( !mbMap || pMapModeDest != &maMapMode ) \
1618 if ( pMapModeDest->GetMapUnit() == MAP_RELATIVE ) \
1619 aMapResDest = maMapRes; \
1620 ImplCalcMapResolution( *pMapModeDest, \
1621 mnDPIX, mnDPIY, aMapResDest ); \
1623 else \
1624 aMapResDest = maMapRes
1626 static void verifyUnitSourceDest( MapUnit eUnitSource, MapUnit eUnitDest )
1628 (void) eUnitSource;
1629 (void) eUnitDest;
1630 DBG_ASSERT( eUnitSource != MAP_SYSFONT
1631 && eUnitSource != MAP_APPFONT
1632 && eUnitSource != MAP_RELATIVE,
1633 "Source MapUnit nicht erlaubt" );
1634 DBG_ASSERT( eUnitDest != MAP_SYSFONT
1635 && eUnitDest != MAP_APPFONT
1636 && eUnitDest != MAP_RELATIVE,
1637 "Destination MapUnit nicht erlaubt" );
1638 DBG_ASSERTWARNING( eUnitSource != MAP_PIXEL,
1639 "MAP_PIXEL mit 72dpi angenaehert" );
1640 DBG_ASSERTWARNING( eUnitDest != MAP_PIXEL,
1641 "MAP_PIXEL mit 72dpi angenaehert" );
1644 #define ENTER3( eUnitSource, eUnitDest ) \
1645 long nNumerator = 1; \
1646 long nDenominator = 1; \
1647 DBG_ASSERT( eUnitSource < s_ImplArySize, "Invalid source map unit"); \
1648 DBG_ASSERT( eUnitDest < s_ImplArySize, "Invalid destination map unit"); \
1649 if( (eUnitSource < s_ImplArySize) && (eUnitDest < s_ImplArySize) ) \
1651 nNumerator = aImplNumeratorAry[eUnitSource] * \
1652 aImplDenominatorAry[eUnitDest]; \
1653 nDenominator = aImplNumeratorAry[eUnitDest] * \
1654 aImplDenominatorAry[eUnitSource]; \
1656 if ( eUnitSource == MAP_PIXEL ) \
1657 nDenominator *= 72; \
1658 else if( eUnitDest == MAP_PIXEL ) \
1659 nNumerator *= 72
1661 #define ENTER4( rMapModeSource, rMapModeDest ) \
1662 ImplMapRes aMapResSource; \
1663 aMapResSource.mnMapOfsX = 0; \
1664 aMapResSource.mnMapOfsY = 0; \
1665 aMapResSource.mnMapScNumX = 1; \
1666 aMapResSource.mnMapScNumY = 1; \
1667 aMapResSource.mnMapScDenomX = 1; \
1668 aMapResSource.mnMapScDenomY = 1; \
1669 aMapResSource.mfOffsetX = 0.0; \
1670 aMapResSource.mfOffsetY = 0.0; \
1671 aMapResSource.mfScaleX = 1.0; \
1672 aMapResSource.mfScaleY = 1.0; \
1673 ImplMapRes aMapResDest(aMapResSource); \
1675 ImplCalcMapResolution( rMapModeSource, 72, 72, aMapResSource ); \
1676 ImplCalcMapResolution( rMapModeDest, 72, 72, aMapResDest )
1678 // return (n1 * n2 * n3) / (n4 * n5)
1679 static long fn5( const long n1,
1680 const long n2,
1681 const long n3,
1682 const long n4,
1683 const long n5 )
1685 if ( n1 == 0 || n2 == 0 || n3 == 0 || n4 == 0 || n5 == 0 )
1686 return 0;
1687 if ( LONG_MAX / std::abs(n2) < std::abs(n3) )
1689 // a6 is skipped
1690 BigInt a7 = n2;
1691 a7 *= n3;
1692 a7 *= n1;
1694 if ( LONG_MAX / std::abs(n4) < std::abs(n5) )
1696 BigInt a8 = n4;
1697 a8 *= n5;
1699 BigInt a9 = a8;
1700 a9 /= 2;
1701 if ( a7.IsNeg() )
1702 a7 -= a9;
1703 else
1704 a7 += a9;
1706 a7 /= a8;
1707 } // of if
1708 else
1710 long n8 = n4 * n5;
1712 if ( a7.IsNeg() )
1713 a7 -= n8 / 2;
1714 else
1715 a7 += n8 / 2;
1717 a7 /= n8;
1718 } // of else
1719 return (long)a7;
1720 } // of if
1721 else
1723 long n6 = n2 * n3;
1725 if ( LONG_MAX / std::abs(n1) < std::abs(n6) )
1727 BigInt a7 = n1;
1728 a7 *= n6;
1730 if ( LONG_MAX / std::abs(n4) < std::abs(n5) )
1732 BigInt a8 = n4;
1733 a8 *= n5;
1735 BigInt a9 = a8;
1736 a9 /= 2;
1737 if ( a7.IsNeg() )
1738 a7 -= a9;
1739 else
1740 a7 += a9;
1742 a7 /= a8;
1743 } // of if
1744 else
1746 long n8 = n4 * n5;
1748 if ( a7.IsNeg() )
1749 a7 -= n8 / 2;
1750 else
1751 a7 += n8 / 2;
1753 a7 /= n8;
1754 } // of else
1755 return (long)a7;
1756 } // of if
1757 else
1759 long n7 = n1 * n6;
1761 if ( LONG_MAX / std::abs(n4) < std::abs(n5) )
1763 BigInt a7 = n7;
1764 BigInt a8 = n4;
1765 a8 *= n5;
1767 BigInt a9 = a8;
1768 a9 /= 2;
1769 if ( a7.IsNeg() )
1770 a7 -= a9;
1771 else
1772 a7 += a9;
1774 a7 /= a8;
1775 return (long)a7;
1776 } // of if
1777 else
1779 const long n8 = n4 * n5;
1780 const long n8_2 = n8 / 2;
1782 if( n7 < 0 )
1784 if( ( n7 - LONG_MIN ) >= n8_2 )
1785 n7 -= n8_2;
1787 else if( ( LONG_MAX - n7 ) >= n8_2 )
1788 n7 += n8_2;
1790 return n7 / n8;
1791 } // of else
1792 } // of else
1793 } // of else
1796 // return (n1 * n2) / n3
1797 static long fn3( const long n1, const long n2, const long n3 )
1799 if ( n1 == 0 || n2 == 0 || n3 == 0 )
1800 return 0;
1801 if ( LONG_MAX / std::abs(n1) < std::abs(n2) )
1803 BigInt a4 = n1;
1804 a4 *= n2;
1806 if ( a4.IsNeg() )
1807 a4 -= n3 / 2;
1808 else
1809 a4 += n3 / 2;
1811 a4 /= n3;
1812 return (long)a4;
1813 } // of if
1814 else
1816 long n4 = n1 * n2;
1817 const long n3_2 = n3 / 2;
1819 if( n4 < 0 )
1821 if( ( n4 - LONG_MIN ) >= n3_2 )
1822 n4 -= n3_2;
1824 else if( ( LONG_MAX - n4 ) >= n3_2 )
1825 n4 += n3_2;
1827 return n4 / n3;
1828 } // of else
1831 Point OutputDevice::LogicToLogic( const Point& rPtSource,
1832 const MapMode* pMapModeSource,
1833 const MapMode* pMapModeDest ) const
1835 ENTER1( rPtSource, pMapModeSource, pMapModeDest );
1837 return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
1838 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1839 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1840 aMapResDest.mnMapOfsX,
1841 fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
1842 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1843 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1844 aMapResDest.mnMapOfsY );
1847 Size OutputDevice::LogicToLogic( const Size& rSzSource,
1848 const MapMode* pMapModeSource,
1849 const MapMode* pMapModeDest ) const
1851 ENTER1( rSzSource, pMapModeSource, pMapModeDest );
1853 return Size( fn5( rSzSource.Width(),
1854 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1855 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
1856 fn5( rSzSource.Height(),
1857 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1858 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
1861 Rectangle OutputDevice::LogicToLogic( const Rectangle& rRectSource,
1862 const MapMode* pMapModeSource,
1863 const MapMode* pMapModeDest ) const
1865 ENTER1( rRectSource, pMapModeSource, pMapModeDest );
1867 return Rectangle( fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
1868 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1869 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1870 aMapResDest.mnMapOfsX,
1871 fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
1872 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1873 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1874 aMapResDest.mnMapOfsY,
1875 fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
1876 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1877 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1878 aMapResDest.mnMapOfsX,
1879 fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
1880 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1881 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1882 aMapResDest.mnMapOfsY );
1885 Point OutputDevice::LogicToLogic( const Point& rPtSource,
1886 const MapMode& rMapModeSource,
1887 const MapMode& rMapModeDest )
1889 if ( rMapModeSource == rMapModeDest )
1890 return rPtSource;
1892 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1893 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
1894 verifyUnitSourceDest( eUnitSource, eUnitDest );
1896 if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1898 ENTER3( eUnitSource, eUnitDest );
1900 return Point( fn3( rPtSource.X(), nNumerator, nDenominator ),
1901 fn3( rPtSource.Y(), nNumerator, nDenominator ) );
1903 else
1905 ENTER4( rMapModeSource, rMapModeDest );
1907 return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
1908 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1909 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1910 aMapResDest.mnMapOfsX,
1911 fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
1912 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1913 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1914 aMapResDest.mnMapOfsY );
1918 Size OutputDevice::LogicToLogic( const Size& rSzSource,
1919 const MapMode& rMapModeSource,
1920 const MapMode& rMapModeDest )
1922 if ( rMapModeSource == rMapModeDest )
1923 return rSzSource;
1925 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1926 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
1927 verifyUnitSourceDest( eUnitSource, eUnitDest );
1929 if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1931 ENTER3( eUnitSource, eUnitDest );
1933 return Size( fn3( rSzSource.Width(), nNumerator, nDenominator ),
1934 fn3( rSzSource.Height(), nNumerator, nDenominator ) );
1936 else
1938 ENTER4( rMapModeSource, rMapModeDest );
1940 return Size( fn5( rSzSource.Width(),
1941 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1942 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
1943 fn5( rSzSource.Height(),
1944 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1945 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
1949 basegfx::B2DPolygon OutputDevice::LogicToLogic( const basegfx::B2DPolygon& rPolySource,
1950 const MapMode& rMapModeSource,
1951 const MapMode& rMapModeDest )
1953 if(rMapModeSource == rMapModeDest)
1955 return rPolySource;
1958 const basegfx::B2DHomMatrix aTransform(LogicToLogic(rMapModeSource, rMapModeDest));
1959 basegfx::B2DPolygon aPoly(rPolySource);
1961 aPoly.transform(aTransform);
1962 return aPoly;
1965 basegfx::B2DPolyPolygon OutputDevice::LogicToLogic( const basegfx::B2DPolyPolygon& rPolySource,
1966 const MapMode& rMapModeSource,
1967 const MapMode& rMapModeDest )
1969 if(rMapModeSource == rMapModeDest)
1971 return rPolySource;
1974 const basegfx::B2DHomMatrix aTransform(LogicToLogic(rMapModeSource, rMapModeDest));
1975 basegfx::B2DPolyPolygon aPoly(rPolySource);
1977 aPoly.transform(aTransform);
1978 return aPoly;
1981 basegfx::B2DHomMatrix OutputDevice::LogicToLogic(const MapMode& rMapModeSource, const MapMode& rMapModeDest)
1983 basegfx::B2DHomMatrix aTransform;
1985 if(rMapModeSource == rMapModeDest)
1987 return aTransform;
1990 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1991 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
1992 verifyUnitSourceDest(eUnitSource, eUnitDest);
1994 if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1996 ENTER3(eUnitSource, eUnitDest);
1998 const double fScaleFactor((double)nNumerator / (double)nDenominator);
1999 aTransform.set(0, 0, fScaleFactor);
2000 aTransform.set(1, 1, fScaleFactor);
2002 else
2004 ENTER4(rMapModeSource, rMapModeDest);
2006 const double fScaleFactorX((double(aMapResSource.mnMapScNumX) * double(aMapResDest.mnMapScDenomX)) / (double(aMapResSource.mnMapScDenomX) * double(aMapResDest.mnMapScNumX)));
2007 const double fScaleFactorY((double(aMapResSource.mnMapScNumY) * double(aMapResDest.mnMapScDenomY)) / (double(aMapResSource.mnMapScDenomY) * double(aMapResDest.mnMapScNumY)));
2008 const double fZeroPointX(double(aMapResSource.mnMapOfsX) * fScaleFactorX - double(aMapResDest.mnMapOfsX));
2009 const double fZeroPointY(double(aMapResSource.mnMapOfsY) * fScaleFactorY - double(aMapResDest.mnMapOfsY));
2011 aTransform.set(0, 0, fScaleFactorX);
2012 aTransform.set(1, 1, fScaleFactorY);
2013 aTransform.set(0, 2, fZeroPointX);
2014 aTransform.set(1, 2, fZeroPointY);
2017 return aTransform;
2020 Rectangle OutputDevice::LogicToLogic( const Rectangle& rRectSource,
2021 const MapMode& rMapModeSource,
2022 const MapMode& rMapModeDest )
2024 if ( rMapModeSource == rMapModeDest )
2025 return rRectSource;
2027 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
2028 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
2029 verifyUnitSourceDest( eUnitSource, eUnitDest );
2031 if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
2033 ENTER3( eUnitSource, eUnitDest );
2035 return Rectangle( fn3( rRectSource.Left(), nNumerator, nDenominator ),
2036 fn3( rRectSource.Top(), nNumerator, nDenominator ),
2037 fn3( rRectSource.Right(), nNumerator, nDenominator ),
2038 fn3( rRectSource.Bottom(), nNumerator, nDenominator ) );
2040 else
2042 ENTER4( rMapModeSource, rMapModeDest );
2044 return Rectangle( fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
2045 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2046 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2047 aMapResDest.mnMapOfsX,
2048 fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
2049 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2050 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2051 aMapResDest.mnMapOfsY,
2052 fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
2053 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
2054 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
2055 aMapResDest.mnMapOfsX,
2056 fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
2057 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
2058 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
2059 aMapResDest.mnMapOfsY );
2063 long OutputDevice::LogicToLogic( long nLongSource,
2064 MapUnit eUnitSource, MapUnit eUnitDest )
2066 if ( eUnitSource == eUnitDest )
2067 return nLongSource;
2069 verifyUnitSourceDest( eUnitSource, eUnitDest );
2070 ENTER3( eUnitSource, eUnitDest );
2072 return fn3( nLongSource, nNumerator, nDenominator );
2075 void OutputDevice::SetPixelOffset( const Size& rOffset )
2077 mnOutOffOrigX = rOffset.Width();
2078 mnOutOffOrigY = rOffset.Height();
2080 mnOutOffLogicX = ImplPixelToLogic( mnOutOffOrigX, mnDPIX,
2081 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
2082 maThresRes.mnThresPixToLogX );
2083 mnOutOffLogicY = ImplPixelToLogic( mnOutOffOrigY, mnDPIY,
2084 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
2085 maThresRes.mnThresPixToLogY );
2087 if( mpAlphaVDev )
2088 mpAlphaVDev->SetPixelOffset( rOffset );
2092 namespace vcl {
2094 long Window::ImplLogicUnitToPixelX( long nX, MapUnit eUnit )
2096 if ( eUnit != MAP_PIXEL )
2098 ImplFrameData* pFrameData = mpWindowImpl->mpFrameData;
2100 // shift map unit, then re-calculate
2101 if ( pFrameData->meMapUnit != eUnit )
2103 pFrameData->meMapUnit = eUnit;
2104 ImplCalcMapResolution( MapMode( eUnit ), mnDPIX, mnDPIY,
2105 pFrameData->maMapUnitRes );
2108 // BigInt is not required, as this function is only used to
2109 // convert the window position
2110 nX = nX * mnDPIX * pFrameData->maMapUnitRes.mnMapScNumX;
2111 nX += nX >= 0 ? (pFrameData->maMapUnitRes.mnMapScDenomX/2) :
2112 -((pFrameData->maMapUnitRes.mnMapScDenomX-1)/2);
2113 nX /= pFrameData->maMapUnitRes.mnMapScDenomX;
2116 return nX;
2119 long Window::ImplLogicUnitToPixelY( long nY, MapUnit eUnit )
2121 if ( eUnit != MAP_PIXEL )
2123 ImplFrameData* pFrameData = mpWindowImpl->mpFrameData;
2125 // shift map unit, then re-calculate
2126 if ( pFrameData->meMapUnit != eUnit )
2128 pFrameData->meMapUnit = eUnit;
2129 ImplCalcMapResolution( MapMode( eUnit ), mnDPIX, mnDPIY,
2130 pFrameData->maMapUnitRes );
2133 // BigInt is not required, as this function is only used to
2134 // convert the window position
2135 nY = nY * mnDPIY * pFrameData->maMapUnitRes.mnMapScNumY;
2136 nY += nY >= 0 ? (pFrameData->maMapUnitRes.mnMapScDenomY/2) :
2137 -((pFrameData->maMapUnitRes.mnMapScDenomY-1)/2);
2138 nY /= pFrameData->maMapUnitRes.mnMapScDenomY;
2141 return nY;
2144 } /* namespace vcl */
2146 DeviceCoordinate OutputDevice::LogicWidthToDeviceCoordinate( long nWidth ) const
2148 if ( !mbMap )
2149 return (DeviceCoordinate)nWidth;
2151 #if VCL_FLOAT_DEVICE_PIXEL
2152 return (double)nWidth * maMapRes.mfScaleX * mnDPIX;
2153 #else
2155 return ImplLogicToPixel( nWidth, mnDPIX,
2156 maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX,
2157 maThresRes.mnThresLogToPixX );
2158 #endif
2161 DeviceCoordinate OutputDevice::LogicHeightToDeviceCoordinate( long nHeight ) const
2163 if ( !mbMap )
2164 return (DeviceCoordinate)nHeight;
2165 #if VCL_FLOAT_DEVICE_PIXEL
2166 return (double)nHeight * maMapRes.mfScaleY * mnDPIY;
2167 #else
2169 return ImplLogicToPixel( nHeight, mnDPIY,
2170 maMapRes.mnMapScNumY, maMapRes.mnMapScDenomY,
2171 maThresRes.mnThresLogToPixY );
2172 #endif
2175 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */