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