1*f6e50924SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*f6e50924SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*f6e50924SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*f6e50924SAndrew Rist * distributed with this work for additional information 6*f6e50924SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*f6e50924SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*f6e50924SAndrew Rist * "License"); you may not use this file except in compliance 9*f6e50924SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*f6e50924SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*f6e50924SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*f6e50924SAndrew Rist * software distributed under the License is distributed on an 15*f6e50924SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*f6e50924SAndrew Rist * KIND, either express or implied. See the License for the 17*f6e50924SAndrew Rist * specific language governing permissions and limitations 18*f6e50924SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*f6e50924SAndrew Rist *************************************************************/ 21*f6e50924SAndrew Rist 22*f6e50924SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_svx.hxx" 26cdf0e10cSrcweir #include <svx/sdr/overlay/overlaymanagerbuffered.hxx> 27cdf0e10cSrcweir #include <vcl/outdev.hxx> 28cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx> 29cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx> 30cdf0e10cSrcweir #include <vcl/salbtype.hxx> 31cdf0e10cSrcweir #include <vcl/window.hxx> 32cdf0e10cSrcweir #include <vcl/bitmap.hxx> 33cdf0e10cSrcweir #include <tools/stream.hxx> 34cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx> 35cdf0e10cSrcweir #include <vcl/cursor.hxx> 36cdf0e10cSrcweir 37cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 38cdf0e10cSrcweir 39cdf0e10cSrcweir namespace sdr 40cdf0e10cSrcweir { 41cdf0e10cSrcweir namespace overlay 42cdf0e10cSrcweir { 43cdf0e10cSrcweir void OverlayManagerBuffered::ImpPrepareBufferDevice() 44cdf0e10cSrcweir { 45cdf0e10cSrcweir // compare size of maBufferDevice with size of visible area 46cdf0e10cSrcweir if(maBufferDevice.GetOutputSizePixel() != getOutputDevice().GetOutputSizePixel()) 47cdf0e10cSrcweir { 48cdf0e10cSrcweir // set new buffer size, copy as much content as possible (use bool parameter for vcl). 49cdf0e10cSrcweir // Newly uncovered regions will be repainted. 50cdf0e10cSrcweir maBufferDevice.SetOutputSizePixel(getOutputDevice().GetOutputSizePixel(), false); 51cdf0e10cSrcweir } 52cdf0e10cSrcweir 53cdf0e10cSrcweir // compare the MapModes for zoom/scroll changes 54cdf0e10cSrcweir if(maBufferDevice.GetMapMode() != getOutputDevice().GetMapMode()) 55cdf0e10cSrcweir { 56cdf0e10cSrcweir const bool bZoomed( 57cdf0e10cSrcweir maBufferDevice.GetMapMode().GetScaleX() != getOutputDevice().GetMapMode().GetScaleX() 58cdf0e10cSrcweir || maBufferDevice.GetMapMode().GetScaleY() != getOutputDevice().GetMapMode().GetScaleY()); 59cdf0e10cSrcweir 60cdf0e10cSrcweir if(!bZoomed) 61cdf0e10cSrcweir { 62cdf0e10cSrcweir const Point& rOriginOld = maBufferDevice.GetMapMode().GetOrigin(); 63cdf0e10cSrcweir const Point& rOriginNew = getOutputDevice().GetMapMode().GetOrigin(); 64cdf0e10cSrcweir const bool bScrolled(rOriginOld != rOriginNew); 65cdf0e10cSrcweir 66cdf0e10cSrcweir if(bScrolled) 67cdf0e10cSrcweir { 68cdf0e10cSrcweir // get pixel bounds 69cdf0e10cSrcweir const Point aOriginOldPixel(maBufferDevice.LogicToPixel(rOriginOld)); 70cdf0e10cSrcweir const Point aOriginNewPixel(maBufferDevice.LogicToPixel(rOriginNew)); 71cdf0e10cSrcweir const Size aOutputSizePixel(maBufferDevice.GetOutputSizePixel()); 72cdf0e10cSrcweir 73cdf0e10cSrcweir // remember and switch off MapMode 74cdf0e10cSrcweir const bool bMapModeWasEnabled(maBufferDevice.IsMapModeEnabled()); 75cdf0e10cSrcweir maBufferDevice.EnableMapMode(false); 76cdf0e10cSrcweir 77cdf0e10cSrcweir // scroll internally buffered stuff 78cdf0e10cSrcweir const Point aDestinationOffsetPixel(aOriginNewPixel - aOriginOldPixel); 79cdf0e10cSrcweir maBufferDevice.DrawOutDev( 80cdf0e10cSrcweir aDestinationOffsetPixel, aOutputSizePixel, // destination 81cdf0e10cSrcweir Point(), aOutputSizePixel); // source 82cdf0e10cSrcweir 83cdf0e10cSrcweir // restore MapMode 84cdf0e10cSrcweir maBufferDevice.EnableMapMode(bMapModeWasEnabled); 85cdf0e10cSrcweir 86cdf0e10cSrcweir // scroll remembered region, too. 87cdf0e10cSrcweir if(!maBufferRememberedRangePixel.isEmpty()) 88cdf0e10cSrcweir { 89cdf0e10cSrcweir const basegfx::B2IPoint aIPointDestinationOffsetPixel(aDestinationOffsetPixel.X(), aDestinationOffsetPixel.Y()); 90cdf0e10cSrcweir const basegfx::B2IPoint aNewMinimum(maBufferRememberedRangePixel.getMinimum() + aIPointDestinationOffsetPixel); 91cdf0e10cSrcweir const basegfx::B2IPoint aNewMaximum(maBufferRememberedRangePixel.getMaximum() + aIPointDestinationOffsetPixel); 92cdf0e10cSrcweir maBufferRememberedRangePixel = basegfx::B2IRange(aNewMinimum, aNewMaximum); 93cdf0e10cSrcweir } 94cdf0e10cSrcweir } 95cdf0e10cSrcweir } 96cdf0e10cSrcweir 97cdf0e10cSrcweir // copy new MapMode 98cdf0e10cSrcweir maBufferDevice.SetMapMode(getOutputDevice().GetMapMode()); 99cdf0e10cSrcweir } 100cdf0e10cSrcweir 101cdf0e10cSrcweir // #i29186# 102cdf0e10cSrcweir maBufferDevice.SetDrawMode(getOutputDevice().GetDrawMode()); 103cdf0e10cSrcweir maBufferDevice.SetSettings(getOutputDevice().GetSettings()); 104cdf0e10cSrcweir maBufferDevice.SetAntialiasing(getOutputDevice().GetAntialiasing()); 105cdf0e10cSrcweir } 106cdf0e10cSrcweir 107cdf0e10cSrcweir void OverlayManagerBuffered::ImpRestoreBackground() const 108cdf0e10cSrcweir { 109cdf0e10cSrcweir const Rectangle aRegionRectanglePixel( 110cdf0e10cSrcweir maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(), 111cdf0e10cSrcweir maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY()); 112cdf0e10cSrcweir const Region aRegionPixel(aRegionRectanglePixel); 113cdf0e10cSrcweir 114cdf0e10cSrcweir ImpRestoreBackground(aRegionPixel); 115cdf0e10cSrcweir } 116cdf0e10cSrcweir 117cdf0e10cSrcweir void OverlayManagerBuffered::ImpRestoreBackground(const Region& rRegionPixel) const 118cdf0e10cSrcweir { 119cdf0e10cSrcweir // local region 120cdf0e10cSrcweir Region aRegionPixel(rRegionPixel); 121cdf0e10cSrcweir RegionHandle aRegionHandle(aRegionPixel.BeginEnumRects()); 122cdf0e10cSrcweir Rectangle aRegionRectanglePixel; 123cdf0e10cSrcweir 124cdf0e10cSrcweir // MapModes off 125cdf0e10cSrcweir const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled()); 126cdf0e10cSrcweir const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled()); 127cdf0e10cSrcweir getOutputDevice().EnableMapMode(false); 128cdf0e10cSrcweir ((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(false); 129cdf0e10cSrcweir 130cdf0e10cSrcweir while(aRegionPixel.GetEnumRects(aRegionHandle, aRegionRectanglePixel)) 131cdf0e10cSrcweir { 132cdf0e10cSrcweir #ifdef DBG_UTIL 133cdf0e10cSrcweir // #i72754# possible graphical region test only with non-pro 134cdf0e10cSrcweir static bool bDoPaintForVisualControl(false); 135cdf0e10cSrcweir if(bDoPaintForVisualControl) 136cdf0e10cSrcweir { 137cdf0e10cSrcweir getOutputDevice().SetLineColor(COL_LIGHTGREEN); 138cdf0e10cSrcweir getOutputDevice().SetFillColor(); 139cdf0e10cSrcweir getOutputDevice().DrawRect(aRegionRectanglePixel); 140cdf0e10cSrcweir } 141cdf0e10cSrcweir #endif 142cdf0e10cSrcweir 143cdf0e10cSrcweir // restore the area 144cdf0e10cSrcweir const Point aTopLeft(aRegionRectanglePixel.TopLeft()); 145cdf0e10cSrcweir const Size aSize(aRegionRectanglePixel.GetSize()); 146cdf0e10cSrcweir 147cdf0e10cSrcweir getOutputDevice().DrawOutDev( 148cdf0e10cSrcweir aTopLeft, aSize, // destination 149cdf0e10cSrcweir aTopLeft, aSize, // source 150cdf0e10cSrcweir maBufferDevice); 151cdf0e10cSrcweir } 152cdf0e10cSrcweir 153cdf0e10cSrcweir aRegionPixel.EndEnumRects(aRegionHandle); 154cdf0e10cSrcweir 155cdf0e10cSrcweir // restore MapModes 156cdf0e10cSrcweir getOutputDevice().EnableMapMode(bMapModeWasEnabledDest); 157cdf0e10cSrcweir ((OverlayManagerBuffered*)this)->maBufferDevice.EnableMapMode(bMapModeWasEnabledSource); 158cdf0e10cSrcweir } 159cdf0e10cSrcweir 160cdf0e10cSrcweir void OverlayManagerBuffered::ImpSaveBackground(const Region& rRegion, OutputDevice* pPreRenderDevice) 161cdf0e10cSrcweir { 162cdf0e10cSrcweir // prepare source 163cdf0e10cSrcweir OutputDevice& rSource = (pPreRenderDevice) ? *pPreRenderDevice : getOutputDevice(); 164cdf0e10cSrcweir 165cdf0e10cSrcweir // Ensure buffer is valid 166cdf0e10cSrcweir ImpPrepareBufferDevice(); 167cdf0e10cSrcweir 168cdf0e10cSrcweir // build region which needs to be copied 169cdf0e10cSrcweir Region aRegion(rSource.LogicToPixel(rRegion)); 170cdf0e10cSrcweir 171cdf0e10cSrcweir // limit to PaintRegion if it's a window. This will be evtl. the expanded one, 172cdf0e10cSrcweir // but always the exact redraw area 173cdf0e10cSrcweir if(OUTDEV_WINDOW == rSource.GetOutDevType()) 174cdf0e10cSrcweir { 175cdf0e10cSrcweir Window& rWindow = (Window&)rSource; 176cdf0e10cSrcweir Region aPaintRegionPixel = rWindow.LogicToPixel(rWindow.GetPaintRegion()); 177cdf0e10cSrcweir aRegion.Intersect(aPaintRegionPixel); 178cdf0e10cSrcweir 179cdf0e10cSrcweir // #i72754# Make sure content is completetly rendered, the window 180cdf0e10cSrcweir // will be used as source of a DrawOutDev soon 181cdf0e10cSrcweir rWindow.Flush(); 182cdf0e10cSrcweir } 183cdf0e10cSrcweir 184cdf0e10cSrcweir // also limit to buffer size 185cdf0e10cSrcweir const Rectangle aBufferDeviceRectanglePixel = Rectangle(Point(), maBufferDevice.GetOutputSizePixel()); 186cdf0e10cSrcweir aRegion.Intersect(aBufferDeviceRectanglePixel); 187cdf0e10cSrcweir 188cdf0e10cSrcweir // prepare to iterate over the rectangles from the region in pixels 189cdf0e10cSrcweir RegionHandle aRegionHandle(aRegion.BeginEnumRects()); 190cdf0e10cSrcweir Rectangle aRegionRectanglePixel; 191cdf0e10cSrcweir 192cdf0e10cSrcweir // MapModes off 193cdf0e10cSrcweir const bool bMapModeWasEnabledDest(rSource.IsMapModeEnabled()); 194cdf0e10cSrcweir const bool bMapModeWasEnabledSource(maBufferDevice.IsMapModeEnabled()); 195cdf0e10cSrcweir rSource.EnableMapMode(false); 196cdf0e10cSrcweir maBufferDevice.EnableMapMode(false); 197cdf0e10cSrcweir 198cdf0e10cSrcweir while(aRegion.GetEnumRects(aRegionHandle, aRegionRectanglePixel)) 199cdf0e10cSrcweir { 200cdf0e10cSrcweir // for each rectangle, save the area 201cdf0e10cSrcweir Point aTopLeft(aRegionRectanglePixel.TopLeft()); 202cdf0e10cSrcweir Size aSize(aRegionRectanglePixel.GetSize()); 203cdf0e10cSrcweir 204cdf0e10cSrcweir maBufferDevice.DrawOutDev( 205cdf0e10cSrcweir aTopLeft, aSize, // destination 206cdf0e10cSrcweir aTopLeft, aSize, // source 207cdf0e10cSrcweir rSource); 208cdf0e10cSrcweir 209cdf0e10cSrcweir #ifdef DBG_UTIL 210cdf0e10cSrcweir // #i72754# possible graphical region test only with non-pro 211cdf0e10cSrcweir static bool bDoPaintForVisualControl(false); 212cdf0e10cSrcweir if(bDoPaintForVisualControl) 213cdf0e10cSrcweir { 214cdf0e10cSrcweir const bool bMapModeWasEnabledTest(getOutputDevice().IsMapModeEnabled()); 215cdf0e10cSrcweir getOutputDevice().EnableMapMode(false); 216cdf0e10cSrcweir getOutputDevice().SetLineColor(COL_LIGHTRED); 217cdf0e10cSrcweir getOutputDevice().SetFillColor(); 218cdf0e10cSrcweir getOutputDevice().DrawRect(aRegionRectanglePixel); 219cdf0e10cSrcweir getOutputDevice().EnableMapMode(bMapModeWasEnabledTest); 220cdf0e10cSrcweir } 221cdf0e10cSrcweir 222cdf0e10cSrcweir static bool bDoSaveForVisualControl(false); 223cdf0e10cSrcweir if(bDoSaveForVisualControl) 224cdf0e10cSrcweir { 225cdf0e10cSrcweir const Bitmap aBitmap(maBufferDevice.GetBitmap(aTopLeft, aSize)); 226cdf0e10cSrcweir SvFileStream aNew((const String&)String(ByteString( "c:\\test.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC); 227cdf0e10cSrcweir aNew << aBitmap; 228cdf0e10cSrcweir } 229cdf0e10cSrcweir #endif 230cdf0e10cSrcweir } 231cdf0e10cSrcweir 232cdf0e10cSrcweir aRegion.EndEnumRects(aRegionHandle); 233cdf0e10cSrcweir 234cdf0e10cSrcweir // restore MapModes 235cdf0e10cSrcweir rSource.EnableMapMode(bMapModeWasEnabledDest); 236cdf0e10cSrcweir maBufferDevice.EnableMapMode(bMapModeWasEnabledSource); 237cdf0e10cSrcweir } 238cdf0e10cSrcweir 239cdf0e10cSrcweir IMPL_LINK(OverlayManagerBuffered, ImpBufferTimerHandler, AutoTimer*, /*pTimer*/) 240cdf0e10cSrcweir { 241cdf0e10cSrcweir // stop timer 242cdf0e10cSrcweir maBufferTimer.Stop(); 243cdf0e10cSrcweir 244cdf0e10cSrcweir if(!maBufferRememberedRangePixel.isEmpty()) 245cdf0e10cSrcweir { 246cdf0e10cSrcweir // logic size for impDrawMember call 247cdf0e10cSrcweir basegfx::B2DRange aBufferRememberedRangeLogic( 248cdf0e10cSrcweir maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(), 249cdf0e10cSrcweir maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY()); 250cdf0e10cSrcweir aBufferRememberedRangeLogic.transform(getOutputDevice().GetInverseViewTransformation()); 251cdf0e10cSrcweir 252cdf0e10cSrcweir // prepare cursor handling 253cdf0e10cSrcweir const bool bTargetIsWindow(OUTDEV_WINDOW == rmOutputDevice.GetOutDevType()); 254cdf0e10cSrcweir bool bCursorWasEnabled(false); 255cdf0e10cSrcweir 256cdf0e10cSrcweir // #i80730# switch off VCL cursor during overlay refresh 257cdf0e10cSrcweir if(bTargetIsWindow) 258cdf0e10cSrcweir { 259cdf0e10cSrcweir Window& rWindow = static_cast< Window& >(rmOutputDevice); 260cdf0e10cSrcweir Cursor* pCursor = rWindow.GetCursor(); 261cdf0e10cSrcweir 262cdf0e10cSrcweir if(pCursor && pCursor->IsVisible()) 263cdf0e10cSrcweir { 264cdf0e10cSrcweir pCursor->Hide(); 265cdf0e10cSrcweir bCursorWasEnabled = true; 266cdf0e10cSrcweir } 267cdf0e10cSrcweir } 268cdf0e10cSrcweir 269cdf0e10cSrcweir if(DoRefreshWithPreRendering()) 270cdf0e10cSrcweir { 271cdf0e10cSrcweir // #i73602# ensure valid and sized maOutputBufferDevice 272cdf0e10cSrcweir const Size aDestinationSizePixel(maBufferDevice.GetOutputSizePixel()); 273cdf0e10cSrcweir const Size aOutputBufferSizePixel(maOutputBufferDevice.GetOutputSizePixel()); 274cdf0e10cSrcweir 275cdf0e10cSrcweir if(aDestinationSizePixel != aOutputBufferSizePixel) 276cdf0e10cSrcweir { 277cdf0e10cSrcweir maOutputBufferDevice.SetOutputSizePixel(aDestinationSizePixel); 278cdf0e10cSrcweir } 279cdf0e10cSrcweir 280cdf0e10cSrcweir maOutputBufferDevice.SetMapMode(getOutputDevice().GetMapMode()); 281cdf0e10cSrcweir maOutputBufferDevice.EnableMapMode(false); 282cdf0e10cSrcweir maOutputBufferDevice.SetDrawMode(maBufferDevice.GetDrawMode()); 283cdf0e10cSrcweir maOutputBufferDevice.SetSettings(maBufferDevice.GetSettings()); 284cdf0e10cSrcweir maOutputBufferDevice.SetAntialiasing(maBufferDevice.GetAntialiasing()); 285cdf0e10cSrcweir 286cdf0e10cSrcweir // calculate sizes 287cdf0e10cSrcweir Rectangle aRegionRectanglePixel( 288cdf0e10cSrcweir maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(), 289cdf0e10cSrcweir maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY()); 290cdf0e10cSrcweir 291cdf0e10cSrcweir // truncate aRegionRectanglePixel to destination pixel size, more does 292cdf0e10cSrcweir // not need to be prepared since destination is a buffer for a window. So, 293cdf0e10cSrcweir // maximum size indirectly shall be limited to getOutputDevice().GetOutputSizePixel() 294cdf0e10cSrcweir if(aRegionRectanglePixel.Left() < 0L) 295cdf0e10cSrcweir { 296cdf0e10cSrcweir aRegionRectanglePixel.Left() = 0L; 297cdf0e10cSrcweir } 298cdf0e10cSrcweir 299cdf0e10cSrcweir if(aRegionRectanglePixel.Top() < 0L) 300cdf0e10cSrcweir { 301cdf0e10cSrcweir aRegionRectanglePixel.Top() = 0L; 302cdf0e10cSrcweir } 303cdf0e10cSrcweir 304cdf0e10cSrcweir if(aRegionRectanglePixel.Right() > aDestinationSizePixel.getWidth()) 305cdf0e10cSrcweir { 306cdf0e10cSrcweir aRegionRectanglePixel.Right() = aDestinationSizePixel.getWidth(); 307cdf0e10cSrcweir } 308cdf0e10cSrcweir 309cdf0e10cSrcweir if(aRegionRectanglePixel.Bottom() > aDestinationSizePixel.getHeight()) 310cdf0e10cSrcweir { 311cdf0e10cSrcweir aRegionRectanglePixel.Bottom() = aDestinationSizePixel.getHeight(); 312cdf0e10cSrcweir } 313cdf0e10cSrcweir 314cdf0e10cSrcweir // get sizes 315cdf0e10cSrcweir const Point aTopLeft(aRegionRectanglePixel.TopLeft()); 316cdf0e10cSrcweir const Size aSize(aRegionRectanglePixel.GetSize()); 317cdf0e10cSrcweir 318cdf0e10cSrcweir { 319cdf0e10cSrcweir const bool bMapModeWasEnabledDest(maBufferDevice.IsMapModeEnabled()); 320cdf0e10cSrcweir maBufferDevice.EnableMapMode(false); 321cdf0e10cSrcweir 322cdf0e10cSrcweir maOutputBufferDevice.DrawOutDev( 323cdf0e10cSrcweir aTopLeft, aSize, // destination 324cdf0e10cSrcweir aTopLeft, aSize, // source 325cdf0e10cSrcweir maBufferDevice); 326cdf0e10cSrcweir 327cdf0e10cSrcweir // restore MapModes 328cdf0e10cSrcweir maBufferDevice.EnableMapMode(bMapModeWasEnabledDest); 329cdf0e10cSrcweir } 330cdf0e10cSrcweir 331cdf0e10cSrcweir // paint overlay content for remembered region, use 332cdf0e10cSrcweir // method from base class directly 333cdf0e10cSrcweir maOutputBufferDevice.EnableMapMode(true); 334cdf0e10cSrcweir OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, maOutputBufferDevice); 335cdf0e10cSrcweir maOutputBufferDevice.EnableMapMode(false); 336cdf0e10cSrcweir 337cdf0e10cSrcweir // copy to output 338cdf0e10cSrcweir { 339cdf0e10cSrcweir const bool bMapModeWasEnabledDest(getOutputDevice().IsMapModeEnabled()); 340cdf0e10cSrcweir getOutputDevice().EnableMapMode(false); 341cdf0e10cSrcweir 342cdf0e10cSrcweir getOutputDevice().DrawOutDev( 343cdf0e10cSrcweir aTopLeft, aSize, // destination 344cdf0e10cSrcweir aTopLeft, aSize, // source 345cdf0e10cSrcweir maOutputBufferDevice); 346cdf0e10cSrcweir 347cdf0e10cSrcweir // debug 348cdf0e10cSrcweir /*getOutputDevice().SetLineColor(COL_RED); 349cdf0e10cSrcweir getOutputDevice().SetFillColor(); 350cdf0e10cSrcweir getOutputDevice().DrawRect(Rectangle(aTopLeft, aSize));*/ 351cdf0e10cSrcweir 352cdf0e10cSrcweir // restore MapModes 353cdf0e10cSrcweir getOutputDevice().EnableMapMode(bMapModeWasEnabledDest); 354cdf0e10cSrcweir } 355cdf0e10cSrcweir } 356cdf0e10cSrcweir else 357cdf0e10cSrcweir { 358cdf0e10cSrcweir // Restore all rectangles for remembered region from buffer 359cdf0e10cSrcweir ImpRestoreBackground(); 360cdf0e10cSrcweir 361cdf0e10cSrcweir // paint overlay content for remembered region, use 362cdf0e10cSrcweir // method from base class directly 363cdf0e10cSrcweir OverlayManager::ImpDrawMembers(aBufferRememberedRangeLogic, getOutputDevice()); 364cdf0e10cSrcweir } 365cdf0e10cSrcweir 366cdf0e10cSrcweir // VCL hack for transparent child windows 367cdf0e10cSrcweir // Problem is e.g. a radiobuttion form control in life mode. The used window 368cdf0e10cSrcweir // is a transparence vcl childwindow. This flag only allows the parent window to 369cdf0e10cSrcweir // paint into the child windows area, but there is no mechanism which takes 370cdf0e10cSrcweir // care for a repaint of the child window. A transparent child window is NOT 371cdf0e10cSrcweir // a window which always keeps it's content consistent over the parent, but it's 372cdf0e10cSrcweir // more like just a paint flag for the parent. 373cdf0e10cSrcweir // To get the update, the windows in question are updated manulally here. 374cdf0e10cSrcweir if(bTargetIsWindow) 375cdf0e10cSrcweir { 376cdf0e10cSrcweir Window& rWindow = static_cast< Window& >(rmOutputDevice); 377cdf0e10cSrcweir 378cdf0e10cSrcweir if(rWindow.IsChildTransparentModeEnabled() && rWindow.GetChildCount()) 379cdf0e10cSrcweir { 380cdf0e10cSrcweir const Rectangle aRegionRectanglePixel( 381cdf0e10cSrcweir maBufferRememberedRangePixel.getMinX(), maBufferRememberedRangePixel.getMinY(), 382cdf0e10cSrcweir maBufferRememberedRangePixel.getMaxX(), maBufferRememberedRangePixel.getMaxY()); 383cdf0e10cSrcweir 384cdf0e10cSrcweir for(sal_uInt16 a(0); a < rWindow.GetChildCount(); a++) 385cdf0e10cSrcweir { 386cdf0e10cSrcweir Window* pCandidate = rWindow.GetChild(a); 387cdf0e10cSrcweir 388cdf0e10cSrcweir if(pCandidate && pCandidate->IsPaintTransparent()) 389cdf0e10cSrcweir { 390cdf0e10cSrcweir const Rectangle aCandidatePosSizePixel(pCandidate->GetPosPixel(), pCandidate->GetSizePixel()); 391cdf0e10cSrcweir 392cdf0e10cSrcweir if(aCandidatePosSizePixel.IsOver(aRegionRectanglePixel)) 393cdf0e10cSrcweir { 394cdf0e10cSrcweir pCandidate->Invalidate(INVALIDATE_NOTRANSPARENT|INVALIDATE_CHILDREN); 395cdf0e10cSrcweir pCandidate->Update(); 396cdf0e10cSrcweir } 397cdf0e10cSrcweir } 398cdf0e10cSrcweir } 399cdf0e10cSrcweir } 400cdf0e10cSrcweir } 401cdf0e10cSrcweir 402cdf0e10cSrcweir // #i80730# restore visibility of VCL cursor 403cdf0e10cSrcweir if(bCursorWasEnabled) 404cdf0e10cSrcweir { 405cdf0e10cSrcweir Window& rWindow = static_cast< Window& >(rmOutputDevice); 406cdf0e10cSrcweir Cursor* pCursor = rWindow.GetCursor(); 407cdf0e10cSrcweir 408cdf0e10cSrcweir if(pCursor) 409cdf0e10cSrcweir { 410cdf0e10cSrcweir // check if cursor still exists. It may have been deleted from someone 411cdf0e10cSrcweir pCursor->Show(); 412cdf0e10cSrcweir } 413cdf0e10cSrcweir } 414cdf0e10cSrcweir 415cdf0e10cSrcweir // forget remembered Region 416cdf0e10cSrcweir maBufferRememberedRangePixel.reset(); 417cdf0e10cSrcweir } 418cdf0e10cSrcweir 419cdf0e10cSrcweir return 0; 420cdf0e10cSrcweir } 421cdf0e10cSrcweir 422cdf0e10cSrcweir OverlayManagerBuffered::OverlayManagerBuffered( 423cdf0e10cSrcweir OutputDevice& rOutputDevice, 424cdf0e10cSrcweir OverlayManager* pOldOverlayManager, 425cdf0e10cSrcweir bool bRefreshWithPreRendering) 426cdf0e10cSrcweir : OverlayManager(rOutputDevice, pOldOverlayManager), 427cdf0e10cSrcweir mbRefreshWithPreRendering(bRefreshWithPreRendering) 428cdf0e10cSrcweir { 429cdf0e10cSrcweir // Init timer 430cdf0e10cSrcweir maBufferTimer.SetTimeout(1); 431cdf0e10cSrcweir maBufferTimer.SetTimeoutHdl(LINK(this, OverlayManagerBuffered, ImpBufferTimerHandler)); 432cdf0e10cSrcweir } 433cdf0e10cSrcweir 434cdf0e10cSrcweir OverlayManagerBuffered::~OverlayManagerBuffered() 435cdf0e10cSrcweir { 436cdf0e10cSrcweir // Clear timer 437cdf0e10cSrcweir maBufferTimer.Stop(); 438cdf0e10cSrcweir 439cdf0e10cSrcweir if(!maBufferRememberedRangePixel.isEmpty()) 440cdf0e10cSrcweir { 441cdf0e10cSrcweir // Restore all rectangles for remembered region from buffer 442cdf0e10cSrcweir ImpRestoreBackground(); 443cdf0e10cSrcweir } 444cdf0e10cSrcweir } 445cdf0e10cSrcweir 446cdf0e10cSrcweir void OverlayManagerBuffered::completeRedraw(const Region& rRegion, OutputDevice* pPreRenderDevice) const 447cdf0e10cSrcweir { 448cdf0e10cSrcweir if(!rRegion.IsEmpty()) 449cdf0e10cSrcweir { 450cdf0e10cSrcweir // save new background 451cdf0e10cSrcweir ((OverlayManagerBuffered*)this)->ImpSaveBackground(rRegion, pPreRenderDevice); 452cdf0e10cSrcweir } 453cdf0e10cSrcweir 454cdf0e10cSrcweir // call parent 455cdf0e10cSrcweir OverlayManager::completeRedraw(rRegion, pPreRenderDevice); 456cdf0e10cSrcweir } 457cdf0e10cSrcweir 458cdf0e10cSrcweir void OverlayManagerBuffered::flush() 459cdf0e10cSrcweir { 460cdf0e10cSrcweir // call timer handler direct 461cdf0e10cSrcweir ImpBufferTimerHandler(0); 462cdf0e10cSrcweir } 463cdf0e10cSrcweir 464cdf0e10cSrcweir // #i68597# part of content gets copied, react on it 465cdf0e10cSrcweir void OverlayManagerBuffered::copyArea(const Point& rDestPt, const Point& rSrcPt, const Size& rSrcSize) 466cdf0e10cSrcweir { 467cdf0e10cSrcweir // scroll local buffered area 468cdf0e10cSrcweir maBufferDevice.CopyArea(rDestPt, rSrcPt, rSrcSize); 469cdf0e10cSrcweir } 470cdf0e10cSrcweir 471cdf0e10cSrcweir void OverlayManagerBuffered::restoreBackground(const Region& rRegion) const 472cdf0e10cSrcweir { 473cdf0e10cSrcweir // restore 474cdf0e10cSrcweir const Region aRegionPixel(getOutputDevice().LogicToPixel(rRegion)); 475cdf0e10cSrcweir ImpRestoreBackground(aRegionPixel); 476cdf0e10cSrcweir 477cdf0e10cSrcweir // call parent 478cdf0e10cSrcweir OverlayManager::restoreBackground(rRegion); 479cdf0e10cSrcweir } 480cdf0e10cSrcweir 481cdf0e10cSrcweir void OverlayManagerBuffered::invalidateRange(const basegfx::B2DRange& rRange) 482cdf0e10cSrcweir { 483cdf0e10cSrcweir if(!rRange.isEmpty()) 484cdf0e10cSrcweir { 485cdf0e10cSrcweir // buffered output, do not invalidate but use the timer 486cdf0e10cSrcweir // to trigger a timer event for refresh 487cdf0e10cSrcweir maBufferTimer.Start(); 488cdf0e10cSrcweir 489cdf0e10cSrcweir // add the discrete range to the remembered region 490cdf0e10cSrcweir // #i75163# use double precision and floor/ceil rounding to get overlapped pixel region, even 491cdf0e10cSrcweir // when the given logic region has a width/height of 0.0. This does NOT work with LogicToPixel 492cdf0e10cSrcweir // since it just transforms the top left and bottom right points equally without taking 493cdf0e10cSrcweir // discrete pixel coverage into account. An empty B2DRange and thus empty logic Rectangle translated 494cdf0e10cSrcweir // to an also empty discrete pixel rectangle - what is wrong. 495cdf0e10cSrcweir basegfx::B2DRange aDiscreteRange(rRange); 496cdf0e10cSrcweir aDiscreteRange.transform(getOutputDevice().GetViewTransformation()); 497cdf0e10cSrcweir 498cdf0e10cSrcweir if(maDrawinglayerOpt.IsAntiAliasing()) 499cdf0e10cSrcweir { 500cdf0e10cSrcweir // assume AA needs one pixel more and invalidate one pixel more 501cdf0e10cSrcweir const double fDiscreteOne(getDiscreteOne()); 502cdf0e10cSrcweir const basegfx::B2IPoint aTopLeft( 503cdf0e10cSrcweir (sal_Int32)floor(aDiscreteRange.getMinX() - fDiscreteOne), 504cdf0e10cSrcweir (sal_Int32)floor(aDiscreteRange.getMinY() - fDiscreteOne)); 505cdf0e10cSrcweir const basegfx::B2IPoint aBottomRight( 506cdf0e10cSrcweir (sal_Int32)ceil(aDiscreteRange.getMaxX() + fDiscreteOne), 507cdf0e10cSrcweir (sal_Int32)ceil(aDiscreteRange.getMaxY() + fDiscreteOne)); 508cdf0e10cSrcweir 509cdf0e10cSrcweir maBufferRememberedRangePixel.expand(aTopLeft); 510cdf0e10cSrcweir maBufferRememberedRangePixel.expand(aBottomRight); 511cdf0e10cSrcweir } 512cdf0e10cSrcweir else 513cdf0e10cSrcweir { 514cdf0e10cSrcweir const basegfx::B2IPoint aTopLeft((sal_Int32)floor(aDiscreteRange.getMinX()), (sal_Int32)floor(aDiscreteRange.getMinY())); 515cdf0e10cSrcweir const basegfx::B2IPoint aBottomRight((sal_Int32)ceil(aDiscreteRange.getMaxX()), (sal_Int32)ceil(aDiscreteRange.getMaxY())); 516cdf0e10cSrcweir 517cdf0e10cSrcweir maBufferRememberedRangePixel.expand(aTopLeft); 518cdf0e10cSrcweir maBufferRememberedRangePixel.expand(aBottomRight); 519cdf0e10cSrcweir } 520cdf0e10cSrcweir } 521cdf0e10cSrcweir } 522cdf0e10cSrcweir 523cdf0e10cSrcweir void OverlayManagerBuffered::SetRefreshWithPreRendering(bool bNew) 524cdf0e10cSrcweir { 525cdf0e10cSrcweir if((bool)mbRefreshWithPreRendering != bNew) 526cdf0e10cSrcweir { 527cdf0e10cSrcweir mbRefreshWithPreRendering = bNew; 528cdf0e10cSrcweir } 529cdf0e10cSrcweir } 530cdf0e10cSrcweir } // end of namespace overlay 531cdf0e10cSrcweir } // end of namespace sdr 532cdf0e10cSrcweir 533cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////// 534cdf0e10cSrcweir // eof 535