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