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