LibreOffice Module vcl (master) 1
map.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <tools/bigint.hxx>
23#include <tools/debug.hxx>
24#include <vcl/cursor.hxx>
25#include <vcl/gdimtf.hxx>
26#include <vcl/lineinfo.hxx>
27#include <vcl/metaact.hxx>
28#include <vcl/virdev.hxx>
29#include <vcl/wrkwin.hxx>
30#include <sal/log.hxx>
31#include <osl/diagnose.h>
32
33#include <ImplOutDevData.hxx>
34#include <svdata.hxx>
35#include <window.h>
36
39
40/*
41Reduces accuracy until it is a fraction (should become
42ctor fraction once); we could also do this with BigInts
43*/
44
46{
47 if( nD1 == 0 || nD2 == 0 ) //under these bad circumstances the following while loop will be endless
48 {
49 SAL_WARN("vcl.gdi", "Invalid parameter for ImplMakeFraction");
50 return Fraction( 1, 1 );
51 }
52
53 tools::Long i = 1;
54
55 if ( nN1 < 0 ) { i = -i; nN1 = -nN1; }
56 if ( nN2 < 0 ) { i = -i; nN2 = -nN2; }
57 if ( nD1 < 0 ) { i = -i; nD1 = -nD1; }
58 if ( nD2 < 0 ) { i = -i; nD2 = -nD2; }
59 // all positive; i sign
60
61 Fraction aF = Fraction( i*nN1, nD1 ) * Fraction( nN2, nD2 );
62
63 while ( !aF.IsValid() ) {
64 if ( nN1 > nN2 )
65 nN1 = (nN1 + 1) / 2;
66 else
67 nN2 = (nN2 + 1) / 2;
68 if ( nD1 > nD2 )
69 nD1 = (nD1 + 1) / 2;
70 else
71 nD2 = (nD2 + 1) / 2;
72
73 aF = Fraction( i*nN1, nD1 ) * Fraction( nN2, nD2 );
74 }
75
76 aF.ReduceInaccurate(32);
77 return aF;
78}
79
80static auto setMapRes(ImplMapRes& rMapRes, const o3tl::Length eUnit)
81{
82 const auto [nNum, nDen] = o3tl::getConversionMulDiv(eUnit, o3tl::Length::in);
83 rMapRes.mnMapScNumX = rMapRes.mnMapScNumY = nNum;
84 rMapRes.mnMapScDenomX = rMapRes.mnMapScDenomY = nDen;
85};
86
87static void ImplCalcMapResolution( const MapMode& rMapMode,
88 tools::Long nDPIX, tools::Long nDPIY, ImplMapRes& rMapRes )
89{
90 switch ( rMapMode.GetMapUnit() )
91 {
92 case MapUnit::MapRelative:
93 break;
94 case MapUnit::Map100thMM:
96 break;
97 case MapUnit::Map10thMM:
99 break;
100 case MapUnit::MapMM:
101 setMapRes(rMapRes, o3tl::Length::mm);
102 break;
103 case MapUnit::MapCM:
104 setMapRes(rMapRes, o3tl::Length::cm);
105 break;
106 case MapUnit::Map1000thInch:
108 break;
109 case MapUnit::Map100thInch:
111 break;
112 case MapUnit::Map10thInch:
114 break;
115 case MapUnit::MapInch:
116 setMapRes(rMapRes, o3tl::Length::in);
117 break;
118 case MapUnit::MapPoint:
119 setMapRes(rMapRes, o3tl::Length::pt);
120 break;
121 case MapUnit::MapTwip:
123 break;
124 case MapUnit::MapPixel:
125 rMapRes.mnMapScNumX = 1;
126 rMapRes.mnMapScDenomX = nDPIX;
127 rMapRes.mnMapScNumY = 1;
128 rMapRes.mnMapScDenomY = nDPIY;
129 break;
130 case MapUnit::MapSysFont:
131 case MapUnit::MapAppFont:
132 {
133 ImplSVData* pSVData = ImplGetSVData();
134 if ( !pSVData->maGDIData.mnAppFontX )
135 {
136 if (pSVData->maFrameData.mpFirstFrame)
138 else
139 {
140 ScopedVclPtrInstance<WorkWindow> pWin( nullptr, 0 );
142 }
143 }
144 rMapRes.mnMapScNumX = pSVData->maGDIData.mnAppFontX;
145 rMapRes.mnMapScDenomX = nDPIX * 40;
146 rMapRes.mnMapScNumY = pSVData->maGDIData.mnAppFontY;
147 rMapRes.mnMapScDenomY = nDPIY * 80;
148 }
149 break;
150 default:
151 OSL_FAIL( "unhandled MapUnit" );
152 break;
153 }
154
155 const Fraction& aScaleX = rMapMode.GetScaleX();
156 const Fraction& aScaleY = rMapMode.GetScaleY();
157
158 // set offset according to MapMode
159 Point aOrigin = rMapMode.GetOrigin();
160 if ( rMapMode.GetMapUnit() != MapUnit::MapRelative )
161 {
162 rMapRes.mnMapOfsX = aOrigin.X();
163 rMapRes.mnMapOfsY = aOrigin.Y();
164 }
165 else
166 {
167 auto nXNumerator = aScaleX.GetNumerator();
168 auto nYNumerator = aScaleY.GetNumerator();
169 assert(nXNumerator != 0 && nYNumerator != 0);
170
171 BigInt aX( rMapRes.mnMapOfsX );
172 aX *= BigInt( aScaleX.GetDenominator() );
173 if ( rMapRes.mnMapOfsX >= 0 )
174 {
175 if (nXNumerator >= 0)
176 aX += BigInt(nXNumerator / 2);
177 else
178 aX -= BigInt((nXNumerator + 1) / 2);
179 }
180 else
181 {
182 if (nXNumerator >= 0 )
183 aX -= BigInt((nXNumerator - 1) / 2);
184 else
185 aX += BigInt(nXNumerator / 2);
186 }
187 aX /= BigInt(nXNumerator);
188 rMapRes.mnMapOfsX = static_cast<tools::Long>(aX) + aOrigin.X();
189 BigInt aY( rMapRes.mnMapOfsY );
190 aY *= BigInt( aScaleY.GetDenominator() );
191 if( rMapRes.mnMapOfsY >= 0 )
192 {
193 if (nYNumerator >= 0)
194 aY += BigInt(nYNumerator / 2);
195 else
196 aY -= BigInt((nYNumerator + 1) / 2);
197 }
198 else
199 {
200 if (nYNumerator >= 0)
201 aY -= BigInt((nYNumerator - 1) / 2);
202 else
203 aY += BigInt(nYNumerator / 2);
204 }
205 aY /= BigInt(nYNumerator);
206 rMapRes.mnMapOfsY = static_cast<tools::Long>(aY) + aOrigin.Y();
207 }
208
209 // calculate scaling factor according to MapMode
210 // aTemp? = rMapRes.mnMapSc? * aScale?
211 Fraction aTempX = ImplMakeFraction( rMapRes.mnMapScNumX,
212 aScaleX.GetNumerator(),
213 rMapRes.mnMapScDenomX,
214 aScaleX.GetDenominator() );
215 Fraction aTempY = ImplMakeFraction( rMapRes.mnMapScNumY,
216 aScaleY.GetNumerator(),
217 rMapRes.mnMapScDenomY,
218 aScaleY.GetDenominator() );
219 rMapRes.mnMapScNumX = aTempX.GetNumerator();
220 rMapRes.mnMapScDenomX = aTempX.GetDenominator();
221 rMapRes.mnMapScNumY = aTempY.GetNumerator();
222 rMapRes.mnMapScDenomY = aTempY.GetDenominator();
223}
224
225// #i75163#
227{
228 if(!mpOutDevData)
229 return;
230
231 if(mpOutDevData->mpViewTransform)
232 {
233 delete mpOutDevData->mpViewTransform;
234 mpOutDevData->mpViewTransform = nullptr;
235 }
236
237 if(mpOutDevData->mpInverseViewTransform)
238 {
239 delete mpOutDevData->mpInverseViewTransform;
240 mpOutDevData->mpInverseViewTransform = nullptr;
241 }
242}
243
245 tools::Long nMapDenom)
246{
247 assert(nDPI > 0);
248 assert(nMapDenom != 0);
249 if constexpr (sizeof(tools::Long) >= 8)
250 {
251 assert(nMapNum >= 0);
252 //detect overflows
253 assert(nMapNum == 0
254 || std::abs(n) < std::numeric_limits<tools::Long>::max() / nMapNum / nDPI);
255 }
256 sal_Int64 n64 = n;
257 n64 *= nMapNum;
258 n64 *= nDPI;
259 if (nMapDenom == 1)
260 n = static_cast<tools::Long>(n64);
261 else
262 {
263 n64 = 2 * n64 / nMapDenom;
264 if (n64 < 0)
265 --n64;
266 else
267 ++n64;
268 n = static_cast<tools::Long>(n64 / 2);
269 }
270 return n;
271}
272
274 tools::Long nMapDenom)
275{
276 assert(nDPI > 0);
277 assert(nMapDenom != 0);
278 return static_cast<double>(n) * nMapNum * nDPI / nMapDenom;
279}
280
282 tools::Long nMapDenom)
283{
284 assert(nDPI > 0);
285 assert(nMapNum != 0);
286
287 return std::round(n * nMapDenom / nMapNum / nDPI);
288}
289
291 tools::Long nMapDenom)
292{
293 assert(nDPI > 0);
294 if (nMapNum == 0)
295 return 0;
296 sal_Int64 nDenom = nDPI;
297 nDenom *= nMapNum;
298
299 sal_Int64 n64 = n;
300 n64 *= nMapDenom;
301 if (nDenom == 1)
302 n = static_cast<tools::Long>(n64);
303 else
304 {
305 n64 = 2 * n64 / nDenom;
306 if (n64 < 0)
307 --n64;
308 else
309 ++n64;
310 n = static_cast<tools::Long>(n64 / 2);
311 }
312 return n;
313}
314
316{
317 if ( !mbMap )
318 return nX+mnOutOffX;
319
322}
323
325{
326 if ( !mbMap )
327 return nY+mnOutOffY;
328
331}
332
334{
335 if ( !mbMap )
336 return nWidth;
337
339}
340
342{
343 if ( !mbMap )
344 return nHeight;
345
347}
348
350{
351 if ( !mbMap )
352 return nWidth;
353
355}
356
358{
359 if ( !mbMap )
360 return nHeight;
361
363}
364
365Point OutputDevice::ImplLogicToDevicePixel( const Point& rLogicPt ) const
366{
367 if ( !mbMap )
368 return Point( rLogicPt.X()+mnOutOffX, rLogicPt.Y()+mnOutOffY );
369
370 return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
372 ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
374}
375
377{
378 if ( !mbMap )
379 return rLogicSize;
380
381 return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
383 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
385}
386
388{
389 // tdf#141761 IsEmpty() removed
390 // Even if rLogicRect.IsEmpty(), transform of the Position contained
391 // in the Rectangle is necessary. Due to Rectangle::Right() returning
392 // Left() when IsEmpty(), the code *could* stay unchanged (same for Bottom),
393 // but:
394 // The Rectangle constructor used with the four tools::Long values does not
395 // check for IsEmpty(), so to keep that state correct there are two possibilities:
396 // (1) Add a test to the Rectangle constructor in question
397 // (2) Do it handish here
398 // I have tried (1) first, but test Test::test_rectangle() claims that for
399 // tools::Rectangle aRect(1, 1, 1, 1);
400 // tools::Long(1) == aRect.GetWidth()
401 // tools::Long(0) == aRect.getWidth()
402 // (remember: this means Left == Right == 1 -> GetWidth => 1, getWidth == 0)
403 // so indeed the 1's have to go uncommented/unchecked into the data body
404 // of rectangle. Switching to (2) *is* needed, doing so
405 tools::Rectangle aRetval;
406
407 if ( !mbMap )
408 {
409 aRetval = tools::Rectangle(
410 rLogicRect.Left()+mnOutOffX,
411 rLogicRect.Top()+mnOutOffY,
412 rLogicRect.IsWidthEmpty() ? 0 : rLogicRect.Right()+mnOutOffX,
413 rLogicRect.IsHeightEmpty() ? 0 : rLogicRect.Bottom()+mnOutOffY );
414 }
415 else
416 {
417 aRetval = tools::Rectangle(
422 }
423
424 if(rLogicRect.IsWidthEmpty())
425 aRetval.SetWidthEmpty();
426
427 if(rLogicRect.IsHeightEmpty())
428 aRetval.SetHeightEmpty();
429
430 return aRetval;
431}
432
434{
435 if ( !mbMap && !mnOutOffX && !mnOutOffY )
436 return rLogicPoly;
437
438 sal_uInt16 i;
439 sal_uInt16 nPoints = rLogicPoly.GetSize();
440 tools::Polygon aPoly( rLogicPoly );
441
442 // get pointer to Point-array (copy data)
443 const Point* pPointAry = aPoly.GetConstPointAry();
444
445 if ( mbMap )
446 {
447 for ( i = 0; i < nPoints; i++ )
448 {
449 const Point& rPt = pPointAry[i];
454 aPoly[i] = aPt;
455 }
456 }
457 else
458 {
459 for ( i = 0; i < nPoints; i++ )
460 {
461 Point aPt = pPointAry[i];
462 aPt.AdjustX(mnOutOffX );
463 aPt.AdjustY(mnOutOffY );
464 aPoly[i] = aPt;
465 }
466 }
467
468 return aPoly;
469}
470
472{
473 if (!mbMap && !mnOutOffX && !mnOutOffY)
474 return rLogicPoly;
475
476 sal_uInt32 nPoints = rLogicPoly.count();
477 basegfx::B2DPolygon aPoly(rLogicPoly);
478
481
482 if (mbMap)
483 {
484 for (sal_uInt32 i = 0; i < nPoints; ++i)
485 {
486 const basegfx::B2DPoint& rPt = aPoly.getB2DPoint(i);
491
492 const bool bC1 = aPoly.isPrevControlPointUsed(i);
493 if (bC1)
494 {
495 const basegfx::B2DPoint aB2DC1(aPoly.getPrevControlPoint(i));
496
501 }
502
503 const bool bC2 = aPoly.isNextControlPointUsed(i);
504 if (bC2)
505 {
506 const basegfx::B2DPoint aB2DC2(aPoly.getNextControlPoint(i));
507
512 }
513
514 aPoly.setB2DPoint(i, aPt);
515
516 if (bC1)
517 aPoly.setPrevControlPoint(i, aC1);
518
519 if (bC2)
520 aPoly.setNextControlPoint(i, aC2);
521 }
522 }
523 else
524 {
525 for (sal_uInt32 i = 0; i < nPoints; ++i)
526 {
527 const basegfx::B2DPoint& rPt = aPoly.getB2DPoint(i);
528 basegfx::B2DPoint aPt(rPt.getX() + mnOutOffX, rPt.getY() + mnOutOffY);
529
530 const bool bC1 = aPoly.isPrevControlPointUsed(i);
531 if (bC1)
532 {
533 const basegfx::B2DPoint aB2DC1(aPoly.getPrevControlPoint(i));
534
535 aC1 = basegfx::B2DPoint(aB2DC1.getX() + mnOutOffX, aB2DC1.getY() + mnOutOffY);
536 }
537
538 const bool bC2 = aPoly.isNextControlPointUsed(i);
539 if (bC2)
540 {
541 const basegfx::B2DPoint aB2DC2(aPoly.getNextControlPoint(i));
542
543 aC1 = basegfx::B2DPoint(aB2DC2.getX() + mnOutOffX, aB2DC2.getY() + mnOutOffY);
544 }
545
546 aPoly.setB2DPoint(i, aPt);
547
548 if (bC1)
549 aPoly.setPrevControlPoint(i, aC1);
550
551 if (bC2)
552 aPoly.setNextControlPoint(i, aC2);
553 }
554 }
555
556 return aPoly;
557}
558
560{
561 if ( !mbMap && !mnOutOffX && !mnOutOffY )
562 return rLogicPolyPoly;
563
564 tools::PolyPolygon aPolyPoly( rLogicPolyPoly );
565 sal_uInt16 nPoly = aPolyPoly.Count();
566 for( sal_uInt16 i = 0; i < nPoly; i++ )
567 {
568 tools::Polygon& rPoly = aPolyPoly[i];
569 rPoly = ImplLogicToDevicePixel( rPoly );
570 }
571 return aPolyPoly;
572}
573
575{
576 LineInfo aInfo( rLineInfo );
577
578 if( aInfo.GetStyle() == LineStyle::Dash )
579 {
580 if( aInfo.GetDotCount() && aInfo.GetDotLen() )
581 aInfo.SetDotLen( std::max( ImplLogicWidthToDevicePixel( aInfo.GetDotLen() ), tools::Long(1) ) );
582 else
583 aInfo.SetDotCount( 0 );
584
585 if( aInfo.GetDashCount() && aInfo.GetDashLen() )
586 aInfo.SetDashLen( std::max( ImplLogicWidthToDevicePixel( aInfo.GetDashLen() ), tools::Long(1) ) );
587 else
588 aInfo.SetDashCount( 0 );
589
590 aInfo.SetDistance( ImplLogicWidthToDevicePixel( aInfo.GetDistance() ) );
591
592 if( ( !aInfo.GetDashCount() && !aInfo.GetDotCount() ) || !aInfo.GetDistance() )
593 aInfo.SetStyle( LineStyle::Solid );
594 }
595
596 aInfo.SetWidth( ImplLogicWidthToDevicePixel( aInfo.GetWidth() ) );
597
598 return aInfo;
599}
600
602{
603 // tdf#141761 see comments above, IsEmpty() removed
604 tools::Rectangle aRetval;
605
606 if ( !mbMap )
607 {
608 aRetval = tools::Rectangle(
609 rPixelRect.Left()-mnOutOffX,
610 rPixelRect.Top()-mnOutOffY,
611 rPixelRect.IsWidthEmpty() ? 0 : rPixelRect.Right()-mnOutOffX,
612 rPixelRect.IsHeightEmpty() ? 0 : rPixelRect.Bottom()-mnOutOffY );
613 }
614 else
615 {
616 aRetval = tools::Rectangle(
621 }
622
623 if(rPixelRect.IsWidthEmpty())
624 aRetval.SetWidthEmpty();
625
626 if(rPixelRect.IsHeightEmpty())
627 aRetval.SetHeightEmpty();
628
629 return aRetval;
630}
631
633{
634 if ( !mnOutOffX && !mnOutOffY )
635 return rRegion;
636
637 vcl::Region aRegion( rRegion );
639 return aRegion;
640}
641
642void OutputDevice::EnableMapMode( bool bEnable )
643{
644 mbMap = bEnable;
645
646 if( mpAlphaVDev )
647 mpAlphaVDev->EnableMapMode( bEnable );
648}
649
651{
652
653 if ( mpMetaFile )
655
656 if ( mbMap || !maMapMode.IsDefault() )
657 {
658 mbMap = false;
659 maMapMode = MapMode();
660
661 // create new objects (clip region are not re-scaled)
662 mbNewFont = true;
663 mbInitFont = true;
665
666 // #106426# Adapt logical offset when changing mapmode
667 mnOutOffLogicX = mnOutOffOrigX; // no mapping -> equal offsets
669
670 // #i75163#
672 }
673
674 if( mpAlphaVDev )
676}
677
678void OutputDevice::SetMapMode( const MapMode& rNewMapMode )
679{
680
681 bool bRelMap = (rNewMapMode.GetMapUnit() == MapUnit::MapRelative);
682
683 if ( mpMetaFile )
684 {
685 mpMetaFile->AddAction( new MetaMapModeAction( rNewMapMode ) );
686 }
687
688 // do nothing if MapMode was not changed
689 if ( maMapMode == rNewMapMode )
690 return;
691
692 if( mpAlphaVDev )
693 mpAlphaVDev->SetMapMode( rNewMapMode );
694
695 // if default MapMode calculate nothing
696 bool bOldMap = mbMap;
697 mbMap = !rNewMapMode.IsDefault();
698 if ( mbMap )
699 {
700 // if only the origin is converted, do not scale new
701 if ( (rNewMapMode.GetMapUnit() == maMapMode.GetMapUnit()) &&
702 (rNewMapMode.GetScaleX() == maMapMode.GetScaleX()) &&
703 (rNewMapMode.GetScaleY() == maMapMode.GetScaleY()) &&
704 (bOldMap == mbMap) )
705 {
706 // set offset
707 Point aOrigin = rNewMapMode.GetOrigin();
708 maMapRes.mnMapOfsX = aOrigin.X();
709 maMapRes.mnMapOfsY = aOrigin.Y();
710 maMapMode = rNewMapMode;
711
712 // #i75163#
714
715 return;
716 }
717 if ( !bOldMap && bRelMap )
718 {
725 }
726
727 // calculate new MapMode-resolution
729 }
730
731 // set new MapMode
732 if ( bRelMap )
733 {
735 // aScale? = maMapMode.GetScale?() * rNewMapMode.GetScale?()
737 rNewMapMode.GetScaleX().GetNumerator(),
739 rNewMapMode.GetScaleX().GetDenominator() );
741 rNewMapMode.GetScaleY().GetNumerator(),
743 rNewMapMode.GetScaleY().GetDenominator() );
744 maMapMode.SetOrigin( aOrigin );
745 maMapMode.SetScaleX( aScaleX );
746 maMapMode.SetScaleY( aScaleY );
747 }
748 else
749 maMapMode = rNewMapMode;
750
751 // create new objects (clip region are not re-scaled)
752 mbNewFont = true;
753 mbInitFont = true;
755
756 // #106426# Adapt logical offset when changing mapmode
761
762 // #i75163#
764}
765
766void OutputDevice::SetMetafileMapMode(const MapMode& rNewMapMode, bool bIsRecord)
767{
768 if (bIsRecord)
769 SetRelativeMapMode(rNewMapMode);
770 else
771 SetMapMode(rNewMapMode);
772}
773
775
777{
778 // do nothing if MapMode did not change
779 if ( maMapMode == rNewMapMode )
780 return;
781
783 MapUnit eNew = rNewMapMode.GetMapUnit();
784
785 // a?F = rNewMapMode.GetScale?() / maMapMode.GetScale?()
786 Fraction aXF = ImplMakeFraction( rNewMapMode.GetScaleX().GetNumerator(),
788 rNewMapMode.GetScaleX().GetDenominator(),
790 Fraction aYF = ImplMakeFraction( rNewMapMode.GetScaleY().GetNumerator(),
792 rNewMapMode.GetScaleY().GetDenominator(),
794
795 Point aPt( LogicToLogic( Point(), nullptr, &rNewMapMode ) );
796 if ( eNew != eOld )
797 {
798 if ( eOld > MapUnit::MapPixel )
799 {
800 SAL_WARN( "vcl.gdi", "Not implemented MapUnit" );
801 }
802 else if ( eNew > MapUnit::MapPixel )
803 {
804 SAL_WARN( "vcl.gdi", "Not implemented MapUnit" );
805 }
806 else
807 {
808 const auto eFrom = MapToO3tlLength(eOld, o3tl::Length::in);
809 const auto eTo = MapToO3tlLength(eNew, o3tl::Length::in);
810 const auto& [mul, div] = o3tl::getConversionMulDiv(eFrom, eTo);
811 Fraction aF(div, mul);
812
813 // a?F = a?F * aF
814 aXF = ImplMakeFraction( aXF.GetNumerator(), aF.GetNumerator(),
815 aXF.GetDenominator(), aF.GetDenominator() );
816 aYF = ImplMakeFraction( aYF.GetNumerator(), aF.GetNumerator(),
817 aYF.GetDenominator(), aF.GetDenominator() );
818 if ( eOld == MapUnit::MapPixel )
819 {
820 aXF *= Fraction( mnDPIX, 1 );
821 aYF *= Fraction( mnDPIY, 1 );
822 }
823 else if ( eNew == MapUnit::MapPixel )
824 {
825 aXF *= Fraction( 1, mnDPIX );
826 aYF *= Fraction( 1, mnDPIY );
827 }
828 }
829 }
830
831 MapMode aNewMapMode( MapUnit::MapRelative, Point( -aPt.X(), -aPt.Y() ), aXF, aYF );
832 SetMapMode( aNewMapMode );
833
834 if ( eNew != eOld )
835 maMapMode = rNewMapMode;
836
837 // #106426# Adapt logical offset when changing MapMode
842
843 if( mpAlphaVDev )
844 mpAlphaVDev->SetRelativeMapMode( rNewMapMode );
845}
846
847// #i75163#
849{
850 if(mbMap && mpOutDevData)
851 {
852 if(!mpOutDevData->mpViewTransform)
853 {
854 mpOutDevData->mpViewTransform = new basegfx::B2DHomMatrix;
855
856 const double fScaleFactorX(static_cast<double>(mnDPIX) * static_cast<double>(maMapRes.mnMapScNumX) / static_cast<double>(maMapRes.mnMapScDenomX));
857 const double fScaleFactorY(static_cast<double>(mnDPIY) * static_cast<double>(maMapRes.mnMapScNumY) / static_cast<double>(maMapRes.mnMapScDenomY));
858 const double fZeroPointX((static_cast<double>(maMapRes.mnMapOfsX) * fScaleFactorX) + static_cast<double>(mnOutOffOrigX));
859 const double fZeroPointY((static_cast<double>(maMapRes.mnMapOfsY) * fScaleFactorY) + static_cast<double>(mnOutOffOrigY));
860
861 mpOutDevData->mpViewTransform->set(0, 0, fScaleFactorX);
862 mpOutDevData->mpViewTransform->set(1, 1, fScaleFactorY);
863 mpOutDevData->mpViewTransform->set(0, 2, fZeroPointX);
864 mpOutDevData->mpViewTransform->set(1, 2, fZeroPointY);
865 }
866
867 return *mpOutDevData->mpViewTransform;
868 }
869 else
870 {
871 return basegfx::B2DHomMatrix();
872 }
873}
874
875// #i75163#
877{
878 if(mbMap && mpOutDevData)
879 {
880 if(!mpOutDevData->mpInverseViewTransform)
881 {
883 mpOutDevData->mpInverseViewTransform = new basegfx::B2DHomMatrix(*mpOutDevData->mpViewTransform);
884 mpOutDevData->mpInverseViewTransform->invert();
885 }
886
887 return *mpOutDevData->mpInverseViewTransform;
888 }
889 else
890 {
891 return basegfx::B2DHomMatrix();
892 }
893}
894
895// #i75163#
897{
898 // #i82615#
899 ImplMapRes aMapRes;
900 ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
901
902 basegfx::B2DHomMatrix aTransform;
903
904 const double fScaleFactorX(static_cast<double>(mnDPIX) * static_cast<double>(aMapRes.mnMapScNumX) / static_cast<double>(aMapRes.mnMapScDenomX));
905 const double fScaleFactorY(static_cast<double>(mnDPIY) * static_cast<double>(aMapRes.mnMapScNumY) / static_cast<double>(aMapRes.mnMapScDenomY));
906 const double fZeroPointX((static_cast<double>(aMapRes.mnMapOfsX) * fScaleFactorX) + static_cast<double>(mnOutOffOrigX));
907 const double fZeroPointY((static_cast<double>(aMapRes.mnMapOfsY) * fScaleFactorY) + static_cast<double>(mnOutOffOrigY));
908
909 aTransform.set(0, 0, fScaleFactorX);
910 aTransform.set(1, 1, fScaleFactorY);
911 aTransform.set(0, 2, fZeroPointX);
912 aTransform.set(1, 2, fZeroPointY);
913
914 return aTransform;
915}
916
917// #i75163#
919{
920 basegfx::B2DHomMatrix aMatrix( GetViewTransformation( rMapMode ) );
921 aMatrix.invert();
922 return aMatrix;
923}
924
926{
928 // TODO: is it worth to cache the transformed result?
929 if( mnOutOffX || mnOutOffY )
930 aTransformation.translate( mnOutOffX, mnOutOffY );
931 return aTransformation;
932}
933
934Point OutputDevice::LogicToPixel( const Point& rLogicPt ) const
935{
936
937 if ( !mbMap )
938 return rLogicPt;
939
940 return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
942 ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
944}
945
946Size OutputDevice::LogicToPixel( const Size& rLogicSize ) const
947{
948
949 if ( !mbMap )
950 return rLogicSize;
951
952 return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
954 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
956}
957
959{
960 // tdf#141761 see comments above, IsEmpty() removed
961 if ( !mbMap )
962 return rLogicRect;
963
964 tools::Rectangle aRetval(
969
970 if(rLogicRect.IsWidthEmpty())
971 aRetval.SetWidthEmpty();
972
973 if(rLogicRect.IsHeightEmpty())
974 aRetval.SetHeightEmpty();
975
976 return aRetval;
977}
978
980{
981
982 if ( !mbMap )
983 return rLogicPoly;
984
985 sal_uInt16 i;
986 sal_uInt16 nPoints = rLogicPoly.GetSize();
987 tools::Polygon aPoly( rLogicPoly );
988
989 // get pointer to Point-array (copy data)
990 const Point* pPointAry = aPoly.GetConstPointAry();
991
992 for ( i = 0; i < nPoints; i++ )
993 {
994 const Point* pPt = &(pPointAry[i]);
995 Point aPt;
996 aPt.setX( ImplLogicToPixel( pPt->X() + maMapRes.mnMapOfsX, mnDPIX,
998 aPt.setY( ImplLogicToPixel( pPt->Y() + maMapRes.mnMapOfsY, mnDPIY,
1000 aPoly[i] = aPt;
1001 }
1002
1003 return aPoly;
1004}
1005
1007{
1008
1009 if ( !mbMap )
1010 return rLogicPolyPoly;
1011
1012 tools::PolyPolygon aPolyPoly( rLogicPolyPoly );
1013 sal_uInt16 nPoly = aPolyPoly.Count();
1014 for( sal_uInt16 i = 0; i < nPoly; i++ )
1015 {
1016 tools::Polygon& rPoly = aPolyPoly[i];
1017 rPoly = LogicToPixel( rPoly );
1018 }
1019 return aPolyPoly;
1020}
1021
1023{
1024 basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly;
1025 const basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation();
1026 aTransformedPoly.transform( rTransformationMatrix );
1027 return aTransformedPoly;
1028}
1029
1031{
1032
1033 if(!mbMap || rLogicRegion.IsNull() || rLogicRegion.IsEmpty())
1034 {
1035 return rLogicRegion;
1036 }
1037
1038 vcl::Region aRegion;
1039
1040 if(rLogicRegion.getB2DPolyPolygon())
1041 {
1042 aRegion = vcl::Region(LogicToPixel(*rLogicRegion.getB2DPolyPolygon()));
1043 }
1044 else if(rLogicRegion.getPolyPolygon())
1045 {
1046 aRegion = vcl::Region(LogicToPixel(*rLogicRegion.getPolyPolygon()));
1047 }
1048 else if(rLogicRegion.getRegionBand())
1049 {
1050 RectangleVector aRectangles;
1051 rLogicRegion.GetRegionRectangles(aRectangles);
1052 const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
1053
1054 // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1055 for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); ++aRectIter)
1056 {
1057 aRegion.Union(LogicToPixel(*aRectIter));
1058 }
1059 }
1060
1061 return aRegion;
1062}
1063
1064Point OutputDevice::LogicToPixel( const Point& rLogicPt,
1065 const MapMode& rMapMode ) const
1066{
1067
1068 if ( rMapMode.IsDefault() )
1069 return rLogicPt;
1070
1071 // convert MapMode resolution and convert
1072 ImplMapRes aMapRes;
1073 ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1074
1075 return Point( ImplLogicToPixel( rLogicPt.X() + aMapRes.mnMapOfsX, mnDPIX,
1076 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX )+mnOutOffOrigX,
1077 ImplLogicToPixel( rLogicPt.Y() + aMapRes.mnMapOfsY, mnDPIY,
1078 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY )+mnOutOffOrigY );
1079}
1080
1082 const MapMode& rMapMode ) const
1083{
1084
1085 if ( rMapMode.IsDefault() )
1086 return rLogicSize;
1087
1088 // convert MapMode resolution and convert
1089 ImplMapRes aMapRes;
1090 ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1091
1092 return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
1093 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ),
1094 ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
1095 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) );
1096}
1097
1099 const MapMode& rMapMode ) const
1100{
1101 // tdf#141761 see comments above, IsEmpty() removed
1102 if ( rMapMode.IsDefault() )
1103 return rLogicRect;
1104
1105 // convert MapMode resolution and convert
1106 ImplMapRes aMapRes;
1107 ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1108
1109 tools::Rectangle aRetval(
1110 ImplLogicToPixel( rLogicRect.Left() + aMapRes.mnMapOfsX, mnDPIX, aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX )+mnOutOffOrigX,
1111 ImplLogicToPixel( rLogicRect.Top() + aMapRes.mnMapOfsY, mnDPIY, aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY )+mnOutOffOrigY,
1112 rLogicRect.IsWidthEmpty() ? 0 : ImplLogicToPixel( rLogicRect.Right() + aMapRes.mnMapOfsX, mnDPIX, aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX )+mnOutOffOrigX,
1113 rLogicRect.IsHeightEmpty() ? 0 : ImplLogicToPixel( rLogicRect.Bottom() + aMapRes.mnMapOfsY, mnDPIY, aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY )+mnOutOffOrigY );
1114
1115 if(rLogicRect.IsWidthEmpty())
1116 aRetval.SetWidthEmpty();
1117
1118 if(rLogicRect.IsHeightEmpty())
1119 aRetval.SetHeightEmpty();
1120
1121 return aRetval;
1122}
1123
1125 const MapMode& rMapMode ) const
1126{
1127
1128 if ( rMapMode.IsDefault() )
1129 return rLogicPoly;
1130
1131 // convert MapMode resolution and convert
1132 ImplMapRes aMapRes;
1133 ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1134
1135 sal_uInt16 i;
1136 sal_uInt16 nPoints = rLogicPoly.GetSize();
1137 tools::Polygon aPoly( rLogicPoly );
1138
1139 // get pointer to Point-array (copy data)
1140 const Point* pPointAry = aPoly.GetConstPointAry();
1141
1142 for ( i = 0; i < nPoints; i++ )
1143 {
1144 const Point* pPt = &(pPointAry[i]);
1145 Point aPt;
1146 aPt.setX( ImplLogicToPixel( pPt->X() + aMapRes.mnMapOfsX, mnDPIX,
1147 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX )+mnOutOffOrigX );
1148 aPt.setY( ImplLogicToPixel( pPt->Y() + aMapRes.mnMapOfsY, mnDPIY,
1149 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY )+mnOutOffOrigY );
1150 aPoly[i] = aPt;
1151 }
1152
1153 return aPoly;
1154}
1155
1157 const MapMode& rMapMode ) const
1158{
1159 basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly;
1160 const basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation( rMapMode );
1161 aTransformedPoly.transform( rTransformationMatrix );
1162 return aTransformedPoly;
1163}
1164
1165Point OutputDevice::PixelToLogic( const Point& rDevicePt ) const
1166{
1167
1168 if ( !mbMap )
1169 return rDevicePt;
1170
1171 return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1173 ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1175}
1176
1178{
1179 if (!mbMap)
1180 {
1181 assert(floor(rDevicePt.getX() == rDevicePt.getX()) && floor(rDevicePt.getY() == rDevicePt.getY()));
1182 return Point(rDevicePt.getX(), rDevicePt.getY());
1183 }
1184
1185 return Point(ImplSubPixelToLogic(rDevicePt.getX(), mnDPIX,
1187 ImplSubPixelToLogic(rDevicePt.getY(), mnDPIY,
1189}
1190
1191Size OutputDevice::PixelToLogic( const Size& rDeviceSize ) const
1192{
1193
1194 if ( !mbMap )
1195 return rDeviceSize;
1196
1197 return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1199 ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1201}
1202
1204{
1205 // tdf#141761 see comments above, IsEmpty() removed
1206 if ( !mbMap )
1207 return rDeviceRect;
1208
1209 tools::Rectangle aRetval(
1214
1215 if(rDeviceRect.IsWidthEmpty())
1216 aRetval.SetWidthEmpty();
1217
1218 if(rDeviceRect.IsHeightEmpty())
1219 aRetval.SetHeightEmpty();
1220
1221 return aRetval;
1222}
1223
1225{
1226
1227 if ( !mbMap )
1228 return rDevicePoly;
1229
1230 sal_uInt16 i;
1231 sal_uInt16 nPoints = rDevicePoly.GetSize();
1232 tools::Polygon aPoly( rDevicePoly );
1233
1234 // get pointer to Point-array (copy data)
1235 const Point* pPointAry = aPoly.GetConstPointAry();
1236
1237 for ( i = 0; i < nPoints; i++ )
1238 {
1239 const Point* pPt = &(pPointAry[i]);
1240 Point aPt;
1241 aPt.setX( ImplPixelToLogic( pPt->X(), mnDPIX,
1243 aPt.setY( ImplPixelToLogic( pPt->Y(), mnDPIY,
1245 aPoly[i] = aPt;
1246 }
1247
1248 return aPoly;
1249}
1250
1252{
1253
1254 if ( !mbMap )
1255 return rDevicePolyPoly;
1256
1257 tools::PolyPolygon aPolyPoly( rDevicePolyPoly );
1258 sal_uInt16 nPoly = aPolyPoly.Count();
1259 for( sal_uInt16 i = 0; i < nPoly; i++ )
1260 {
1261 tools::Polygon& rPoly = aPolyPoly[i];
1262 rPoly = PixelToLogic( rPoly );
1263 }
1264 return aPolyPoly;
1265}
1266
1268{
1269 basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly;
1270 const basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation();
1271 aTransformedPoly.transform( rTransformationMatrix );
1272 return aTransformedPoly;
1273}
1274
1276{
1277
1278 if(!mbMap || rDeviceRegion.IsNull() || rDeviceRegion.IsEmpty())
1279 {
1280 return rDeviceRegion;
1281 }
1282
1283 vcl::Region aRegion;
1284
1285 if(rDeviceRegion.getB2DPolyPolygon())
1286 {
1287 aRegion = vcl::Region(PixelToLogic(*rDeviceRegion.getB2DPolyPolygon()));
1288 }
1289 else if(rDeviceRegion.getPolyPolygon())
1290 {
1291 aRegion = vcl::Region(PixelToLogic(*rDeviceRegion.getPolyPolygon()));
1292 }
1293 else if(rDeviceRegion.getRegionBand())
1294 {
1295 RectangleVector aRectangles;
1296 rDeviceRegion.GetRegionRectangles(aRectangles);
1297 const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
1298
1299 // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1300 for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); ++aRectIter)
1301 {
1302 aRegion.Union(PixelToLogic(*aRectIter));
1303 }
1304 }
1305
1306 return aRegion;
1307}
1308
1309Point OutputDevice::PixelToLogic( const Point& rDevicePt,
1310 const MapMode& rMapMode ) const
1311{
1312
1313 // calculate nothing if default-MapMode
1314 if ( rMapMode.IsDefault() )
1315 return rDevicePt;
1316
1317 // calculate MapMode-resolution and convert
1318 ImplMapRes aMapRes;
1319 ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1320
1321 return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1322 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1323 ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1324 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1325}
1326
1328 const MapMode& rMapMode ) const
1329{
1330
1331 // calculate nothing if default-MapMode
1332 if ( rMapMode.IsDefault() )
1333 return rDeviceSize;
1334
1335 // calculate MapMode-resolution and convert
1336 ImplMapRes aMapRes;
1337 ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1338
1339 return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1340 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ),
1341 ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1342 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) );
1343}
1344
1346 const MapMode& rMapMode ) const
1347{
1348 // calculate nothing if default-MapMode
1349 // tdf#141761 see comments above, IsEmpty() removed
1350 if ( rMapMode.IsDefault() )
1351 return rDeviceRect;
1352
1353 // calculate MapMode-resolution and convert
1354 ImplMapRes aMapRes;
1355 ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1356
1357 tools::Rectangle aRetval(
1358 ImplPixelToLogic( rDeviceRect.Left(), mnDPIX, aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1359 ImplPixelToLogic( rDeviceRect.Top(), mnDPIY, aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) - aMapRes.mnMapOfsY - mnOutOffLogicY,
1360 rDeviceRect.IsWidthEmpty() ? 0 : ImplPixelToLogic( rDeviceRect.Right(), mnDPIX, aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1361 rDeviceRect.IsHeightEmpty() ? 0 : ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY, aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1362
1363 if(rDeviceRect.IsWidthEmpty())
1364 aRetval.SetWidthEmpty();
1365
1366 if(rDeviceRect.IsHeightEmpty())
1367 aRetval.SetHeightEmpty();
1368
1369 return aRetval;
1370}
1371
1373 const MapMode& rMapMode ) const
1374{
1375
1376 // calculate nothing if default-MapMode
1377 if ( rMapMode.IsDefault() )
1378 return rDevicePoly;
1379
1380 // calculate MapMode-resolution and convert
1381 ImplMapRes aMapRes;
1382 ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1383
1384 sal_uInt16 i;
1385 sal_uInt16 nPoints = rDevicePoly.GetSize();
1386 tools::Polygon aPoly( rDevicePoly );
1387
1388 // get pointer to Point-array (copy data)
1389 const Point* pPointAry = aPoly.GetConstPointAry();
1390
1391 for ( i = 0; i < nPoints; i++ )
1392 {
1393 const Point* pPt = &(pPointAry[i]);
1394 Point aPt;
1395 aPt.setX( ImplPixelToLogic( pPt->X(), mnDPIX,
1396 aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ) - aMapRes.mnMapOfsX - mnOutOffLogicX );
1397 aPt.setY( ImplPixelToLogic( pPt->Y(), mnDPIY,
1398 aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1399 aPoly[i] = aPt;
1400 }
1401
1402 return aPoly;
1403}
1404
1406 const MapMode& rMapMode ) const
1407{
1408 basegfx::B2DPolygon aTransformedPoly = rPixelPoly;
1409 const basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation( rMapMode );
1410 aTransformedPoly.transform( rTransformationMatrix );
1411 return aTransformedPoly;
1412}
1413
1415 const MapMode& rMapMode ) const
1416{
1417 basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly;
1418 const basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation( rMapMode );
1419 aTransformedPoly.transform( rTransformationMatrix );
1420 return aTransformedPoly;
1421}
1422
1423#define ENTER1( rSource, pMapModeSource, pMapModeDest ) \
1424 if ( !pMapModeSource ) \
1425 pMapModeSource = &maMapMode; \
1426 if ( !pMapModeDest ) \
1427 pMapModeDest = &maMapMode; \
1428 if ( *pMapModeSource == *pMapModeDest ) \
1429 return rSource; \
1430 \
1431 ImplMapRes aMapResSource; \
1432 ImplMapRes aMapResDest; \
1433 \
1434 if ( !mbMap || pMapModeSource != &maMapMode ) \
1435 { \
1436 if ( pMapModeSource->GetMapUnit() == MapUnit::MapRelative ) \
1437 aMapResSource = maMapRes; \
1438 ImplCalcMapResolution( *pMapModeSource, \
1439 mnDPIX, mnDPIY, aMapResSource ); \
1440 } \
1441 else \
1442 aMapResSource = maMapRes; \
1443 if ( !mbMap || pMapModeDest != &maMapMode ) \
1444 { \
1445 if ( pMapModeDest->GetMapUnit() == MapUnit::MapRelative ) \
1446 aMapResDest = maMapRes; \
1447 ImplCalcMapResolution( *pMapModeDest, \
1448 mnDPIX, mnDPIY, aMapResDest ); \
1449 } \
1450 else \
1451 aMapResDest = maMapRes
1452
1453static void verifyUnitSourceDest( MapUnit eUnitSource, MapUnit eUnitDest )
1454{
1455 DBG_ASSERT( eUnitSource != MapUnit::MapSysFont
1456 && eUnitSource != MapUnit::MapAppFont
1457 && eUnitSource != MapUnit::MapRelative,
1458 "Source MapUnit is not permitted" );
1459 DBG_ASSERT( eUnitDest != MapUnit::MapSysFont
1460 && eUnitDest != MapUnit::MapAppFont
1461 && eUnitDest != MapUnit::MapRelative,
1462 "Destination MapUnit is not permitted" );
1463}
1464
1465namespace
1466{
1467auto getCorrectedUnit(MapUnit eMapSrc, MapUnit eMapDst)
1468{
1471 if (eMapSrc > MapUnit::MapPixel)
1472 SAL_WARN("vcl.gdi", "Invalid source map unit");
1473 else if (eMapDst > MapUnit::MapPixel)
1474 SAL_WARN("vcl.gdi", "Invalid destination map unit");
1475 else if (eMapSrc != eMapDst)
1476 {
1477 // Here 72 PPI is assumed for MapPixel
1478 eSrc = MapToO3tlLength(eMapSrc, o3tl::Length::pt);
1479 eDst = MapToO3tlLength(eMapDst, o3tl::Length::pt);
1480 }
1481 return std::make_pair(eSrc, eDst);
1482}
1483
1484std::pair<ImplMapRes, ImplMapRes> ENTER4(const MapMode& rMMSource, const MapMode& rMMDest)
1485{
1486 std::pair<ImplMapRes, ImplMapRes> result;
1487 ImplCalcMapResolution(rMMSource, 72, 72, result.first);
1488 ImplCalcMapResolution(rMMDest, 72, 72, result.second);
1489 return result;
1490}
1491}
1492
1493// return (n1 * n2 * n3) / (n4 * n5)
1494static tools::Long fn5( const tools::Long n1,
1495 const tools::Long n2,
1496 const tools::Long n3,
1497 const tools::Long n4,
1498 const tools::Long n5 )
1499{
1500 if ( n1 == 0 || n2 == 0 || n3 == 0 || n4 == 0 || n5 == 0 )
1501 return 0;
1502 if (std::numeric_limits<tools::Long>::max() / std::abs(n2) < std::abs(n3))
1503 {
1504 // a6 is skipped
1505 BigInt a7 = n2;
1506 a7 *= n3;
1507 a7 *= n1;
1508
1509 if (std::numeric_limits<tools::Long>::max() / std::abs(n4) < std::abs(n5))
1510 {
1511 BigInt a8 = n4;
1512 a8 *= n5;
1513
1514 BigInt a9 = a8;
1515 a9 /= 2;
1516 if ( a7.IsNeg() )
1517 a7 -= a9;
1518 else
1519 a7 += a9;
1520
1521 a7 /= a8;
1522 } // of if
1523 else
1524 {
1525 tools::Long n8 = n4 * n5;
1526
1527 if ( a7.IsNeg() )
1528 a7 -= n8 / 2;
1529 else
1530 a7 += n8 / 2;
1531
1532 a7 /= n8;
1533 } // of else
1534 return static_cast<tools::Long>(a7);
1535 } // of if
1536 else
1537 {
1538 tools::Long n6 = n2 * n3;
1539
1540 if (std::numeric_limits<tools::Long>::max() / std::abs(n1) < std::abs(n6))
1541 {
1542 BigInt a7 = n1;
1543 a7 *= n6;
1544
1545 if (std::numeric_limits<tools::Long>::max() / std::abs(n4) < std::abs(n5))
1546 {
1547 BigInt a8 = n4;
1548 a8 *= n5;
1549
1550 BigInt a9 = a8;
1551 a9 /= 2;
1552 if ( a7.IsNeg() )
1553 a7 -= a9;
1554 else
1555 a7 += a9;
1556
1557 a7 /= a8;
1558 } // of if
1559 else
1560 {
1561 tools::Long n8 = n4 * n5;
1562
1563 if ( a7.IsNeg() )
1564 a7 -= n8 / 2;
1565 else
1566 a7 += n8 / 2;
1567
1568 a7 /= n8;
1569 } // of else
1570 return static_cast<tools::Long>(a7);
1571 } // of if
1572 else
1573 {
1574 tools::Long n7 = n1 * n6;
1575
1576 if (std::numeric_limits<tools::Long>::max() / std::abs(n4) < std::abs(n5))
1577 {
1578 BigInt a7 = n7;
1579 BigInt a8 = n4;
1580 a8 *= n5;
1581
1582 BigInt a9 = a8;
1583 a9 /= 2;
1584 if ( a7.IsNeg() )
1585 a7 -= a9;
1586 else
1587 a7 += a9;
1588
1589 a7 /= a8;
1590 return static_cast<tools::Long>(a7);
1591 } // of if
1592 else
1593 {
1594 const tools::Long n8 = n4 * n5;
1595 const tools::Long n8_2 = n8 / 2;
1596
1597 if( n7 < 0 )
1598 {
1599 if ((n7 - std::numeric_limits<tools::Long>::min()) >= n8_2)
1600 n7 -= n8_2;
1601 }
1602 else if ((std::numeric_limits<tools::Long>::max() - n7) >= n8_2)
1603 n7 += n8_2;
1604
1605 return n7 / n8;
1606 } // of else
1607 } // of else
1608 } // of else
1609}
1610
1611static tools::Long fn3(const tools::Long n1, const o3tl::Length eFrom, const o3tl::Length eTo)
1612{
1613 if (n1 == 0 || eFrom == o3tl::Length::invalid || eTo == o3tl::Length::invalid)
1614 return 0;
1615 bool bOverflow;
1616 const auto nResult = o3tl::convert(n1, eFrom, eTo, bOverflow);
1617 if (bOverflow)
1618 {
1619 const auto& [n2, n3] = o3tl::getConversionMulDiv(eFrom, eTo);
1620 BigInt a4 = n1;
1621 a4 *= n2;
1622
1623 if ( a4.IsNeg() )
1624 a4 -= n3 / 2;
1625 else
1626 a4 += n3 / 2;
1627
1628 a4 /= n3;
1629 return static_cast<tools::Long>(a4);
1630 } // of if
1631 else
1632 return nResult;
1633}
1634
1635Point OutputDevice::LogicToLogic( const Point& rPtSource,
1636 const MapMode* pMapModeSource,
1637 const MapMode* pMapModeDest ) const
1638{
1639 ENTER1( rPtSource, pMapModeSource, pMapModeDest );
1640
1641 return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
1642 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1643 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1644 aMapResDest.mnMapOfsX,
1645 fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
1646 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1647 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1648 aMapResDest.mnMapOfsY );
1649}
1650
1652 const MapMode* pMapModeSource,
1653 const MapMode* pMapModeDest ) const
1654{
1655 ENTER1( rSzSource, pMapModeSource, pMapModeDest );
1656
1657 return Size( fn5( rSzSource.Width(),
1658 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1659 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
1660 fn5( rSzSource.Height(),
1661 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1662 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
1663}
1664
1666 const MapMode* pMapModeSource,
1667 const MapMode* pMapModeDest ) const
1668{
1669 ENTER1( rRectSource, pMapModeSource, pMapModeDest );
1670
1671 return tools::Rectangle( fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
1672 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1673 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1674 aMapResDest.mnMapOfsX,
1675 fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
1676 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1677 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1678 aMapResDest.mnMapOfsY,
1679 fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
1680 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1681 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1682 aMapResDest.mnMapOfsX,
1683 fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
1684 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1685 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1686 aMapResDest.mnMapOfsY );
1687}
1688
1689Point OutputDevice::LogicToLogic( const Point& rPtSource,
1690 const MapMode& rMapModeSource,
1691 const MapMode& rMapModeDest )
1692{
1693 if ( rMapModeSource == rMapModeDest )
1694 return rPtSource;
1695
1696 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1697 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
1698 verifyUnitSourceDest( eUnitSource, eUnitDest );
1699
1700 if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1701 {
1702 const auto& [eFrom, eTo] = getCorrectedUnit(eUnitSource, eUnitDest);
1703 return Point(fn3(rPtSource.X(), eFrom, eTo), fn3(rPtSource.Y(), eFrom, eTo));
1704 }
1705 else
1706 {
1707 const auto& [aMapResSource, aMapResDest] = ENTER4( rMapModeSource, rMapModeDest );
1708
1709 return Point( fn5( rPtSource.X() + aMapResSource.mnMapOfsX,
1710 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1711 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1712 aMapResDest.mnMapOfsX,
1713 fn5( rPtSource.Y() + aMapResSource.mnMapOfsY,
1714 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1715 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1716 aMapResDest.mnMapOfsY );
1717 }
1718}
1719
1721 const MapMode& rMapModeSource,
1722 const MapMode& rMapModeDest )
1723{
1724 if ( rMapModeSource == rMapModeDest )
1725 return rSzSource;
1726
1727 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1728 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
1729 verifyUnitSourceDest( eUnitSource, eUnitDest );
1730
1731 if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1732 {
1733 const auto& [eFrom, eTo] = getCorrectedUnit(eUnitSource, eUnitDest);
1734 return Size(fn3(rSzSource.Width(), eFrom, eTo), fn3(rSzSource.Height(), eFrom, eTo));
1735 }
1736 else
1737 {
1738 const auto& [aMapResSource, aMapResDest] = ENTER4( rMapModeSource, rMapModeDest );
1739
1740 return Size( fn5( rSzSource.Width(),
1741 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1742 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ),
1743 fn5( rSzSource.Height(),
1744 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1745 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) );
1746 }
1747}
1748
1750 const MapMode& rMapModeSource,
1751 const MapMode& rMapModeDest )
1752{
1753 if(rMapModeSource == rMapModeDest)
1754 {
1755 return rPolySource;
1756 }
1757
1758 const basegfx::B2DHomMatrix aTransform(LogicToLogic(rMapModeSource, rMapModeDest));
1759 basegfx::B2DPolygon aPoly(rPolySource);
1760
1761 aPoly.transform(aTransform);
1762 return aPoly;
1763}
1764
1765basegfx::B2DHomMatrix OutputDevice::LogicToLogic(const MapMode& rMapModeSource, const MapMode& rMapModeDest)
1766{
1767 basegfx::B2DHomMatrix aTransform;
1768
1769 if(rMapModeSource == rMapModeDest)
1770 {
1771 return aTransform;
1772 }
1773
1774 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1775 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
1776 verifyUnitSourceDest(eUnitSource, eUnitDest);
1777
1778 if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1779 {
1780 const auto& [eFrom, eTo] = getCorrectedUnit(eUnitSource, eUnitDest);
1781 const double fScaleFactor(eFrom == o3tl::Length::invalid || eTo == o3tl::Length::invalid
1782 ? std::numeric_limits<double>::quiet_NaN()
1783 : o3tl::convert(1.0, eFrom, eTo));
1784 aTransform.set(0, 0, fScaleFactor);
1785 aTransform.set(1, 1, fScaleFactor);
1786 }
1787 else
1788 {
1789 const auto& [aMapResSource, aMapResDest] = ENTER4(rMapModeSource, rMapModeDest);
1790
1791 const double fScaleFactorX((double(aMapResSource.mnMapScNumX) * double(aMapResDest.mnMapScDenomX)) / (double(aMapResSource.mnMapScDenomX) * double(aMapResDest.mnMapScNumX)));
1792 const double fScaleFactorY((double(aMapResSource.mnMapScNumY) * double(aMapResDest.mnMapScDenomY)) / (double(aMapResSource.mnMapScDenomY) * double(aMapResDest.mnMapScNumY)));
1793 const double fZeroPointX(double(aMapResSource.mnMapOfsX) * fScaleFactorX - double(aMapResDest.mnMapOfsX));
1794 const double fZeroPointY(double(aMapResSource.mnMapOfsY) * fScaleFactorY - double(aMapResDest.mnMapOfsY));
1795
1796 aTransform.set(0, 0, fScaleFactorX);
1797 aTransform.set(1, 1, fScaleFactorY);
1798 aTransform.set(0, 2, fZeroPointX);
1799 aTransform.set(1, 2, fZeroPointY);
1800 }
1801
1802 return aTransform;
1803}
1804
1806 const MapMode& rMapModeSource,
1807 const MapMode& rMapModeDest )
1808{
1809 if ( rMapModeSource == rMapModeDest )
1810 return rRectSource;
1811
1812 MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1813 MapUnit eUnitDest = rMapModeDest.GetMapUnit();
1814 verifyUnitSourceDest( eUnitSource, eUnitDest );
1815
1816 tools::Rectangle aRetval;
1817
1818 if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1819 {
1820 const auto& [eFrom, eTo] = getCorrectedUnit(eUnitSource, eUnitDest);
1821
1822 auto left = fn3(rRectSource.Left(), eFrom, eTo);
1823 auto top = fn3(rRectSource.Top(), eFrom, eTo);
1824
1825 // tdf#141761 see comments above, IsEmpty() removed
1826 auto right = rRectSource.IsWidthEmpty() ? 0 : fn3(rRectSource.Right(), eFrom, eTo);
1827 auto bottom = rRectSource.IsHeightEmpty() ? 0 : fn3(rRectSource.Bottom(), eFrom, eTo);
1828
1829 aRetval = tools::Rectangle(left, top, right, bottom);
1830 }
1831 else
1832 {
1833 const auto& [aMapResSource, aMapResDest] = ENTER4( rMapModeSource, rMapModeDest );
1834
1835 auto left = fn5( rRectSource.Left() + aMapResSource.mnMapOfsX,
1836 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1837 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1838 aMapResDest.mnMapOfsX;
1839 auto top = fn5( rRectSource.Top() + aMapResSource.mnMapOfsY,
1840 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1841 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1842 aMapResDest.mnMapOfsY;
1843
1844 // tdf#141761 see comments above, IsEmpty() removed
1845 auto right = rRectSource.IsWidthEmpty() ? 0 : fn5( rRectSource.Right() + aMapResSource.mnMapOfsX,
1846 aMapResSource.mnMapScNumX, aMapResDest.mnMapScDenomX,
1847 aMapResSource.mnMapScDenomX, aMapResDest.mnMapScNumX ) -
1848 aMapResDest.mnMapOfsX;
1849 auto bottom = rRectSource.IsHeightEmpty() ? 0 : fn5( rRectSource.Bottom() + aMapResSource.mnMapOfsY,
1850 aMapResSource.mnMapScNumY, aMapResDest.mnMapScDenomY,
1851 aMapResSource.mnMapScDenomY, aMapResDest.mnMapScNumY ) -
1852 aMapResDest.mnMapOfsY;
1853
1854 aRetval = tools::Rectangle(left, top, right, bottom);
1855 }
1856
1857 if(rRectSource.IsWidthEmpty())
1858 aRetval.SetWidthEmpty();
1859
1860 if(rRectSource.IsHeightEmpty())
1861 aRetval.SetHeightEmpty();
1862
1863 return aRetval;
1864}
1865
1867 MapUnit eUnitSource, MapUnit eUnitDest )
1868{
1869 if ( eUnitSource == eUnitDest )
1870 return nLongSource;
1871
1872 verifyUnitSourceDest( eUnitSource, eUnitDest );
1873 const auto& [eFrom, eTo] = getCorrectedUnit(eUnitSource, eUnitDest);
1874 return fn3(nLongSource, eFrom, eTo);
1875}
1876
1878{
1879 mnOutOffOrigX = rOffset.Width();
1880 mnOutOffOrigY = rOffset.Height();
1881
1886
1887 if( mpAlphaVDev )
1888 mpAlphaVDev->SetPixelOffset( rOffset );
1889}
1890
1891
1893{
1894 if ( !mbMap )
1895 return static_cast<DeviceCoordinate>(nWidth);
1896
1897#if VCL_FLOAT_DEVICE_PIXEL
1899#else
1901#endif
1902}
1903
1905{
1906 if (!mbMap)
1907 return nWidth;
1908
1909 return ImplLogicToSubPixel(nWidth, mnDPIX,
1911}
1912
1914{
1915 if (!mbMap)
1916 return nHeight;
1917
1918 return ImplLogicToSubPixel(nHeight, mnDPIY,
1920}
1921
1923{
1924 if (!mbMap)
1925 return DevicePoint(rPoint.X() + mnOutOffX, rPoint.Y() + mnOutOffY);
1926
1933}
1934
1935/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr o3tl::Length MapToO3tlLength(MapUnit eU, o3tl::Length ePixelValue=o3tl::Length::px)
bool IsNeg() const
sal_Int32 GetNumerator() const
void ReduceInaccurate(unsigned nSignificantBits)
sal_Int32 GetDenominator() const
bool IsValid() const
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:581
void SetOrigin(const Point &rOrigin)
Definition: mapmod.cxx:105
void SetScaleY(const Fraction &rScaleY)
Definition: mapmod.cxx:118
const Fraction & GetScaleX() const
Definition: mapmod.cxx:154
MapUnit GetMapUnit() const
Definition: mapmod.cxx:150
bool IsSimple() const
Definition: mapmod.cxx:158
const Point & GetOrigin() const
Definition: mapmod.cxx:152
const Fraction & GetScaleY() const
Definition: mapmod.cxx:156
bool IsDefault() const
Definition: mapmod.cxx:134
void SetScaleX(const Fraction &rScaleX)
Definition: mapmod.cxx:111
ImplMapRes maMapRes
Definition: outdev.hxx:223
SAL_DLLPRIVATE tools::Long ImplLogicYToDevicePixel(tools::Long nY) const
Convert a logical Y coordinate to a device pixel's Y coordinate.
Definition: map.cxx:324
void EnableMapMode(bool bEnable=true)
Definition: map.cxx:642
basegfx::B2DHomMatrix GetViewTransformation() const
Definition: map.cxx:848
sal_Int32 mnDPIY
Definition: outdev.hxx:214
tools::Long mnOutOffY
Output offset for device output in pixel (pseudo window offset within window system's frames)
Definition: outdev.hxx:210
SAL_DLLPRIVATE tools::Long ImplDevicePixelToLogicHeight(tools::Long nHeight) const
Convert device pixels to a height in logical units.
Definition: map.cxx:357
virtual void SetMetafileMapMode(const MapMode &rNewMapMode, bool bIsRecord)
Definition: map.cxx:766
SAL_DLLPRIVATE tools::Rectangle ImplLogicToDevicePixel(const tools::Rectangle &rLogicRect) const
Convert a logical rectangle to a rectangle in physical device pixel units.
Definition: map.cxx:387
basegfx::B2DHomMatrix GetInverseViewTransformation() const
Definition: map.cxx:876
SAL_DLLPRIVATE double ImplLogicHeightToDeviceSubPixel(tools::Long nHeight) const
Definition: map.cxx:1913
tools::Long mnOutOffX
Output offset for device output in pixel (pseudo window offset within window system's frames)
Definition: outdev.hxx:208
tools::Long mnOutOffLogicX
Additional output offset in logical coordinates, applied in PixelToLogic (used by SetPixelOffset/GetP...
Definition: outdev.hxx:202
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
Definition: map.cxx:1165
std::unique_ptr< ImplOutDevData > mpOutDevData
Definition: outdev.hxx:190
MapMode maMapMode
Definition: outdev.hxx:236
GDIMetaFile * mpMetaFile
Definition: outdev.hxx:186
bool mbMap
Definition: outdev.hxx:241
SAL_DLLPRIVATE tools::Long ImplLogicHeightToDevicePixel(tools::Long nHeight) const
Convert a logical height to a height in units of device pixels.
Definition: map.cxx:341
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
Definition: map.cxx:1635
void SetMapMode()
Definition: map.cxx:650
virtual void ImplInitMapModeObjects()
Definition: map.cxx:774
bool mbNewFont
Definition: outdev.hxx:255
SAL_DLLPRIVATE tools::Long ImplLogicWidthToDevicePixel(tools::Long nWidth) const
Convert a logical width to a width in units of device pixels.
Definition: map.cxx:333
bool mbInitFont
Definition: outdev.hxx:251
void SetPixelOffset(const Size &rOffset)
Set an offset in pixel.
Definition: map.cxx:1877
SAL_DLLPRIVATE double ImplLogicWidthToDeviceSubPixel(tools::Long nWidth) const
Definition: map.cxx:1904
void SetRelativeMapMode(const MapMode &rNewMapMode)
Definition: map.cxx:776
SAL_DLLPRIVATE DeviceCoordinate LogicWidthToDeviceCoordinate(tools::Long nWidth) const
Definition: map.cxx:1892
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:934
SAL_DLLPRIVATE void ImplInvalidateViewTransform()
Invalidate the view transformation.
Definition: map.cxx:226
SAL_DLLPRIVATE tools::Long ImplDevicePixelToLogicWidth(tools::Long nWidth) const
Convert device pixels to a width in logical units.
Definition: map.cxx:349
SAL_DLLPRIVATE tools::Rectangle ImplDevicePixelToLogic(const tools::Rectangle &rPixelRect) const
Convert a rectangle in physical pixel units to a rectangle in physical pixel units and coords.
Definition: map.cxx:601
SAL_DLLPRIVATE DevicePoint ImplLogicToDeviceSubPixel(const Point &rLogicPt) const
Definition: map.cxx:1922
tools::Long mnOutOffOrigX
Additional output pixel offset, applied in LogicToPixel (used by SetPixelOffset/GetPixelOffset)
Definition: outdev.hxx:200
VclPtr< VirtualDevice > mpAlphaVDev
Definition: outdev.hxx:197
tools::Long mnOutOffOrigY
Additional output pixel offset, applied in LogicToPixel (used by SetPixelOffset/GetPixelOffset)
Definition: outdev.hxx:204
SAL_DLLPRIVATE basegfx::B2DHomMatrix ImplGetDeviceTransformation() const
Get device transformation.
Definition: map.cxx:925
SAL_DLLPRIVATE Point SubPixelToLogic(const DevicePoint &rDevicePt) const
Definition: map.cxx:1177
tools::Long mnOutOffLogicY
Additional output offset in logical coordinates, applied in PixelToLogic (used by SetPixelOffset/GetP...
Definition: outdev.hxx:206
SAL_DLLPRIVATE vcl::Region ImplPixelToDevicePixel(const vcl::Region &rRegion) const
Convert a region in pixel units to a region in device pixel units and coords.
Definition: map.cxx:632
SAL_DLLPRIVATE tools::Long ImplLogicXToDevicePixel(tools::Long nX) const
Convert a logical X coordinate to a device pixel's X coordinate.
Definition: map.cxx:315
sal_Int32 mnDPIX
Definition: outdev.hxx:213
A construction helper for ScopedVclPtr.
Definition: vclptr.hxx:408
constexpr tools::Long Height() const
constexpr tools::Long Width() const
void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue)
void translate(double fX, double fY)
void transform(const basegfx::B2DHomMatrix &rMatrix)
void transform(const basegfx::B2DHomMatrix &rMatrix)
sal_uInt32 count() const
TYPE getX() const
TYPE getY() const
sal_uInt16 Count() const
const Point * GetConstPointAry() const
sal_uInt16 GetSize() const
constexpr tools::Long Top() const
constexpr tools::Long Right() const
constexpr bool IsWidthEmpty() const
constexpr bool IsHeightEmpty() const
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
void Move(tools::Long nHorzMove, tools::Long nVertMove)
Definition: region.cxx:401
bool IsNull() const
Definition: region.hxx:99
const RegionBand * getRegionBand() const
Definition: region.hxx:78
const std::optional< basegfx::B2DPolyPolygon > & getB2DPolyPolygon() const
Definition: region.hxx:76
bool IsEmpty() const
Definition: region.cxx:229
void Union(const tools::Rectangle &rRegion)
Definition: region.cxx:507
void GetRegionRectangles(RectangleVector &rTarget) const
Definition: region.cxx:1674
const std::optional< tools::PolyPolygon > & getPolyPolygon() const
Definition: region.hxx:77
static SAL_DLLPRIVATE void ImplInitAppFontData(vcl::Window const *pWindow)
Definition: window.cxx:1183
#define DBG_ASSERT(sCon, aError)
sal_Int32 DeviceCoordinate
basegfx::B2DPoint DevicePoint
OString right
OString top
OString bottom
sal_Int64 n
#define SAL_WARN(area, stream)
#define ENTER1(rSource, pMapModeSource, pMapModeDest)
Definition: map.cxx:1423
static Fraction ImplMakeFraction(tools::Long nN1, tools::Long nN2, tools::Long nD1, tools::Long nD2)
Definition: map.cxx:45
static tools::Long ImplSubPixelToLogic(double n, tools::Long nDPI, tools::Long nMapNum, tools::Long nMapDenom)
Definition: map.cxx:281
static tools::Long ImplLogicToPixel(tools::Long n, tools::Long nDPI, tools::Long nMapNum, tools::Long nMapDenom)
Definition: map.cxx:244
static void verifyUnitSourceDest(MapUnit eUnitSource, MapUnit eUnitDest)
Definition: map.cxx:1453
static double ImplLogicToSubPixel(tools::Long n, tools::Long nDPI, tools::Long nMapNum, tools::Long nMapDenom)
Definition: map.cxx:273
static tools::Long fn3(const tools::Long n1, const o3tl::Length eFrom, const o3tl::Length eTo)
Definition: map.cxx:1611
static tools::Long fn5(const tools::Long n1, const tools::Long n2, const tools::Long n3, const tools::Long n4, const tools::Long n5)
Definition: map.cxx:1494
static tools::Long ImplPixelToLogic(tools::Long n, tools::Long nDPI, tools::Long nMapNum, tools::Long nMapDenom)
Definition: map.cxx:290
static void ImplCalcMapResolution(const MapMode &rMapMode, tools::Long nDPIX, tools::Long nDPIY, ImplMapRes &rMapRes)
Definition: map.cxx:87
static auto setMapRes(ImplMapRes &rMapRes, const o3tl::Length eUnit)
Definition: map.cxx:80
MapUnit
int n2
int n1
int i
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
double div(const double &fNumerator, const double &fDenominator)
long Long
std::vector< tools::Rectangle > RectangleVector
Definition: region.hxx:34
tools::Long mnMapScDenomX
Scaling factor - denominator in X direction.
Definition: ImplMapRes.hxx:32
tools::Long mnMapScDenomY
Scaling factor - denominator in Y direction.
Definition: ImplMapRes.hxx:33
tools::Long mnMapScNumY
Scaling factor - numerator in Y direction.
Definition: ImplMapRes.hxx:31
tools::Long mnMapOfsY
Offset in Y direction.
Definition: ImplMapRes.hxx:29
tools::Long mnMapScNumX
Scaling factor - numerator in X direction.
Definition: ImplMapRes.hxx:30
tools::Long mnMapOfsX
Offset in X direction.
Definition: ImplMapRes.hxx:28
ImplSVFrameData maFrameData
Definition: svdata.hxx:402
ImplSVGDIData maGDIData
Definition: svdata.hxx:401
VclPtr< vcl::Window > mpFirstFrame
Definition: svdata.hxx:245
tools::Long mnAppFontY
Definition: svdata.hxx:235
tools::Long mnAppFontX
Definition: svdata.hxx:234
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:76
Any result
sal_uInt64 left