Reduce Cyclomatic Complexity of some methods in text-typesetter, transtion-data ...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-label-impl.cpp
index 62e221c..d1c1b1a 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <dali-toolkit/internal/controls/text-controls/text-label-impl.h>
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/dali-common.h>
 #include <dali/public-api/object/type-registry-helper.h>
-#include <dali/public-api/common/stage.h>
+#include <dali/devel-api/common/stage.h>
 #include <dali/devel-api/object/property-helper-devel.h>
 #include <dali/devel-api/adaptor-framework/image-loading.h>
+#include <dali/devel-api/adaptor-framework/window-devel.h>
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
-#include <dali-toolkit/public-api/text/rendering-backend.h>
 #include <dali-toolkit/public-api/text/text-enumerations.h>
+#include <dali-toolkit/devel-api/text/rendering-backend.h>
 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
 #include <dali-toolkit/internal/text/property-string-parser.h>
 #include <dali-toolkit/internal/text/rendering/text-backend.h>
@@ -60,27 +62,29 @@ namespace Internal
 
 namespace
 {
-  const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
-
-  /**
-   * @brief How the text visual should be aligned vertically inside the control.
-   *
-   * 0.0f aligns the text to the top, 0.5f aligns the text to the center, 1.0f aligns the text to the bottom.
-   * The alignment depends on the alignment value of the text label (Use Text::VerticalAlignment enumerations).
-   */
-  const float VERTICAL_ALIGNMENT_TABLE[ Text::VerticalAlignment::BOTTOM + 1 ] =
-  {
-    0.0f,  // VerticalAlignment::TOP
-    0.5f,  // VerticalAlignment::CENTER
-    1.0f   // VerticalAlignment::BOTTOM
-  };
-}
+const unsigned int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::DevelText::DEFAULT_RENDERING_BACKEND;
 
-namespace
+/**
+ * @brief How the text visual should be aligned vertically inside the control.
+ *
+ * 0.0f aligns the text to the top, 0.5f aligns the text to the center, 1.0f aligns the text to the bottom.
+ * The alignment depends on the alignment value of the text label (Use Text::VerticalAlignment enumerations).
+ */
+const float VERTICAL_ALIGNMENT_TABLE[ Text::VerticalAlignment::BOTTOM + 1 ] =
 {
+  0.0f,  // VerticalAlignment::TOP
+  0.5f,  // VerticalAlignment::CENTER
+  1.0f   // VerticalAlignment::BOTTOM
+};
+
+const std::string TEXT_FIT_ENABLE_KEY( "enable" );
+const std::string TEXT_FIT_MIN_SIZE_KEY( "minSize" );
+const std::string TEXT_FIT_MAX_SIZE_KEY( "maxSize" );
+const std::string TEXT_FIT_STEP_SIZE_KEY( "stepSize" );
+const std::string TEXT_FIT_FONT_SIZE_TYPE_KEY( "fontSizeType" );
 
 #if defined ( DEBUG_ENABLED )
-  Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
 #endif
 
 const Scripting::StringEnum AUTO_SCROLL_STOP_MODE_TABLE[] =
@@ -99,7 +103,6 @@ BaseHandle Create()
 // Setup properties, signals and actions using the type-registry.
 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextLabel, Toolkit::Control, Create );
 
-DALI_PROPERTY_REGISTRATION( Toolkit,           TextLabel, "renderingBackend",          INTEGER, RENDERING_BACKEND          )
 DALI_PROPERTY_REGISTRATION( Toolkit,           TextLabel, "text",                      STRING,  TEXT                       )
 DALI_PROPERTY_REGISTRATION( Toolkit,           TextLabel, "fontFamily",                STRING,  FONT_FAMILY                )
 DALI_PROPERTY_REGISTRATION( Toolkit,           TextLabel, "fontStyle",                 MAP,     FONT_STYLE                 )
