[dali_1.0.9] Merge branch 'tizen'
[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::SetGradient( BufferIndex updateBufferIndex, const Vector4& color, const Vector2& startPoint, const Vector2& endPoint )
135 {
136   DALI_ASSERT_DEBUG(mSceneController);
137
138   typedef MessageValue3< TextRenderer, Vector4, Vector2, Vector2 > 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::SetGradient, color, startPoint, endPoint );
145 }
146
147 void TextAttachment::SetTextColor( BufferIndex updateBufferIndex, const Vector4& color )
148 {
149   DALI_ASSERT_DEBUG(mSceneController);
150
151   typedef MessageValue1< TextRenderer, Vector4 > 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::SetTextColor, color );
158 }
159
160 void TextAttachment::SetOutline( BufferIndex updateBufferIndex, const bool enable, const Vector4& color, const Vector2& params )
161 {
162   DALI_ASSERT_DEBUG(mSceneController);
163
164   typedef MessageValue3< TextRenderer, bool, Vector4, 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::SetOutline, enable, color, params );
171 }
172
173 void TextAttachment::SetGlow( BufferIndex updateBufferIndex, const bool enable, const Vector4& color, const float params )
174 {
175   DALI_ASSERT_DEBUG(mSceneController);
176
177   typedef MessageValue3< TextRenderer, bool, Vector4, float > 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::SetGlow, enable, color, params );
184 }
185
186 void TextAttachment::SetDropShadow( BufferIndex updateBufferIndex, const bool enable, const Vector4& color, const Vector2& offset, const float size )
187 {
188   DALI_ASSERT_DEBUG(mSceneController);
189
190   typedef MessageValue4< TextRenderer, bool, Vector4, Vector2, float > 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::SetDropShadow, enable, color, offset, size );
197 }
198
199 void TextAttachment::SetSmoothEdge( BufferIndex updateBufferIndex, const float params )
200 {
201   DALI_ASSERT_DEBUG(mSceneController);
202
203   typedef MessageValue1< TextRenderer, 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::SetSmoothEdge, params );
210 }
211
212 void TextAttachment::ShaderChanged( BufferIndex updateBufferIndex )
213 {
214   // nothing to do
215 }
216
217 void TextAttachment::SizeChanged( BufferIndex updateBufferIndex )
218 {
219   SetRecalculateScaleForSize();
220 }
221
222 bool TextAttachment::DoPrepareResources( BufferIndex updateBufferIndex, ResourceManager& resourceManager )
223 {
224   bool resourcesAvailable = false;
225   mFinishedResourceAcquisition = false;
226
227   if( mAtlasId > 0)
228   {
229     if( resourceManager.IsResourceLoaded( mAtlasId ) )
230     {
231       // Check if currently loading glyph sets have finished writing to atlas
232       resourcesAvailable = true;
233
234       Integration::LoadStatus status = resourceManager.GetAtlasLoadStatus( mAtlasId );
235
236       if( status == Integration::RESOURCE_COMPLETELY_LOADED)
237       {
238         // all glyphs are loaded with high quality
239         mFinishedResourceAcquisition = true;
240       }
241     }
242   }
243
244   DALI_LOG_INFO(gTextFilter, Debug::Verbose, "TextAttachment::DoPrepareResources(this=%p) == %d  Complete:%d\n", this, resourcesAvailable, mFinishedResourceAcquisition);
245
246   return resourcesAvailable;
247 }
248
249 void TextAttachment::DoPrepareRender( BufferIndex updateBufferIndex )
250 {
251 }
252
253 void TextAttachment::DoGetScaleForSize( const Vector3& nodeSize, Vector3& scaling )
254 {
255   // update cached scale for size if needed
256   if( IsScaleForSizeDirty() )
257   {
258     // scale the geometry to fill the actor
259     if( mGeometrySize.width > 0.0f )
260     {
261       mGeometryScaling.width = nodeSize.width / mGeometrySize.width;
262     }
263     if( mGeometrySize.height > 0.0f )
264     {
265       mGeometryScaling.height = nodeSize.height / mGeometrySize.height;
266     }
267   }
268   // use the already calculated value
269   scaling.width  = mGeometryScaling.width;
270   scaling.height = mGeometryScaling.height;
271   scaling.depth  = 1.0f;
272 }
273
274 } // namespace SceneGraph
275
276 } // namespace Internal
277
278 } // namespace Dali