1*25ea7f45SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*25ea7f45SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*25ea7f45SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*25ea7f45SAndrew Rist  * distributed with this work for additional information
6*25ea7f45SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*25ea7f45SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*25ea7f45SAndrew Rist  * "License"); you may not use this file except in compliance
9*25ea7f45SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*25ea7f45SAndrew Rist  *
11*25ea7f45SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*25ea7f45SAndrew Rist  *
13*25ea7f45SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*25ea7f45SAndrew Rist  * software distributed under the License is distributed on an
15*25ea7f45SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*25ea7f45SAndrew Rist  * KIND, either express or implied.  See the License for the
17*25ea7f45SAndrew Rist  * specific language governing permissions and limitations
18*25ea7f45SAndrew Rist  * under the License.
19*25ea7f45SAndrew Rist  *
20*25ea7f45SAndrew Rist  *************************************************************/
21*25ea7f45SAndrew Rist 
22*25ea7f45SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_canvas.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <osl/mutex.hxx>
28cdf0e10cSrcweir #include <osl/process.h>
29cdf0e10cSrcweir #include <cppuhelper/implementationentry.hxx>
30cdf0e10cSrcweir #include <cppuhelper/factory.hxx>
31cdf0e10cSrcweir #include <cppuhelper/implbase3.hxx>
32cdf0e10cSrcweir #include <vcl/configsettings.hxx>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include <com/sun/star/uno/XComponentContext.hpp>
35cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
36cdf0e10cSrcweir #include <com/sun/star/lang/XSingleComponentFactory.hpp>
37cdf0e10cSrcweir #include <com/sun/star/container/XContentEnumerationAccess.hpp>
38cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp>
39cdf0e10cSrcweir #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
40cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp>
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include <boost/bind.hpp>
43cdf0e10cSrcweir #include <vector>
44cdf0e10cSrcweir #include <utility>
45cdf0e10cSrcweir #include <functional>
46cdf0e10cSrcweir #include <algorithm>
47cdf0e10cSrcweir 
48cdf0e10cSrcweir #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
49cdf0e10cSrcweir #define ARLEN(x) (sizeof (x) / sizeof *(x))
50cdf0e10cSrcweir 
51cdf0e10cSrcweir 
52cdf0e10cSrcweir using namespace ::com::sun::star;
53cdf0e10cSrcweir using namespace ::com::sun::star::uno;
54cdf0e10cSrcweir using ::rtl::OUString;
55cdf0e10cSrcweir 
56cdf0e10cSrcweir namespace
57cdf0e10cSrcweir {
58cdf0e10cSrcweir 
getImplName()59cdf0e10cSrcweir OUString SAL_CALL getImplName()
60cdf0e10cSrcweir {
61cdf0e10cSrcweir     return OUSTR("com.sun.star.comp.rendering.CanvasFactory");
62cdf0e10cSrcweir }
63cdf0e10cSrcweir 
getSuppServices()64cdf0e10cSrcweir Sequence<OUString> SAL_CALL getSuppServices()
65cdf0e10cSrcweir {
66cdf0e10cSrcweir     OUString name = OUSTR("com.sun.star.rendering.CanvasFactory");
67cdf0e10cSrcweir     return Sequence<OUString>(&name, 1);
68cdf0e10cSrcweir }
69cdf0e10cSrcweir 
70cdf0e10cSrcweir //==============================================================================
71cdf0e10cSrcweir class CanvasFactory
72cdf0e10cSrcweir     : public ::cppu::WeakImplHelper3< lang::XServiceInfo,
73cdf0e10cSrcweir                                       lang::XMultiComponentFactory,
74cdf0e10cSrcweir                                       lang::XMultiServiceFactory >
75cdf0e10cSrcweir {
76cdf0e10cSrcweir     typedef std::pair<OUString,Sequence<OUString> > AvailPair;
77cdf0e10cSrcweir     typedef std::pair<OUString,OUString>            CachePair;
78cdf0e10cSrcweir     typedef std::vector< AvailPair >                AvailVector;
79cdf0e10cSrcweir     typedef std::vector< CachePair >                CacheVector;
80cdf0e10cSrcweir 
81cdf0e10cSrcweir 
82cdf0e10cSrcweir     mutable ::osl::Mutex              m_mutex;
83cdf0e10cSrcweir     Reference<XComponentContext>      m_xContext;
84cdf0e10cSrcweir     Reference<container::XNameAccess> m_xCanvasConfigNameAccess;
85cdf0e10cSrcweir     AvailVector                       m_aAvailableImplementations;
86cdf0e10cSrcweir     AvailVector                       m_aAcceleratedImplementations;
87cdf0e10cSrcweir     AvailVector                       m_aAAImplementations;
88cdf0e10cSrcweir     mutable CacheVector               m_aCachedImplementations;
89cdf0e10cSrcweir     mutable bool                      m_bCacheHasForcedLastImpl;
90cdf0e10cSrcweir     mutable bool                      m_bCacheHasUseAcceleratedEntry;
91cdf0e10cSrcweir     mutable bool                      m_bCacheHasUseAAEntry;
92cdf0e10cSrcweir 
93cdf0e10cSrcweir     void checkConfigFlag( bool& r_bFlag,
94cdf0e10cSrcweir                           bool& r_CacheFlag,
95cdf0e10cSrcweir                           const OUString& nodeName ) const;
96cdf0e10cSrcweir     Reference<XInterface> use(
97cdf0e10cSrcweir         OUString const & serviceName,
98cdf0e10cSrcweir         Sequence<Any> const & args,
99cdf0e10cSrcweir         Reference<XComponentContext> const & xContext ) const;
100cdf0e10cSrcweir     Reference<XInterface> lookupAndUse(
101cdf0e10cSrcweir         OUString const & serviceName, Sequence<Any> const & args,
102cdf0e10cSrcweir         Reference<XComponentContext> const & xContext ) const;
103cdf0e10cSrcweir 
104cdf0e10cSrcweir public:
105cdf0e10cSrcweir     virtual ~CanvasFactory();
106cdf0e10cSrcweir     CanvasFactory( Reference<XComponentContext> const & xContext );
107cdf0e10cSrcweir 
108cdf0e10cSrcweir     // XServiceInfo
109cdf0e10cSrcweir     virtual OUString SAL_CALL getImplementationName() throw (RuntimeException);
110cdf0e10cSrcweir     virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
111cdf0e10cSrcweir         throw (RuntimeException);
112cdf0e10cSrcweir     virtual Sequence<OUString> SAL_CALL getSupportedServiceNames()
113cdf0e10cSrcweir         throw (RuntimeException);
114cdf0e10cSrcweir 
115cdf0e10cSrcweir     // XMultiComponentFactory
116cdf0e10cSrcweir     virtual Sequence<OUString> SAL_CALL getAvailableServiceNames()
117cdf0e10cSrcweir         throw (RuntimeException);
118cdf0e10cSrcweir     virtual Reference<XInterface> SAL_CALL createInstanceWithContext(
119cdf0e10cSrcweir         OUString const & name,
120cdf0e10cSrcweir         Reference<XComponentContext> const & xContext ) throw (Exception);
121cdf0e10cSrcweir     virtual Reference<XInterface> SAL_CALL
122cdf0e10cSrcweir     createInstanceWithArgumentsAndContext(
123cdf0e10cSrcweir         OUString const & name,
124cdf0e10cSrcweir         Sequence<Any> const & args,
125cdf0e10cSrcweir         Reference<XComponentContext> const & xContext ) throw (Exception);
126cdf0e10cSrcweir 
127cdf0e10cSrcweir     // XMultiServiceFactory
128cdf0e10cSrcweir     virtual Reference<XInterface> SAL_CALL createInstance(
129cdf0e10cSrcweir         OUString const & name )
130cdf0e10cSrcweir         throw (Exception);
131cdf0e10cSrcweir     virtual Reference<XInterface> SAL_CALL createInstanceWithArguments(
132cdf0e10cSrcweir         OUString const & name, Sequence<Any> const & args )
133cdf0e10cSrcweir         throw (Exception);
134cdf0e10cSrcweir };
135cdf0e10cSrcweir 
CanvasFactory(Reference<XComponentContext> const & xContext)136cdf0e10cSrcweir CanvasFactory::CanvasFactory( Reference<XComponentContext> const & xContext ) :
137cdf0e10cSrcweir     m_mutex(),
138cdf0e10cSrcweir     m_xContext(xContext),
139cdf0e10cSrcweir     m_xCanvasConfigNameAccess(),
140cdf0e10cSrcweir     m_aAvailableImplementations(),
141cdf0e10cSrcweir     m_aAcceleratedImplementations(),
142cdf0e10cSrcweir     m_aAAImplementations(),
143cdf0e10cSrcweir     m_aCachedImplementations(),
144cdf0e10cSrcweir     m_bCacheHasForcedLastImpl(),
145cdf0e10cSrcweir     m_bCacheHasUseAcceleratedEntry(),
146cdf0e10cSrcweir     m_bCacheHasUseAAEntry()
147cdf0e10cSrcweir {
148cdf0e10cSrcweir     try
149cdf0e10cSrcweir     {
150cdf0e10cSrcweir         // read out configuration for preferred services:
151cdf0e10cSrcweir         Reference<lang::XMultiServiceFactory> xConfigProvider(
152cdf0e10cSrcweir             m_xContext->getServiceManager()->createInstanceWithContext(
153cdf0e10cSrcweir                 OUSTR("com.sun.star.configuration.ConfigurationProvider"),
154cdf0e10cSrcweir                 m_xContext ), UNO_QUERY_THROW );
155cdf0e10cSrcweir 
156cdf0e10cSrcweir         Any propValue(
157cdf0e10cSrcweir             makeAny( beans::PropertyValue(
158cdf0e10cSrcweir                          OUSTR("nodepath"), -1,
159cdf0e10cSrcweir                          makeAny( OUSTR("/org.openoffice.Office.Canvas") ),
160cdf0e10cSrcweir                          beans::PropertyState_DIRECT_VALUE ) ) );
161cdf0e10cSrcweir 
162cdf0e10cSrcweir         m_xCanvasConfigNameAccess.set(
163cdf0e10cSrcweir             xConfigProvider->createInstanceWithArguments(
164cdf0e10cSrcweir                 OUSTR("com.sun.star.configuration.ConfigurationAccess"),
165cdf0e10cSrcweir                 Sequence<Any>( &propValue, 1 ) ),
166cdf0e10cSrcweir             UNO_QUERY_THROW );
167cdf0e10cSrcweir 
168cdf0e10cSrcweir         propValue = makeAny(
169cdf0e10cSrcweir             beans::PropertyValue(
170cdf0e10cSrcweir                 OUSTR("nodepath"), -1,
171cdf0e10cSrcweir                 makeAny( OUSTR("/org.openoffice.Office.Canvas/CanvasServiceList") ),
172cdf0e10cSrcweir                 beans::PropertyState_DIRECT_VALUE ) );
173cdf0e10cSrcweir 
174cdf0e10cSrcweir         Reference<container::XNameAccess> xNameAccess(
175cdf0e10cSrcweir             xConfigProvider->createInstanceWithArguments(
176cdf0e10cSrcweir                 OUSTR("com.sun.star.configuration.ConfigurationAccess"),
177cdf0e10cSrcweir                 Sequence<Any>( &propValue, 1 ) ), UNO_QUERY_THROW );
178cdf0e10cSrcweir         Reference<container::XHierarchicalNameAccess> xHierarchicalNameAccess(
179cdf0e10cSrcweir             xNameAccess, UNO_QUERY_THROW);
180cdf0e10cSrcweir 
181cdf0e10cSrcweir         Sequence<OUString> serviceNames = xNameAccess->getElementNames();
182cdf0e10cSrcweir         const OUString* pCurr = serviceNames.getConstArray();
183cdf0e10cSrcweir         const OUString* const pEnd = pCurr + serviceNames.getLength();
184cdf0e10cSrcweir         while( pCurr != pEnd )
185cdf0e10cSrcweir         {
186cdf0e10cSrcweir             Reference<container::XNameAccess> xEntryNameAccess(
187cdf0e10cSrcweir                 xHierarchicalNameAccess->getByHierarchicalName(*pCurr),
188cdf0e10cSrcweir                 UNO_QUERY );
189cdf0e10cSrcweir 
190cdf0e10cSrcweir             if( xEntryNameAccess.is() )
191cdf0e10cSrcweir             {
192cdf0e10cSrcweir                 Sequence<OUString> implementationList;
193cdf0e10cSrcweir                 if( (xEntryNameAccess->getByName( OUSTR("PreferredImplementations") ) >>= implementationList) )
194cdf0e10cSrcweir                     m_aAvailableImplementations.push_back( std::make_pair(*pCurr,implementationList) );
195cdf0e10cSrcweir                 if( (xEntryNameAccess->getByName( OUSTR("AcceleratedImplementations") ) >>= implementationList) )
196cdf0e10cSrcweir                     m_aAcceleratedImplementations.push_back( std::make_pair(*pCurr,implementationList) );
197cdf0e10cSrcweir                 if( (xEntryNameAccess->getByName( OUSTR("AntialiasingImplementations") ) >>= implementationList) )
198cdf0e10cSrcweir                     m_aAAImplementations.push_back( std::make_pair(*pCurr,implementationList) );
199cdf0e10cSrcweir             }
200cdf0e10cSrcweir 
201cdf0e10cSrcweir             ++pCurr;
202cdf0e10cSrcweir         }
203cdf0e10cSrcweir     }
204cdf0e10cSrcweir     catch (RuntimeException &)
205cdf0e10cSrcweir     {
206cdf0e10cSrcweir         throw;
207cdf0e10cSrcweir     }
208cdf0e10cSrcweir     catch (Exception&)
209cdf0e10cSrcweir     {
210cdf0e10cSrcweir     }
211cdf0e10cSrcweir 
212cdf0e10cSrcweir     if( m_aAvailableImplementations.empty() )
213cdf0e10cSrcweir     {
214cdf0e10cSrcweir         // Ugh. Looks like configuration is borked. Fake minimal
215cdf0e10cSrcweir         // setup.
216cdf0e10cSrcweir         Sequence<OUString> aServices(1);
217cdf0e10cSrcweir         aServices[0] = OUSTR("com.sun.star.comp.rendering.Canvas.VCL");
218cdf0e10cSrcweir         m_aAvailableImplementations.push_back( std::make_pair(OUSTR("com.sun.star.rendering.Canvas"),
219cdf0e10cSrcweir                                                               aServices) );
220cdf0e10cSrcweir 
221cdf0e10cSrcweir         aServices[0] = OUSTR("com.sun.star.comp.rendering.SpriteCanvas.VCL");
222cdf0e10cSrcweir         m_aAvailableImplementations.push_back( std::make_pair(OUSTR("com.sun.star.rendering.SpriteCanvas"),
223cdf0e10cSrcweir                                                               aServices) );
224cdf0e10cSrcweir     }
225cdf0e10cSrcweir }
226cdf0e10cSrcweir 
~CanvasFactory()227cdf0e10cSrcweir CanvasFactory::~CanvasFactory()
228cdf0e10cSrcweir {
229cdf0e10cSrcweir }
230cdf0e10cSrcweir 
231cdf0e10cSrcweir //------------------------------------------------------------------------------
create(Reference<XComponentContext> const & xContext)232cdf0e10cSrcweir Reference<XInterface> create( Reference<XComponentContext> const & xContext )
233cdf0e10cSrcweir {
234cdf0e10cSrcweir     return static_cast< ::cppu::OWeakObject * >(
235cdf0e10cSrcweir         new CanvasFactory( xContext ) );
236cdf0e10cSrcweir }
237cdf0e10cSrcweir 
238cdf0e10cSrcweir // XServiceInfo
239cdf0e10cSrcweir //______________________________________________________________________________
getImplementationName()240cdf0e10cSrcweir OUString CanvasFactory::getImplementationName() throw (RuntimeException)
241cdf0e10cSrcweir {
242cdf0e10cSrcweir     return getImplName();
243cdf0e10cSrcweir }
244cdf0e10cSrcweir 
245cdf0e10cSrcweir //______________________________________________________________________________
supportsService(OUString const & serviceName)246cdf0e10cSrcweir sal_Bool CanvasFactory::supportsService( OUString const & serviceName )
247cdf0e10cSrcweir     throw (RuntimeException)
248cdf0e10cSrcweir {
249cdf0e10cSrcweir     return serviceName.equals(getSuppServices()[0]);
250cdf0e10cSrcweir }
251cdf0e10cSrcweir 
252cdf0e10cSrcweir //______________________________________________________________________________
getSupportedServiceNames()253cdf0e10cSrcweir Sequence<OUString> CanvasFactory::getSupportedServiceNames()
254cdf0e10cSrcweir     throw (RuntimeException)
255cdf0e10cSrcweir {
256cdf0e10cSrcweir     return getSuppServices();
257cdf0e10cSrcweir }
258cdf0e10cSrcweir 
259cdf0e10cSrcweir // XMultiComponentFactory
260cdf0e10cSrcweir //______________________________________________________________________________
getAvailableServiceNames()261cdf0e10cSrcweir Sequence<OUString> CanvasFactory::getAvailableServiceNames()
262cdf0e10cSrcweir     throw (RuntimeException)
263cdf0e10cSrcweir {
264cdf0e10cSrcweir     Sequence<OUString> aServiceNames(m_aAvailableImplementations.size());
265cdf0e10cSrcweir     std::transform(m_aAvailableImplementations.begin(),
266cdf0e10cSrcweir                    m_aAvailableImplementations.end(),
267cdf0e10cSrcweir                    aServiceNames.getArray(),
268cdf0e10cSrcweir                    std::select1st<AvailPair>());
269cdf0e10cSrcweir     return aServiceNames;
270cdf0e10cSrcweir }
271cdf0e10cSrcweir 
272cdf0e10cSrcweir //______________________________________________________________________________
createInstanceWithContext(OUString const & name,Reference<XComponentContext> const & xContext)273cdf0e10cSrcweir Reference<XInterface> CanvasFactory::createInstanceWithContext(
274cdf0e10cSrcweir     OUString const & name, Reference<XComponentContext> const & xContext )
275cdf0e10cSrcweir     throw (Exception)
276cdf0e10cSrcweir {
277cdf0e10cSrcweir     return createInstanceWithArgumentsAndContext(
278cdf0e10cSrcweir         name, Sequence<Any>(), xContext );
279cdf0e10cSrcweir }
280cdf0e10cSrcweir 
281cdf0e10cSrcweir //______________________________________________________________________________
use(OUString const & serviceName,Sequence<Any> const & args,Reference<XComponentContext> const & xContext) const282cdf0e10cSrcweir Reference<XInterface> CanvasFactory::use(
283cdf0e10cSrcweir     OUString const & serviceName,
284cdf0e10cSrcweir     Sequence<Any> const & args,
285cdf0e10cSrcweir     Reference<XComponentContext> const & xContext ) const
286cdf0e10cSrcweir {
287cdf0e10cSrcweir     try {
288cdf0e10cSrcweir         return m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
289cdf0e10cSrcweir             serviceName, args, xContext);
290cdf0e10cSrcweir     }
291cdf0e10cSrcweir     catch (RuntimeException &)
292cdf0e10cSrcweir     {
293cdf0e10cSrcweir         throw;
294cdf0e10cSrcweir     }
295cdf0e10cSrcweir     catch (Exception &)
296cdf0e10cSrcweir     {
297cdf0e10cSrcweir         return Reference<XInterface>();
298cdf0e10cSrcweir     }
299cdf0e10cSrcweir }
300cdf0e10cSrcweir 
301cdf0e10cSrcweir //______________________________________________________________________________
checkConfigFlag(bool & r_bFlag,bool & r_CacheFlag,const OUString & nodeName) const302cdf0e10cSrcweir void CanvasFactory::checkConfigFlag( bool& r_bFlag,
303cdf0e10cSrcweir                                      bool& r_CacheFlag,
304cdf0e10cSrcweir                                      const OUString& nodeName ) const
305cdf0e10cSrcweir {
306cdf0e10cSrcweir     if( m_xCanvasConfigNameAccess.is() )
307cdf0e10cSrcweir     {
308cdf0e10cSrcweir         m_xCanvasConfigNameAccess->getByName( nodeName ) >>= r_bFlag;
309cdf0e10cSrcweir 
310cdf0e10cSrcweir         if( r_CacheFlag != r_bFlag )
311cdf0e10cSrcweir         {
312cdf0e10cSrcweir             // cache is invalid, because of different order of
313cdf0e10cSrcweir             // elements
314cdf0e10cSrcweir             r_CacheFlag = r_bFlag;
315cdf0e10cSrcweir             m_aCachedImplementations.clear();
316cdf0e10cSrcweir         }
317cdf0e10cSrcweir     }
318cdf0e10cSrcweir }
319cdf0e10cSrcweir 
320cdf0e10cSrcweir //______________________________________________________________________________
lookupAndUse(OUString const & serviceName,Sequence<Any> const & args,Reference<XComponentContext> const & xContext) const321cdf0e10cSrcweir Reference<XInterface> CanvasFactory::lookupAndUse(
322cdf0e10cSrcweir     OUString const & serviceName, Sequence<Any> const & args,
323cdf0e10cSrcweir     Reference<XComponentContext> const & xContext ) const
324cdf0e10cSrcweir {
325cdf0e10cSrcweir     ::osl::MutexGuard guard(m_mutex);
326cdf0e10cSrcweir 
327cdf0e10cSrcweir     // forcing last entry from impl list, if config flag set
328cdf0e10cSrcweir     bool bForceLastEntry(false);
329cdf0e10cSrcweir     checkConfigFlag( bForceLastEntry,
330cdf0e10cSrcweir                      m_bCacheHasForcedLastImpl,
331cdf0e10cSrcweir                      OUSTR("ForceSafeServiceImpl") );
332cdf0e10cSrcweir 
333cdf0e10cSrcweir     // use anti-aliasing canvas, if config flag set (or not existing)
334cdf0e10cSrcweir     bool bUseAAEntry(true);
335cdf0e10cSrcweir     checkConfigFlag( bUseAAEntry,
336cdf0e10cSrcweir                      m_bCacheHasUseAAEntry,
337cdf0e10cSrcweir                      OUSTR("UseAntialiasingCanvas") );
338cdf0e10cSrcweir 
339cdf0e10cSrcweir     // use accelerated canvas, if config flag set (or not existing)
340cdf0e10cSrcweir     bool bUseAcceleratedEntry(true);
341cdf0e10cSrcweir     checkConfigFlag( bUseAcceleratedEntry,
342cdf0e10cSrcweir                      m_bCacheHasUseAcceleratedEntry,
343cdf0e10cSrcweir                      OUSTR("UseAcceleratedCanvas") );
344cdf0e10cSrcweir 
345cdf0e10cSrcweir     // try to reuse last working implementation for given service name
346cdf0e10cSrcweir     const CacheVector::iterator aEnd(m_aCachedImplementations.end());
347cdf0e10cSrcweir     CacheVector::iterator aMatch;
348cdf0e10cSrcweir     if( (aMatch=std::find_if(m_aCachedImplementations.begin(),
349cdf0e10cSrcweir                              aEnd,
350cdf0e10cSrcweir                              boost::bind(&OUString::equals,
351cdf0e10cSrcweir                                          boost::cref(serviceName),
352cdf0e10cSrcweir                                          boost::bind(
353cdf0e10cSrcweir                                              std::select1st<CachePair>(),
354cdf0e10cSrcweir                                              _1)))) != aEnd )
355cdf0e10cSrcweir     {
356cdf0e10cSrcweir         Reference<XInterface> xCanvas( use( aMatch->second, args, xContext ) );
357cdf0e10cSrcweir         if(xCanvas.is())
358cdf0e10cSrcweir             return xCanvas;
359cdf0e10cSrcweir     }
360cdf0e10cSrcweir 
361cdf0e10cSrcweir     // lookup in available service list
362cdf0e10cSrcweir     const AvailVector::const_iterator aAvailEnd(m_aAvailableImplementations.end());
363cdf0e10cSrcweir     AvailVector::const_iterator aAvailImplsMatch;
364cdf0e10cSrcweir     if( (aAvailImplsMatch=std::find_if(m_aAvailableImplementations.begin(),
365cdf0e10cSrcweir                                        aAvailEnd,
366cdf0e10cSrcweir                                        boost::bind(&OUString::equals,
367cdf0e10cSrcweir                                                    boost::cref(serviceName),
368cdf0e10cSrcweir                                                    boost::bind(
369cdf0e10cSrcweir                                                        std::select1st<AvailPair>(),
370cdf0e10cSrcweir                                                        _1)))) == aAvailEnd )
371cdf0e10cSrcweir     {
372cdf0e10cSrcweir         return Reference<XInterface>();
373cdf0e10cSrcweir     }
374cdf0e10cSrcweir 
375cdf0e10cSrcweir     const AvailVector::const_iterator aAAEnd(m_aAAImplementations.end());
376cdf0e10cSrcweir     AvailVector::const_iterator aAAImplsMatch;
377cdf0e10cSrcweir     if( (aAAImplsMatch=std::find_if(m_aAAImplementations.begin(),
378cdf0e10cSrcweir                                     aAAEnd,
379cdf0e10cSrcweir                                     boost::bind(&OUString::equals,
380cdf0e10cSrcweir                                                 boost::cref(serviceName),
381cdf0e10cSrcweir                                                 boost::bind(
382cdf0e10cSrcweir                                                     std::select1st<AvailPair>(),
383cdf0e10cSrcweir                                                     _1)))) == aAAEnd )
384cdf0e10cSrcweir     {
385cdf0e10cSrcweir         return Reference<XInterface>();
386cdf0e10cSrcweir     }
387cdf0e10cSrcweir 
388cdf0e10cSrcweir     const AvailVector::const_iterator aAccelEnd(m_aAcceleratedImplementations.end());
389cdf0e10cSrcweir     AvailVector::const_iterator aAccelImplsMatch;
390cdf0e10cSrcweir     if( (aAccelImplsMatch=std::find_if(m_aAcceleratedImplementations.begin(),
391cdf0e10cSrcweir                                        aAccelEnd,
392cdf0e10cSrcweir                                        boost::bind(&OUString::equals,
393cdf0e10cSrcweir                                                    boost::cref(serviceName),
394cdf0e10cSrcweir                                                    boost::bind(
395cdf0e10cSrcweir                                                        std::select1st<AvailPair>(),
396cdf0e10cSrcweir                                                        _1)))) == aAccelEnd )
397cdf0e10cSrcweir     {
398cdf0e10cSrcweir         return Reference<XInterface>();
399cdf0e10cSrcweir     }
400cdf0e10cSrcweir 
401cdf0e10cSrcweir     const Sequence<OUString> aPreferredImpls( aAvailImplsMatch->second );
402cdf0e10cSrcweir     const OUString* pCurrImpl = aPreferredImpls.getConstArray();
403cdf0e10cSrcweir     const OUString* const pEndImpl = pCurrImpl + aPreferredImpls.getLength();
404cdf0e10cSrcweir 
405cdf0e10cSrcweir     const Sequence<OUString> aAAImpls( aAAImplsMatch->second );
406cdf0e10cSrcweir     const OUString* const pFirstAAImpl = aAAImpls.getConstArray();
407cdf0e10cSrcweir     const OUString* const pEndAAImpl = pFirstAAImpl + aAAImpls.getLength();
408cdf0e10cSrcweir 
409cdf0e10cSrcweir     const Sequence<OUString> aAccelImpls( aAccelImplsMatch->second );
410cdf0e10cSrcweir     const OUString* const pFirstAccelImpl = aAccelImpls.getConstArray();
411cdf0e10cSrcweir     const OUString* const pEndAccelImpl = pFirstAccelImpl + aAccelImpls.getLength();
412cdf0e10cSrcweir 
413cdf0e10cSrcweir     // force last entry from impl list, if config flag set
414cdf0e10cSrcweir     if( bForceLastEntry )
415cdf0e10cSrcweir         pCurrImpl = pEndImpl-1;
416cdf0e10cSrcweir 
417cdf0e10cSrcweir     while( pCurrImpl != pEndImpl )
418cdf0e10cSrcweir     {
419cdf0e10cSrcweir         const OUString aCurrName(pCurrImpl->trim());
420cdf0e10cSrcweir 
421cdf0e10cSrcweir         // check whether given canvas service is listed in the
422cdf0e10cSrcweir         // sequence of "accelerated canvas implementations"
423cdf0e10cSrcweir         const bool bIsAcceleratedImpl(
424cdf0e10cSrcweir             std::find_if(pFirstAccelImpl,
425cdf0e10cSrcweir                          pEndAccelImpl,
426cdf0e10cSrcweir                          boost::bind(&OUString::equals,
427cdf0e10cSrcweir                                      boost::cref(aCurrName),
428cdf0e10cSrcweir                                      boost::bind(
429cdf0e10cSrcweir                                          &OUString::trim,
430cdf0e10cSrcweir                                          _1))) != pEndAccelImpl );
431cdf0e10cSrcweir 
432cdf0e10cSrcweir         // check whether given canvas service is listed in the
433cdf0e10cSrcweir         // sequence of "antialiasing canvas implementations"
434cdf0e10cSrcweir         const bool bIsAAImpl(
435cdf0e10cSrcweir             std::find_if(pFirstAAImpl,
436cdf0e10cSrcweir                          pEndAAImpl,
437cdf0e10cSrcweir                          boost::bind(&OUString::equals,
438cdf0e10cSrcweir                                      boost::cref(aCurrName),
439cdf0e10cSrcweir                                      boost::bind(
440cdf0e10cSrcweir                                          &OUString::trim,
441cdf0e10cSrcweir                                          _1))) != pEndAAImpl );
442cdf0e10cSrcweir 
443cdf0e10cSrcweir         // try to instantiate canvas *only* if either accel and AA
444cdf0e10cSrcweir         // property match preference, *or*, if there's a mismatch, only
445cdf0e10cSrcweir         // go for a less capable canvas (that effectively let those
446cdf0e10cSrcweir         // pour canvas impls still work as fallbacks, should an
447cdf0e10cSrcweir         // accelerated/AA one fail). Property implies configuration:
448cdf0e10cSrcweir         // http://en.wikipedia.org/wiki/Truth_table#Logical_implication
449cdf0e10cSrcweir         if( (!bIsAAImpl || bUseAAEntry) && (!bIsAcceleratedImpl || bUseAcceleratedEntry) )
450cdf0e10cSrcweir         {
451cdf0e10cSrcweir             Reference<XInterface> xCanvas(
452cdf0e10cSrcweir                 use( pCurrImpl->trim(), args, xContext ) );
453cdf0e10cSrcweir 
454cdf0e10cSrcweir             if(xCanvas.is())
455cdf0e10cSrcweir             {
456cdf0e10cSrcweir                 if( aMatch != aEnd )
457cdf0e10cSrcweir                 {
458cdf0e10cSrcweir                     // cache entry exists, replace dysfunctional
459cdf0e10cSrcweir                     // implementation name
460cdf0e10cSrcweir                     aMatch->second = pCurrImpl->trim();
461cdf0e10cSrcweir                 }
462cdf0e10cSrcweir                 else
463cdf0e10cSrcweir                 {
464cdf0e10cSrcweir                     // new service name, add new cache entry
465cdf0e10cSrcweir                     m_aCachedImplementations.push_back(std::make_pair(serviceName,
466cdf0e10cSrcweir                                                                       pCurrImpl->trim()));
467cdf0e10cSrcweir                 }
468cdf0e10cSrcweir 
469cdf0e10cSrcweir                 return xCanvas;
470cdf0e10cSrcweir             }
471cdf0e10cSrcweir         }
472cdf0e10cSrcweir 
473cdf0e10cSrcweir         ++pCurrImpl;
474cdf0e10cSrcweir     }
475cdf0e10cSrcweir 
476cdf0e10cSrcweir     return Reference<XInterface>();
477cdf0e10cSrcweir }
478cdf0e10cSrcweir 
479cdf0e10cSrcweir //______________________________________________________________________________
createInstanceWithArgumentsAndContext(OUString const & preferredOne,Sequence<Any> const & args,Reference<XComponentContext> const & xContext)480cdf0e10cSrcweir Reference<XInterface> CanvasFactory::createInstanceWithArgumentsAndContext(
481cdf0e10cSrcweir     OUString const & preferredOne, Sequence<Any> const & args,
482cdf0e10cSrcweir     Reference<XComponentContext> const & xContext ) throw (Exception)
483cdf0e10cSrcweir {
484cdf0e10cSrcweir     Reference<XInterface> xCanvas(
485cdf0e10cSrcweir         lookupAndUse( preferredOne, args, xContext ) );
486cdf0e10cSrcweir     if(xCanvas.is())
487cdf0e10cSrcweir         return xCanvas;
488cdf0e10cSrcweir 
489cdf0e10cSrcweir     // last resort: try service name directly
490cdf0e10cSrcweir     return use( preferredOne, args, xContext );
491cdf0e10cSrcweir }
492cdf0e10cSrcweir 
493cdf0e10cSrcweir // XMultiServiceFactory
494cdf0e10cSrcweir //______________________________________________________________________________
createInstance(OUString const & name)495cdf0e10cSrcweir Reference<XInterface> CanvasFactory::createInstance( OUString const & name )
496cdf0e10cSrcweir     throw (Exception)
497cdf0e10cSrcweir {
498cdf0e10cSrcweir     return createInstanceWithArgumentsAndContext(
499cdf0e10cSrcweir         name, Sequence<Any>(), m_xContext );
500cdf0e10cSrcweir }
501cdf0e10cSrcweir 
502cdf0e10cSrcweir //______________________________________________________________________________
createInstanceWithArguments(OUString const & name,Sequence<Any> const & args)503cdf0e10cSrcweir Reference<XInterface> CanvasFactory::createInstanceWithArguments(
504cdf0e10cSrcweir     OUString const & name, Sequence<Any> const & args ) throw (Exception)
505cdf0e10cSrcweir {
506cdf0e10cSrcweir     return createInstanceWithArgumentsAndContext(
507cdf0e10cSrcweir         name, args, m_xContext );
508cdf0e10cSrcweir }
509cdf0e10cSrcweir 
510cdf0e10cSrcweir const ::cppu::ImplementationEntry s_entries [] = {
511cdf0e10cSrcweir     {
512cdf0e10cSrcweir         create,
513cdf0e10cSrcweir         getImplName,
514cdf0e10cSrcweir         getSuppServices,
515cdf0e10cSrcweir         ::cppu::createSingleComponentFactory,
516cdf0e10cSrcweir         0, 0
517cdf0e10cSrcweir     },
518cdf0e10cSrcweir     { 0, 0, 0, 0, 0, 0 }
519cdf0e10cSrcweir };
520cdf0e10cSrcweir 
521cdf0e10cSrcweir } // anon namespace
522cdf0e10cSrcweir 
523cdf0e10cSrcweir extern "C" {
524cdf0e10cSrcweir 
component_getImplementationEnvironment(const sal_Char ** ppEnvTypeName,uno_Environment **)525cdf0e10cSrcweir void SAL_CALL component_getImplementationEnvironment(
526cdf0e10cSrcweir     const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
527cdf0e10cSrcweir {
528cdf0e10cSrcweir     *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
529cdf0e10cSrcweir }
530cdf0e10cSrcweir 
component_getFactory(sal_Char const * pImplName,lang::XMultiServiceFactory * pServiceManager,registry::XRegistryKey * pRegistryKey)531cdf0e10cSrcweir void * SAL_CALL component_getFactory(
532cdf0e10cSrcweir     sal_Char const * pImplName,
533cdf0e10cSrcweir     lang::XMultiServiceFactory * pServiceManager,
534cdf0e10cSrcweir     registry::XRegistryKey * pRegistryKey )
535cdf0e10cSrcweir {
536cdf0e10cSrcweir     return ::cppu::component_getFactoryHelper(
537cdf0e10cSrcweir         pImplName, pServiceManager, pRegistryKey, s_entries );
538cdf0e10cSrcweir }
539cdf0e10cSrcweir 
540cdf0e10cSrcweir }
541cdf0e10cSrcweir 
542