/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_canvas.hxx" #include "bitmapbackbuffer.hxx" #include #include #include #include #include namespace vclcanvas { BitmapBackBuffer::BitmapBackBuffer( const BitmapEx& rBitmap, const OutputDevice& rRefDevice ) : maBitmap( rBitmap ), mpVDev( NULL ), mrRefDevice( rRefDevice ), mbBitmapContentIsCurrent( false ), mbVDevContentIsCurrent( false ) { } BitmapBackBuffer::~BitmapBackBuffer() { // make sure solar mutex is held on deletion (other methods // are supposed to be called with already locked solar mutex) ::vos::OGuard aGuard( Application::GetSolarMutex() ); if( mpVDev ) delete mpVDev; } OutputDevice& BitmapBackBuffer::getOutDev() { createVDev(); updateVDev(); return *mpVDev; } const OutputDevice& BitmapBackBuffer::getOutDev() const { createVDev(); updateVDev(); return *mpVDev; } void BitmapBackBuffer::clear() { // force current content to bitmap, make all transparent white getBitmapReference().Erase(COL_TRANSPARENT); } BitmapEx& BitmapBackBuffer::getBitmapReference() { OSL_ENSURE( !mbBitmapContentIsCurrent || !mbVDevContentIsCurrent, "BitmapBackBuffer::getBitmapReference(): Both bitmap and VDev are valid?!" ); if( mbVDevContentIsCurrent && mpVDev ) { // VDev content is more current than bitmap - copy contents before! mpVDev->EnableMapMode( sal_False ); mpVDev->SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); const Point aEmptyPoint; *maBitmap = mpVDev->GetBitmapEx( aEmptyPoint, mpVDev->GetOutputSizePixel() ); } // client queries bitmap, and will possibly alter content - // next time, VDev needs to be updated mbBitmapContentIsCurrent = true; mbVDevContentIsCurrent = false; return *maBitmap; } Size BitmapBackBuffer::getBitmapSizePixel() const { Size aSize = maBitmap->GetSizePixel(); if( mbVDevContentIsCurrent && mpVDev ) { mpVDev->EnableMapMode( sal_False ); mpVDev->SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); aSize = mpVDev->GetOutputSizePixel(); } return aSize; } void BitmapBackBuffer::createVDev() const { if( !mpVDev ) { // VDev not yet created, do it now. Create an alpha-VDev, // if bitmap has transparency. mpVDev = maBitmap->IsTransparent() ? new VirtualDevice( mrRefDevice, 0, 0 ) : new VirtualDevice( mrRefDevice ); OSL_ENSURE( mpVDev, "BitmapBackBuffer::createVDev(): Unable to create VirtualDevice" ); mpVDev->SetOutputSizePixel( maBitmap->GetSizePixel() ); // #i95645# #if defined( QUARTZ ) // use AA on VCLCanvas for Mac mpVDev->SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW | mpVDev->GetAntialiasing() ); #else // switch off AA for WIN32 and UNIX, the VCLCanvas does not look good with it and // is not required to do AA. It would need to be adapted to use it correctly // (especially gradient painting). This will need extra work. mpVDev->SetAntialiasing(mpVDev->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); #endif } } void BitmapBackBuffer::updateVDev() const { OSL_ENSURE( !mbBitmapContentIsCurrent || !mbVDevContentIsCurrent, "BitmapBackBuffer::updateVDev(): Both bitmap and VDev are valid?!" ); if( mpVDev && mbBitmapContentIsCurrent ) { // fill with bitmap content mpVDev->EnableMapMode( sal_False ); mpVDev->SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); const Point aEmptyPoint; mpVDev->DrawBitmapEx( aEmptyPoint, *maBitmap ); } // canvas queried the VDev, and will possibly paint into // it. Next time, bitmap must be updated mbBitmapContentIsCurrent = false; mbVDevContentIsCurrent = true; } }