2 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @file simple-text-renderer-example.cpp
20 * @brief Basic usage of Text Renderer utility.
24 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
25 #include <dali-toolkit/dali-toolkit.h>
26 #include <dali-toolkit/devel-api/text/text-utils-devel.h>
27 #include <dali/devel-api/adaptor-framework/image-loading.h>
31 using namespace Dali::Toolkit;
36 const std::string IMAGE1 = DEMO_IMAGE_DIR "application-icon-1.png";
37 const std::string IMAGE2 = DEMO_IMAGE_DIR "application-icon-6.png";
39 #define MAKE_SHADER(A)#A
41 const std::string VERSION_3_ES = "#version 300 es\n";
43 const char* VERTEX_SHADER = MAKE_SHADER(
44 precision mediump float;
52 uniform mat4 uMvpMatrix;
56 vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);
57 vertexPosition.xyz *= uSize;
58 gl_Position = uMvpMatrix * vertexPosition;
64 const char* FRAGMENT_SHADER = MAKE_SHADER(
65 precision mediump float;
71 uniform sampler2D sAlbedo;
76 vec4 color = texture( sAlbedo, vUV );
77 FragColor = vec4( color.rgb, uColor.a * color.a );
81 Renderer CreateRenderer()
83 // Create the geometry.
86 Dali::Vector2 position;
87 Dali::Vector2 texCoord;
90 static const Vertex vertices[] = {{ Dali::Vector2( -0.5f, -0.5f ), Dali::Vector2( 0.0f, 0.0f ) },
91 { Dali::Vector2( 0.5f, -0.5f ), Dali::Vector2( 1.0f, 0.0f ) },
92 { Dali::Vector2( -0.5f, 0.5f ), Dali::Vector2( 0.0f, 1.0f ) },
93 { Dali::Vector2( 0.5f, 0.5f ), Dali::Vector2( 1.0f, 1.0f ) }};
95 Property::Map property;
96 property.Add("aPosition", Property::VECTOR2).Add("aTexCoord", Property::VECTOR2);
98 VertexBuffer vertexBuffer = VertexBuffer::New(property);
100 vertexBuffer.SetData(vertices, sizeof(vertices) / sizeof(Vertex));
102 Geometry geometry = Geometry::New();
103 geometry.AddVertexBuffer(vertexBuffer);
105 geometry.SetType(Geometry::TRIANGLE_STRIP);
108 Shader shader = Shader::New( VERSION_3_ES + VERTEX_SHADER, VERSION_3_ES + FRAGMENT_SHADER );
110 // Create the renderer
112 Renderer renderer = Renderer::New( geometry, shader );
117 TextureSet CreateTextureSet( const Dali::Toolkit::DevelText::RendererParameters& textParameters, const std::vector<std::string>& embeddedItems )
120 Dali::Vector<Dali::Toolkit::DevelText::EmbeddedItemInfo> embeddedItemLayout;
122 Devel::PixelBuffer pixelBuffer = Toolkit::DevelText::Render( textParameters, embeddedItemLayout );
125 const int dstWidth = static_cast<int>( pixelBuffer.GetWidth() );
126 const int dstHeight = static_cast<int>( pixelBuffer.GetHeight() );
128 unsigned int index = 0u;
129 for( const auto& itemLayout : embeddedItemLayout )
131 int width = static_cast<int>( itemLayout.size.width );
132 int height = static_cast<int>( itemLayout.size.height );
133 int x = static_cast<int>( itemLayout.position.x );
134 int y = static_cast<int>( itemLayout.position.y );
136 Dali::Devel::PixelBuffer itemPixelBuffer = Dali::LoadImageFromFile( embeddedItems[index++] );
137 itemPixelBuffer.Resize( width, height );
138 itemPixelBuffer.Rotate( itemLayout.angle );
140 width = static_cast<int>( itemPixelBuffer.GetWidth() );
141 height = static_cast<int>( itemPixelBuffer.GetHeight() );
143 Dali::Pixel::Format itemPixelFormat = itemPixelBuffer.GetPixelFormat();
145 // Check if the item is out of the buffer.
147 if( ( x + width < 0 ) ||
150 ( y - height > dstHeight ) )
152 // The embedded item is completely out of the buffer.
156 // Crop if it exceeds the boundaries of the destination buffer.
161 int newWidth = width;
162 int newHeight = height;
169 cropX = std::abs( x );
177 if( cropX + newWidth > dstWidth )
180 newWidth -= ( ( cropX + newWidth ) - dstWidth );
186 newHeight += layoutY;
187 cropY = std::abs(layoutY);
191 if( cropY + newHeight > dstHeight )
194 newHeight -= ( ( cropY + newHeight ) - dstHeight );
197 uint16_t uiCropX = static_cast<uint16_t>(cropX);
198 uint16_t uiCropY = static_cast<uint16_t>(cropY);
199 uint16_t uiNewWidth = static_cast<uint16_t>(newWidth);
200 uint16_t uiNewHeight = static_cast<uint16_t>(newHeight);
204 itemPixelBuffer.Crop( uiCropX, uiCropY, uiNewWidth, uiNewHeight );
207 // Blend the item pixel buffer with the text's color according its blending mode.
208 if( Dali::TextAbstraction::ColorBlendingMode::MULTIPLY == itemLayout.colorBlendingMode )
210 Dali::Devel::PixelBuffer buffer = Dali::Devel::PixelBuffer::New( uiNewWidth,
214 unsigned char* bufferPtr = buffer.GetBuffer();
215 const unsigned char* itemBufferPtr = itemPixelBuffer.GetBuffer();
216 const unsigned int bytesPerPixel = Dali::Pixel::GetBytesPerPixel(itemPixelFormat);
217 const unsigned int size = uiNewWidth * uiNewHeight * bytesPerPixel;
219 for (unsigned int i = 0u; i < size; i += bytesPerPixel)
221 *(bufferPtr + 0u) = static_cast<unsigned char>( static_cast<float>( *(itemBufferPtr + 0u) ) * textParameters.textColor.r );
222 *(bufferPtr + 1u) = static_cast<unsigned char>( static_cast<float>( *(itemBufferPtr + 1u) ) * textParameters.textColor.g );
223 *(bufferPtr + 2u) = static_cast<unsigned char>( static_cast<float>( *(itemBufferPtr + 2u) ) * textParameters.textColor.b );
224 *(bufferPtr + 3u) = static_cast<unsigned char>( static_cast<float>( *(itemBufferPtr + 3u) ) * textParameters.textColor.a );
226 itemBufferPtr += bytesPerPixel;
227 bufferPtr += bytesPerPixel;
230 itemPixelBuffer = buffer;
233 Dali::Toolkit::DevelText::UpdateBuffer(itemPixelBuffer, pixelBuffer, layoutX, layoutY, true);
236 PixelData pixelData = Devel::PixelBuffer::Convert( pixelBuffer );
238 Texture texture = Texture::New( TextureType::TEXTURE_2D,
239 pixelData.GetPixelFormat(),
240 pixelData.GetWidth(),
241 pixelData.GetHeight() );
242 texture.Upload(pixelData);
244 TextureSet textureSet = TextureSet::New();
245 textureSet.SetTexture( 0u, texture );
254 * @brief The main class of the demo.
256 class SimpleTextRendererExample : public ConnectionTracker
260 SimpleTextRendererExample( Application& application )
261 : mApplication( application )
263 // Connect to the Application's Init signal
264 mApplication.InitSignal().Connect( this, &SimpleTextRendererExample::Create );
267 ~SimpleTextRendererExample()
269 // Nothing to do here.
273 * One-time setup in response to Application InitSignal.
275 void Create( Application& application )
277 Window window = application.GetWindow();
278 window.SetBackgroundColor( Color::WHITE );
279 window.SetBackgroundColor( Vector4( 0.04f, 0.345f, 0.392f, 1.0f ) );
281 window.KeyEventSignal().Connect(this, &SimpleTextRendererExample::OnKeyEvent);
283 const std::string image1 = "<item 'width'=26 'height'=26 'url'='" + IMAGE1 + "'/>";
284 const std::string image2 = "<item 'width'=26 'height'=26/>";
286 Dali::Toolkit::DevelText::RendererParameters textParameters;
287 textParameters.text = "Hello " + image1 + " world " + image2 + " this " + image1 + " is " + image2 + " a " + image1 + " demo " + image2 + " of " + image1 + " circular " + image2 + " text " + image1 + " width " + image2 + " icons.";
288 textParameters.horizontalAlignment = "center";
289 textParameters.verticalAlignment = "center";
290 textParameters.circularAlignment = "center";
291 textParameters.fontFamily = "SamsungUI";
292 textParameters.fontWeight = "";
293 textParameters.fontWidth = "";
294 textParameters.fontSlant = "";
295 textParameters.layout = "circular";
296 textParameters.textColor = Color::BLACK;
297 textParameters.fontSize = 25.f;
298 textParameters.textWidth = 360u;
299 textParameters.textHeight = 360u;
300 textParameters.radius = 180u;
301 textParameters.beginAngle = 15.f;
302 textParameters.incrementAngle = 360.f;
303 textParameters.ellipsisEnabled = true;
304 textParameters.markupEnabled = true;
306 std::vector<std::string> embeddedItems = { IMAGE2, IMAGE2, IMAGE2, IMAGE2, IMAGE2 };
308 TextureSet textureSet = CreateTextureSet( textParameters, embeddedItems );
310 Renderer renderer = CreateRenderer();
311 renderer.SetTextures( textureSet );
313 Actor actor = Actor::New();
314 actor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
315 actor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
316 actor.SetProperty( Actor::Property::POSITION, Vector2( 0.f, 0.f));
317 actor.SetProperty( Actor::Property::SIZE, Vector2( 360.f, 360.f ) );
318 actor.SetProperty( Actor::Property::COLOR, Color::WHITE );
320 actor.AddRenderer( renderer );
326 * Main key event handler
328 void OnKeyEvent(const KeyEvent& event)
330 if(event.state == KeyEvent::Down)
332 if( IsKey( event, DALI_KEY_ESCAPE) || IsKey( event, DALI_KEY_BACK ) )
341 Application& mApplication;
344 /** Entry point for Linux & Tizen applications */
345 int DALI_EXPORT_API main( int argc, char **argv )
347 Application application = Application::New( &argc, &argv );
349 SimpleTextRendererExample test( application );
351 application.MainLoop();