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