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