28#include <com/sun/star/configuration/theDefaultProvider.hpp>
29#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
30#include <com/sun/star/container/XNameAccess.hpp>
31#include <com/sun/star/lang/IllegalArgumentException.hpp>
32#include <com/sun/star/lang/XServiceInfo.hpp>
33#include <com/sun/star/lang/XServiceName.hpp>
34#include <com/sun/star/uno/XComponentContext.hpp>
51 :
public ::cppu::WeakImplHelper< lang::XServiceInfo,
52 lang::XMultiComponentFactory,
53 lang::XMultiServiceFactory >
55 typedef std::pair< OUString, Sequence< OUString > > AvailPair;
56 typedef std::pair< OUString, OUString > CachePair;
57 typedef std::vector< AvailPair > AvailVector;
58 typedef std::vector< CachePair > CacheVector;
63 Reference<container::XNameAccess> m_xCanvasConfigNameAccess;
64 AvailVector m_aAvailableImplementations;
65 AvailVector m_aAcceleratedImplementations;
66 AvailVector m_aAAImplementations;
67 mutable CacheVector m_aCachedImplementations;
68 mutable bool m_bCacheHasForcedLastImpl;
69 mutable bool m_bCacheHasUseAcceleratedEntry;
70 mutable bool m_bCacheHasUseAAEntry;
72 void checkConfigFlag(
bool& r_bFlag,
74 const OUString& nodeName )
const;
75 Reference<XInterface>
use(
76 OUString
const & serviceName,
77 Sequence<Any>
const & args,
78 Reference<XComponentContext>
const & xContext )
const;
79 Reference<XInterface> lookupAndUse(
80 OUString
const & serviceName, Sequence<Any>
const & args,
81 Reference<XComponentContext>
const & xContext )
const;
84 virtual ~CanvasFactory()
override;
85 explicit CanvasFactory( Reference<XComponentContext>
const & xContext );
93 virtual Sequence<OUString> SAL_CALL getAvailableServiceNames()
override;
94 virtual Reference<XInterface> SAL_CALL createInstanceWithContext(
95 OUString
const & name,
96 Reference<XComponentContext>
const & xContext )
override;
97 virtual Reference<XInterface> SAL_CALL
98 createInstanceWithArgumentsAndContext(
99 OUString
const & name,
100 Sequence<Any>
const & args,
101 Reference<XComponentContext>
const & xContext )
override;
105 OUString
const & name )
override;
106 virtual Reference<XInterface> SAL_CALL createInstanceWithArguments(
107 OUString
const & name, Sequence<Any>
const & args )
override;
110CanvasFactory::CanvasFactory( Reference<XComponentContext>
const & xContext ) :
112 m_bCacheHasForcedLastImpl(),
113 m_bCacheHasUseAcceleratedEntry(),
114 m_bCacheHasUseAAEntry()
121 Reference<lang::XMultiServiceFactory> xConfigProvider(
122 configuration::theDefaultProvider::get( m_xContext ) );
126 {
"nodepath",
uno::Any(OUString(
"/org.openoffice.Office.Canvas"))}
128 m_xCanvasConfigNameAccess.set(
129 xConfigProvider->createInstanceWithArguments(
130 "com.sun.star.configuration.ConfigurationAccess",
136 {
"nodepath",
uno::Any(OUString(
"/org.openoffice.Office.Canvas/CanvasServiceList"))}
138 Reference<container::XNameAccess> xNameAccess(
139 xConfigProvider->createInstanceWithArguments(
140 "com.sun.star.configuration.ConfigurationAccess",
141 aArgs2 ), UNO_QUERY_THROW );
142 Reference<container::XHierarchicalNameAccess> xHierarchicalNameAccess(
143 xNameAccess, UNO_QUERY_THROW);
145 Sequence<OUString> serviceNames = xNameAccess->getElementNames();
146 const OUString* pCurr = serviceNames.getConstArray();
147 const OUString*
const pEnd = pCurr + serviceNames.getLength();
148 while( pCurr != pEnd )
150 Reference<container::XNameAccess> xEntryNameAccess(
151 xHierarchicalNameAccess->getByHierarchicalName(*pCurr),
154 if( xEntryNameAccess.is() )
156 Sequence<OUString> implementationList;
157 if( xEntryNameAccess->getByName(
"PreferredImplementations") >>= implementationList )
159 m_aAvailableImplementations.emplace_back(*pCurr,implementationList );
161 if( xEntryNameAccess->getByName(
"AcceleratedImplementations") >>= implementationList )
163 m_aAcceleratedImplementations.emplace_back(*pCurr,implementationList );
165 if( xEntryNameAccess->getByName(
"AntialiasingImplementations") >>= implementationList )
167 m_aAAImplementations.emplace_back(*pCurr,implementationList );
179 catch (
const Exception&)
184 if (m_aAvailableImplementations.empty())
188 m_aAvailableImplementations.emplace_back(OUString(
"com.sun.star.rendering.Canvas"),
189 Sequence<OUString>{
"com.sun.star.comp.rendering.Canvas.VCL" } );
191 m_aAvailableImplementations.emplace_back(OUString(
"com.sun.star.rendering.SpriteCanvas"),
192 Sequence<OUString>{
"com.sun.star.comp.rendering.SpriteCanvas.VCL" } );
196CanvasFactory::~CanvasFactory()
202OUString CanvasFactory::getImplementationName()
204 return "com.sun.star.comp.rendering.CanvasFactory";
207sal_Bool CanvasFactory::supportsService( OUString
const & serviceName )
212Sequence<OUString> CanvasFactory::getSupportedServiceNames()
214 return {
"com.sun.star.rendering.CanvasFactory" };
218Sequence<OUString> CanvasFactory::getAvailableServiceNames()
220 Sequence<OUString>
aServiceNames(m_aAvailableImplementations.size());
221 std::transform(m_aAvailableImplementations.begin(),
222 m_aAvailableImplementations.end(),
228Reference<XInterface> CanvasFactory::createInstanceWithContext(
229 OUString
const & name, Reference<XComponentContext>
const & xContext )
231 return createInstanceWithArgumentsAndContext(
232 name, Sequence<Any>(), xContext );
236Reference<XInterface> CanvasFactory::use(
237 OUString
const & serviceName,
238 Sequence<Any>
const & args,
239 Reference<XComponentContext>
const & xContext )
const
242 return m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
243 serviceName, args, xContext);
245 catch (css::lang::IllegalArgumentException &)
247 return Reference<XInterface>();
253 catch (
const Exception &)
255 return Reference<XInterface>();
260void CanvasFactory::checkConfigFlag(
bool& r_bFlag,
262 const OUString& nodeName )
const
264 if( m_xCanvasConfigNameAccess.is() )
266 m_xCanvasConfigNameAccess->getByName( nodeName ) >>= r_bFlag;
268 if( r_CacheFlag != r_bFlag )
272 r_CacheFlag = r_bFlag;
273 m_aCachedImplementations.clear();
279Reference<XInterface> CanvasFactory::lookupAndUse(
280 OUString
const & serviceName, Sequence<Any>
const & args,
281 Reference<XComponentContext>
const & xContext )
const
283 std::scoped_lock guard(m_mutex);
286 bool bForceLastEntry(
false);
287 checkConfigFlag( bForceLastEntry,
288 m_bCacheHasForcedLastImpl,
289 "ForceSafeServiceImpl" );
292 bool bUseAAEntry(
true);
293 checkConfigFlag( bUseAAEntry,
294 m_bCacheHasUseAAEntry,
295 "UseAntialiasingCanvas" );
298 bool bUseAcceleratedEntry(
true);
299 checkConfigFlag( bUseAcceleratedEntry,
300 m_bCacheHasUseAcceleratedEntry,
301 "UseAcceleratedCanvas" );
304 const CacheVector::iterator aEnd(m_aCachedImplementations.end());
305 auto aMatch = std::find_if(
306 m_aCachedImplementations.begin(),
308 [&serviceName](CachePair
const& cp)
309 { return serviceName == cp.first; }
311 if( aMatch != aEnd ) {
312 Reference<XInterface> xCanvas(
use( aMatch->second, args, xContext ) );
318 const AvailVector::const_iterator aAvailEnd(m_aAvailableImplementations.end());
319 auto aAvailImplsMatch = std::find_if(
320 m_aAvailableImplementations.begin(),
322 [&serviceName](AvailPair
const& ap)
323 { return serviceName == ap.first; }
325 if( aAvailImplsMatch == aAvailEnd ) {
326 return Reference<XInterface>();
329 const AvailVector::const_iterator aAAEnd(m_aAAImplementations.end());
330 auto aAAImplsMatch = std::find_if(
331 m_aAAImplementations.begin(),
333 [&serviceName](AvailPair
const& ap)
334 { return serviceName == ap.first; }
336 if( aAAImplsMatch == aAAEnd ) {
337 return Reference<XInterface>();
340 const AvailVector::const_iterator aAccelEnd(m_aAcceleratedImplementations.end());
341 auto aAccelImplsMatch = std::find_if(
342 m_aAcceleratedImplementations.begin(),
344 [&serviceName](AvailPair
const& ap)
345 { return serviceName == ap.first; }
347 if( aAccelImplsMatch == aAccelEnd ) {
348 return Reference<XInterface>();
351 const Sequence<OUString> aPreferredImpls( aAvailImplsMatch->second );
352 const OUString* pCurrImpl = aPreferredImpls.begin();
353 const OUString*
const pEndImpl = aPreferredImpls.end();
355 const Sequence<OUString> aAAImpls( aAAImplsMatch->second );
357 const Sequence<OUString> aAccelImpls( aAccelImplsMatch->second );
360 if (bForceLastEntry && pCurrImpl != pEndImpl)
361 pCurrImpl = pEndImpl-1;
363 for(; pCurrImpl != pEndImpl; ++pCurrImpl)
365 const OUString aCurrName(pCurrImpl->trim());
373 const bool bIsAcceleratedImpl(
374 std::any_of(aAccelImpls.begin(), aAccelImpls.end(),
375 [&aCurrName](OUString
const& src)
376 { return aCurrName == o3tl::trim(src); }
381 const bool bIsAAImpl(
382 std::any_of(aAAImpls.begin(), aAAImpls.end(),
383 [&aCurrName](OUString
const& src)
384 { return aCurrName == o3tl::trim(src); }
393 if( (!bIsAAImpl || bUseAAEntry) && (!bIsAcceleratedImpl || bUseAcceleratedEntry) )
395 Reference<XInterface> xCanvas(
use(aCurrName, args, xContext));
403 aMatch->second = aCurrName;
408 m_aCachedImplementations.emplace_back(serviceName, aCurrName);
416 return Reference<XInterface>();
420Reference<XInterface> CanvasFactory::createInstanceWithArgumentsAndContext(
421 OUString
const & preferredOne, Sequence<Any>
const & args,
422 Reference<XComponentContext>
const & xContext )
424 Reference<XInterface> xCanvas(lookupAndUse(preferredOne, args, xContext));
427 xCanvas =
use(preferredOne, args, xContext);
431 Reference<lang::XServiceName> xServiceName(xCanvas, uno::UNO_QUERY);
432 SAL_INFO(
"canvas",
"using " << (xServiceName.is() ? xServiceName->getServiceName()
433 : OUString(
"(unknown)")));
440Reference<XInterface> CanvasFactory::createInstance( OUString
const & name )
442 return createInstanceWithArgumentsAndContext(
443 name, Sequence<Any>(), m_xContext );
447Reference<XInterface> CanvasFactory::createInstanceWithArguments(
448 OUString
const & name, Sequence<Any>
const & args )
450 return createInstanceWithArgumentsAndContext(
451 name, args, m_xContext );
457extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
459 css::uno::Sequence<css::uno::Any>
const &)
461 return cppu::acquire(
new CanvasFactory(context));
Reference< XComponentContext > m_xContext
HRESULT createInstance(REFIID iid, Ifc **ppIfc)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_rendering_CanvasFactory_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Sequence< OUString > aServiceNames
#define SAL_INFO(area, stream)
VCL_DLLPUBLIC bool isVCLSkiaEnabled()
css::uno::Sequence< css::uno::Any > InitAnyPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)