@@ -107,7 +110,6 @@ DALI_PROPERTY_REGISTRATION( Toolkit,           TextLabel, "pointSize",
 DALI_PROPERTY_REGISTRATION( Toolkit,           TextLabel, "multiLine",                 BOOLEAN, MULTI_LINE                 )
 DALI_PROPERTY_REGISTRATION( Toolkit,           TextLabel, "horizontalAlignment",       STRING,  HORIZONTAL_ALIGNMENT       )
 DALI_PROPERTY_REGISTRATION( Toolkit,           TextLabel, "verticalAlignment",         STRING,  VERTICAL_ALIGNMENT         )
-DALI_PROPERTY_REGISTRATION( Toolkit,           TextLabel, "unusedPropertyTextColor",   VECTOR4, UNUSED_PROPERTY_TEXT_COLOR )
 DALI_PROPERTY_REGISTRATION( Toolkit,           TextLabel, "enableMarkup",              BOOLEAN, ENABLE_MARKUP              )
 DALI_PROPERTY_REGISTRATION( Toolkit,           TextLabel, "enableAutoScroll",          BOOLEAN, ENABLE_AUTO_SCROLL         )
 DALI_PROPERTY_REGISTRATION( Toolkit,           TextLabel, "autoScrollSpeed",           INTEGER, AUTO_SCROLL_SPEED          )
@@ -129,6 +131,9 @@ DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "verticalLineAlignment
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "textBackground",            MAP,     BACKGROUND                 )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "ignoreSpacesAfterText",     BOOLEAN, IGNORE_SPACES_AFTER_TEXT   )
 DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "matchSystemLanguageDirection", BOOLEAN, MATCH_SYSTEM_LANGUAGE_DIRECTION )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "textFit",                   MAP,     TEXT_FIT                   )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "minLineSize",               FLOAT,   MIN_LINE_SIZE              )
+DALI_DEVEL_PROPERTY_REGISTRATION( Toolkit,     TextLabel, "renderingBackend",          INTEGER, RENDERING_BACKEND          )
 DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, TextLabel, "textColor",      Color::BLACK,     TEXT_COLOR     )
 DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit,    TextLabel, "textColorRed",   TEXT_COLOR_RED,   TEXT_COLOR, 0  )
 DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit,    TextLabel, "textColorGreen", TEXT_COLOR_GREEN, TEXT_COLOR, 1  )
@@ -136,6 +141,73 @@ DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit,    TextLabel, "textCol
 DALI_ANIMATABLE_PROPERTY_COMPONENT_REGISTRATION( Toolkit,    TextLabel, "textColorAlpha", TEXT_COLOR_ALPHA, TEXT_COLOR, 3  )
 DALI_TYPE_REGISTRATION_END()
 
+/// Parses the property map for the TEXT_FIT property
+void ParseTextFitProperty(Text::ControllerPtr& controller, const Property::Map* propertiesMap)
+{
+  if ( propertiesMap && !propertiesMap->Empty() )
+  {
+    bool enabled = false;
+    float minSize = 0.f;
+    float maxSize = 0.f;
+    float stepSize = 0.f;
+    bool isMinSizeSet = false, isMaxSizeSet = false, isStepSizeSet = false;
+    Controller::FontSizeType type = Controller::FontSizeType::POINT_SIZE;
+
+    const unsigned int numberOfItems = propertiesMap->Count();
+
+    // Parses and applies
+    for( unsigned int index = 0u; index < numberOfItems; ++index )
+    {
+      const KeyValuePair& valueGet = propertiesMap->GetKeyValue( index );
+
+      if( ( Controller::TextFitInfo::Property::TEXT_FIT_ENABLE == valueGet.first.indexKey ) || ( TEXT_FIT_ENABLE_KEY == valueGet.first.stringKey ) )
+      {
+        /// Enable key.
+        enabled = valueGet.second.Get< bool >();
+      }
+      else if( ( Controller::TextFitInfo::Property::TEXT_FIT_MIN_SIZE == valueGet.first.indexKey ) || ( TEXT_FIT_MIN_SIZE_KEY == valueGet.first.stringKey ) )
+      {
+        /// min size.
+        minSize = valueGet.second.Get< float >();
+        isMinSizeSet = true;
+      }
+      else if( ( Controller::TextFitInfo::Property::TEXT_FIT_MAX_SIZE == valueGet.first.indexKey ) || ( TEXT_FIT_MAX_SIZE_KEY == valueGet.first.stringKey ) )
+      {
+        /// max size.
+        maxSize = valueGet.second.Get< float >();
+        isMaxSizeSet = true;
+      }
+      else if( ( Controller::TextFitInfo::Property::TEXT_FIT_STEP_SIZE == valueGet.first.indexKey ) || ( TEXT_FIT_STEP_SIZE_KEY == valueGet.first.stringKey ) )
+      {
+        /// step size.
+        stepSize = valueGet.second.Get< float >();
+        isStepSizeSet = true;
+      }
+      else if( ( Controller::TextFitInfo::Property::TEXT_FIT_FONT_SIZE_TYPE == valueGet.first.indexKey ) || ( TEXT_FIT_FONT_SIZE_TYPE_KEY == valueGet.first.stringKey ) )
+      {
+        if( "pixelSize" == valueGet.second.Get< std::string >() )
+        {
+          type = Controller::FontSizeType::PIXEL_SIZE;
+        }
+      }
+    }
+
+    controller->SetTextFitEnabled( enabled );
+    if( isMinSizeSet )
+    {
+      controller->SetTextFitMinSize( minSize, type );
+    }
+    if( isMaxSizeSet )
+    {
+      controller->SetTextFitMaxSize( maxSize, type );
+    }
+    if( isStepSizeSet )
+    {
+      controller->SetTextFitStepSize( stepSize, type );
+    }
+  }
+}
+
 } // namespace
 
 Toolkit::TextLabel TextLabel::New()
