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