License conversion from Flora to Apache 2.0
[platform/core/uifw/dali-core.git] / dali / internal / update / node-attachments / scene-graph-text-attachment.cpp
1 /*
2  * Copyright (c) 2014 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
18 // CLASS HEADER
19 #include <dali/internal/update/node-attachments/scene-graph-text-attachment.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/common/dali-common.h>
23 #include <dali/public-api/math/vector3.h>
24 #include <dali/public-api/math/vector4.h>
25 #include <dali/internal/common/internal-constants.h>
26 #include <dali/internal/common/text-parameters.h>
27 #include <dali/internal/render/common/performance-monitor.h>
28 #include <dali/internal/render/queue/render-queue.h>
29 #include <dali/internal/render/common/vertex.h>
30 #include <dali/internal/render/renderers/scene-graph-text-renderer.h>
31 #include <dali/internal/render/renderers/scene-graph-renderer-declarations.h>
32 #include <dali/internal/render/shaders/shader.h>
33 #include <dali/internal/update/controllers/render-message-dispatcher.h>
34 #include <dali/internal/update/controllers/scene-controller.h>
35 #include <dali/internal/update/nodes/node.h>
36 #include <dali/integration-api/debug.h>
37
38 #if defined(DEBUG_ENABLED)
39 namespace
40 {
41 Debug::Filter* gTextFilter = Debug::Filter::New(Debug::Concise, false, "LOG_SCENE_GRAPH_TEXT_ATTACHMENT");
42 }
43 #endif
44
45 namespace Dali
46 {
47
48 namespace Internal
49 {
50
51 namespace SceneGraph
52 {
53
54 TextAttachment* TextAttachment::New( )
55 {
56   return new TextAttachment;
57 }
58
59 TextAttachment::TextAttachment()
60 : RenderableAttachment( true ), // scale enabled
61   mTextRenderer( NULL ),
62   mGeometrySize(), // Vector2::ZERO
63   mGeometryScaling(), // Vector2::ZERO
64   mAtlasId(0)
65 {
66   DALI_LOG_INFO(gTextFilter, Debug::General, "TextAttachment::constructor(this=%p)\n", this);
67 }
68
69 void TextAttachment::ConnectToSceneGraph2( BufferIndex updateBufferIndex )
70 {
71   DALI_ASSERT_DEBUG( NULL != mSceneController );
72
73   // Create the renderer, passing ownership to the render-thread
74   mTextRenderer = TextRenderer::New( *mParent );
75   mTextRenderer->SetUseBlend( true ); // Text renderer always requires blending
76
77   mSceneController->GetRenderMessageDispatcher().AddRenderer( *mTextRenderer );
78 }
79
80 void TextAttachment::OnDestroy2()
81 {
82   DALI_ASSERT_DEBUG( NULL != mSceneController );
83
84   // Request deletion in the next Render
85   mSceneController->GetRenderMessageDispatcher().RemoveRenderer( *mTextRenderer );
86   mTextRenderer = NULL;
87 }
88
89 TextAttachment::~TextAttachment()
90 {
91 }
92
93 Renderer& TextAttachment::GetRenderer()
94 {
95   return *mTextRenderer;
96 }
97
98 const Renderer& TextAttachment::GetRenderer() const
99 {
100   return *mTextRenderer;
101 }
102
103 void TextAttachment::SetTextVertexBuffer( BufferIndex updateBufferIndex, TextVertexBuffer* vertexBuffer )
104 {
105   DALI_LOG_INFO( gTextFilter, Debug::Verbose, "TextAttachment::SetTextVertexBuffer( vertexBuffer:%p\n", vertexBuffer );
106
107   if( vertexBuffer )
108   {
109     mGeometrySize = vertexBuffer->mVertexMax;
110     SetRecalculateScaleForSize(); // update cached scaling if geometry is changed
111     mAtlasId = vertexBuffer->mTextureId;
112
113     typedef MessageValue1< TextRenderer, OwnerPointer< TextVertexBuffer> > DerivedType;
114
115     // Reserve some memory inside the render queue
116     unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
117
118     // Construct message in the render queue memory; note that delete should not be called on the return value
119     new (slot) DerivedType( mTextRenderer, &TextRenderer::SetVertexData, vertexBuffer );
120   }
121 }
122
123 void TextAttachment::SetTextFontSize( BufferIndex updateBufferIndex, float pixelSize )
124 {
125   typedef MessageValue1< TextRenderer, float > DerivedType;
126
127   // Reserve some memory inside the render queue
128   unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
129
130   // Construct message in the render queue memory; note that delete should not be called on the return value
131   new (slot) DerivedType( mTextRenderer, &TextRenderer::SetFontSize, pixelSize );
132 }
133
134 void TextAttachment::SetGradientColor( BufferIndex updateBufferIndex, const Vector4& color )
135 {
136   DALI_ASSERT_DEBUG(mSceneController);
137
138   typedef MessageValue1< TextRenderer, Vector4 > DerivedType;
139
140   // Reserve some memory inside the render queue
141   unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
142
143   // Construct message in the render queue memory; note that delete should not be called on the return value
144   new (slot) DerivedType( mTextRenderer, &TextRenderer::SetGradientColor, color );
145 }
146
147 void TextAttachment::SetGradientStartPoint( BufferIndex updateBufferIndex, const Vector2& position )
148 {
149   DALI_ASSERT_DEBUG(mSceneController);
150
151   typedef MessageValue1< TextRenderer, Vector2 > DerivedType;
152
153   // Reserve some memory inside the render queue
154   unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
155
156   // Construct message in the render queue memory; note that delete should not be called on the return value
157   new (slot) DerivedType( mTextRenderer, &TextRenderer::SetGradientStartPoint, position );
158 }
159
160 void TextAttachment::SetGradientEndPoint( BufferIndex updateBufferIndex, const Vector2& position )
161 {
162   DALI_ASSERT_DEBUG(mSceneController);
163
164   typedef MessageValue1< TextRenderer, Vector2 > DerivedType;
165
166   // Reserve some memory inside the render queue
167   unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
168
169   // Construct message in the render queue memory; note that delete should not be called on the return value
170   new (slot) DerivedType( mTextRenderer, &TextRenderer::SetGradientEndPoint, position );
171 }
172
173 void TextAttachment::SetTextColor( BufferIndex updateBufferIndex, const Vector4& color )
174 {
175   DALI_ASSERT_DEBUG(mSceneController);
176
177   typedef MessageValue1< TextRenderer, Vector4 > DerivedType;
178
179   // Reserve some memory inside the render queue
180   unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
181
182   // Construct message in the render queue memory; note that delete should not be called on the return value
183   new (slot) DerivedType( mTextRenderer, &TextRenderer::SetTextColor, color );
184 }
185
186 void TextAttachment::SetOutline( BufferIndex updateBufferIndex, const bool enable, const Vector4& color, const Vector2& params )
187 {
188   DALI_ASSERT_DEBUG(mSceneController);
189
190   typedef MessageValue3< TextRenderer, bool, Vector4, Vector2 > DerivedType;
191
192   // Reserve some memory inside the render queue
193   unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
194
195   // Construct message in the render queue memory; note that delete should not be called on the return value
196   new (slot) DerivedType( mTextRenderer, &TextRenderer::SetOutline, enable, color, params );
197 }
198
199 void TextAttachment::SetGlow( BufferIndex updateBufferIndex, const bool enable, const Vector4& color, const float params )
200 {
201   DALI_ASSERT_DEBUG(mSceneController);
202
203   typedef MessageValue3< TextRenderer, bool, Vector4, float > DerivedType;
204
205   // Reserve some memory inside the render queue
206   unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
207
208   // Construct message in the render queue memory; note that delete should not be called on the return value
209   new (slot) DerivedType( mTextRenderer, &TextRenderer::SetGlow, enable, color, params );
210 }
211
212 void TextAttachment::SetDropShadow( BufferIndex updateBufferIndex, const bool enable, const Vector4& color, const Vector2& offset, const float size )
213 {
214   DALI_ASSERT_DEBUG(mSceneController);
215
216   typedef MessageValue4< TextRenderer, bool, Vector4, Vector2, float > DerivedType;
217
218   // Reserve some memory inside the render queue
219   unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
220
221   // Construct message in the render queue memory; note that delete should not be called on the return value
222   new (slot) DerivedType( mTextRenderer, &TextRenderer::SetDropShadow, enable, color, offset, size );
223 }
224
225 void TextAttachment::SetSmoothEdge( BufferIndex updateBufferIndex, const float params )
226 {
227   DALI_ASSERT_DEBUG(mSceneController);
228
229   typedef MessageValue1< TextRenderer, float > DerivedType;
230
231   // Reserve some memory inside the render queue
232   unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
233
234   // Construct message in the render queue memory; note that delete should not be called on the return value
235   new (slot) DerivedType( mTextRenderer, &TextRenderer::SetSmoothEdge, params );
236 }
237
238 void TextAttachment::ShaderChanged( BufferIndex updateBufferIndex )
239 {
240   {
241     Shader* shader = GetParent().GetInheritedShader();
242
243     typedef MessageValue1< Renderer, Shader* > DerivedType;
244
245     // Reserve some memory inside the render queue
246     unsigned int* slot = mSceneController->GetRenderQueue().ReserveMessageSlot( updateBufferIndex, sizeof( DerivedType ) );
247
248     // Construct message in the mRenderer queue memory; note that delete should not be called on the return value
249     new (slot) DerivedType( mTextRenderer, &Renderer::SetShader, shader );
250   }
251 }
252
253 void TextAttachment::SizeChanged( BufferIndex updateBufferIndex )
254 {
255   SetRecalculateScaleForSize();
256 }
257
258 bool TextAttachment::DoPrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager )
259 {
260   bool resourcesAvailable = false;
261   mFinishedResourceAcquisition = false;
262
263   if( mAtlasId > 0)
264   {
265     if( resourceManager.IsResourceLoaded( mAtlasId ) )
266     {
267       // Check if currently loading glyph sets have finished writing to atlas
268       resourcesAvailable = true;
269
270       Integration::LoadStatus status = resourceManager.GetAtlasLoadStatus( mAtlasId );
271
272       if( status == Integration::RESOURCE_COMPLETELY_LOADED)
273       {
274         // all glyphs are loaded with high quality
275         mFinishedResourceAcquisition = true;
276       }
277     }
278   }
279
280   DALI_LOG_INFO(gTextFilter, Debug::Verbose, "TextAttachment::DoPrepareResources(this=%p) == %d  Complete:%d\n", this, resourcesAvailable, mFinishedResourceAcquisition);
281
282   return resourcesAvailable;
283 }
284
285 void TextAttachment::DoPrepareRender( BufferIndex updateBufferIndex )
286 {
287 }
288
289 void TextAttachment::DoGetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
290 {
291   // update cached scale for size if needed
292   if( IsScaleForSizeDirty() )
293   {
294     // scale the geometry to fill the actor
295     if( mGeometrySize.width > 0.0f )
296     {
297       mGeometryScaling.width = nodeSize.width / mGeometrySize.width;
298     }
299     if( mGeometrySize.height > 0.0f )
300     {
301       mGeometryScaling.height = nodeSize.height / mGeometrySize.height;
302     }
303   }
304   // use the already calculated value
305   scaling.width  = mGeometryScaling.width;
306   scaling.height = mGeometryScaling.height;
307   scaling.depth  = 1.0f;
308 }
309
310 } // namespace SceneGraph
311
312 } // namespace Internal
313
314 } // namespace Dali