@@ -160,16 +232,16 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
   if( label )
   {
     TextLabel& impl( GetImpl( label ) );
+    DALI_ASSERT_ALWAYS( impl.mController && "No text contoller" );
+
     switch( index )
     {
-      case Toolkit::TextLabel::Property::RENDERING_BACKEND:
+      case Toolkit::DevelTextLabel::Property::RENDERING_BACKEND:
       {
-        DALI_LOG_WARNING("[%s] Using deprecated Property TextLabel::Property::RENDERING_BACKEND which is no longer supported and will be ignored\n", __FUNCTION__);
-
         int backend = value.Get< int >();
 
 #ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
-        if( Text::RENDERING_VECTOR_BASED == backend )
+        if( DevelText::RENDERING_VECTOR_BASED == backend )
         {
           backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering
         }
@@ -179,32 +251,23 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
           impl.mRenderingBackend = backend;
           impl.mTextUpdateNeeded = true;
 
-          if( impl.mController )
-          {
-            // When using the vector-based rendering, the size of the GLyphs are different
-            TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
-            impl.mController->SetGlyphType( glyphType );
-          }
+          // When using the vector-based rendering, the size of the GLyphs are different
+          TextAbstraction::GlyphType glyphType = (DevelText::RENDERING_VECTOR_BASED == impl.mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
+          impl.mController->SetGlyphType( glyphType );
         }
         break;
       }
       case Toolkit::TextLabel::Property::TEXT:
       {
-        if( impl.mController )
-        {
-          impl.mController->SetText( value.Get< std::string >() );
-        }
+        impl.mController->SetText( value.Get< std::string >() );
         break;
       }
       case Toolkit::TextLabel::Property::FONT_FAMILY:
       {
-        if( impl.mController )
-        {
-          const std::string& fontFamily = value.Get< std::string >();
+        const std::string& fontFamily = value.Get< std::string >();
 
-          DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::SetProperty Property::FONT_FAMILY newFont(%s)\n", fontFamily.c_str() );
-          impl.mController->SetDefaultFontFamily( fontFamily );
-        }
+        DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::SetProperty Property::FONT_FAMILY newFont(%s)\n", fontFamily.c_str() );
+        impl.mController->SetDefaultFontFamily( fontFamily );
         break;
       }
       case Toolkit::TextLabel::Property::FONT_STYLE:
@@ -214,233 +277,156 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextLabel::Property::POINT_SIZE:
       {
-        if( impl.mController )
-        {
-          const float pointSize = value.Get< float >();
+        const float pointSize = value.Get< float >();
 
-          if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE ), pointSize ) )
-          {
-            impl.mController->SetDefaultFontSize( pointSize, Text::Controller::POINT_SIZE );
-          }
+        if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE ), pointSize ) )
+        {
+          impl.mController->SetDefaultFontSize( pointSize, Text::Controller::POINT_SIZE );
         }
         break;
       }
       case Toolkit::TextLabel::Property::MULTI_LINE:
       {
-        if( impl.mController )
-        {
-          impl.mController->SetMultiLineEnabled( value.Get< bool >() );
-        }
+        impl.mController->SetMultiLineEnabled( value.Get< bool >() );
         break;
       }
       case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
       {
-        if( impl.mController )
+        Text::HorizontalAlignment::Type alignment( static_cast< Text::HorizontalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
+        if( Text::GetHorizontalAlignmentEnumeration( value, alignment ) )
         {
-          Text::HorizontalAlignment::Type alignment( static_cast< Text::HorizontalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
-          if( Text::GetHorizontalAlignmentEnumeration( value, alignment ) )
-          {
-            impl.mController->SetHorizontalAlignment( alignment );
-          }
+          impl.mController->SetHorizontalAlignment( alignment );
         }
         break;
       }
       case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
       {
-        if( impl.mController )
+        Toolkit::Text::VerticalAlignment::Type alignment( static_cast< Text::VerticalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
+        if( Text::GetVerticalAlignmentEnumeration( value, alignment ) )
         {
-          Toolkit::Text::VerticalAlignment::Type alignment( static_cast< Text::VerticalAlignment::Type >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
-          if( Text::GetVerticalAlignmentEnumeration( value, alignment ) )
-          {
-            impl.mController->SetVerticalAlignment( alignment );
-          }
+          impl.mController->SetVerticalAlignment( alignment );
         }
         break;
       }
-
-      case Toolkit::TextLabel::Property::UNUSED_PROPERTY_TEXT_COLOR:
-      {
-        label.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, value );
-        impl.mTextUpdateNeeded = true;
-        break;
-      }
       case Toolkit::TextLabel::Property::ENABLE_MARKUP:
       {
-        if( impl.mController )
-        {
-          const bool enableMarkup = value.Get<bool>();
-          impl.mController->SetMarkupProcessorEnabled( enableMarkup );
-        }
+        const bool enableMarkup = value.Get<bool>();
+        impl.mController->SetMarkupProcessorEnabled( enableMarkup );
         break;
       }
       case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL:
       {
-        if( impl.mController )
+        const bool enableAutoScroll = value.Get<bool>();
+        // If request to auto scroll is the same as current state then do nothing.
+        if ( enableAutoScroll != impl.mController->IsAutoScrollEnabled() )
         {
-          const bool enableAutoScroll = value.Get<bool>();
-          // If request to auto scroll is the same as current state then do nothing.
-          if ( enableAutoScroll != impl.mController->IsAutoScrollEnabled() )
-          {
-             // If request is disable (false) and auto scrolling is enabled then need to stop it
-             if ( enableAutoScroll == false )
-             {
-               if( impl.mTextScroller )
-               {
-                 impl.mTextScroller->StopScrolling();
-               }
-             }
-             // If request is enable (true) then start autoscroll as not already running
-             else
+           // If request is disable (false) and auto scrolling is enabled then need to stop it
+           if ( enableAutoScroll == false )
+           {
+             if( impl.mTextScroller )
              {
-               impl.mController->SetAutoScrollEnabled( enableAutoScroll );
+               impl.mTextScroller->StopScrolling();
              }
-          }
+           }
+           // If request is enable (true) then start autoscroll as not already running
+           else
+           {
+             impl.mController->SetAutoScrollEnabled( enableAutoScroll );
+           }
         }
         break;
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_STOP_MODE:
       {
-        if( !impl.mTextScroller )
-        {
-          impl.mTextScroller = Text::TextScroller::New( impl );
-        }
-        Toolkit::TextLabel::AutoScrollStopMode::Type stopMode = impl.mTextScroller->GetStopMode();
+        Text::TextScrollerPtr textScroller = impl.GetTextScroller();
+        Toolkit::TextLabel::AutoScrollStopMode::Type stopMode = textScroller->GetStopMode();
         if( Scripting::GetEnumerationProperty< Toolkit::TextLabel::AutoScrollStopMode::Type >( value,
-                                                                                                    AUTO_SCROLL_STOP_MODE_TABLE,
-                                                                                                    AUTO_SCROLL_STOP_MODE_TABLE_COUNT,
-                                                                                                    stopMode ) )
+                                                                                               AUTO_SCROLL_STOP_MODE_TABLE,
+                                                                                               AUTO_SCROLL_STOP_MODE_TABLE_COUNT,
+                                                                                               stopMode ) )
         {
-            impl.mTextScroller->SetStopMode( stopMode );
+          textScroller->SetStopMode( stopMode );
         }
         break;
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED:
       {
-        if( !impl.mTextScroller )
-        {
-          impl.mTextScroller = Text::TextScroller::New( impl );
-        }
-        impl.mTextScroller->SetSpeed( value.Get<int>() );
+        impl.GetTextScroller()->SetSpeed( value.Get<int>() );
         break;
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT:
       {
-        if( !impl.mTextScroller )
-        {
-          impl.mTextScroller = Text::TextScroller::New( impl );
-        }
-        impl.mTextScroller->SetLoopCount( value.Get<int>() );
+        impl.GetTextScroller()->SetLoopCount( value.Get<int>() );
         break;
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_DELAY:
       {
-         if( !impl.mTextScroller )
-        {
-          impl.mTextScroller = Text::TextScroller::New( impl );
-        }
-        impl.mTextScroller->SetLoopDelay( value.Get<float>() );
+        impl.GetTextScroller()->SetLoopDelay( value.Get<float>() );
         break;
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP:
       {
-        if( !impl.mTextScroller )
-        {
-          impl.mTextScroller = Text::TextScroller::New( impl );
-        }
-        impl.mTextScroller->SetGap( value.Get<float>() );
+        impl.GetTextScroller()->SetGap( value.Get<float>() );
         break;
       }
       case Toolkit::TextLabel::Property::LINE_SPACING:
       {
-        if( impl.mController )
-        {
-          const float lineSpacing = value.Get<float>();
-
-          // Don't trigger anything if the line spacing didn't change
-          if( impl.mController->SetDefaultLineSpacing( lineSpacing ) )
-          {
-            impl.mTextUpdateNeeded = true;
-          }
-        }
+        const float lineSpacing = value.Get<float>();
+        impl.mTextUpdateNeeded = impl.mController->SetDefaultLineSpacing( lineSpacing ) || impl.mTextUpdateNeeded;
         break;
       }
       case Toolkit::TextLabel::Property::UNDERLINE:
       {
-        const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        if( update )
-        {
-          impl.mTextUpdateNeeded = true;
-        }
+        impl.mTextUpdateNeeded = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ) || impl.mTextUpdateNeeded;
         break;
       }
       case Toolkit::TextLabel::Property::SHADOW:
       {
-        const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        if( update )
-        {
-          impl.mTextUpdateNeeded = true;
-        }
+        impl.mTextUpdateNeeded = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT ) || impl.mTextUpdateNeeded;
         break;
       }
       case Toolkit::TextLabel::Property::EMBOSS:
       {
-        const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        if( update )
-        {
-          impl.mTextUpdateNeeded = true;
-        }
+        impl.mTextUpdateNeeded = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT ) || impl.mTextUpdateNeeded;
         break;
       }
       case Toolkit::TextLabel::Property::OUTLINE:
       {
-        const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        if( update )
-        {
-          impl.mTextUpdateNeeded = true;
-        }
+        impl.mTextUpdateNeeded = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT ) || impl.mTextUpdateNeeded;
         break;
       }
       case Toolkit::TextLabel::Property::PIXEL_SIZE:
       {
-        if( impl.mController )
-        {
-          const float pixelSize = value.Get< float >();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize );
+        const float pixelSize = value.Get< float >();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p PIXEL_SIZE %f\n", impl.mController.Get(), pixelSize );
 
-          if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE ), pixelSize ) )
-          {
-            impl.mController->SetDefaultFontSize( pixelSize, Text::Controller::PIXEL_SIZE );
-          }
+        if( !Equals( impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE ), pixelSize ) )
+        {
+          impl.mController->SetDefaultFontSize( pixelSize, Text::Controller::PIXEL_SIZE );
         }
         break;
       }
       case Toolkit::TextLabel::Property::ELLIPSIS:
       {
-        if( impl.mController )
-        {
-          const bool ellipsis = value.Get<bool>();
-          DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis );
+        const bool ellipsis = value.Get<bool>();
+        DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p ELLIPSIS %d\n", impl.mController.Get(), ellipsis );
 
-          impl.mController->SetTextElideEnabled( ellipsis );
-        }
+        impl.mController->SetTextElideEnabled( ellipsis );
         break;
       }
       case Toolkit::TextLabel::Property::LINE_WRAP_MODE:
       {
-        if( impl.mController )
+        Text::LineWrap::Mode lineWrapMode( static_cast< Text::LineWrap::Mode >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
+        if( GetLineWrapModeEnumeration( value, lineWrapMode ) )
         {
-          Text::LineWrap::Mode lineWrapMode( static_cast< Text::LineWrap::Mode >( -1 ) ); // Set to invalid value to ensure a valid mode does get set
-          if( GetLineWrapModeEnumeration( value, lineWrapMode ) )
-          {
-            DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p LineWrap::MODE %d\n", impl.mController.Get(), lineWrapMode );
-            impl.mController->SetLineWrapMode( lineWrapMode );
-          }
+          DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel %p LineWrap::MODE %d\n", impl.mController.Get(), lineWrapMode );
+          impl.mController->SetLineWrapMode( lineWrapMode );
         }
         break;
       }
       case Toolkit::DevelTextLabel::Property::VERTICAL_LINE_ALIGNMENT:
       {
-        if( impl.mController && impl.mController->GetTextModel() )
+        if( impl.mController->GetTextModel() )
         {
           DevelText::VerticalLineAlignment::Type alignment = static_cast<DevelText::VerticalLineAlignment::Type>( value.Get<int>() );
 
@@ -456,11 +442,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::DevelTextLabel::Property::BACKGROUND:
       {
-        const bool update = SetBackgroundProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        if( update )
-        {
-          impl.mTextUpdateNeeded = true;
-        }
+        impl.mTextUpdateNeeded = SetBackgroundProperties( impl.mController, value, Text::EffectStyle::DEFAULT ) || impl.mTextUpdateNeeded;
         break;
       }
       case Toolkit::DevelTextLabel::Property::IGNORE_SPACES_AFTER_TEXT:
@@ -473,6 +455,17 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
         impl.mController->SetMatchSystemLanguageDirection(value.Get< bool >());
         break;
       }
+      case Toolkit::DevelTextLabel::Property::TEXT_FIT:
+      {
+        ParseTextFitProperty(impl.mController, value.GetMap());
+        break;
+      }
+      case Toolkit::DevelTextLabel::Property::MIN_LINE_SIZE:
+      {
+        const float lineSize = value.Get<float>();
+        impl.mTextUpdateNeeded = impl.mController->SetDefaultLineSize( lineSize ) || impl.mTextUpdateNeeded;
+        break;
+      }
     }
 
     // Request relayout when text update is needed. It's necessary to call it
@@ -484,10 +477,6 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       impl.RequestTextRelayout();
     }
   }
