Merge "Added pixel format to fix bug with ktx loader" into devel/graphics
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / visual-factory-impl.cpp
1 /*
2  * Copyright (c) 2021 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/visuals/visual-factory-impl.h>
19
20 // EXTERNAL INCLUDES
21 #include <dali/devel-api/scripting/scripting.h>
22 #include <dali/integration-api/debug.h>
23 #include <dali/public-api/object/property-array.h>
24 #include <dali/public-api/object/type-registry-helper.h>
25 #include <dali/public-api/object/type-registry.h>
26
27 // INTERNAL INCLUDES
28 #include <dali-toolkit/devel-api/asset-manager/asset-manager.h>
29 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
30 #include <dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h>
31 #include <dali-toolkit/internal/visuals/animated-image/animated-image-visual.h>
32 #include <dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h>
33 #include <dali-toolkit/internal/visuals/arc/arc-visual.h>
34 #include <dali-toolkit/internal/visuals/border/border-visual.h>
35 #include <dali-toolkit/internal/visuals/color/color-visual.h>
36 #include <dali-toolkit/internal/visuals/gradient/gradient-visual.h>
37 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
38 #include <dali-toolkit/internal/visuals/image/image-visual.h>
39 #include <dali-toolkit/internal/visuals/mesh/mesh-visual.h>
40 #include <dali-toolkit/internal/visuals/npatch/npatch-visual.h>
41 #include <dali-toolkit/internal/visuals/primitive/primitive-visual.h>
42 #include <dali-toolkit/internal/visuals/svg/svg-visual.h>
43 #include <dali-toolkit/internal/visuals/text/text-visual.h>
44 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
45 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
46 #include <dali-toolkit/internal/visuals/visual-url.h>
47 #include <dali-toolkit/internal/visuals/wireframe/wireframe-visual.h>
48 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
49 #include <dali-toolkit/public-api/visuals/text-visual-properties.h>
50 #include <dali-toolkit/public-api/visuals/visual-properties.h>
51
52 namespace Dali
53 {
54 namespace Toolkit
55 {
56 namespace Internal
57 {
58 namespace
59 {
60 #if defined(DEBUG_ENABLED)
61 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_CONTROL_VISUALS");
62 #endif
63
64 BaseHandle Create()
65 {
66   BaseHandle handle = Toolkit::VisualFactory::Get();
67
68   return handle;
69 }
70
71 DALI_TYPE_REGISTRATION_BEGIN_CREATE(Toolkit::VisualFactory, Dali::BaseHandle, Create, true)
72 DALI_TYPE_REGISTRATION_END()
73 const char* const BROKEN_IMAGE_FILE_NAME = "broken.png"; ///< The file name of the broken image.
74
75 } // namespace
76
77 VisualFactory::VisualFactory(bool debugEnabled)
78 : mFactoryCache(),
79   mImageVisualShaderFactory(),
80   mSlotDelegate(this),
81   mDebugEnabled(debugEnabled),
82   mPreMultiplyOnLoad(true)
83 {
84 }
85
86 VisualFactory::~VisualFactory()
87 {
88 }
89
90 void VisualFactory::OnStyleChangedSignal(Toolkit::StyleManager styleManager, StyleChange::Type type)
91 {
92   if(type == StyleChange::THEME_CHANGE)
93   {
94     const std::string imageDirPath   = AssetManager::GetDaliImagePath();
95     std::string       brokenImageUrl = imageDirPath + BROKEN_IMAGE_FILE_NAME;
96
97     Property::Map config = Toolkit::DevelStyleManager::GetConfigurations(styleManager);
98     config["brokenImageUrl"].Get(brokenImageUrl);
99
100     if(mFactoryCache)
101     {
102       mFactoryCache->SetBrokenImageUrl(brokenImageUrl);
103     }
104   }
105 }
106
107 Toolkit::Visual::Base VisualFactory::CreateVisual(const Property::Map& propertyMap)
108 {
109   Visual::BasePtr visualPtr;
110
111   Property::Value*           typeValue  = propertyMap.Find(Toolkit::Visual::Property::TYPE, VISUAL_TYPE);
112   Toolkit::DevelVisual::Type visualType = Toolkit::DevelVisual::IMAGE; // Default to IMAGE type.
113   if(typeValue)
114   {
115     Scripting::GetEnumerationProperty(*typeValue, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT, visualType);
116   }
117
118   switch(visualType)
119   {
120     case Toolkit::Visual::BORDER:
121     {
122       visualPtr = BorderVisual::New(GetFactoryCache(), propertyMap);
123       break;
124     }
125
126     case Toolkit::Visual::COLOR:
127     {
128       visualPtr = ColorVisual::New(GetFactoryCache(), propertyMap);
129       break;
130     }
131
132     case Toolkit::Visual::GRADIENT:
133     {
134       visualPtr = GradientVisual::New(GetFactoryCache(), propertyMap);
135       break;
136     }
137
138     case Toolkit::Visual::IMAGE:
139     {
140       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
141       std::string      imageUrl;
142       if(imageURLValue)
143       {
144         if(imageURLValue->Get(imageUrl))
145         {
146           if(!imageUrl.empty())
147           {
148             VisualUrl visualUrl(imageUrl);
149
150             switch(visualUrl.GetType())
151             {
152               case VisualUrl::N_PATCH:
153               {
154                 visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap);
155                 break;
156               }
157               case VisualUrl::SVG:
158               {
159                 visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap);
160                 break;
161               }
162               case VisualUrl::GIF:
163               case VisualUrl::WEBP:
164               {
165                 visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap);
166                 break;
167               }
168               case VisualUrl::JSON:
169               case VisualUrl::RIVE:
170               {
171                 visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
172                 break;
173               }
174               case VisualUrl::REGULAR_IMAGE:
175               {
176                 visualPtr = ImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap);
177                 break;
178               }
179             }
180           }
181         }
182         else
183         {
184           Property::Array* array = imageURLValue->GetArray();
185           if(array)
186           {
187             visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), *array, propertyMap);
188           }
189         }
190       }
191       break;
192     }
193
194     case Toolkit::Visual::MESH:
195     {
196       visualPtr = MeshVisual::New(GetFactoryCache(), propertyMap);
197       break;
198     }
199
200     case Toolkit::Visual::PRIMITIVE:
201     {
202       visualPtr = PrimitiveVisual::New(GetFactoryCache(), propertyMap);
203       break;
204     }
205
206     case Toolkit::Visual::WIREFRAME:
207     {
208       visualPtr = WireframeVisual::New(GetFactoryCache(), propertyMap);
209       break;
210     }
211
212     case Toolkit::Visual::TEXT:
213     {
214       visualPtr = TextVisual::New(GetFactoryCache(), propertyMap);
215       break;
216     }
217
218     case Toolkit::Visual::N_PATCH:
219     {
220       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
221       std::string      imageUrl;
222       if(imageURLValue && imageURLValue->Get(imageUrl))
223       {
224         visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
225       }
226       break;
227     }
228
229     case Toolkit::Visual::SVG:
230     {
231       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
232       std::string      imageUrl;
233       if(imageURLValue && imageURLValue->Get(imageUrl))
234       {
235         visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
236       }
237       break;
238     }
239
240     case Toolkit::Visual::ANIMATED_IMAGE:
241     {
242       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
243       std::string      imageUrl;
244       if(imageURLValue)
245       {
246         if(imageURLValue->Get(imageUrl))
247         {
248           visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
249         }
250         else
251         {
252           Property::Array* array = imageURLValue->GetArray();
253           if(array)
254           {
255             visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), *array, propertyMap);
256           }
257         }
258       }
259       break;
260     }
261
262     case Toolkit::DevelVisual::ANIMATED_GRADIENT:
263     {
264       visualPtr = AnimatedGradientVisual::New(GetFactoryCache(), propertyMap);
265       break;
266     }
267
268     case Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE:
269     {
270       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
271       std::string      imageUrl;
272       if(imageURLValue && imageURLValue->Get(imageUrl))
273       {
274         visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
275       }
276       break;
277     }
278
279     case Toolkit::DevelVisual::ARC:
280     {
281       visualPtr = ArcVisual::New(GetFactoryCache(), propertyMap);
282       break;
283     }
284   }
285
286   DALI_LOG_INFO(gLogFilter, Debug::Concise, "VisualFactory::CreateVisual( VisualType:%s %s%s)\n", Scripting::GetEnumerationName<Toolkit::DevelVisual::Type>(visualType, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT), (visualType == Toolkit::DevelVisual::IMAGE) ? "url:" : "", (visualType == Toolkit::DevelVisual::IMAGE) ? (([&]() {
287                   // Return URL if present in PropertyMap else return "not found message"
288                   Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
289                   return (imageURLValue) ? imageURLValue->Get<std::string>().c_str() : "url not found in PropertyMap";
290                 })())
291                                                                                                                                                                                                                                                                                                                             : "");
292
293   if(!visualPtr)
294   {
295     DALI_LOG_ERROR("VisualType unknown\n");
296   }
297
298   if(mDebugEnabled && visualType != Toolkit::DevelVisual::WIREFRAME)
299   {
300     //Create a WireframeVisual if we have debug enabled
301     visualPtr = WireframeVisual::New(GetFactoryCache(), visualPtr, propertyMap);
302   }
303
304   return Toolkit::Visual::Base(visualPtr.Get());
305 }
306
307 Toolkit::Visual::Base VisualFactory::CreateVisual(const std::string& url, ImageDimensions size)
308 {
309   Visual::BasePtr visualPtr;
310
311   if(!url.empty())
312   {
313     // first resolve url type to know which visual to create
314     VisualUrl visualUrl(url);
315     switch(visualUrl.GetType())
316     {
317       case VisualUrl::N_PATCH:
318       {
319         visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
320         break;
321       }
322       case VisualUrl::SVG:
323       {
324         visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
325         break;
326       }
327       case VisualUrl::GIF:
328       case VisualUrl::WEBP:
329       {
330         visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
331         break;
332       }
333       case VisualUrl::JSON:
334       case VisualUrl::RIVE:
335       {
336         visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
337         break;
338       }
339       case VisualUrl::REGULAR_IMAGE:
340       {
341         visualPtr = ImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size);
342         break;
343       }
344     }
345   }
346
347   if(mDebugEnabled)
348   {
349     //Create a WireframeVisual if we have debug enabled
350     visualPtr = WireframeVisual::New(GetFactoryCache(), visualPtr);
351   }
352
353   return Toolkit::Visual::Base(visualPtr.Get());
354 }
355
356 void VisualFactory::SetPreMultiplyOnLoad(bool preMultiply)
357 {
358   if(mPreMultiplyOnLoad != preMultiply)
359   {
360     GetFactoryCache().SetPreMultiplyOnLoad(preMultiply);
361   }
362   mPreMultiplyOnLoad = preMultiply;
363 }
364
365 bool VisualFactory::GetPreMultiplyOnLoad() const
366 {
367   return mPreMultiplyOnLoad;
368 }
369
370 Internal::TextureManager& VisualFactory::GetTextureManager()
371 {
372   return GetFactoryCache().GetTextureManager();
373 }
374
375 Internal::VisualFactoryCache& VisualFactory::GetFactoryCache()
376 {
377   if(!mFactoryCache)
378   {
379     mFactoryCache = std::unique_ptr<VisualFactoryCache>(new VisualFactoryCache(mPreMultiplyOnLoad));
380
381     const std::string imageDirPath   = AssetManager::GetDaliImagePath();
382     std::string       brokenImageUrl = imageDirPath + BROKEN_IMAGE_FILE_NAME;
383
384     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
385     if(styleManager)
386     {
387       Property::Map config = Toolkit::DevelStyleManager::GetConfigurations(styleManager);
388       config["brokenImageUrl"].Get(brokenImageUrl);
389       styleManager.StyleChangedSignal().Connect(mSlotDelegate, &VisualFactory::OnStyleChangedSignal);
390     }
391
392     mFactoryCache->SetBrokenImageUrl(brokenImageUrl);
393   }
394   return *mFactoryCache;
395 }
396
397 ImageVisualShaderFactory& VisualFactory::GetImageVisualShaderFactory()
398 {
399   if(!mImageVisualShaderFactory)
400   {
401     mImageVisualShaderFactory = std::unique_ptr<ImageVisualShaderFactory>(new ImageVisualShaderFactory());
402   }
403   return *mImageVisualShaderFactory;
404 }
405
406 } // namespace Internal
407
408 } // namespace Toolkit
409
410 } // namespace Dali