Merge "Update approval test for text" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / visual-factory-impl.cpp
1 /*
2  * Copyright (c) 2023 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/styling/style-manager-devel.h>
30 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
31 #include <dali-toolkit/internal/visuals/animated-gradient/animated-gradient-visual.h>
32 #include <dali-toolkit/internal/visuals/animated-image/animated-image-visual.h>
33 #include <dali-toolkit/internal/visuals/animated-vector-image/animated-vector-image-visual.h>
34 #include <dali-toolkit/internal/visuals/arc/arc-visual.h>
35 #include <dali-toolkit/internal/visuals/border/border-visual.h>
36 #include <dali-toolkit/internal/visuals/color/color-visual.h>
37 #include <dali-toolkit/internal/visuals/gradient/gradient-visual.h>
38 #include <dali-toolkit/internal/visuals/image-visual-shader-factory.h>
39 #include <dali-toolkit/internal/visuals/image/image-visual.h>
40 #include <dali-toolkit/internal/visuals/mesh/mesh-visual.h>
41 #include <dali-toolkit/internal/visuals/npatch/npatch-visual.h>
42 #include <dali-toolkit/internal/visuals/primitive/primitive-visual.h>
43 #include <dali-toolkit/internal/visuals/svg/svg-visual.h>
44 #include <dali-toolkit/internal/visuals/text-visual-shader-factory.h>
45 #include <dali-toolkit/internal/visuals/text/text-visual.h>
46 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
47 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
48 #include <dali-toolkit/internal/visuals/visual-url.h>
49 #include <dali-toolkit/internal/visuals/wireframe/wireframe-visual.h>
50 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
51 #include <dali-toolkit/public-api/visuals/text-visual-properties.h>
52 #include <dali-toolkit/public-api/visuals/visual-properties.h>
53
54 namespace Dali
55 {
56 namespace Toolkit
57 {
58 namespace Internal
59 {
60 namespace
61 {
62 #if defined(DEBUG_ENABLED)
63 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_CONTROL_VISUALS");
64 #endif
65
66 BaseHandle Create()
67 {
68   BaseHandle handle = Toolkit::VisualFactory::Get();
69
70   return handle;
71 }
72
73 DALI_TYPE_REGISTRATION_BEGIN_CREATE(Toolkit::VisualFactory, Dali::BaseHandle, Create, true)
74 DALI_TYPE_REGISTRATION_END()
75 const char* const BROKEN_IMAGE_FILE_NAME = "broken.png"; ///< The file name of the broken image.
76
77 } // namespace
78
79 VisualFactory::VisualFactory(bool debugEnabled)
80 : mFactoryCache(),
81   mImageVisualShaderFactory(),
82   mTextVisualShaderFactory(),
83   mSlotDelegate(this),
84   mDebugEnabled(debugEnabled),
85   mPreMultiplyOnLoad(true)
86 {
87 }
88
89 VisualFactory::~VisualFactory()
90 {
91 }
92
93 void VisualFactory::OnStyleChangedSignal(Toolkit::StyleManager styleManager, StyleChange::Type type)
94 {
95   if(type == StyleChange::THEME_CHANGE)
96   {
97     SetBrokenImageUrl(styleManager);
98   }
99 }
100
101 void VisualFactory::OnBrokenImageChangedSignal(Toolkit::StyleManager styleManager)
102 {
103   SetBrokenImageUrl(styleManager);
104 }
105
106 Toolkit::Visual::Base VisualFactory::CreateVisual(const Property::Map& propertyMap)
107 {
108   Visual::BasePtr visualPtr;
109
110   Property::Value*           typeValue  = propertyMap.Find(Toolkit::Visual::Property::TYPE, VISUAL_TYPE);
111   Toolkit::DevelVisual::Type visualType = Toolkit::DevelVisual::IMAGE; // Default to IMAGE type.
112   if(typeValue)
113   {
114     Scripting::GetEnumerationProperty(*typeValue, VISUAL_TYPE_TABLE, VISUAL_TYPE_TABLE_COUNT, visualType);
115   }
116
117   switch(visualType)
118   {
119     case Toolkit::Visual::BORDER:
120     {
121       visualPtr = BorderVisual::New(GetFactoryCache(), propertyMap);
122       break;
123     }
124
125     case Toolkit::Visual::COLOR:
126     {
127       visualPtr = ColorVisual::New(GetFactoryCache(), propertyMap);
128       break;
129     }
130
131     case Toolkit::Visual::GRADIENT:
132     {
133       visualPtr = GradientVisual::New(GetFactoryCache(), propertyMap);
134       break;
135     }
136
137     case Toolkit::Visual::IMAGE:
138     {
139       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
140       std::string      imageUrl;
141       if(imageURLValue)
142       {
143         if(imageURLValue->Get(imageUrl))
144         {
145           if(!imageUrl.empty())
146           {
147             VisualUrl visualUrl(imageUrl);
148
149             switch(visualUrl.GetType())
150             {
151               case VisualUrl::N_PATCH:
152               {
153                 visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, propertyMap);
154                 break;
155               }
156               case VisualUrl::TVG:
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 && array->Count() > 0)
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(), GetTextVisualShaderFactory(), 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         if(!imageUrl.empty())
224         {
225           visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
226         }
227       }
228       break;
229     }
230
231     case Toolkit::Visual::SVG:
232     {
233       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
234       std::string      imageUrl;
235       if(imageURLValue && imageURLValue->Get(imageUrl))
236       {
237         if(!imageUrl.empty())
238         {
239           visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
240         }
241       }
242       break;
243     }
244
245     case Toolkit::Visual::ANIMATED_IMAGE:
246     {
247       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
248       std::string      imageUrl;
249       if(imageURLValue)
250       {
251         if(imageURLValue->Get(imageUrl))
252         {
253           if(!imageUrl.empty())
254           {
255             visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
256           }
257         }
258         else
259         {
260           Property::Array* array = imageURLValue->GetArray();
261           if(array && array->Count() > 0)
262           {
263             visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), *array, propertyMap);
264           }
265         }
266       }
267       break;
268     }
269
270     case Toolkit::DevelVisual::ANIMATED_GRADIENT:
271     {
272       visualPtr = AnimatedGradientVisual::New(GetFactoryCache(), propertyMap);
273       break;
274     }
275
276     case Toolkit::DevelVisual::ANIMATED_VECTOR_IMAGE:
277     {
278       Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
279       std::string      imageUrl;
280       if(imageURLValue && imageURLValue->Get(imageUrl))
281       {
282         if(!imageUrl.empty())
283         {
284           visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), imageUrl, propertyMap);
285         }
286       }
287       break;
288     }
289
290     case Toolkit::DevelVisual::ARC:
291     {
292       visualPtr = ArcVisual::New(GetFactoryCache(), propertyMap);
293       break;
294     }
295   }
296
297   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) ? (([&]() {
298                   // Return URL if present in PropertyMap else return "not found message"
299                   Property::Value* imageURLValue = propertyMap.Find(Toolkit::ImageVisual::Property::URL, IMAGE_URL_NAME);
300                   return (imageURLValue) ? imageURLValue->Get<std::string>().c_str() : "url not found in PropertyMap";
301                 })())
302                                                                                                                                                                                                                                                                                                                             : "");
303
304   if(!visualPtr)
305   {
306     DALI_LOG_ERROR("VisualType unknown\n");
307   }
308
309   if(mDebugEnabled && visualType != Toolkit::DevelVisual::WIREFRAME)
310   {
311     //Create a WireframeVisual if we have debug enabled
312     visualPtr = WireframeVisual::New(GetFactoryCache(), visualPtr, propertyMap);
313   }
314
315   return Toolkit::Visual::Base(visualPtr.Get());
316 }
317
318 Toolkit::Visual::Base VisualFactory::CreateVisual(const std::string& url, ImageDimensions size)
319 {
320   Visual::BasePtr visualPtr;
321
322   if(!url.empty())
323   {
324     // first resolve url type to know which visual to create
325     VisualUrl visualUrl(url);
326     switch(visualUrl.GetType())
327     {
328       case VisualUrl::N_PATCH:
329       {
330         visualPtr = NPatchVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl);
331         break;
332       }
333       case VisualUrl::TVG:
334       case VisualUrl::SVG:
335       {
336         visualPtr = SvgVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size);
337         break;
338       }
339       case VisualUrl::GIF:
340       case VisualUrl::WEBP:
341       {
342         visualPtr = AnimatedImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size);
343         break;
344       }
345       case VisualUrl::JSON:
346       {
347         visualPtr = AnimatedVectorImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size);
348         break;
349       }
350       case VisualUrl::REGULAR_IMAGE:
351       {
352         visualPtr = ImageVisual::New(GetFactoryCache(), GetImageVisualShaderFactory(), visualUrl, size);
353         break;
354       }
355     }
356   }
357
358   if(mDebugEnabled)
359   {
360     //Create a WireframeVisual if we have debug enabled
361     visualPtr = WireframeVisual::New(GetFactoryCache(), visualPtr);
362   }
363
364   return Toolkit::Visual::Base(visualPtr.Get());
365 }
366
367 void VisualFactory::SetPreMultiplyOnLoad(bool preMultiply)
368 {
369   if(mPreMultiplyOnLoad != preMultiply)
370   {
371     GetFactoryCache().SetPreMultiplyOnLoad(preMultiply);
372   }
373   mPreMultiplyOnLoad = preMultiply;
374 }
375
376 bool VisualFactory::GetPreMultiplyOnLoad() const
377 {
378   return mPreMultiplyOnLoad;
379 }
380
381 Internal::TextureManager& VisualFactory::GetTextureManager()
382 {
383   return GetFactoryCache().GetTextureManager();
384 }
385
386 void VisualFactory::SetBrokenImageUrl(Toolkit::StyleManager& styleManager)
387 {
388   const std::string        imageDirPath   = AssetManager::GetDaliImagePath();
389   std::string              brokenImageUrl = imageDirPath + BROKEN_IMAGE_FILE_NAME;
390   std::vector<std::string> customBrokenImageUrlList;
391
392   if(styleManager)
393   {
394     customBrokenImageUrlList       = Toolkit::DevelStyleManager::GetBrokenImageUrlList(styleManager);
395     const auto brokenImageUrlValue = Toolkit::DevelStyleManager::GetConfigurations(styleManager).Find("brokenImageUrl", Property::Type::STRING);
396     if(brokenImageUrlValue)
397     {
398       brokenImageUrlValue->Get(brokenImageUrl);
399     }
400   }
401
402   // Add default image
403   mFactoryCache->SetBrokenImageUrl(brokenImageUrl, customBrokenImageUrlList);
404 }
405
406 Internal::VisualFactoryCache& VisualFactory::GetFactoryCache()
407 {
408   if(!mFactoryCache)
409   {
410     mFactoryCache                      = std::unique_ptr<VisualFactoryCache>(new VisualFactoryCache(mPreMultiplyOnLoad));
411     Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
412     if(styleManager)
413     {
414       styleManager.StyleChangedSignal().Connect(mSlotDelegate, &VisualFactory::OnStyleChangedSignal);
415       Toolkit::DevelStyleManager::BrokenImageChangedSignal(styleManager).Connect(mSlotDelegate, &VisualFactory::OnBrokenImageChangedSignal);
416     }
417     SetBrokenImageUrl(styleManager);
418   }
419   return *mFactoryCache;
420 }
421
422 ImageVisualShaderFactory& VisualFactory::GetImageVisualShaderFactory()
423 {
424   if(!mImageVisualShaderFactory)
425   {
426     mImageVisualShaderFactory = std::unique_ptr<ImageVisualShaderFactory>(new ImageVisualShaderFactory());
427   }
428   return *mImageVisualShaderFactory;
429 }
430
431 TextVisualShaderFactory& VisualFactory::GetTextVisualShaderFactory()
432 {
433   if(!mTextVisualShaderFactory)
434   {
435     mTextVisualShaderFactory = std::unique_ptr<TextVisualShaderFactory>(new TextVisualShaderFactory());
436   }
437   return *mTextVisualShaderFactory;
438 }
439
440 } // namespace Internal
441
442 } // namespace Toolkit
443
444 } // namespace Dali