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 .
20 #include <config_features.h>
21 #include <vcl/skia/SkiaHelper.hxx>
23 #include <skia/x11/gdiimpl.hxx>
24 #include <skia/x11/textrender.hxx>
28 #include <X11/Xutil.h>
30 #include <basegfx/polygon/b2dpolygon.hxx>
31 #include <basegfx/polygon/b2dpolypolygon.hxx>
32 #include <basegfx/polygon/b2dpolypolygontools.hxx>
33 #include <basegfx/matrix/b2dhommatrix.hxx>
34 #include <basegfx/curve/b2dcubicbezier.hxx>
36 #include <headless/svpgdi.hxx>
38 #include <vcl/sysdata.hxx>
39 #include <vcl/virdev.hxx>
40 #include <sal/log.hxx>
41 #include <o3tl/string_view.hxx>
43 #include <unx/salunx.h>
44 #include <unx/saldisp.hxx>
45 #include <unx/salgdi.h>
46 #include <unx/x11/xlimits.hxx>
48 #include <salframe.hxx>
49 #include <salgdiimpl.hxx>
50 #include <textrender.hxx>
53 #include <unx/salframe.h>
54 #include <unx/cairotextrender.hxx>
55 #include "cairo_xlib_cairo.hxx"
56 #include <cairo-xlib.h>
58 #include "X11CairoSalGraphicsImpl.hxx"
63 X11Common::X11Common()
65 , m_pColormap(nullptr)
70 X11SalGraphics::X11SalGraphics():
76 if (SkiaHelper::isVCLSkiaEnabled())
78 mxImpl
.reset(new X11SkiaSalGraphicsImpl(*this));
79 mxTextRenderImpl
.reset(new SkiaTextRender
);
84 mxImpl
.reset(new X11CairoSalGraphicsImpl(*this, maCairoCommon
));
85 mxTextRenderImpl
.reset(new CairoTextRender(maCairoCommon
));
89 X11SalGraphics::~X11SalGraphics() COVERITY_NOEXCEPT_FALSE
92 SetDrawable(None
, nullptr, m_nXScreen
);
97 void X11SalGraphics::FreeColorMap()
99 if( m_pDeleteColormap
)
101 m_pDeleteColormap
.reset();
102 maX11Common
.m_pColormap
= nullptr;
106 SalGraphicsImpl
* X11SalGraphics::GetImpl() const
111 void X11SalGraphics::SetDrawable(Drawable aDrawable
, cairo_surface_t
* pSurface
, SalX11Screen nXScreen
)
113 maCairoCommon
.m_pSurface
= pSurface
;
114 if (maCairoCommon
.m_pSurface
)
116 maCairoCommon
.m_aFrameSize
.setX(cairo_xlib_surface_get_width(pSurface
));
117 maCairoCommon
.m_aFrameSize
.setY(cairo_xlib_surface_get_height(pSurface
));
118 dl_cairo_surface_get_device_scale(pSurface
, &maCairoCommon
.m_fScale
, nullptr);
121 // shortcut if nothing changed
122 if( maX11Common
.m_hDrawable
== aDrawable
)
125 // free screen specific resources if needed
126 if( nXScreen
!= m_nXScreen
)
129 maX11Common
.m_pColormap
= &vcl_sal::getSalDisplay(GetGenericUnixSalData())->GetColormap( nXScreen
);
130 m_nXScreen
= nXScreen
;
133 maX11Common
.m_hDrawable
= aDrawable
;
136 void X11SalGraphics::Init( X11SalFrame
& rFrame
, Drawable aTarget
,
137 SalX11Screen nXScreen
)
139 maX11Common
.m_pColormap
= &vcl_sal::getSalDisplay(GetGenericUnixSalData())->GetColormap(nXScreen
);
140 m_nXScreen
= nXScreen
;
145 SetDrawable(aTarget
, rFrame
.GetSurface(), nXScreen
);
146 mxImpl
->UpdateX11GeometryProvider();
149 void X11SalGraphics::GetResolution( sal_Int32
&rDPIX
, sal_Int32
&rDPIY
) // const
152 if ((pForceDpi
= getenv("SAL_FORCEDPI")))
154 rDPIX
= rDPIY
= o3tl::toInt32(std::string_view(pForceDpi
));
158 const SalDisplay
*pDisplay
= GetDisplay();
161 SAL_WARN( "vcl", "Null display");
166 Pair dpi
= pDisplay
->GetResolution();
172 rDPIX
= Divide( rDPIX
* 200, rDPIY
);
176 // #i12705# equalize x- and y-resolution if they are close enough
180 // different x- and y- resolutions are usually artifacts of
181 // a wrongly calculated screen size.
182 #if OSL_DEBUG_LEVEL >= 2
183 SAL_INFO("vcl.gdi", "Forcing Resolution from "
188 << std::dec
<< rDPIY
);
190 rDPIX
= rDPIY
; // y-resolution is more trustworthy
193 SystemGraphicsData
X11SalGraphics::GetGraphicsData() const
195 SystemGraphicsData aRes
;
197 aRes
.nSize
= sizeof(aRes
);
198 aRes
.pDisplay
= GetXDisplay();
199 aRes
.hDrawable
= maX11Common
.m_hDrawable
;
200 aRes
.pVisual
= GetVisual().visual
;
201 aRes
.nScreen
= m_nXScreen
.getXScreen();
205 void X11SalGraphics::Flush()
207 if( X11GraphicsImpl
* x11Impl
= dynamic_cast< X11GraphicsImpl
* >( mxImpl
.get()))
211 #if ENABLE_CAIRO_CANVAS
213 bool X11SalGraphics::SupportsCairo() const
218 cairo::SurfaceSharedPtr
X11SalGraphics::CreateSurface(const cairo::CairoSurfaceSharedPtr
& rSurface
) const
220 return std::make_shared
<cairo::X11Surface
>(rSurface
);
225 cairo::X11SysData
getSysData( const vcl::Window
& rWindow
)
227 const SystemEnvData
* pSysData
= rWindow
.GetSystemData();
230 return cairo::X11SysData();
232 return cairo::X11SysData(*pSysData
, rWindow
.ImplGetFrame());
235 cairo::X11SysData
getSysData( const VirtualDevice
& rVirDev
)
237 return cairo::X11SysData( rVirDev
.GetSystemGfxData() );
241 cairo::SurfaceSharedPtr
X11SalGraphics::CreateSurface( const OutputDevice
& rRefDevice
,
242 int x
, int y
, int width
, int height
) const
244 if( rRefDevice
.GetOutDevType() == OUTDEV_WINDOW
)
245 return std::make_shared
<cairo::X11Surface
>(getSysData(*rRefDevice
.GetOwnerWindow()),
247 if( rRefDevice
.IsVirtual() )
248 return std::make_shared
<cairo::X11Surface
>(getSysData(static_cast<const VirtualDevice
&>(rRefDevice
)),
250 return cairo::SurfaceSharedPtr();
253 cairo::SurfaceSharedPtr
X11SalGraphics::CreateBitmapSurface( const OutputDevice
& rRefDevice
,
254 const BitmapSystemData
& rData
,
255 const Size
& rSize
) const
257 SAL_INFO("vcl", "requested size: " << rSize
.Width() << " x " << rSize
.Height()
258 << " available size: " << rData
.mnWidth
<< " x "
260 if ( rData
.mnWidth
== rSize
.Width() && rData
.mnHeight
== rSize
.Height() )
262 if( rRefDevice
.GetOutDevType() == OUTDEV_WINDOW
)
263 return std::make_shared
<cairo::X11Surface
>(getSysData(*rRefDevice
.GetOwnerWindow()), rData
);
264 else if( rRefDevice
.IsVirtual() )
265 return std::make_shared
<cairo::X11Surface
>(getSysData(static_cast<const VirtualDevice
&>(rRefDevice
)), rData
);
268 return cairo::SurfaceSharedPtr();
271 css::uno::Any
X11SalGraphics::GetNativeSurfaceHandle(cairo::SurfaceSharedPtr
& rSurface
, const basegfx::B2ISize
& /*rSize*/) const
273 cairo::X11Surface
& rXlibSurface
=dynamic_cast<cairo::X11Surface
&>(*rSurface
);
274 css::uno::Sequence
< css::uno::Any
> args
{
275 css::uno::Any(false), // do not call XFreePixmap on it
276 css::uno::Any(sal_Int64(rXlibSurface
.getPixmap()->mhDrawable
))
278 return css::uno::Any(args
);
281 #endif // ENABLE_CAIRO_CANVAS
283 SalGeometryProvider
*X11SalGraphics::GetGeometryProvider() const
286 return static_cast< SalGeometryProvider
* >(m_pFrame
);
288 return static_cast< SalGeometryProvider
* >(m_pVDev
);
291 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */