1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
23 #include <X11/extensions/Xrender.h>
27 #include "cairo_xlib_cairo.hxx"
29 #include <vcl/sysdata.hxx>
30 #include <vcl/bitmap.hxx>
31 #include <vcl/virdev.hxx>
32 #include <basegfx/vector/b2isize.hxx>
36 Pixmap
limitXCreatePixmap(Display
*display
, Drawable d
, unsigned int width
, unsigned int height
, unsigned int depth
)
38 // The X protocol request CreatePixmap puts an upper bound
39 // of 16 bit to the size.
41 // see, e.g. moz#424333, fdo#48961
42 // we've a duplicate of this in vcl :-(
43 if (width
> SAL_MAX_INT16
|| height
> SAL_MAX_INT16
)
45 SAL_WARN("canvas", "overlarge pixmap: " << width
<< " x " << height
);
48 return XCreatePixmap(display
, d
, width
, height
, depth
);
55 #include <cairo-xlib.h>
56 #include <cairo-xlib-xrender.h>
58 // TODO(F3): svp headless case!
60 bool IsCairoWorking( OutputDevice
* pOutDev
)
65 Display
* pDisplay
= (Display
*)pOutDev
->GetSystemGfxData().pDisplay
;
70 return XQueryExtension( pDisplay
, "RENDER", &nDummy
, &nDummy
, &nDummy
);
73 X11SysData::X11SysData() :
83 X11SysData::X11SysData( const SystemGraphicsData
& pSysDat
) :
84 pDisplay(pSysDat
.pDisplay
),
85 hDrawable(pSysDat
.hDrawable
),
86 pVisual(pSysDat
.pVisual
),
87 nScreen(pSysDat
.nScreen
),
88 nDepth(pSysDat
.nDepth
),
89 aColormap(pSysDat
.aColormap
),
90 pRenderFormat(pSysDat
.pXRenderFormat
)
93 X11SysData::X11SysData( const SystemEnvData
& pSysDat
) :
94 pDisplay(pSysDat
.pDisplay
),
95 hDrawable(pSysDat
.aWindow
),
96 pVisual(pSysDat
.pVisual
),
97 nScreen(pSysDat
.nScreen
),
98 nDepth(pSysDat
.nDepth
),
99 aColormap(pSysDat
.aColormap
),
103 X11Pixmap::~X11Pixmap()
105 if( mpDisplay
&& mhDrawable
)
106 XFreePixmap( (Display
*)mpDisplay
, mhDrawable
);
110 * Surface::Surface: Create Canvas surface with existing data
111 * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
112 * @param pSurface Cairo surface
114 * pSysData contains the platform native Drawable reference
115 * This constructor only stores data, it does no processing.
116 * It is used by e.g. Surface::getSimilar()
118 * Set the mpSurface as pSurface
120 X11Surface::X11Surface( const X11SysData
& rSysData
,
121 const X11PixmapSharedPtr
& rPixmap
,
122 const CairoSurfaceSharedPtr
& pSurface
) :
129 * Surface::Surface: Create generic Canvas surface using given Cairo Surface
131 * @param pSurface Cairo Surface
133 * This constructor only stores data, it does no processing.
134 * It is used with e.g. cairo_image_surface_create_for_data()
135 * Unlike other constructors, mpSysData is set to NULL
137 * Set the mpSurface as pSurface
139 X11Surface::X11Surface( const CairoSurfaceSharedPtr
& pSurface
) :
146 * Surface::Surface: Create Canvas surface from Window reference.
147 * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
148 * @param x horizontal location of the new surface
149 * @param y vertical location of the new surface
150 * @param width width of the new surface
151 * @param height height of the new surface
153 * pSysData contains the platform native Window reference.
155 * pSysData is used to create a surface on the Window
157 * Set the mpSurface to the new surface or NULL
159 X11Surface::X11Surface( const X11SysData
& rSysData
, int x
, int y
, int width
, int height
) :
163 cairo_xlib_surface_create( (Display
*)rSysData
.pDisplay
,
165 (Visual
*)rSysData
.pVisual
,
166 width
+ x
, height
+ y
),
167 &cairo_surface_destroy
)
169 cairo_surface_set_device_offset(mpSurface
.get(), x
, y
);
173 * Surface::Surface: Create platfrom native Canvas surface from BitmapSystemData
174 * @param pSysData Platform native system environment data (struct SystemEnvData in vcl/inc/sysdata.hxx)
175 * @param pBmpData Platform native image data (struct BitmapSystemData in vcl/inc/bitmap.hxx)
176 * @param width width of the new surface
177 * @param height height of the new surface
179 * The pBmpData provides the imagedata that the created surface should contain.
181 * Set the mpSurface to the new surface or NULL
183 X11Surface::X11Surface( const X11SysData
& rSysData
,
184 const BitmapSystemData
& rData
) :
185 maSysData( rSysData
),
188 cairo_xlib_surface_create( (Display
*)rSysData
.pDisplay
,
189 (Drawable
)rData
.aPixmap
,
190 (Visual
*) rSysData
.pVisual
,
191 rData
.mnWidth
, rData
.mnHeight
),
192 &cairo_surface_destroy
)
197 * Surface::getCairo: Create Cairo (drawing object) for the Canvas surface
199 * @return new Cairo or NULL
201 CairoSharedPtr
X11Surface::getCairo() const
203 return CairoSharedPtr( cairo_create(mpSurface
.get()),
208 * Surface::getSimilar: Create new similar Canvas surface
209 * @param aContent format of the new surface (cairo_content_t from cairo/src/cairo.h)
210 * @param width width of the new surface
211 * @param height height of the new surface
213 * Creates a new Canvas surface. This normally creates platform native surface, even though
214 * generic function is used.
216 * Cairo surface from aContent (cairo_content_t)
218 * @return new surface or NULL
220 SurfaceSharedPtr
X11Surface::getSimilar( Content aContent
, int width
, int height
) const
224 if( maSysData
.pDisplay
&& maSysData
.hDrawable
)
226 XRenderPictFormat
* pFormat
;
231 case CAIRO_CONTENT_ALPHA
:
232 nFormat
= PictStandardA8
;
234 case CAIRO_CONTENT_COLOR
:
235 nFormat
= PictStandardRGB24
;
237 case CAIRO_CONTENT_COLOR_ALPHA
:
239 nFormat
= PictStandardARGB32
;
243 pFormat
= XRenderFindStandardFormat( (Display
*)maSysData
.pDisplay
, nFormat
);
244 hPixmap
= limitXCreatePixmap( (Display
*)maSysData
.pDisplay
, maSysData
.hDrawable
,
245 width
> 0 ? width
: 1, height
> 0 ? height
: 1,
248 X11SysData
aSysData(maSysData
);
249 aSysData
.pRenderFormat
= pFormat
;
250 return SurfaceSharedPtr(
251 new X11Surface( aSysData
,
253 new X11Pixmap(hPixmap
, maSysData
.pDisplay
)),
254 CairoSurfaceSharedPtr(
255 cairo_xlib_surface_create_with_xrender_format(
256 (Display
*)maSysData
.pDisplay
,
258 ScreenOfDisplay((Display
*)maSysData
.pDisplay
, maSysData
.nScreen
),
259 pFormat
, width
, height
),
260 &cairo_surface_destroy
) ));
263 return SurfaceSharedPtr(
264 new X11Surface( maSysData
,
265 X11PixmapSharedPtr(),
266 CairoSurfaceSharedPtr(
267 cairo_surface_create_similar( mpSurface
.get(), aContent
, width
, height
),
268 &cairo_surface_destroy
)));
271 boost::shared_ptr
<VirtualDevice
> X11Surface::createVirtualDevice() const
273 SystemGraphicsData aSystemGraphicsData
;
275 aSystemGraphicsData
.nSize
= sizeof(SystemGraphicsData
);
276 aSystemGraphicsData
.hDrawable
= getDrawable();
277 aSystemGraphicsData
.pXRenderFormat
= getRenderFormat();
279 return boost::shared_ptr
<VirtualDevice
>(
280 new VirtualDevice( &aSystemGraphicsData
, std::max( getDepth(), 0 ) ));
284 * Surface::Resize: Resizes the Canvas surface.
285 * @param width new width of the surface
286 * @param height new height of the surface
290 * @return The new surface or NULL
292 void X11Surface::Resize( int width
, int height
)
294 cairo_xlib_surface_set_size( mpSurface
.get(), width
, height
);
297 void X11Surface::flush() const
299 XSync( (Display
*)maSysData
.pDisplay
, false );
303 * Surface::getDepth: Get the color depth of the Canvas surface.
305 * @return color depth
307 int X11Surface::getDepth() const
309 if( maSysData
.pRenderFormat
)
310 return ((XRenderPictFormat
*) maSysData
.pRenderFormat
)->depth
;
315 SurfaceSharedPtr
createSurface( const CairoSurfaceSharedPtr
& rSurface
)
317 return SurfaceSharedPtr(new X11Surface(rSurface
));
320 static X11SysData
getSysData( const Window
& rWindow
)
322 const SystemEnvData
* pSysData
= GetSysData(&rWindow
);
327 return X11SysData(*pSysData
);
330 static X11SysData
getSysData( const VirtualDevice
& rVirDev
)
332 return X11SysData( rVirDev
.GetSystemGfxData() );
335 SurfaceSharedPtr
createSurface( const OutputDevice
& rRefDevice
,
336 int x
, int y
, int width
, int height
)
338 if( rRefDevice
.GetOutDevType() == OUTDEV_WINDOW
)
339 return SurfaceSharedPtr(new X11Surface(getSysData((const Window
&)rRefDevice
),
341 else if( rRefDevice
.GetOutDevType() == OUTDEV_VIRDEV
)
342 return SurfaceSharedPtr(new X11Surface(getSysData((const VirtualDevice
&)rRefDevice
),
345 return SurfaceSharedPtr();
348 SurfaceSharedPtr
createBitmapSurface( const OutputDevice
& rRefDevice
,
349 const BitmapSystemData
& rData
,
352 OSL_TRACE( "requested size: %d x %d available size: %d x %d",
353 rSize
.Width(), rSize
.Height(), rData
.mnWidth
, rData
.mnHeight
);
354 if ( rData
.mnWidth
== rSize
.Width() && rData
.mnHeight
== rSize
.Height() )
356 if( rRefDevice
.GetOutDevType() == OUTDEV_WINDOW
)
357 return SurfaceSharedPtr(new X11Surface(getSysData((const Window
&)rRefDevice
), rData
));
358 else if( rRefDevice
.GetOutDevType() == OUTDEV_VIRDEV
)
359 return SurfaceSharedPtr(new X11Surface(getSysData((const VirtualDevice
&)rRefDevice
), rData
));
362 return SurfaceSharedPtr();
366 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */