Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <canvas/debug.hxx>
21 : #include <canvas/verbosetrace.hxx>
22 : #include <canvas/canvastools.hxx>
23 :
24 : #include <osl/mutex.hxx>
25 : #include <cppuhelper/compbase1.hxx>
26 :
27 : #include <com/sun/star/lang/NoSupportException.hpp>
28 :
29 : #include <toolkit/helper/vclunohelper.hxx>
30 : #include <basegfx/tools/canvastools.hxx>
31 : #include <basegfx/tools/unopolypolygon.hxx>
32 :
33 : #include <vcl/canvastools.hxx>
34 : #include <vcl/dibtools.hxx>
35 :
36 : #include <tools/stream.hxx>
37 :
38 : #include "cairo_spritecanvas.hxx"
39 : #include "cairo_canvasbitmap.hxx"
40 : #include "cairo_devicehelper.hxx"
41 :
42 : using namespace ::cairo;
43 : using namespace ::com::sun::star;
44 :
45 : namespace cairocanvas
46 : {
47 3 : DeviceHelper::DeviceHelper() :
48 : mpSurfaceProvider( NULL ),
49 : mpRefDevice( NULL ),
50 3 : mpSurface()
51 : {
52 3 : }
53 :
54 2 : void DeviceHelper::implInit( SurfaceProvider& rSurfaceProvider,
55 : OutputDevice& rRefDevice )
56 : {
57 2 : mpSurfaceProvider = &rSurfaceProvider;
58 2 : mpRefDevice = &rRefDevice;
59 :
60 : // no own surface, this is handled by derived classes
61 2 : }
62 :
63 2 : void DeviceHelper::init( SurfaceProvider& rSurfaceProvider,
64 : OutputDevice& rRefDevice )
65 : {
66 2 : implInit(rSurfaceProvider, rRefDevice);
67 :
68 2 : OutputDevice* pOutDev = getOutputDevice();
69 8 : mpSurface = pOutDev->CreateSurface(pOutDev->GetOutOffXPixel(),
70 2 : pOutDev->GetOutOffYPixel(),
71 2 : pOutDev->GetOutputWidthPixel(),
72 4 : pOutDev->GetOutputHeightPixel());
73 2 : }
74 :
75 3 : void DeviceHelper::disposing()
76 : {
77 : // release all references
78 3 : mpSurface.reset();
79 3 : mpRefDevice = NULL;
80 3 : mpSurfaceProvider = NULL;
81 3 : }
82 :
83 0 : void DeviceHelper::setSize( const ::basegfx::B2ISize& rSize )
84 : {
85 : SAL_INFO(
86 : "canvas.cairo",
87 : "device size " << rSize.getX() << " x " << rSize.getY());
88 :
89 0 : if( !mpRefDevice )
90 0 : return; // disposed
91 :
92 0 : OutputDevice* pOutDev = getOutputDevice();
93 :
94 : // X11 only
95 0 : bool bReuseSurface = mpSurface &&
96 0 : mpSurface->Resize(rSize.getX() + pOutDev->GetOutOffXPixel(),
97 0 : rSize.getY() + pOutDev->GetOutOffYPixel());
98 :
99 0 : if (!bReuseSurface)
100 : {
101 0 : mpSurface = pOutDev->CreateSurface(
102 0 : pOutDev->GetOutOffXPixel(),
103 0 : pOutDev->GetOutOffYPixel(),
104 0 : rSize.getX(), rSize.getY() );
105 : }
106 : }
107 :
108 0 : geometry::RealSize2D DeviceHelper::getPhysicalResolution()
109 : {
110 : // Map a one-by-one millimeter box to pixel
111 0 : const MapMode aOldMapMode( mpRefDevice->GetMapMode() );
112 0 : mpRefDevice->SetMapMode( MapMode(MAP_MM) );
113 0 : const Size aPixelSize( mpRefDevice->LogicToPixel(Size(1,1)) );
114 0 : mpRefDevice->SetMapMode( aOldMapMode );
115 :
116 0 : return vcl::unotools::size2DFromSize( aPixelSize );
117 : }
118 :
119 0 : geometry::RealSize2D DeviceHelper::getPhysicalSize()
120 : {
121 0 : if( !mpRefDevice )
122 0 : return ::canvas::tools::createInfiniteSize2D(); // we're disposed
123 :
124 : // Map the pixel dimensions of the output window to millimeter
125 0 : const MapMode aOldMapMode( mpRefDevice->GetMapMode() );
126 0 : mpRefDevice->SetMapMode( MapMode(MAP_MM) );
127 0 : const Size aLogSize( mpRefDevice->PixelToLogic(mpRefDevice->GetOutputSizePixel()) );
128 0 : mpRefDevice->SetMapMode( aOldMapMode );
129 :
130 0 : return vcl::unotools::size2DFromSize( aLogSize );
131 : }
132 :
133 12 : uno::Reference< rendering::XLinePolyPolygon2D > DeviceHelper::createCompatibleLinePolyPolygon(
134 : const uno::Reference< rendering::XGraphicDevice >& ,
135 : const uno::Sequence< uno::Sequence< geometry::RealPoint2D > >& points )
136 : {
137 : // disposed?
138 12 : if( !mpSurfaceProvider )
139 0 : return uno::Reference< rendering::XLinePolyPolygon2D >(); // we're disposed
140 :
141 : return uno::Reference< rendering::XLinePolyPolygon2D >(
142 : new ::basegfx::unotools::UnoPolyPolygon(
143 12 : ::basegfx::unotools::polyPolygonFromPoint2DSequenceSequence( points ) ) );
144 : }
145 :
146 4 : uno::Reference< rendering::XBezierPolyPolygon2D > DeviceHelper::createCompatibleBezierPolyPolygon(
147 : const uno::Reference< rendering::XGraphicDevice >& ,
148 : const uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > >& points )
149 : {
150 : // disposed?
151 4 : if( !mpSurfaceProvider )
152 0 : return uno::Reference< rendering::XBezierPolyPolygon2D >(); // we're disposed
153 :
154 : return uno::Reference< rendering::XBezierPolyPolygon2D >(
155 : new ::basegfx::unotools::UnoPolyPolygon(
156 4 : ::basegfx::unotools::polyPolygonFromBezier2DSequenceSequence( points ) ) );
157 : }
158 :
159 0 : uno::Reference< rendering::XBitmap > DeviceHelper::createCompatibleBitmap(
160 : const uno::Reference< rendering::XGraphicDevice >& rDevice,
161 : const geometry::IntegerSize2D& size )
162 : {
163 : // disposed?
164 0 : if( !mpSurfaceProvider )
165 0 : return uno::Reference< rendering::XBitmap >(); // we're disposed
166 :
167 : return uno::Reference< rendering::XBitmap >(
168 : new CanvasBitmap(
169 : ::basegfx::unotools::b2ISizeFromIntegerSize2D( size ),
170 : SurfaceProviderRef(mpSurfaceProvider),
171 : rDevice.get(),
172 0 : false ));
173 : }
174 :
175 0 : uno::Reference< rendering::XVolatileBitmap > DeviceHelper::createVolatileBitmap(
176 : const uno::Reference< rendering::XGraphicDevice >& ,
177 : const geometry::IntegerSize2D& /*size*/ )
178 : {
179 0 : return uno::Reference< rendering::XVolatileBitmap >();
180 : }
181 :
182 2 : uno::Reference< rendering::XBitmap > DeviceHelper::createCompatibleAlphaBitmap(
183 : const uno::Reference< rendering::XGraphicDevice >& rDevice,
184 : const geometry::IntegerSize2D& size )
185 : {
186 : // disposed?
187 2 : if( !mpSurfaceProvider )
188 0 : return uno::Reference< rendering::XBitmap >(); // we're disposed
189 :
190 : return uno::Reference< rendering::XBitmap >(
191 : new CanvasBitmap(
192 : ::basegfx::unotools::b2ISizeFromIntegerSize2D( size ),
193 : SurfaceProviderRef(mpSurfaceProvider),
194 : rDevice.get(),
195 2 : true ));
196 : }
197 :
198 0 : uno::Reference< rendering::XVolatileBitmap > DeviceHelper::createVolatileAlphaBitmap(
199 : const uno::Reference< rendering::XGraphicDevice >& ,
200 : const geometry::IntegerSize2D& /*size*/ )
201 : {
202 0 : return uno::Reference< rendering::XVolatileBitmap >();
203 : }
204 :
205 0 : uno::Any DeviceHelper::isAccelerated() const
206 : {
207 0 : return ::com::sun::star::uno::makeAny(false);
208 : }
209 :
210 0 : uno::Any DeviceHelper::getDeviceHandle() const
211 : {
212 0 : return uno::makeAny( reinterpret_cast< sal_Int64 >(mpRefDevice.get()) );
213 : }
214 :
215 0 : uno::Any DeviceHelper::getSurfaceHandle() const
216 : {
217 0 : return uno::Any();
218 : }
219 :
220 : namespace
221 : {
222 : struct DeviceColorSpace: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>,
223 : DeviceColorSpace>
224 : {
225 1 : uno::Reference<rendering::XColorSpace> operator()()
226 : {
227 1 : return vcl::unotools::createStandardColorSpace();
228 : }
229 : };
230 : }
231 :
232 10 : uno::Reference<rendering::XColorSpace> DeviceHelper::getColorSpace() const
233 : {
234 : // always the same
235 10 : return DeviceColorSpace::get();
236 : }
237 :
238 0 : void DeviceHelper::dumpScreenContent() const
239 : {
240 : static sal_Int32 nFilePostfixCount(0);
241 :
242 0 : if( mpRefDevice )
243 : {
244 0 : OUString aFilename("dbg_frontbuffer");
245 0 : aFilename += OUString::number(nFilePostfixCount);
246 0 : aFilename += ".bmp";
247 :
248 0 : SvFileStream aStream( aFilename, STREAM_STD_READWRITE );
249 :
250 0 : const ::Point aEmptyPoint;
251 0 : bool bOldMap( mpRefDevice->IsMapModeEnabled() );
252 0 : mpRefDevice->EnableMapMode( false );
253 0 : const ::Bitmap aTempBitmap(mpRefDevice->GetBitmap(aEmptyPoint, mpRefDevice->GetOutputSizePixel()));
254 0 : WriteDIB(aTempBitmap, aStream, false, true);
255 0 : mpRefDevice->EnableMapMode( bOldMap );
256 :
257 0 : ++nFilePostfixCount;
258 : }
259 0 : }
260 :
261 2 : SurfaceSharedPtr DeviceHelper::createSurface( const ::basegfx::B2ISize& rSize, int aContent )
262 : {
263 2 : if( mpSurface )
264 2 : return mpSurface->getSimilar( aContent, rSize.getX(), rSize.getY() );
265 :
266 0 : return SurfaceSharedPtr();
267 : }
268 :
269 0 : SurfaceSharedPtr DeviceHelper::createSurface( BitmapSystemData& rData, const Size& rSize )
270 : {
271 0 : if (mpRefDevice)
272 0 : return mpRefDevice->CreateBitmapSurface(rData, rSize);
273 :
274 0 : return SurfaceSharedPtr();
275 : }
276 6 : }
277 :
278 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|