-
-
-
-
 }
 
 Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index index )
@@ -499,31 +488,25 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
   if( label )
   {
     TextLabel& impl( GetImpl( label ) );
+    DALI_ASSERT_DEBUG( impl.mController && "No text contoller" );
+
     switch( index )
     {
-      case Toolkit::TextLabel::Property::RENDERING_BACKEND:
+      case Toolkit::DevelTextLabel::Property::RENDERING_BACKEND:
       {
-        DALI_LOG_WARNING("[%s] Using deprecated Property TextLabel::Property::RENDERING_BACKEND which is no longer supported and will be ignored\n", __FUNCTION__);
-
         value = impl.mRenderingBackend;
         break;
       }
       case Toolkit::TextLabel::Property::TEXT:
       {
-        if( impl.mController )
-        {
-          std::string text;
-          impl.mController->GetText( text );
-          value = text;
-        }
+        std::string text;
+        impl.mController->GetText( text );
+        value = text;
         break;
       }
       case Toolkit::TextLabel::Property::FONT_FAMILY:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultFontFamily();
-        }
+        value = impl.mController->GetDefaultFontFamily();
         break;
       }
       case Toolkit::TextLabel::Property::FONT_STYLE:
@@ -533,64 +516,41 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextLabel::Property::POINT_SIZE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE );
-        }
+        value = impl.mController->GetDefaultFontSize( Text::Controller::POINT_SIZE );
         break;
       }
       case Toolkit::TextLabel::Property::MULTI_LINE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsMultiLineEnabled();
