2c885622afd1407aff1c0d0766a43c8e1f585460
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / renderers / renderer-factory-impl.cpp
1  /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 // CLASS HEADER
18 #include "renderer-factory-impl.h"
19
20 // EXTERNAL INCLUDES
21 #include <dali/integration-api/debug.h>
22 #include <dali/public-api/images/image.h>
23 #include <dali/public-api/object/property-array.h>
24 #include <dali/public-api/object/type-registry.h>
25 #include <dali/devel-api/object/type-registry-helper.h>
26
27 // Internal HEADER
28 #include <dali-toolkit/internal/controls/renderers/border/border-renderer.h>
29 #include <dali-toolkit/internal/controls/renderers/color/color-renderer.h>
30 #include <dali-toolkit/internal/controls/renderers/debug/debug-renderer.h>
31 #include <dali-toolkit/internal/controls/renderers/gradient/gradient-renderer.h>
32 #include <dali-toolkit/internal/controls/renderers/npatch/npatch-renderer.h>
33 #include <dali-toolkit/internal/controls/renderers/image/image-renderer.h>
34 #include <dali-toolkit/internal/controls/renderers/svg/svg-renderer.h>
35 #include <dali-toolkit/internal/controls/renderers/renderer-factory-cache.h>
36 #include <dali-toolkit/internal/controls/renderers/image-atlas-manager.h>
37
38 namespace
39 {
40 const char * const RENDERER_TYPE_NAME( "rendererType" );
41
42 const char * const COLOR_RENDERER("color");
43 const char * const BORDER_RENDERER("border");
44 const char * const GRADIENT_RENDERER("gradient");
45 const char * const IMAGE_RENDERER("image");
46 const char * const N_PATCH_RENDERER("nPatch");
47 const char * const SVG_RENDERER("svg");
48
49 const char * const BROKEN_RENDERER_IMAGE_URL( DALI_IMAGE_DIR "broken.png");
50
51 }
52
53 namespace Dali
54 {
55
56 namespace Toolkit
57 {
58
59 namespace Internal
60 {
61
62 namespace
63 {
64
65 BaseHandle Create()
66 {
67   BaseHandle handle = Toolkit::RendererFactory::Get();
68
69   return handle;
70 }
71
72 DALI_TYPE_REGISTRATION_BEGIN_CREATE( Toolkit::RendererFactory, Dali::BaseHandle, Create, true )
73 DALI_TYPE_REGISTRATION_END()
74
75 } // namespace
76
77 RendererFactory::RendererFactory( bool debugEnabled )
78 :mDebugEnabled( debugEnabled )
79 {
80 }
81
82 RendererFactory::~RendererFactory()
83 {
84 }
85
86 Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Property::Map& propertyMap )
87 {
88   ControlRenderer* rendererPtr = NULL;
89
90   Property::Value* type = propertyMap.Find( RENDERER_TYPE_NAME );
91   std::string typeValue ;
92   if( type && type->Get( typeValue ))
93   {
94     if( !mFactoryCache )
95     {
96       mFactoryCache = new RendererFactoryCache();
97     }
98
99     if( mDebugEnabled )
100     {
101       return Toolkit::ControlRenderer( new DebugRenderer( *( mFactoryCache.Get() ) ) );
102     }
103
104     if( typeValue ==  COLOR_RENDERER )
105     {
106       rendererPtr = new ColorRenderer( *( mFactoryCache.Get() ) );
107     }
108     else if( typeValue ==  GRADIENT_RENDERER )
109     {
110       rendererPtr = new GradientRenderer( *( mFactoryCache.Get() ) );
111     }
112     else if( typeValue ==  IMAGE_RENDERER )
113     {
114       CreateAtlasManager();
115       rendererPtr = new ImageRenderer( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) );
116     }
117     else if( typeValue ==  N_PATCH_RENDERER )
118     {
119       rendererPtr = new NPatchRenderer( *( mFactoryCache.Get() ) );
120     }
121     else if( typeValue == BORDER_RENDERER )
122     {
123       rendererPtr = new BorderRenderer( *( mFactoryCache.Get() ) );
124     }
125     else if( typeValue == SVG_RENDERER )
126     {
127       CreateAtlasManager();
128       rendererPtr = new SvgRenderer( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) );
129     }
130   }
131
132   if( rendererPtr )
133   {
134     Actor actor;
135     rendererPtr->Initialize( actor, propertyMap );
136   }
137   else
138   {
139     DALI_LOG_ERROR( "Renderer type unknown" );
140   }
141
142   return Toolkit::ControlRenderer( rendererPtr );
143 }
144
145 Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Vector4& color )
146 {
147   if( !mFactoryCache )
148   {
149     mFactoryCache = new RendererFactoryCache();
150   }
151
152   if( mDebugEnabled )
153   {
154     return Toolkit::ControlRenderer( new DebugRenderer( *( mFactoryCache.Get() ) ) );
155   }
156
157   ColorRenderer* rendererPtr = new ColorRenderer( *( mFactoryCache.Get() ) );
158   rendererPtr->SetColor( color );
159
160   return Toolkit::ControlRenderer( rendererPtr );
161 }
162
163 void RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const Vector4& color )
164 {
165   if( mDebugEnabled && renderer )
166   {
167     return;
168   }
169
170   if( renderer )
171   {
172     ColorRenderer* rendererPtr = dynamic_cast< ColorRenderer* >( &GetImplementation( renderer ) );
173     if( rendererPtr )
174     {
175       rendererPtr->SetColor( color );
176       return;
177     }
178
179     renderer.RemoveAndReset( actor );
180   }
181
182   renderer = GetControlRenderer( color );
183   if( actor && actor.OnStage() )
184   {
185     renderer.SetOnStage( actor );
186   }
187 }
188
189 Toolkit::ControlRenderer RendererFactory::GetControlRenderer( float borderSize, const Vector4& borderColor, bool antiAliasing )
190 {
191   if( !mFactoryCache )
192   {
193     mFactoryCache = new RendererFactoryCache();
194   }
195
196   if( mDebugEnabled )
197   {
198     return Toolkit::ControlRenderer( new DebugRenderer( *( mFactoryCache.Get() ) ) );
199   }
200
201   BorderRenderer* rendererPtr = new BorderRenderer( *mFactoryCache.Get() );
202
203   rendererPtr->SetBorderSize( borderSize );
204   rendererPtr->SetBorderColor( borderColor );
205   rendererPtr->RequireAntiAliasing( antiAliasing );
206
207   return Toolkit::ControlRenderer( rendererPtr );
208 }
209
210 Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Image& image )
211 {
212   if( !mFactoryCache )
213   {
214     mFactoryCache = new RendererFactoryCache();
215   }
216
217   if( mDebugEnabled )
218   {
219     return Toolkit::ControlRenderer( new DebugRenderer( *( mFactoryCache.Get() ) ) );
220   }
221
222   NinePatchImage npatchImage = NinePatchImage::DownCast( image );
223   if( npatchImage )
224   {
225     NPatchRenderer* rendererPtr = new NPatchRenderer( *( mFactoryCache.Get() ) );
226     rendererPtr->SetImage( npatchImage );
227
228     return Toolkit::ControlRenderer( rendererPtr );
229   }
230   else
231   {
232     CreateAtlasManager();
233     ImageRenderer* rendererPtr = new ImageRenderer( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) );
234     Actor actor;
235     rendererPtr->SetImage( actor, image );
236
237     return Toolkit::ControlRenderer( rendererPtr );
238   }
239 }
240
241 void RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const Image& image )
242 {
243   if( mDebugEnabled && renderer )
244   {
245     return;
246   }
247
248   if( renderer )
249   {
250     if( ! image )
251     {
252       // If the image is empty, then reset the renderer and return
253       renderer.RemoveAndReset( actor );
254       return;
255     }
256
257     NinePatchImage npatchImage = NinePatchImage::DownCast( image );
258     if( npatchImage )
259     {
260       NPatchRenderer* rendererPtr = dynamic_cast< NPatchRenderer* >( &GetImplementation( renderer ) );
261       if( rendererPtr )
262       {
263         rendererPtr->SetImage( npatchImage );
264         return;
265       }
266     }
267     else
268     {
269       ImageRenderer* rendererPtr = dynamic_cast< ImageRenderer* >( &GetImplementation( renderer ) );
270       if( rendererPtr )
271       {
272         rendererPtr->SetImage( actor, image );
273         return;
274       }
275     }
276
277     renderer.RemoveAndReset( actor );
278   }
279
280   renderer = GetControlRenderer( image );
281   if( actor && actor.OnStage() )
282   {
283     renderer.SetOnStage( actor );
284   }
285 }
286
287 Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const std::string& url, ImageDimensions size )
288 {
289   if( !mFactoryCache )
290   {
291     mFactoryCache = new RendererFactoryCache();
292   }
293
294   if( mDebugEnabled )
295   {
296     return Toolkit::ControlRenderer( new DebugRenderer( *( mFactoryCache.Get() ) ) );
297   }
298
299   if( NinePatchImage::IsNinePatchUrl( url ) )
300   {
301     NPatchRenderer* rendererPtr = new NPatchRenderer( *( mFactoryCache.Get() ) );
302     rendererPtr->SetImage( url );
303
304     return Toolkit::ControlRenderer( rendererPtr );
305   }
306   else if( SvgRenderer::IsSvgUrl( url ) )
307   {
308     CreateAtlasManager();
309     SvgRenderer* rendererPtr = new SvgRenderer( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) );
310     rendererPtr->SetImage( url, size );
311     return Toolkit::ControlRenderer( rendererPtr );
312   }
313   else
314   {
315     CreateAtlasManager();
316     ImageRenderer* rendererPtr = new ImageRenderer( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) );
317     Actor actor;
318     rendererPtr->SetImage( actor, url, size );
319
320     return Toolkit::ControlRenderer( rendererPtr );
321   }
322 }
323
324 void RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const std::string& url, ImageDimensions size )
325 {
326   if( mDebugEnabled && renderer )
327   {
328     return;
329   }
330
331   if( renderer )
332   {
333     if( url.empty() )
334     {
335       // If the URL is empty, then reset the renderer and return
336       renderer.RemoveAndReset( actor );
337       return;
338     }
339     else if( NinePatchImage::IsNinePatchUrl( url ) )
340     {
341       NPatchRenderer* rendererPtr = dynamic_cast< NPatchRenderer* >( &GetImplementation( renderer ) );
342       if( rendererPtr )
343       {
344         rendererPtr->SetImage( url );
345         return;
346       }
347     }
348     else if( SvgRenderer::IsSvgUrl( url ) )
349     {
350       SvgRenderer* rendererPtr = dynamic_cast< SvgRenderer* >( &GetImplementation( renderer ) );
351       if( rendererPtr )
352       {
353         rendererPtr->SetImage( url, size );
354         return;
355       }
356     }
357     else
358     {
359       ImageRenderer* rendererPtr = dynamic_cast< ImageRenderer* >( &GetImplementation( renderer ) );
360       if( rendererPtr )
361       {
362         rendererPtr->SetImage( actor, url, size );
363         return;
364       }
365     }
366
367     renderer.RemoveAndReset( actor );
368   }
369
370   renderer = GetControlRenderer( url, size );
371   if( actor && actor.OnStage() )
372   {
373     renderer.SetOnStage( actor );
374   }
375 }
376
377 void RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const Property::Map& propertyMap )
378 {
379   if( mDebugEnabled && renderer )
380   {
381     return;
382   }
383
384   if( renderer )
385   {
386     ControlRenderer& controlRenderer = GetImplementation( renderer );
387
388     Property::Value* type = propertyMap.Find( RENDERER_TYPE_NAME );
389     std::string typeValue ;
390
391     //If there's no renderer type specified or if there hasn't been a renderer type change then we can reuse the renderer
392     if( !type || !type->Get( typeValue ) ||
393         ( typeValue == IMAGE_RENDERER    && typeid( controlRenderer ) == typeid( ImageRenderer ) ) ||
394         ( typeValue == N_PATCH_RENDERER  && typeid( controlRenderer ) == typeid( NPatchRenderer ) ) ||
395         ( typeValue == COLOR_RENDERER    && typeid( controlRenderer ) == typeid( ColorRenderer ) )||
396         ( typeValue == GRADIENT_RENDERER && typeid( controlRenderer ) == typeid( GradientRenderer ) ) ||
397         ( typeValue == BORDER_RENDERER   && typeid( controlRenderer ) == typeid( BorderRenderer ) ) ||
398         ( typeValue == SVG_RENDERER      && typeid( controlRenderer ) == typeid( SvgRenderer ) ) )
399     {
400       controlRenderer.Initialize( actor, propertyMap );
401       return;
402     }
403
404     renderer.RemoveAndReset( actor );
405   }
406
407   renderer = GetControlRenderer( propertyMap );
408   if( renderer && actor && actor.OnStage() )
409   {
410     renderer.SetOnStage( actor );
411   }
412 }
413
414 Image RendererFactory::GetBrokenRendererImage()
415 {
416   return ResourceImage::New( BROKEN_RENDERER_IMAGE_URL );
417 }
418
419 void RendererFactory::CreateAtlasManager()
420 {
421   if( !mAtlasManager )
422   {
423     Shader shader = ImageRenderer::GetImageShader( *( mFactoryCache.Get() ) );
424     mAtlasManager = new ImageAtlasManager();
425     mAtlasManager->SetBrokenImage( BROKEN_RENDERER_IMAGE_URL );
426   }
427 }
428
429 } // namespace Internal
430
431 } // namespace Toolkit
432
433 } // namespace Dali
434