baba7442be1ec69c116adc33c77297a7ddca2f42
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / text / text-visual.cpp
1 /*
2  * Copyright (c) 2016 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-toolkit/internal/visuals/text/text-visual.h>
20
21 // EXTERNAL HEADER
22 #include <dali/devel-api/scripting/enum-helper.h>
23 // #include <dali/devel-api/scripting/scripting.h>
24
25 // INTERNAL HEADER
26 #include <dali-toolkit/public-api/text/rendering-backend.h>
27 #include <dali-toolkit/public-api/visuals/text-visual-properties.h>
28 #include <dali-toolkit/devel-api/visual-factory/devel-visual-properties.h>
29 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
30 #include <dali-toolkit/internal/text/rendering/text-backend.h>
31 #include <dali-toolkit/internal/text/text-view.h>
32 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
33 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
34 #include <dali-toolkit/internal/text/text-font-style.h>
35 #include <dali-toolkit/internal/text/text-effects-style.h>
36
37 using Dali::Toolkit::Text::LayoutEngine;
38
39 namespace Dali
40 {
41
42 namespace Toolkit
43 {
44
45 namespace Internal
46 {
47
48 namespace
49 {
50
51 // Property names.
52 const char * const RENDERING_BACKEND_PROPERTY( "renderingBackend" );
53 const char * const TEXT_PROPERTY( "text" );
54 const char * const FONT_FAMILY_PROPERTY( "fontFamily" );
55 const char * const FONT_STYLE_PROPERTY( "fontStyle" );
56 const char * const POINT_SIZE_PROPERTY( "pointSize" );
57 const char * const MULTI_LINE_PROPERTY( "multiLine" );
58 const char * const HORIZONTAL_ALIGNMENT_PROPERTY( "horizontalAlignment" );
59 const char * const VERTICAL_ALIGNMENT_PROPERTY( "verticalAlignment" );
60 const char * const TEXT_COLOR_PROPERTY( "textColor" );
61 const char * const ENABLE_MARKUP_PROPERTY( "enableMarkup" );
62 const char * const ENABLE_AUTO_SCROLL_PROPERTY( "enableAutoScroll" );
63 const char * const AUTO_SCROLL_SPEED_PROPERTY( "autoScrollSpeed" );
64 const char * const AUTO_SCROLL_LOOP_COUNT_PROPERTY( "autoScrollLoopCount" );
65 const char * const AUTO_SCROLL_GAP_PROPERTY( "autoScrollGap" );
66 const char * const LINE_SPACING_PROPERTY( "lineSpacing" );
67 const char * const UNDERLINE_PROPERTY( "underline" );
68 const char * const SHADOW_PROPERTY( "shadow" );
69 const char * const OUTLINE_PROPERTY( "outline" );
70 const char * const BATCHING_ENABLED_PROPERTY( "batchingEnabled" );
71
72 const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
73 {
74   { "BEGIN",  Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN  },
75   { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
76   { "END",    Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END    },
77 };
78 const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
79
80 const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
81 {
82   { "TOP",    Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP    },
83   { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
84   { "BOTTOM", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_BOTTOM },
85 };
86 const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
87
88 std::string GetHorizontalAlignment( LayoutEngine::HorizontalAlignment alignment )
89 {
90   const char* name = Scripting::GetEnumerationName<Toolkit::Text::LayoutEngine::HorizontalAlignment>( alignment,
91                                                                                                       HORIZONTAL_ALIGNMENT_STRING_TABLE,
92                                                                                                       HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
93
94   return std::string( name );
95 }
96
97 std::string GetVerticalAlignment( LayoutEngine::VerticalAlignment alignment )
98 {
99   const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( alignment,
100                                                                                                       VERTICAL_ALIGNMENT_STRING_TABLE,
101                                                                                                       VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
102
103   return std::string( name );
104 }
105
106 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
107   attribute mediump vec2 aPosition;\n
108   uniform mediump mat4 uMvpMatrix;\n
109   uniform mediump vec3 uSize;\n
110   uniform mediump vec4 pixelArea;
111   varying mediump vec2 vTexCoord;\n
112   \n
113   void main()\n
114   {\n
115     mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
116     vertexPosition.xyz *= uSize;\n
117     vertexPosition = uMvpMatrix * vertexPosition;\n
118     \n
119     vTexCoord = pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) );\n
120     gl_Position = vertexPosition;\n
121   }\n
122 );
123
124 const char* FRAGMENT_SHADER_ATLAS_CLAMP = DALI_COMPOSE_SHADER(
125     varying mediump vec2 vTexCoord;\n
126     uniform sampler2D sTexture;\n
127     uniform mediump vec4 uAtlasRect;\n
128     uniform lowp vec4 uColor;\n
129     \n
130     void main()\n
131     {\n
132       mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n
133       gl_FragColor = texture2D( sTexture, texCoord ) * uColor;\n
134     }\n
135 );
136
137 Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridSize )
138 {
139   Geometry geometry;
140
141   if( gridSize == ImageDimensions( 1, 1 ) )
142   {
143     geometry = factoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
144     if( !geometry )
145     {
146       geometry =  VisualFactoryCache::CreateQuadGeometry();
147       factoryCache.SaveGeometry( VisualFactoryCache::QUAD_GEOMETRY, geometry );
148     }
149   }
150   else
151   {
152     geometry = VisualFactoryCache::CreateGridGeometry( gridSize );
153   }
154
155   return geometry;
156 }
157
158 } // unnamed namespace
159
160 TextVisualPtr TextVisual::New( VisualFactoryCache& factoryCache )
161 {
162   return new TextVisual( factoryCache );
163 }
164
165 void TextVisual::SetSize( const Vector2& size )
166 {
167   const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
168
169   if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) ||
170       !mRenderer )
171   {
172     if( !mRenderer )
173     {
174       mRenderer = Text::Backend::Get().NewRenderer( mRenderingBackend );
175     }
176
177     RenderText();
178   }
179 }
180
181 float TextVisual::GetHeightForWidth( float width ) const
182 {
183   return mController->GetHeightForWidth( width );
184 }
185
186 void TextVisual::GetNaturalSize( Vector2& naturalSize )
187 {
188   naturalSize = mController->GetNaturalSize().GetVectorXY();
189 }
190
191 void TextVisual::DoCreatePropertyMap( Property::Map& map ) const
192 {
193   Property::Value value;
194
195   map.Clear();
196   map.Insert( Toolkit::VisualProperty::TYPE, Toolkit::Visual::TEXT );
197
198   map.Insert( Toolkit::TextVisual::Property::RENDERING_BACKEND, mRenderingBackend );
199
200   std::string text;
201   mController->GetText( text );
202   map.Insert( Toolkit::TextVisual::Property::TEXT, text );
203
204   map.Insert( Toolkit::TextVisual::Property::FONT_FAMILY, mController->GetDefaultFontFamily() );
205
206   GetFontStyleProperty( mController, value, Text::FontStyle::DEFAULT );
207   map.Insert( Toolkit::TextVisual::Property::FONT_STYLE, value );
208
209   map.Insert( Toolkit::TextVisual::Property::POINT_SIZE, mController->GetDefaultPointSize() );
210
211   map.Insert( Toolkit::TextVisual::Property::MULTI_LINE, mController->IsMultiLineEnabled() );
212
213   map.Insert( Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT, GetHorizontalAlignment( mController->GetHorizontalAlignment() ) );
214
215   map.Insert( Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT, GetVerticalAlignment( mController->GetVerticalAlignment() ) );
216
217   map.Insert( Toolkit::TextVisual::Property::TEXT_COLOR, mController->GetTextColor() );
218
219   map.Insert( Toolkit::TextVisual::Property::ENABLE_MARKUP, mController->IsMarkupProcessorEnabled() );
220
221   map.Insert( Toolkit::TextVisual::Property::LINE_SPACING, mController->GetDefaultLineSpacing() );
222
223   GetUnderlineProperties( mController, value, Text::EffectStyle::DEFAULT );
224   map.Insert( Toolkit::TextVisual::Property::UNDERLINE, value );
225
226   GetShadowProperties( mController, value, Text::EffectStyle::DEFAULT );
227   map.Insert( Toolkit::TextVisual::Property::SHADOW, value );
228
229   GetOutlineProperties( mController, value, Text::EffectStyle::DEFAULT );
230   map.Insert( Toolkit::TextVisual::Property::OUTLINE, value );
231
232   map.Insert( Toolkit::TextVisual::Property::BATCHING_ENABLED, false ); // TODO
233 }
234
235 TextVisual::TextVisual( VisualFactoryCache& factoryCache )
236 : Visual::Base( factoryCache ),
237   mController( Text::Controller::New() ),
238   mRenderingBackend( Toolkit::Text::DEFAULT_RENDERING_BACKEND ),
239   mHasBeenStaged( false )
240 {
241 }
242
243 TextVisual::~TextVisual()
244 {
245 }
246
247 void TextVisual::DoSetProperties( const Property::Map& propertyMap )
248 {
249   for( Property::Map::SizeType index = 0u, count = propertyMap.Count(); index < count; ++index )
250   {
251     const KeyValuePair& keyValue = propertyMap.GetKeyValue( index );
252
253     switch( keyValue.first.type )
254     {
255       case Property::Key::INDEX:
256       {
257         if( Toolkit::VisualProperty::TYPE != keyValue.first.indexKey ) // Toolkit::VisualProperty::TYPE is not a TextVisual's property.
258         {
259           DoSetProperty( keyValue.first.indexKey, keyValue.second );
260         }
261         break;
262       }
263       case Property::Key::STRING:
264       {
265         if( keyValue.first.stringKey == RENDERING_BACKEND_PROPERTY )
266         {
267           DoSetProperty( Toolkit::TextVisual::Property::RENDERING_BACKEND, keyValue.second );
268         }
269         else if( keyValue.first.stringKey == TEXT_PROPERTY )
270         {
271           DoSetProperty( Toolkit::TextVisual::Property::TEXT, keyValue.second );
272         }
273         else if( keyValue.first.stringKey == FONT_FAMILY_PROPERTY )
274         {
275           DoSetProperty( Toolkit::TextVisual::Property::FONT_FAMILY, keyValue.second );
276         }
277         else if( keyValue.first.stringKey == FONT_STYLE_PROPERTY )
278         {
279           DoSetProperty( Toolkit::TextVisual::Property::FONT_STYLE, keyValue.second );
280         }
281         else if( keyValue.first.stringKey == POINT_SIZE_PROPERTY )
282         {
283           DoSetProperty( Toolkit::TextVisual::Property::POINT_SIZE, keyValue.second );
284         }
285         else if( keyValue.first.stringKey == MULTI_LINE_PROPERTY )
286         {
287           DoSetProperty( Toolkit::TextVisual::Property::MULTI_LINE, keyValue.second );
288         }
289         else if( keyValue.first.stringKey == HORIZONTAL_ALIGNMENT_PROPERTY )
290         {
291           DoSetProperty( Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT, keyValue.second );
292         }
293         else if( keyValue.first.stringKey == VERTICAL_ALIGNMENT_PROPERTY )
294         {
295           DoSetProperty( Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT, keyValue.second );
296         }
297         else if( keyValue.first.stringKey == TEXT_COLOR_PROPERTY )
298         {
299           DoSetProperty( Toolkit::TextVisual::Property::TEXT_COLOR, keyValue.second );
300         }
301         else if( keyValue.first.stringKey == ENABLE_MARKUP_PROPERTY )
302         {
303           DoSetProperty( Toolkit::TextVisual::Property::ENABLE_MARKUP, keyValue.second );
304         }
305         else if( keyValue.first.stringKey == ENABLE_AUTO_SCROLL_PROPERTY )
306         {
307           DoSetProperty( Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL, keyValue.second );
308         }
309         else if( keyValue.first.stringKey == AUTO_SCROLL_SPEED_PROPERTY )
310         {
311           DoSetProperty( Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED, keyValue.second );
312         }
313         else if( keyValue.first.stringKey == AUTO_SCROLL_LOOP_COUNT_PROPERTY )
314         {
315           DoSetProperty( Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT, keyValue.second );
316         }
317         else if( keyValue.first.stringKey == AUTO_SCROLL_GAP_PROPERTY )
318         {
319           DoSetProperty( Toolkit::TextVisual::Property::AUTO_SCROLL_GAP, keyValue.second );
320         }
321         else if( keyValue.first.stringKey == LINE_SPACING_PROPERTY )
322         {
323           DoSetProperty( Toolkit::TextVisual::Property::LINE_SPACING, keyValue.second );
324         }
325         else if( keyValue.first.stringKey == UNDERLINE_PROPERTY )
326         {
327           DoSetProperty( Toolkit::TextVisual::Property::UNDERLINE, keyValue.second );
328         }
329         else if( keyValue.first.stringKey == SHADOW_PROPERTY )
330         {
331           DoSetProperty( Toolkit::TextVisual::Property::SHADOW, keyValue.second );
332         }
333         else if( keyValue.first.stringKey == OUTLINE_PROPERTY )
334         {
335           DoSetProperty( Toolkit::TextVisual::Property::OUTLINE, keyValue.second );
336         }
337         else if( keyValue.first.stringKey == BATCHING_ENABLED_PROPERTY )
338         {
339           DoSetProperty( Toolkit::TextVisual::Property::BATCHING_ENABLED, keyValue.second );
340         }
341         break;
342       }
343     }
344   }
345
346   // Retrieve the layout engine to set whether to elide the text and set the cursor's width.
347   Text::LayoutEngine& engine = mController->GetLayoutEngine();
348
349   // Elide the text if it exceeds the boundaries.
350   engine.SetTextEllipsisEnabled( true );
351
352   // Sets 0 as cursor's width.
353   engine.SetCursorWidth( 0u ); // Do not layout space for the cursor.
354 }
355
356 void TextVisual::DoSetOnStage( Actor& actor )
357 {
358   // TODO Create the actual renderer(s) for the text!!!!
359   //      Will crash if no mImpl->mRenderer is set.
360   Geometry geometry;
361   Shader shader;
362
363   geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
364
365   shader = mFactoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP );
366   if( !shader )
367   {
368     shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP );
369     mFactoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP, shader );
370   }
371
372   mImpl->mRenderer = Renderer::New( geometry, shader );
373
374   mSelf = actor;
375
376   if( mHasBeenStaged )
377   {
378     RenderText();
379   }
380   else
381   {
382     mHasBeenStaged = true;
383   }
384 }
385
386 void TextVisual::DoSetOffStage( Actor& actor )
387 {
388   mSelf.Reset();
389 }
390
391 void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
392 {
393   switch( index )
394   {
395     case Toolkit::TextVisual::Property::RENDERING_BACKEND:
396     {
397       int backend = propertyValue.Get<int>();
398
399 #ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
400       if( Text::RENDERING_VECTOR_BASED == backend )
401       {
402         backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering
403       }
404 #endif
405       if( mRenderingBackend != backend )
406       {
407         mRenderingBackend = backend;
408         mRenderer.Reset();
409
410         // When using the vector-based rendering, the size of the GLyphs are different
411         TextAbstraction::GlyphType glyphType = ( Text::RENDERING_VECTOR_BASED == mRenderingBackend ) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
412         mController->SetGlyphType( glyphType );
413       }
414       break;
415     }
416     case Toolkit::TextVisual::Property::TEXT:
417     {
418       mController->SetText( propertyValue.Get<std::string>() );
419       break;
420     }
421     case Toolkit::TextVisual::Property::FONT_FAMILY:
422     {
423       SetFontFamilyProperty( mController, propertyValue );
424       break;
425     }
426     case Toolkit::TextVisual::Property::FONT_STYLE:
427     {
428       SetFontStyleProperty( mController, propertyValue, Text::FontStyle::DEFAULT );
429       break;
430     }
431     case Toolkit::TextVisual::Property::POINT_SIZE:
432     {
433       const float pointSize = propertyValue.Get<float>();
434
435       if( !Equals( mController->GetDefaultPointSize(), pointSize ) )
436       {
437         mController->SetDefaultPointSize( pointSize );
438       }
439       break;
440     }
441     case Toolkit::TextVisual::Property::MULTI_LINE:
442     {
443       mController->SetMultiLineEnabled( propertyValue.Get<bool>() );
444       break;
445     }
446     case Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT:
447     {
448       LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
449       if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( propertyValue.Get< std::string >().c_str(),
450                                                                                          HORIZONTAL_ALIGNMENT_STRING_TABLE,
451                                                                                          HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
452                                                                                          alignment ) )
453       {
454         mController->SetHorizontalAlignment( alignment );
455       }
456       break;
457     }
458     case Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT:
459     {
460       LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
461       if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( propertyValue.Get< std::string >().c_str(),
462                                                                                        VERTICAL_ALIGNMENT_STRING_TABLE,
463                                                                                        VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
464                                                                                        alignment ) )
465       {
466         mController->SetVerticalAlignment( alignment );
467       }
468       break;
469     }
470     case Toolkit::TextVisual::Property::TEXT_COLOR:
471     {
472       const Vector4 textColor = propertyValue.Get< Vector4 >();
473       if( mController->GetTextColor() != textColor )
474       {
475         mController->SetTextColor( textColor );
476         mRenderer.Reset();
477       }
478       break;
479     }
480     case Toolkit::TextVisual::Property::ENABLE_MARKUP:
481     {
482       const bool enableMarkup = propertyValue.Get<bool>();
483       mController->SetMarkupProcessorEnabled( enableMarkup );
484       break;
485     }
486     case Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL:
487     {
488       // nothing to do.
489       break;
490     }
491     case Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED:
492     {
493       // nothing to do.
494       break;
495     }
496     case Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT:
497     {
498       // nothing to do.
499       break;
500     }
501     case Toolkit::TextVisual::Property::AUTO_SCROLL_GAP:
502     {
503       // nothing to do.
504       break;
505     }
506     case Toolkit::TextVisual::Property::LINE_SPACING:
507     {
508       const float lineSpacing = propertyValue.Get<float>();
509       mController->SetDefaultLineSpacing( lineSpacing );
510       mRenderer.Reset();
511       break;
512     }
513     case Toolkit::TextVisual::Property::UNDERLINE:
514     {
515       // TODO : This switch can be removed when the deprecated SHADOW_OFFSET and SHADOW_COLOR properties are finally removed.
516       //        Only the code for the MAP case should be kept.
517       switch( propertyValue.GetType() )
518       {
519         case Property::VECTOR4:
520         {
521           const Vector4 color = propertyValue.Get<Vector4>();
522           if( mController->GetUnderlineColor() != color )
523           {
524             mController->SetUnderlineColor( color );
525             mRenderer.Reset();
526           }
527           break;
528         }
529         case Property::FLOAT:
530         {
531           float height = propertyValue.Get<float>();
532           if( fabsf( mController->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 )
533           {
534             mController->SetUnderlineHeight( height );
535             mRenderer.Reset();
536           }
537           break;
538         }
539         case Property::BOOLEAN:
540         {
541           const bool enabled = propertyValue.Get<bool>();
542           if( mController->IsUnderlineEnabled() != enabled )
543           {
544             mController->SetUnderlineEnabled( enabled );
545             mRenderer.Reset();
546           }
547           break;
548         }
549         case Property::MAP:
550         {
551           const bool update = SetUnderlineProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
552           if( update )
553           {
554             mRenderer.Reset();
555           }
556           break;
557         }
558         default:
559         {
560           // Nothing to do.
561           break;
562         }
563       }
564
565       break;
566     }
567     case Toolkit::TextVisual::Property::SHADOW:
568     {
569       // TODO : This switch can be removed when the deprecated SHADOW_OFFSET and SHADOW_COLOR properties are finally removed.
570       //        Only the code for the MAP case should be kept.
571       switch( propertyValue.GetType() )
572       {
573         case Property::VECTOR2:
574         {
575           const Vector2 shadowOffset = propertyValue.Get<Vector2>();
576           if( mController->GetShadowOffset() != shadowOffset )
577           {
578             mController->SetShadowOffset( shadowOffset );
579             mRenderer.Reset();
580           }
581           break;
582         }
583         case Property::VECTOR4:
584         {
585           const Vector4 shadowColor = propertyValue.Get<Vector4>();
586           if( mController->GetShadowColor() != shadowColor )
587           {
588             mController->SetShadowColor( shadowColor );
589             mRenderer.Reset();
590           }
591           break;
592         }
593         case Property::MAP:
594         {
595           const bool update = SetShadowProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
596           if( update )
597           {
598             mRenderer.Reset();
599           }
600           break;
601         }
602         default:
603         {
604           // Nothing to do.
605           break;
606         }
607       }
608       break;
609     }
610     case Toolkit::TextVisual::Property::EMBOSS:
611     {
612       const bool update = SetEmbossProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
613       if( update )
614       {
615         mRenderer.Reset();
616      }
617       break;
618     }
619     case Toolkit::TextVisual::Property::OUTLINE:
620     {
621       const bool update = SetOutlineProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
622       if( update )
623       {
624         mRenderer.Reset();
625       }
626       break;
627     }
628     case Toolkit::TextVisual::Property::BATCHING_ENABLED:
629     {
630       // TODO
631       break;
632     }
633     default:
634     {
635       // Should not arrive here.
636       DALI_ASSERT_DEBUG( false );
637     }
638   }
639 }
640
641 Dali::Property::Value TextVisual::DoGetProperty( Dali::Property::Index index )
642 {
643   Dali::Property::Value value;
644
645   switch( index )
646   {
647     case Toolkit::TextVisual::Property::RENDERING_BACKEND:
648     {
649       value = mRenderingBackend;
650       break;
651     }
652     case Toolkit::TextVisual::Property::TEXT:
653     {
654       std::string text;
655       mController->GetText( text );
656       value = text;
657       break;
658     }
659     case Toolkit::TextVisual::Property::FONT_FAMILY:
660     {
661       value = mController->GetDefaultFontFamily();
662       break;
663     }
664     case Toolkit::TextVisual::Property::FONT_STYLE:
665     {
666       GetFontStyleProperty( mController, value, Text::FontStyle::DEFAULT );
667       break;
668     }
669     case Toolkit::TextVisual::Property::POINT_SIZE:
670     {
671       value = mController->GetDefaultPointSize();
672       break;
673     }
674     case Toolkit::TextVisual::Property::MULTI_LINE:
675     {
676       value = mController->IsMultiLineEnabled();
677       break;
678     }
679     case Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT:
680     {
681       const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( mController->GetHorizontalAlignment(),
682                                                                                                             HORIZONTAL_ALIGNMENT_STRING_TABLE,
683                                                                                                             HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
684       if( name )
685       {
686         value = std::string( name );
687       }
688       break;
689     }
690     case Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT:
691     {
692       const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( mController->GetVerticalAlignment(),
693                                                                                                           VERTICAL_ALIGNMENT_STRING_TABLE,
694                                                                                                           VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
695       if( name )
696       {
697         value = std::string( name );
698       }
699       break;
700     }
701     case Toolkit::TextVisual::Property::TEXT_COLOR:
702     {
703       value = mController->GetTextColor();
704       break;
705     }
706     case Toolkit::TextVisual::Property::ENABLE_MARKUP:
707     {
708       value = mController->IsMarkupProcessorEnabled();
709       break;
710     }
711     case Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL:
712     {
713       // nothing to do.
714       break;
715     }
716     case Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED:
717     {
718       // nothing to do.
719       break;
720     }
721     case Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT:
722     {
723       // nothing to do.
724       break;
725     }
726     case Toolkit::TextVisual::Property::AUTO_SCROLL_GAP:
727     {
728       // nothing to do.
729       break;
730     }
731     case Toolkit::TextVisual::Property::LINE_SPACING:
732     {
733       value = mController->GetDefaultLineSpacing();
734       break;
735     }
736     case Toolkit::TextVisual::Property::UNDERLINE:
737     {
738       GetUnderlineProperties( mController, value, Text::EffectStyle::DEFAULT );
739       break;
740     }
741     case Toolkit::TextVisual::Property::SHADOW:
742     {
743       GetShadowProperties( mController, value, Text::EffectStyle::DEFAULT );
744       break;
745     }
746     case Toolkit::TextVisual::Property::EMBOSS:
747     {
748       GetEmbossProperties( mController, value, Text::EffectStyle::DEFAULT );
749       break;
750     }
751     case Toolkit::TextVisual::Property::OUTLINE:
752     {
753       GetOutlineProperties( mController, value, Text::EffectStyle::DEFAULT );
754       break;
755     }
756     case Toolkit::TextVisual::Property::BATCHING_ENABLED:
757     {
758       // TODO
759       break;
760     }
761     default:
762     {
763       // Should not arrive here.
764       DALI_ASSERT_DEBUG( false );
765     }
766   }
767
768   return value;
769 }
770
771 void TextVisual::RenderText()
772 {
773   Actor self = mSelf.GetHandle();
774   if( !self )
775   {
776     // Nothing to do if the handle is not initialized.
777     return;
778   }
779
780   Actor renderableActor;
781
782   if( mRenderer )
783   {
784     renderableActor = mRenderer->Render( mController->GetView(), Toolkit::DepthIndex::TEXT );
785   }
786
787   if( renderableActor != mRenderableActor )
788   {
789     UnparentAndReset( mRenderableActor );
790
791     if( renderableActor )
792     {
793       const Vector2& scrollOffset = mController->GetScrollPosition();
794       renderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
795
796       self.Add( renderableActor );
797     }
798     mRenderableActor = renderableActor;
799   }
800 }
801
802 } // namespace Internal
803
804 } // namespace Toolkit
805
806 } // namespace Dali