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