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-toolkit/dali-toolkit.h>
25 #include <dali-toolkit/devel-api/text/text-utils-devel.h>
26 #include <dali/devel-api/adaptor-framework/image-loading.h>
27 #include <dali/devel-api/adaptor-framework/pixel-buffer.h>
30 #include "generated/simple-text-renderer-vert.h"
31 #include "generated/simple-text-renderer-frag.h"
35 using namespace Dali::Toolkit;
39 const std::string IMAGE1 = DEMO_IMAGE_DIR "application-icon-1.png";
40 const std::string IMAGE2 = DEMO_IMAGE_DIR "application-icon-6.png";
42 Renderer CreateRenderer()
44 // Create the geometry.
47 Dali::Vector2 position;
48 Dali::Vector2 texCoord;
51 static const Vertex vertices[] = {{Dali::Vector2(-0.5f, -0.5f), Dali::Vector2(0.0f, 0.0f)},
52 {Dali::Vector2(0.5f, -0.5f), Dali::Vector2(1.0f, 0.0f)},
53 {Dali::Vector2(-0.5f, 0.5f), Dali::Vector2(0.0f, 1.0f)},
54 {Dali::Vector2(0.5f, 0.5f), Dali::Vector2(1.0f, 1.0f)}};
56 Property::Map property;
57 property.Add("aPosition", Property::VECTOR2).Add("aTexCoord", Property::VECTOR2);
59 VertexBuffer vertexBuffer = VertexBuffer::New(property);
61 vertexBuffer.SetData(vertices, sizeof(vertices) / sizeof(Vertex));
63 Geometry geometry = Geometry::New();
64 geometry.AddVertexBuffer(vertexBuffer);
66 geometry.SetType(Geometry::TRIANGLE_STRIP);
69 Shader shader = Shader::New(SHADER_SIMPLE_TEXT_RENDERER_VERT, SHADER_SIMPLE_TEXT_RENDERER_FRAG);
71 // Create the renderer
73 Renderer renderer = Renderer::New(geometry, shader);
78 TextureSet CreateTextureSet(const Dali::Toolkit::DevelText::RendererParameters& textParameters, const std::vector<std::string>& embeddedItems)
80 Dali::Vector<Dali::Toolkit::DevelText::EmbeddedItemInfo> embeddedItemLayout;
82 Devel::PixelBuffer pixelBuffer = Toolkit::DevelText::Render(textParameters, embeddedItemLayout);
84 const int dstWidth = static_cast<int>(pixelBuffer.GetWidth());
85 const int dstHeight = static_cast<int>(pixelBuffer.GetHeight());
87 unsigned int index = 0u;
88 for(const auto& itemLayout : embeddedItemLayout)
90 int width = static_cast<int>(itemLayout.size.width);
91 int height = static_cast<int>(itemLayout.size.height);
92 int x = static_cast<int>(itemLayout.position.x);
93 int y = static_cast<int>(itemLayout.position.y);
95 Dali::Devel::PixelBuffer itemPixelBuffer = Dali::LoadImageFromFile(embeddedItems[index++]);
96 itemPixelBuffer.Resize(width, height);
97 itemPixelBuffer.Rotate(itemLayout.angle);
99 width = static_cast<int>(itemPixelBuffer.GetWidth());
100 height = static_cast<int>(itemPixelBuffer.GetHeight());
102 Dali::Pixel::Format itemPixelFormat = itemPixelBuffer.GetPixelFormat();
104 // Check if the item is out of the buffer.
106 if((x + width < 0) ||
109 (y - height > dstHeight))
111 // The embedded item is completely out of the buffer.
115 // Crop if it exceeds the boundaries of the destination buffer.
120 int newWidth = width;
121 int newHeight = height;
136 if(cropX + newWidth > dstWidth)
139 newWidth -= ((cropX + newWidth) - dstWidth);
145 newHeight += layoutY;
146 cropY = std::abs(layoutY);
150 if(cropY + newHeight > dstHeight)
153 newHeight -= ((cropY + newHeight) - dstHeight);
156 uint16_t uiCropX = static_cast<uint16_t>(cropX);
157 uint16_t uiCropY = static_cast<uint16_t>(cropY);
158 uint16_t uiNewWidth = static_cast<uint16_t>(newWidth);
159 uint16_t uiNewHeight = static_cast<uint16_t>(newHeight);
163 itemPixelBuffer.Crop(uiCropX, uiCropY, uiNewWidth, uiNewHeight);
166 // Blend the item pixel buffer with the text's color according its blending mode.
167 if(Dali::TextAbstraction::ColorBlendingMode::MULTIPLY == itemLayout.colorBlendingMode)
169 Dali::Devel::PixelBuffer buffer = Dali::Devel::PixelBuffer::New(uiNewWidth,
173 unsigned char* bufferPtr = buffer.GetBuffer();
174 const unsigned char* itemBufferPtr = itemPixelBuffer.GetBuffer();
175 const unsigned int bytesPerPixel = Dali::Pixel::GetBytesPerPixel(itemPixelFormat);
176 const unsigned int size = uiNewWidth * uiNewHeight * bytesPerPixel;
178 for(unsigned int i = 0u; i < size; i += bytesPerPixel)
180 *(bufferPtr + 0u) = static_cast<unsigned char>(static_cast<float>(*(itemBufferPtr + 0u)) * textParameters.textColor.r);
181 *(bufferPtr + 1u) = static_cast<unsigned char>(static_cast<float>(*(itemBufferPtr + 1u)) * textParameters.textColor.g);
182 *(bufferPtr + 2u) = static_cast<unsigned char>(static_cast<float>(*(itemBufferPtr + 2u)) * textParameters.textColor.b);
183 *(bufferPtr + 3u) = static_cast<unsigned char>(static_cast<float>(*(itemBufferPtr + 3u)) * textParameters.textColor.a);
185 itemBufferPtr += bytesPerPixel;
186 bufferPtr += bytesPerPixel;
189 itemPixelBuffer = buffer;
192 Dali::Toolkit::DevelText::UpdateBuffer(itemPixelBuffer, pixelBuffer, layoutX, layoutY, true);
195 PixelData pixelData = Devel::PixelBuffer::Convert(pixelBuffer);
197 Texture texture = Texture::New(TextureType::TEXTURE_2D,
198 pixelData.GetPixelFormat(),
199 pixelData.GetWidth(),
200 pixelData.GetHeight());
201 texture.Upload(pixelData);
203 TextureSet textureSet = TextureSet::New();
204 textureSet.SetTexture(0u, texture);
212 * @brief The main class of the demo.
214 class SimpleTextRendererExample : public ConnectionTracker
217 SimpleTextRendererExample(Application& application)
218 : mApplication(application)
220 // Connect to the Application's Init signal
221 mApplication.InitSignal().Connect(this, &SimpleTextRendererExample::Create);
224 ~SimpleTextRendererExample()
226 // Nothing to do here.
230 * One-time setup in response to Application InitSignal.
232 void Create(Application& application)
234 Window window = application.GetWindow();
235 window.SetBackgroundColor(Color::WHITE);
236 window.SetBackgroundColor(Vector4(0.04f, 0.345f, 0.392f, 1.0f));
238 window.KeyEventSignal().Connect(this, &SimpleTextRendererExample::OnKeyEvent);
240 const std::string image1 = "<item 'width'=26 'height'=26 'url'='" + IMAGE1 + "'/>";
241 const std::string image2 = "<item 'width'=26 'height'=26/>";
243 Dali::Toolkit::DevelText::RendererParameters textParameters;
244 textParameters.text = "Hello " + image1 + " world " + image2 + " this " + image1 + " is " + image2 + " a " + image1 + " demo " + image2 + " of " + image1 + " circular " + image2 + " text " + image1 + " width " + image2 + " icons.";
245 textParameters.horizontalAlignment = "center";
246 textParameters.verticalAlignment = "center";
247 textParameters.circularAlignment = "center";
248 textParameters.fontFamily = "SamsungUI";
249 textParameters.fontWeight = "";
250 textParameters.fontWidth = "";
251 textParameters.fontSlant = "";
252 textParameters.layout = "circular";
253 textParameters.textColor = Color::BLACK;
254 textParameters.fontSize = 25.f;
255 textParameters.textWidth = 360u;
256 textParameters.textHeight = 360u;
257 textParameters.radius = 180u;
258 textParameters.beginAngle = 15.f;
259 textParameters.incrementAngle = 360.f;
260 textParameters.ellipsisEnabled = true;
261 textParameters.markupEnabled = true;
263 std::vector<std::string> embeddedItems = {IMAGE2, IMAGE2, IMAGE2, IMAGE2, IMAGE2};
265 TextureSet textureSet = CreateTextureSet(textParameters, embeddedItems);
267 Renderer renderer = CreateRenderer();
268 renderer.SetTextures(textureSet);
270 Actor actor = Actor::New();
271 actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
272 actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
273 actor.SetProperty(Actor::Property::POSITION, Vector2(0.f, 0.f));
274 actor.SetProperty(Actor::Property::SIZE, Vector2(360.f, 360.f));
275 actor.SetProperty(Actor::Property::COLOR, Color::WHITE);
277 actor.AddRenderer(renderer);
283 * Main key event handler
285 void OnKeyEvent(const KeyEvent& event)
287 if(event.GetState() == KeyEvent::DOWN)
289 if(IsKey(event, DALI_KEY_ESCAPE) || IsKey(event, DALI_KEY_BACK))
297 Application& mApplication;
300 /** Entry point for Linux & Tizen applications */
301 int DALI_EXPORT_API main(int argc, char** argv)
303 Application application = Application::New(&argc, &argv);
305 SimpleTextRendererExample test(application);
307 application.MainLoop();