Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <utility>
30 : :
31 : : #include <tools/prex.h>
32 : : #include <X11/extensions/Xrender.h>
33 : : #include <X11/Xlib.h>
34 : : #include <tools/postx.h>
35 : :
36 : : #include "cairo_xlib_cairo.hxx"
37 : :
38 : : #include <vcl/sysdata.hxx>
39 : : #include <vcl/bitmap.hxx>
40 : : #include <vcl/virdev.hxx>
41 : : #include <basegfx/vector/b2isize.hxx>
42 : :
43 : : namespace
44 : : {
45 : 0 : Pixmap limitXCreatePixmap(Display *display, Drawable d, unsigned int width, unsigned int height, unsigned int depth)
46 : : {
47 : : // The X protocol request CreatePixmap puts an upper bound
48 : : // of 16 bit to the size.
49 : : //
50 : : // see, e.g. moz#424333, fdo#48961
51 : : // we've a duplicate of this in vcl :-(
52 : 0 : if (width > SAL_MAX_INT16 || height > SAL_MAX_INT16)
53 : : {
54 : : SAL_WARN("canvas", "overlarge pixmap: " << width << " x " << height);
55 : 0 : return None;
56 : : }
57 : 0 : return XCreatePixmap(display, d, width, height, depth);
58 : : }
59 : : }
60 : :
61 : : namespace cairo
62 : : {
63 : :
64 : : #include <cairo-xlib.h>
65 : : #include <cairo-xlib-xrender.h>
66 : :
67 : : // TODO(F3): svp headless case!
68 : :
69 : 0 : bool IsCairoWorking( OutputDevice* pOutDev )
70 : : {
71 : 0 : if( !pOutDev )
72 : 0 : return false;
73 : :
74 : 0 : Display* pDisplay = (Display*)pOutDev->GetSystemGfxData().pDisplay;
75 : 0 : if( !pDisplay )
76 : 0 : return false;
77 : :
78 : : int nDummy;
79 : 0 : return XQueryExtension( pDisplay, "RENDER", &nDummy, &nDummy, &nDummy );
80 : : }
81 : :
82 : 0 : X11SysData::X11SysData() :
83 : : pDisplay(NULL),
84 : : hDrawable(0),
85 : : pVisual(NULL),
86 : : nScreen(0),
87 : : nDepth(-1),
88 : : aColormap(-1),
89 : 0 : pRenderFormat(NULL)
90 : 0 : {}
91 : :
92 : 0 : X11SysData::X11SysData( const SystemGraphicsData& pSysDat ) :
93 : : pDisplay(pSysDat.pDisplay),
94 : : hDrawable(pSysDat.hDrawable),
95 : : pVisual(pSysDat.pVisual),
96 : : nScreen(pSysDat.nScreen),
97 : : nDepth(pSysDat.nDepth),
98 : : aColormap(pSysDat.aColormap),
99 : 0 : pRenderFormat(pSysDat.pXRenderFormat)
100 : 0 : {}
101 : :
102 : 0 : X11SysData::X11SysData( const SystemEnvData& pSysDat ) :
103 : : pDisplay(pSysDat.pDisplay),
104 : : hDrawable(pSysDat.aWindow),
105 : : pVisual(pSysDat.pVisual),
106 : : nScreen(pSysDat.nScreen),
107 : : nDepth(pSysDat.nDepth),
108 : : aColormap(pSysDat.aColormap),
109 : 0 : pRenderFormat(NULL)
110 : 0 : {}
111 : :
112 : 0 : X11Pixmap::~X11Pixmap()
113 : : {
114 : 0 : if( mpDisplay && mhDrawable )
115 : 0 : XFreePixmap( (Display*)mpDisplay, mhDrawable );
116 : 0 : }
117 : :
118 : : /**
119 : : * Surface::Surface: Create Canvas surface with existing data
120 : : * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
121 : : * @param pSurface Cairo surface
122 : : *
123 : : * pSysData contains the platform native Drawable reference
124 : : * This constructor only stores data, it does no processing.
125 : : * It is used by e.g. Surface::getSimilar()
126 : : *
127 : : * Set the mpSurface as pSurface
128 : : **/
129 : 0 : X11Surface::X11Surface( const X11SysData& rSysData,
130 : : const X11PixmapSharedPtr& rPixmap,
131 : : const CairoSurfaceSharedPtr& pSurface ) :
132 : : maSysData(rSysData),
133 : : mpPixmap(rPixmap),
134 : 0 : mpSurface(pSurface)
135 : 0 : {}
136 : :
137 : : /**
138 : : * Surface::Surface: Create generic Canvas surface using given Cairo Surface
139 : : *
140 : : * @param pSurface Cairo Surface
141 : : *
142 : : * This constructor only stores data, it does no processing.
143 : : * It is used with e.g. cairo_image_surface_create_for_data()
144 : : * Unlike other constructors, mpSysData is set to NULL
145 : : *
146 : : * Set the mpSurface as pSurface
147 : : **/
148 : 0 : X11Surface::X11Surface( const CairoSurfaceSharedPtr& pSurface ) :
149 : : maSysData(),
150 : : mpPixmap(),
151 : 0 : mpSurface(pSurface)
152 : 0 : {}
153 : :
154 : : /**
155 : : * Surface::Surface: Create Canvas surface from Window reference.
156 : : * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
157 : : * @param x horizontal location of the new surface
158 : : * @param y vertical location of the new surface
159 : : * @param width width of the new surface
160 : : * @param height height of the new surface
161 : : *
162 : : * pSysData contains the platform native Window reference.
163 : : *
164 : : * pSysData is used to create a surface on the Window
165 : : *
166 : : * Set the mpSurface to the new surface or NULL
167 : : **/
168 : 0 : X11Surface::X11Surface( const X11SysData& rSysData, int x, int y, int width, int height ) :
169 : : maSysData(rSysData),
170 : : mpPixmap(),
171 : : mpSurface(
172 : : cairo_xlib_surface_create( (Display*)rSysData.pDisplay,
173 : : rSysData.hDrawable,
174 : : (Visual*)rSysData.pVisual,
175 : : width + x, height + y ),
176 : 0 : &cairo_surface_destroy)
177 : : {
178 : 0 : cairo_surface_set_device_offset(mpSurface.get(), x, y );
179 : 0 : }
180 : :
181 : : /**
182 : : * Surface::Surface: Create platfrom native Canvas surface from BitmapSystemData
183 : : * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
184 : : * @param pBmpData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx)
185 : : * @param width width of the new surface
186 : : * @param height height of the new surface
187 : : *
188 : : * The pBmpData provides the imagedata that the created surface should contain.
189 : : *
190 : : * Set the mpSurface to the new surface or NULL
191 : : **/
192 : 0 : X11Surface::X11Surface( const X11SysData& rSysData,
193 : : const BitmapSystemData& rData ) :
194 : : maSysData( rSysData ),
195 : : mpPixmap(),
196 : : mpSurface(
197 : : cairo_xlib_surface_create( (Display*)rSysData.pDisplay,
198 : : (Drawable)rData.aPixmap,
199 : : (Visual*) rSysData.pVisual,
200 : : rData.mnWidth, rData.mnHeight ),
201 : 0 : &cairo_surface_destroy)
202 : : {
203 : 0 : }
204 : :
205 : : /**
206 : : * Surface::getCairo: Create Cairo (drawing object) for the Canvas surface
207 : : *
208 : : * @return new Cairo or NULL
209 : : **/
210 : 0 : CairoSharedPtr X11Surface::getCairo() const
211 : : {
212 : : return CairoSharedPtr( cairo_create(mpSurface.get()),
213 : 0 : &cairo_destroy );
214 : : }
215 : :
216 : : /**
217 : : * Surface::getSimilar: Create new similar Canvas surface
218 : : * @param aContent format of the new surface (cairo_content_t from cairo/src/cairo.h)
219 : : * @param width width of the new surface
220 : : * @param height height of the new surface
221 : : *
222 : : * Creates a new Canvas surface. This normally creates platform native surface, even though
223 : : * generic function is used.
224 : : *
225 : : * Cairo surface from aContent (cairo_content_t)
226 : : *
227 : : * @return new surface or NULL
228 : : **/
229 : 0 : SurfaceSharedPtr X11Surface::getSimilar( Content aContent, int width, int height ) const
230 : : {
231 : : Pixmap hPixmap;
232 : :
233 : 0 : if( maSysData.pDisplay && maSysData.hDrawable )
234 : : {
235 : : XRenderPictFormat* pFormat;
236 : : int nFormat;
237 : :
238 : 0 : switch (aContent)
239 : : {
240 : : case CAIRO_CONTENT_ALPHA:
241 : 0 : nFormat = PictStandardA8;
242 : 0 : break;
243 : : case CAIRO_CONTENT_COLOR:
244 : 0 : nFormat = PictStandardRGB24;
245 : 0 : break;
246 : : case CAIRO_CONTENT_COLOR_ALPHA:
247 : : default:
248 : 0 : nFormat = PictStandardARGB32;
249 : 0 : break;
250 : : }
251 : :
252 : 0 : pFormat = XRenderFindStandardFormat( (Display*)maSysData.pDisplay, nFormat );
253 : : hPixmap = limitXCreatePixmap( (Display*)maSysData.pDisplay, maSysData.hDrawable,
254 : : width > 0 ? width : 1, height > 0 ? height : 1,
255 : 0 : pFormat->depth );
256 : :
257 : 0 : X11SysData aSysData(maSysData);
258 : 0 : aSysData.pRenderFormat = pFormat;
259 : : return SurfaceSharedPtr(
260 : : new X11Surface( aSysData,
261 : : X11PixmapSharedPtr(
262 : 0 : new X11Pixmap(hPixmap, maSysData.pDisplay)),
263 : : CairoSurfaceSharedPtr(
264 : : cairo_xlib_surface_create_with_xrender_format(
265 : : (Display*)maSysData.pDisplay,
266 : : hPixmap,
267 : : ScreenOfDisplay((Display *)maSysData.pDisplay, maSysData.nScreen),
268 : : pFormat, width, height ),
269 : 0 : &cairo_surface_destroy) ));
270 : : }
271 : : else
272 : : return SurfaceSharedPtr(
273 : : new X11Surface( maSysData,
274 : : X11PixmapSharedPtr(),
275 : : CairoSurfaceSharedPtr(
276 : : cairo_surface_create_similar( mpSurface.get(), aContent, width, height ),
277 : 0 : &cairo_surface_destroy )));
278 : : }
279 : :
280 : 0 : boost::shared_ptr<VirtualDevice> X11Surface::createVirtualDevice() const
281 : : {
282 : 0 : SystemGraphicsData aSystemGraphicsData;
283 : :
284 : 0 : aSystemGraphicsData.nSize = sizeof(SystemGraphicsData);
285 : 0 : aSystemGraphicsData.hDrawable = getDrawable();
286 : 0 : aSystemGraphicsData.pXRenderFormat = getRenderFormat();
287 : :
288 : : return boost::shared_ptr<VirtualDevice>(
289 : 0 : new VirtualDevice( &aSystemGraphicsData, std::max( getDepth(), 0 ) ));
290 : : }
291 : :
292 : : /**
293 : : * Surface::Resize: Resizes the Canvas surface.
294 : : * @param width new width of the surface
295 : : * @param height new height of the surface
296 : : *
297 : : * Only used on X11.
298 : : *
299 : : * @return The new surface or NULL
300 : : **/
301 : 0 : void X11Surface::Resize( int width, int height )
302 : : {
303 : 0 : cairo_xlib_surface_set_size( mpSurface.get(), width, height );
304 : 0 : }
305 : :
306 : 0 : void X11Surface::flush() const
307 : : {
308 : 0 : XSync( (Display*)maSysData.pDisplay, false );
309 : 0 : }
310 : :
311 : : /**
312 : : * Surface::getDepth: Get the color depth of the Canvas surface.
313 : : *
314 : : * @return color depth
315 : : **/
316 : 0 : int X11Surface::getDepth() const
317 : : {
318 : 0 : if( maSysData.pRenderFormat )
319 : 0 : return ((XRenderPictFormat*) maSysData.pRenderFormat)->depth;
320 : :
321 : 0 : return -1;
322 : : }
323 : :
324 : 0 : SurfaceSharedPtr createSurface( const CairoSurfaceSharedPtr& rSurface )
325 : : {
326 : 0 : return SurfaceSharedPtr(new X11Surface(rSurface));
327 : : }
328 : :
329 : 0 : static X11SysData getSysData( const Window& rWindow )
330 : : {
331 : 0 : const SystemEnvData* pSysData = GetSysData(&rWindow);
332 : :
333 : 0 : if( !pSysData )
334 : 0 : return X11SysData();
335 : : else
336 : 0 : return X11SysData(*pSysData);
337 : : }
338 : :
339 : 0 : static X11SysData getSysData( const VirtualDevice& rVirDev )
340 : : {
341 : 0 : return X11SysData( rVirDev.GetSystemGfxData() );
342 : : }
343 : :
344 : 0 : SurfaceSharedPtr createSurface( const OutputDevice& rRefDevice,
345 : : int x, int y, int width, int height )
346 : : {
347 : 0 : if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW )
348 : : return SurfaceSharedPtr(new X11Surface(getSysData((const Window&)rRefDevice),
349 : 0 : x,y,width,height));
350 : 0 : else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV )
351 : : return SurfaceSharedPtr(new X11Surface(getSysData((const VirtualDevice&)rRefDevice),
352 : 0 : x,y,width,height));
353 : : else
354 : 0 : return SurfaceSharedPtr();
355 : : }
356 : :
357 : 0 : SurfaceSharedPtr createBitmapSurface( const OutputDevice& rRefDevice,
358 : : const BitmapSystemData& rData,
359 : : const Size& rSize )
360 : : {
361 : : OSL_TRACE( "requested size: %d x %d available size: %d x %d",
362 : : rSize.Width(), rSize.Height(), rData.mnWidth, rData.mnHeight );
363 : 0 : if ( rData.mnWidth == rSize.Width() && rData.mnHeight == rSize.Height() )
364 : : {
365 : 0 : if( rRefDevice.GetOutDevType() == OUTDEV_WINDOW )
366 : 0 : return SurfaceSharedPtr(new X11Surface(getSysData((const Window&)rRefDevice), rData ));
367 : 0 : else if( rRefDevice.GetOutDevType() == OUTDEV_VIRDEV )
368 : 0 : return SurfaceSharedPtr(new X11Surface(getSysData((const VirtualDevice&)rRefDevice), rData ));
369 : : }
370 : :
371 : 0 : return SurfaceSharedPtr();
372 : : }
373 : : }
374 : :
375 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|