125ea7f45SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
325ea7f45SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
425ea7f45SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
525ea7f45SAndrew Rist  * distributed with this work for additional information
625ea7f45SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
725ea7f45SAndrew Rist  * to you under the Apache License, Version 2.0 (the
825ea7f45SAndrew Rist  * "License"); you may not use this file except in compliance
925ea7f45SAndrew Rist  * with the License.  You may obtain a copy of the License at
1025ea7f45SAndrew Rist  *
1125ea7f45SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
1225ea7f45SAndrew Rist  *
1325ea7f45SAndrew Rist  * Unless required by applicable law or agreed to in writing,
1425ea7f45SAndrew Rist  * software distributed under the License is distributed on an
1525ea7f45SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1625ea7f45SAndrew Rist  * KIND, either express or implied.  See the License for the
1725ea7f45SAndrew Rist  * specific language governing permissions and limitations
1825ea7f45SAndrew Rist  * under the License.
1925ea7f45SAndrew Rist  *
2025ea7f45SAndrew Rist  *************************************************************/
2125ea7f45SAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_canvas.hxx"
24cdf0e10cSrcweir 
25cdf0e10cSrcweir #include <canvas/debug.hxx>
26cdf0e10cSrcweir #include <canvas/verbosetrace.hxx>
27cdf0e10cSrcweir #include <canvas/canvastools.hxx>
28cdf0e10cSrcweir #include <osl/mutex.hxx>
29cdf0e10cSrcweir #include <cppuhelper/compbase1.hxx>
30cdf0e10cSrcweir #include <com/sun/star/lang/NoSupportException.hpp>
31cdf0e10cSrcweir #include <toolkit/helper/vclunohelper.hxx>
32cdf0e10cSrcweir #include <basegfx/tools/canvastools.hxx>
33cdf0e10cSrcweir #include <basegfx/tools/unopolypolygon.hxx>
34cdf0e10cSrcweir #include <vcl/canvastools.hxx>
35*53602e99SArmin Le Grand #include <vcl/dibtools.hxx>
36cdf0e10cSrcweir #include <tools/stream.hxx>
37cdf0e10cSrcweir #include "cairo_spritecanvas.hxx"
38cdf0e10cSrcweir #include "cairo_canvasbitmap.hxx"
39cdf0e10cSrcweir #include "cairo_devicehelper.hxx"
40cdf0e10cSrcweir 
41cdf0e10cSrcweir using namespace ::cairo;
42cdf0e10cSrcweir using namespace ::com::sun::star;
43cdf0e10cSrcweir 
44cdf0e10cSrcweir namespace cairocanvas
45cdf0e10cSrcweir {
DeviceHelper()46cdf0e10cSrcweir     DeviceHelper::DeviceHelper() :
47cdf0e10cSrcweir         mpSurfaceProvider( NULL ),
48cdf0e10cSrcweir         mpRefDevice( NULL ),
49cdf0e10cSrcweir         mpSurface()
50cdf0e10cSrcweir     {
51cdf0e10cSrcweir     }
52cdf0e10cSrcweir 
implInit(SurfaceProvider & rSurfaceProvider,OutputDevice & rRefDevice)53cdf0e10cSrcweir     void DeviceHelper::implInit( SurfaceProvider& rSurfaceProvider,
54cdf0e10cSrcweir                                  OutputDevice&    rRefDevice )
55cdf0e10cSrcweir     {
56cdf0e10cSrcweir         mpSurfaceProvider = &rSurfaceProvider;
57cdf0e10cSrcweir         mpRefDevice = &rRefDevice;
58cdf0e10cSrcweir 
59cdf0e10cSrcweir         // no own surface, this is handled by derived classes
60cdf0e10cSrcweir     }
61cdf0e10cSrcweir 
init(SurfaceProvider & rSurfaceProvider,OutputDevice & rRefDevice)62cdf0e10cSrcweir     void DeviceHelper::init( SurfaceProvider& rSurfaceProvider,
63cdf0e10cSrcweir                              OutputDevice&    rRefDevice )
64cdf0e10cSrcweir     {
65cdf0e10cSrcweir         implInit(rSurfaceProvider, rRefDevice);
66cdf0e10cSrcweir 
67cdf0e10cSrcweir         OutputDevice* pOutDev=getOutputDevice();
68cdf0e10cSrcweir         mpSurface = cairo::createSurface( *pOutDev,
69cdf0e10cSrcweir                                           pOutDev->GetOutOffXPixel(),
70cdf0e10cSrcweir                                           pOutDev->GetOutOffYPixel(),
71cdf0e10cSrcweir                                           pOutDev->GetOutputWidthPixel(),
72cdf0e10cSrcweir                                           pOutDev->GetOutputHeightPixel() );
73cdf0e10cSrcweir     }
74cdf0e10cSrcweir 
disposing()75cdf0e10cSrcweir     void DeviceHelper::disposing()
76cdf0e10cSrcweir     {
77cdf0e10cSrcweir         // release all references
78cdf0e10cSrcweir         mpSurface.reset();
79cdf0e10cSrcweir         mpRefDevice = NULL;
80cdf0e10cSrcweir         mpSurfaceProvider = NULL;
81cdf0e10cSrcweir     }
82cdf0e10cSrcweir 
setSize(const::basegfx::B2ISize & rSize)83cdf0e10cSrcweir     void DeviceHelper::setSize( const ::basegfx::B2ISize& rSize )
84cdf0e10cSrcweir     {
85cdf0e10cSrcweir 		OSL_TRACE("DeviceHelper::setSize(): device size %d x %d", rSize.getX(), rSize.getY() );
86cdf0e10cSrcweir 
87cdf0e10cSrcweir         if( !mpRefDevice )
88cdf0e10cSrcweir             return; // disposed
89cdf0e10cSrcweir 
90cdf0e10cSrcweir         OutputDevice* pOutDev=getOutputDevice();
91cdf0e10cSrcweir 
92cdf0e10cSrcweir #if defined (UNX) && !defined (QUARTZ)
93cdf0e10cSrcweir         // X11 only
94cdf0e10cSrcweir 		if( mpSurface )
95cdf0e10cSrcweir 			mpSurface->Resize( rSize.getX() + pOutDev->GetOutOffXPixel(),
96cdf0e10cSrcweir                                rSize.getY() + pOutDev->GetOutOffYPixel() );
97cdf0e10cSrcweir         else
98cdf0e10cSrcweir #endif
99cdf0e10cSrcweir 			mpSurface = cairo::createSurface(
100cdf0e10cSrcweir                 *pOutDev,
101cdf0e10cSrcweir                 pOutDev->GetOutOffXPixel(),
102cdf0e10cSrcweir                 pOutDev->GetOutOffYPixel(),
103cdf0e10cSrcweir                 rSize.getX(), rSize.getY() );
104cdf0e10cSrcweir     }
105cdf0e10cSrcweir 
getPhysicalResolution()106cdf0e10cSrcweir     geometry::RealSize2D DeviceHelper::getPhysicalResolution()
107cdf0e10cSrcweir     {
108cdf0e10cSrcweir         // Map a one-by-one millimeter box to pixel
109cdf0e10cSrcweir         const MapMode aOldMapMode( mpRefDevice->GetMapMode() );
110cdf0e10cSrcweir         mpRefDevice->SetMapMode( MapMode(MAP_MM) );
111cdf0e10cSrcweir         const Size aPixelSize( mpRefDevice->LogicToPixel(Size(1,1)) );
112cdf0e10cSrcweir         mpRefDevice->SetMapMode( aOldMapMode );
113cdf0e10cSrcweir 
114cdf0e10cSrcweir         return ::vcl::unotools::size2DFromSize( aPixelSize );
115cdf0e10cSrcweir     }
116cdf0e10cSrcweir 
getPhysicalSize()117cdf0e10cSrcweir     geometry::RealSize2D DeviceHelper::getPhysicalSize()
118cdf0e10cSrcweir     {
119cdf0e10cSrcweir         if( !mpRefDevice )
120cdf0e10cSrcweir             return ::canvas::tools::createInfiniteSize2D(); // we're disposed
121cdf0e10cSrcweir 
122cdf0e10cSrcweir         // Map the pixel dimensions of the output window to millimeter
123cdf0e10cSrcweir         const MapMode aOldMapMode( mpRefDevice->GetMapMode() );
124cdf0e10cSrcweir         mpRefDevice->SetMapMode( MapMode(MAP_MM) );
125cdf0e10cSrcweir         const Size aLogSize( mpRefDevice->PixelToLogic(mpRefDevice->GetOutputSizePixel()) );
126cdf0e10cSrcweir         mpRefDevice->SetMapMode( aOldMapMode );
127cdf0e10cSrcweir 
128cdf0e10cSrcweir         return ::vcl::unotools::size2DFromSize( aLogSize );
129cdf0e10cSrcweir     }
130cdf0e10cSrcweir 
createCompatibleLinePolyPolygon(const uno::Reference<rendering::XGraphicDevice> &,const uno::Sequence<uno::Sequence<geometry::RealPoint2D>> & points)131cdf0e10cSrcweir     uno::Reference< rendering::XLinePolyPolygon2D > DeviceHelper::createCompatibleLinePolyPolygon(
132cdf0e10cSrcweir         const uno::Reference< rendering::XGraphicDevice >& 				,
133cdf0e10cSrcweir         const uno::Sequence< uno::Sequence< geometry::RealPoint2D > >&	points )
134cdf0e10cSrcweir     {
135cdf0e10cSrcweir         // disposed?
136cdf0e10cSrcweir         if( !mpSurfaceProvider )
137cdf0e10cSrcweir             return uno::Reference< rendering::XLinePolyPolygon2D >(); // we're disposed
138cdf0e10cSrcweir 
139cdf0e10cSrcweir         return uno::Reference< rendering::XLinePolyPolygon2D >(
140cdf0e10cSrcweir             new ::basegfx::unotools::UnoPolyPolygon(
141cdf0e10cSrcweir                 ::basegfx::unotools::polyPolygonFromPoint2DSequenceSequence( points ) ) );
142cdf0e10cSrcweir     }
143cdf0e10cSrcweir 
createCompatibleBezierPolyPolygon(const uno::Reference<rendering::XGraphicDevice> &,const uno::Sequence<uno::Sequence<geometry::RealBezierSegment2D>> & points)144cdf0e10cSrcweir     uno::Reference< rendering::XBezierPolyPolygon2D > DeviceHelper::createCompatibleBezierPolyPolygon(
145cdf0e10cSrcweir         const uno::Reference< rendering::XGraphicDevice >& 						,
146cdf0e10cSrcweir         const uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > >&	points )
147cdf0e10cSrcweir     {
148cdf0e10cSrcweir         // disposed?
149cdf0e10cSrcweir         if( !mpSurfaceProvider )
150cdf0e10cSrcweir             return uno::Reference< rendering::XBezierPolyPolygon2D >(); // we're disposed
151cdf0e10cSrcweir 
152cdf0e10cSrcweir         return uno::Reference< rendering::XBezierPolyPolygon2D >(
153cdf0e10cSrcweir             new ::basegfx::unotools::UnoPolyPolygon(
154cdf0e10cSrcweir                 ::basegfx::unotools::polyPolygonFromBezier2DSequenceSequence( points ) ) );
155cdf0e10cSrcweir     }
156cdf0e10cSrcweir 
createCompatibleBitmap(const uno::Reference<rendering::XGraphicDevice> & rDevice,const geometry::IntegerSize2D & size)157cdf0e10cSrcweir     uno::Reference< rendering::XBitmap > DeviceHelper::createCompatibleBitmap(
158cdf0e10cSrcweir         const uno::Reference< rendering::XGraphicDevice >& 	rDevice,
159cdf0e10cSrcweir         const geometry::IntegerSize2D& 						size )
160cdf0e10cSrcweir     {
161cdf0e10cSrcweir         // disposed?
162cdf0e10cSrcweir         if( !mpSurfaceProvider )
163cdf0e10cSrcweir             return uno::Reference< rendering::XBitmap >(); // we're disposed
164cdf0e10cSrcweir 
165cdf0e10cSrcweir         return uno::Reference< rendering::XBitmap >(
166cdf0e10cSrcweir             new CanvasBitmap(
167cdf0e10cSrcweir                 ::basegfx::unotools::b2ISizeFromIntegerSize2D( size ),
168cdf0e10cSrcweir                 SurfaceProviderRef(mpSurfaceProvider),
169cdf0e10cSrcweir                 rDevice.get(),
170cdf0e10cSrcweir                 false ));
171cdf0e10cSrcweir     }
172cdf0e10cSrcweir 
createVolatileBitmap(const uno::Reference<rendering::XGraphicDevice> &,const geometry::IntegerSize2D &)173cdf0e10cSrcweir     uno::Reference< rendering::XVolatileBitmap > DeviceHelper::createVolatileBitmap(
174cdf0e10cSrcweir         const uno::Reference< rendering::XGraphicDevice >& 	,
175cdf0e10cSrcweir         const geometry::IntegerSize2D& 						/*size*/ )
176cdf0e10cSrcweir     {
177cdf0e10cSrcweir         return uno::Reference< rendering::XVolatileBitmap >();
178cdf0e10cSrcweir     }
179cdf0e10cSrcweir 
createCompatibleAlphaBitmap(const uno::Reference<rendering::XGraphicDevice> & rDevice,const geometry::IntegerSize2D & size)180cdf0e10cSrcweir     uno::Reference< rendering::XBitmap > DeviceHelper::createCompatibleAlphaBitmap(
181cdf0e10cSrcweir         const uno::Reference< rendering::XGraphicDevice >& 	rDevice,
182cdf0e10cSrcweir         const geometry::IntegerSize2D& 						size )
183cdf0e10cSrcweir     {
184cdf0e10cSrcweir         // disposed?
185cdf0e10cSrcweir         if( !mpSurfaceProvider )
186cdf0e10cSrcweir             return uno::Reference< rendering::XBitmap >(); // we're disposed
187cdf0e10cSrcweir 
188cdf0e10cSrcweir         return uno::Reference< rendering::XBitmap >(
189cdf0e10cSrcweir             new CanvasBitmap(
190cdf0e10cSrcweir                 ::basegfx::unotools::b2ISizeFromIntegerSize2D( size ),
191cdf0e10cSrcweir                 SurfaceProviderRef(mpSurfaceProvider),
192cdf0e10cSrcweir                 rDevice.get(),
193cdf0e10cSrcweir                 true ));
194cdf0e10cSrcweir     }
195cdf0e10cSrcweir 
createVolatileAlphaBitmap(const uno::Reference<rendering::XGraphicDevice> &,const geometry::IntegerSize2D &)196cdf0e10cSrcweir     uno::Reference< rendering::XVolatileBitmap > DeviceHelper::createVolatileAlphaBitmap(
197cdf0e10cSrcweir         const uno::Reference< rendering::XGraphicDevice >& 	,
198cdf0e10cSrcweir         const geometry::IntegerSize2D& 						/*size*/ )
199cdf0e10cSrcweir     {
200cdf0e10cSrcweir         return uno::Reference< rendering::XVolatileBitmap >();
201cdf0e10cSrcweir     }
202cdf0e10cSrcweir 
hasFullScreenMode()203cdf0e10cSrcweir     sal_Bool DeviceHelper::hasFullScreenMode()
204cdf0e10cSrcweir     {
205cdf0e10cSrcweir         // TODO(F3): offer fullscreen mode the XCanvas way
206cdf0e10cSrcweir         return false;
207cdf0e10cSrcweir     }
208cdf0e10cSrcweir 
enterFullScreenMode(sal_Bool)209cdf0e10cSrcweir     sal_Bool DeviceHelper::enterFullScreenMode( sal_Bool /*bEnter*/ )
210cdf0e10cSrcweir     {
211cdf0e10cSrcweir         // TODO(F3): offer fullscreen mode the XCanvas way
212cdf0e10cSrcweir         return false;
213cdf0e10cSrcweir     }
214cdf0e10cSrcweir 
isAccelerated() const215cdf0e10cSrcweir     uno::Any DeviceHelper::isAccelerated() const
216cdf0e10cSrcweir     {
217cdf0e10cSrcweir         return ::com::sun::star::uno::makeAny(false);
218cdf0e10cSrcweir     }
219cdf0e10cSrcweir 
getDeviceHandle() const220cdf0e10cSrcweir     uno::Any DeviceHelper::getDeviceHandle() const
221cdf0e10cSrcweir     {
222cdf0e10cSrcweir         return uno::makeAny( reinterpret_cast< sal_Int64 >(mpRefDevice) );
223cdf0e10cSrcweir     }
224cdf0e10cSrcweir 
getSurfaceHandle() const225cdf0e10cSrcweir     uno::Any DeviceHelper::getSurfaceHandle() const
226cdf0e10cSrcweir     {
227cdf0e10cSrcweir         return uno::Any();
228cdf0e10cSrcweir     }
229cdf0e10cSrcweir 
230cdf0e10cSrcweir     namespace
231cdf0e10cSrcweir     {
232cdf0e10cSrcweir         struct DeviceColorSpace: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>,
233cdf0e10cSrcweir                                                             DeviceColorSpace>
234cdf0e10cSrcweir         {
operator ()cairocanvas::__anon70b3e0fd0111::DeviceColorSpace235cdf0e10cSrcweir             uno::Reference<rendering::XColorSpace> operator()()
236cdf0e10cSrcweir             {
237cdf0e10cSrcweir                 return vcl::unotools::createStandardColorSpace();
238cdf0e10cSrcweir             }
239cdf0e10cSrcweir         };
240cdf0e10cSrcweir     }
241cdf0e10cSrcweir 
getColorSpace() const242cdf0e10cSrcweir     uno::Reference<rendering::XColorSpace> DeviceHelper::getColorSpace() const
243cdf0e10cSrcweir     {
244cdf0e10cSrcweir         // always the same
245cdf0e10cSrcweir         return DeviceColorSpace::get();
246cdf0e10cSrcweir     }
247cdf0e10cSrcweir 
dumpScreenContent() const248cdf0e10cSrcweir     void DeviceHelper::dumpScreenContent() const
249cdf0e10cSrcweir     {
250cdf0e10cSrcweir         static sal_uInt32 nFilePostfixCount(0);
251cdf0e10cSrcweir 
252cdf0e10cSrcweir         if( mpRefDevice )
253cdf0e10cSrcweir         {
254cdf0e10cSrcweir             String aFilename( String::CreateFromAscii("dbg_frontbuffer") );
255cdf0e10cSrcweir             aFilename += String::CreateFromInt32(nFilePostfixCount);
256cdf0e10cSrcweir             aFilename += String::CreateFromAscii(".bmp");
257cdf0e10cSrcweir 
258cdf0e10cSrcweir             SvFileStream aStream( aFilename, STREAM_STD_READWRITE );
259cdf0e10cSrcweir 
260cdf0e10cSrcweir             const ::Point aEmptyPoint;
261cdf0e10cSrcweir             bool bOldMap( mpRefDevice->IsMapModeEnabled() );
262cdf0e10cSrcweir             mpRefDevice->EnableMapMode( sal_False );
263*53602e99SArmin Le Grand             const ::Bitmap aTempBitmap(mpRefDevice->GetBitmap(aEmptyPoint, mpRefDevice->GetOutputSizePixel()));
264*53602e99SArmin Le Grand             WriteDIB(aTempBitmap, aStream, false, true);
265cdf0e10cSrcweir             mpRefDevice->EnableMapMode( bOldMap );
266cdf0e10cSrcweir 
267cdf0e10cSrcweir             ++nFilePostfixCount;
268cdf0e10cSrcweir         }
269cdf0e10cSrcweir     }
270cdf0e10cSrcweir 
getSurface()271cdf0e10cSrcweir     SurfaceSharedPtr DeviceHelper::getSurface()
272cdf0e10cSrcweir     {
273cdf0e10cSrcweir         return mpSurface;
274cdf0e10cSrcweir     }
275cdf0e10cSrcweir 
createSurface(const::basegfx::B2ISize & rSize,Content aContent)276cdf0e10cSrcweir     SurfaceSharedPtr DeviceHelper::createSurface( const ::basegfx::B2ISize& rSize, Content aContent )
277cdf0e10cSrcweir     {
278cdf0e10cSrcweir 		if( mpSurface )
279cdf0e10cSrcweir 			return mpSurface->getSimilar( aContent, rSize.getX(), rSize.getY() );
280cdf0e10cSrcweir 
281cdf0e10cSrcweir 		return SurfaceSharedPtr();
282cdf0e10cSrcweir     }
283cdf0e10cSrcweir 
createSurface(BitmapSystemData & rData,const Size & rSize)284cdf0e10cSrcweir     SurfaceSharedPtr DeviceHelper::createSurface( BitmapSystemData& rData, const Size& rSize )
285cdf0e10cSrcweir     {
286cdf0e10cSrcweir         if( mpRefDevice )
287cdf0e10cSrcweir             return createBitmapSurface( *mpRefDevice, rData, rSize );
288cdf0e10cSrcweir 
289cdf0e10cSrcweir         return SurfaceSharedPtr();
290cdf0e10cSrcweir     }
291cdf0e10cSrcweir }
292