-        }
+        value = impl.mController->IsMultiLineEnabled();
         break;
       }
       case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
       {
-        if( impl.mController )
-        {
-          const char* name = Text::GetHorizontalAlignmentString( impl.mController->GetHorizontalAlignment() );
+        const char* name = Text::GetHorizontalAlignmentString( impl.mController->GetHorizontalAlignment() );
 
-           if ( name )
-           {
-             value = std::string( name );
-           }
+        if ( name )
+        {
+          value = std::string( name );
         }
         break;
       }
       case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
       {
-        if( impl.mController )
+        const char* name = Text::GetVerticalAlignmentString( impl.mController->GetVerticalAlignment() );
+        if( name )
         {
-          const char* name = Text::GetVerticalAlignmentString( impl.mController->GetVerticalAlignment() );
-          if( name )
-          {
-            value = std::string( name );
-          }
+          value = std::string( name );
         }
         break;
       }
-      case Toolkit::TextLabel::Property::UNUSED_PROPERTY_TEXT_COLOR:
-      {
-        value = label.GetProperty( Toolkit::TextLabel::Property::TEXT_COLOR );
-        break;
-      }
       case Toolkit::TextLabel::Property::ENABLE_MARKUP:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsMarkupProcessorEnabled();
-        }
+        value = impl.mController->IsMarkupProcessorEnabled();
         break;
       }
       case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsAutoScrollEnabled();
