LCOV - code coverage report
Current view: top level - svx/source/sdr/overlay - overlaymanagerbuffered.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 168 189 88.9 %
Date: 2015-06-13 12:38:46 Functions: 13 15 86.7 %
Legend: Lines: hit not hit

          Line data    Source code
       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 <sdr/overlay/overlaymanagerbuffered.hxx>
      21             : #include <svx/sdrpaintwindow.hxx>
      22             : #include <vcl/outdev.hxx>
      23             : #include <basegfx/point/b2dpoint.hxx>
      24             : #include <basegfx/range/b2drange.hxx>
      25             : #include <vcl/window.hxx>
      26             : #include <vcl/bitmap.hxx>
      27             : #include <tools/stream.hxx>
      28             : #include <tools/fract.hxx>
      29             : #include <basegfx/matrix/b2dhommatrix.hxx>
      30             : #include <vcl/cursor.hxx>
      31             : #include <vcl/dibtools.hxx>
      32             : 
      33             : 
      34             : 
      35             : namespace sdr
      36             : {
      37             :     namespace overlay
      38             :     {
      39       13746 :         void OverlayManagerBuffered::ImpPrepareBufferDevice()
      40             :         {
      41             :             // compare size of mpBufferDevice with size of visible area
      42       13746 :             if(mpBufferDevice->GetOutputSizePixel() != getOutputDevice().GetOutputSizePixel())
      43             :             {
      44             :                 // set new buffer size, copy as much content as possible (use bool parameter for vcl).
      45             :                 // Newly uncovered regions will be repainted.
      46        1224 :                 mpBufferDevice->SetOutputSizePixel(getOutputDevice().GetOutputSizePixel(), false);
      47             :             }
      48             : 
      49             :             // compare the MapModes for zoom/scroll changes
      50       13746 :             if(mpBufferDevice->GetMapMode() != getOutputDevice().GetMapMode())
      51             :             {
      52             :                 const bool bZoomed(
      53        1587 :                     mpBufferDevice->GetMapMode().GetScaleX() != getOutputDevice().GetMapMode().GetScaleX()
      54        1587 :                     || mpBufferDevice->GetMapMode().GetScaleY() != getOutputDevice().GetMapMode().GetScaleY());
      55             : 
      56        1587 :                 if(!bZoomed)
      57             :                 {
      58        1040 :                     const Point& rOriginOld = mpBufferDevice->GetMapMode().GetOrigin();
      59        1040 :                     const Point& rOriginNew = getOutputDevice().GetMapMode().GetOrigin();
      60        1040 :                     const bool bScrolled(rOriginOld != rOriginNew);
      61             : 
      62        1040 :                     if(bScrolled)
      63             :                     {
      64             :                         // get pixel bounds
      65         367 :                         const Point aOriginOldPixel(mpBufferDevice->LogicToPixel(rOriginOld));
      66         367 :                         const Point aOriginNewPixel(mpBufferDevice->LogicToPixel(rOriginNew));
      67         367 :                         const Size aOutputSizePixel(mpBufferDevice->GetOutputSizePixel());
      68             : 
      69             :                         // remember and switch off MapMode
      70         367 :                         const bool bMapModeWasEnabled(mpBufferDevice->IsMapModeEnabled());
      71         367 :                         mpBufferDevice->EnableMapMode(false);
      72             : 
      73             :                         // scroll internally buffered stuff
      74         367 :                         const Point aDestinationOffsetPixel(aOriginNewPixel - aOriginOldPixel);
      75         367 :                         mpBufferDevice->DrawOutDev(
      76             :                             aDestinationOffsetPixel, aOutputSizePixel, // destination
      77         367 :                             Point(), aOutputSizePixel); // source
      78             : 
      79             :                         // restore MapMode
      80         367 :                         mpBufferDevice->EnableMapMode(bMapModeWasEnabled);
      81             : 
      82             :                         // scroll remembered region, too.
      83         367 :                         if(!maBufferRememberedRangePixel.isEmpty())
      84             :                         {
      85          68 :                             const basegfx::B2IPoint aIPointDestinationOffsetPixel(aDestinationOffsetPixel.X(), aDestinationOffsetPixel.Y());
      86         136 :                             const basegfx::B2IPoint aNewMinimum(maBufferRememberedRangePixel.getMinimum() + aIPointDestinationOffsetPixel);
      87         136 :                             const basegfx::B2IPoint aNewMaximum(maBufferRememberedRangePixel.getMaximum() + aIPointDestinationOffsetPixel);
      88         136 :                             maBufferRememberedRangePixel = basegfx::B2IRange(aNewMinimum, aNewMaximum);
      89             :                         }
      90             :                     }
      91             :                 }
      92             : 
      93             :                 // copy new MapMode
      94        1587 :                 mpBufferDevice->SetMapMode(getOutputDevice().GetMapMode());
      95             :             }
      96             : 
      97             :             // #i29186#
      98       13746 :             mpBufferDevice->SetDrawMode(getOutputDevice().GetDrawMode());
      99       13746 :             mpBufferDevice->SetSettings(getOutputDevice().GetSettings());
     100       13746 :             mpBufferDevice->SetAntialiasing(getOutputDevice().GetAntialiasing());
     101       13746 :         }
     102             : 
     103         240 :         void OverlayManagerBuffered::ImpRestoreBackground() const
     104             :         {
     105             :             const Rectangle aRegionRectanglePixel(
     106         480 :                 maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
     107         720 :                 maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
     108         240 :             const vcl::Region aRegionPixel(aRegionRectanglePixel);
     109             : 
     110         240 :             ImpRestoreBackground(aRegionPixel);
     111         240 :         }
     112             : 
     113         240 :         void OverlayManagerBuffered::ImpRestoreBackground(const vcl::Region& rRegionPixel) const
     114             :         {
     115             :             // MapModes off
     116         240 :             const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled());
     117         240 :             const bool bMapModeWasEnabledSource(mpBufferDevice->IsMapModeEnabled());
     118         240 :             getOutputDevice().EnableMapMode(false);
     119         240 :             const_cast<OverlayManagerBuffered*>(this)->mpBufferDevice->EnableMapMode(false);
     120             : 
     121             :             // local region
     122         240 :             RectangleVector aRectangles;
     123         240 :             rRegionPixel.GetRegionRectangles(aRectangles);
     124             : 
     125         480 :             for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
     126             :             {
     127             : #ifdef DBG_UTIL
     128             :                 // #i72754# possible graphical region test only with non-pro
     129             :                 static bool bDoPaintForVisualControl(false);
     130             : 
     131             :                 if(bDoPaintForVisualControl)
     132             :                 {
     133             :                     getOutputDevice().SetLineColor(COL_LIGHTGREEN);
     134             :                     getOutputDevice().SetFillColor();
     135             :                     getOutputDevice().DrawRect(*aRectIter);
     136             :                 }
     137             : #endif
     138             : 
     139             :                 // restore the area
     140         240 :                 const Point aTopLeft(aRectIter->TopLeft());
     141         240 :                 const Size aSize(aRectIter->GetSize());
     142             : 
     143         240 :                 getOutputDevice().DrawOutDev(
     144             :                     aTopLeft, aSize, // destination
     145             :                     aTopLeft, aSize, // source
     146         240 :                     *mpBufferDevice.get());
     147             :             }
     148             : 
     149             :             // restore MapModes
     150         240 :             getOutputDevice().EnableMapMode(bMapModeWasEnabledDest);
     151         240 :             const_cast<OverlayManagerBuffered*>(this)->mpBufferDevice->EnableMapMode(bMapModeWasEnabledSource);
     152         240 :         }
     153             : 
     154       13746 :         void OverlayManagerBuffered::ImpSaveBackground(const vcl::Region& rRegion, OutputDevice* pPreRenderDevice)
     155             :         {
     156             :             // prepare source
     157       13746 :             OutputDevice& rSource = (pPreRenderDevice) ? *pPreRenderDevice : getOutputDevice();
     158             : 
     159             :             // Ensure buffer is valid
     160       13746 :             ImpPrepareBufferDevice();
     161             : 
     162             :             // build region which needs to be copied
     163       13746 :             vcl::Region aRegion(rSource.LogicToPixel(rRegion));
     164             : 
     165             :             // limit to PaintRegion if it's a window. This will be evtl. the expanded one,
     166             :             // but always the exact redraw area
     167       13746 :             if(OUTDEV_WINDOW == rSource.GetOutDevType())
     168             :             {
     169           0 :                 vcl::Window& rWindow = static_cast<vcl::Window&>(rSource);
     170           0 :                 vcl::Region aPaintRegionPixel = rWindow.LogicToPixel(rWindow.GetPaintRegion());
     171           0 :                 aRegion.Intersect(aPaintRegionPixel);
     172             : 
     173             :                 // #i72754# Make sure content is completetly rendered, the window
     174             :                 // will be used as source of a DrawOutDev soon
     175           0 :                 rWindow.Flush();
     176             :             }
     177             : 
     178             :             // also limit to buffer size
     179       13746 :             const Rectangle aBufferDeviceRectanglePixel(Point(), mpBufferDevice->GetOutputSizePixel());
     180       13746 :             aRegion.Intersect(aBufferDeviceRectanglePixel);
     181             : 
     182             :             // MapModes off
     183       13746 :             const bool bMapModeWasEnabledDest(rSource.IsMapModeEnabled());
     184       13746 :             const bool bMapModeWasEnabledSource(mpBufferDevice->IsMapModeEnabled());
     185       13746 :             rSource.EnableMapMode(false);
     186       13746 :             mpBufferDevice->EnableMapMode(false);
     187             : 
     188             :             // prepare to iterate over the rectangles from the region in pixels
     189       27492 :             RectangleVector aRectangles;
     190       13746 :             aRegion.GetRegionRectangles(aRectangles);
     191             : 
     192       27873 :             for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
     193             :             {
     194             :                 // for each rectangle, save the area
     195       14127 :                 const Point aTopLeft(aRectIter->TopLeft());
     196       14127 :                 const Size aSize(aRectIter->GetSize());
     197             : 
     198       14127 :                 mpBufferDevice->DrawOutDev(
     199             :                     aTopLeft, aSize, // destination
     200             :                     aTopLeft, aSize, // source
     201       14127 :                     rSource);
     202             :             }
     203             : 
     204             :             // restore MapModes
     205       13746 :             rSource.EnableMapMode(bMapModeWasEnabledDest);
     206       27492 :             mpBufferDevice->EnableMapMode(bMapModeWasEnabledSource);
     207       13746 :         }
     208             : 
     209        1172 :         IMPL_LINK_NOARG_TYPED(OverlayManagerBuffered, ImpBufferTimerHandler, Idle*, void)
     210             :         {
     211             :             //Resolves: fdo#46728 ensure this exists until end of scope
     212         588 :             rtl::Reference<OverlayManager> xRef(this);
     213             : 
     214             :             // stop timer
     215         588 :             maBufferIdle.Stop();
     216             : 
     217         588 :             if(!maBufferRememberedRangePixel.isEmpty())
     218             :             {
     219             :                 // logic size for impDrawMember call
     220             :                 basegfx::B2DRange aBufferRememberedRangeLogic(
     221        1174 :                     maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
     222        1761 :                     maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
     223         587 :                 aBufferRememberedRangeLogic.transform(getOutputDevice().GetInverseViewTransformation());
     224             : 
     225             :                 // prepare cursor handling
     226         587 :                 const bool bTargetIsWindow(OUTDEV_WINDOW == mrOutputDevice.GetOutDevType());
     227         587 :                 bool bCursorWasEnabled(false);
     228             : 
     229             :                 // #i80730# switch off VCL cursor during overlay refresh
     230         587 :                 if(bTargetIsWindow)
     231             :                 {
     232         587 :                     vcl::Window& rWindow = static_cast< vcl::Window& >(mrOutputDevice);
     233         587 :                     vcl::Cursor* pCursor = rWindow.GetCursor();
     234             : 
     235         587 :                     if(pCursor && pCursor->IsVisible())
     236             :                     {
     237          83 :                         pCursor->Hide();
     238          83 :                         bCursorWasEnabled = true;
     239             :                     }
     240             :                 }
     241             : 
     242         587 :                 if(DoRefreshWithPreRendering())
     243             :                 {
     244             :                     // #i73602# ensure valid and sized mpOutputBufferDevice
     245         587 :                     const Size aDestinationSizePixel(mpBufferDevice->GetOutputSizePixel());
     246         587 :                     const Size aOutputBufferSizePixel(mpOutputBufferDevice->GetOutputSizePixel());
     247             : 
     248         587 :                     if(aDestinationSizePixel != aOutputBufferSizePixel)
     249             :                     {
     250          68 :                         mpOutputBufferDevice->SetOutputSizePixel(aDestinationSizePixel);
     251             :                     }
     252             : 
     253         587 :                     mpOutputBufferDevice->SetMapMode(getOutputDevice().GetMapMode());
     254         587 :                     mpOutputBufferDevice->EnableMapMode(false);
     255         587 :                     mpOutputBufferDevice->SetDrawMode(mpBufferDevice->GetDrawMode());
     256         587 :                     mpOutputBufferDevice->SetSettings(mpBufferDevice->GetSettings());
     257         587 :                     mpOutputBufferDevice->SetAntialiasing(mpBufferDevice->GetAntialiasing());
     258             : 
     259             :                     // calculate sizes
     260             :                     Rectangle aRegionRectanglePixel(
     261        1174 :                         maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(),
     262        1761 :                         maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY());
     263             : 
     264             :                     // truncate aRegionRectanglePixel to destination pixel size, more does
     265             :                     // not need to be prepared since destination is a buffer for a window. So,
     266             :                     // maximum size indirectly shall be limited to getOutputDevice().GetOutputSizePixel()
     267         587 :                     if(aRegionRectanglePixel.Left() < 0L)
     268             :                     {
     269         388 :                         aRegionRectanglePixel.Left() = 0L;
     270             :                     }
     271             : 
     272         587 :                     if(aRegionRectanglePixel.Top() < 0L)
     273             :                     {
     274         355 :                         aRegionRectanglePixel.Top() = 0L;
     275             :                     }
     276             : 
     277         587 :                     if(aRegionRectanglePixel.Right() > aDestinationSizePixel.getWidth())
     278             :                     {
     279         282 :                         aRegionRectanglePixel.Right() = aDestinationSizePixel.getWidth();
     280             :                     }
     281             : 
     282         587 :                     if(aRegionRectanglePixel.Bottom() > aDestinationSizePixel.getHeight())
     283             :                     {
     284         240 :                         aRegionRectanglePixel.Bottom() = aDestinationSizePixel.getHeight();
     285             :                     }
     286             : 
     287             :                     // get sizes
     288         587 :                     const Point aTopLeft(aRegionRectanglePixel.TopLeft());
     289         587 :                     const Size aSize(aRegionRectanglePixel.GetSize());
     290             : 
     291             :                     {
     292         587 :                         const bool bMapModeWasEnabledDest(mpBufferDevice->IsMapModeEnabled());
     293         587 :                         mpBufferDevice->EnableMapMode(false);
     294             : 
     295         587 :                         mpOutputBufferDevice->DrawOutDev(
     296             :                             aTopLeft, aSize, // destination
     297             :                             aTopLeft, aSize, // source
     298         587 :                             *mpBufferDevice.get());
     299             : 
     300             :                         // restore MapModes
     301         587 :                         mpBufferDevice->EnableMapMode(bMapModeWasEnabledDest);
     302             :                     }
     303             : 
     304             :                     // paint overlay content for remembered region, use
     305             :                     // method from base class directly
     306         587 :                     mpOutputBufferDevice->EnableMapMode(true);
     307         587 :                     OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, *mpOutputBufferDevice.get());
     308         587 :                     mpOutputBufferDevice->EnableMapMode(false);
     309             : 
     310             :                     // copy to output
     311             :                     {
     312         587 :                         const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled());
     313         587 :                         getOutputDevice().EnableMapMode(false);
     314             : 
     315         587 :                         getOutputDevice().DrawOutDev(
     316             :                             aTopLeft, aSize, // destination
     317             :                             aTopLeft, aSize, // source
     318         587 :                             *mpOutputBufferDevice.get());
     319             : 
     320             :                         // debug
     321             :                         /*getOutputDevice().SetLineColor(COL_RED);
     322             :                         getOutputDevice().SetFillColor();
     323             :                         getOutputDevice().DrawRect(Rectangle(aTopLeft, aSize));*/
     324             : 
     325             :                         // restore MapModes
     326         587 :                         getOutputDevice().EnableMapMode(bMapModeWasEnabledDest);
     327             :                     }
     328             :                 }
     329             :                 else
     330             :                 {
     331             :                     // Restore all rectangles for remembered region from buffer
     332           0 :                     ImpRestoreBackground();
     333             : 
     334             :                     // paint overlay content for remembered region, use
     335             :                     // method from base class directly
     336           0 :                     OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, getOutputDevice());
     337             :                 }
     338             : 
     339             :                 // VCL hack for transparent child windows
     340             :                 // Problem is e.g. a radiobuttion form control in life mode. The used window
     341             :                 // is a transparence vcl childwindow. This flag only allows the parent window to
     342             :                 // paint into the child windows area, but there is no mechanism which takes
     343             :                 // care for a repaint of the child window. A transparent child window is NOT
     344             :                 // a window which always keeps it's content consistent over the parent, but it's
     345             :                 // more like just a paint flag for the parent.
     346             :                 // To get the update, the windows in question are updated manulally here.
     347         587 :                 if(bTargetIsWindow)
     348             :                 {
     349         587 :                     vcl::Window& rWindow = static_cast< vcl::Window& >(mrOutputDevice);
     350             : 
     351             :                     const Rectangle aRegionRectanglePixel(
     352         587 :                         maBufferRememberedRangePixel.getMinX(),
     353         587 :                         maBufferRememberedRangePixel.getMinY(),
     354         587 :                         maBufferRememberedRangePixel.getMaxX(),
     355        2348 :                         maBufferRememberedRangePixel.getMaxY());
     356         587 :                     PaintTransparentChildren(rWindow, aRegionRectanglePixel);
     357             :                 }
     358             : 
     359             :                 // #i80730# restore visibility of VCL cursor
     360         587 :                 if(bCursorWasEnabled)
     361             :                 {
     362          83 :                     vcl::Window& rWindow = static_cast< vcl::Window& >(mrOutputDevice);
     363          83 :                     vcl::Cursor* pCursor = rWindow.GetCursor();
     364             : 
     365          83 :                     if(pCursor)
     366             :                     {
     367             :                         // check if cursor still exists. It may have been deleted from someone
     368          83 :                         pCursor->Show();
     369             :                     }
     370             :                 }
     371             : 
     372             :                 // forget remembered Region
     373         587 :                 maBufferRememberedRangePixel.reset();
     374         588 :             }
     375         588 :         }
     376             : 
     377        1303 :         OverlayManagerBuffered::OverlayManagerBuffered(
     378             :             OutputDevice& rOutputDevice,
     379             :             const SdrModel* pModel,
     380             :             bool bRefreshWithPreRendering)
     381             :         :   OverlayManager(rOutputDevice, pModel),
     382             :             mpBufferDevice(VclPtr<VirtualDevice>::Create()),
     383             :             mpOutputBufferDevice(VclPtr<VirtualDevice>::Create()),
     384        1303 :             mbRefreshWithPreRendering(bRefreshWithPreRendering)
     385             :         {
     386             :             // Init timer
     387        1303 :             maBufferIdle.SetPriority( SchedulerPriority::HIGH );
     388        1303 :             maBufferIdle.SetIdleHdl(LINK(this, OverlayManagerBuffered, ImpBufferTimerHandler));
     389        1303 :         }
     390             : 
     391        1303 :         rtl::Reference<OverlayManager> OverlayManagerBuffered::create(
     392             :             OutputDevice& rOutputDevice,
     393             :             const SdrModel* pModel,
     394             :             bool bRefreshWithPreRendering)
     395             :         {
     396             :             return rtl::Reference<OverlayManager>(new OverlayManagerBuffered(rOutputDevice,
     397             :                 pModel,
     398        1303 :                 bRefreshWithPreRendering));
     399             :         }
     400             : 
     401        3846 :         OverlayManagerBuffered::~OverlayManagerBuffered()
     402             :         {
     403             :             // Clear timer
     404        1282 :             maBufferIdle.Stop();
     405             : 
     406        1282 :             if(!maBufferRememberedRangePixel.isEmpty())
     407             :             {
     408             :                 // Restore all rectangles for remembered region from buffer
     409         240 :                 ImpRestoreBackground();
     410             :             }
     411        2564 :         }
     412             : 
     413       13746 :         void OverlayManagerBuffered::completeRedraw(const vcl::Region& rRegion, OutputDevice* pPreRenderDevice) const
     414             :         {
     415       13746 :             if(!rRegion.IsEmpty())
     416             :             {
     417             :                 // save new background
     418       13746 :                 const_cast<OverlayManagerBuffered*>(this)->ImpSaveBackground(rRegion, pPreRenderDevice);
     419             :             }
     420             : 
     421             :             // call parent
     422       13746 :             OverlayManager::completeRedraw(rRegion, pPreRenderDevice);
     423       13746 :         }
     424             : 
     425           4 :         void OverlayManagerBuffered::flush()
     426             :         {
     427             :             // call timer handler direct
     428           4 :             ImpBufferTimerHandler(0);
     429           4 :         }
     430             : 
     431             :         // #i68597# part of content gets copied, react on it
     432           0 :         void OverlayManagerBuffered::copyArea(const Point& rDestPt, const Point& rSrcPt, const Size& rSrcSize)
     433             :         {
     434             :             // scroll local buffered area
     435           0 :             mpBufferDevice->CopyArea(rDestPt, rSrcPt, rSrcSize);
     436           0 :         }
     437             : 
     438           0 :         void OverlayManagerBuffered::restoreBackground(const vcl::Region& rRegion) const
     439             :         {
     440             :             // restore
     441           0 :             const vcl::Region aRegionPixel(getOutputDevice().LogicToPixel(rRegion));
     442           0 :             ImpRestoreBackground(aRegionPixel);
     443             : 
     444             :             // call parent
     445           0 :             OverlayManager::restoreBackground(rRegion);
     446           0 :         }
     447             : 
     448       13257 :         void OverlayManagerBuffered::invalidateRange(const basegfx::B2DRange& rRange)
     449             :         {
     450       13257 :             if(!rRange.isEmpty())
     451             :             {
     452             :                 // buffered output, do not invalidate but use the timer
     453             :                 // to trigger a timer event for refresh
     454       13257 :                 maBufferIdle.Start();
     455             : 
     456             :                 // add the discrete range to the remembered region
     457             :                 // #i75163# use double precision and floor/ceil rounding to get overlapped pixel region, even
     458             :                 // when the given logic region has a width/height of 0.0. This does NOT work with LogicToPixel
     459             :                 // since it just transforms the top left and bottom right points equally without taking
     460             :                 // discrete pixel coverage into account. An empty B2DRange and thus empty logic Rectangle translated
     461             :                 // to an also empty discrete pixel rectangle - what is wrong.
     462       13257 :                 basegfx::B2DRange aDiscreteRange(rRange);
     463       13257 :                 aDiscreteRange.transform(getOutputDevice().GetViewTransformation());
     464             : 
     465       13257 :                 if(maDrawinglayerOpt.IsAntiAliasing())
     466             :                 {
     467             :                     // assume AA needs one pixel more and invalidate one pixel more
     468           0 :                     const double fDiscreteOne(getDiscreteOne());
     469             :                     const basegfx::B2IPoint aTopLeft(
     470           0 :                         (sal_Int32)floor(aDiscreteRange.getMinX() - fDiscreteOne),
     471           0 :                         (sal_Int32)floor(aDiscreteRange.getMinY() - fDiscreteOne));
     472             :                     const basegfx::B2IPoint aBottomRight(
     473           0 :                         (sal_Int32)ceil(aDiscreteRange.getMaxX() + fDiscreteOne),
     474           0 :                         (sal_Int32)ceil(aDiscreteRange.getMaxY() + fDiscreteOne));
     475             : 
     476           0 :                     maBufferRememberedRangePixel.expand(aTopLeft);
     477           0 :                     maBufferRememberedRangePixel.expand(aBottomRight);
     478             :                 }
     479             :                 else
     480             :                 {
     481       13257 :                     const basegfx::B2IPoint aTopLeft((sal_Int32)floor(aDiscreteRange.getMinX()), (sal_Int32)floor(aDiscreteRange.getMinY()));
     482       26514 :                     const basegfx::B2IPoint aBottomRight((sal_Int32)ceil(aDiscreteRange.getMaxX()), (sal_Int32)ceil(aDiscreteRange.getMaxY()));
     483             : 
     484       13257 :                     maBufferRememberedRangePixel.expand(aTopLeft);
     485       26514 :                     maBufferRememberedRangePixel.expand(aBottomRight);
     486             :                 }
     487             :             }
     488       13257 :         }
     489             :     } // end of namespace overlay
     490             : } // end of namespace sdr
     491             : 
     492             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11