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