1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_canvas.hxx"
31 #include <tools/prex.h>
32 #include <X11/extensions/Xrender.h>
34 #include <tools/postx.h>
36 #include "cairo_xlib_cairo.hxx"
38 #include <vcl/sysdata.hxx>
39 #include <vcl/bitmap.hxx>
40 #include <vcl/virdev.hxx>
41 #include <basegfx/vector/b2isize.hxx>
46 #include <cairo-xlib.h>
47 #include <cairo-xlib-xrender.h>
49 // TODO(F3): svp headless case!
51 bool IsCairoWorking( OutputDevice
* pOutDev
)
56 Display
* pDisplay
= (Display
*)pOutDev
->GetSystemGfxData().pDisplay
;
58 return XQueryExtension( pDisplay
, "RENDER", &nDummy
, &nDummy
, &nDummy
);
61 X11SysData::X11SysData() :
71 X11SysData::X11SysData( const SystemGraphicsData
& pSysDat
) :
72 pDisplay(pSysDat
.pDisplay
),
73 hDrawable(pSysDat
.hDrawable
),
74 pVisual(pSysDat
.pVisual
),
75 nScreen(pSysDat
.nScreen
),
76 nDepth(pSysDat
.nDepth
),
77 aColormap(pSysDat
.aColormap
),
78 pRenderFormat(pSysDat
.pRenderFormat
)
81 X11SysData::X11SysData( const SystemEnvData
& pSysDat
) :
82 pDisplay(pSysDat
.pDisplay
),
83 hDrawable(pSysDat
.aWindow
),
84 pVisual(pSysDat
.pVisual
),
85 nScreen(pSysDat
.nScreen
),
86 nDepth(pSysDat
.nDepth
),
87 aColormap(pSysDat
.aColormap
),
91 X11Pixmap::~X11Pixmap()
93 if( mpDisplay
&& mhDrawable
)
94 XFreePixmap( (Display
*)mpDisplay
, mhDrawable
);
98 * Surface::Surface: Create Canvas surface with existing data
99 * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
100 * @param pSurface Cairo surface
102 * pSysData contains the platform native Drawable reference
103 * This constructor only stores data, it does no processing.
104 * It is used by e.g. Surface::getSimilar()
106 * Set the mpSurface as pSurface
108 X11Surface::X11Surface( const X11SysData
& rSysData
,
109 const X11PixmapSharedPtr
& rPixmap
,
110 const CairoSurfaceSharedPtr
& pSurface
) :
117 * Surface::Surface: Create generic Canvas surface using given Cairo Surface
119 * @param pSurface Cairo Surface
121 * This constructor only stores data, it does no processing.
122 * It is used with e.g. cairo_image_surface_create_for_data()
123 * Unlike other constructors, mpSysData is set to NULL
125 * Set the mpSurface as pSurface
127 X11Surface::X11Surface( const CairoSurfaceSharedPtr
& pSurface
) :
134 * Surface::Surface: Create Canvas surface from Window reference.
135 * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
136 * @param x horizontal location of the new surface
137 * @param y vertical location of the new surface
138 * @param width width of the new surface
139 * @param height height of the new surface
141 * pSysData contains the platform native Window reference.
143 * pSysData is used to create a surface on the Window
145 * Set the mpSurface to the new surface or NULL
147 X11Surface::X11Surface( const X11SysData
& rSysData
, int x
, int y
, int width
, int height
) :
151 cairo_xlib_surface_create( (Display
*)rSysData
.pDisplay
,
153 (Visual
*)rSysData
.pVisual
,
154 width
+ x
, height
+ y
),
155 &cairo_surface_destroy
)
157 cairo_surface_set_device_offset(mpSurface
.get(), x
, y
);
161 * Surface::Surface: Create platfrom native Canvas surface from BitmapSystemData
162 * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
163 * @param pBmpData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx)
164 * @param width width of the new surface
165 * @param height height of the new surface
167 * The pBmpData provides the imagedata that the created surface should contain.
169 * Set the mpSurface to the new surface or NULL
171 X11Surface::X11Surface( const X11SysData
& rSysData
,
172 const BitmapSystemData
& rData
) :
173 maSysData( rSysData
),
176 cairo_xlib_surface_create( (Display
*)rSysData
.pDisplay
,
177 (Drawable
)rData
.aPixmap
,
178 (Visual
*) rSysData
.pVisual
,
179 rData
.mnWidth
, rData
.mnHeight
),
180 &cairo_surface_destroy
)
185 * Surface::getCairo: Create Cairo (drawing object) for the Canvas surface
187 * @return new Cairo or NULL
189 CairoSharedPtr
X11Surface::getCairo() const
191 return CairoSharedPtr( cairo_create(mpSurface
.get()),
196 * Surface::getSimilar: Create new similar Canvas surface
197 * @param aContent format of the new surface (cairo_content_t from cairo/src/cairo.h)
198 * @param width width of the new surface
199 * @param height height of the new surface
201 * Creates a new Canvas surface. This normally creates platform native surface, even though
202 * generic function is used.
204 * Cairo surface from aContent (cairo_content_t)
206 * @return new surface or NULL
208 SurfaceSharedPtr
X11Surface::getSimilar( Content aContent
, int width
, int height
) const
212 if( maSysData
.pDisplay
&& maSysData
.hDrawable
)
214 XRenderPictFormat
* pFormat
;
219 case CAIRO_CONTENT_ALPHA
:
220 nFormat
= PictStandardA8
;
222 case CAIRO_CONTENT_COLOR
:
223 nFormat
= PictStandardRGB24
;
225 case CAIRO_CONTENT_COLOR_ALPHA
:
227 nFormat
= PictStandardARGB32
;
231 pFormat
= XRenderFindStandardFormat( (Display
*)maSysData
.pDisplay
, nFormat
);
232 hPixmap
= XCreatePixmap( (Display
*)maSysData
.pDisplay
, maSysData
.hDrawable
,
233 width
> 0 ? width
: 1, height
> 0 ? height
: 1,
236 X11SysData
aSysData(maSysData
);
237 aSysData
.pRenderFormat
= pFormat
;
238 return SurfaceSharedPtr(
239 new X11Surface( aSysData
,
241 new X11Pixmap(hPixmap
, maSysData
.pDisplay
)),
242 CairoSurfaceSharedPtr(
243 cairo_xlib_surface_create_with_xrender_format(
244 (Display
*)maSysData
.pDisplay
,
246 ScreenOfDisplay((Display
*)maSysData
.pDisplay
, maSysData
.nScreen
),
247 pFormat
, width
, height
),
248 &cairo_surface_destroy
) ));
251 return SurfaceSharedPtr(
252 new X11Surface( maSysData
,
253 X11PixmapSharedPtr(),
254 CairoSurfaceSharedPtr(
255 cairo_surface_create_similar( mpSurface
.get(), aContent
, width
, height
),
256 &cairo_surface_destroy
)));
259 boost::shared_ptr
<VirtualDevice
> X11Surface::createVirtualDevice() const
261 SystemGraphicsData aSystemGraphicsData
;
263 aSystemGraphicsData
.nSize
= sizeof(SystemGraphicsData
);
264 aSystemGraphicsData
.hDrawable
= getDrawable();
265 aSystemGraphicsData
.pRenderFormat
= getRenderFormat();
267 return boost::shared_ptr
<VirtualDevice
>(
268 new VirtualDevice( &aSystemGraphicsData
, getDepth() ));
272 * Surface::Resize: Resizes the Canvas surface.
273 * @param width new width of the surface
274 * @param height new height of the surface
278 * @return The new surface or NULL
280 void X11Surface::Resize( int width
, int height
)
282 cairo_xlib_surface_set_size( mpSurface
.get(), width
, height
);
285 void X11Surface::flush() const
287 XSync( (Display
*)maSysData
.pDisplay
, false );
291 * Surface::getDepth: Get the color depth of the Canvas surface.
293 * @return color depth
295 int X11Surface::getDepth() const
297 if( maSysData
.pRenderFormat
)
298 return ((XRenderPictFormat
*) maSysData
.pRenderFormat
)->depth
;
303 SurfaceSharedPtr
createSurface( const CairoSurfaceSharedPtr
& rSurface
)
305 return SurfaceSharedPtr(new X11Surface(rSurface
));
308 static X11SysData
getSysData( const Window
& rWindow
)
310 const SystemEnvData
* pSysData
= GetSysData(&rWindow
);
315 return X11SysData(*pSysData
);
318 static X11SysData
getSysData( const VirtualDevice
& rVirDev
)
320 return X11SysData( rVirDev
.GetSystemGfxData() );
323 SurfaceSharedPtr
createSurface( const OutputDevice
& rRefDevice
,
324 int x
, int y
, int width
, int height
)
326 if( rRefDevice
.GetOutDevType() == OUTDEV_WINDOW
)
327 return SurfaceSharedPtr(new X11Surface(getSysData((const Window
&)rRefDevice
),
329 else if( rRefDevice
.GetOutDevType() == OUTDEV_VIRDEV
)
330 return SurfaceSharedPtr(new X11Surface(getSysData((const VirtualDevice
&)rRefDevice
),
333 return SurfaceSharedPtr();
336 SurfaceSharedPtr
createBitmapSurface( const OutputDevice
& rRefDevice
,
337 const BitmapSystemData
& rData
,
340 OSL_TRACE( "requested size: %d x %d available size: %d x %d",
341 rSize
.Width(), rSize
.Height(), rData
.mnWidth
, rData
.mnHeight
);
342 if ( rData
.mnWidth
== rSize
.Width() && rData
.mnHeight
== rSize
.Height() )
344 if( rRefDevice
.GetOutDevType() == OUTDEV_WINDOW
)
345 return SurfaceSharedPtr(new X11Surface(getSysData((const Window
&)rRefDevice
), rData
));
346 else if( rRefDevice
.GetOutDevType() == OUTDEV_VIRDEV
)
347 return SurfaceSharedPtr(new X11Surface(getSysData((const VirtualDevice
&)rRefDevice
), rData
));
350 return SurfaceSharedPtr();