-        }
+        value = impl.mController->IsAutoScrollEnabled();
         break;
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_STOP_MODE:
@@ -609,7 +569,6 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED:
       {
-        TextLabel& impl( GetImpl( label ) );
         if ( impl.mTextScroller )
         {
           value = impl.mTextScroller->GetSpeed();
@@ -618,31 +577,22 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT:
       {
-        if( impl.mController )
+        if ( impl.mTextScroller )
         {
-          TextLabel& impl( GetImpl( label ) );
-          if ( impl.mTextScroller )
-          {
-            value = impl.mTextScroller->GetLoopCount();
-          }
+          value = impl.mTextScroller->GetLoopCount();
         }
         break;
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_DELAY:
       {
-        if( impl.mController )
+        if ( impl.mTextScroller )
         {
-          TextLabel& impl( GetImpl( label ) );
-          if ( impl.mTextScroller )
-          {
-            value = impl.mTextScroller->GetLoopDelay();
-          }
+          value = impl.mTextScroller->GetLoopDelay();
         }
         break;
       }
       case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP:
       {
-        TextLabel& impl( GetImpl( label ) );
         if ( impl.mTextScroller )
         {
           value = impl.mTextScroller->GetGap();
@@ -651,10 +601,7 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextLabel::Property::LINE_SPACING:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultLineSpacing();
-        }
+        value = impl.mController->GetDefaultLineSpacing();
         break;
       }
       case Toolkit::TextLabel::Property::UNDERLINE:
@@ -679,51 +626,33 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextLabel::Property::PIXEL_SIZE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE );
-        }
+        value = impl.mController->GetDefaultFontSize( Text::Controller::PIXEL_SIZE );
         break;
       }
       case Toolkit::TextLabel::Property::ELLIPSIS:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->IsTextElideEnabled();
