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 
38 #include <tools/UnitConversion.hxx>
39 
40 /*
41 Reduces accuracy until it is a fraction (should become
42 ctor 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 
80 static 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 
87 static 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:
98  setMapRes(rMapRes, o3tl::Length::mm10);
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:
110  setMapRes(rMapRes, o3tl::Length::in100);
111  break;
112  case MapUnit::Map10thInch:
113  setMapRes(rMapRes, o3tl::Length::in10);
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:
122  setMapRes(rMapRes, o3tl::Length::twip);
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 
273 static double ImplLogicToPixel(double n, tools::Long nDPI, tools::Long nMapNum,
274  tools::Long nMapDenom)
275 {
276  assert(nDPI > 0);
277  assert(nMapDenom != 0);
278  return n * nMapNum * nDPI / nMapDenom;
279 }
280 
282  tools::Long nMapDenom)
283 {
284  assert(nDPI > 0);
285  if (nMapNum == 0)
286  return 0;
287  sal_Int64 nDenom = nDPI;
288  nDenom *= nMapNum;
289 
290  sal_Int64 n64 = n;
291  n64 *= nMapDenom;
292  if (nDenom == 1)
293  n = static_cast<tools::Long>(n64);
294  else
295  {
296  n64 = 2 * n64 / nDenom;
297  if (n64 < 0)
298  --n64;
299  else
300  ++n64;
301  n = static_cast<tools::Long>(n64 / 2);
302  }
303  return n;
304 }
305 
307 {
308  if ( !mbMap )
309  return nX+mnOutOffX;
310 
313 }
314 
316 {
317  if ( !mbMap )
318  return nY+mnOutOffY;
319 
322 }
323 
325 {
326  if ( !mbMap )
327  return nWidth;
328 
330 }
331 
333 {
334  if ( !mbMap )
335  return nHeight;
336 
338 }
339 
340 float OutputDevice::ImplFloatLogicHeightToDevicePixel( float fLogicHeight) const
341 {
342  if( !mbMap)
343  return fLogicHeight;
344  float fPixelHeight = (fLogicHeight * mnDPIY * maMapRes.mnMapScNumY) / maMapRes.mnMapScDenomY;
345  return fPixelHeight;
346 }
347 
349 {
350  if ( !mbMap )
351  return nWidth;
352 
354 }
355 
357 {
358  if ( !mbMap )
359  return nHeight;
360 
362 }
363 
364 Point OutputDevice::ImplLogicToDevicePixel( const Point& rLogicPt ) const
365 {
366  if ( !mbMap )
367  return Point( rLogicPt.X()+mnOutOffX, rLogicPt.Y()+mnOutOffY );
368 
369  return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
371  ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
373 }
374 
376 {
377  if ( !mbMap )
378  return rLogicSize;
379 
380  return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
382  ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
384 }
385 
387 {
388  // tdf#141761 IsEmpty() removed
389  // Even if rLogicRect.IsEmpty(), transform of the Position contained
390  // in the Rectangle is necessary. Due to Rectangle::Right() returning
391  // Left() when IsEmpty(), the code *could* stay unchanged (same for Bottom),
392  // but:
393  // The Rectangle constructor used with the four tools::Long values does not
394  // check for IsEmpty(), so to keep that state correct there are two possibilities:
395  // (1) Add a test to the Rectangle constructor in question
396  // (2) Do it handish here
397  // I have tried (1) first, but test Test::test_rectangle() claims that for
398  // tools::Rectangle aRect(1, 1, 1, 1);
399  // tools::Long(1) == aRect.GetWidth()
400  // tools::Long(0) == aRect.getWidth()
401  // (remember: this means Left == Right == 1 -> GetWidth => 1, getWidth == 0)
402  // so indeed the 1's have to go uncommented/unchecked into the data body
403  // of rectangle. Switching to (2) *is* needed, doing so
404  tools::Rectangle aRetval;
405 
406  if ( !mbMap )
407  {
408  aRetval = tools::Rectangle(
409  rLogicRect.Left()+mnOutOffX,
410  rLogicRect.Top()+mnOutOffY,
411  rLogicRect.IsWidthEmpty() ? 0 : rLogicRect.Right()+mnOutOffX,
412  rLogicRect.IsHeightEmpty() ? 0 : rLogicRect.Bottom()+mnOutOffY );
413  }
414  else
415  {
416  aRetval = tools::Rectangle(
421  }
422 
423  if(rLogicRect.IsWidthEmpty())
424  aRetval.SetWidthEmpty();
425 
426  if(rLogicRect.IsHeightEmpty())
427  aRetval.SetHeightEmpty();
428 
429  return aRetval;
430 }
431 
433 {
434  if ( !mbMap && !mnOutOffX && !mnOutOffY )
435  return rLogicPoly;
436 
437  sal_uInt16 i;
438  sal_uInt16 nPoints = rLogicPoly.GetSize();
439  tools::Polygon aPoly( rLogicPoly );
440 
441  // get pointer to Point-array (copy data)
442  const Point* pPointAry = aPoly.GetConstPointAry();
443 
444  if ( mbMap )
445  {
446  for ( i = 0; i < nPoints; i++ )
447  {
448  const Point& rPt = pPointAry[i];
453  aPoly[i] = aPt;
454  }
455  }
456  else
457  {
458  for ( i = 0; i < nPoints; i++ )
459  {
460  Point aPt = pPointAry[i];
461  aPt.AdjustX(mnOutOffX );
462  aPt.AdjustY(mnOutOffY );
463  aPoly[i] = aPt;
464  }
465  }
466 
467  return aPoly;
468 }
469 
471 {
472  if (!mbMap && !mnOutOffX && !mnOutOffY)
473  return rLogicPoly;
474 
475  sal_uInt32 nPoints = rLogicPoly.count();
476  basegfx::B2DPolygon aPoly(rLogicPoly);
477 
478  basegfx::B2DPoint aC1;
479  basegfx::B2DPoint aC2;
480 
481  if (mbMap)
482  {
483  for (sal_uInt32 i = 0; i < nPoints; ++i)
484  {
485  const basegfx::B2DPoint& rPt = aPoly.getB2DPoint(i);
490 
491  const bool bC1 = aPoly.isPrevControlPointUsed(i);
492  if (bC1)
493  {
494  const basegfx::B2DPoint aB2DC1(aPoly.getPrevControlPoint(i));
495 
498  ImplLogicToPixel( aB2DC1.getY()+maMapRes.mnMapOfsY, mnDPIY,
500  }
501 
502  const bool bC2 = aPoly.isNextControlPointUsed(i);
503  if (bC2)
504  {
505  const basegfx::B2DPoint aB2DC2(aPoly.getNextControlPoint(i));
506 
509  ImplLogicToPixel( aB2DC2.getY()+maMapRes.mnMapOfsY, mnDPIY,
511  }
512 
513  aPoly.setB2DPoint(i, aPt);
514 
515  if (bC1)
516  aPoly.setPrevControlPoint(i, aC1);
517 
518  if (bC2)
519  aPoly.setNextControlPoint(i, aC2);
520  }
521  }
522  else
523  {
524  for (sal_uInt32 i = 0; i < nPoints; ++i)
525  {
526  const basegfx::B2DPoint& rPt = aPoly.getB2DPoint(i);
527  basegfx::B2DPoint aPt(rPt.getX() + mnOutOffX, rPt.getY() + mnOutOffY);
528 
529  const bool bC1 = aPoly.isPrevControlPointUsed(i);
530  if (bC1)
531  {
532  const basegfx::B2DPoint aB2DC1(aPoly.getPrevControlPoint(i));
533 
534  aC1 = basegfx::B2DPoint(aB2DC1.getX() + mnOutOffX, aB2DC1.getY() + mnOutOffY);
535  }
536 
537  const bool bC2 = aPoly.isNextControlPointUsed(i);
538  if (bC2)
539  {
540  const basegfx::B2DPoint aB2DC2(aPoly.getNextControlPoint(i));
541 
542  aC1 = basegfx::B2DPoint(aB2DC2.getX() + mnOutOffX, aB2DC2.getY() + mnOutOffY);
543  }
544 
545  aPoly.setB2DPoint(i, aPt);
546 
547  if (bC1)
548  aPoly.setPrevControlPoint(i, aC1);
549 
550  if (bC2)
551  aPoly.setNextControlPoint(i, aC2);
552  }
553  }
554 
555  return aPoly;
556 }
557 
559 {
560  if ( !mbMap && !mnOutOffX && !mnOutOffY )
561  return rLogicPolyPoly;
562 
563  tools::PolyPolygon aPolyPoly( rLogicPolyPoly );
564  sal_uInt16 nPoly = aPolyPoly.Count();
565  for( sal_uInt16 i = 0; i < nPoly; i++ )
566  {
567  tools::Polygon& rPoly = aPolyPoly[i];
568  rPoly = ImplLogicToDevicePixel( rPoly );
569  }
570  return aPolyPoly;
571 }
572 
574 {
575  LineInfo aInfo( rLineInfo );
576 
577  if( aInfo.GetStyle() == LineStyle::Dash )
578  {
579  if( aInfo.GetDotCount() && aInfo.GetDotLen() )
580  aInfo.SetDotLen( std::max( ImplLogicWidthToDevicePixel( aInfo.GetDotLen() ), tools::Long(1) ) );
581  else
582  aInfo.SetDotCount( 0 );
583 
584  if( aInfo.GetDashCount() && aInfo.GetDashLen() )
585  aInfo.SetDashLen( std::max( ImplLogicWidthToDevicePixel( aInfo.GetDashLen() ), tools::Long(1) ) );
586  else
587  aInfo.SetDashCount( 0 );
588 
589  aInfo.SetDistance( ImplLogicWidthToDevicePixel( aInfo.GetDistance() ) );
590 
591  if( ( !aInfo.GetDashCount() && !aInfo.GetDotCount() ) || !aInfo.GetDistance() )
592  aInfo.SetStyle( LineStyle::Solid );
593  }
594 
595  aInfo.SetWidth( ImplLogicWidthToDevicePixel( aInfo.GetWidth() ) );
596 
597  return aInfo;
598 }
599 
601 {
602  // tdf#141761 see comments above, IsEmpty() removed
603  tools::Rectangle aRetval;
604 
605  if ( !mbMap )
606  {
607  aRetval = tools::Rectangle(
608  rPixelRect.Left()-mnOutOffX,
609  rPixelRect.Top()-mnOutOffY,
610  rPixelRect.IsWidthEmpty() ? 0 : rPixelRect.Right()-mnOutOffX,
611  rPixelRect.IsHeightEmpty() ? 0 : rPixelRect.Bottom()-mnOutOffY );
612  }
613  else
614  {
615  aRetval = tools::Rectangle(
620  }
621 
622  if(rPixelRect.IsWidthEmpty())
623  aRetval.SetWidthEmpty();
624 
625  if(rPixelRect.IsHeightEmpty())
626  aRetval.SetHeightEmpty();
627 
628  return aRetval;
629 }
630 
632 {
633  if ( !mnOutOffX && !mnOutOffY )
634  return rRegion;
635 
636  vcl::Region aRegion( rRegion );
638  return aRegion;
639 }
640 
641 void OutputDevice::EnableMapMode( bool bEnable )
642 {
643  mbMap = bEnable;
644 
645  if( mpAlphaVDev )
646  mpAlphaVDev->EnableMapMode( bEnable );
647 }
648 
650 {
651 
652  if ( mpMetaFile )
654 
655  if ( mbMap || !maMapMode.IsDefault() )
656  {
657  mbMap = false;
658  maMapMode = MapMode();
659 
660  // create new objects (clip region are not re-scaled)
661  mbNewFont = true;
662  mbInitFont = true;
664 
665  // #106426# Adapt logical offset when changing mapmode
666  mnOutOffLogicX = mnOutOffOrigX; // no mapping -> equal offsets
668 
669  // #i75163#
671  }
672 
673  if( mpAlphaVDev )
675 }
676 
677 void OutputDevice::SetMapMode( const MapMode& rNewMapMode )
678 {
679 
680  bool bRelMap = (rNewMapMode.GetMapUnit() == MapUnit::MapRelative);
681 
682  if ( mpMetaFile )
683  {
684  mpMetaFile->AddAction( new MetaMapModeAction( rNewMapMode ) );
685  }
686 
687  // do nothing if MapMode was not changed
688  if ( maMapMode == rNewMapMode )
689  return;
690 
691  if( mpAlphaVDev )
692  mpAlphaVDev->SetMapMode( rNewMapMode );
693 
694  // if default MapMode calculate nothing
695  bool bOldMap = mbMap;
696  mbMap = !rNewMapMode.IsDefault();
697  if ( mbMap )
698  {
699  // if only the origin is converted, do not scale new
700  if ( (rNewMapMode.GetMapUnit() == maMapMode.GetMapUnit()) &&
701  (rNewMapMode.GetScaleX() == maMapMode.GetScaleX()) &&
702  (rNewMapMode.GetScaleY() == maMapMode.GetScaleY()) &&
703  (bOldMap == mbMap) )
704  {
705  // set offset
706  Point aOrigin = rNewMapMode.GetOrigin();
707  maMapRes.mnMapOfsX = aOrigin.X();
708  maMapRes.mnMapOfsY = aOrigin.Y();
709  maMapMode = rNewMapMode;
710 
711  // #i75163#
713 
714  return;
715  }
716  if ( !bOldMap && bRelMap )
717  {
718  maMapRes.mnMapScNumX = 1;
719  maMapRes.mnMapScNumY = 1;
722  maMapRes.mnMapOfsX = 0;
723  maMapRes.mnMapOfsY = 0;
724  }
725 
726  // calculate new MapMode-resolution
728  }
729 
730  // set new MapMode
731  if ( bRelMap )
732  {
734  // aScale? = maMapMode.GetScale?() * rNewMapMode.GetScale?()
736  rNewMapMode.GetScaleX().GetNumerator(),
738  rNewMapMode.GetScaleX().GetDenominator() );
740  rNewMapMode.GetScaleY().GetNumerator(),
742  rNewMapMode.GetScaleY().GetDenominator() );
743  maMapMode.SetOrigin( aOrigin );
744  maMapMode.SetScaleX( aScaleX );
745  maMapMode.SetScaleY( aScaleY );
746  }
747  else
748  maMapMode = rNewMapMode;
749 
750  // create new objects (clip region are not re-scaled)
751  mbNewFont = true;
752  mbInitFont = true;
754 
755  // #106426# Adapt logical offset when changing mapmode
760 
761  // #i75163#
763 }
764 
765 void OutputDevice::SetMetafileMapMode(const MapMode& rNewMapMode, bool bIsRecord)
766 {
767  if (bIsRecord)
768  SetRelativeMapMode(rNewMapMode);
769  else
770  SetMapMode(rNewMapMode);
771 }
772 
774 
775 void OutputDevice::SetRelativeMapMode( const MapMode& rNewMapMode )
776 {
777  // do nothing if MapMode did not change
778  if ( maMapMode == rNewMapMode )
779  return;
780 
781  MapUnit eOld = maMapMode.GetMapUnit();
782  MapUnit eNew = rNewMapMode.GetMapUnit();
783 
784  // a?F = rNewMapMode.GetScale?() / maMapMode.GetScale?()
785  Fraction aXF = ImplMakeFraction( rNewMapMode.GetScaleX().GetNumerator(),
787  rNewMapMode.GetScaleX().GetDenominator(),
789  Fraction aYF = ImplMakeFraction( rNewMapMode.GetScaleY().GetNumerator(),
791  rNewMapMode.GetScaleY().GetDenominator(),
793 
794  Point aPt( LogicToLogic( Point(), nullptr, &rNewMapMode ) );
795  if ( eNew != eOld )
796  {
797  if ( eOld > MapUnit::MapPixel )
798  {
799  SAL_WARN( "vcl.gdi", "Not implemented MapUnit" );
800  }
801  else if ( eNew > MapUnit::MapPixel )
802  {
803  SAL_WARN( "vcl.gdi", "Not implemented MapUnit" );
804  }
805  else
806  {
807  const auto eFrom = MapToO3tlLength(eOld, o3tl::Length::in);
808  const auto eTo = MapToO3tlLength(eNew, o3tl::Length::in);
809  const auto& [mul, div] = o3tl::getConversionMulDiv(eFrom, eTo);
810  Fraction aF(div, mul);
811 
812  // a?F = a?F * aF
813  aXF = ImplMakeFraction( aXF.GetNumerator(), aF.GetNumerator(),
814  aXF.GetDenominator(), aF.GetDenominator() );
815  aYF = ImplMakeFraction( aYF.GetNumerator(), aF.GetNumerator(),
816  aYF.GetDenominator(), aF.GetDenominator() );
817  if ( eOld == MapUnit::MapPixel )
818  {
819  aXF *= Fraction( mnDPIX, 1 );
820  aYF *= Fraction( mnDPIY, 1 );
821  }
822  else if ( eNew == MapUnit::MapPixel )
823  {
824  aXF *= Fraction( 1, mnDPIX );
825  aYF *= Fraction( 1, mnDPIY );
826  }
827  }
828  }
829 
830  MapMode aNewMapMode( MapUnit::MapRelative, Point( -aPt.X(), -aPt.Y() ), aXF, aYF );
831  SetMapMode( aNewMapMode );
832 
833  if ( eNew != eOld )
834  maMapMode = rNewMapMode;
835 
836  // #106426# Adapt logical offset when changing MapMode
841 
842  if( mpAlphaVDev )
843  mpAlphaVDev->SetRelativeMapMode( rNewMapMode );
844 }
845 
846 // #i75163#
848 {
849  if(mbMap && mpOutDevData)
850  {
851  if(!mpOutDevData->mpViewTransform)
852  {
853  mpOutDevData->mpViewTransform = new basegfx::B2DHomMatrix;
854 
855  const double fScaleFactorX(static_cast<double>(mnDPIX) * static_cast<double>(maMapRes.mnMapScNumX) / static_cast<double>(maMapRes.mnMapScDenomX));
856  const double fScaleFactorY(static_cast<double>(mnDPIY) * static_cast<double>(maMapRes.mnMapScNumY) / static_cast<double>(maMapRes.mnMapScDenomY));
857  const double fZeroPointX((static_cast<double>(maMapRes.mnMapOfsX) * fScaleFactorX) + static_cast<double>(mnOutOffOrigX));
858  const double fZeroPointY((static_cast<double>(maMapRes.mnMapOfsY) * fScaleFactorY) + static_cast<double>(mnOutOffOrigY));
859 
860  mpOutDevData->mpViewTransform->set(0, 0, fScaleFactorX);
861  mpOutDevData->mpViewTransform->set(1, 1, fScaleFactorY);
862  mpOutDevData->mpViewTransform->set(0, 2, fZeroPointX);
863  mpOutDevData->mpViewTransform->set(1, 2, fZeroPointY);
864  }
865 
866  return *mpOutDevData->mpViewTransform;
867  }
868  else
869  {
870  return basegfx::B2DHomMatrix();
871  }
872 }
873 
874 // #i75163#
876 {
877  if(mbMap && mpOutDevData)
878  {
879  if(!mpOutDevData->mpInverseViewTransform)
880  {
882  mpOutDevData->mpInverseViewTransform = new basegfx::B2DHomMatrix(*mpOutDevData->mpViewTransform);
883  mpOutDevData->mpInverseViewTransform->invert();
884  }
885 
886  return *mpOutDevData->mpInverseViewTransform;
887  }
888  else
889  {
890  return basegfx::B2DHomMatrix();
891  }
892 }
893 
894 // #i75163#
896 {
897  // #i82615#
898  ImplMapRes aMapRes;
899  ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
900 
901  basegfx::B2DHomMatrix aTransform;
902 
903  const double fScaleFactorX(static_cast<double>(mnDPIX) * static_cast<double>(aMapRes.mnMapScNumX) / static_cast<double>(aMapRes.mnMapScDenomX));
904  const double fScaleFactorY(static_cast<double>(mnDPIY) * static_cast<double>(aMapRes.mnMapScNumY) / static_cast<double>(aMapRes.mnMapScDenomY));
905  const double fZeroPointX((static_cast<double>(aMapRes.mnMapOfsX) * fScaleFactorX) + static_cast<double>(mnOutOffOrigX));
906  const double fZeroPointY((static_cast<double>(aMapRes.mnMapOfsY) * fScaleFactorY) + static_cast<double>(mnOutOffOrigY));
907 
908  aTransform.set(0, 0, fScaleFactorX);
909  aTransform.set(1, 1, fScaleFactorY);
910  aTransform.set(0, 2, fZeroPointX);
911  aTransform.set(1, 2, fZeroPointY);
912 
913  return aTransform;
914 }
915 
916 // #i75163#
918 {
919  basegfx::B2DHomMatrix aMatrix( GetViewTransformation( rMapMode ) );
920  aMatrix.invert();
921  return aMatrix;
922 }
923 
925 {
926  basegfx::B2DHomMatrix aTransformation = GetViewTransformation();
927  // TODO: is it worth to cache the transformed result?
928  if( mnOutOffX || mnOutOffY )
929  aTransformation.translate( mnOutOffX, mnOutOffY );
930  return aTransformation;
931 }
932 
933 Point OutputDevice::LogicToPixel( const Point& rLogicPt ) const
934 {
935 
936  if ( !mbMap )
937  return rLogicPt;
938 
939  return Point( ImplLogicToPixel( rLogicPt.X() + maMapRes.mnMapOfsX, mnDPIX,
941  ImplLogicToPixel( rLogicPt.Y() + maMapRes.mnMapOfsY, mnDPIY,
943 }
944 
945 Size OutputDevice::LogicToPixel( const Size& rLogicSize ) const
946 {
947 
948  if ( !mbMap )
949  return rLogicSize;
950 
951  return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
953  ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
955 }
956 
958 {
959  // tdf#141761 see comments above, IsEmpty() removed
960  if ( !mbMap )
961  return rLogicRect;
962 
963  tools::Rectangle aRetval(
968 
969  if(rLogicRect.IsWidthEmpty())
970  aRetval.SetWidthEmpty();
971 
972  if(rLogicRect.IsHeightEmpty())
973  aRetval.SetHeightEmpty();
974 
975  return aRetval;
976 }
977 
979 {
980 
981  if ( !mbMap )
982  return rLogicPoly;
983 
984  sal_uInt16 i;
985  sal_uInt16 nPoints = rLogicPoly.GetSize();
986  tools::Polygon aPoly( rLogicPoly );
987 
988  // get pointer to Point-array (copy data)
989  const Point* pPointAry = aPoly.GetConstPointAry();
990 
991  for ( i = 0; i < nPoints; i++ )
992  {
993  const Point* pPt = &(pPointAry[i]);
994  Point aPt;
995  aPt.setX( ImplLogicToPixel( pPt->X() + maMapRes.mnMapOfsX, mnDPIX,
997  aPt.setY( ImplLogicToPixel( pPt->Y() + maMapRes.mnMapOfsY, mnDPIY,
999  aPoly[i] = aPt;
1000  }
1001 
1002  return aPoly;
1003 }
1004 
1006 {
1007 
1008  if ( !mbMap )
1009  return rLogicPolyPoly;
1010 
1011  tools::PolyPolygon aPolyPoly( rLogicPolyPoly );
1012  sal_uInt16 nPoly = aPolyPoly.Count();
1013  for( sal_uInt16 i = 0; i < nPoly; i++ )
1014  {
1015  tools::Polygon& rPoly = aPolyPoly[i];
1016  rPoly = LogicToPixel( rPoly );
1017  }
1018  return aPolyPoly;
1019 }
1020 
1022 {
1023  basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly;
1024  const basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation();
1025  aTransformedPoly.transform( rTransformationMatrix );
1026  return aTransformedPoly;
1027 }
1028 
1030 {
1031 
1032  if(!mbMap || rLogicRegion.IsNull() || rLogicRegion.IsEmpty())
1033  {
1034  return rLogicRegion;
1035  }
1036 
1037  vcl::Region aRegion;
1038 
1039  if(rLogicRegion.getB2DPolyPolygon())
1040  {
1041  aRegion = vcl::Region(LogicToPixel(*rLogicRegion.getB2DPolyPolygon()));
1042  }
1043  else if(rLogicRegion.getPolyPolygon())
1044  {
1045  aRegion = vcl::Region(LogicToPixel(*rLogicRegion.getPolyPolygon()));
1046  }
1047  else if(rLogicRegion.getRegionBand())
1048  {
1049  RectangleVector aRectangles;
1050  rLogicRegion.GetRegionRectangles(aRectangles);
1051  const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
1052 
1053  // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1054  for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); ++aRectIter)
1055  {
1056  aRegion.Union(LogicToPixel(*aRectIter));
1057  }
1058  }
1059 
1060  return aRegion;
1061 }
1062 
1063 Point OutputDevice::LogicToPixel( const Point& rLogicPt,
1064  const MapMode& rMapMode ) const
1065 {
1066 
1067  if ( rMapMode.IsDefault() )
1068  return rLogicPt;
1069 
1070  // convert MapMode resolution and convert
1071  ImplMapRes aMapRes;
1072  ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1073 
1074  return Point( ImplLogicToPixel( rLogicPt.X() + aMapRes.mnMapOfsX, mnDPIX,
1075  aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX )+mnOutOffOrigX,
1076  ImplLogicToPixel( rLogicPt.Y() + aMapRes.mnMapOfsY, mnDPIY,
1077  aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY )+mnOutOffOrigY );
1078 }
1079 
1081  const MapMode& rMapMode ) const
1082 {
1083 
1084  if ( rMapMode.IsDefault() )
1085  return rLogicSize;
1086 
1087  // convert MapMode resolution and convert
1088  ImplMapRes aMapRes;
1089  ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1090 
1091  return Size( ImplLogicToPixel( rLogicSize.Width(), mnDPIX,
1092  aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ),
1093  ImplLogicToPixel( rLogicSize.Height(), mnDPIY,
1094  aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) );
1095 }
1096 
1098  const MapMode& rMapMode ) const
1099 {
1100  // tdf#141761 see comments above, IsEmpty() removed
1101  if ( rMapMode.IsDefault() )
1102  return rLogicRect;
1103 
1104  // convert MapMode resolution and convert
1105  ImplMapRes aMapRes;
1106  ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1107 
1108  tools::Rectangle aRetval(
1109  ImplLogicToPixel( rLogicRect.Left() + aMapRes.mnMapOfsX, mnDPIX, aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX )+mnOutOffOrigX,
1110  ImplLogicToPixel( rLogicRect.Top() + aMapRes.mnMapOfsY, mnDPIY, aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY )+mnOutOffOrigY,
1111  rLogicRect.IsWidthEmpty() ? 0 : ImplLogicToPixel( rLogicRect.Right() + aMapRes.mnMapOfsX, mnDPIX, aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX )+mnOutOffOrigX,
1112  rLogicRect.IsHeightEmpty() ? 0 : ImplLogicToPixel( rLogicRect.Bottom() + aMapRes.mnMapOfsY, mnDPIY, aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY )+mnOutOffOrigY );
1113 
1114  if(rLogicRect.IsWidthEmpty())
1115  aRetval.SetWidthEmpty();
1116 
1117  if(rLogicRect.IsHeightEmpty())
1118  aRetval.SetHeightEmpty();
1119 
1120  return aRetval;
1121 }
1122 
1124  const MapMode& rMapMode ) const
1125 {
1126 
1127  if ( rMapMode.IsDefault() )
1128  return rLogicPoly;
1129 
1130  // convert MapMode resolution and convert
1131  ImplMapRes aMapRes;
1132  ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1133 
1134  sal_uInt16 i;
1135  sal_uInt16 nPoints = rLogicPoly.GetSize();
1136  tools::Polygon aPoly( rLogicPoly );
1137 
1138  // get pointer to Point-array (copy data)
1139  const Point* pPointAry = aPoly.GetConstPointAry();
1140 
1141  for ( i = 0; i < nPoints; i++ )
1142  {
1143  const Point* pPt = &(pPointAry[i]);
1144  Point aPt;
1145  aPt.setX( ImplLogicToPixel( pPt->X() + aMapRes.mnMapOfsX, mnDPIX,
1146  aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX )+mnOutOffOrigX );
1147  aPt.setY( ImplLogicToPixel( pPt->Y() + aMapRes.mnMapOfsY, mnDPIY,
1148  aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY )+mnOutOffOrigY );
1149  aPoly[i] = aPt;
1150  }
1151 
1152  return aPoly;
1153 }
1154 
1156  const MapMode& rMapMode ) const
1157 {
1158  basegfx::B2DPolyPolygon aTransformedPoly = rLogicPolyPoly;
1159  const basegfx::B2DHomMatrix& rTransformationMatrix = GetViewTransformation( rMapMode );
1160  aTransformedPoly.transform( rTransformationMatrix );
1161  return aTransformedPoly;
1162 }
1163 
1164 Point OutputDevice::PixelToLogic( const Point& rDevicePt ) const
1165 {
1166 
1167  if ( !mbMap )
1168  return rDevicePt;
1169 
1170  return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1172  ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1174 }
1175 
1176 Size OutputDevice::PixelToLogic( const Size& rDeviceSize ) const
1177 {
1178 
1179  if ( !mbMap )
1180  return rDeviceSize;
1181 
1182  return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1184  ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1186 }
1187 
1189 {
1190  // tdf#141761 see comments above, IsEmpty() removed
1191  if ( !mbMap )
1192  return rDeviceRect;
1193 
1194  tools::Rectangle aRetval(
1199 
1200  if(rDeviceRect.IsWidthEmpty())
1201  aRetval.SetWidthEmpty();
1202 
1203  if(rDeviceRect.IsHeightEmpty())
1204  aRetval.SetHeightEmpty();
1205 
1206  return aRetval;
1207 }
1208 
1210 {
1211 
1212  if ( !mbMap )
1213  return rDevicePoly;
1214 
1215  sal_uInt16 i;
1216  sal_uInt16 nPoints = rDevicePoly.GetSize();
1217  tools::Polygon aPoly( rDevicePoly );
1218 
1219  // get pointer to Point-array (copy data)
1220  const Point* pPointAry = aPoly.GetConstPointAry();
1221 
1222  for ( i = 0; i < nPoints; i++ )
1223  {
1224  const Point* pPt = &(pPointAry[i]);
1225  Point aPt;
1226  aPt.setX( ImplPixelToLogic( pPt->X(), mnDPIX,
1228  aPt.setY( ImplPixelToLogic( pPt->Y(), mnDPIY,
1230  aPoly[i] = aPt;
1231  }
1232 
1233  return aPoly;
1234 }
1235 
1237 {
1238 
1239  if ( !mbMap )
1240  return rDevicePolyPoly;
1241 
1242  tools::PolyPolygon aPolyPoly( rDevicePolyPoly );
1243  sal_uInt16 nPoly = aPolyPoly.Count();
1244  for( sal_uInt16 i = 0; i < nPoly; i++ )
1245  {
1246  tools::Polygon& rPoly = aPolyPoly[i];
1247  rPoly = PixelToLogic( rPoly );
1248  }
1249  return aPolyPoly;
1250 }
1251 
1253 {
1254  basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly;
1255  const basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation();
1256  aTransformedPoly.transform( rTransformationMatrix );
1257  return aTransformedPoly;
1258 }
1259 
1261 {
1262 
1263  if(!mbMap || rDeviceRegion.IsNull() || rDeviceRegion.IsEmpty())
1264  {
1265  return rDeviceRegion;
1266  }
1267 
1268  vcl::Region aRegion;
1269 
1270  if(rDeviceRegion.getB2DPolyPolygon())
1271  {
1272  aRegion = vcl::Region(PixelToLogic(*rDeviceRegion.getB2DPolyPolygon()));
1273  }
1274  else if(rDeviceRegion.getPolyPolygon())
1275  {
1276  aRegion = vcl::Region(PixelToLogic(*rDeviceRegion.getPolyPolygon()));
1277  }
1278  else if(rDeviceRegion.getRegionBand())
1279  {
1280  RectangleVector aRectangles;
1281  rDeviceRegion.GetRegionRectangles(aRectangles);
1282  const RectangleVector& rRectangles(aRectangles); // needed to make the '!=' work
1283 
1284  // make reverse run to fill new region bottom-up, this will speed it up due to the used data structuring
1285  for(RectangleVector::const_reverse_iterator aRectIter(rRectangles.rbegin()); aRectIter != rRectangles.rend(); ++aRectIter)
1286  {
1287  aRegion.Union(PixelToLogic(*aRectIter));
1288  }
1289  }
1290 
1291  return aRegion;
1292 }
1293 
1294 Point OutputDevice::PixelToLogic( const Point& rDevicePt,
1295  const MapMode& rMapMode ) const
1296 {
1297 
1298  // calculate nothing if default-MapMode
1299  if ( rMapMode.IsDefault() )
1300  return rDevicePt;
1301 
1302  // calculate MapMode-resolution and convert
1303  ImplMapRes aMapRes;
1304  ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1305 
1306  return Point( ImplPixelToLogic( rDevicePt.X(), mnDPIX,
1307  aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1308  ImplPixelToLogic( rDevicePt.Y(), mnDPIY,
1309  aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1310 }
1311 
1313  const MapMode& rMapMode ) const
1314 {
1315 
1316  // calculate nothing if default-MapMode
1317  if ( rMapMode.IsDefault() )
1318  return rDeviceSize;
1319 
1320  // calculate MapMode-resolution and convert
1321  ImplMapRes aMapRes;
1322  ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1323 
1324  return Size( ImplPixelToLogic( rDeviceSize.Width(), mnDPIX,
1325  aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ),
1326  ImplPixelToLogic( rDeviceSize.Height(), mnDPIY,
1327  aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) );
1328 }
1329 
1331  const MapMode& rMapMode ) const
1332 {
1333  // calculate nothing if default-MapMode
1334  // tdf#141761 see comments above, IsEmpty() removed
1335  if ( rMapMode.IsDefault() )
1336  return rDeviceRect;
1337 
1338  // calculate MapMode-resolution and convert
1339  ImplMapRes aMapRes;
1340  ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1341 
1342  tools::Rectangle aRetval(
1343  ImplPixelToLogic( rDeviceRect.Left(), mnDPIX, aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1344  ImplPixelToLogic( rDeviceRect.Top(), mnDPIY, aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) - aMapRes.mnMapOfsY - mnOutOffLogicY,
1345  rDeviceRect.IsWidthEmpty() ? 0 : ImplPixelToLogic( rDeviceRect.Right(), mnDPIX, aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ) - aMapRes.mnMapOfsX - mnOutOffLogicX,
1346  rDeviceRect.IsHeightEmpty() ? 0 : ImplPixelToLogic( rDeviceRect.Bottom(), mnDPIY, aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1347 
1348  if(rDeviceRect.IsWidthEmpty())
1349  aRetval.SetWidthEmpty();
1350 
1351  if(rDeviceRect.IsHeightEmpty())
1352  aRetval.SetHeightEmpty();
1353 
1354  return aRetval;
1355 }
1356 
1358  const MapMode& rMapMode ) const
1359 {
1360 
1361  // calculate nothing if default-MapMode
1362  if ( rMapMode.IsDefault() )
1363  return rDevicePoly;
1364 
1365  // calculate MapMode-resolution and convert
1366  ImplMapRes aMapRes;
1367  ImplCalcMapResolution(rMapMode, mnDPIX, mnDPIY, aMapRes);
1368 
1369  sal_uInt16 i;
1370  sal_uInt16 nPoints = rDevicePoly.GetSize();
1371  tools::Polygon aPoly( rDevicePoly );
1372 
1373  // get pointer to Point-array (copy data)
1374  const Point* pPointAry = aPoly.GetConstPointAry();
1375 
1376  for ( i = 0; i < nPoints; i++ )
1377  {
1378  const Point* pPt = &(pPointAry[i]);
1379  Point aPt;
1380  aPt.setX( ImplPixelToLogic( pPt->X(), mnDPIX,
1381  aMapRes.mnMapScNumX, aMapRes.mnMapScDenomX ) - aMapRes.mnMapOfsX - mnOutOffLogicX );
1382  aPt.setY( ImplPixelToLogic( pPt->Y(), mnDPIY,
1383  aMapRes.mnMapScNumY, aMapRes.mnMapScDenomY ) - aMapRes.mnMapOfsY - mnOutOffLogicY );
1384  aPoly[i] = aPt;
1385  }
1386 
1387  return aPoly;
1388 }
1389 
1391  const MapMode& rMapMode ) const
1392 {
1393  basegfx::B2DPolygon aTransformedPoly = rPixelPoly;
1394  const basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation( rMapMode );
1395  aTransformedPoly.transform( rTransformationMatrix );
1396  return aTransformedPoly;
1397 }
1398 
1400  const MapMode& rMapMode ) const
1401 {
1402  basegfx::B2DPolyPolygon aTransformedPoly = rPixelPolyPoly;
1403  const basegfx::B2DHomMatrix& rTransformationMatrix = GetInverseViewTransformation( rMapMode );
1404  aTransformedPoly.transform( rTransformationMatrix );
1405  return aTransformedPoly;
1406 }
1407 
1408 #define ENTER1( rSource, pMapModeSource, pMapModeDest ) \
1409  if ( !pMapModeSource ) \
1410  pMapModeSource = &maMapMode; \
1411  if ( !pMapModeDest ) \
1412  pMapModeDest = &maMapMode; \
1413  if ( *pMapModeSource == *pMapModeDest ) \
1414  return rSource; \
1415  \
1416  ImplMapRes aMapResSource; \
1417  ImplMapRes aMapResDest; \
1418  \
1419  if ( !mbMap || pMapModeSource != &maMapMode ) \
1420  { \
1421  if ( pMapModeSource->GetMapUnit() == MapUnit::MapRelative ) \
1422  aMapResSource = maMapRes; \
1423  ImplCalcMapResolution( *pMapModeSource, \
1424  mnDPIX, mnDPIY, aMapResSource ); \
1425  } \
1426  else \
1427  aMapResSource = maMapRes; \
1428  if ( !mbMap || pMapModeDest != &maMapMode ) \
1429  { \
1430  if ( pMapModeDest->GetMapUnit() == MapUnit::MapRelative ) \
1431  aMapResDest = maMapRes; \
1432  ImplCalcMapResolution( *pMapModeDest, \
1433  mnDPIX, mnDPIY, aMapResDest ); \
1434  } \
1435  else \
1436  aMapResDest = maMapRes
1437 
1438 static void verifyUnitSourceDest( MapUnit eUnitSource, MapUnit eUnitDest )
1439 {
1440  DBG_ASSERT( eUnitSource != MapUnit::MapSysFont
1441  && eUnitSource != MapUnit::MapAppFont
1442  && eUnitSource != MapUnit::MapRelative,
1443  "Source MapUnit is not permitted" );
1444  DBG_ASSERT( eUnitDest != MapUnit::MapSysFont
1445  && eUnitDest != MapUnit::MapAppFont
1446  && eUnitDest != MapUnit::MapRelative,
1447  "Destination MapUnit is not permitted" );
1448 }
1449 
1450 namespace
1451 {
1452 auto getCorrectedUnit(MapUnit eMapSrc, MapUnit eMapDst)
1453 {
1456  if (eMapSrc > MapUnit::MapPixel)
1457  SAL_WARN("vcl.gdi", "Invalid source map unit");
1458  else if (eMapDst > MapUnit::MapPixel)
1459  SAL_WARN("vcl.gdi", "Invalid destination map unit");
1460  else if (eMapSrc != eMapDst)
1461  {
1462  // Here 72 PPI is assumed for MapPixel
1463  eSrc = MapToO3tlLength(eMapSrc, o3tl::Length::pt);
1464  eDst = MapToO3tlLength(eMapDst, o3tl::Length::pt);
1465  }
1466  return std::make_pair(eSrc, eDst);
1467 }
1468 }
1469 
1470 #define ENTER4( rMapModeSource, rMapModeDest ) \
1471  ImplMapRes aMapResSource; \
1472  ImplMapRes aMapResDest; \
1473  \
1474  ImplCalcMapResolution( rMapModeSource, 72, 72, aMapResSource ); \
1475  ImplCalcMapResolution( rMapModeDest, 72, 72, aMapResDest )
1476 
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 )
1483 {
1484  if ( n1 == 0 || n2 == 0 || n3 == 0 || n4 == 0 || n5 == 0 )
1485  return 0;
1486  if (std::numeric_limits<tools::Long>::max() / std::abs(n2) < std::abs(n3))
1487  {
1488  // a6 is skipped
1489  BigInt a7 = n2;
1490  a7 *= n3;
1491  a7 *= n1;
1492 
1493  if (std::numeric_limits<tools::Long>::max() / std::abs(n4) < std::abs(n5))
1494  {
1495  BigInt a8 = n4;
1496  a8 *= n5;
1497 
1498  BigInt a9 = a8;
1499  a9 /= 2;
1500  if ( a7.IsNeg() )
1501  a7 -= a9;
1502  else
1503  a7 += a9;
1504 
1505  a7 /= a8;
1506  } // of if
1507  else
1508  {
1509  tools::Long n8 = n4 * n5;
1510 
1511  if ( a7.IsNeg() )
1512  a7 -= n8 / 2;
1513  else
1514  a7 += n8 / 2;
1515 
1516  a7 /= n8;
1517  } // of else
1518  return static_cast<tools::Long>(a7);
1519  } // of if
1520  else
1521  {
1522  tools::Long n6 = n2 * n3;
1523 
1524  if (std::numeric_limits<tools::Long>::max() / std::abs(n1) < std::abs(n6))
1525  {
1526  BigInt a7 = n1;
1527  a7 *= n6;
1528 
1529  if (std::numeric_limits<tools::Long>::max() / std::abs(n4) < std::abs(n5))
1530  {
1531  BigInt a8 = n4;
1532  a8 *= n5;
1533 
1534  BigInt a9 = a8;
1535  a9 /= 2;
1536  if ( a7.IsNeg() )
1537  a7 -= a9;
1538  else
1539  a7 += a9;
1540 
1541  a7 /= a8;
1542  } // of if
1543  else
1544  {
1545  tools::Long n8 = n4 * n5;
1546 
1547  if ( a7.IsNeg() )
1548  a7 -= n8 / 2;
1549  else
1550  a7 += n8 / 2;
1551 
1552  a7 /= n8;
1553  } // of else
1554  return static_cast<tools::Long>(a7);
1555  } // of if
1556  else
1557  {
1558  tools::Long n7 = n1 * n6;
1559 
1560  if (std::numeric_limits<tools::Long>::max() / std::abs(n4) < std::abs(n5))
1561  {
1562  BigInt a7 = n7;
1563  BigInt a8 = n4;
1564  a8 *= n5;
1565 
1566  BigInt a9 = a8;
1567  a9 /= 2;
1568  if ( a7.IsNeg() )
1569  a7 -= a9;
1570  else
1571  a7 += a9;
1572 
1573  a7 /= a8;
1574  return static_cast<tools::Long>(a7);
1575  } // of if
1576  else
1577  {
1578  const tools::Long n8 = n4 * n5;
1579  const tools::Long n8_2 = n8 / 2;
1580 
1581  if( n7 < 0 )
1582  {
1583  if ((n7 - std::numeric_limits<tools::Long>::min()) >= n8_2)
1584  n7 -= n8_2;
1585  }
1586  else if ((std::numeric_limits<tools::Long>::max() - n7) >= n8_2)
1587  n7 += n8_2;
1588 
1589  return n7 / n8;
1590  } // of else
1591  } // of else
1592  } // of else
1593 }
1594 
1595 static tools::Long fn3(const tools::Long n1, const o3tl::Length eFrom, const o3tl::Length eTo)
1596 {
1597  if (n1 == 0 || eFrom == o3tl::Length::invalid || eTo == o3tl::Length::invalid)
1598  return 0;
1599  bool bOverflow;
1600  const auto nResult = o3tl::convert(n1, eFrom, eTo, bOverflow);
1601  if (bOverflow)
1602  {
1603  const auto& [n2, n3] = o3tl::getConversionMulDiv(eFrom, eTo);
1604  BigInt a4 = n1;
1605  a4 *= n2;
1606 
1607  if ( a4.IsNeg() )
1608  a4 -= n3 / 2;
1609  else
1610  a4 += n3 / 2;
1611 
1612  a4 /= n3;
1613  return static_cast<tools::Long>(a4);
1614  } // of if
1615  else
1616  return nResult;
1617 }
1618 
1619 Point OutputDevice::LogicToLogic( const Point& rPtSource,
1620  const MapMode* pMapModeSource,
1621  const MapMode* pMapModeDest ) const
1622 {
1623  ENTER1( rPtSource, pMapModeSource, pMapModeDest );
1624 
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 );
1633 }
1634 
1636  const MapMode* pMapModeSource,
1637  const MapMode* pMapModeDest ) const
1638 {
1639  ENTER1( rSzSource, pMapModeSource, pMapModeDest );
1640 
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 ) );
1647 }
1648 
1650  const MapMode* pMapModeSource,
1651  const MapMode* pMapModeDest ) const
1652 {
1653  ENTER1( rRectSource, pMapModeSource, pMapModeDest );
1654 
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 );
1671 }
1672 
1673 Point OutputDevice::LogicToLogic( const Point& rPtSource,
1674  const MapMode& rMapModeSource,
1675  const MapMode& rMapModeDest )
1676 {
1677  if ( rMapModeSource == rMapModeDest )
1678  return rPtSource;
1679 
1680  MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1681  MapUnit eUnitDest = rMapModeDest.GetMapUnit();
1682  verifyUnitSourceDest( eUnitSource, eUnitDest );
1683 
1684  if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1685  {
1686  const auto& [eFrom, eTo] = getCorrectedUnit(eUnitSource, eUnitDest);
1687  return Point(fn3(rPtSource.X(), eFrom, eTo), fn3(rPtSource.Y(), eFrom, eTo));
1688  }
1689  else
1690  {
1691  ENTER4( rMapModeSource, rMapModeDest );
1692 
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 );
1701  }
1702 }
1703 
1705  const MapMode& rMapModeSource,
1706  const MapMode& rMapModeDest )
1707 {
1708  if ( rMapModeSource == rMapModeDest )
1709  return rSzSource;
1710 
1711  MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1712  MapUnit eUnitDest = rMapModeDest.GetMapUnit();
1713  verifyUnitSourceDest( eUnitSource, eUnitDest );
1714 
1715  if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1716  {
1717  const auto& [eFrom, eTo] = getCorrectedUnit(eUnitSource, eUnitDest);
1718  return Size(fn3(rSzSource.Width(), eFrom, eTo), fn3(rSzSource.Height(), eFrom, eTo));
1719  }
1720  else
1721  {
1722  ENTER4( rMapModeSource, rMapModeDest );
1723 
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 ) );
1730  }
1731 }
1732 
1734  const MapMode& rMapModeSource,
1735  const MapMode& rMapModeDest )
1736 {
1737  if(rMapModeSource == rMapModeDest)
1738  {
1739  return rPolySource;
1740  }
1741 
1742  const basegfx::B2DHomMatrix aTransform(LogicToLogic(rMapModeSource, rMapModeDest));
1743  basegfx::B2DPolygon aPoly(rPolySource);
1744 
1745  aPoly.transform(aTransform);
1746  return aPoly;
1747 }
1748 
1749 basegfx::B2DHomMatrix OutputDevice::LogicToLogic(const MapMode& rMapModeSource, const MapMode& rMapModeDest)
1750 {
1751  basegfx::B2DHomMatrix aTransform;
1752 
1753  if(rMapModeSource == rMapModeDest)
1754  {
1755  return aTransform;
1756  }
1757 
1758  MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1759  MapUnit eUnitDest = rMapModeDest.GetMapUnit();
1760  verifyUnitSourceDest(eUnitSource, eUnitDest);
1761 
1762  if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1763  {
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);
1770  }
1771  else
1772  {
1773  ENTER4(rMapModeSource, rMapModeDest);
1774 
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));
1779 
1780  aTransform.set(0, 0, fScaleFactorX);
1781  aTransform.set(1, 1, fScaleFactorY);
1782  aTransform.set(0, 2, fZeroPointX);
1783  aTransform.set(1, 2, fZeroPointY);
1784  }
1785 
1786  return aTransform;
1787 }
1788 
1790  const MapMode& rMapModeSource,
1791  const MapMode& rMapModeDest )
1792 {
1793  if ( rMapModeSource == rMapModeDest )
1794  return rRectSource;
1795 
1796  MapUnit eUnitSource = rMapModeSource.GetMapUnit();
1797  MapUnit eUnitDest = rMapModeDest.GetMapUnit();
1798  verifyUnitSourceDest( eUnitSource, eUnitDest );
1799 
1800  tools::Rectangle aRetval;
1801 
1802  if (rMapModeSource.IsSimple() && rMapModeDest.IsSimple())
1803  {
1804  const auto& [eFrom, eTo] = getCorrectedUnit(eUnitSource, eUnitDest);
1805 
1806  auto left = fn3(rRectSource.Left(), eFrom, eTo);
1807  auto top = fn3(rRectSource.Top(), eFrom, eTo);
1808 
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);
1812 
1813  aRetval = tools::Rectangle(left, top, right, bottom);
1814  }
1815  else
1816  {
1817  ENTER4( rMapModeSource, rMapModeDest );
1818 
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;
1827 
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;
1837 
1838  aRetval = tools::Rectangle(left, top, right, bottom);
1839  }
1840 
1841  if(rRectSource.IsWidthEmpty())
1842  aRetval.SetWidthEmpty();
1843 
1844  if(rRectSource.IsHeightEmpty())
1845  aRetval.SetHeightEmpty();
1846 
1847  return aRetval;
1848 }
1849 
1851  MapUnit eUnitSource, MapUnit eUnitDest )
1852 {
1853  if ( eUnitSource == eUnitDest )
1854  return nLongSource;
1855 
1856  verifyUnitSourceDest( eUnitSource, eUnitDest );
1857  const auto& [eFrom, eTo] = getCorrectedUnit(eUnitSource, eUnitDest);
1858  return fn3(nLongSource, eFrom, eTo);
1859 }
1860 
1861 void OutputDevice::SetPixelOffset( const Size& rOffset )
1862 {
1863  mnOutOffOrigX = rOffset.Width();
1864  mnOutOffOrigY = rOffset.Height();
1865 
1870 
1871  if( mpAlphaVDev )
1872  mpAlphaVDev->SetPixelOffset( rOffset );
1873 }
1874 
1875 
1877 {
1878  if ( !mbMap )
1879  return static_cast<DeviceCoordinate>(nWidth);
1880 
1881 #if VCL_FLOAT_DEVICE_PIXEL
1882  return ImplLogicToPixel(static_cast<double>(nWidth), mnDPIX, maMapRes.mnMapScNumX, maMapRes.mnMapScDenomX);
1883 #else
1885 #endif
1886 }
1887 
1889 {
1890  if (!mbMap)
1891  return nWidth;
1892 
1893  return ImplLogicToPixel(static_cast<double>(nWidth), mnDPIX,
1895 }
1896 
1898 {
1899  if (!mbMap)
1900  return DevicePoint(rPoint.X() + mnOutOffX, rPoint.Y() + mnOutOffY);
1901 
1902  return DevicePoint(ImplLogicToPixel(static_cast<double>(rPoint.X() + maMapRes.mnMapOfsX), mnDPIX,
1905  ImplLogicToPixel(static_cast<double>(rPoint.Y() + maMapRes.mnMapOfsY), mnDPIY,
1907  + mnOutOffY + mnOutOffOrigY);
1908 }
1909 
1910 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt16 Count() const
basegfx::B2DHomMatrix GetInverseViewTransformation() const
Definition: map.cxx:875
const Fraction & GetScaleX() const
Definition: mapmod.cxx:154
double getY() const
void SetPixelOffset(const Size &rOffset)
Set an offset in pixel.
Definition: map.cxx:1861
SAL_DLLPRIVATE DeviceCoordinate LogicWidthToDeviceCoordinate(tools::Long nWidth) const
Definition: map.cxx:1876
void SetRelativeMapMode(const MapMode &rNewMapMode)
Definition: map.cxx:775
static auto setMapRes(ImplMapRes &rMapRes, const o3tl::Length eUnit)
Definition: map.cxx:80
static void verifyUnitSourceDest(MapUnit eUnitSource, MapUnit eUnitDest)
Definition: map.cxx:1438
tools::Long mnOutOffLogicX
Additional output offset in logical coordinates, applied in PixelToLogic (used by SetPixelOffset/GetP...
Definition: outdev.hxx:207
void set(sal_uInt16 nRow, sal_uInt16 nColumn, double fValue)
tools::Long mnOutOffOrigY
Additional output pixel offset, applied in LogicToPixel (used by SetPixelOffset/GetPixelOffset) ...
Definition: outdev.hxx:209
bool IsNull() const
Definition: region.hxx:99
static Fraction ImplMakeFraction(tools::Long nN1, tools::Long nN2, tools::Long nD1, tools::Long nD2)
Definition: map.cxx:45
sal_uInt64 left
void Move(tools::Long nHorzMove, tools::Long nVertMove)
Definition: region.cxx:400
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
Definition: map.cxx:1619
constexpr tools::Long Left() const
static SAL_DLLPRIVATE void ImplInitAppFontData(vcl::Window const *pWindow)
Definition: window.cxx:1183
void Union(const tools::Rectangle &rRegion)
Definition: region.cxx:506
long Long
bool IsSimple() const
Definition: mapmod.cxx:158
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
SAL_DLLPRIVATE double ImplLogicWidthToDeviceFontWidth(tools::Long nWidth) const
Definition: map.cxx:1888
tools::Long mnOutOffY
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:215
sal_Int32 mnDPIY
Definition: outdev.hxx:219
sal_Int32 mnDPIX
Definition: outdev.hxx:218
void EnableMapMode(bool bEnable=true)
Definition: map.cxx:641
bool mbMap
Definition: outdev.hxx:247
sal_Int32 DeviceCoordinate
constexpr bool IsHeightEmpty() const
tools::Long mnMapScDenomX
Scaling factor - denominator in X direction.
Definition: ImplMapRes.hxx:32
bool IsDefault() const
Definition: mapmod.cxx:134
const RegionBand * getRegionBand() const
Definition: region.hxx:78
void SetMapMode()
Definition: map.cxx:649
ImplSVGDIData maGDIData
Definition: svdata.hxx:399
tools::Long mnOutOffOrigX
Additional output pixel offset, applied in LogicToPixel (used by SetPixelOffset/GetPixelOffset) ...
Definition: outdev.hxx:205
std::vector< tools::Rectangle > RectangleVector
Definition: region.hxx:34
MapMode maMapMode
Definition: outdev.hxx:241
#define ENTER1(rSource, pMapModeSource, pMapModeDest)
Definition: map.cxx:1408
constexpr tools::Long Width() const
A construction helper for ScopedVclPtr.
Definition: vclptr.hxx:407
int n2
static void ImplCalcMapResolution(const MapMode &rMapMode, tools::Long nDPIX, tools::Long nDPIY, ImplMapRes &rMapRes)
Definition: map.cxx:87
SAL_DLLPRIVATE tools::Long ImplLogicXToDevicePixel(tools::Long nX) const
Convert a logical X coordinate to a device pixel's X coordinate.
Definition: map.cxx:306
#define ENTER4(rMapModeSource, rMapModeDest)
Definition: map.cxx:1470
const Fraction & GetScaleY() const
Definition: mapmod.cxx:156
tools::Long mnMapScDenomY
Scaling factor - denominator in Y direction.
Definition: ImplMapRes.hxx:33
OString top
OString right
SAL_DLLPRIVATE basegfx::B2DHomMatrix ImplGetDeviceTransformation() const
Get device transformation.
Definition: map.cxx:924
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:1478
static tools::Long ImplLogicToPixel(tools::Long n, tools::Long nDPI, tools::Long nMapNum, tools::Long nMapDenom)
Definition: map.cxx:244
static tools::Long ImplPixelToLogic(tools::Long n, tools::Long nDPI, tools::Long nMapNum, tools::Long nMapDenom)
Definition: map.cxx:281
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:76
SAL_DLLPRIVATE void ImplInvalidateViewTransform()
Invalidate the view transformation.
Definition: map.cxx:226
bool IsEmpty() const
Definition: region.cxx:229
void ReduceInaccurate(unsigned nSignificantBits)
void SetScaleX(const Fraction &rScaleX)
Definition: mapmod.cxx:111
virtual void ImplInitMapModeObjects()
Definition: map.cxx:773
#define DBG_ASSERT(sCon, aError)
int i
SAL_DLLPRIVATE float ImplFloatLogicHeightToDevicePixel(float fLogicHeight) const
Convert logical height to device pixels, with exact sub-pixel value.
Definition: map.cxx:340
const Point * GetConstPointAry() const
void SetOrigin(const Point &rOrigin)
Definition: mapmod.cxx:105
constexpr tools::Long Right() const
bool mbNewFont
Definition: outdev.hxx:261
SAL_DLLPRIVATE tools::Long ImplLogicWidthToDevicePixel(tools::Long nWidth) const
Convert a logical width to a width in units of device pixels.
Definition: map.cxx:324
void transform(const basegfx::B2DHomMatrix &rMatrix)
void SetScaleY(const Fraction &rScaleY)
Definition: mapmod.cxx:118
constexpr tools::Long Top() const
sal_uInt16 GetSize() const
tools::Long mnMapOfsX
Offset in X direction.
Definition: ImplMapRes.hxx:28
MapUnit GetMapUnit() const
Definition: mapmod.cxx:150
bool IsNeg() const
virtual void SetMetafileMapMode(const MapMode &rNewMapMode, bool bIsRecord)
Definition: map.cxx:765
tools::Long mnMapOfsY
Offset in Y direction.
Definition: ImplMapRes.hxx:29
static tools::Long fn3(const tools::Long n1, const o3tl::Length eFrom, const o3tl::Length eTo)
Definition: map.cxx:1595
void transform(const basegfx::B2DHomMatrix &rMatrix)
constexpr tools::Long Bottom() const
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
Definition: map.cxx:1164
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:933
const std::optional< basegfx::B2DPolyPolygon > & getB2DPolyPolygon() const
Definition: region.hxx:76
basegfx::B2DPoint DevicePoint
VclPtr< VirtualDevice > mpAlphaVDev
Definition: outdev.hxx:202
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:631
ImplMapRes maMapRes
Definition: outdev.hxx:228
sal_Int32 GetDenominator() const
tools::Long mnMapScNumY
Scaling factor - numerator in Y direction.
Definition: ImplMapRes.hxx:31
constexpr tools::Long Height() const
constexpr o3tl::Length MapToO3tlLength(MapUnit eU, o3tl::Length ePixelValue=o3tl::Length::px)
tools::Long mnAppFontX
Definition: svdata.hxx:234
void AddAction(const rtl::Reference< MetaAction > &pAction)
Definition: gdimtf.cxx:581
tools::Long mnMapScNumX
Scaling factor - numerator in X direction.
Definition: ImplMapRes.hxx:30
ImplSVFrameData maFrameData
Definition: svdata.hxx:400
void GetRegionRectangles(RectangleVector &rTarget) const
Definition: region.cxx:1673
OString bottom
sal_Int32 GetNumerator() const
bool mbInitFont
Definition: outdev.hxx:257
const Point & GetOrigin() const
Definition: mapmod.cxx:152
void translate(double fX, double fY)
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:386
VclPtr< vcl::Window > mpFirstFrame
Definition: svdata.hxx:245
MapUnit
tools::Long mnOutOffX
Output offset for device output in pixel (pseudo window offset within window system's frames) ...
Definition: outdev.hxx:213
const std::optional< tools::PolyPolygon > & getPolyPolygon() const
Definition: region.hxx:77
#define SAL_WARN(area, stream)
std::unique_ptr< ImplOutDevData > mpOutDevData
Definition: outdev.hxx:195
double getX() const
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:600
SAL_DLLPRIVATE tools::Long ImplLogicYToDevicePixel(tools::Long nY) const
Convert a logical Y coordinate to a device pixel's Y coordinate.
Definition: map.cxx:315
bool IsValid() const
tools::Long mnOutOffLogicY
Additional output offset in logical coordinates, applied in PixelToLogic (used by SetPixelOffset/GetP...
Definition: outdev.hxx:211
SAL_DLLPRIVATE DevicePoint ImplLogicToDeviceFontCoordinate(const Point &rLogicPt) const
Definition: map.cxx:1897
SAL_DLLPRIVATE tools::Long ImplDevicePixelToLogicWidth(tools::Long nWidth) const
Convert device pixels to a width in logical units.
Definition: map.cxx:348
tools::Long mnAppFontY
Definition: svdata.hxx:235
basegfx::B2DHomMatrix GetViewTransformation() const
Definition: map.cxx:847
SAL_DLLPRIVATE tools::Long ImplLogicHeightToDevicePixel(tools::Long nHeight) const
Convert a logical height to a height in units of device pixels.
Definition: map.cxx:332
SAL_DLLPRIVATE tools::Long ImplDevicePixelToLogicHeight(tools::Long nHeight) const
Convert device pixels to a height in logical units.
Definition: map.cxx:356
constexpr bool IsWidthEmpty() const
double div(const double &fNumerator, const double &fDenominator)
GDIMetaFile * mpMetaFile
Definition: outdev.hxx:191
sal_uInt32 count() const