[dali_2.3.19] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / text-visual-shader-factory.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/text-visual-shader-factory.h>
19
20 // INTERNAL INCLUDES
21 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
22 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
23 #include <dali/integration-api/debug.h>
24
25 namespace Dali
26 {
27 namespace Toolkit
28 {
29 namespace Internal
30 {
31 namespace
32 {
33 // enum of required list when we select shader
34 enum class TextVisualRequireFlag : uint32_t
35 {
36   DEFAULT     = 0,
37   STYLES      = 1 << 0,
38   OVERLAY     = 1 << 1,
39   EMOJI       = 1 << 2,
40   MULTI_COLOR = 1 << 3,
41 };
42
43 const VisualFactoryCache::ShaderType SHADER_TYPE_TABLE[] =
44   {
45     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT,
46     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE,
47     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_OVERLAY,
48     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_OVERLAY,
49     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_EMOJI,
50     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_EMOJI,
51     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_OVERLAY_AND_EMOJI,
52     VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT_WITH_STYLE_AND_OVERLAY_AND_EMOJI,
53     VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT,
54     VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE,
55     VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_OVERLAY,
56     VisualFactoryCache::TEXT_SHADER_MULTI_COLOR_TEXT_WITH_STYLE_AND_OVERLAY,
57 };
58
59 } // unnamed namespace
60
61 namespace TextVisualShaderFeature
62 {
63 FeatureBuilder& FeatureBuilder::EnableMultiColor(bool enableMultiColor)
64 {
65   mTextMultiColor = enableMultiColor ? TextMultiColor::MULTI_COLOR_TEXT : TextMultiColor::SINGLE_COLOR_TEXT;
66   return *this;
67 }
68 FeatureBuilder& FeatureBuilder::EnableEmoji(bool enableEmoji)
69 {
70   mTextEmoji = enableEmoji ? TextEmoji::HAS_EMOJI : TextEmoji::NO_EMOJI;
71   return *this;
72 }
73 FeatureBuilder& FeatureBuilder::EnableStyle(bool enableStyle)
74 {
75   mTextStyle = enableStyle ? TextStyle::HAS_STYLES : TextStyle::NO_STYLES;
76   return *this;
77 }
78 FeatureBuilder& FeatureBuilder::EnableOverlay(bool enableOverlay)
79 {
80   mTextOverlay = enableOverlay ? TextOverlay::HAS_OVERLAY : TextOverlay::NO_OVERLAY;
81   return *this;
82 }
83 } // namespace TextVisualShaderFeature
84
85 TextVisualShaderFactory::TextVisualShaderFactory()
86 {
87 }
88
89 TextVisualShaderFactory::~TextVisualShaderFactory()
90 {
91 }
92
93 Shader TextVisualShaderFactory::GetShader(VisualFactoryCache& factoryCache, const TextVisualShaderFeature::FeatureBuilder& featureBuilder)
94 {
95   Shader                         shader;
96   uint32_t                       shaderTypeFlag = static_cast<uint32_t>(TextVisualRequireFlag::DEFAULT);
97   VisualFactoryCache::ShaderType shaderType     = VisualFactoryCache::TEXT_SHADER_SINGLE_COLOR_TEXT;
98
99   const auto& multiColor = featureBuilder.mTextMultiColor;
100   const auto& emoji      = featureBuilder.mTextEmoji;
101   const auto& style      = featureBuilder.mTextStyle;
102   const auto& overlay    = featureBuilder.mTextOverlay;
103
104   if(style == TextVisualShaderFeature::TextStyle::HAS_STYLES)
105   {
106     shaderTypeFlag |= static_cast<uint32_t>(TextVisualRequireFlag::STYLES);
107   }
108   if(overlay == TextVisualShaderFeature::TextOverlay::HAS_OVERLAY)
109   {
110     shaderTypeFlag |= static_cast<uint32_t>(TextVisualRequireFlag::OVERLAY);
111   }
112   // multi color can also render emoji. If multi color text, dont consider emoji
113   if(multiColor != TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT && emoji == TextVisualShaderFeature::TextEmoji::HAS_EMOJI)
114   {
115     shaderTypeFlag |= static_cast<uint32_t>(TextVisualRequireFlag::EMOJI);
116   }
117   if(multiColor == TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT)
118   {
119     shaderTypeFlag |= static_cast<uint32_t>(TextVisualRequireFlag::MULTI_COLOR);
120   }
121
122   shaderType = SHADER_TYPE_TABLE[shaderTypeFlag];
123   shader     = factoryCache.GetShader(shaderType);
124
125   if(!shader)
126   {
127     std::string vertexShaderPrefixList;
128     std::string fragmentShaderPrefixList;
129
130     if(style == TextVisualShaderFeature::TextStyle::HAS_STYLES)
131     {
132       fragmentShaderPrefixList += "#define IS_REQUIRED_STYLE\n";
133     }
134     if(overlay == TextVisualShaderFeature::TextOverlay::HAS_OVERLAY)
135     {
136       fragmentShaderPrefixList += "#define IS_REQUIRED_OVERLAY\n";
137     }
138     // multi color can also render emoji. If multi color text, dont consider emoji
139     if(multiColor != TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT && emoji == TextVisualShaderFeature::TextEmoji::HAS_EMOJI)
140     {
141       fragmentShaderPrefixList += "#define IS_REQUIRED_EMOJI\n";
142     }
143     if(multiColor == TextVisualShaderFeature::TextMultiColor::MULTI_COLOR_TEXT)
144     {
145       fragmentShaderPrefixList += "#define IS_REQUIRED_MULTI_COLOR\n";
146     }
147
148     std::string vertexShader   = std::string(Dali::Shader::GetVertexShaderPrefix() + vertexShaderPrefixList + SHADER_TEXT_VISUAL_SHADER_VERT.data());
149     std::string fragmentShader = std::string(Dali::Shader::GetFragmentShaderPrefix() + fragmentShaderPrefixList + SHADER_TEXT_VISUAL_SHADER_FRAG.data());
150
151     shader = Shader::New(vertexShader, fragmentShader);
152     factoryCache.SaveShader(shaderType, shader);
153   }
154   return shader;
155 }
156
157 } // namespace Internal
158
159 } // namespace Toolkit
160
161 } // namespace Dali