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