1*25ea7f45SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*25ea7f45SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*25ea7f45SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*25ea7f45SAndrew Rist * distributed with this work for additional information 6*25ea7f45SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*25ea7f45SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*25ea7f45SAndrew Rist * "License"); you may not use this file except in compliance 9*25ea7f45SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*25ea7f45SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*25ea7f45SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*25ea7f45SAndrew Rist * software distributed under the License is distributed on an 15*25ea7f45SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*25ea7f45SAndrew Rist * KIND, either express or implied. See the License for the 17*25ea7f45SAndrew Rist * specific language governing permissions and limitations 18*25ea7f45SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*25ea7f45SAndrew Rist *************************************************************/ 21*25ea7f45SAndrew Rist 22*25ea7f45SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_canvas.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "bitmapbackbuffer.hxx" 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include <osl/mutex.hxx> 30cdf0e10cSrcweir #include <vos/mutex.hxx> 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include <vcl/svapp.hxx> 33cdf0e10cSrcweir #include <vcl/bitmapex.hxx> 34cdf0e10cSrcweir #include <vcl/bmpacc.hxx> 35cdf0e10cSrcweir 36cdf0e10cSrcweir 37cdf0e10cSrcweir namespace vclcanvas 38cdf0e10cSrcweir { 39cdf0e10cSrcweir BitmapBackBuffer::BitmapBackBuffer( const BitmapEx& rBitmap, 40cdf0e10cSrcweir const OutputDevice& rRefDevice ) : 41cdf0e10cSrcweir maBitmap( rBitmap ), 42cdf0e10cSrcweir mpVDev( NULL ), 43cdf0e10cSrcweir mrRefDevice( rRefDevice ), 44cdf0e10cSrcweir mbBitmapContentIsCurrent( false ), 45cdf0e10cSrcweir mbVDevContentIsCurrent( false ) 46cdf0e10cSrcweir { 47cdf0e10cSrcweir } 48cdf0e10cSrcweir 49cdf0e10cSrcweir BitmapBackBuffer::~BitmapBackBuffer() 50cdf0e10cSrcweir { 51cdf0e10cSrcweir // make sure solar mutex is held on deletion (other methods 52cdf0e10cSrcweir // are supposed to be called with already locked solar mutex) 53cdf0e10cSrcweir ::vos::OGuard aGuard( Application::GetSolarMutex() ); 54cdf0e10cSrcweir 55cdf0e10cSrcweir if( mpVDev ) 56cdf0e10cSrcweir delete mpVDev; 57cdf0e10cSrcweir } 58cdf0e10cSrcweir 59cdf0e10cSrcweir OutputDevice& BitmapBackBuffer::getOutDev() 60cdf0e10cSrcweir { 61cdf0e10cSrcweir createVDev(); 62cdf0e10cSrcweir updateVDev(); 63cdf0e10cSrcweir return *mpVDev; 64cdf0e10cSrcweir } 65cdf0e10cSrcweir 66cdf0e10cSrcweir const OutputDevice& BitmapBackBuffer::getOutDev() const 67cdf0e10cSrcweir { 68cdf0e10cSrcweir createVDev(); 69cdf0e10cSrcweir updateVDev(); 70cdf0e10cSrcweir return *mpVDev; 71cdf0e10cSrcweir } 72cdf0e10cSrcweir 73cdf0e10cSrcweir void BitmapBackBuffer::clear() 74cdf0e10cSrcweir { 75cdf0e10cSrcweir // force current content to bitmap, make all transparent white 76cdf0e10cSrcweir getBitmapReference().Erase(COL_TRANSPARENT); 77cdf0e10cSrcweir } 78cdf0e10cSrcweir 79cdf0e10cSrcweir BitmapEx& BitmapBackBuffer::getBitmapReference() 80cdf0e10cSrcweir { 81cdf0e10cSrcweir OSL_ENSURE( !mbBitmapContentIsCurrent || !mbVDevContentIsCurrent, 82cdf0e10cSrcweir "BitmapBackBuffer::getBitmapReference(): Both bitmap and VDev are valid?!" ); 83cdf0e10cSrcweir 84cdf0e10cSrcweir if( mbVDevContentIsCurrent && mpVDev ) 85cdf0e10cSrcweir { 86cdf0e10cSrcweir // VDev content is more current than bitmap - copy contents before! 87cdf0e10cSrcweir mpVDev->EnableMapMode( sal_False ); 88cdf0e10cSrcweir const Point aEmptyPoint; 89cdf0e10cSrcweir *maBitmap = mpVDev->GetBitmapEx( aEmptyPoint, 90cdf0e10cSrcweir mpVDev->GetOutputSizePixel() ); 91cdf0e10cSrcweir } 92cdf0e10cSrcweir 93cdf0e10cSrcweir // client queries bitmap, and will possibly alter content - 94cdf0e10cSrcweir // next time, VDev needs to be updated 95cdf0e10cSrcweir mbBitmapContentIsCurrent = true; 96cdf0e10cSrcweir mbVDevContentIsCurrent = false; 97cdf0e10cSrcweir 98cdf0e10cSrcweir return *maBitmap; 99cdf0e10cSrcweir } 100cdf0e10cSrcweir 101cdf0e10cSrcweir Size BitmapBackBuffer::getBitmapSizePixel() const 102cdf0e10cSrcweir { 103cdf0e10cSrcweir Size aSize = maBitmap->GetSizePixel(); 104cdf0e10cSrcweir 105cdf0e10cSrcweir if( mbVDevContentIsCurrent && mpVDev ) 106cdf0e10cSrcweir { 107cdf0e10cSrcweir mpVDev->EnableMapMode( sal_False ); 108cdf0e10cSrcweir aSize = mpVDev->GetOutputSizePixel(); 109cdf0e10cSrcweir } 110cdf0e10cSrcweir 111cdf0e10cSrcweir return aSize; 112cdf0e10cSrcweir } 113cdf0e10cSrcweir 114cdf0e10cSrcweir void BitmapBackBuffer::createVDev() const 115cdf0e10cSrcweir { 116cdf0e10cSrcweir if( !mpVDev ) 117cdf0e10cSrcweir { 118cdf0e10cSrcweir // VDev not yet created, do it now. Create an alpha-VDev, 119cdf0e10cSrcweir // if bitmap has transparency. 120cdf0e10cSrcweir mpVDev = maBitmap->IsTransparent() ? 121cdf0e10cSrcweir new VirtualDevice( mrRefDevice, 0, 0 ) : 122cdf0e10cSrcweir new VirtualDevice( mrRefDevice ); 123cdf0e10cSrcweir 124cdf0e10cSrcweir OSL_ENSURE( mpVDev, 125cdf0e10cSrcweir "BitmapBackBuffer::createVDev(): Unable to create VirtualDevice" ); 126cdf0e10cSrcweir 127cdf0e10cSrcweir mpVDev->SetOutputSizePixel( maBitmap->GetSizePixel() ); 128cdf0e10cSrcweir 129cdf0e10cSrcweir // #i95645# 130cdf0e10cSrcweir #if defined( QUARTZ ) 131cdf0e10cSrcweir // use AA on VCLCanvas for Mac 132cdf0e10cSrcweir mpVDev->SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW | mpVDev->GetAntialiasing() ); 133cdf0e10cSrcweir #else 134cdf0e10cSrcweir // switch off AA for WIN32 and UNIX, the VCLCanvas does not look good with it and 135cdf0e10cSrcweir // is not required to do AA. It would need to be adapted to use it correctly 136cdf0e10cSrcweir // (especially gradient painting). This will need extra work. 137cdf0e10cSrcweir mpVDev->SetAntialiasing(mpVDev->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); 138cdf0e10cSrcweir #endif 139cdf0e10cSrcweir } 140cdf0e10cSrcweir } 141cdf0e10cSrcweir 142cdf0e10cSrcweir void BitmapBackBuffer::updateVDev() const 143cdf0e10cSrcweir { 144cdf0e10cSrcweir OSL_ENSURE( !mbBitmapContentIsCurrent || !mbVDevContentIsCurrent, 145cdf0e10cSrcweir "BitmapBackBuffer::updateVDev(): Both bitmap and VDev are valid?!" ); 146cdf0e10cSrcweir 147cdf0e10cSrcweir if( mpVDev && mbBitmapContentIsCurrent ) 148cdf0e10cSrcweir { 149cdf0e10cSrcweir // fill with bitmap content 150cdf0e10cSrcweir mpVDev->EnableMapMode( sal_False ); 151cdf0e10cSrcweir const Point aEmptyPoint; 152cdf0e10cSrcweir mpVDev->DrawBitmapEx( aEmptyPoint, *maBitmap ); 153cdf0e10cSrcweir } 154cdf0e10cSrcweir 155cdf0e10cSrcweir // canvas queried the VDev, and will possibly paint into 156cdf0e10cSrcweir // it. Next time, bitmap must be updated 157cdf0e10cSrcweir mbBitmapContentIsCurrent = false; 158cdf0e10cSrcweir mbVDevContentIsCurrent = true; 159cdf0e10cSrcweir } 160cdf0e10cSrcweir } 161cdf0e10cSrcweir 162