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