Merge "Increased precision of texture coordinate in textured mesh shader" into tizen
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / text-actor-impl.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/event/actors/text-actor-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/object/type-registry.h>
23 #include <dali/public-api/text/text-actor-parameters.h>
24 #include <dali/internal/event/actor-attachments/text-attachment-impl.h>
25 #include <dali/internal/event/common/property-index-ranges.h>
26 #include <dali/internal/event/text/font-impl.h>
27 #include <dali/internal/event/text/utf8-impl.h>
28 #include <dali/internal/event/text/text-impl.h>
29 #include <dali/integration-api/platform-abstraction.h>
30 #include <dali/integration-api/debug.h>
31 #include <dali/internal/common/core-impl.h>
32
33 namespace Dali
34 {
35
36 const Property::Index TextActor::TEXT                       = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
37 const Property::Index TextActor::FONT                       = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 1;
38 const Property::Index TextActor::FONT_STYLE                 = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 2;
39 const Property::Index TextActor::OUTLINE_ENABLE             = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 3;
40 const Property::Index TextActor::OUTLINE_COLOR              = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 4;
41 const Property::Index TextActor::OUTLINE_THICKNESS_WIDTH    = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 5;
42 const Property::Index TextActor::SMOOTH_EDGE                = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 6;
43 const Property::Index TextActor::GLOW_ENABLE                = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 7;
44 const Property::Index TextActor::GLOW_COLOR                 = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 8;
45 const Property::Index TextActor::GLOW_INTENSITY             = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 9;
46 const Property::Index TextActor::SHADOW_ENABLE              = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 10;
47 const Property::Index TextActor::SHADOW_COLOR               = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 11;
48 const Property::Index TextActor::SHADOW_OFFSET              = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 12;
49 const Property::Index TextActor::ITALICS_ANGLE              = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 13;
50 const Property::Index TextActor::UNDERLINE                  = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 14;
51 const Property::Index TextActor::WEIGHT                     = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 15;
52 const Property::Index TextActor::FONT_DETECTION_AUTOMATIC   = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 16;
53 const Property::Index TextActor::GRADIENT_COLOR             = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 17;
54 const Property::Index TextActor::GRADIENT_START_POINT       = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 18;
55 const Property::Index TextActor::GRADIENT_END_POINT         = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 19;
56 const Property::Index TextActor::SHADOW_SIZE                = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 20;
57 const Property::Index TextActor::TEXT_COLOR                 = Internal::DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 21;
58
59 namespace
60 {
61
62 const std::string DEFAULT_TEXT_ACTOR_PROPERTY_NAMES[] =
63 {
64   "text",
65   "font",
66   "font-style",
67   "outline-enable",
68   "outline-color",
69   "outline-thickness-width",
70   "smooth-edge",
71   "glow-enable",
72   "glow-color",
73   "glow-intensity",
74   "shadow-enable",
75   "shadow-color",
76   "shadow-offset",
77   "italics-angle",
78   "underline",
79   "weight",
80   "font-detection-automatic",
81   "gradient-color",
82   "gradient-start-point",
83   "gradient-end-point",
84   "shadow-size",
85   "text-color"
86 };
87 const int DEFAULT_TEXT_ACTOR_PROPERTY_COUNT = sizeof( DEFAULT_TEXT_ACTOR_PROPERTY_NAMES ) / sizeof( std::string );
88
89 const Property::Type DEFAULT_TEXT_ACTOR_PROPERTY_TYPES[DEFAULT_TEXT_ACTOR_PROPERTY_COUNT] =
90 {
91   Property::STRING,   // "text"
92   Property::STRING,   // "font"
93   Property::STRING,   // "font-style"
94   Property::BOOLEAN,  // "outline-enable"
95   Property::VECTOR4,  // "outline-color"
96   Property::VECTOR2,  // "outline-thickness-width"
97   Property::FLOAT,    // "smooth-edge"
98   Property::BOOLEAN,  // "glow-enable"
99   Property::VECTOR4,  // "glow-color"
100   Property::FLOAT,    // "glow-intensity"
101   Property::BOOLEAN,  // "shadow-enable"
102   Property::VECTOR4,  // "shadow-color"
103   Property::VECTOR2,  // "shadow-offset"
104   Property::FLOAT,    // "italics-angle"
105   Property::BOOLEAN,  // "underline"
106   Property::INTEGER,  // "weight"
107   Property::BOOLEAN,  // "font-detection-automatic"
108   Property::VECTOR4,  // "gradient-color",
109   Property::VECTOR2,  // "gradient-start-point",
110   Property::VECTOR2,  // "gradient-end-point"
111   Property::FLOAT,    // "shadow-size"
112   Property::VECTOR4,  // "text-color",
113 };
114
115 }
116
117 namespace Internal
118 {
119 bool TextActor::mFirstInstance = true;
120 Actor::DefaultPropertyLookup* TextActor::mDefaultTextActorPropertyLookup = NULL;
121
122 namespace
123 {
124
125 BaseHandle Create()
126 {
127   return Dali::TextActor::New();
128 }
129
130 TypeRegistration mType( typeid(Dali::TextActor), typeid(Dali::RenderableActor), Create );
131
132 SignalConnectorType s1( mType, Dali::TextActor::SIGNAL_TEXT_LOADING_FINISHED, &TextActor::DoConnectSignal );
133
134 }
135
136 TextActorPtr TextActor::New( const Integration::TextArray& utfCodes, const TextActorParameters& parameters )
137 {
138   // first stage construction
139   TextActorPtr actor ( new TextActor( parameters.IsAutomaticFontDetectionEnabled() ) );
140
141   const TextStyle& style = parameters.GetTextStyle();
142
143   FontPointer fontPtr( Font::New(style.GetFontName(), style.GetFontStyle(), style.GetFontPointSize() ) );
144
145   // Second-phase construction
146   actor->Initialize();
147
148   //create the attachment
149   actor->mTextAttachment = TextAttachment::New( *actor->mNode, Integration::TextArray(), fontPtr );
150   actor->Attach(*actor->mTextAttachment);
151
152   // Note: SetTextStyle() MUST be called before SetText(), to ensure
153   //       that a single ResourceRequest for the glyphs is made. Calling
154   //       them in the wrong order will issue two requests.
155   actor->SetTextStyle( style, DONT_REQUEST_NEW_TEXT );
156
157   actor->SetText( utfCodes );
158
159   return actor;
160 }
161
162 TextActor::TextActor(bool fontDetection)
163 : RenderableActor(),
164   mLoadingState(Dali::ResourceLoading),
165   mUsingNaturalSize(true),
166   mInternalSetSize(false),
167   mFontDetection(fontDetection),
168   mObserving(false)
169 {
170 }
171
172 void TextActor::OnInitialize()
173 {
174   if(TextActor::mFirstInstance)
175   {
176     mDefaultTextActorPropertyLookup = new DefaultPropertyLookup();
177     const int start = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
178     for ( int i = 0; i < DEFAULT_TEXT_ACTOR_PROPERTY_COUNT; ++i )
179     {
180       (*mDefaultTextActorPropertyLookup)[DEFAULT_TEXT_ACTOR_PROPERTY_NAMES[i]] = i + start;
181     }
182     TextActor::mFirstInstance = false ;
183   }
184 }
185
186 TextActor::~TextActor()
187 {
188   StopObservingTextLoads();
189 }
190
191 const std::string TextActor::GetText() const
192 {
193   const Integration::TextArray& utfCodes = mTextAttachment->GetText();
194
195   std::string text;
196
197   const std::size_t length = utfCodes.Count();
198   // minimize allocations for ascii strings
199   text.reserve( length );
200
201   for (unsigned int i = 0; i < length; ++i)
202   {
203     unsigned char utf8Data[4];
204     unsigned int utf8Length;
205
206     utf8Length = UTF8Write(utfCodes[i], utf8Data);
207
208     text.append(reinterpret_cast<const char*>(utf8Data), utf8Length);
209   }
210
211   return text;
212 }
213
214 Font* TextActor::GetFont() const
215 {
216   return &mTextAttachment->GetFont();
217 }
218
219 void TextActor::SetToNaturalSize()
220 {
221   // ignore size set by application
222   mUsingNaturalSize = true;
223   TextChanged(); // this will calculate natural size
224 }
225
226 void TextActor::StopObservingTextLoads()
227 {
228   if( mObserving )
229   {
230     mTextAttachment->GetFont().RemoveObserver( *this );
231     mObserving = false;
232   }
233 }
234
235 void TextActor::StartObservingTextLoads()
236 {
237   if( !mObserving )
238   {
239     mTextAttachment->GetFont().AddObserver( *this );
240     mObserving = true;
241   }
242 }
243
244 void TextActor::SetText(const Integration::TextArray& utfCodes)
245 {
246   StopObservingTextLoads();
247
248   // assign the new text
249   mTextAttachment->SetText(utfCodes);
250
251   if( mFontDetection )
252   {
253     // first check if the provided font supports the text
254     //
255     if( !mTextAttachment->GetFont().AllGlyphsSupported(utfCodes) )
256     {
257       // auto-detect font
258       // @todo GetFamilyForText should return font name and style
259       const std::string fontName = Font::GetFamilyForText(utfCodes);
260
261       // use previous formatting
262       Internal::Font& font = mTextAttachment->GetFont();
263
264       Dali::Font fontNew = Dali::Font::New( Dali::FontParameters( fontName, font.GetStyle(), PointSize(font.GetPointSize() ) ) );
265
266       SetFont( GetImplementation(fontNew), DONT_REQUEST_NEW_TEXT );
267     }
268   }
269
270   TextChanged();
271 }
272
273 void TextActor::SetFont(Font& font, TextRequestMode mode )
274 {
275   StopObservingTextLoads();
276
277   if( mode == REQUEST_NEW_TEXT )
278   {
279     // set the new font
280     mTextAttachment->SetFont( font );
281
282     // request text for new font
283     TextChanged();
284   }
285   else
286   {
287     // just set the font
288     mTextAttachment->SetFont( font );
289   }
290 }
291
292 Vector3 TextActor::GetNaturalSize() const
293 {
294   Vector2 naturalSize( mTextAttachment->GetNaturalTextSize() );
295   return Vector3( naturalSize.width, naturalSize.height, CalculateSizeZ( naturalSize ) );
296 }
297
298 void TextActor::OnSizeSet(const Vector3& targetSize)
299 {
300   if( !mInternalSetSize )
301   {
302     // after size is once set by application we no longer use the natural size
303     mUsingNaturalSize = false;
304   }
305 }
306
307 void TextActor::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
308 {
309   // after size has been animated by application we no longer use the natural size
310   mUsingNaturalSize = false;
311 }
312
313 RenderableAttachment& TextActor::GetRenderableAttachment() const
314 {
315   DALI_ASSERT_DEBUG( mTextAttachment );
316   return *mTextAttachment;
317 }
318
319 void TextActor::SetGradientColor( const Vector4& color )
320 {
321   mTextAttachment->SetGradient( color, mTextAttachment->GetGradientStartPoint(), mTextAttachment->GetGradientEndPoint() );
322 }
323
324 const Vector4& TextActor::GetGradientColor() const
325 {
326   return mTextAttachment->GetGradientColor();
327 }
328
329 void TextActor::SetGradientStartPoint( const Vector2& position )
330 {
331   mTextAttachment->SetGradient( mTextAttachment->GetGradientColor(), position, mTextAttachment->GetGradientEndPoint() );
332 }
333
334 const Vector2& TextActor::GetGradientStartPoint() const
335 {
336   return mTextAttachment->GetGradientStartPoint();
337 }
338
339 void TextActor::SetGradientEndPoint( const Vector2& position )
340 {
341   mTextAttachment->SetGradient( mTextAttachment->GetGradientColor(), mTextAttachment->GetGradientStartPoint(), position );
342 }
343
344 const Vector2& TextActor::GetGradientEndPoint() const
345 {
346   return mTextAttachment->GetGradientEndPoint();
347 }
348
349 void TextActor::SetGradient( const Vector4& color, const Vector2& startPoint, const Vector2& endPoint )
350 {
351   mTextAttachment->SetGradient( color, startPoint, endPoint );
352 }
353
354 void TextActor::SetTextStyle( const TextStyle& style, TextRequestMode mode )
355 {
356   // Set font.
357   const Font& font = mTextAttachment->GetFont();
358
359   // Determine the font name/style/size that Font would create.
360   // Then compare this to the existing font (which has been validated by Font).
361
362   std::string resolvedFontName = style.GetFontName();
363   std::string resolvedFontStyle = style.GetFontStyle();
364   float resolvedFontPointSize = style.GetFontPointSize();
365   bool resolvedFontFamilyDefault(false);
366   bool resolvedFontPointSizeDefault(false);
367
368   Font::ValidateFontRequest( resolvedFontName,
369                              resolvedFontStyle,
370                              resolvedFontPointSize,
371                              resolvedFontFamilyDefault,
372                              resolvedFontPointSizeDefault );
373
374   // Now compare to existing font used to see if a font change is necessary.
375   if( ( font.GetName() != resolvedFontName ) ||
376       ( font.GetStyle() != resolvedFontStyle ) ||
377       ( fabsf(font.GetPointSize() - resolvedFontPointSize) >= GetRangedEpsilon(font.GetPointSize(), resolvedFontPointSize) ) )
378   {
379     // Create font with original request (so font can determine if family and/or point size is default)
380     SetFont( *(Font::New( style.GetFontName(), style.GetFontStyle(), style.GetFontPointSize() ) ), mode );
381   }
382
383   // Set color.
384   if( !style.IsTextColorDefault() )
385   {
386     SetTextColor( style.GetTextColor() );
387   }
388   else
389   {
390     mTextAttachment->ResetTextColor();
391   }
392
393   // Italics
394   if( !style.IsItalicsDefault() )
395   {
396     SetItalics( style.IsItalicsEnabled() ? Radian( style.GetItalicsAngle() ) : Radian( 0.0f ) );
397   }
398   else
399   {
400     mTextAttachment->ResetItalics();
401   }
402
403   // Underline
404   if( !style.IsUnderlineDefault() )
405   {
406     SetUnderline( style.IsUnderlineEnabled(), style.GetUnderlineThickness(), style.GetUnderlinePosition() );
407   }
408   else
409   {
410     mTextAttachment->ResetUnderline();
411   }
412
413   // Shadow
414   if( !style.IsShadowDefault() )
415   {
416     SetShadow( style.IsShadowEnabled(), style.GetShadowColor(), style.GetShadowOffset(), style.GetShadowSize() );
417   }
418   else
419   {
420     mTextAttachment->ResetShadow();
421   }
422
423   // Glow
424   if( !style.IsGlowDefault() )
425   {
426     SetGlow( style.IsGlowEnabled(), style.GetGlowColor(), style.GetGlowIntensity() );
427   }
428   else
429   {
430     mTextAttachment->ResetGlow();
431   }
432
433   // Soft Smooth edge.
434   if( !style.IsSmoothEdgeDefault() )
435   {
436     SetSmoothEdge( style.GetSmoothEdge() );
437   }
438   else
439   {
440     mTextAttachment->ResetSmoothEdge();
441   }
442
443   // Outline
444   if( !style.IsOutlineDefault() )
445   {
446     SetOutline( style.IsOutlineEnabled(), style.GetOutlineColor(), style.GetOutlineThickness() );
447   }
448   else
449   {
450     mTextAttachment->ResetOutline();
451   }
452
453   // Weight
454   if( !style.IsFontWeightDefault() )
455   {
456     SetWeight( style.GetWeight() );
457   }
458   else
459   {
460     mTextAttachment->ResetWeight();
461   }
462
463   //Gradient
464   if( !style.IsGradientDefault() )
465   {
466     if( style.IsGradientEnabled() )
467     {
468       SetGradient( style.GetGradientColor(), style.GetGradientStartPoint(), style.GetGradientEndPoint() );
469     }
470     else
471     {
472       SetGradient( TextStyle::DEFAULT_GRADIENT_COLOR, TextStyle::DEFAULT_GRADIENT_START_POINT, TextStyle::DEFAULT_GRADIENT_END_POINT );
473     }
474   }
475   else
476   {
477     mTextAttachment->ResetGradient();
478   }
479   TextChanged();
480 }
481
482 TextStyle TextActor::GetTextStyle() const
483 {
484   TextStyle textStyle;
485   mTextAttachment->GetTextStyle( textStyle );
486
487   return textStyle;
488 }
489
490 void TextActor::SetTextColor(const Vector4& color)
491 {
492   mTextAttachment->SetTextColor( color );
493 }
494
495 Vector4 TextActor::GetTextColor() const
496 {
497   return mTextAttachment->GetTextColor();
498 }
499
500 void TextActor::SetSmoothEdge( float smoothEdge )
501 {
502   mTextAttachment->SetSmoothEdge(smoothEdge);
503 }
504
505 void TextActor::SetOutline( bool enable, const Vector4& color, const Vector2& offset )
506 {
507   mTextAttachment->SetOutline(enable, color, offset);
508 }
509
510 void TextActor::SetGlow( bool enable, const Vector4& color, float intensity )
511 {
512   mTextAttachment->SetGlow(enable, color, intensity);
513 }
514
515 void TextActor::SetShadow( bool enable, const Vector4& color, const Vector2& offset, float size )
516 {
517   mTextAttachment->SetShadow(enable, color, offset, size);
518 }
519
520 void TextActor::SetItalics( Radian angle )
521 {
522   mTextAttachment->SetItalics( angle );
523
524   TextChanged();
525 }
526
527 bool TextActor::GetItalics() const
528 {
529   return mTextAttachment->GetItalics();
530 }
531
532 Radian TextActor::GetItalicsAngle() const
533 {
534   return mTextAttachment->GetItalicsAngle();
535 }
536
537 void TextActor::SetUnderline( bool enable, float thickness, float position )
538 {
539   mTextAttachment->SetUnderline( enable, thickness, position );
540
541   TextChanged();
542 }
543
544 bool TextActor::GetUnderline() const
545 {
546   return mTextAttachment->GetUnderline();
547 }
548
549 float TextActor::GetUnderlineThickness() const
550 {
551   return mTextAttachment->GetUnderlineThickness();
552 }
553
554 float TextActor::GetUnderlinePosition() const
555 {
556   return mTextAttachment->GetUnderlinePosition();
557 }
558
559 void TextActor::SetWeight( TextStyle::Weight weight )
560 {
561   mTextAttachment->SetWeight( weight );
562 }
563
564 TextStyle::Weight TextActor::GetWeight() const
565 {
566   return mTextAttachment->GetWeight();
567 }
568
569 void TextActor::SetFontDetectionAutomatic(bool value)
570 {
571   mFontDetection = value;
572 }
573
574 bool TextActor::IsFontDetectionAutomatic() const
575 {
576   return mFontDetection;
577 }
578
579 bool TextActor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
580 {
581   bool connected( true );
582   TextActor* textActor = dynamic_cast<TextActor*>(object);
583
584   if( Dali::TextActor::SIGNAL_TEXT_LOADING_FINISHED == signalName )
585   {
586     textActor->TextAvailableSignal().Connect( tracker, functor );
587   }
588   else
589   {
590     // signalName does not match any signal
591     connected = false;
592   }
593
594   return connected;
595 }
596
597 void TextActor::TextLoaded()
598 {
599   // if the text is loaded, trigger the loaded finished signal
600   CheckTextLoadState();
601 }
602
603 void TextActor::TextChanged()
604 {
605   // this will tell the text attachment to act on any text or font changes
606   mTextAttachment->TextChanged();
607
608   // check the loading state
609   bool loaded = CheckTextLoadState();
610   if( ! loaded)
611   {
612     mLoadingState = Dali::ResourceLoading;
613
614     StartObservingTextLoads();
615   }
616   // the text natural size is calculated synchronously above, when TextChanged() is called
617   if (mUsingNaturalSize)
618   {
619     mInternalSetSize = true; // to know we're internally setting size
620     SetSize( mTextAttachment->GetNaturalTextSize() );
621     mInternalSetSize = false;
622   }
623 }
624
625 bool TextActor::CheckTextLoadState()
626 {
627   if( mTextAttachment->IsTextLoaded() )
628   {
629     mLoadingState = Dali::ResourceLoadingSucceeded;
630
631     StopObservingTextLoads();
632
633     // emit text available signal
634
635     mLoadingFinishedV2.Emit( Dali::TextActor( this ) );
636
637     return true;
638   }
639
640   // text not loaded
641   return false;
642 }
643
644 unsigned int TextActor::GetDefaultPropertyCount() const
645 {
646   return RenderableActor::GetDefaultPropertyCount() + DEFAULT_TEXT_ACTOR_PROPERTY_COUNT;
647 }
648
649 void TextActor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
650 {
651   RenderableActor::GetDefaultPropertyIndices( indices ); // RenderableActor class properties
652
653   indices.reserve( indices.size() + DEFAULT_TEXT_ACTOR_PROPERTY_COUNT );
654
655   int index = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
656   for ( int i = 0; i < DEFAULT_TEXT_ACTOR_PROPERTY_COUNT; ++i, ++index )
657   {
658     indices.push_back( index );
659   }
660 }
661
662 const std::string& TextActor::GetDefaultPropertyName( Property::Index index ) const
663 {
664   if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
665   {
666     return RenderableActor::GetDefaultPropertyName(index) ;
667   }
668   else
669   {
670     index -= DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
671
672     if ( ( index >= 0 ) && ( index < DEFAULT_TEXT_ACTOR_PROPERTY_COUNT ) )
673     {
674       return DEFAULT_TEXT_ACTOR_PROPERTY_NAMES[index];
675     }
676     else
677     {
678       // index out-of-bounds
679       static const std::string INVALID_PROPERTY_NAME;
680       return INVALID_PROPERTY_NAME;
681     }
682   }
683 }
684
685 Property::Index TextActor::GetDefaultPropertyIndex(const std::string& name) const
686 {
687   Property::Index index = Property::INVALID_INDEX;
688
689   DALI_ASSERT_DEBUG( NULL != mDefaultTextActorPropertyLookup );
690
691   // Look for name in current class' default properties
692   DefaultPropertyLookup::const_iterator result = mDefaultTextActorPropertyLookup->find( name );
693   if ( mDefaultTextActorPropertyLookup->end() != result )
694   {
695     index = result->second;
696   }
697   else
698   {
699     // If not found, check in base class
700     index = RenderableActor::GetDefaultPropertyIndex( name );
701   }
702
703   return index;
704 }
705
706 bool TextActor::IsDefaultPropertyWritable( Property::Index index ) const
707 {
708   if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
709   {
710     return RenderableActor::IsDefaultPropertyWritable(index) ;
711   }
712   else
713   {
714     return true ;
715   }
716 }
717
718 bool TextActor::IsDefaultPropertyAnimatable( Property::Index index ) const
719 {
720   if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
721   {
722     return RenderableActor::IsDefaultPropertyAnimatable(index) ;
723   }
724   else
725   {
726     return false ;
727   }
728 }
729
730 bool TextActor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
731 {
732   if( index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT )
733   {
734     return RenderableActor::IsDefaultPropertyAConstraintInput(index);
735   }
736   return true; // Our properties can be used as input to constraints.
737 }
738
739 Property::Type TextActor::GetDefaultPropertyType( Property::Index index ) const
740 {
741   if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
742   {
743     return RenderableActor::GetDefaultPropertyType(index) ;
744   }
745   else
746   {
747     index -= DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
748
749     if ( ( index >= 0 ) && ( index < DEFAULT_TEXT_ACTOR_PROPERTY_COUNT ) )
750     {
751       return DEFAULT_TEXT_ACTOR_PROPERTY_TYPES[index];
752     }
753     else
754     {
755       // index out-of-bounds
756       return Property::NONE;
757     }
758   }
759 }
760
761 void TextActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
762 {
763   if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
764   {
765     RenderableActor::SetDefaultProperty(index, propertyValue) ;
766   }
767   else
768   {
769     switch(index)
770     {
771       case Dali::TextActor::TEXT:
772       {
773         SetText( GetTextArray( Dali::Text( propertyValue.Get<std::string>() ) ) );
774         break;
775       }
776       case Dali::TextActor::FONT:
777       {
778         SetFont(*Font::New(propertyValue.Get<std::string>(),
779                            mTextAttachment->GetFont().GetStyle(),
780                            PointSize(mTextAttachment->GetFont().GetPointSize())));
781         break;
782       }
783       case Dali::TextActor::FONT_STYLE:
784       {
785         SetFont(*Font::New(mTextAttachment->GetFont().GetName(),
786                            propertyValue.Get<std::string>(),
787                            PointSize(mTextAttachment->GetFont().GetPointSize())));
788         break;
789       }
790       case Dali::TextActor::OUTLINE_ENABLE:
791       {
792         Vector4 color;
793         Vector2 thickness;
794         mTextAttachment->GetOutlineParams( color, thickness );
795         mTextAttachment->SetOutline(propertyValue.Get<bool>(), color, thickness);
796         break;
797       }
798       case Dali::TextActor::OUTLINE_COLOR:
799       {
800         Vector4 color;
801         Vector2 thickness;
802         mTextAttachment->GetOutlineParams( color, thickness );
803         mTextAttachment->SetOutline(mTextAttachment->GetOutline(), propertyValue.Get<Vector4>(), thickness);
804         break;
805       }
806       case Dali::TextActor::OUTLINE_THICKNESS_WIDTH:
807       {
808         Vector4 color;
809         Vector2 thickness;
810         mTextAttachment->GetOutlineParams( color, thickness );
811         mTextAttachment->SetOutline(mTextAttachment->GetOutline(), color, propertyValue.Get<Vector2>());
812         break;
813       }
814       case Dali::TextActor::SMOOTH_EDGE:
815       {
816         mTextAttachment->SetSmoothEdge( propertyValue.Get<float>());
817         break;
818       }
819       case Dali::TextActor::GLOW_ENABLE:
820       {
821         Vector4 color;
822         float intensity;
823         mTextAttachment->GetGlowParams( color, intensity );
824         mTextAttachment->SetGlow(propertyValue.Get<bool>(), color, intensity);
825         break;
826       }
827       case Dali::TextActor::GLOW_COLOR:
828       {
829         Vector4 color;
830         float intensity;
831         mTextAttachment->GetGlowParams( color, intensity );
832         mTextAttachment->SetGlow(mTextAttachment->GetGlow(), propertyValue.Get<Vector4>(), intensity);
833         break;
834       }
835       case Dali::TextActor::GLOW_INTENSITY:
836       {
837         Vector4 color;
838         float intensity;
839         mTextAttachment->GetGlowParams( color, intensity );
840         mTextAttachment->SetGlow(mTextAttachment->GetGlow(), color, propertyValue.Get<float>());
841         break;
842       }
843       case Dali::TextActor::SHADOW_ENABLE:
844       {
845         Vector4 color;
846         Vector2 offset;
847         float size;
848         mTextAttachment->GetShadowParams( color, offset, size );
849         mTextAttachment->SetShadow(propertyValue.Get<bool>(), color, offset, size );
850         break;
851       }
852       case Dali::TextActor::SHADOW_COLOR:
853       {
854         Vector4 color;
855         Vector2 offset;
856         float size;
857         mTextAttachment->GetShadowParams( color, offset, size );
858         mTextAttachment->SetShadow(mTextAttachment->GetShadow(), propertyValue.Get<Vector4>(), offset, size);
859         break;
860       }
861       case Dali::TextActor::SHADOW_OFFSET:
862       {
863         Vector4 color;
864         Vector2 offset;
865         float size;
866         mTextAttachment->GetShadowParams( color, offset, size );
867         mTextAttachment->SetShadow(mTextAttachment->GetShadow(), color, propertyValue.Get<Vector2>(), size );
868         break;
869       }
870       case Dali::TextActor::SHADOW_SIZE:
871       {
872         Vector4 color;
873         Vector2 offset;
874         float size;
875         mTextAttachment->GetShadowParams( color, offset, size );
876         mTextAttachment->SetShadow(mTextAttachment->GetShadow(), color, offset, propertyValue.Get<float>());
877         break;
878       }
879       case Dali::TextActor::ITALICS_ANGLE:
880       {
881         SetItalics(Radian(propertyValue.Get<float>())) ;
882         break;
883       }
884       case Dali::TextActor::UNDERLINE:
885       {
886         SetUnderline(propertyValue.Get<bool>(), 0.f, 0.f ) ;
887         break;
888       }
889       case Dali::TextActor::WEIGHT:
890       {
891         mTextAttachment->SetWeight(static_cast<TextStyle::Weight>(propertyValue.Get<int>())) ;
892         break;
893       }
894       case Dali::TextActor::FONT_DETECTION_AUTOMATIC:
895       {
896         mFontDetection = propertyValue.Get<bool>()  ;
897         break;
898       }
899       case Dali::TextActor::GRADIENT_COLOR:
900       {
901         mTextAttachment->SetGradient( propertyValue.Get<Vector4>(), mTextAttachment->GetGradientStartPoint(), mTextAttachment->GetGradientEndPoint() );
902         break;
903       }
904       case Dali::TextActor::GRADIENT_START_POINT:
905       {
906         mTextAttachment->SetGradient( mTextAttachment->GetGradientColor(), propertyValue.Get<Vector2>(), mTextAttachment->GetGradientEndPoint() );
907         break;
908       }
909       case Dali::TextActor::GRADIENT_END_POINT:
910       {
911         mTextAttachment->SetGradient( mTextAttachment->GetGradientColor(), mTextAttachment->GetGradientStartPoint(), propertyValue.Get<Vector2>() );
912         break;
913       }
914       case Dali::TextActor::TEXT_COLOR:
915       {
916         mTextAttachment->SetTextColor( propertyValue.Get<Vector4>() );
917         break;
918       }
919       default:
920       {
921         DALI_LOG_WARNING("Unknown text set property (%d)\n", index);
922         break;
923       }
924     } // switch(index)
925
926   } // else
927 }
928
929 Property::Value TextActor::GetDefaultProperty( Property::Index index ) const
930 {
931   Property::Value ret ;
932   if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
933   {
934     ret = RenderableActor::GetDefaultProperty(index) ;
935   }
936   else
937   {
938     switch(index)
939     {
940       case Dali::TextActor::TEXT:
941       {
942         ret = GetText();
943         break;
944       }
945       case Dali::TextActor::FONT:
946       {
947         ret = mTextAttachment->GetFont().GetName();
948         break;
949       }
950       case Dali::TextActor::FONT_STYLE:
951       {
952         ret = mTextAttachment->GetFont().GetStyle();
953         break;
954       }
955       case Dali::TextActor::OUTLINE_ENABLE:
956       {
957         ret = mTextAttachment->GetOutline();
958         break;
959       }
960       case Dali::TextActor::OUTLINE_COLOR:
961       {
962         Vector4 color;
963         Vector2 thickness;
964         mTextAttachment->GetOutlineParams( color, thickness );
965         ret = color;
966         break;
967       }
968       case Dali::TextActor::OUTLINE_THICKNESS_WIDTH:
969       {
970         Vector4 color;
971         Vector2 thickness;
972         mTextAttachment->GetOutlineParams( color, thickness );
973         ret = thickness;
974         break;
975       }
976       case Dali::TextActor::SMOOTH_EDGE:
977       {
978         ret = mTextAttachment->GetSmoothEdge();
979         break;
980       }
981       case Dali::TextActor::GLOW_ENABLE:
982       {
983         ret = mTextAttachment->GetGlow();
984         break;
985       }
986       case Dali::TextActor::GLOW_COLOR:
987       {
988         Vector4 color;
989         float intensity(0.0f);
990         mTextAttachment->GetGlowParams( color, intensity );
991         ret  = color;
992         break;
993       }
994       case Dali::TextActor::GLOW_INTENSITY:
995       {
996         Vector4 color;
997         float intensity(0.0f);
998         mTextAttachment->GetGlowParams( color, intensity );
999         ret = intensity;
1000         break;
1001       }
1002       case Dali::TextActor::SHADOW_ENABLE:
1003       {
1004         ret = mTextAttachment->GetShadow();
1005         break;
1006       }
1007       case Dali::TextActor::SHADOW_COLOR:
1008       {
1009         Vector4 color;
1010         Vector2 offset;
1011         float size;
1012         mTextAttachment->GetShadowParams( color, offset, size );
1013         ret = color;
1014         break;
1015       }
1016       case Dali::TextActor::SHADOW_OFFSET:
1017       {
1018         Vector4 color;
1019         Vector2 offset;
1020         float size;
1021         mTextAttachment->GetShadowParams( color, offset, size );
1022         ret = offset;
1023         break;
1024       }
1025       case Dali::TextActor::SHADOW_SIZE:
1026       {
1027         Vector4 color;
1028         Vector2 offset;
1029         float size;
1030         mTextAttachment->GetShadowParams( color, offset, size );
1031         ret = size;
1032         break;
1033       }
1034       case Dali::TextActor::ITALICS_ANGLE:
1035       {
1036         ret = static_cast<float>(mTextAttachment->GetItalics()) ;
1037         break;
1038       }
1039       case Dali::TextActor::UNDERLINE:
1040       {
1041         ret = mTextAttachment->GetUnderline() ;
1042         break;
1043       }
1044       case Dali::TextActor::WEIGHT:
1045       {
1046         ret = static_cast<int>(mTextAttachment->GetWeight());
1047         break;
1048       }
1049       case Dali::TextActor::FONT_DETECTION_AUTOMATIC:
1050       {
1051         ret = mFontDetection;
1052         break;
1053       }
1054       case Dali::TextActor::GRADIENT_COLOR:
1055       {
1056         ret = mTextAttachment->GetGradientColor();
1057         break;
1058       }
1059       case Dali::TextActor::GRADIENT_START_POINT:
1060       {
1061         ret = mTextAttachment->GetGradientStartPoint();
1062         break;
1063       }
1064       case Dali::TextActor::GRADIENT_END_POINT:
1065       {
1066         ret = mTextAttachment->GetGradientEndPoint();
1067         break;
1068       }
1069       case Dali::TextActor::TEXT_COLOR:
1070       {
1071         ret = mTextAttachment->GetTextColor();
1072         break;
1073       }
1074       default:
1075       {
1076         DALI_LOG_WARNING("Unknown text set property (%d)\n", index);
1077         break;
1078       }
1079     } // switch(index)
1080   } // if from base class
1081
1082   return ret ;
1083 }
1084
1085 } // namespace Internal
1086
1087 } // namespace Dali