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