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