[dali_1.1.40] Merge branch 'devel/master'
[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 <dali-toolkit/internal/controls/renderers/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/public-api/object/type-registry-helper.h>
26
27 // INTERNAL INCLUDES
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/mesh/mesh-renderer.h>
36 #include <dali-toolkit/internal/controls/renderers/renderer-factory-cache.h>
37 #include <dali-toolkit/internal/controls/renderers/renderer-string-constants.h>
38 #include <dali-toolkit/internal/controls/renderers/image-atlas-manager.h>
39
40 namespace
41 {
42 const char * const BROKEN_RENDERER_IMAGE_URL( DALI_IMAGE_DIR "broken.png");
43 }
44
45 namespace Dali
46 {
47
48 namespace Toolkit
49 {
50
51 namespace Internal
52 {
53
54 namespace
55 {
56
57 BaseHandle Create()
58 {
59   BaseHandle handle = Toolkit::RendererFactory::Get();
60
61   return handle;
62 }
63
64 DALI_TYPE_REGISTRATION_BEGIN_CREATE( Toolkit::RendererFactory, Dali::BaseHandle, Create, true )
65 DALI_TYPE_REGISTRATION_END()
66
67 } // namespace
68
69 RendererFactory::RendererFactory( bool debugEnabled )
70 :mDebugEnabled( debugEnabled )
71 {
72 }
73
74 RendererFactory::~RendererFactory()
75 {
76 }
77
78 RendererFactory::RendererType RendererFactory::GetRendererType( const Property::Map& propertyMap )
79 {
80   RendererType rendererType = UNDEFINED;
81
82   Property::Value* type = propertyMap.Find( RENDERER_TYPE );
83   std::string typeValue ;
84   if( type && type->Get( typeValue ))
85   {
86     if( typeValue == COLOR_RENDERER )
87     {
88       rendererType = COLOR;
89     }
90     else if( typeValue == BORDER_RENDERER )
91     {
92       rendererType = BORDER;
93     }
94     else if( typeValue == GRADIENT_RENDERER )
95     {
96       rendererType = GRADIENT;
97     }
98     else if( typeValue == IMAGE_RENDERER )
99     {
100       rendererType = IMAGE;
101     }
102     else if( typeValue == MESH_RENDERER )
103     {
104       rendererType = MESH;
105     }
106   }
107
108   // check the url if exist, to decide the renderer type
109   if( rendererType == IMAGE || rendererType == UNDEFINED )
110   {
111     Property::Value* imageURLValue = propertyMap.Find( IMAGE_URL_NAME );
112     std::string imageUrl;
113     if( imageURLValue && imageURLValue->Get( imageUrl ))
114     {
115       if( NinePatchImage::IsNinePatchUrl( imageUrl ) )
116       {
117         rendererType = N_PATCH;
118       }
119       else if( SvgRenderer::IsSvgUrl( imageUrl ) )
120       {
121         rendererType = SVG;
122       }
123       else
124       {
125         rendererType = IMAGE;
126       }
127     }
128   }
129
130   return rendererType;
131 }
132
133 Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Property::Map& propertyMap )
134 {
135   ControlRenderer* rendererPtr = NULL;
136
137   RendererType type = GetRendererType( propertyMap );
138   if( type != UNDEFINED)
139   {
140     if( !mFactoryCache )
141     {
142       mFactoryCache = new RendererFactoryCache();
143     }
144
145     if( mDebugEnabled )
146     {
147       return Toolkit::ControlRenderer( new DebugRenderer( *( mFactoryCache.Get() ) ) );
148     }
149   }
150
151   switch( type )
152   {
153     case COLOR:
154     {
155       rendererPtr = new ColorRenderer( *( mFactoryCache.Get() ) );
156       break;
157     }
158      case GRADIENT:
159      {
160        rendererPtr = new GradientRenderer( *( mFactoryCache.Get() ) );
161        break;
162      }
163     case BORDER:
164     {
165       rendererPtr = new BorderRenderer( *( mFactoryCache.Get() ) );
166       break;
167     }
168     case IMAGE:
169     {
170       CreateAtlasManager();
171       rendererPtr = new ImageRenderer( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) );
172       break;
173     }
174     case N_PATCH:
175     {
176       rendererPtr = new NPatchRenderer( *( mFactoryCache.Get() ) );
177       break;
178     }
179     case SVG:
180     {
181       CreateAtlasManager();
182       rendererPtr = new SvgRenderer( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) );
183       break;
184     }
185     case MESH:
186     {
187       rendererPtr = new MeshRenderer( *( mFactoryCache.Get() ) );
188       break;
189     }
190     case UNDEFINED:
191     default:
192     {
193       break;
194     }
195   }
196
197   if( rendererPtr )
198   {
199     Actor actor;
200     rendererPtr->Initialize( actor, propertyMap );
201   }
202   else
203   {
204     DALI_LOG_ERROR( "Renderer type unknown" );
205   }
206
207   return Toolkit::ControlRenderer( rendererPtr );
208 }
209
210 Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Vector4& color )
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   ColorRenderer* rendererPtr = new ColorRenderer( *( mFactoryCache.Get() ) );
223   rendererPtr->SetColor( color );
224
225   return Toolkit::ControlRenderer( rendererPtr );
226 }
227
228 void RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const Vector4& color )
229 {
230   if( mDebugEnabled && renderer )
231   {
232     return;
233   }
234
235   if( renderer )
236   {
237     ColorRenderer* rendererPtr = dynamic_cast< ColorRenderer* >( &GetImplementation( renderer ) );
238     if( rendererPtr )
239     {
240       rendererPtr->SetColor( color );
241       return;
242     }
243
244     renderer.RemoveAndReset( actor );
245   }
246
247   renderer = GetControlRenderer( color );
248   if( actor && actor.OnStage() )
249   {
250     renderer.SetOnStage( actor );
251   }
252 }
253
254 Toolkit::ControlRenderer RendererFactory::GetControlRenderer( float borderSize, const Vector4& borderColor, bool antiAliasing )
255 {
256   if( !mFactoryCache )
257   {
258     mFactoryCache = new RendererFactoryCache();
259   }
260
261   if( mDebugEnabled )
262   {
263     return Toolkit::ControlRenderer( new DebugRenderer( *( mFactoryCache.Get() ) ) );
264   }
265
266   BorderRenderer* rendererPtr = new BorderRenderer( *mFactoryCache.Get() );
267
268   rendererPtr->SetBorderSize( borderSize );
269   rendererPtr->SetBorderColor( borderColor );
270   rendererPtr->RequireAntiAliasing( antiAliasing );
271
272   return Toolkit::ControlRenderer( rendererPtr );
273 }
274
275 Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const Image& image )
276 {
277   if( !mFactoryCache )
278   {
279     mFactoryCache = new RendererFactoryCache();
280   }
281
282   if( mDebugEnabled )
283   {
284     return Toolkit::ControlRenderer( new DebugRenderer( *( mFactoryCache.Get() ) ) );
285   }
286
287   NinePatchImage npatchImage = NinePatchImage::DownCast( image );
288   if( npatchImage )
289   {
290     NPatchRenderer* rendererPtr = new NPatchRenderer( *( mFactoryCache.Get() ) );
291     rendererPtr->SetImage( npatchImage );
292
293     return Toolkit::ControlRenderer( rendererPtr );
294   }
295   else
296   {
297     CreateAtlasManager();
298     ImageRenderer* rendererPtr = new ImageRenderer( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) );
299     Actor actor;
300     rendererPtr->SetImage( actor, image );
301
302     return Toolkit::ControlRenderer( rendererPtr );
303   }
304 }
305
306 void RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const Image& image )
307 {
308   if( mDebugEnabled && renderer )
309   {
310     return;
311   }
312
313   if( renderer )
314   {
315     if( ! image )
316     {
317       // If the image is empty, then reset the renderer and return
318       renderer.RemoveAndReset( actor );
319       return;
320     }
321
322     NinePatchImage npatchImage = NinePatchImage::DownCast( image );
323     if( npatchImage )
324     {
325       NPatchRenderer* rendererPtr = dynamic_cast< NPatchRenderer* >( &GetImplementation( renderer ) );
326       if( rendererPtr )
327       {
328         rendererPtr->SetImage( npatchImage );
329         return;
330       }
331     }
332     else
333     {
334       ImageRenderer* rendererPtr = dynamic_cast< ImageRenderer* >( &GetImplementation( renderer ) );
335       if( rendererPtr )
336       {
337         rendererPtr->SetImage( actor, image );
338         return;
339       }
340     }
341
342     renderer.RemoveAndReset( actor );
343   }
344
345   renderer = GetControlRenderer( image );
346   if( actor && actor.OnStage() )
347   {
348     renderer.SetOnStage( actor );
349   }
350 }
351
352 Toolkit::ControlRenderer RendererFactory::GetControlRenderer( const std::string& url, ImageDimensions size )
353 {
354   if( !mFactoryCache )
355   {
356     mFactoryCache = new RendererFactoryCache();
357   }
358
359   if( mDebugEnabled )
360   {
361     return Toolkit::ControlRenderer( new DebugRenderer( *( mFactoryCache.Get() ) ) );
362   }
363
364   if( NinePatchImage::IsNinePatchUrl( url ) )
365   {
366     NPatchRenderer* rendererPtr = new NPatchRenderer( *( mFactoryCache.Get() ) );
367     rendererPtr->SetImage( url );
368
369     return Toolkit::ControlRenderer( rendererPtr );
370   }
371   else if( SvgRenderer::IsSvgUrl( url ) )
372   {
373     CreateAtlasManager();
374     SvgRenderer* rendererPtr = new SvgRenderer( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) );
375     rendererPtr->SetImage( url, size );
376     return Toolkit::ControlRenderer( rendererPtr );
377   }
378   else
379   {
380     CreateAtlasManager();
381     ImageRenderer* rendererPtr = new ImageRenderer( *( mFactoryCache.Get() ), *( mAtlasManager.Get() ) );
382     Actor actor;
383     rendererPtr->SetImage( actor, url, size );
384
385     return Toolkit::ControlRenderer( rendererPtr );
386   }
387 }
388
389 void RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const std::string& url, ImageDimensions size )
390 {
391   if( mDebugEnabled && renderer )
392   {
393     return;
394   }
395
396   if( renderer )
397   {
398     if( url.empty() )
399     {
400       // If the URL is empty, then reset the renderer and return
401       renderer.RemoveAndReset( actor );
402       return;
403     }
404     else if( NinePatchImage::IsNinePatchUrl( url ) )
405     {
406       NPatchRenderer* rendererPtr = dynamic_cast< NPatchRenderer* >( &GetImplementation( renderer ) );
407       if( rendererPtr )
408       {
409         rendererPtr->SetImage( url );
410         return;
411       }
412     }
413     else if( SvgRenderer::IsSvgUrl( url ) )
414     {
415       SvgRenderer* rendererPtr = dynamic_cast< SvgRenderer* >( &GetImplementation( renderer ) );
416       if( rendererPtr )
417       {
418         rendererPtr->SetImage( url, size );
419         return;
420       }
421     }
422     else
423     {
424       ImageRenderer* rendererPtr = dynamic_cast< ImageRenderer* >( &GetImplementation( renderer ) );
425       if( rendererPtr )
426       {
427         rendererPtr->SetImage( actor, url, size );
428         return;
429       }
430     }
431
432     renderer.RemoveAndReset( actor );
433   }
434
435   renderer = GetControlRenderer( url, size );
436   if( actor && actor.OnStage() )
437   {
438     renderer.SetOnStage( actor );
439   }
440 }
441
442 void RendererFactory::ResetRenderer( Toolkit::ControlRenderer& renderer, Actor& actor, const Property::Map& propertyMap )
443 {
444   if( mDebugEnabled && renderer )
445   {
446     return;
447   }
448
449   if( renderer )
450   {
451     ControlRenderer& controlRenderer = GetImplementation( renderer );
452
453     RendererType type = GetRendererType( propertyMap );
454
455     //If there's no renderer type specified or if there hasn't been a renderer type change then we can reuse the renderer
456     if( type == UNDEFINED ||
457         ( type == IMAGE     && typeid( controlRenderer ) == typeid( ImageRenderer ) ) ||
458         ( type == N_PATCH   && typeid( controlRenderer ) == typeid( NPatchRenderer ) ) ||
459         ( type == COLOR     && typeid( controlRenderer ) == typeid( ColorRenderer ) ) ||
460         ( type == GRADIENT  && typeid( controlRenderer ) == typeid( GradientRenderer ) ) ||
461         ( type == BORDER    && typeid( controlRenderer ) == typeid( BorderRenderer ) ) ||
462         ( type == SVG       && typeid( controlRenderer ) == typeid( SvgRenderer ) ) ||
463         ( type == MESH      && typeid( controlRenderer ) == typeid( MeshRenderer ) ) )
464     {
465       controlRenderer.Initialize( actor, propertyMap );
466       return;
467     }
468
469     renderer.RemoveAndReset( actor );
470   }
471
472   renderer = GetControlRenderer( propertyMap );
473   if( renderer && actor && actor.OnStage() )
474   {
475     renderer.SetOnStage( actor );
476   }
477 }
478
479 Image RendererFactory::GetBrokenRendererImage()
480 {
481   return ResourceImage::New( BROKEN_RENDERER_IMAGE_URL );
482 }
483
484 void RendererFactory::CreateAtlasManager()
485 {
486   if( !mAtlasManager )
487   {
488     Shader shader = ImageRenderer::GetImageShader( *( mFactoryCache.Get() ) );
489     mAtlasManager = new ImageAtlasManager();
490     mAtlasManager->SetBrokenImage( BROKEN_RENDERER_IMAGE_URL );
491   }
492 }
493
494 } // namespace Internal
495
496 } // namespace Toolkit
497
498 } // namespace Dali