Merge "Reduce exports by inlining alpha functions and helper constraints, removing...
[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 }
480
481 TextStyle TextActor::GetTextStyle() const
482 {
483   TextStyle textStyle;
484   mTextAttachment->GetTextStyle( textStyle );
485
486   return textStyle;
487 }
488
489 void TextActor::SetTextColor(const Vector4& color)
490 {
491   mTextAttachment->SetTextColor( color );
492 }
493
494 Vector4 TextActor::GetTextColor() const
495 {
496   return mTextAttachment->GetTextColor();
497 }
498
499 void TextActor::SetSmoothEdge( float smoothEdge )
500 {
501   mTextAttachment->SetSmoothEdge(smoothEdge);
502 }
503
504 void TextActor::SetOutline( bool enable, const Vector4& color, const Vector2& offset )
505 {
506   mTextAttachment->SetOutline(enable, color, offset);
507 }
508
509 void TextActor::SetGlow( bool enable, const Vector4& color, float intensity )
510 {
511   mTextAttachment->SetGlow(enable, color, intensity);
512 }
513
514 void TextActor::SetShadow( bool enable, const Vector4& color, const Vector2& offset, float size )
515 {
516   mTextAttachment->SetShadow(enable, color, offset, size);
517 }
518
519 void TextActor::SetItalics( Radian angle )
520 {
521   mTextAttachment->SetItalics( angle );
522
523   TextChanged();
524 }
525
526 bool TextActor::GetItalics() const
527 {
528   return mTextAttachment->GetItalics();
529 }
530
531 Radian TextActor::GetItalicsAngle() const
532 {
533   return mTextAttachment->GetItalicsAngle();
534 }
535
536 void TextActor::SetUnderline( bool enable, float thickness, float position )
537 {
538   mTextAttachment->SetUnderline( enable, thickness, position );
539
540   TextChanged();
541 }
542
543 bool TextActor::GetUnderline() const
544 {
545   return mTextAttachment->GetUnderline();
546 }
547
548 float TextActor::GetUnderlineThickness() const
549 {
550   return mTextAttachment->GetUnderlineThickness();
551 }
552
553 float TextActor::GetUnderlinePosition() const
554 {
555   return mTextAttachment->GetUnderlinePosition();
556 }
557
558 void TextActor::SetWeight( TextStyle::Weight weight )
559 {
560   mTextAttachment->SetWeight( weight );
561 }
562
563 TextStyle::Weight TextActor::GetWeight() const
564 {
565   return mTextAttachment->GetWeight();
566 }
567
568 void TextActor::SetFontDetectionAutomatic(bool value)
569 {
570   mFontDetection = value;
571 }
572
573 bool TextActor::IsFontDetectionAutomatic() const
574 {
575   return mFontDetection;
576 }
577
578 bool TextActor::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
579 {
580   bool connected( true );
581   TextActor* textActor = dynamic_cast<TextActor*>(object);
582
583   if( Dali::TextActor::SIGNAL_TEXT_LOADING_FINISHED == signalName )
584   {
585     textActor->TextAvailableSignal().Connect( tracker, functor );
586   }
587   else
588   {
589     // signalName does not match any signal
590     connected = false;
591   }
592
593   return connected;
594 }
595
596 void TextActor::TextLoaded()
597 {
598   // if the text is loaded, trigger the loaded finished signal
599   CheckTextLoadState();
600 }
601
602 void TextActor::TextChanged()
603 {
604   // this will tell the text attachment to act on any text or font changes
605   mTextAttachment->TextChanged();
606
607   // check the loading state
608   bool loaded = CheckTextLoadState();
609   if( ! loaded)
610   {
611     mLoadingState = Dali::ResourceLoading;
612
613     StartObservingTextLoads();
614   }
615   // the text natural size is calculated synchronously above, when TextChanged() is called
616   if (mUsingNaturalSize)
617   {
618     mInternalSetSize = true; // to know we're internally setting size
619     SetSize( mTextAttachment->GetNaturalTextSize() );
620     mInternalSetSize = false;
621   }
622 }
623
624 bool TextActor::CheckTextLoadState()
625 {
626   if( mTextAttachment->IsTextLoaded() )
627   {
628     mLoadingState = Dali::ResourceLoadingSucceeded;
629
630     StopObservingTextLoads();
631
632     // emit text available signal
633
634     mLoadingFinishedV2.Emit( Dali::TextActor( this ) );
635
636     return true;
637   }
638
639   // text not loaded
640   return false;
641 }
642
643 unsigned int TextActor::GetDefaultPropertyCount() const
644 {
645   return RenderableActor::GetDefaultPropertyCount() + DEFAULT_TEXT_ACTOR_PROPERTY_COUNT;
646 }
647
648 void TextActor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
649 {
650   RenderableActor::GetDefaultPropertyIndices( indices ); // RenderableActor class properties
651
652   indices.reserve( indices.size() + DEFAULT_TEXT_ACTOR_PROPERTY_COUNT );
653
654   int index = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
655   for ( int i = 0; i < DEFAULT_TEXT_ACTOR_PROPERTY_COUNT; ++i, ++index )
656   {
657     indices.push_back( index );
658   }
659 }
660
661 const std::string& TextActor::GetDefaultPropertyName( Property::Index index ) const
662 {
663   if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
664   {
665     return RenderableActor::GetDefaultPropertyName(index) ;
666   }
667   else
668   {
669     index -= DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
670
671     if ( ( index >= 0 ) && ( index < DEFAULT_TEXT_ACTOR_PROPERTY_COUNT ) )
672     {
673       return DEFAULT_TEXT_ACTOR_PROPERTY_NAMES[index];
674     }
675     else
676     {
677       // index out-of-bounds
678       static const std::string INVALID_PROPERTY_NAME;
679       return INVALID_PROPERTY_NAME;
680     }
681   }
682 }
683
684 Property::Index TextActor::GetDefaultPropertyIndex(const std::string& name) const
685 {
686   Property::Index index = Property::INVALID_INDEX;
687
688   DALI_ASSERT_DEBUG( NULL != mDefaultTextActorPropertyLookup );
689
690   // Look for name in current class' default properties
691   DefaultPropertyLookup::const_iterator result = mDefaultTextActorPropertyLookup->find( name );
692   if ( mDefaultTextActorPropertyLookup->end() != result )
693   {
694     index = result->second;
695   }
696   else
697   {
698     // If not found, check in base class
699     index = RenderableActor::GetDefaultPropertyIndex( name );
700   }
701
702   return index;
703 }
704
705 bool TextActor::IsDefaultPropertyWritable( Property::Index index ) const
706 {
707   if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
708   {
709     return RenderableActor::IsDefaultPropertyWritable(index) ;
710   }
711   else
712   {
713     return true ;
714   }
715 }
716
717 bool TextActor::IsDefaultPropertyAnimatable( Property::Index index ) const
718 {
719   if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
720   {
721     return RenderableActor::IsDefaultPropertyAnimatable(index) ;
722   }
723   else
724   {
725     return false ;
726   }
727 }
728
729 bool TextActor::IsDefaultPropertyAConstraintInput( Property::Index index ) const
730 {
731   if( index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT )
732   {
733     return RenderableActor::IsDefaultPropertyAConstraintInput(index);
734   }
735   return true; // Our properties can be used as input to constraints.
736 }
737
738 Property::Type TextActor::GetDefaultPropertyType( Property::Index index ) const
739 {
740   if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
741   {
742     return RenderableActor::GetDefaultPropertyType(index) ;
743   }
744   else
745   {
746     index -= DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
747
748     if ( ( index >= 0 ) && ( index < DEFAULT_TEXT_ACTOR_PROPERTY_COUNT ) )
749     {
750       return DEFAULT_TEXT_ACTOR_PROPERTY_TYPES[index];
751     }
752     else
753     {
754       // index out-of-bounds
755       return Property::NONE;
756     }
757   }
758 }
759
760 void TextActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
761 {
762   if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
763   {
764     RenderableActor::SetDefaultProperty(index, propertyValue) ;
765   }
766   else
767   {
768     switch(index)
769     {
770       case Dali::TextActor::TEXT:
771       {
772         SetText( GetTextArray( Dali::Text( propertyValue.Get<std::string>() ) ) );
773         break;
774       }
775       case Dali::TextActor::FONT:
776       {
777         SetFont(*Font::New(propertyValue.Get<std::string>(),
778                            mTextAttachment->GetFont().GetStyle(),
779                            PointSize(mTextAttachment->GetFont().GetPointSize())));
780         break;
781       }
782       case Dali::TextActor::FONT_STYLE:
783       {
784         SetFont(*Font::New(mTextAttachment->GetFont().GetName(),
785                            propertyValue.Get<std::string>(),
786                            PointSize(mTextAttachment->GetFont().GetPointSize())));
787         break;
788       }
789       case Dali::TextActor::OUTLINE_ENABLE:
790       {
791         Vector4 color;
792         Vector2 thickness;
793         mTextAttachment->GetOutlineParams( color, thickness );
794         mTextAttachment->SetOutline(propertyValue.Get<bool>(), color, thickness);
795         break;
796       }
797       case Dali::TextActor::OUTLINE_COLOR:
798       {
799         Vector4 color;
800         Vector2 thickness;
801         mTextAttachment->GetOutlineParams( color, thickness );
802         mTextAttachment->SetOutline(mTextAttachment->GetOutline(), propertyValue.Get<Vector4>(), thickness);
803         break;
804       }
805       case Dali::TextActor::OUTLINE_THICKNESS_WIDTH:
806       {
807         Vector4 color;
808         Vector2 thickness;
809         mTextAttachment->GetOutlineParams( color, thickness );
810         mTextAttachment->SetOutline(mTextAttachment->GetOutline(), color, propertyValue.Get<Vector2>());
811         break;
812       }
813       case Dali::TextActor::SMOOTH_EDGE:
814       {
815         mTextAttachment->SetSmoothEdge( propertyValue.Get<float>());
816         break;
817       }
818       case Dali::TextActor::GLOW_ENABLE:
819       {
820         Vector4 color;
821         float intensity;
822         mTextAttachment->GetGlowParams( color, intensity );
823         mTextAttachment->SetGlow(propertyValue.Get<bool>(), color, intensity);
824         break;
825       }
826       case Dali::TextActor::GLOW_COLOR:
827       {
828         Vector4 color;
829         float intensity;
830         mTextAttachment->GetGlowParams( color, intensity );
831         mTextAttachment->SetGlow(mTextAttachment->GetGlow(), propertyValue.Get<Vector4>(), intensity);
832         break;
833       }
834       case Dali::TextActor::GLOW_INTENSITY:
835       {
836         Vector4 color;
837         float intensity;
838         mTextAttachment->GetGlowParams( color, intensity );
839         mTextAttachment->SetGlow(mTextAttachment->GetGlow(), color, propertyValue.Get<float>());
840         break;
841       }
842       case Dali::TextActor::SHADOW_ENABLE:
843       {
844         Vector4 color;
845         Vector2 offset;
846         float size;
847         mTextAttachment->GetShadowParams( color, offset, size );
848         mTextAttachment->SetShadow(propertyValue.Get<bool>(), color, offset, size );
849         break;
850       }
851       case Dali::TextActor::SHADOW_COLOR:
852       {
853         Vector4 color;
854         Vector2 offset;
855         float size;
856         mTextAttachment->GetShadowParams( color, offset, size );
857         mTextAttachment->SetShadow(mTextAttachment->GetShadow(), propertyValue.Get<Vector4>(), offset, size);
858         break;
859       }
860       case Dali::TextActor::SHADOW_OFFSET:
861       {
862         Vector4 color;
863         Vector2 offset;
864         float size;
865         mTextAttachment->GetShadowParams( color, offset, size );
866         mTextAttachment->SetShadow(mTextAttachment->GetShadow(), color, propertyValue.Get<Vector2>(), size );
867         break;
868       }
869       case Dali::TextActor::SHADOW_SIZE:
870       {
871         Vector4 color;
872         Vector2 offset;
873         float size;
874         mTextAttachment->GetShadowParams( color, offset, size );
875         mTextAttachment->SetShadow(mTextAttachment->GetShadow(), color, offset, propertyValue.Get<float>());
876         break;
877       }
878       case Dali::TextActor::ITALICS_ANGLE:
879       {
880         SetItalics(Radian(propertyValue.Get<float>())) ;
881         break;
882       }
883       case Dali::TextActor::UNDERLINE:
884       {
885         SetUnderline(propertyValue.Get<bool>(), 0.f, 0.f ) ;
886         break;
887       }
888       case Dali::TextActor::WEIGHT:
889       {
890         mTextAttachment->SetWeight(static_cast<TextStyle::Weight>(propertyValue.Get<int>())) ;
891         break;
892       }
893       case Dali::TextActor::FONT_DETECTION_AUTOMATIC:
894       {
895         mFontDetection = propertyValue.Get<bool>()  ;
896         break;
897       }
898       case Dali::TextActor::GRADIENT_COLOR:
899       {
900         mTextAttachment->SetGradient( propertyValue.Get<Vector4>(), mTextAttachment->GetGradientStartPoint(), mTextAttachment->GetGradientEndPoint() );
901         break;
902       }
903       case Dali::TextActor::GRADIENT_START_POINT:
904       {
905         mTextAttachment->SetGradient( mTextAttachment->GetGradientColor(), propertyValue.Get<Vector2>(), mTextAttachment->GetGradientEndPoint() );
906         break;
907       }
908       case Dali::TextActor::GRADIENT_END_POINT:
909       {
910         mTextAttachment->SetGradient( mTextAttachment->GetGradientColor(), mTextAttachment->GetGradientStartPoint(), propertyValue.Get<Vector2>() );
911         break;
912       }
913       case Dali::TextActor::TEXT_COLOR:
914       {
915         mTextAttachment->SetTextColor( propertyValue.Get<Vector4>() );
916         break;
917       }
918       default:
919       {
920         DALI_LOG_WARNING("Unknown text set property (%d)\n", index);
921         break;
922       }
923     } // switch(index)
924
925   } // else
926 }
927
928 Property::Value TextActor::GetDefaultProperty( Property::Index index ) const
929 {
930   Property::Value ret ;
931   if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
932   {
933     ret = RenderableActor::GetDefaultProperty(index) ;
934   }
935   else
936   {
937     switch(index)
938     {
939       case Dali::TextActor::TEXT:
940       {
941         ret = GetText();
942         break;
943       }
944       case Dali::TextActor::FONT:
945       {
946         ret = mTextAttachment->GetFont().GetName();
947         break;
948       }
949       case Dali::TextActor::FONT_STYLE:
950       {
951         ret = mTextAttachment->GetFont().GetStyle();
952         break;
953       }
954       case Dali::TextActor::OUTLINE_ENABLE:
955       {
956         ret = mTextAttachment->GetOutline();
957         break;
958       }
959       case Dali::TextActor::OUTLINE_COLOR:
960       {
961         Vector4 color;
962         Vector2 thickness;
963         mTextAttachment->GetOutlineParams( color, thickness );
964         ret = color;
965         break;
966       }
967       case Dali::TextActor::OUTLINE_THICKNESS_WIDTH:
968       {
969         Vector4 color;
970         Vector2 thickness;
971         mTextAttachment->GetOutlineParams( color, thickness );
972         ret = thickness;
973         break;
974       }
975       case Dali::TextActor::SMOOTH_EDGE:
976       {
977         ret = mTextAttachment->GetSmoothEdge();
978         break;
979       }
980       case Dali::TextActor::GLOW_ENABLE:
981       {
982         ret = mTextAttachment->GetGlow();
983         break;
984       }
985       case Dali::TextActor::GLOW_COLOR:
986       {
987         Vector4 color;
988         float intensity(0.0f);
989         mTextAttachment->GetGlowParams( color, intensity );
990         ret  = color;
991         break;
992       }
993       case Dali::TextActor::GLOW_INTENSITY:
994       {
995         Vector4 color;
996         float intensity(0.0f);
997         mTextAttachment->GetGlowParams( color, intensity );
998         ret = intensity;
999         break;
1000       }
1001       case Dali::TextActor::SHADOW_ENABLE:
1002       {
1003         ret = mTextAttachment->GetShadow();
1004         break;
1005       }
1006       case Dali::TextActor::SHADOW_COLOR:
1007       {
1008         Vector4 color;
1009         Vector2 offset;
1010         float size;
1011         mTextAttachment->GetShadowParams( color, offset, size );
1012         ret = color;
1013         break;
1014       }
1015       case Dali::TextActor::SHADOW_OFFSET:
1016       {
1017         Vector4 color;
1018         Vector2 offset;
1019         float size;
1020         mTextAttachment->GetShadowParams( color, offset, size );
1021         ret = offset;
1022         break;
1023       }
1024       case Dali::TextActor::SHADOW_SIZE:
1025       {
1026         Vector4 color;
1027         Vector2 offset;
1028         float size;
1029         mTextAttachment->GetShadowParams( color, offset, size );
1030         ret = size;
1031         break;
1032       }
1033       case Dali::TextActor::ITALICS_ANGLE:
1034       {
1035         ret = static_cast<float>(mTextAttachment->GetItalics()) ;
1036         break;
1037       }
1038       case Dali::TextActor::UNDERLINE:
1039       {
1040         ret = mTextAttachment->GetUnderline() ;
1041         break;
1042       }
1043       case Dali::TextActor::WEIGHT:
1044       {
1045         ret = static_cast<int>(mTextAttachment->GetWeight());
1046         break;
1047       }
1048       case Dali::TextActor::FONT_DETECTION_AUTOMATIC:
1049       {
1050         ret = mFontDetection;
1051         break;
1052       }
1053       case Dali::TextActor::GRADIENT_COLOR:
1054       {
1055         ret = mTextAttachment->GetGradientColor();
1056         break;
1057       }
1058       case Dali::TextActor::GRADIENT_START_POINT:
1059       {
1060         ret = mTextAttachment->GetGradientStartPoint();
1061         break;
1062       }
1063       case Dali::TextActor::GRADIENT_END_POINT:
1064       {
1065         ret = mTextAttachment->GetGradientEndPoint();
1066         break;
1067       }
1068       case Dali::TextActor::TEXT_COLOR:
1069       {
1070         ret = mTextAttachment->GetTextColor();
1071         break;
1072       }
1073       default:
1074       {
1075         DALI_LOG_WARNING("Unknown text set property (%d)\n", index);
1076         break;
1077       }
1078     } // switch(index)
1079   } // if from base class
1080
1081   return ret ;
1082 }
1083
1084 } // namespace Internal
1085
1086 } // namespace Dali