-        }
+        value = impl.mController->IsTextElideEnabled();
         break;
       }
       case Toolkit::TextLabel::Property::LINE_WRAP_MODE:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetLineWrapMode();
-        }
+        value = impl.mController->GetLineWrapMode();
         break;
       }
       case Toolkit::TextLabel::Property::LINE_COUNT:
       {
-        if( impl.mController )
-        {
-          float width = label.GetProperty( Actor::Property::SIZE_WIDTH ).Get<float>();
-          value = impl.mController->GetLineCount( width );
-        }
+        float width = label.GetProperty( Actor::Property::SIZE_WIDTH ).Get<float>();
+        value = impl.mController->GetLineCount( width );
         break;
       }
       case Toolkit::DevelTextLabel::Property::TEXT_DIRECTION:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetTextDirection();
-        }
+        value = impl.mController->GetTextDirection();
         break;
       }
       case Toolkit::DevelTextLabel::Property::VERTICAL_LINE_ALIGNMENT:
       {
-        if( impl.mController )
-        {
-          value = impl.mController->GetVerticalLineAlignment();
-        }
+        value = impl.mController->GetVerticalLineAlignment();
         break;
       }
       case Toolkit::DevelTextLabel::Property::BACKGROUND:
@@ -741,6 +670,28 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
         value = impl.mController->IsMatchSystemLanguageDirection();
         break;
       }
