vclhelperbufferdevice.cxx (464702f4) | vclhelperbufferdevice.cxx (ce37d08f) |
---|---|
1/************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance --- 15 unchanged lines hidden (view full) --- 24// MARKER(update_precomp.py): autogen include statement, do not remove 25#include "precompiled_drawinglayer.hxx" 26 27#include <vclhelperbufferdevice.hxx> 28#include <basegfx/range/b2drange.hxx> 29#include <vcl/bitmapex.hxx> 30#include <basegfx/matrix/b2dhommatrix.hxx> 31#include <tools/stream.hxx> | 1/************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance --- 15 unchanged lines hidden (view full) --- 24// MARKER(update_precomp.py): autogen include statement, do not remove 25#include "precompiled_drawinglayer.hxx" 26 27#include <vclhelperbufferdevice.hxx> 28#include <basegfx/range/b2drange.hxx> 29#include <vcl/bitmapex.hxx> 30#include <basegfx/matrix/b2dhommatrix.hxx> 31#include <tools/stream.hxx> |
32#include <vcl/timer.hxx> 33#include <comphelper/broadcasthelper.hxx> |
|
32 33////////////////////////////////////////////////////////////////////////////// | 34 35////////////////////////////////////////////////////////////////////////////// |
36// buffered VDev usage 37 38namespace 39{ 40 typedef ::std::vector< VirtualDevice* > aBuffers; 41 42 class VDevBuffer : public Timer, protected comphelper::OBaseMutex 43 { 44 private: 45 aBuffers maBuffers; 46 47 public: 48 VDevBuffer(); 49 virtual ~VDevBuffer(); 50 51 VirtualDevice* alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear, bool bMono); 52 void free(VirtualDevice& rDevice); 53 54 // Timer virtuals 55 virtual void Timeout(); 56 }; 57 58 VDevBuffer::VDevBuffer() 59 : Timer(), 60 maBuffers() 61 { 62 SetTimeout(10L * 1000L); // ten seconds 63 } 64 65 VDevBuffer::~VDevBuffer() 66 { 67 ::osl::MutexGuard aGuard(m_aMutex); 68 Stop(); 69 70 while(!maBuffers.empty()) 71 { 72 delete *(maBuffers.end() - 1); 73 maBuffers.pop_back(); 74 } 75 } 76 77 VirtualDevice* VDevBuffer::alloc(OutputDevice& rOutDev, const Size& rSizePixel, bool bClear, bool bMono) 78 { 79 ::osl::MutexGuard aGuard(m_aMutex); 80 VirtualDevice* pRetval = 0; 81 82 if(!maBuffers.empty()) 83 { 84 bool bOkay(false); 85 aBuffers::iterator aFound(maBuffers.end()); 86 87 for(aBuffers::iterator a(maBuffers.begin()); a != maBuffers.end(); a++) 88 { 89 OSL_ENSURE(*a, "Empty pointer in VDevBuffer (!)"); 90 91 if((bMono && 1 == (*a)->GetBitCount()) || (!bMono && (*a)->GetBitCount() > 1)) 92 { 93 // candidate is valid due to bit depth 94 if(aFound != maBuffers.end()) 95 { 96 // already found 97 if(bOkay) 98 { 99 // found is valid 100 const bool bCandidateOkay((*a)->GetOutputWidthPixel() >= rSizePixel.getWidth() && (*a)->GetOutputHeightPixel() >= rSizePixel.getHeight()); 101 102 if(bCandidateOkay) 103 { 104 // found and candidate are valid 105 const sal_uLong aSquare((*aFound)->GetOutputWidthPixel() * (*aFound)->GetOutputHeightPixel()); 106 const sal_uLong aCandidateSquare((*a)->GetOutputWidthPixel() * (*a)->GetOutputHeightPixel()); 107 108 if(aCandidateSquare < aSquare) 109 { 110 // candidate is valid and smaller, use it 111 aFound = a; 112 } 113 } 114 else 115 { 116 // found is valid, candidate is not. Keep found 117 } 118 } 119 else 120 { 121 // found is invalid, use candidate 122 aFound = a; 123 bOkay = (*aFound)->GetOutputWidthPixel() >= rSizePixel.getWidth() && (*aFound)->GetOutputHeightPixel() >= rSizePixel.getHeight(); 124 } 125 } 126 else 127 { 128 // none yet, use candidate 129 aFound = a; 130 bOkay = (*aFound)->GetOutputWidthPixel() >= rSizePixel.getWidth() && (*aFound)->GetOutputHeightPixel() >= rSizePixel.getHeight(); 131 } 132 } 133 } 134 135 if(aFound != maBuffers.end()) 136 { 137 pRetval = *aFound; 138 maBuffers.erase(aFound); 139 140 if(bOkay) 141 { 142 if(bClear) 143 { 144 pRetval->Erase(Rectangle(0, 0, rSizePixel.getWidth(), rSizePixel.getHeight())); 145 } 146 } 147 else 148 { 149 pRetval->SetOutputSizePixel(rSizePixel, bClear); 150 } 151 } 152 } 153 154 // no success yet, create new buffer 155 if(!pRetval) 156 { 157 pRetval = (bMono) ? new VirtualDevice(rOutDev, 1) : new VirtualDevice(rOutDev); 158 pRetval->SetOutputSizePixel(rSizePixel, bClear); 159 } 160 else 161 { 162 // reused, reset some values 163 pRetval->SetMapMode(); 164 } 165 166 return pRetval; 167 } 168 169 void VDevBuffer::free(VirtualDevice& rDevice) 170 { 171 ::osl::MutexGuard aGuard(m_aMutex); 172 maBuffers.push_back(&rDevice); 173 Start(); 174 } 175 176 void VDevBuffer::Timeout() 177 { 178 ::osl::MutexGuard aGuard(m_aMutex); 179 180 while(!maBuffers.empty()) 181 { 182 delete *(maBuffers.end() - 1); 183 maBuffers.pop_back(); 184 } 185 } 186} 187 188////////////////////////////////////////////////////////////////////////////// |
|
34// support for rendering Bitmap and BitmapEx contents 35 36namespace drawinglayer 37{ | 189// support for rendering Bitmap and BitmapEx contents 190 191namespace drawinglayer 192{ |
38 impBufferDevice::impBufferDevice( 39 OutputDevice& rOutDev, 40 const basegfx::B2DRange& rRange, 41 bool bAddOffsetToMapping) 42 : mrOutDev(rOutDev), 43 maContent(rOutDev), 44 mpMask(0L), 45 mpAlpha(0L) 46 { | 193 // static global VDev buffer for the VclProcessor2D's (VclMetafileProcessor2D and VclPixelProcessor2D) 194 static VDevBuffer aVDevBuffer; 195 196 impBufferDevice::impBufferDevice( 197 OutputDevice& rOutDev, 198 const basegfx::B2DRange& rRange, 199 bool bAddOffsetToMapping) 200 : mrOutDev(rOutDev), 201 mpContent(0), 202 mpMask(0), 203 mpAlpha(0) 204 { |
47 basegfx::B2DRange aRangePixel(rRange); | 205 basegfx::B2DRange aRangePixel(rRange); |
48 aRangePixel.transform(rOutDev.GetViewTransformation()); | 206 aRangePixel.transform(mrOutDev.GetViewTransformation()); |
49 const Rectangle aRectPixel( | 207 const Rectangle aRectPixel( |
50 (sal_Int32)floor(aRangePixel.getMinX()), (sal_Int32)floor(aRangePixel.getMinY()), 51 (sal_Int32)ceil(aRangePixel.getMaxX()), (sal_Int32)ceil(aRangePixel.getMaxY())); 52 const Point aEmptyPoint; 53 maDestPixel = Rectangle(aEmptyPoint, rOutDev.GetOutputSizePixel()); 54 maDestPixel.Intersection(aRectPixel); | 208 (sal_Int32)floor(aRangePixel.getMinX()), (sal_Int32)floor(aRangePixel.getMinY()), 209 (sal_Int32)ceil(aRangePixel.getMaxX()), (sal_Int32)ceil(aRangePixel.getMaxY())); 210 const Point aEmptyPoint; 211 maDestPixel = Rectangle(aEmptyPoint, mrOutDev.GetOutputSizePixel()); 212 maDestPixel.Intersection(aRectPixel); |
55 | 213 |
56 if(isVisible()) 57 { 58 maContent.SetOutputSizePixel(maDestPixel.GetSize(), false); | 214 if(isVisible()) 215 { 216 mpContent = aVDevBuffer.alloc(mrOutDev, maDestPixel.GetSize(), false, false); |
59 60 // #i93485# assert when copying from window to VDev is used | 217 218 // #i93485# assert when copying from window to VDev is used |
61 OSL_ENSURE(rOutDev.GetOutDevType() != OUTDEV_WINDOW, | 219 OSL_ENSURE(mrOutDev.GetOutDevType() != OUTDEV_WINDOW, |
62 "impBufferDevice render helper: Copying from Window to VDev, this should be avoided (!)"); 63 | 220 "impBufferDevice render helper: Copying from Window to VDev, this should be avoided (!)"); 221 |
64 const bool bWasEnabledSrc(rOutDev.IsMapModeEnabled()); 65 rOutDev.EnableMapMode(false); 66 maContent.DrawOutDev(aEmptyPoint, maDestPixel.GetSize(), maDestPixel.TopLeft(), maDestPixel.GetSize(), rOutDev); 67 rOutDev.EnableMapMode(bWasEnabledSrc); | 222 const bool bWasEnabledSrc(mrOutDev.IsMapModeEnabled()); 223 mrOutDev.EnableMapMode(false); 224 mpContent->DrawOutDev(aEmptyPoint, maDestPixel.GetSize(), maDestPixel.TopLeft(), maDestPixel.GetSize(), mrOutDev); 225 mrOutDev.EnableMapMode(bWasEnabledSrc); |
68 | 226 |
69 MapMode aNewMapMode(rOutDev.GetMapMode()); | 227 MapMode aNewMapMode(mrOutDev.GetMapMode()); |
70 | 228 |
71 if(bAddOffsetToMapping) 72 { 73 const Point aLogicTopLeft(rOutDev.PixelToLogic(maDestPixel.TopLeft())); 74 aNewMapMode.SetOrigin(Point(-aLogicTopLeft.X(), -aLogicTopLeft.Y())); 75 } | 229 if(bAddOffsetToMapping) 230 { 231 const Point aLogicTopLeft(mrOutDev.PixelToLogic(maDestPixel.TopLeft())); 232 aNewMapMode.SetOrigin(Point(-aLogicTopLeft.X(), -aLogicTopLeft.Y())); 233 } |
76 | 234 |
77 maContent.SetMapMode(aNewMapMode); | 235 mpContent->SetMapMode(aNewMapMode); |
78 79 // copy AA flag for new target | 236 237 // copy AA flag for new target |
80 maContent.SetAntialiasing(mrOutDev.GetAntialiasing()); 81 } 82 } | 238 mpContent->SetAntialiasing(mrOutDev.GetAntialiasing()); 239 } 240 } |
83 | 241 |
84 impBufferDevice::~impBufferDevice() 85 { 86 delete mpMask; 87 delete mpAlpha; 88 } | 242 impBufferDevice::~impBufferDevice() 243 { 244 if(mpContent) 245 { 246 aVDevBuffer.free(*mpContent); 247 } |
89 | 248 |
90 void impBufferDevice::paint(double fTrans) 91 { 92 const Point aEmptyPoint; 93 const Size aSizePixel(maContent.GetOutputSizePixel()); 94 const bool bWasEnabledDst(mrOutDev.IsMapModeEnabled()); 95 static bool bDoSaveForVisualControl(false); | 249 if(mpMask) 250 { 251 aVDevBuffer.free(*mpMask); 252 } |
96 | 253 |
97 mrOutDev.EnableMapMode(false); 98 maContent.EnableMapMode(false); 99 Bitmap aContent(maContent.GetBitmap(aEmptyPoint, aSizePixel)); 100 101 if(bDoSaveForVisualControl) 102 { 103 SvFileStream aNew((const String&)String(ByteString( "c:\\content.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC); 104 aNew << aContent; 105 } 106 | |
107 if(mpAlpha) | 254 if(mpAlpha) |
108 { 109 mpAlpha->EnableMapMode(false); 110 const AlphaMask aAlphaMask(mpAlpha->GetBitmap(aEmptyPoint, aSizePixel)); 111 112 if(bDoSaveForVisualControl) 113 { 114 SvFileStream aNew((const String&)String(ByteString( "c:\\transparence.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC); 115 aNew << aAlphaMask.GetBitmap(); 116 } 117 118 mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aAlphaMask)); 119 } 120 else if(mpMask) 121 { 122 mpMask->EnableMapMode(false); 123 const Bitmap aMask(mpMask->GetBitmap(aEmptyPoint, aSizePixel)); | 255 { 256 aVDevBuffer.free(*mpAlpha); 257 } 258 } |
124 | 259 |
260 void impBufferDevice::paint(double fTrans) 261 { 262 if(isVisible()) 263 { 264 const Point aEmptyPoint; 265 const Size aSizePixel(maDestPixel.GetSize()); 266 const bool bWasEnabledDst(mrOutDev.IsMapModeEnabled()); 267 static bool bDoSaveForVisualControl(false); 268 269 mrOutDev.EnableMapMode(false); 270 mpContent->EnableMapMode(false); 271 Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel)); 272 |
|
125 if(bDoSaveForVisualControl) | 273 if(bDoSaveForVisualControl) |
126 { 127 SvFileStream aNew((const String&)String(ByteString( "c:\\mask.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC); 128 aNew << aMask; 129 } | 274 { 275 SvFileStream aNew((const String&)String(ByteString( "c:\\content.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC); 276 aNew << aContent; 277 } 278 279 if(mpAlpha) 280 { 281 mpAlpha->EnableMapMode(false); 282 const AlphaMask aAlphaMask(mpAlpha->GetBitmap(aEmptyPoint, aSizePixel)); |
130 | 283 |
131 mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aMask)); 132 } 133 else if(0.0 != fTrans) 134 { 135 sal_uInt8 nMaskValue((sal_uInt8)basegfx::fround(fTrans * 255.0)); 136 const AlphaMask aAlphaMask(aSizePixel, &nMaskValue); 137 mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aAlphaMask)); 138 } 139 else 140 { 141 mrOutDev.DrawBitmap(maDestPixel.TopLeft(), aContent); 142 } | 284 if(bDoSaveForVisualControl) 285 { 286 SvFileStream aNew((const String&)String(ByteString( "c:\\transparence.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC); 287 aNew << aAlphaMask.GetBitmap(); 288 } |
143 | 289 |
144 mrOutDev.EnableMapMode(bWasEnabledDst); 145 } | 290 mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aAlphaMask)); 291 } 292 else if(mpMask) 293 { 294 mpMask->EnableMapMode(false); 295 const Bitmap aMask(mpMask->GetBitmap(aEmptyPoint, aSizePixel)); |
146 | 296 |
147 VirtualDevice& impBufferDevice::getMask() 148 { 149 if(!mpMask) 150 { 151 mpMask = new VirtualDevice(mrOutDev, 1); 152 mpMask->SetOutputSizePixel(maDestPixel.GetSize(), true); 153 mpMask->SetMapMode(maContent.GetMapMode()); | 297 if(bDoSaveForVisualControl) 298 { 299 SvFileStream aNew((const String&)String(ByteString( "c:\\mask.bmp" ), RTL_TEXTENCODING_UTF8), STREAM_WRITE|STREAM_TRUNC); 300 aNew << aMask; 301 } |
154 | 302 |
155 // do NOT copy AA flag for mask! 156 } | 303 mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aMask)); 304 } 305 else if(0.0 != fTrans) 306 { 307 sal_uInt8 nMaskValue((sal_uInt8)basegfx::fround(fTrans * 255.0)); 308 const AlphaMask aAlphaMask(aSizePixel, &nMaskValue); 309 mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aAlphaMask)); 310 } 311 else 312 { 313 mrOutDev.DrawBitmap(maDestPixel.TopLeft(), aContent); 314 } 315 316 mrOutDev.EnableMapMode(bWasEnabledDst); 317 } 318 } |
157 | 319 |
158 return *mpMask; 159 } | 320 VirtualDevice& impBufferDevice::getContent() 321 { 322 OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible() before accessing (!)"); 323 return *mpContent; 324 } |
160 | 325 |
161 VirtualDevice& impBufferDevice::getTransparence() 162 { 163 if(!mpAlpha) 164 { 165 mpAlpha = new VirtualDevice(); 166 mpAlpha->SetOutputSizePixel(maDestPixel.GetSize(), true); 167 mpAlpha->SetMapMode(maContent.GetMapMode()); | 326 VirtualDevice& impBufferDevice::getMask() 327 { 328 OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible() before accessing (!)"); 329 if(!mpMask) 330 { 331 mpMask = aVDevBuffer.alloc(mrOutDev, maDestPixel.GetSize(), true, true); 332 mpMask->SetMapMode(mpContent->GetMapMode()); |
168 | 333 |
169 // copy AA flag for new target; masking needs to be smooth 170 mpAlpha->SetAntialiasing(maContent.GetAntialiasing()); 171 } | 334 // do NOT copy AA flag for mask! 335 } 336 337 return *mpMask; 338 } 339 340 VirtualDevice& impBufferDevice::getTransparence() 341 { 342 OSL_ENSURE(mpContent, "impBufferDevice: No content, check isVisible() before accessing (!)"); 343 if(!mpAlpha) 344 { 345 mpAlpha = aVDevBuffer.alloc(mrOutDev, maDestPixel.GetSize(), true, false); 346 mpAlpha->SetMapMode(mpContent->GetMapMode()); |
172 | 347 |
173 return *mpAlpha; 174 } | 348 // copy AA flag for new target; masking needs to be smooth 349 mpAlpha->SetAntialiasing(mpContent->GetAntialiasing()); 350 } 351 352 return *mpAlpha; 353 } |
175} // end of namespace drawinglayer 176 177////////////////////////////////////////////////////////////////////////////// 178// eof | 354} // end of namespace drawinglayer 355 356////////////////////////////////////////////////////////////////////////////// 357// eof |