1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_canvas.hxx"
30 
31 #include "bitmapbackbuffer.hxx"
32 
33 #include <osl/mutex.hxx>
34 #include <vos/mutex.hxx>
35 
36 #include <vcl/svapp.hxx>
37 #include <vcl/bitmapex.hxx>
38 #include <vcl/bmpacc.hxx>
39 
40 
41 namespace vclcanvas
42 {
43     BitmapBackBuffer::BitmapBackBuffer( const BitmapEx& 		rBitmap,
44                                         const OutputDevice& 	rRefDevice ) :
45         maBitmap( rBitmap ),
46         mpVDev( NULL ),
47         mrRefDevice( rRefDevice ),
48         mbBitmapContentIsCurrent( false ),
49         mbVDevContentIsCurrent( false )
50     {
51     }
52 
53     BitmapBackBuffer::~BitmapBackBuffer()
54     {
55         // make sure solar mutex is held on deletion (other methods
56         // are supposed to be called with already locked solar mutex)
57         ::vos::OGuard aGuard( Application::GetSolarMutex() );
58 
59         if( mpVDev )
60             delete mpVDev;
61     }
62 
63     OutputDevice& BitmapBackBuffer::getOutDev()
64     {
65         createVDev();
66         updateVDev();
67         return *mpVDev;
68     }
69 
70     const OutputDevice& BitmapBackBuffer::getOutDev() const
71     {
72         createVDev();
73         updateVDev();
74         return *mpVDev;
75     }
76 
77     void BitmapBackBuffer::clear()
78     {
79         // force current content to bitmap, make all transparent white
80         getBitmapReference().Erase(COL_TRANSPARENT);
81     }
82 
83     BitmapEx& BitmapBackBuffer::getBitmapReference()
84     {
85         OSL_ENSURE( !mbBitmapContentIsCurrent || !mbVDevContentIsCurrent,
86                     "BitmapBackBuffer::getBitmapReference(): Both bitmap and VDev are valid?!" );
87 
88         if( mbVDevContentIsCurrent && mpVDev )
89         {
90             // VDev content is more current than bitmap - copy contents before!
91             mpVDev->EnableMapMode( sal_False );
92             const Point aEmptyPoint;
93             *maBitmap = mpVDev->GetBitmapEx( aEmptyPoint,
94                                              mpVDev->GetOutputSizePixel() );
95         }
96 
97         // client queries bitmap, and will possibly alter content -
98         // next time, VDev needs to be updated
99         mbBitmapContentIsCurrent = true;
100         mbVDevContentIsCurrent 	 = false;
101 
102         return *maBitmap;
103     }
104 
105     Size BitmapBackBuffer::getBitmapSizePixel() const
106     {
107         Size aSize = maBitmap->GetSizePixel();
108 
109         if( mbVDevContentIsCurrent && mpVDev )
110         {
111             mpVDev->EnableMapMode( sal_False );
112             aSize = mpVDev->GetOutputSizePixel();
113         }
114 
115         return aSize;
116     }
117 
118     void BitmapBackBuffer::createVDev() const
119     {
120         if( !mpVDev )
121         {
122             // VDev not yet created, do it now. Create an alpha-VDev,
123             // if bitmap has transparency.
124             mpVDev = maBitmap->IsTransparent() ?
125                 new VirtualDevice( mrRefDevice, 0, 0 ) :
126                 new VirtualDevice( mrRefDevice );
127 
128             OSL_ENSURE( mpVDev,
129                         "BitmapBackBuffer::createVDev(): Unable to create VirtualDevice" );
130 
131             mpVDev->SetOutputSizePixel( maBitmap->GetSizePixel() );
132 
133             // #i95645#
134 #if defined( QUARTZ )
135             // use AA on VCLCanvas for Mac
136 			mpVDev->SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW | mpVDev->GetAntialiasing() );
137 #else
138             // switch off AA for WIN32 and UNIX, the VCLCanvas does not look good with it and
139             // is not required to do AA. It would need to be adapted to use it correctly
140             // (especially gradient painting). This will need extra work.
141 			mpVDev->SetAntialiasing(mpVDev->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW);
142 #endif
143         }
144     }
145 
146     void BitmapBackBuffer::updateVDev() const
147     {
148         OSL_ENSURE( !mbBitmapContentIsCurrent || !mbVDevContentIsCurrent,
149                     "BitmapBackBuffer::updateVDev(): Both bitmap and VDev are valid?!" );
150 
151         if( mpVDev && mbBitmapContentIsCurrent )
152         {
153             // fill with bitmap content
154             mpVDev->EnableMapMode( sal_False );
155             const Point aEmptyPoint;
156             mpVDev->DrawBitmapEx( aEmptyPoint, *maBitmap );
157         }
158 
159         // canvas queried the VDev, and will possibly paint into
160         // it. Next time, bitmap must be updated
161         mbBitmapContentIsCurrent = false;
162         mbVDevContentIsCurrent 	 = true;
163     }
164 }
165 
166