+      case Toolkit::DevelTextLabel::Property::TEXT_FIT:
+      {
+        const bool enabled = impl.mController->IsTextFitEnabled();
+        const float minSize = impl.mController->GetTextFitMinSize();
+        const float maxSize = impl.mController->GetTextFitMaxSize();
+        const float stepSize = impl.mController->GetTextFitStepSize();
+
+        Property::Map map;
+        map.Insert( TEXT_FIT_ENABLE_KEY, enabled );
+        map.Insert( TEXT_FIT_MIN_SIZE_KEY, minSize );
+        map.Insert( TEXT_FIT_MAX_SIZE_KEY, maxSize );
+        map.Insert( TEXT_FIT_STEP_SIZE_KEY, stepSize );
+        map.Insert( TEXT_FIT_FONT_SIZE_TYPE_KEY, "pointSize" );
+
+        value = map;
+        break;
+      }
+      case Toolkit::DevelTextLabel::Property::MIN_LINE_SIZE:
+      {
+        value = impl.mController->GetDefaultLineSize();
+        break;
+      }
     }
   }
 
@@ -760,10 +711,9 @@ void TextLabel::OnInitialize()
   TextVisual::SetAnimatableTextColorProperty( mVisual, Toolkit::TextLabel::Property::TEXT_COLOR );
 
   mController = TextVisual::GetController(mVisual);
-  if( mController )
-  {
-    mController->SetControlInterface(this);
-  }
+  DALI_ASSERT_DEBUG( mController && "Invalid Text Controller")
+
+  mController->SetControlInterface(this);
 
   // Use height-for-width negotiation by default
   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
@@ -833,7 +783,7 @@ float TextLabel::GetHeightForWidth( float width )
   return mController->GetHeightForWidth( width ) + padding.top + padding.bottom;
 }
 
-void TextLabel::OnPropertySet( Property::Index index, Property::Value propertyValue )
+void TextLabel::OnPropertySet( Property::Index index, const Property::Value& propertyValue )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::OnPropertySet index[%d]\n", index );
 
@@ -866,9 +816,22 @@ void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container )
 
   Vector2 contentSize( size.x - ( padding.start + padding.end ), size.y - ( padding.top + padding.bottom ) );
 
-  // Support Right-To-Left
-  Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>( Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
+  if( mController->IsTextFitEnabled() )
+  {
+    mController->FitPointSizeforLayout( contentSize );
+    mController->SetTextFitContentSize( contentSize );
+  }
 
+  // Support Right-To-Left
+  Dali::LayoutDirection::Type layoutDirection;
+  if( mController->IsMatchSystemLanguageDirection() )
+  {
+    layoutDirection = static_cast<Dali::LayoutDirection::Type>( DevelWindow::Get( Self() ).GetRootLayer().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
+  }
+  else
+  {
+    layoutDirection = static_cast<Dali::LayoutDirection::Type>( Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
+  }
   const Text::Controller::UpdateTextType updateTextType = mController->Relayout( contentSize, layoutDirection );
 
   if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) )
@@ -925,7 +888,7 @@ void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container )
 void TextLabel::RequestTextRelayout()
 {
   RelayoutRequest();
-  Toolkit::DevelControl::RequestLayout( *this );
+  // Signal that a Relayout may be needed
 }
 
 void TextLabel::SetUpAutoScrolling()
@@ -955,6 +918,7 @@ void TextLabel::SetUpAutoScrolling()
   const int maxTextureSize = Dali::GetMaxTextureSize();
 
   //if the texture size width exceed maxTextureSize, modify the visual model size and enabled the ellipsis
+  bool actualellipsis = mController->IsTextElideEnabled();
   if( verifiedSize.width > maxTextureSize )
   {
     verifiedSize.width = maxTextureSize;
@@ -987,6 +951,7 @@ void TextLabel::SetUpAutoScrolling()
   // Set parameters for scrolling
   Renderer renderer = static_cast<Internal::Visual::Base&>( GetImplementation( mVisual ) ).GetRenderer();
   mTextScroller->SetParameters( Self(), renderer, textureSet, controlSize, verifiedSize, wrapGap, direction, mController->GetHorizontalAlignment(), mController->GetVerticalAlignment() );
+  mController->SetTextElideEnabled( actualellipsis );
 }
 
 void TextLabel::ScrollingFinished()
@@ -994,7 +959,6 @@ void TextLabel::ScrollingFinished()
   // Pure Virtual from TextScroller Interface
   DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::ScrollingFinished\n");
   mController->SetAutoScrollEnabled( false );
-  mController->SetTextElideEnabled( true );
   RequestTextRelayout();
 }