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