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