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