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