1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <sal/log.hxx>
23 #include <osl/diagnose.h>
24 #include <tools/bigint.hxx>
25 #include <tools/debug.hxx>
27 #include <vcl/cursor.hxx>
28 #include <vcl/lineinfo.hxx>
29 #include <vcl/metaact.hxx>
30 #include <vcl/virdev.hxx>
31 #include <vcl/wrkwin.hxx>
33 #include <ImplOutDevData.hxx>
37 #include <basegfx/matrix/b2dhommatrix.hxx>
38 #include <tools/UnitConversion.hxx>
40 static auto setMapRes(ImplMapRes
& rMapRes
, const o3tl::Length eUnit
)
42 const auto [nNum
, nDen
] = o3tl::getConversionMulDiv(eUnit
, o3tl::Length::in
);
43 rMapRes
.mnMapScNumX
= rMapRes
.mnMapScNumY
= nNum
;
44 rMapRes
.mnMapScDenomX
= rMapRes
.mnMapScDenomY
= nDen
;
47 static void ImplCalcMapResolution( const MapMode
& rMapMode
,
48 tools::Long nDPIX
, tools::Long nDPIY
, ImplMapRes
& rMapRes
)
50 switch ( rMapMode
.GetMapUnit() )
52 case MapUnit::MapRelative
:
54 case MapUnit::Map100thMM
:
55 setMapRes(rMapRes
, o3tl::Length::mm100
);
57 case MapUnit::Map10thMM
:
58 setMapRes(rMapRes
, o3tl::Length::mm10
);
61 setMapRes(rMapRes
, o3tl::Length::mm
);
64 setMapRes(rMapRes
, o3tl::Length::cm
);
66 case MapUnit::Map1000thInch
:
67 setMapRes(rMapRes
, o3tl::Length::in1000
);
69 case MapUnit::Map100thInch
:
70 setMapRes(rMapRes
, o3tl::Length::in100
);
72 case MapUnit::Map10thInch
:
73 setMapRes(rMapRes
, o3tl::Length::in10
);
75 case MapUnit::MapInch
:
76 setMapRes(rMapRes
, o3tl::Length::in
);
78 case MapUnit::MapPoint
:
79 setMapRes(rMapRes
, o3tl::Length::pt
);
81 case MapUnit::MapTwip
:
82 setMapRes(rMapRes
, o3tl::Length::twip
);
84 case MapUnit::MapPixel
:
85 rMapRes
.mnMapScNumX
= 1;
86 rMapRes
.mnMapScDenomX
= nDPIX
;
87 rMapRes
.mnMapScNumY
= 1;
88 rMapRes
.mnMapScDenomY
= nDPIY
;
90 case MapUnit::MapSysFont
:
91 case MapUnit::MapAppFont
:
93 ImplSVData
* pSVData
= ImplGetSVData();
94 if ( !pSVData
->maGDIData
.mnAppFontX
)
96 if (pSVData
->maFrameData
.mpFirstFrame
)
97 vcl::Window::ImplInitAppFontData(pSVData
->maFrameData
.mpFirstFrame
);
100 ScopedVclPtrInstance
<WorkWindow
> pWin( nullptr, 0 );
101 vcl::Window::ImplInitAppFontData( pWin
);
104 rMapRes
.mnMapScNumX
= pSVData
->maGDIData
.mnAppFontX
;
105 rMapRes
.mnMapScDenomX
= nDPIX
* 40;
106 rMapRes
.mnMapScNumY
= pSVData
->maGDIData
.mnAppFontY
;
107 rMapRes
.mnMapScDenomY
= nDPIY
* 80;
111 OSL_FAIL( "unhandled MapUnit" );
115 const Fraction
& aScaleX
= rMapMode
.GetScaleX();
116 const Fraction
& aScaleY
= rMapMode
.GetScaleY();
118 // set offset according to MapMode
119 Point aOrigin
= rMapMode
.GetOrigin();
120 if ( rMapMode
.GetMapUnit() != MapUnit::MapRelative
)
122 rMapRes
.mnMapOfsX
= aOrigin
.X();
123 rMapRes
.mnMapOfsY
= aOrigin
.Y();
127 auto funcCalcOffset
= [](const Fraction
& rScale
, tools::Long
& rnMapOffset
, tools::Long nOrigin
)
129 auto nNumerator
= rScale
.GetNumerator();
130 assert(nNumerator
!= 0);
132 BigInt
aX( rnMapOffset
);
133 aX
*= BigInt( rScale
.GetDenominator() );
134 if ( rnMapOffset
>= 0 )
137 aX
+= BigInt(nNumerator
/ 2);
139 aX
-= BigInt((nNumerator
+ 1) / 2);
143 if (nNumerator
>= 0 )
144 aX
-= BigInt((nNumerator
- 1) / 2);
146 aX
+= BigInt(nNumerator
/ 2);
148 aX
/= BigInt(nNumerator
);
149 rnMapOffset
= static_cast<tools::Long
>(aX
) + nOrigin
;
152 funcCalcOffset(aScaleX
, rMapRes
.mnMapOfsX
, aOrigin
.X());
153 funcCalcOffset(aScaleY
, rMapRes
.mnMapOfsY
, aOrigin
.Y());
156 // calculate scaling factor according to MapMode
157 // aTemp? = rMapRes.mnMapSc? * aScale?
158 Fraction aTempX
= Fraction::MakeFraction( rMapRes
.mnMapScNumX
,
159 aScaleX
.GetNumerator(),
160 rMapRes
.mnMapScDenomX
,
161 aScaleX
.GetDenominator() );
162 Fraction aTempY
= Fraction::MakeFraction( rMapRes
.mnMapScNumY
,
163 aScaleY
.GetNumerator(),
164 rMapRes
.mnMapScDenomY
,
165 aScaleY
.GetDenominator() );
166 rMapRes
.mnMapScNumX
= aTempX
.GetNumerator();
167 rMapRes
.mnMapScDenomX
= aTempX
.GetDenominator();
168 rMapRes
.mnMapScNumY
= aTempY
.GetNumerator();
169 rMapRes
.mnMapScDenomY
= aTempY
.GetDenominator();
173 void OutputDevice::ImplInvalidateViewTransform()
178 if(mpOutDevData
->mpViewTransform
)
180 delete mpOutDevData
->mpViewTransform
;
181 mpOutDevData
->mpViewTransform
= nullptr;
184 if(mpOutDevData
->mpInverseViewTransform
)
186 delete mpOutDevData
->mpInverseViewTransform
;
187 mpOutDevData
->mpInverseViewTransform
= nullptr;
191 static tools::Long
ImplLogicToPixel(tools::Long n
, tools::Long nDPI
, tools::Long nMapNum
,
192 tools::Long nMapDenom
)
195 assert(nMapDenom
!= 0);
196 if constexpr (sizeof(tools::Long
) >= 8)
198 assert(nMapNum
>= 0);
201 || std::abs(n
) < std::numeric_limits
<tools::Long
>::max() / nMapNum
/ nDPI
);
207 n
= static_cast<tools::Long
>(n64
);
210 n64
= 2 * n64
/ nMapDenom
;
215 n
= static_cast<tools::Long
>(n64
/ 2);
220 static double ImplLogicToSubPixel(tools::Long n
, tools::Long nDPI
, tools::Long nMapNum
,
221 tools::Long nMapDenom
)
224 assert(nMapDenom
!= 0);
225 return static_cast<double>(n
) * nMapNum
* nDPI
/ nMapDenom
;
228 static tools::Long
ImplSubPixelToLogic(double n
, tools::Long nDPI
, tools::Long nMapNum
,
229 tools::Long nMapDenom
)
232 assert(nMapNum
!= 0);
234 return std::round(n
* nMapDenom
/ nMapNum
/ nDPI
);
237 static tools::Long
ImplPixelToLogic(tools::Long n
, tools::Long nDPI
, tools::Long nMapNum
,
238 tools::Long nMapDenom
)
243 sal_Int64 nDenom
= nDPI
;
249 n
= static_cast<tools::Long
>(n64
);
252 n64
= 2 * n64
/ nDenom
;
257 n
= static_cast<tools::Long
>(n64
/ 2);
262 static double ImplPixelToLogicDouble(double n
, tools::Long nDPI
, tools::Long nMapNum
,
263 tools::Long nMapDenom
)
275 tools::Long
OutputDevice::ImplLogicXToDevicePixel( tools::Long nX
) const
280 // coverity[ tainted_data_return : FALSE ] version 2023.12.2
281 return ImplLogicToPixel( nX
+ maMapRes
.mnMapOfsX
, mnDPIX
,
282 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)+mnOutOffX
+mnOutOffOrigX
;
285 tools::Long
OutputDevice::ImplLogicYToDevicePixel( tools::Long nY
) const
290 // coverity[ tainted_data_return : FALSE ] version 2023.12.2
291 return ImplLogicToPixel( nY
+ maMapRes
.mnMapOfsY
, mnDPIY
,
292 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)+mnOutOffY
+mnOutOffOrigY
;
295 tools::Long
OutputDevice::ImplLogicWidthToDevicePixel( tools::Long nWidth
) const
300 return ImplLogicToPixel(nWidth
, mnDPIX
, maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
);
303 tools::Long
OutputDevice::ImplLogicHeightToDevicePixel( tools::Long nHeight
) const
308 return ImplLogicToPixel(nHeight
, mnDPIY
, maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
);
311 tools::Long
OutputDevice::ImplDevicePixelToLogicWidth( tools::Long nWidth
) const
316 return ImplPixelToLogic(nWidth
, mnDPIX
, maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
);
319 SAL_DLLPRIVATE
double OutputDevice::ImplDevicePixelToLogicWidthDouble(double nWidth
) const
324 return ImplPixelToLogicDouble(nWidth
, mnDPIX
, maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
);
327 tools::Long
OutputDevice::ImplDevicePixelToLogicHeight( tools::Long nHeight
) const
332 return ImplPixelToLogic(nHeight
, mnDPIY
, maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
);
335 double OutputDevice::ImplDevicePixelToLogicHeightDouble(double nHeight
) const
340 return ImplPixelToLogicDouble(nHeight
, mnDPIY
, maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
);
343 Point
OutputDevice::ImplLogicToDevicePixel( const Point
& rLogicPt
) const
346 return Point( rLogicPt
.X()+mnOutOffX
, rLogicPt
.Y()+mnOutOffY
);
348 return Point( ImplLogicToPixel( rLogicPt
.X() + maMapRes
.mnMapOfsX
, mnDPIX
,
349 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)+mnOutOffX
+mnOutOffOrigX
,
350 ImplLogicToPixel( rLogicPt
.Y() + maMapRes
.mnMapOfsY
, mnDPIY
,
351 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)+mnOutOffY
+mnOutOffOrigY
);
354 Size
OutputDevice::ImplLogicToDevicePixel( const Size
& rLogicSize
) const
359 return Size( ImplLogicToPixel( rLogicSize
.Width(), mnDPIX
,
360 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
),
361 ImplLogicToPixel( rLogicSize
.Height(), mnDPIY
,
362 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
) );
365 tools::Rectangle
OutputDevice::ImplLogicToDevicePixel( const tools::Rectangle
& rLogicRect
) const
367 // tdf#141761 IsEmpty() removed
368 // Even if rLogicRect.IsEmpty(), transform of the Position contained
369 // in the Rectangle is necessary. Due to Rectangle::Right() returning
370 // Left() when IsEmpty(), the code *could* stay unchanged (same for Bottom),
372 // The Rectangle constructor used with the four tools::Long values does not
373 // check for IsEmpty(), so to keep that state correct there are two possibilities:
374 // (1) Add a test to the Rectangle constructor in question
375 // (2) Do it handish here
376 // I have tried (1) first, but test Test::test_rectangle() claims that for
377 // tools::Rectangle aRect(1, 1, 1, 1);
378 // tools::Long(1) == aRect.GetWidth()
379 // tools::Long(0) == aRect.getWidth()
380 // (remember: this means Left == Right == 1 -> GetWidth => 1, getWidth == 0)
381 // so indeed the 1's have to go uncommented/unchecked into the data body
382 // of rectangle. Switching to (2) *is* needed, doing so
383 tools::Rectangle aRetval
;
387 aRetval
= tools::Rectangle(
388 rLogicRect
.Left()+mnOutOffX
,
389 rLogicRect
.Top()+mnOutOffY
,
390 rLogicRect
.IsWidthEmpty() ? 0 : rLogicRect
.Right()+mnOutOffX
,
391 rLogicRect
.IsHeightEmpty() ? 0 : rLogicRect
.Bottom()+mnOutOffY
);
395 aRetval
= tools::Rectangle(
396 ImplLogicToPixel( rLogicRect
.Left()+maMapRes
.mnMapOfsX
, mnDPIX
, maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)+mnOutOffX
+mnOutOffOrigX
,
397 ImplLogicToPixel( rLogicRect
.Top()+maMapRes
.mnMapOfsY
, mnDPIY
, maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)+mnOutOffY
+mnOutOffOrigY
,
398 rLogicRect
.IsWidthEmpty() ? 0 : ImplLogicToPixel( rLogicRect
.Right()+maMapRes
.mnMapOfsX
, mnDPIX
, maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)+mnOutOffX
+mnOutOffOrigX
,
399 rLogicRect
.IsHeightEmpty() ? 0 : ImplLogicToPixel( rLogicRect
.Bottom()+maMapRes
.mnMapOfsY
, mnDPIY
, maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)+mnOutOffY
+mnOutOffOrigY
);
402 if(rLogicRect
.IsWidthEmpty())
403 aRetval
.SetWidthEmpty();
405 if(rLogicRect
.IsHeightEmpty())
406 aRetval
.SetHeightEmpty();
411 tools::Polygon
OutputDevice::ImplLogicToDevicePixel( const tools::Polygon
& rLogicPoly
) const
413 if ( !mbMap
&& !mnOutOffX
&& !mnOutOffY
)
417 sal_uInt16 nPoints
= rLogicPoly
.GetSize();
418 tools::Polygon
aPoly( rLogicPoly
);
420 // get pointer to Point-array (copy data)
421 const Point
* pPointAry
= aPoly
.GetConstPointAry();
425 for ( i
= 0; i
< nPoints
; i
++ )
427 const Point
& rPt
= pPointAry
[i
];
428 Point
aPt(ImplLogicToPixel( rPt
.X()+maMapRes
.mnMapOfsX
, mnDPIX
,
429 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)+mnOutOffX
+mnOutOffOrigX
,
430 ImplLogicToPixel( rPt
.Y()+maMapRes
.mnMapOfsY
, mnDPIY
,
431 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)+mnOutOffY
+mnOutOffOrigY
);
437 for ( i
= 0; i
< nPoints
; i
++ )
439 Point aPt
= pPointAry
[i
];
440 aPt
.AdjustX(mnOutOffX
);
441 aPt
.AdjustY(mnOutOffY
);
449 basegfx::B2DPolygon
OutputDevice::ImplLogicToDevicePixel(const basegfx::B2DPolygon
& rLogicPoly
) const
451 if (!mbMap
&& !mnOutOffX
&& !mnOutOffY
)
454 sal_uInt32 nPoints
= rLogicPoly
.count();
455 basegfx::B2DPolygon
aPoly(rLogicPoly
);
457 basegfx::B2DPoint aC1
;
458 basegfx::B2DPoint aC2
;
462 for (sal_uInt32 i
= 0; i
< nPoints
; ++i
)
464 const basegfx::B2DPoint
& rPt
= aPoly
.getB2DPoint(i
);
465 basegfx::B2DPoint
aPt(ImplLogicToPixel( rPt
.getX()+maMapRes
.mnMapOfsX
, mnDPIX
,
466 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)+mnOutOffX
+mnOutOffOrigX
,
467 ImplLogicToPixel( rPt
.getY()+maMapRes
.mnMapOfsY
, mnDPIY
,
468 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)+mnOutOffY
+mnOutOffOrigY
);
470 const bool bC1
= aPoly
.isPrevControlPointUsed(i
);
473 const basegfx::B2DPoint
aB2DC1(aPoly
.getPrevControlPoint(i
));
475 aC1
= basegfx::B2DPoint(ImplLogicToPixel( aB2DC1
.getX()+maMapRes
.mnMapOfsX
, mnDPIX
,
476 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)+mnOutOffX
+mnOutOffOrigX
,
477 ImplLogicToPixel( aB2DC1
.getY()+maMapRes
.mnMapOfsY
, mnDPIY
,
478 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)+mnOutOffY
+mnOutOffOrigY
);
481 const bool bC2
= aPoly
.isNextControlPointUsed(i
);
484 const basegfx::B2DPoint
aB2DC2(aPoly
.getNextControlPoint(i
));
486 aC2
= basegfx::B2DPoint(ImplLogicToPixel( aB2DC2
.getX()+maMapRes
.mnMapOfsX
, mnDPIX
,
487 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)+mnOutOffX
+mnOutOffOrigX
,
488 ImplLogicToPixel( aB2DC2
.getY()+maMapRes
.mnMapOfsY
, mnDPIY
,
489 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)+mnOutOffY
+mnOutOffOrigY
);
492 aPoly
.setB2DPoint(i
, aPt
);
495 aPoly
.setPrevControlPoint(i
, aC1
);
498 aPoly
.setNextControlPoint(i
, aC2
);
503 for (sal_uInt32 i
= 0; i
< nPoints
; ++i
)
505 const basegfx::B2DPoint
& rPt
= aPoly
.getB2DPoint(i
);
506 basegfx::B2DPoint
aPt(rPt
.getX() + mnOutOffX
, rPt
.getY() + mnOutOffY
);
508 const bool bC1
= aPoly
.isPrevControlPointUsed(i
);
511 const basegfx::B2DPoint
aB2DC1(aPoly
.getPrevControlPoint(i
));
513 aC1
= basegfx::B2DPoint(aB2DC1
.getX() + mnOutOffX
, aB2DC1
.getY() + mnOutOffY
);
516 const bool bC2
= aPoly
.isNextControlPointUsed(i
);
519 const basegfx::B2DPoint
aB2DC2(aPoly
.getNextControlPoint(i
));
521 aC1
= basegfx::B2DPoint(aB2DC2
.getX() + mnOutOffX
, aB2DC2
.getY() + mnOutOffY
);
524 aPoly
.setB2DPoint(i
, aPt
);
527 aPoly
.setPrevControlPoint(i
, aC1
);
530 aPoly
.setNextControlPoint(i
, aC2
);
537 tools::PolyPolygon
OutputDevice::ImplLogicToDevicePixel( const tools::PolyPolygon
& rLogicPolyPoly
) const
539 if ( !mbMap
&& !mnOutOffX
&& !mnOutOffY
)
540 return rLogicPolyPoly
;
542 tools::PolyPolygon
aPolyPoly( rLogicPolyPoly
);
543 sal_uInt16 nPoly
= aPolyPoly
.Count();
544 for( sal_uInt16 i
= 0; i
< nPoly
; i
++ )
546 tools::Polygon
& rPoly
= aPolyPoly
[i
];
547 rPoly
= ImplLogicToDevicePixel( rPoly
);
552 LineInfo
OutputDevice::ImplLogicToDevicePixel( const LineInfo
& rLineInfo
) const
554 LineInfo
aInfo( rLineInfo
);
556 if( aInfo
.GetStyle() == LineStyle::Dash
)
558 if( aInfo
.GetDotCount() && aInfo
.GetDotLen() )
559 aInfo
.SetDotLen( std::max( ImplLogicWidthToDevicePixel( aInfo
.GetDotLen() ), tools::Long(1) ) );
561 aInfo
.SetDotCount( 0 );
563 if( aInfo
.GetDashCount() && aInfo
.GetDashLen() )
564 aInfo
.SetDashLen( std::max( ImplLogicWidthToDevicePixel( aInfo
.GetDashLen() ), tools::Long(1) ) );
566 aInfo
.SetDashCount( 0 );
568 aInfo
.SetDistance( ImplLogicWidthToDevicePixel( aInfo
.GetDistance() ) );
570 if( ( !aInfo
.GetDashCount() && !aInfo
.GetDotCount() ) || !aInfo
.GetDistance() )
571 aInfo
.SetStyle( LineStyle::Solid
);
574 aInfo
.SetWidth( ImplLogicWidthToDevicePixel( aInfo
.GetWidth() ) );
579 tools::Rectangle
OutputDevice::ImplDevicePixelToLogic( const tools::Rectangle
& rPixelRect
) const
581 // tdf#141761 see comments above, IsEmpty() removed
582 tools::Rectangle aRetval
;
586 aRetval
= tools::Rectangle(
587 rPixelRect
.Left()-mnOutOffX
,
588 rPixelRect
.Top()-mnOutOffY
,
589 rPixelRect
.IsWidthEmpty() ? 0 : rPixelRect
.Right()-mnOutOffX
,
590 rPixelRect
.IsHeightEmpty() ? 0 : rPixelRect
.Bottom()-mnOutOffY
);
594 aRetval
= tools::Rectangle(
595 ImplPixelToLogic( rPixelRect
.Left()-mnOutOffX
-mnOutOffOrigX
, mnDPIX
, maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)-maMapRes
.mnMapOfsX
,
596 ImplPixelToLogic( rPixelRect
.Top()-mnOutOffY
-mnOutOffOrigY
, mnDPIY
, maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)-maMapRes
.mnMapOfsY
,
597 rPixelRect
.IsWidthEmpty() ? 0 : ImplPixelToLogic( rPixelRect
.Right()-mnOutOffX
-mnOutOffOrigX
, mnDPIX
, maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)-maMapRes
.mnMapOfsX
,
598 rPixelRect
.IsHeightEmpty() ? 0 : ImplPixelToLogic( rPixelRect
.Bottom()-mnOutOffY
-mnOutOffOrigY
, mnDPIY
, maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)-maMapRes
.mnMapOfsY
);
601 if(rPixelRect
.IsWidthEmpty())
602 aRetval
.SetWidthEmpty();
604 if(rPixelRect
.IsHeightEmpty())
605 aRetval
.SetHeightEmpty();
610 vcl::Region
OutputDevice::ImplPixelToDevicePixel( const vcl::Region
& rRegion
) const
612 if ( !mnOutOffX
&& !mnOutOffY
)
615 vcl::Region
aRegion( rRegion
);
616 aRegion
.Move( mnOutOffX
+mnOutOffOrigX
, mnOutOffY
+mnOutOffOrigY
);
620 void OutputDevice::EnableMapMode( bool bEnable
)
625 mpAlphaVDev
->EnableMapMode( bEnable
);
628 void OutputDevice::SetMapMode()
632 mpMetaFile
->AddAction( new MetaMapModeAction( MapMode() ) );
634 if ( mbMap
|| !maMapMode
.IsDefault() )
637 maMapMode
= MapMode();
639 // create new objects (clip region are not re-scaled)
642 ImplInitMapModeObjects();
644 // #106426# Adapt logical offset when changing mapmode
645 mnOutOffLogicX
= mnOutOffOrigX
; // no mapping -> equal offsets
646 mnOutOffLogicY
= mnOutOffOrigY
;
649 ImplInvalidateViewTransform();
653 mpAlphaVDev
->SetMapMode();
656 void OutputDevice::SetMapMode( const MapMode
& rNewMapMode
)
659 bool bRelMap
= (rNewMapMode
.GetMapUnit() == MapUnit::MapRelative
);
663 mpMetaFile
->AddAction( new MetaMapModeAction( rNewMapMode
) );
666 // do nothing if MapMode was not changed
667 if ( maMapMode
== rNewMapMode
)
671 mpAlphaVDev
->SetMapMode( rNewMapMode
);
673 // if default MapMode calculate nothing
674 bool bOldMap
= mbMap
;
675 mbMap
= !rNewMapMode
.IsDefault();
678 // if only the origin is converted, do not scale new
679 if ( (rNewMapMode
.GetMapUnit() == maMapMode
.GetMapUnit()) &&
680 (rNewMapMode
.GetScaleX() == maMapMode
.GetScaleX()) &&
681 (rNewMapMode
.GetScaleY() == maMapMode
.GetScaleY()) &&
685 Point aOrigin
= rNewMapMode
.GetOrigin();
686 maMapRes
.mnMapOfsX
= aOrigin
.X();
687 maMapRes
.mnMapOfsY
= aOrigin
.Y();
688 maMapMode
= rNewMapMode
;
691 ImplInvalidateViewTransform();
695 if ( !bOldMap
&& bRelMap
)
697 maMapRes
.mnMapScNumX
= 1;
698 maMapRes
.mnMapScNumY
= 1;
699 maMapRes
.mnMapScDenomX
= mnDPIX
;
700 maMapRes
.mnMapScDenomY
= mnDPIY
;
701 maMapRes
.mnMapOfsX
= 0;
702 maMapRes
.mnMapOfsY
= 0;
705 // calculate new MapMode-resolution
706 ImplCalcMapResolution(rNewMapMode
, mnDPIX
, mnDPIY
, maMapRes
);
712 maMapMode
.SetScaleX(Fraction::MakeFraction(
713 maMapMode
.GetScaleX().GetNumerator(), rNewMapMode
.GetScaleX().GetNumerator(),
714 maMapMode
.GetScaleX().GetDenominator(), rNewMapMode
.GetScaleX().GetDenominator()));
716 maMapMode
.SetScaleY(Fraction::MakeFraction(
717 maMapMode
.GetScaleY().GetNumerator(), rNewMapMode
.GetScaleY().GetNumerator(),
718 maMapMode
.GetScaleY().GetDenominator(), rNewMapMode
.GetScaleY().GetDenominator()));
720 maMapMode
.SetOrigin(Point(maMapRes
.mnMapOfsX
, maMapRes
.mnMapOfsY
));
724 maMapMode
= rNewMapMode
;
727 // create new objects (clip region are not re-scaled)
730 ImplInitMapModeObjects();
732 // #106426# Adapt logical offset when changing mapmode
733 mnOutOffLogicX
= ImplPixelToLogic( mnOutOffOrigX
, mnDPIX
,
734 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
);
735 mnOutOffLogicY
= ImplPixelToLogic( mnOutOffOrigY
, mnDPIY
,
736 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
);
739 ImplInvalidateViewTransform();
742 void OutputDevice::SetMetafileMapMode(const MapMode
& rNewMapMode
, bool bIsRecord
)
745 SetRelativeMapMode(rNewMapMode
);
747 SetMapMode(rNewMapMode
);
750 void OutputDevice::ImplInitMapModeObjects() {}
752 void OutputDevice::SetRelativeMapMode( const MapMode
& rNewMapMode
)
754 // do nothing if MapMode did not change
755 if ( maMapMode
== rNewMapMode
)
758 MapUnit eOld
= maMapMode
.GetMapUnit();
759 MapUnit eNew
= rNewMapMode
.GetMapUnit();
761 // a?F = rNewMapMode.GetScale?() / maMapMode.GetScale?()
762 Fraction aXF
= Fraction::MakeFraction( rNewMapMode
.GetScaleX().GetNumerator(),
763 maMapMode
.GetScaleX().GetDenominator(),
764 rNewMapMode
.GetScaleX().GetDenominator(),
765 maMapMode
.GetScaleX().GetNumerator() );
766 Fraction aYF
= Fraction::MakeFraction( rNewMapMode
.GetScaleY().GetNumerator(),
767 maMapMode
.GetScaleY().GetDenominator(),
768 rNewMapMode
.GetScaleY().GetDenominator(),
769 maMapMode
.GetScaleY().GetNumerator() );
771 Point
aPt( LogicToLogic( Point(), nullptr, &rNewMapMode
) );
774 if ( eOld
> MapUnit::MapPixel
)
776 SAL_WARN( "vcl.gdi", "Not implemented MapUnit" );
778 else if ( eNew
> MapUnit::MapPixel
)
780 SAL_WARN( "vcl.gdi", "Not implemented MapUnit" );
784 const auto eFrom
= MapToO3tlLength(eOld
, o3tl::Length::in
);
785 const auto eTo
= MapToO3tlLength(eNew
, o3tl::Length::in
);
786 const auto [mul
, div
] = o3tl::getConversionMulDiv(eFrom
, eTo
);
787 Fraction
aF(div
, mul
);
790 aXF
= Fraction::MakeFraction( aXF
.GetNumerator(), aF
.GetNumerator(),
791 aXF
.GetDenominator(), aF
.GetDenominator() );
792 aYF
= Fraction::MakeFraction( aYF
.GetNumerator(), aF
.GetNumerator(),
793 aYF
.GetDenominator(), aF
.GetDenominator() );
794 if ( eOld
== MapUnit::MapPixel
)
796 aXF
*= Fraction( mnDPIX
, 1 );
797 aYF
*= Fraction( mnDPIY
, 1 );
799 else if ( eNew
== MapUnit::MapPixel
)
801 aXF
*= Fraction( 1, mnDPIX
);
802 aYF
*= Fraction( 1, mnDPIY
);
807 MapMode
aNewMapMode( MapUnit::MapRelative
, Point( -aPt
.X(), -aPt
.Y() ), aXF
, aYF
);
808 SetMapMode( aNewMapMode
);
811 maMapMode
= rNewMapMode
;
813 // #106426# Adapt logical offset when changing MapMode
814 mnOutOffLogicX
= ImplPixelToLogic( mnOutOffOrigX
, mnDPIX
,
815 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
);
816 mnOutOffLogicY
= ImplPixelToLogic( mnOutOffOrigY
, mnDPIY
,
817 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
);
820 mpAlphaVDev
->SetRelativeMapMode( rNewMapMode
);
824 basegfx::B2DHomMatrix
OutputDevice::GetViewTransformation() const
826 if(mbMap
&& mpOutDevData
)
828 if(!mpOutDevData
->mpViewTransform
)
830 mpOutDevData
->mpViewTransform
= new basegfx::B2DHomMatrix
;
832 const double fScaleFactorX(static_cast<double>(mnDPIX
) * static_cast<double>(maMapRes
.mnMapScNumX
) / static_cast<double>(maMapRes
.mnMapScDenomX
));
833 const double fScaleFactorY(static_cast<double>(mnDPIY
) * static_cast<double>(maMapRes
.mnMapScNumY
) / static_cast<double>(maMapRes
.mnMapScDenomY
));
834 const double fZeroPointX((static_cast<double>(maMapRes
.mnMapOfsX
) * fScaleFactorX
) + static_cast<double>(mnOutOffOrigX
));
835 const double fZeroPointY((static_cast<double>(maMapRes
.mnMapOfsY
) * fScaleFactorY
) + static_cast<double>(mnOutOffOrigY
));
837 mpOutDevData
->mpViewTransform
->set(0, 0, fScaleFactorX
);
838 mpOutDevData
->mpViewTransform
->set(1, 1, fScaleFactorY
);
839 mpOutDevData
->mpViewTransform
->set(0, 2, fZeroPointX
);
840 mpOutDevData
->mpViewTransform
->set(1, 2, fZeroPointY
);
843 return *mpOutDevData
->mpViewTransform
;
847 return basegfx::B2DHomMatrix();
852 basegfx::B2DHomMatrix
OutputDevice::GetInverseViewTransformation() const
854 if(mbMap
&& mpOutDevData
)
856 if(!mpOutDevData
->mpInverseViewTransform
)
858 GetViewTransformation();
859 mpOutDevData
->mpInverseViewTransform
= new basegfx::B2DHomMatrix(*mpOutDevData
->mpViewTransform
);
860 mpOutDevData
->mpInverseViewTransform
->invert();
863 return *mpOutDevData
->mpInverseViewTransform
;
867 return basegfx::B2DHomMatrix();
872 basegfx::B2DHomMatrix
OutputDevice::GetViewTransformation( const MapMode
& rMapMode
) const
876 ImplCalcMapResolution(rMapMode
, mnDPIX
, mnDPIY
, aMapRes
);
878 basegfx::B2DHomMatrix aTransform
;
880 const double fScaleFactorX(static_cast<double>(mnDPIX
) * static_cast<double>(aMapRes
.mnMapScNumX
) / static_cast<double>(aMapRes
.mnMapScDenomX
));
881 const double fScaleFactorY(static_cast<double>(mnDPIY
) * static_cast<double>(aMapRes
.mnMapScNumY
) / static_cast<double>(aMapRes
.mnMapScDenomY
));
882 const double fZeroPointX((static_cast<double>(aMapRes
.mnMapOfsX
) * fScaleFactorX
) + static_cast<double>(mnOutOffOrigX
));
883 const double fZeroPointY((static_cast<double>(aMapRes
.mnMapOfsY
) * fScaleFactorY
) + static_cast<double>(mnOutOffOrigY
));
885 aTransform
.set(0, 0, fScaleFactorX
);
886 aTransform
.set(1, 1, fScaleFactorY
);
887 aTransform
.set(0, 2, fZeroPointX
);
888 aTransform
.set(1, 2, fZeroPointY
);
894 basegfx::B2DHomMatrix
OutputDevice::GetInverseViewTransformation( const MapMode
& rMapMode
) const
896 basegfx::B2DHomMatrix
aMatrix( GetViewTransformation( rMapMode
) );
901 basegfx::B2DHomMatrix
OutputDevice::ImplGetDeviceTransformation() const
903 basegfx::B2DHomMatrix aTransformation
= GetViewTransformation();
904 // TODO: is it worth to cache the transformed result?
905 if( mnOutOffX
|| mnOutOffY
)
906 aTransformation
.translate( mnOutOffX
, mnOutOffY
);
907 return aTransformation
;
910 Point
OutputDevice::LogicToPixel( const Point
& rLogicPt
) const
916 return Point( ImplLogicToPixel( rLogicPt
.X() + maMapRes
.mnMapOfsX
, mnDPIX
,
917 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)+mnOutOffOrigX
,
918 ImplLogicToPixel( rLogicPt
.Y() + maMapRes
.mnMapOfsY
, mnDPIY
,
919 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)+mnOutOffOrigY
);
922 Size
OutputDevice::LogicToPixel( const Size
& rLogicSize
) const
928 return Size( ImplLogicToPixel( rLogicSize
.Width(), mnDPIX
,
929 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
),
930 ImplLogicToPixel( rLogicSize
.Height(), mnDPIY
,
931 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
) );
934 tools::Rectangle
OutputDevice::LogicToPixel( const tools::Rectangle
& rLogicRect
) const
936 // tdf#141761 see comments above, IsEmpty() removed
940 tools::Rectangle
aRetval(
941 ImplLogicToPixel( rLogicRect
.Left() + maMapRes
.mnMapOfsX
, mnDPIX
, maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)+mnOutOffOrigX
,
942 ImplLogicToPixel( rLogicRect
.Top() + maMapRes
.mnMapOfsY
, mnDPIY
, maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)+mnOutOffOrigY
,
943 rLogicRect
.IsWidthEmpty() ? 0 : ImplLogicToPixel( rLogicRect
.Right() + maMapRes
.mnMapOfsX
, mnDPIX
, maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)+mnOutOffOrigX
,
944 rLogicRect
.IsHeightEmpty() ? 0 : ImplLogicToPixel( rLogicRect
.Bottom() + maMapRes
.mnMapOfsY
, mnDPIY
, maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)+mnOutOffOrigY
);
946 if(rLogicRect
.IsWidthEmpty())
947 aRetval
.SetWidthEmpty();
949 if(rLogicRect
.IsHeightEmpty())
950 aRetval
.SetHeightEmpty();
955 tools::Polygon
OutputDevice::LogicToPixel( const tools::Polygon
& rLogicPoly
) const
962 sal_uInt16 nPoints
= rLogicPoly
.GetSize();
963 tools::Polygon
aPoly( rLogicPoly
);
965 // get pointer to Point-array (copy data)
966 const Point
* pPointAry
= aPoly
.GetConstPointAry();
968 for ( i
= 0; i
< nPoints
; i
++ )
970 const Point
* pPt
= &(pPointAry
[i
]);
972 aPt
.setX( ImplLogicToPixel( pPt
->X() + maMapRes
.mnMapOfsX
, mnDPIX
,
973 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)+mnOutOffOrigX
);
974 aPt
.setY( ImplLogicToPixel( pPt
->Y() + maMapRes
.mnMapOfsY
, mnDPIY
,
975 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)+mnOutOffOrigY
);
982 tools::PolyPolygon
OutputDevice::LogicToPixel( const tools::PolyPolygon
& rLogicPolyPoly
) const
986 return rLogicPolyPoly
;
988 tools::PolyPolygon
aPolyPoly( rLogicPolyPoly
);
989 sal_uInt16 nPoly
= aPolyPoly
.Count();
990 for( sal_uInt16 i
= 0; i
< nPoly
; i
++ )
992 tools::Polygon
& rPoly
= aPolyPoly
[i
];
993 rPoly
= LogicToPixel( rPoly
);
998 basegfx::B2DPolyPolygon
OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon
& rLogicPolyPoly
) const
1000 basegfx::B2DPolyPolygon aTransformedPoly
= rLogicPolyPoly
;
1001 const basegfx::B2DHomMatrix aTransformationMatrix
= GetViewTransformation();
1002 aTransformedPoly
.transform( aTransformationMatrix
);
1003 return aTransformedPoly
;
1006 vcl::Region
OutputDevice::LogicToPixel( const vcl::Region
& rLogicRegion
) const
1009 if(!mbMap
|| rLogicRegion
.IsNull() || rLogicRegion
.IsEmpty())
1011 return rLogicRegion
;
1014 vcl::Region aRegion
;
1016 if(rLogicRegion
.getB2DPolyPolygon())
1018 aRegion
= vcl::Region(LogicToPixel(*rLogicRegion
.getB2DPolyPolygon()));
1020 else if(rLogicRegion
.getPolyPolygon())
1022 aRegion
= vcl::Region(LogicToPixel(*rLogicRegion
.getPolyPolygon()));
1024 else if(rLogicRegion
.getRegionBand())
1026 RectangleVector aRectangles
;
1027 rLogicRegion
.GetRegionRectangles(aRectangles
);
1028 const RectangleVector
& rRectangles(aRectangles
); // needed to make the '!=' work
1030 // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1031 for(RectangleVector::const_reverse_iterator
aRectIter(rRectangles
.rbegin()); aRectIter
!= rRectangles
.rend(); ++aRectIter
)
1033 aRegion
.Union(LogicToPixel(*aRectIter
));
1040 Point
OutputDevice::LogicToPixel( const Point
& rLogicPt
,
1041 const MapMode
& rMapMode
) const
1044 if ( rMapMode
.IsDefault() )
1047 // convert MapMode resolution and convert
1049 ImplCalcMapResolution(rMapMode
, mnDPIX
, mnDPIY
, aMapRes
);
1051 return Point( ImplLogicToPixel( rLogicPt
.X() + aMapRes
.mnMapOfsX
, mnDPIX
,
1052 aMapRes
.mnMapScNumX
, aMapRes
.mnMapScDenomX
)+mnOutOffOrigX
,
1053 ImplLogicToPixel( rLogicPt
.Y() + aMapRes
.mnMapOfsY
, mnDPIY
,
1054 aMapRes
.mnMapScNumY
, aMapRes
.mnMapScDenomY
)+mnOutOffOrigY
);
1057 Size
OutputDevice::LogicToPixel( const Size
& rLogicSize
,
1058 const MapMode
& rMapMode
) const
1061 if ( rMapMode
.IsDefault() )
1064 // convert MapMode resolution and convert
1066 ImplCalcMapResolution(rMapMode
, mnDPIX
, mnDPIY
, aMapRes
);
1068 return Size( ImplLogicToPixel( rLogicSize
.Width(), mnDPIX
,
1069 aMapRes
.mnMapScNumX
, aMapRes
.mnMapScDenomX
),
1070 ImplLogicToPixel( rLogicSize
.Height(), mnDPIY
,
1071 aMapRes
.mnMapScNumY
, aMapRes
.mnMapScDenomY
) );
1074 tools::Rectangle
OutputDevice::LogicToPixel( const tools::Rectangle
& rLogicRect
,
1075 const MapMode
& rMapMode
) const
1077 // tdf#141761 see comments above, IsEmpty() removed
1078 if ( rMapMode
.IsDefault() )
1081 // convert MapMode resolution and convert
1083 ImplCalcMapResolution(rMapMode
, mnDPIX
, mnDPIY
, aMapRes
);
1085 tools::Rectangle
aRetval(
1086 ImplLogicToPixel( rLogicRect
.Left() + aMapRes
.mnMapOfsX
, mnDPIX
, aMapRes
.mnMapScNumX
, aMapRes
.mnMapScDenomX
)+mnOutOffOrigX
,
1087 ImplLogicToPixel( rLogicRect
.Top() + aMapRes
.mnMapOfsY
, mnDPIY
, aMapRes
.mnMapScNumY
, aMapRes
.mnMapScDenomY
)+mnOutOffOrigY
,
1088 rLogicRect
.IsWidthEmpty() ? 0 : ImplLogicToPixel( rLogicRect
.Right() + aMapRes
.mnMapOfsX
, mnDPIX
, aMapRes
.mnMapScNumX
, aMapRes
.mnMapScDenomX
)+mnOutOffOrigX
,
1089 rLogicRect
.IsHeightEmpty() ? 0 : ImplLogicToPixel( rLogicRect
.Bottom() + aMapRes
.mnMapOfsY
, mnDPIY
, aMapRes
.mnMapScNumY
, aMapRes
.mnMapScDenomY
)+mnOutOffOrigY
);
1091 if(rLogicRect
.IsWidthEmpty())
1092 aRetval
.SetWidthEmpty();
1094 if(rLogicRect
.IsHeightEmpty())
1095 aRetval
.SetHeightEmpty();
1100 tools::Polygon
OutputDevice::LogicToPixel( const tools::Polygon
& rLogicPoly
,
1101 const MapMode
& rMapMode
) const
1104 if ( rMapMode
.IsDefault() )
1107 // convert MapMode resolution and convert
1109 ImplCalcMapResolution(rMapMode
, mnDPIX
, mnDPIY
, aMapRes
);
1112 sal_uInt16 nPoints
= rLogicPoly
.GetSize();
1113 tools::Polygon
aPoly( rLogicPoly
);
1115 // get pointer to Point-array (copy data)
1116 const Point
* pPointAry
= aPoly
.GetConstPointAry();
1118 for ( i
= 0; i
< nPoints
; i
++ )
1120 const Point
* pPt
= &(pPointAry
[i
]);
1122 aPt
.setX( ImplLogicToPixel( pPt
->X() + aMapRes
.mnMapOfsX
, mnDPIX
,
1123 aMapRes
.mnMapScNumX
, aMapRes
.mnMapScDenomX
)+mnOutOffOrigX
);
1124 aPt
.setY( ImplLogicToPixel( pPt
->Y() + aMapRes
.mnMapOfsY
, mnDPIY
,
1125 aMapRes
.mnMapScNumY
, aMapRes
.mnMapScDenomY
)+mnOutOffOrigY
);
1132 basegfx::B2DPolyPolygon
OutputDevice::LogicToPixel( const basegfx::B2DPolyPolygon
& rLogicPolyPoly
,
1133 const MapMode
& rMapMode
) const
1135 basegfx::B2DPolyPolygon aTransformedPoly
= rLogicPolyPoly
;
1136 const basegfx::B2DHomMatrix aTransformationMatrix
= GetViewTransformation( rMapMode
);
1137 aTransformedPoly
.transform( aTransformationMatrix
);
1138 return aTransformedPoly
;
1141 Point
OutputDevice::PixelToLogic( const Point
& rDevicePt
) const
1147 return Point( ImplPixelToLogic( rDevicePt
.X(), mnDPIX
,
1148 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
) - maMapRes
.mnMapOfsX
- mnOutOffLogicX
,
1149 ImplPixelToLogic( rDevicePt
.Y(), mnDPIY
,
1150 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
) - maMapRes
.mnMapOfsY
- mnOutOffLogicY
);
1153 Point
OutputDevice::SubPixelToLogic(const basegfx::B2DPoint
& rDevicePt
) const
1157 assert(floor(rDevicePt
.getX() == rDevicePt
.getX()) && floor(rDevicePt
.getY() == rDevicePt
.getY()));
1158 return Point(rDevicePt
.getX(), rDevicePt
.getY());
1161 return Point(ImplSubPixelToLogic(rDevicePt
.getX(), mnDPIX
,
1162 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
) - maMapRes
.mnMapOfsX
- mnOutOffLogicX
,
1163 ImplSubPixelToLogic(rDevicePt
.getY(), mnDPIY
,
1164 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
) - maMapRes
.mnMapOfsY
- mnOutOffLogicY
);
1167 Size
OutputDevice::PixelToLogic( const Size
& rDeviceSize
) const
1173 return Size( ImplPixelToLogic( rDeviceSize
.Width(), mnDPIX
,
1174 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
),
1175 ImplPixelToLogic( rDeviceSize
.Height(), mnDPIY
,
1176 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
) );
1179 tools::Rectangle
OutputDevice::PixelToLogic( const tools::Rectangle
& rDeviceRect
) const
1181 // tdf#141761 see comments above, IsEmpty() removed
1185 tools::Rectangle
aRetval(
1186 ImplPixelToLogic( rDeviceRect
.Left(), mnDPIX
, maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
) - maMapRes
.mnMapOfsX
- mnOutOffLogicX
,
1187 ImplPixelToLogic( rDeviceRect
.Top(), mnDPIY
, maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
) - maMapRes
.mnMapOfsY
- mnOutOffLogicY
,
1188 rDeviceRect
.IsWidthEmpty() ? 0 : ImplPixelToLogic( rDeviceRect
.Right(), mnDPIX
, maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
) - maMapRes
.mnMapOfsX
- mnOutOffLogicX
,
1189 rDeviceRect
.IsHeightEmpty() ? 0 : ImplPixelToLogic( rDeviceRect
.Bottom(), mnDPIY
, maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
) - maMapRes
.mnMapOfsY
- mnOutOffLogicY
);
1191 if(rDeviceRect
.IsWidthEmpty())
1192 aRetval
.SetWidthEmpty();
1194 if(rDeviceRect
.IsHeightEmpty())
1195 aRetval
.SetHeightEmpty();
1200 tools::Polygon
OutputDevice::PixelToLogic( const tools::Polygon
& rDevicePoly
) const
1207 sal_uInt16 nPoints
= rDevicePoly
.GetSize();
1208 tools::Polygon
aPoly( rDevicePoly
);
1210 // get pointer to Point-array (copy data)
1211 const Point
* pPointAry
= aPoly
.GetConstPointAry();
1213 for ( i
= 0; i
< nPoints
; i
++ )
1215 const Point
* pPt
= &(pPointAry
[i
]);
1217 aPt
.setX( ImplPixelToLogic( pPt
->X(), mnDPIX
,
1218 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
) - maMapRes
.mnMapOfsX
- mnOutOffLogicX
);
1219 aPt
.setY( ImplPixelToLogic( pPt
->Y(), mnDPIY
,
1220 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
) - maMapRes
.mnMapOfsY
- mnOutOffLogicY
);
1227 tools::PolyPolygon
OutputDevice::PixelToLogic( const tools::PolyPolygon
& rDevicePolyPoly
) const
1231 return rDevicePolyPoly
;
1233 tools::PolyPolygon
aPolyPoly( rDevicePolyPoly
);
1234 sal_uInt16 nPoly
= aPolyPoly
.Count();
1235 for( sal_uInt16 i
= 0; i
< nPoly
; i
++ )
1237 tools::Polygon
& rPoly
= aPolyPoly
[i
];
1238 rPoly
= PixelToLogic( rPoly
);
1243 basegfx::B2DPolyPolygon
OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygon
& rPixelPolyPoly
) const
1245 basegfx::B2DPolyPolygon aTransformedPoly
= rPixelPolyPoly
;
1246 const basegfx::B2DHomMatrix aTransformationMatrix
= GetInverseViewTransformation();
1247 aTransformedPoly
.transform( aTransformationMatrix
);
1248 return aTransformedPoly
;
1251 basegfx::B2DRectangle
OutputDevice::PixelToLogic(const basegfx::B2DRectangle
& rDeviceRect
) const
1253 basegfx::B2DRectangle aTransformedRect
= rDeviceRect
;
1254 const basegfx::B2DHomMatrix aTransformationMatrix
= GetInverseViewTransformation();
1255 aTransformedRect
.transform(aTransformationMatrix
);
1256 return aTransformedRect
;
1259 vcl::Region
OutputDevice::PixelToLogic( const vcl::Region
& rDeviceRegion
) const
1262 if(!mbMap
|| rDeviceRegion
.IsNull() || rDeviceRegion
.IsEmpty())
1264 return rDeviceRegion
;
1267 vcl::Region aRegion
;
1269 if(rDeviceRegion
.getB2DPolyPolygon())
1271 aRegion
= vcl::Region(PixelToLogic(*rDeviceRegion
.getB2DPolyPolygon()));
1273 else if(rDeviceRegion
.getPolyPolygon())
1275 aRegion
= vcl::Region(PixelToLogic(*rDeviceRegion
.getPolyPolygon()));
1277 else if(rDeviceRegion
.getRegionBand())
1279 RectangleVector aRectangles
;
1280 rDeviceRegion
.GetRegionRectangles(aRectangles
);
1281 const RectangleVector
& rRectangles(aRectangles
); // needed to make the '!=' work
1283 // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1284 for(RectangleVector::const_reverse_iterator
aRectIter(rRectangles
.rbegin()); aRectIter
!= rRectangles
.rend(); ++aRectIter
)
1286 aRegion
.Union(PixelToLogic(*aRectIter
));
1293 Point
OutputDevice::PixelToLogic( const Point
& rDevicePt
,
1294 const MapMode
& rMapMode
) const
1297 // calculate nothing if default-MapMode
1298 if ( rMapMode
.IsDefault() )
1301 // calculate MapMode-resolution and convert
1303 ImplCalcMapResolution(rMapMode
, mnDPIX
, mnDPIY
, aMapRes
);
1305 return Point( ImplPixelToLogic( rDevicePt
.X(), mnDPIX
,
1306 aMapRes
.mnMapScNumX
, aMapRes
.mnMapScDenomX
) - aMapRes
.mnMapOfsX
- mnOutOffLogicX
,
1307 ImplPixelToLogic( rDevicePt
.Y(), mnDPIY
,
1308 aMapRes
.mnMapScNumY
, aMapRes
.mnMapScDenomY
) - aMapRes
.mnMapOfsY
- mnOutOffLogicY
);
1311 Size
OutputDevice::PixelToLogic( const Size
& rDeviceSize
,
1312 const MapMode
& rMapMode
) const
1315 // calculate nothing if default-MapMode
1316 if ( rMapMode
.IsDefault() )
1319 // calculate MapMode-resolution and convert
1321 ImplCalcMapResolution(rMapMode
, mnDPIX
, mnDPIY
, aMapRes
);
1323 return Size( ImplPixelToLogic( rDeviceSize
.Width(), mnDPIX
,
1324 aMapRes
.mnMapScNumX
, aMapRes
.mnMapScDenomX
),
1325 ImplPixelToLogic( rDeviceSize
.Height(), mnDPIY
,
1326 aMapRes
.mnMapScNumY
, aMapRes
.mnMapScDenomY
) );
1329 tools::Rectangle
OutputDevice::PixelToLogic( const tools::Rectangle
& rDeviceRect
,
1330 const MapMode
& rMapMode
) const
1332 // calculate nothing if default-MapMode
1333 // tdf#141761 see comments above, IsEmpty() removed
1334 if ( rMapMode
.IsDefault() )
1337 // calculate MapMode-resolution and convert
1339 ImplCalcMapResolution(rMapMode
, mnDPIX
, mnDPIY
, aMapRes
);
1341 tools::Rectangle
aRetval(
1342 ImplPixelToLogic( rDeviceRect
.Left(), mnDPIX
, aMapRes
.mnMapScNumX
, aMapRes
.mnMapScDenomX
) - aMapRes
.mnMapOfsX
- mnOutOffLogicX
,
1343 ImplPixelToLogic( rDeviceRect
.Top(), mnDPIY
, aMapRes
.mnMapScNumY
, aMapRes
.mnMapScDenomY
) - aMapRes
.mnMapOfsY
- mnOutOffLogicY
,
1344 rDeviceRect
.IsWidthEmpty() ? 0 : ImplPixelToLogic( rDeviceRect
.Right(), mnDPIX
, aMapRes
.mnMapScNumX
, aMapRes
.mnMapScDenomX
) - aMapRes
.mnMapOfsX
- mnOutOffLogicX
,
1345 rDeviceRect
.IsHeightEmpty() ? 0 : ImplPixelToLogic( rDeviceRect
.Bottom(), mnDPIY
, aMapRes
.mnMapScNumY
, aMapRes
.mnMapScDenomY
) - aMapRes
.mnMapOfsY
- mnOutOffLogicY
);
1347 if(rDeviceRect
.IsWidthEmpty())
1348 aRetval
.SetWidthEmpty();
1350 if(rDeviceRect
.IsHeightEmpty())
1351 aRetval
.SetHeightEmpty();
1356 tools::Polygon
OutputDevice::PixelToLogic( const tools::Polygon
& rDevicePoly
,
1357 const MapMode
& rMapMode
) const
1360 // calculate nothing if default-MapMode
1361 if ( rMapMode
.IsDefault() )
1364 // calculate MapMode-resolution and convert
1366 ImplCalcMapResolution(rMapMode
, mnDPIX
, mnDPIY
, aMapRes
);
1369 sal_uInt16 nPoints
= rDevicePoly
.GetSize();
1370 tools::Polygon
aPoly( rDevicePoly
);
1372 // get pointer to Point-array (copy data)
1373 const Point
* pPointAry
= aPoly
.GetConstPointAry();
1375 for ( i
= 0; i
< nPoints
; i
++ )
1377 const Point
* pPt
= &(pPointAry
[i
]);
1379 aPt
.setX( ImplPixelToLogic( pPt
->X(), mnDPIX
,
1380 aMapRes
.mnMapScNumX
, aMapRes
.mnMapScDenomX
) - aMapRes
.mnMapOfsX
- mnOutOffLogicX
);
1381 aPt
.setY( ImplPixelToLogic( pPt
->Y(), mnDPIY
,
1382 aMapRes
.mnMapScNumY
, aMapRes
.mnMapScDenomY
) - aMapRes
.mnMapOfsY
- mnOutOffLogicY
);
1389 basegfx::B2DPolygon
OutputDevice::PixelToLogic( const basegfx::B2DPolygon
& rPixelPoly
,
1390 const MapMode
& rMapMode
) const
1392 basegfx::B2DPolygon aTransformedPoly
= rPixelPoly
;
1393 const basegfx::B2DHomMatrix aTransformationMatrix
= GetInverseViewTransformation( rMapMode
);
1394 aTransformedPoly
.transform( aTransformationMatrix
);
1395 return aTransformedPoly
;
1398 basegfx::B2DPolyPolygon
OutputDevice::PixelToLogic( const basegfx::B2DPolyPolygon
& rPixelPolyPoly
,
1399 const MapMode
& rMapMode
) const
1401 basegfx::B2DPolyPolygon aTransformedPoly
= rPixelPolyPoly
;
1402 const basegfx::B2DHomMatrix aTransformationMatrix
= GetInverseViewTransformation( rMapMode
);
1403 aTransformedPoly
.transform( aTransformationMatrix
);
1404 return aTransformedPoly
;
1407 #define ENTER1( rSource, pMapModeSource, pMapModeDest ) \
1408 if ( !pMapModeSource ) \
1409 pMapModeSource = &maMapMode; \
1410 if ( !pMapModeDest ) \
1411 pMapModeDest = &maMapMode; \
1412 if ( *pMapModeSource == *pMapModeDest ) \
1415 ImplMapRes aMapResSource; \
1416 ImplMapRes aMapResDest; \
1418 if ( !mbMap || pMapModeSource != &maMapMode ) \
1420 if ( pMapModeSource->GetMapUnit() == MapUnit::MapRelative ) \
1421 aMapResSource = maMapRes; \
1422 ImplCalcMapResolution( *pMapModeSource, \
1423 mnDPIX, mnDPIY, aMapResSource ); \
1426 aMapResSource = maMapRes; \
1427 if ( !mbMap || pMapModeDest != &maMapMode ) \
1429 if ( pMapModeDest->GetMapUnit() == MapUnit::MapRelative ) \
1430 aMapResDest = maMapRes; \
1431 ImplCalcMapResolution( *pMapModeDest, \
1432 mnDPIX, mnDPIY, aMapResDest ); \
1435 aMapResDest = maMapRes
1437 static void verifyUnitSourceDest( MapUnit eUnitSource
, MapUnit eUnitDest
)
1439 DBG_ASSERT( eUnitSource
!= MapUnit::MapSysFont
1440 && eUnitSource
!= MapUnit::MapAppFont
1441 && eUnitSource
!= MapUnit::MapRelative
,
1442 "Source MapUnit is not permitted" );
1443 DBG_ASSERT( eUnitDest
!= MapUnit::MapSysFont
1444 && eUnitDest
!= MapUnit::MapAppFont
1445 && eUnitDest
!= MapUnit::MapRelative
,
1446 "Destination MapUnit is not permitted" );
1451 auto getCorrectedUnit(MapUnit eMapSrc
, MapUnit eMapDst
)
1453 o3tl::Length eSrc
= o3tl::Length::invalid
;
1454 o3tl::Length eDst
= o3tl::Length::invalid
;
1455 if (eMapSrc
> MapUnit::MapPixel
)
1456 SAL_WARN("vcl.gdi", "Invalid source map unit");
1457 else if (eMapDst
> MapUnit::MapPixel
)
1458 SAL_WARN("vcl.gdi", "Invalid destination map unit");
1459 else if (eMapSrc
!= eMapDst
)
1461 // Here 72 PPI is assumed for MapPixel
1462 eSrc
= MapToO3tlLength(eMapSrc
, o3tl::Length::pt
);
1463 eDst
= MapToO3tlLength(eMapDst
, o3tl::Length::pt
);
1465 return std::make_pair(eSrc
, eDst
);
1468 std::pair
<ImplMapRes
, ImplMapRes
> ENTER4(const MapMode
& rMMSource
, const MapMode
& rMMDest
)
1470 std::pair
<ImplMapRes
, ImplMapRes
> result
;
1471 ImplCalcMapResolution(rMMSource
, 72, 72, result
.first
);
1472 ImplCalcMapResolution(rMMDest
, 72, 72, result
.second
);
1477 // return (n1 * n2 * n3) / (n4 * n5)
1478 static tools::Long
fn5( const tools::Long n1
,
1479 const tools::Long n2
,
1480 const tools::Long n3
,
1481 const tools::Long n4
,
1482 const tools::Long n5
)
1484 if ( n1
== 0 || n2
== 0 || n3
== 0 || n4
== 0 || n5
== 0 )
1486 if (std::numeric_limits
<tools::Long
>::max() / std::abs(n2
) < std::abs(n3
))
1493 if (std::numeric_limits
<tools::Long
>::max() / std::abs(n4
) < std::abs(n5
))
1509 tools::Long n8
= n4
* n5
;
1518 return static_cast<tools::Long
>(a7
);
1522 tools::Long n6
= n2
* n3
;
1524 if (std::numeric_limits
<tools::Long
>::max() / std::abs(n1
) < std::abs(n6
))
1529 if (std::numeric_limits
<tools::Long
>::max() / std::abs(n4
) < std::abs(n5
))
1545 tools::Long n8
= n4
* n5
;
1554 return static_cast<tools::Long
>(a7
);
1558 tools::Long n7
= n1
* n6
;
1560 if (std::numeric_limits
<tools::Long
>::max() / std::abs(n4
) < std::abs(n5
))
1574 return static_cast<tools::Long
>(a7
);
1578 const tools::Long n8
= n4
* n5
;
1579 const tools::Long n8_2
= n8
/ 2;
1583 if ((n7
- std::numeric_limits
<tools::Long
>::min()) >= n8_2
)
1586 else if ((std::numeric_limits
<tools::Long
>::max() - n7
) >= n8_2
)
1595 static tools::Long
fn3(const tools::Long n1
, const o3tl::Length eFrom
, const o3tl::Length eTo
)
1597 if (n1
== 0 || eFrom
== o3tl::Length::invalid
|| eTo
== o3tl::Length::invalid
)
1600 const auto nResult
= o3tl::convert(n1
, eFrom
, eTo
, bOverflow
);
1603 const auto [n2
, n3
] = o3tl::getConversionMulDiv(eFrom
, eTo
);
1613 return static_cast<tools::Long
>(a4
);
1619 Point
OutputDevice::LogicToLogic( const Point
& rPtSource
,
1620 const MapMode
* pMapModeSource
,
1621 const MapMode
* pMapModeDest
) const
1623 ENTER1( rPtSource
, pMapModeSource
, pMapModeDest
);
1625 return Point( fn5( rPtSource
.X() + aMapResSource
.mnMapOfsX
,
1626 aMapResSource
.mnMapScNumX
, aMapResDest
.mnMapScDenomX
,
1627 aMapResSource
.mnMapScDenomX
, aMapResDest
.mnMapScNumX
) -
1628 aMapResDest
.mnMapOfsX
,
1629 fn5( rPtSource
.Y() + aMapResSource
.mnMapOfsY
,
1630 aMapResSource
.mnMapScNumY
, aMapResDest
.mnMapScDenomY
,
1631 aMapResSource
.mnMapScDenomY
, aMapResDest
.mnMapScNumY
) -
1632 aMapResDest
.mnMapOfsY
);
1635 Size
OutputDevice::LogicToLogic( const Size
& rSzSource
,
1636 const MapMode
* pMapModeSource
,
1637 const MapMode
* pMapModeDest
) const
1639 ENTER1( rSzSource
, pMapModeSource
, pMapModeDest
);
1641 return Size( fn5( rSzSource
.Width(),
1642 aMapResSource
.mnMapScNumX
, aMapResDest
.mnMapScDenomX
,
1643 aMapResSource
.mnMapScDenomX
, aMapResDest
.mnMapScNumX
),
1644 fn5( rSzSource
.Height(),
1645 aMapResSource
.mnMapScNumY
, aMapResDest
.mnMapScDenomY
,
1646 aMapResSource
.mnMapScDenomY
, aMapResDest
.mnMapScNumY
) );
1649 tools::Rectangle
OutputDevice::LogicToLogic( const tools::Rectangle
& rRectSource
,
1650 const MapMode
* pMapModeSource
,
1651 const MapMode
* pMapModeDest
) const
1653 ENTER1( rRectSource
, pMapModeSource
, pMapModeDest
);
1655 return tools::Rectangle( fn5( rRectSource
.Left() + aMapResSource
.mnMapOfsX
,
1656 aMapResSource
.mnMapScNumX
, aMapResDest
.mnMapScDenomX
,
1657 aMapResSource
.mnMapScDenomX
, aMapResDest
.mnMapScNumX
) -
1658 aMapResDest
.mnMapOfsX
,
1659 fn5( rRectSource
.Top() + aMapResSource
.mnMapOfsY
,
1660 aMapResSource
.mnMapScNumY
, aMapResDest
.mnMapScDenomY
,
1661 aMapResSource
.mnMapScDenomY
, aMapResDest
.mnMapScNumY
) -
1662 aMapResDest
.mnMapOfsY
,
1663 fn5( rRectSource
.Right() + aMapResSource
.mnMapOfsX
,
1664 aMapResSource
.mnMapScNumX
, aMapResDest
.mnMapScDenomX
,
1665 aMapResSource
.mnMapScDenomX
, aMapResDest
.mnMapScNumX
) -
1666 aMapResDest
.mnMapOfsX
,
1667 fn5( rRectSource
.Bottom() + aMapResSource
.mnMapOfsY
,
1668 aMapResSource
.mnMapScNumY
, aMapResDest
.mnMapScDenomY
,
1669 aMapResSource
.mnMapScDenomY
, aMapResDest
.mnMapScNumY
) -
1670 aMapResDest
.mnMapOfsY
);
1673 Point
OutputDevice::LogicToLogic( const Point
& rPtSource
,
1674 const MapMode
& rMapModeSource
,
1675 const MapMode
& rMapModeDest
)
1677 if ( rMapModeSource
== rMapModeDest
)
1680 MapUnit eUnitSource
= rMapModeSource
.GetMapUnit();
1681 MapUnit eUnitDest
= rMapModeDest
.GetMapUnit();
1682 verifyUnitSourceDest( eUnitSource
, eUnitDest
);
1684 if (rMapModeSource
.IsSimple() && rMapModeDest
.IsSimple())
1686 const auto [eFrom
, eTo
] = getCorrectedUnit(eUnitSource
, eUnitDest
);
1687 return Point(fn3(rPtSource
.X(), eFrom
, eTo
), fn3(rPtSource
.Y(), eFrom
, eTo
));
1691 const auto [aMapResSource
, aMapResDest
] = ENTER4( rMapModeSource
, rMapModeDest
);
1693 return Point( fn5( rPtSource
.X() + aMapResSource
.mnMapOfsX
,
1694 aMapResSource
.mnMapScNumX
, aMapResDest
.mnMapScDenomX
,
1695 aMapResSource
.mnMapScDenomX
, aMapResDest
.mnMapScNumX
) -
1696 aMapResDest
.mnMapOfsX
,
1697 fn5( rPtSource
.Y() + aMapResSource
.mnMapOfsY
,
1698 aMapResSource
.mnMapScNumY
, aMapResDest
.mnMapScDenomY
,
1699 aMapResSource
.mnMapScDenomY
, aMapResDest
.mnMapScNumY
) -
1700 aMapResDest
.mnMapOfsY
);
1704 Size
OutputDevice::LogicToLogic( const Size
& rSzSource
,
1705 const MapMode
& rMapModeSource
,
1706 const MapMode
& rMapModeDest
)
1708 if ( rMapModeSource
== rMapModeDest
)
1711 MapUnit eUnitSource
= rMapModeSource
.GetMapUnit();
1712 MapUnit eUnitDest
= rMapModeDest
.GetMapUnit();
1713 verifyUnitSourceDest( eUnitSource
, eUnitDest
);
1715 if (rMapModeSource
.IsSimple() && rMapModeDest
.IsSimple())
1717 const auto [eFrom
, eTo
] = getCorrectedUnit(eUnitSource
, eUnitDest
);
1718 return Size(fn3(rSzSource
.Width(), eFrom
, eTo
), fn3(rSzSource
.Height(), eFrom
, eTo
));
1722 const auto [aMapResSource
, aMapResDest
] = ENTER4( rMapModeSource
, rMapModeDest
);
1724 return Size( fn5( rSzSource
.Width(),
1725 aMapResSource
.mnMapScNumX
, aMapResDest
.mnMapScDenomX
,
1726 aMapResSource
.mnMapScDenomX
, aMapResDest
.mnMapScNumX
),
1727 fn5( rSzSource
.Height(),
1728 aMapResSource
.mnMapScNumY
, aMapResDest
.mnMapScDenomY
,
1729 aMapResSource
.mnMapScDenomY
, aMapResDest
.mnMapScNumY
) );
1733 basegfx::B2DPolygon
OutputDevice::LogicToLogic( const basegfx::B2DPolygon
& rPolySource
,
1734 const MapMode
& rMapModeSource
,
1735 const MapMode
& rMapModeDest
)
1737 if(rMapModeSource
== rMapModeDest
)
1742 const basegfx::B2DHomMatrix
aTransform(LogicToLogic(rMapModeSource
, rMapModeDest
));
1743 basegfx::B2DPolygon
aPoly(rPolySource
);
1745 aPoly
.transform(aTransform
);
1749 basegfx::B2DHomMatrix
OutputDevice::LogicToLogic(const MapMode
& rMapModeSource
, const MapMode
& rMapModeDest
)
1751 basegfx::B2DHomMatrix aTransform
;
1753 if(rMapModeSource
== rMapModeDest
)
1758 MapUnit eUnitSource
= rMapModeSource
.GetMapUnit();
1759 MapUnit eUnitDest
= rMapModeDest
.GetMapUnit();
1760 verifyUnitSourceDest(eUnitSource
, eUnitDest
);
1762 if (rMapModeSource
.IsSimple() && rMapModeDest
.IsSimple())
1764 const auto [eFrom
, eTo
] = getCorrectedUnit(eUnitSource
, eUnitDest
);
1765 const double fScaleFactor(eFrom
== o3tl::Length::invalid
|| eTo
== o3tl::Length::invalid
1766 ? std::numeric_limits
<double>::quiet_NaN()
1767 : o3tl::convert(1.0, eFrom
, eTo
));
1768 aTransform
.set(0, 0, fScaleFactor
);
1769 aTransform
.set(1, 1, fScaleFactor
);
1773 const auto [aMapResSource
, aMapResDest
] = ENTER4(rMapModeSource
, rMapModeDest
);
1775 const double fScaleFactorX((double(aMapResSource
.mnMapScNumX
) * double(aMapResDest
.mnMapScDenomX
)) / (double(aMapResSource
.mnMapScDenomX
) * double(aMapResDest
.mnMapScNumX
)));
1776 const double fScaleFactorY((double(aMapResSource
.mnMapScNumY
) * double(aMapResDest
.mnMapScDenomY
)) / (double(aMapResSource
.mnMapScDenomY
) * double(aMapResDest
.mnMapScNumY
)));
1777 const double fZeroPointX(double(aMapResSource
.mnMapOfsX
) * fScaleFactorX
- double(aMapResDest
.mnMapOfsX
));
1778 const double fZeroPointY(double(aMapResSource
.mnMapOfsY
) * fScaleFactorY
- double(aMapResDest
.mnMapOfsY
));
1780 aTransform
.set(0, 0, fScaleFactorX
);
1781 aTransform
.set(1, 1, fScaleFactorY
);
1782 aTransform
.set(0, 2, fZeroPointX
);
1783 aTransform
.set(1, 2, fZeroPointY
);
1789 tools::Rectangle
OutputDevice::LogicToLogic( const tools::Rectangle
& rRectSource
,
1790 const MapMode
& rMapModeSource
,
1791 const MapMode
& rMapModeDest
)
1793 if ( rMapModeSource
== rMapModeDest
)
1796 MapUnit eUnitSource
= rMapModeSource
.GetMapUnit();
1797 MapUnit eUnitDest
= rMapModeDest
.GetMapUnit();
1798 verifyUnitSourceDest( eUnitSource
, eUnitDest
);
1800 tools::Rectangle aRetval
;
1802 if (rMapModeSource
.IsSimple() && rMapModeDest
.IsSimple())
1804 const auto [eFrom
, eTo
] = getCorrectedUnit(eUnitSource
, eUnitDest
);
1806 auto left
= fn3(rRectSource
.Left(), eFrom
, eTo
);
1807 auto top
= fn3(rRectSource
.Top(), eFrom
, eTo
);
1809 // tdf#141761 see comments above, IsEmpty() removed
1810 auto right
= rRectSource
.IsWidthEmpty() ? 0 : fn3(rRectSource
.Right(), eFrom
, eTo
);
1811 auto bottom
= rRectSource
.IsHeightEmpty() ? 0 : fn3(rRectSource
.Bottom(), eFrom
, eTo
);
1813 aRetval
= tools::Rectangle(left
, top
, right
, bottom
);
1817 const auto [aMapResSource
, aMapResDest
] = ENTER4( rMapModeSource
, rMapModeDest
);
1819 auto left
= fn5( rRectSource
.Left() + aMapResSource
.mnMapOfsX
,
1820 aMapResSource
.mnMapScNumX
, aMapResDest
.mnMapScDenomX
,
1821 aMapResSource
.mnMapScDenomX
, aMapResDest
.mnMapScNumX
) -
1822 aMapResDest
.mnMapOfsX
;
1823 auto top
= fn5( rRectSource
.Top() + aMapResSource
.mnMapOfsY
,
1824 aMapResSource
.mnMapScNumY
, aMapResDest
.mnMapScDenomY
,
1825 aMapResSource
.mnMapScDenomY
, aMapResDest
.mnMapScNumY
) -
1826 aMapResDest
.mnMapOfsY
;
1828 // tdf#141761 see comments above, IsEmpty() removed
1829 auto right
= rRectSource
.IsWidthEmpty() ? 0 : fn5( rRectSource
.Right() + aMapResSource
.mnMapOfsX
,
1830 aMapResSource
.mnMapScNumX
, aMapResDest
.mnMapScDenomX
,
1831 aMapResSource
.mnMapScDenomX
, aMapResDest
.mnMapScNumX
) -
1832 aMapResDest
.mnMapOfsX
;
1833 auto bottom
= rRectSource
.IsHeightEmpty() ? 0 : fn5( rRectSource
.Bottom() + aMapResSource
.mnMapOfsY
,
1834 aMapResSource
.mnMapScNumY
, aMapResDest
.mnMapScDenomY
,
1835 aMapResSource
.mnMapScDenomY
, aMapResDest
.mnMapScNumY
) -
1836 aMapResDest
.mnMapOfsY
;
1838 aRetval
= tools::Rectangle(left
, top
, right
, bottom
);
1841 if(rRectSource
.IsWidthEmpty())
1842 aRetval
.SetWidthEmpty();
1844 if(rRectSource
.IsHeightEmpty())
1845 aRetval
.SetHeightEmpty();
1850 tools::Long
OutputDevice::LogicToLogic( tools::Long nLongSource
,
1851 MapUnit eUnitSource
, MapUnit eUnitDest
)
1853 if ( eUnitSource
== eUnitDest
)
1856 verifyUnitSourceDest( eUnitSource
, eUnitDest
);
1857 const auto [eFrom
, eTo
] = getCorrectedUnit(eUnitSource
, eUnitDest
);
1858 return fn3(nLongSource
, eFrom
, eTo
);
1861 void OutputDevice::SetPixelOffset( const Size
& rOffset
)
1863 mnOutOffOrigX
= rOffset
.Width();
1864 mnOutOffOrigY
= rOffset
.Height();
1866 mnOutOffLogicX
= ImplPixelToLogic( mnOutOffOrigX
, mnDPIX
,
1867 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
);
1868 mnOutOffLogicY
= ImplPixelToLogic( mnOutOffOrigY
, mnDPIY
,
1869 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
);
1872 mpAlphaVDev
->SetPixelOffset( rOffset
);
1876 double OutputDevice::ImplLogicWidthToDeviceSubPixel(tools::Long nWidth
) const
1881 return ImplLogicToSubPixel(nWidth
, mnDPIX
,
1882 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
);
1885 double OutputDevice::ImplLogicHeightToDeviceSubPixel(tools::Long nHeight
) const
1890 return ImplLogicToSubPixel(nHeight
, mnDPIY
,
1891 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
);
1894 basegfx::B2DPoint
OutputDevice::ImplLogicToDeviceSubPixel(const Point
& rPoint
) const
1897 return basegfx::B2DPoint(rPoint
.X() + mnOutOffX
, rPoint
.Y() + mnOutOffY
);
1899 return basegfx::B2DPoint(ImplLogicToSubPixel(rPoint
.X() + maMapRes
.mnMapOfsX
, mnDPIX
,
1900 maMapRes
.mnMapScNumX
, maMapRes
.mnMapScDenomX
)
1901 + mnOutOffX
+ mnOutOffOrigX
,
1902 ImplLogicToSubPixel(rPoint
.Y() + maMapRes
.mnMapOfsY
, mnDPIY
,
1903 maMapRes
.mnMapScNumY
, maMapRes
.mnMapScDenomY
)
1904 + mnOutOffY
+ mnOutOffOrigY
);
1907 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */