Merge "Add support for span tag" into devel/master
[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               {
170                 visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
171                 break;
172               }
173               case VisualUrl::REGULAR_IMAGE:
174               {
175                 visualPtr = ImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap);
176                 break;
177               }
178             }
179           }
180         }
181         else
182         {
183           Property::Array* array = imageURLValue->GetArray();
184           if(array)
185           {
186             visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), *array, propertyMap);
187           }
188         }
189       }
190       break;
191     }
192
193     case Toolkit::Visual::MESH:
194     {
195       visualPtr = MeshVisual::New(GetFactoryCache(), propertyMap);
196       break;
197     }
198
199     case Toolkit::Visual::PRIMITIVE:
200     {
201       visualPtr = PrimitiveVisual::New(GetFactoryCache(), propertyMap);
202       break;
203     }
204
205     case Toolkit::Visual::WIREFRAME:
206     {
207       visualPtr = WireframeVisual::New(GetFactoryCache(), propertyMap);
208       break;
209     }
210
211     case Toolkit::Visual::TEXT:
212     {
213       visualPtr = TextVisual::New(GetFactoryCache(), propertyMap);
214       break;
215     }
216
217     case Toolkit::Visual::N_PATCH:
218     {
219       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
220       std::string      imageUrl;
221       if(imageURLValue && imageURLValue->Get(imageUrl))
222       {
223         visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
224       }
225       break;
226     }
227
228     case Toolkit::Visual::SVG:
229     {
230       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
231       std::string      imageUrl;
232       if(imageURLValue && imageURLValue->Get(imageUrl))
233       {
234         visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
235       }
236       break;
237     }
238
239     case Toolkit::Visual::ANIMATED_IMAGE:
240     {
241       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
242       std::string      imageUrl;
243       if(imageURLValue)
244       {
245         if(imageURLValue->Get(imageUrl))
246         {
247           visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
248         }
249         else
250         {
251           Property::Array* array = imageURLValue->GetArray();
252           if(array)
253           {
254             visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), *array, propertyMap);
255           }
256         }
257       }
258       break;
259     }
260
261     case Toolkit::DevelVisual::ANIMATED_GRADIENT:
262     {
263       visualPtr = AnimatedGradientVisual::New(GetFactoryCache(), propertyMap);
264       break;
265     }
266
267     case Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE:
268     {
269       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
270       std::string      imageUrl;
271       if(imageURLValue && imageURLValue->Get(imageUrl))
272       {
273         visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
274       }
275       break;
276     }
277
278     case Toolkit::DevelVisual::ARC:
279     {
280       visualPtr = ArcVisual::New(GetFactoryCache(), propertyMap);
281       break;
282     }
283   }
284
285   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) ? (([&]() {
286                   // Return URL if present in PropertyMap else return "not found message"
287                   Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
288                   return (imageURLValue) ? imageURLValue->Get<std::string>().c_str() : "url not found in PropertyMap";
289                 })())
290                                                                                                                                                                                                                                                                                                                             : "");
291
292   if(!visualPtr)
293   {
294     DALI_LOG_ERROR("VisualType unknown\n");
295   }
296
297   if(mDebugEnabled && visualType != Toolkit::DevelVisual::WIREFRAME)
298   {
299     //Create a WireframeVisual if we have debug enabled
300     visualPtr = WireframeVisual::New(GetFactoryCache(), visualPtr, propertyMap);
301   }
302
303   return Toolkit::Visual::Base(visualPtr.Get());
304 }
305
306 Toolkit::Visual::Base VisualFactory::CreateVisual(const std::string& url, ImageDimensions size)
307 {
308   Visual::BasePtr visualPtr;
309
310   if(!url.empty())
311   {
312     // first resolve url type to know which visual to create
313     VisualUrl visualUrl(url);
314     switch(visualUrl.GetType())
315     {
316       case VisualUrl::N_PATCH:
317       {
318         visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
319         break;
320       }
321       case VisualUrl::SVG:
322       {
323         visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
324         break;
325       }
326       case VisualUrl::GIF:
327       case VisualUrl::WEBP:
328       {
329         visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
330         break;
331       }
332       case VisualUrl::JSON:
333       {
334         visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
335         break;
336       }
337       case VisualUrl::REGULAR_IMAGE:
338       {
339         visualPtr = ImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size);
340         break;
341       }
342     }
343   }
344
345   if(mDebugEnabled)
346   {
347     //Create a WireframeVisual if we have debug enabled
348     visualPtr = WireframeVisual::New(GetFactoryCache(), visualPtr);
349   }
350
351   return Toolkit::Visual::Base(visualPtr.Get());
352 }
353
354 void VisualFactory::SetPreMultiplyOnLoad(bool preMultiply)
355 {
356   if(mPreMultiplyOnLoad != preMultiply)
357   {
358     GetFactoryCache().SetPreMultiplyOnLoad(preMultiply);
359   }
360   mPreMultiplyOnLoad = preMultiply;
361 }
362
363 bool VisualFactory::GetPreMultiplyOnLoad() const
364 {
365   return mPreMultiplyOnLoad;
366 }
367
368 Internal::TextureManager& VisualFactory::GetTextureManager()
369 {
370   return GetFactoryCache().GetTextureManager();
371 }
372
373 Internal::VisualFactoryCache& VisualFactory::GetFactoryCache()
374 {
375   if(!mFactoryCache)
376   {
377     mFactoryCache = std::unique_ptr<VisualFactoryCache>(new VisualFactoryCache(mPreMultiplyOnLoad));
378
379     const std::string imageDirPath   = AssetManager::GetDaliImagePath();
380     std::string       brokenImageUrl = imageDirPath + BROKEN_IMAGE_FILE_NAME;
381
382     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
383     if(styleManager)
384     {
385       Property::Map config = Toolkit::DevelStyleManager::GetConfigurations(styleManager);
386       config["brokenImageUrl"].Get(brokenImageUrl);
387       styleManager.StyleChangedSignal().Connect(mSlotDelegate, &VisualFactory::OnStyleChangedSignal);
388     }
389
390     mFactoryCache->SetBrokenImageUrl(brokenImageUrl);
391   }
392   return *mFactoryCache;
393 }
394
395 ImageVisualShaderFactory& VisualFactory::GetImageVisualShaderFactory()
396 {
397   if(!mImageVisualShaderFactory)
398   {
399     mImageVisualShaderFactory = std::unique_ptr<ImageVisualShaderFactory>(new ImageVisualShaderFactory());
400   }
401   return *mImageVisualShaderFactory;
402 }
403
404 } // namespace Internal
405
406 } // namespace Toolkit
407
408 } // namespace Dali