Merge "Added code for stylable transitions" into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 21 Oct 2016 10:34:10 +0000 (03:34 -0700)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Fri, 21 Oct 2016 10:34:10 +0000 (03:34 -0700)
116 files changed:
automated-tests/src/dali-toolkit-internal/CMakeLists.txt
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextLabel.cpp
automated-tests/src/dali-toolkit/utc-Dali-Visual.cpp
automated-tests/src/dali-toolkit/utc-Dali-VisualFactory.cpp
dali-toolkit/dali-toolkit.h
dali-toolkit/devel-api/visual-factory/visual-base.cpp
dali-toolkit/devel-api/visual-factory/visual-base.h
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.h
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.h
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.h
dali-toolkit/internal/file.list
dali-toolkit/internal/text/markup-processor-helper-functions.cpp
dali-toolkit/internal/text/markup-processor-helper-functions.h
dali-toolkit/internal/text/property-string-parser.cpp
dali-toolkit/internal/text/property-string-parser.h
dali-toolkit/internal/text/text-control-interface.h
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/text/text-editable-control-interface.h [new file with mode: 0644]
dali-toolkit/internal/text/text-effects-style.cpp
dali-toolkit/internal/text/text-effects-style.h
dali-toolkit/internal/text/text-font-style.cpp
dali-toolkit/internal/text/text-font-style.h
dali-toolkit/internal/text/text-scroller-data.cpp [moved from dali-toolkit/internal/text/text-control-interface.cpp with 65% similarity]
dali-toolkit/internal/text/text-scroller-data.h [new file with mode: 0644]
dali-toolkit/internal/text/text-scroller.cpp
dali-toolkit/internal/text/text-scroller.h
dali-toolkit/internal/visuals/border/border-visual.cpp
dali-toolkit/internal/visuals/border/border-visual.h
dali-toolkit/internal/visuals/color/color-visual.cpp
dali-toolkit/internal/visuals/color/color-visual.h
dali-toolkit/internal/visuals/gradient/gradient-visual.cpp
dali-toolkit/internal/visuals/gradient/gradient-visual.h
dali-toolkit/internal/visuals/image/batch-image-visual.cpp
dali-toolkit/internal/visuals/image/batch-image-visual.h
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.h
dali-toolkit/internal/visuals/mesh/mesh-visual.cpp
dali-toolkit/internal/visuals/mesh/mesh-visual.h
dali-toolkit/internal/visuals/npatch/npatch-visual.cpp
dali-toolkit/internal/visuals/npatch/npatch-visual.h
dali-toolkit/internal/visuals/primitive/primitive-visual.cpp
dali-toolkit/internal/visuals/primitive/primitive-visual.h
dali-toolkit/internal/visuals/svg/svg-visual.cpp
dali-toolkit/internal/visuals/svg/svg-visual.h
dali-toolkit/internal/visuals/text/text-visual.cpp [new file with mode: 0644]
dali-toolkit/internal/visuals/text/text-visual.h [new file with mode: 0644]
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/internal/visuals/visual-base-impl.h
dali-toolkit/internal/visuals/visual-factory-impl.cpp
dali-toolkit/internal/visuals/visual-factory-impl.h
dali-toolkit/internal/visuals/wireframe/wireframe-visual.cpp
dali-toolkit/internal/visuals/wireframe/wireframe-visual.h
dali-toolkit/public-api/controls/text-controls/text-label.h
dali-toolkit/public-api/file.list
dali-toolkit/public-api/visuals/text-visual-properties.h [new file with mode: 0644]
dali-toolkit/public-api/visuals/visual-properties.h
plugins/dali-swig/examples/firstscreen/App.cs [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/Constants.cs [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/EdenData.cs [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/EdenEffect.cs [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/IEdenEffect.cs [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/Program.cs [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/ScrollContainer.cs [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/0-normal.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/1-normal.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/2-normal.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/background.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/eden_launcher_shadow.9.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/eden_launcher_shadow_n.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/edeneffect/halo.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/edeneffect/horizontalFrame.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/edeneffect/verticalFrame.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/focus_grid.9.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/highlight_spot.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/highlight_stroke.9.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/menu/0.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/menu/1.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/menu/2.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/menu/3.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/menu/4.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/menu/5.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/menu/6.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/0.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/1.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/10.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/11.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/12.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/13.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/2.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/3.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/4.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/5.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/6.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/7.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/8.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster0/9.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster1/0.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster1/1.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster1/2.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster1/3.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster1/4.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/poster1/5.jpg [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/star-dim.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/star-highlight.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/thumbnail_shadow.9.png [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/images/white-pixel.png [new file with mode: 0644]

index 05380dd..4a9a003 100644 (file)
@@ -20,6 +20,7 @@ SET(TC_SOURCES
  utc-Dali-Text-Controller.cpp
  utc-Dali-VisualFactoryResolveUrl.cpp
  utc-Dali-Visuals.cpp
+ utc-Dali-Text-Markup.cpp
 )
 
 # Append list of test harness files (Won't get parsed for test cases)
index 7480435..f2e761f 100644 (file)
 
 #include <stdlib.h>
 #include <limits>
+#include <unistd.h>
 
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali-toolkit/internal/text/text-controller.h>
+#include <dali-toolkit/internal/text/text-control-interface.h>
+#include <dali-toolkit/internal/text/text-editable-control-interface.h>
+#include <dali-toolkit/internal/text/text-scroller-data.h>
 
 using namespace Dali;
 using namespace Toolkit;
@@ -40,7 +44,9 @@ const char* const OPTION_CLIPBOARD("optionClipboard");      // "Clipboard" popup
 
 const Size CONTROL_SIZE( 300.f, 60.f );
 
-class ControlImpl : public ControlInterface
+const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
+
+class ControlImpl : public ControlInterface, public Text::EditableControlInterface
 {
 public:
   ControlImpl()
@@ -80,8 +86,7 @@ int UtcDaliTextController(void)
   ToolkitTestApplication application;
 
   // Creates a text controller.
-  ControlImpl controlImpl;
-  ControllerPtr controller = Controller::New( controlImpl );
+  ControllerPtr controller = Controller::New();
 
   DALI_TEST_CHECK( controller );
 
@@ -95,8 +100,7 @@ int UtcDaliTextControllerEnableCursorBlinking(void)
   ToolkitTestApplication application;
 
   // Creates a text controller.
-  ControlImpl controlImpl;
-  ControllerPtr controller = Controller::New( controlImpl );
+  ControllerPtr controller = Controller::New();
 
   DALI_TEST_CHECK( controller );
 
@@ -131,8 +135,7 @@ int UtcDaliTextControllerImfEvent(void)
   ToolkitTestApplication application;
 
   // Creates a text controller.
-  ControlImpl controlImpl;
-  ControllerPtr controller = Controller::New( controlImpl );
+  ControllerPtr controller = Controller::New();
 
   std::string text;
   ImfManager::ImfEventData imfEvent;
@@ -214,8 +217,7 @@ int UtcDaliTextControllerTextPopupButtonTouched(void)
   ToolkitTestApplication application;
 
   // Creates a text controller.
-  ControlImpl controlImpl;
-  ControllerPtr controller = Controller::New( controlImpl );
+  ControllerPtr controller = Controller::New();
 
   DALI_TEST_CHECK( controller );
 
@@ -330,3 +332,193 @@ int UtcDaliTextControllerTextPopupButtonTouched(void)
   tet_result(TET_PASS);
   END_TEST;
 }
+
+int UtcDaliTextControllerGetInputShadowProperty(void)
+{
+  tet_infoline(" UtcDaliTextControllerGetInputShadowProperty");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  DALI_TEST_CHECK( controller );
+
+  const std::string& shadowProperties = controller->GetInputShadowProperties();
+
+  DALI_TEST_CHECK( shadowProperties.empty() );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextControllerGetInputUnderlineProperty(void)
+{
+  tet_infoline(" UtcDaliTextControllerGetInputUnderlineProperty");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  DALI_TEST_CHECK( controller );
+
+  const std::string& underlineProperties = controller->GetInputUnderlineProperties();
+
+  DALI_TEST_CHECK( underlineProperties.empty() );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextControllerSetGetAutoScrollEnabled(void)
+{
+  tet_infoline(" UtcDaliTextControllerSetGetAutoScrollEnabled");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  DALI_TEST_CHECK( controller );
+
+  DALI_TEST_CHECK( !controller->IsAutoScrollEnabled() );
+
+  // The auto scrolling shouldn't be enabled if the multi-line is enabled.
+
+  // Enable multi-line.
+  controller->SetMultiLineEnabled( true );
+
+  // Enable text scrolling.
+  controller->SetAutoScrollEnabled( true );
+
+  DALI_TEST_CHECK( !controller->IsAutoScrollEnabled() );
+
+  // Disable multi-line.
+  controller->SetMultiLineEnabled( false );
+
+  // Enable text scrolling.
+  controller->SetAutoScrollEnabled( true );
+
+  // Should be ebabled now.
+  DALI_TEST_CHECK( controller->IsAutoScrollEnabled() );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextControllerSetGetAutoScrollSpeed(void)
+{
+  tet_infoline(" UtcDaliTextControllerSetGetAutoScrollSpeed");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  DALI_TEST_CHECK( controller );
+
+  // Check the default value.
+  DALI_TEST_EQUALS( 0, controller->GetAutoScrollSpeed(), TEST_LOCATION );
+
+  // Set the auto scroll speed.
+  controller->SetAutoscrollSpeed( 10 );
+
+  DALI_TEST_EQUALS( 10, controller->GetAutoScrollSpeed(), TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextControllerSetGetAutoScrollLoopCount(void)
+{
+  tet_infoline(" UtcDaliTextControllerSetGetAutoScrollLoopCount");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  DALI_TEST_CHECK( controller );
+
+  // Check the default value.
+  DALI_TEST_EQUALS( 0, controller->GetAutoScrollLoopCount(), TEST_LOCATION );
+
+  // Set the auto scroll loop count.
+  controller->SetAutoScrollLoopCount( 5 );
+
+  DALI_TEST_EQUALS( 5, controller->GetAutoScrollLoopCount(), TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextControllerSetGetAutoScrollWrapGap(void)
+{
+  tet_infoline(" UtcDaliTextControllerSetGetAutoScrollWrapGap");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  DALI_TEST_CHECK( controller );
+
+  // Check the default value.
+  DALI_TEST_EQUALS( 0.f, controller->GetAutoScrollWrapGap(), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  // Set the auto scroll loop count.
+  controller->SetAutoScrollWrapGap( 25.f );
+
+  DALI_TEST_EQUALS( 25.f, controller->GetAutoScrollWrapGap(), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextControllerGetAutoScrollData(void)
+{
+  tet_infoline(" UtcDaliTextControllerGetAutoScrollData");
+  ToolkitTestApplication application;
+
+  // Load some fonts to get the same metrics on different platforms.
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+  fontClient.SetDpi( 96u, 96u );
+
+  char* pathNamePtr = get_current_dir_name();
+  const std::string pathName( pathNamePtr );
+  free( pathNamePtr );
+
+  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  DALI_TEST_CHECK( controller );
+
+  DALI_TEST_CHECK( NULL == controller->GetAutoScrollData() );
+
+  // Set and check some values.
+  controller->SetAutoscrollSpeed( 10 );
+  controller->SetAutoScrollLoopCount( 5 );
+  controller->SetAutoScrollWrapGap( 25.f );
+
+  const ScrollerData* scrollerData = controller->GetAutoScrollData();
+  DALI_TEST_CHECK( NULL != controller->GetAutoScrollData() );
+
+  DALI_TEST_EQUALS( Size::ZERO, scrollerData->mControlSize, TEST_LOCATION );
+  DALI_TEST_EQUALS( Size::ZERO, scrollerData->mOffscreenSize, TEST_LOCATION );
+  DALI_TEST_EQUALS( 10, scrollerData->mScrollSpeed, TEST_LOCATION );
+  DALI_TEST_EQUALS( 5, scrollerData->mLoopCount, TEST_LOCATION );
+  DALI_TEST_EQUALS( 25.f, scrollerData->mWrapGap, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+  DALI_TEST_EQUALS( 0.f, scrollerData->mAlignmentOffset, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+  DALI_TEST_CHECK( !scrollerData->mAutoScrollDirectionRTL );
+
+  // Set some text and layout.
+  controller->SetMarkupProcessorEnabled( true );
+  controller->SetHorizontalAlignment( LayoutEngine::HORIZONTAL_ALIGN_END );
+  controller->SetText( "<font family='TizenSans' size='12'>Hello world</font>" );
+  controller->Relayout( Size( 100.f, 20.f ) );
+
+  scrollerData = controller->GetAutoScrollData();
+  DALI_TEST_EQUALS( Size( 100.f, 20.f ), scrollerData->mControlSize, TEST_LOCATION );
+  DALI_TEST_EQUALS( Size( 80.f, 20.f ), scrollerData->mOffscreenSize, TEST_LOCATION );
+  DALI_TEST_EQUALS( 20.f, scrollerData->mAlignmentOffset, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp
new file mode 100644 (file)
index 0000000..23f7e51
--- /dev/null
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2016 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <iostream>
+
+#include <stdlib.h>
+#include <limits>
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <toolkit-text-model.h>
+#include <dali-toolkit/internal/text/markup-processor.h>
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
+#include <dali-toolkit/internal/text/color-run.h>
+#include <dali-toolkit/internal/text/font-description-run.h>
+#include <dali-toolkit/internal/text/text-definitions.h>
+#include <dali-toolkit/internal/text/text-io.h>
+
+using namespace Dali;
+using namespace Toolkit;
+using namespace Text;
+
+namespace
+{
+  ///////////////////////////////////////////////////////////
+
+  struct TokenComparisonData
+  {
+    std::string description;
+    std::string string1; ///< must be in lower case!!!!
+    std::string string2;
+    bool expectedResult;
+  };
+
+  bool TokenComparisonTest( const TokenComparisonData& data )
+  {
+    std::cout << "  testing " << data.description << std::endl;
+
+    const bool result = TokenComparison( data.string1,
+                                         data.string2.c_str(),
+                                         data.string2.size() );
+
+    if( result != data.expectedResult )
+    {
+      std::cout << "  different conparison result : " << result << ", expected : " << data.expectedResult << std::endl;
+      std::cout << "  comparing : [" << data.string1 << "] and [" << data.string2 << "]" << std::endl;
+
+      return false;
+    }
+
+    return true;
+  }
+
+  ///////////////////////////////////////////////////////////
+
+  struct ColorStringToVector4Data
+  {
+    std::string description;
+    std::string colorStr;
+    Vector4 expectedColor;
+  };
+
+  bool ColorStringToVector4Test( const ColorStringToVector4Data& data )
+  {
+    std::cout << "  testing " << data.description << std::endl;
+
+    Vector4 color;
+    ColorStringToVector4( data.colorStr.c_str(), data.colorStr.size(), color );
+
+    if( color != data.expectedColor )
+    {
+      std::cout << "  different color : " << color << ", expected : " << data.expectedColor << std::endl;
+      return false;
+    }
+
+    return true;
+  }
+
+  ///////////////////////////////////////////////////////////
+
+  struct Vector4ToColorStringData
+  {
+    std::string description;
+    Vector4 color;
+    std::string expectedColorStr;
+  };
+
+  bool Vector4ToColorStringTest( const Vector4ToColorStringData& data )
+  {
+    std::cout << "  testing " << data.description << std::endl;
+
+    std::string colorStr;
+    Vector4ToColorString( data.color, colorStr );
+
+    if( colorStr != data.expectedColorStr )
+    {
+      std::cout << "  different color : [" << colorStr << "], expected : [" << data.expectedColorStr << "]" << std::endl;
+      return false;
+    }
+
+    return true;
+  }
+
+  ///////////////////////////////////////////////////////////
+
+  struct StringToVector2Data
+  {
+    std::string description;
+    std::string vector2Str;
+    Vector2 expectedVector2;
+  };
+
+  bool StringToVector2Test( const StringToVector2Data& data )
+  {
+    std::cout << "  testing " << data.description << std::endl;
+
+    Vector2 vector2;
+    StringToVector2( data.vector2Str.c_str(), data.vector2Str.size(), vector2 );
+
+    if( vector2 != data.expectedVector2 )
+    {
+      std::cout << "  different vector2 : " << vector2 << ", expected : " << data.expectedVector2 << std::endl;
+      return false;
+    }
+
+    return true;
+  }
+
+  ///////////////////////////////////////////////////////////
+
+
+  struct Vector2ToStringData
+  {
+    std::string description;
+    Vector2 vector2;
+    std::string expectedVector2Str;
+  };
+
+  bool Vector2ToStringTest( const Vector2ToStringData& data )
+  {
+    std::cout << "  testing " << data.description << std::endl;
+
+    std::string vector2Str;
+    Vector2ToString( data.vector2, vector2Str );
+
+    if( vector2Str != data.expectedVector2Str )
+    {
+      std::cout << "  different vector2 : [" << vector2Str << "], expected : [" << data.expectedVector2Str << "]" << std::endl;
+      return false;
+    }
+
+    return true;
+  }
+
+} // namespace
+
+int UtcDaliTextTokenComparison(void)
+{
+  tet_infoline(" UtcDaliTextTokenComparison");
+
+  const TokenComparisonData data[] =
+  {
+    {
+      "void texts",
+      "",
+      "",
+      true
+    },
+    {
+      "different size text",
+      "hello",
+      "world!",
+      false
+    },
+    {
+      "different texts",
+      "hello",
+      "world",
+      false
+    },
+    {
+      "same texts",
+      "world",
+      "wOrLD",
+      true
+    },
+    {
+      "some punctuation characters, numbers, ...",
+      "hello0123456789.![?]",
+      "Hello0123456789.![?]",
+      true
+    }
+
+  };
+  const unsigned int numberOfTests = 5u;
+
+  for( unsigned int index = 0u; index < numberOfTests; ++index )
+  {
+    ToolkitTestApplication application;
+    if( !TokenComparisonTest( data[index] ) )
+    {
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextColorStringToVector4(void)
+{
+  tet_infoline(" UtcDaliTextColorStringToVector4");
+
+  const ColorStringToVector4Data data[] =
+  {
+    {
+      "black string",
+      "bLack",
+      Color::BLACK
+    },
+    {
+      "white string",
+      "White",
+      Color::WHITE
+    },
+    {
+      "red string",
+      "reD",
+      Color::RED
+    },
+    {
+      "green string",
+      "green",
+      Color::GREEN
+    },
+    {
+      "blue string",
+      "blue",
+      Color::BLUE
+    },
+    {
+      "yellow string",
+      "yeLloW",
+      Color::YELLOW
+    },
+    {
+      "magenta string",
+      "MagEnta",
+      Color::MAGENTA
+    },
+    {
+      "cyan string",
+      "CyaN",
+      Color::CYAN
+    },
+    {
+      "transparent string",
+      "transparent",
+      Color::TRANSPARENT
+    },
+    {
+      "3 component web color",
+      "#F00",
+      Color::RED
+    },
+    {
+      "6 component web color",
+      "#fF0000",
+      Color::RED
+    },
+    {
+      "hex color red (ARGB)",
+      "0xffff0000",
+      Color::RED
+    },
+    {
+      "hex color green (ARGB)",
+      "0xFf00FF00",
+      Color::GREEN
+    },
+    {
+      "undefined color",
+      "undefined",
+      Vector4::ZERO
+    },
+  };
+  const unsigned int numberOfTests = 14u;
+
+  for( unsigned int index = 0u; index < numberOfTests; ++index )
+  {
+    ToolkitTestApplication application;
+    if( !ColorStringToVector4Test( data[index] ) )
+    {
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextVector4ToColorString(void)
+{
+  tet_infoline(" UtcDaliTextVector4ToColorString");
+
+  const Vector4ToColorStringData data[] =
+  {
+    {
+      "black color",
+      Color::BLACK,
+      "black"
+    },
+    {
+      "white string",
+      Color::WHITE,
+      "white"
+    },
+    {
+      "red string",
+      Color::RED,
+      "red"
+    },
+    {
+      "green string",
+      Color::GREEN,
+      "green"
+    },
+    {
+      "blue string",
+      Color::BLUE,
+      "blue"
+    },
+    {
+      "yellow string",
+      Color::YELLOW,
+      "yellow"
+    },
+    {
+      "magenta string",
+      Color::MAGENTA,
+      "magenta",
+    },
+    {
+      "cyan string",
+      Color::CYAN,
+      "cyan"
+    },
+    {
+      "transparent string",
+      Color::TRANSPARENT,
+      "transparent"
+    },
+    {
+      "hex color",
+      Vector4( 0.4f, 0.5f, 0.6f, 1.f ),
+      "0xff667f99"
+    },
+  };
+  const unsigned int numberOfTests = 10u;
+
+  for( unsigned int index = 0u; index < numberOfTests; ++index )
+  {
+    ToolkitTestApplication application;
+    if( !Vector4ToColorStringTest( data[index] ) )
+    {
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextStringToVector2(void)
+{
+  tet_infoline(" UtcDaliTextStringToVector2");
+  const StringToVector2Data data[] =
+  {
+    {
+      "void text",
+      "",
+      Vector2::ZERO
+    },
+    {
+      "zero zero",
+      "0 0",
+      Vector2::ZERO
+    },
+    {
+      "five four",
+      "5 4",
+      Vector2(5.f, 4.f)
+    }
+  };
+  const unsigned int numberOfTests = 3u;
+
+  for( unsigned int index = 0u; index < numberOfTests; ++index )
+  {
+    ToolkitTestApplication application;
+    if( !StringToVector2Test( data[index] ) )
+    {
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextVector2ToString(void)
+{
+  tet_infoline(" UtcDaliTextVector2ToString");
+  const Vector2ToStringData data[] =
+  {
+    {
+      "zero zero",
+      Vector2::ZERO,
+      "0 0",
+    },
+    {
+      "five four",
+      Vector2(5.f, 4.f),
+      "5 4",
+    }
+  };
+  const unsigned int numberOfTests = 2u;
+
+  for( unsigned int index = 0u; index < numberOfTests; ++index )
+  {
+    ToolkitTestApplication application;
+    if( !Vector2ToStringTest( data[index] ) )
+    {
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
index 83744f3..b6b638c 100644 (file)
@@ -441,16 +441,16 @@ int UtcDaliTextEditorSetPropertyP(void)
   DALI_TEST_EQUALS( editor.GetProperty<float>( TextEditor::Property::INPUT_LINE_SPACING ), 20.0f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
 
   // Check the underline property
-  editor.SetProperty( TextEditor::Property::UNDERLINE, "Underline properties" );
-  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::UNDERLINE ), std::string("Underline properties"), TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::UNDERLINE, "{\"enable\":\"true\",\"color\":\"red\",\"height\":\"1\"}" );
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::UNDERLINE ), std::string("{\"enable\":\"true\",\"color\":\"red\",\"height\":\"1\"}"), TEST_LOCATION );
 
   // Check the input underline property
   editor.SetProperty( TextEditor::Property::INPUT_UNDERLINE, "Underline input properties" );
   DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::INPUT_UNDERLINE ), std::string("Underline input properties"), TEST_LOCATION );
 
   // Check the shadow property
-  editor.SetProperty( TextEditor::Property::SHADOW, "Shadow properties" );
-  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::SHADOW ), std::string("Shadow properties"), TEST_LOCATION );
+  editor.SetProperty( TextEditor::Property::SHADOW, "{\"color\":\"green\",\"offset\":\"2 2\"}" );
+  DALI_TEST_EQUALS( editor.GetProperty<std::string>( TextEditor::Property::SHADOW ), std::string("{\"color\":\"green\",\"offset\":\"2 2\"}"), TEST_LOCATION );
 
   // Check the input shadow property
   editor.SetProperty( TextEditor::Property::INPUT_SHADOW, "Shadow input properties" );
index 0335e4e..80ed1d7 100644 (file)
@@ -612,16 +612,16 @@ int UtcDaliTextFieldSetPropertyP(void)
   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::INPUT_FONT_STYLE ), std::string(""), TEST_LOCATION );
 
   // Check the underline property
-  field.SetProperty( TextField::Property::UNDERLINE, "Underline properties" );
-  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::UNDERLINE ), std::string("Underline properties"), TEST_LOCATION );
+  field.SetProperty( TextField::Property::UNDERLINE, "{\"enable\":\"true\",\"color\":\"red\",\"height\":\"1\"}" );
+  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::UNDERLINE ), std::string("{\"enable\":\"true\",\"color\":\"red\",\"height\":\"1\"}"), TEST_LOCATION );
 
   // Check the input underline property
   field.SetProperty( TextField::Property::INPUT_UNDERLINE, "Underline input properties" );
   DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::INPUT_UNDERLINE ), std::string("Underline input properties"), TEST_LOCATION );
 
   // Check the shadow property
-  field.SetProperty( TextField::Property::SHADOW, "Shadow properties" );
-  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::SHADOW ), std::string("Shadow properties"), TEST_LOCATION );
+  field.SetProperty( TextField::Property::SHADOW, "{\"color\":\"green\",\"offset\":\"2 2\"}" );
+  DALI_TEST_EQUALS( field.GetProperty<std::string>( TextField::Property::SHADOW ), std::string("{\"color\":\"green\",\"offset\":\"2 2\"}"), TEST_LOCATION );
 
   // Check the input shadow property
   field.SetProperty( TextField::Property::INPUT_SHADOW, "Shadow input properties" );
index 5f9a710..0f0072e 100644 (file)
@@ -222,6 +222,8 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   // The underline color is changed as well.
   DALI_TEST_EQUALS( label.GetProperty<Vector4>( TextLabel::Property::UNDERLINE_COLOR ), Color::BLUE, TEST_LOCATION );
 
+  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::UNDERLINE ), std::string("{\"enable\":\"false\",\"color\":\"blue\",\"height\":\"0\"}"), TEST_LOCATION );
+
   // Check that shadow parameters can be correctly set
   label.SetProperty( TextLabel::Property::SHADOW_OFFSET, Vector2( 3.0f, 3.0f ) );
   DALI_TEST_EQUALS( label.GetProperty<Vector2>( TextLabel::Property::SHADOW_OFFSET ), Vector2( 3.0f, 3.0f ), TEST_LOCATION );
@@ -266,12 +268,18 @@ int UtcDaliToolkitTextLabelSetPropertyP(void)
   DALI_TEST_EQUALS( label.GetProperty<float>( TextLabel::Property::LINE_SPACING ), 10.0f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
 
   // Check the underline property
-  label.SetProperty( TextLabel::Property::UNDERLINE, "Underline properties" );
-  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::UNDERLINE ), std::string("Underline properties"), TEST_LOCATION );
+  label.SetProperty( TextLabel::Property::UNDERLINE, "{\"enable\":\"true\",\"color\":\"red\",\"height\":\"1\"}" );
+  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::UNDERLINE ), std::string("{\"enable\":\"true\",\"color\":\"red\",\"height\":\"1\"}"), TEST_LOCATION );
+
+  label.SetProperty( TextLabel::Property::UNDERLINE, "" );
+  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::UNDERLINE ), std::string("{\"enable\":\"false\",\"color\":\"red\",\"height\":\"1\"}"), TEST_LOCATION );
 
   // Check the shadow property
-  label.SetProperty( TextLabel::Property::SHADOW, "Shadow properties" );
-  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::SHADOW ), std::string("Shadow properties"), TEST_LOCATION );
+  label.SetProperty( TextLabel::Property::SHADOW, "{\"color\":\"green\",\"offset\":\"2 2\"}" );
+  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::SHADOW ), std::string("{\"color\":\"green\",\"offset\":\"2 2\"}"), TEST_LOCATION );
+
+  label.SetProperty( TextLabel::Property::SHADOW, "" );
+  DALI_TEST_EQUALS( label.GetProperty<std::string>( TextLabel::Property::SHADOW ), std::string("{\"color\":\"green\",\"offset\":\"0 0\"}"), TEST_LOCATION );
 
   // Check the emboss property
   label.SetProperty( TextLabel::Property::EMBOSS, "Emboss properties" );
@@ -395,14 +403,14 @@ int UtcDaliToolkitTextlabelScrollingP(void)
   Stage::GetCurrent().Add( label );
   // Turn on all the effects
   label.SetProperty( TextLabel::Property::MULTI_LINE, false );
-  label.SetProperty(  TextLabel::Property::AUTO_SCROLL_GAP, 50.0f );
-  label.SetProperty(  TextLabel::Property::AUTO_SCROLL_LOOP_COUNT, 3 );
-  label.SetProperty(  TextLabel::Property::AUTO_SCROLL_SPEED, 80.0f);
+  label.SetProperty( TextLabel::Property::AUTO_SCROLL_GAP, 50.0f );
+  label.SetProperty( TextLabel::Property::AUTO_SCROLL_LOOP_COUNT, 3 );
+  label.SetProperty( TextLabel::Property::AUTO_SCROLL_SPEED, 80.0f );
 
   try
   {
     // Render some text with the shared atlas backend
-    label.SetProperty(  TextLabel::Property::ENABLE_AUTO_SCROLL, true );
+    label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, true );
     application.SendNotification();
     application.Render();
   }
@@ -414,6 +422,37 @@ int UtcDaliToolkitTextlabelScrollingP(void)
   END_TEST;
 }
 
+int UtcDaliToolkitTextlabelScrollingN(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliToolkitTextlabelScrollingN");
+
+  TextLabel label = TextLabel::New("Some text to scroll");
+  DALI_TEST_CHECK( label );
+
+  Stage::GetCurrent().Add( label );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  // The text scrolling works only on single line text.
+  label.SetProperty( TextLabel::Property::MULTI_LINE, true );
+
+  // Turn on all the effects.
+  label.SetProperty( TextLabel::Property::AUTO_SCROLL_GAP, 50.0f );
+  label.SetProperty( TextLabel::Property::AUTO_SCROLL_LOOP_COUNT, 3 );
+  label.SetProperty( TextLabel::Property::AUTO_SCROLL_SPEED, 80.0f );
+
+  // Enable the auto scrolling effect.
+  label.SetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL, true );
+
+  // The auto scrolling shouldn't be enabled.
+  const bool enabled = label.GetProperty( TextLabel::Property::ENABLE_AUTO_SCROLL ).Get<bool>();
+  DALI_TEST_CHECK( !enabled );
+
+  END_TEST;
+}
+
 int UtcDaliToolkitTextlabelEllipsis(void)
 {
   ToolkitTestApplication application;
index dc0723d..35c224e 100644 (file)
@@ -16,6 +16,8 @@
 
 #include <iostream>
 #include <stdlib.h>
+#include <unistd.h>
+
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali/public-api/rendering/renderer.h>
 #include <dali/public-api/rendering/texture-set.h>
@@ -35,6 +37,8 @@ const char* TEST_SVG_FILE_NAME = TEST_RESOURCE_DIR "/svg1.svg";
 const char* TEST_OBJ_FILE_NAME = TEST_RESOURCE_DIR "/Cube.obj";
 const char* TEST_MTL_FILE_NAME = TEST_RESOURCE_DIR "/ToyRobot-Metal.mtl";
 const char* TEST_RESOURCE_LOCATION = TEST_RESOURCE_DIR "/";
+
+const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
 }
 
 void dali_visual_startup(void)
@@ -208,6 +212,12 @@ int UtcDaliVisualSize(void)
   //  </svg>
   DALI_TEST_EQUALS( naturalSize, Vector2(100.f, 100.f), TEST_LOCATION );
 
+  // svg visual with a size
+  Visual::Base svgVisual2 = factory.CreateVisual( TEST_SVG_FILE_NAME, ImageDimensions(200, 200) );
+  DALI_TEST_EQUALS( svgVisual2.GetSize(), Vector2( 200.f, 200.f ), TEST_LOCATION );
+  svgVisual2.GetNaturalSize(naturalSize);
+  DALI_TEST_EQUALS( naturalSize, Vector2(100.f, 100.f), TEST_LOCATION ); // Natural size should still be 100, 100
+
   // Batch Image visual
   propertyMap.Clear();
   propertyMap.Insert( Visual::Property::TYPE, Visual::IMAGE );
@@ -219,6 +229,31 @@ int UtcDaliVisualSize(void)
   batchImageVisual.GetNaturalSize( naturalSize );
   DALI_TEST_EQUALS( naturalSize, Vector2( 80.0f, 160.0f ), TEST_LOCATION );
 
+  // Text visual.
+
+  // Load some fonts to get the same metrics on different platforms.
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+  fontClient.SetDpi( 96u, 96u );
+
+  char* pathNamePtr = get_current_dir_name();
+  const std::string pathName( pathNamePtr );
+  free( pathNamePtr );
+
+  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
+
+  propertyMap.Clear();
+  propertyMap.Insert( Visual::Property::TYPE, Visual::TEXT );
+  propertyMap.Insert( TextVisual::Property::ENABLE_MARKUP, true );
+  propertyMap.Insert( TextVisual::Property::TEXT, "<font family='TizenSans' size='12'>Hello world</font>" );
+  propertyMap.Insert( TextVisual::Property::MULTI_LINE, true );
+
+  Visual::Base textVisual = factory.CreateVisual( propertyMap );
+  textVisual.GetNaturalSize( naturalSize );
+  DALI_TEST_EQUALS( naturalSize, Size( 80.f, 20.f ), TEST_LOCATION );
+
+  const float height = textVisual.GetHeightForWidth( 40.f );
+  DALI_TEST_EQUALS( height, 40.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
   END_TEST;
 }
 
@@ -912,6 +947,95 @@ int UtcDaliVisualGetPropertyMapBatchImageVisual(void)
   END_TEST;
 }
 
+//Text shape visual
+int UtcDaliVisualGetPropertyMap10(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualGetPropertyMap10: TextVisual" );
+
+  //Request PrimitiveVisual using a property map.
+  VisualFactory factory = VisualFactory::Get();
+
+  Property::Map propertyMap;
+  propertyMap.Insert( Visual::Property::TYPE, Visual::TEXT );
+  propertyMap.Insert( "renderingBackend", static_cast<int>( Toolkit::Text::DEFAULT_RENDERING_BACKEND ) );
+  propertyMap.Insert( "text", "Hello world" );
+  propertyMap.Insert( "fontFamily", "TizenSans" );
+  propertyMap.Insert( "fontStyle", "{\"weight\":\"bold\"}" );
+  propertyMap.Insert( "pointSize", 12.f );
+  propertyMap.Insert( "multiLine", true );
+  propertyMap.Insert( "horizontalAlignment", "CENTER" );
+  propertyMap.Insert( "verticalAlignment", "CENTER" );
+  propertyMap.Insert( "textColor", Color::RED );
+  propertyMap.Insert( "enableMarkup", false );
+  propertyMap.Insert( "enableAutoScroll", false );
+  propertyMap.Insert( "lineSpacing", 0.f );
+  propertyMap.Insert( "batchingEnabled", false );
+  Visual::Base textVisual = factory.CreateVisual( propertyMap );
+
+  Property::Map resultMap;
+  textVisual.CreatePropertyMap( resultMap );
+
+  //Check values in the result map are identical to the initial map's values.
+  Property::Value* value = resultMap.Find( Visual::Property::TYPE, Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<int>(), (int)Visual::TEXT, TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::RENDERING_BACKEND, Property::INTEGER );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<int>(), Toolkit::Text::DEFAULT_RENDERING_BACKEND, TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::TEXT, Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "Hello world", TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::FONT_FAMILY, Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "TizenSans", TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::FONT_STYLE, Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "{\"weight\":\"bold\"}", TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::POINT_SIZE, Property::FLOAT );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<float>(), 12.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::MULTI_LINE, Property::BOOLEAN );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( value->Get<bool>() );
+
+  value = resultMap.Find( TextVisual::Property::HORIZONTAL_ALIGNMENT, Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "CENTER", TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::VERTICAL_ALIGNMENT, Property::STRING );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<std::string>(), "CENTER", TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::TEXT_COLOR, Property::VECTOR4 );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<Vector4>(), Color::RED, TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::ENABLE_MARKUP, Property::BOOLEAN );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( !value->Get<bool>() );
+
+  value = resultMap.Find( TextVisual::Property::ENABLE_AUTO_SCROLL, Property::BOOLEAN );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( !value->Get<bool>() );
+
+  value = resultMap.Find( TextVisual::Property::LINE_SPACING, Property::FLOAT );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_EQUALS( value->Get<float>(), 0.f, Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  value = resultMap.Find( TextVisual::Property::BATCHING_ENABLED, Property::BOOLEAN );
+  DALI_TEST_CHECK( value );
+  DALI_TEST_CHECK( !value->Get<bool>() );
+
+  END_TEST;
+}
+
 int UtcDaliVisualGetPropertyMapBatchImageVisualNoAtlas(void)
 {
   ToolkitTestApplication application;
index 40e37c9..3fe52b4 100644 (file)
@@ -1139,6 +1139,46 @@ int UtcDaliVisualFactoryGetSvgVisual(void)
   END_TEST;
 }
 
+int UtcDaliVisualFactoryGetSvgVisualLarge(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualFactoryGetSvgVisual: Request svg visual with a svg url" );
+
+  VisualFactory factory = VisualFactory::Get();
+  Visual::Base visual = factory.CreateVisual( TEST_SVG_FILE_NAME, ImageDimensions( 2000, 2000 ) );
+  DALI_TEST_CHECK( visual );
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  TraceCallStack& textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  Actor actor = Actor::New();
+  Stage::GetCurrent().Add( actor );
+  visual.SetOnStage( actor );
+  application.SendNotification();
+  application.Render();
+
+  // renderer is not added to actor until the rasterization is completed.
+  DALI_TEST_CHECK( actor.GetRendererCount() == 0u );
+
+  EventThreadCallback* eventTrigger = EventThreadCallback::Get();
+  CallbackBase* callback = eventTrigger->GetCallback();
+
+  eventTrigger->WaitingForTrigger( 1 );// waiting until the svg image is rasterized.
+  CallbackBase::Execute( *callback );
+
+  // renderer is added to actor
+  DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
+
+  // waiting for the resource uploading
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+
+  END_TEST;
+}
+
 //Creates a mesh visual from the given propertyMap and tries to load it on stage in the given application.
 //This is expected to succeed, which will then pass the test.
 void MeshVisualLoadsCorrectlyTest( Property::Map& propertyMap, ToolkitTestApplication& application )
index 4e39d12..be46ddd 100644 (file)
@@ -61,6 +61,7 @@
 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/mesh-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/primitive-visual-properties.h>
+#include <dali-toolkit/public-api/visuals/text-visual-properties.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
 
 #include <dali-toolkit/public-api/dali-toolkit-version.h>
index dfe7370..c40bc41 100644 (file)
@@ -71,6 +71,11 @@ const Vector2& Visual::Base::GetSize() const
   return GetImplementation( *this ).GetSize();
 }
 
+float Visual::Base::GetHeightForWidth( float width ) const
+{
+  return GetImplementation( *this ).GetHeightForWidth( width );
+}
+
 void Visual::Base::GetNaturalSize(Vector2& naturalSize ) const
 {
   GetImplementation( *this ).GetNaturalSize( naturalSize );
index c38720c..2cbb0b7 100644 (file)
@@ -106,6 +106,15 @@ public:
   const Vector2& GetSize() const;
 
   /**
+   * @brief Returns the height for a given width.
+   *
+   * @param[in] width Width to use.
+   *
+   * @return The height based on the width.
+   */
+  float GetHeightForWidth( float width ) const;
+
+  /**
    * @brief Return the natural size of the visual.
    *
    * Deriving classes stipulate the natural size and by default a visual has a ZERO natural size.
index ddcb8d5..9d59568 100644 (file)
@@ -933,7 +933,7 @@ void TextEditor::OnInitialize()
 {
   Actor self = Self();
 
-  mController = Text::Controller::New( *this );
+  mController = Text::Controller::New( this, this );
 
   mDecorator = Text::Decorator::New( *mController,
                                      *mController );
@@ -949,6 +949,7 @@ void TextEditor::OnInitialize()
   // Disables the horizontal scrolling.
   mController->SetHorizontalScrollEnabled( false );
 
+  // Sets the maximum number of characters.
   mController->SetMaximumNumberOfCharacters( std::numeric_limits<Length>::max() );
 
   // Enable the smooth handle panning.
@@ -1042,7 +1043,7 @@ void TextEditor::OnRelayout( const Vector2& size, RelayoutContainer& container )
       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
     }
 
-    EnableClipping( true, size );
+    EnableClipping( size );
     RenderText( updateTextType );
   }
 
@@ -1235,21 +1236,6 @@ bool TextEditor::OnKeyEvent( const KeyEvent& event )
   return mController->KeyEvent( event );
 }
 
-void TextEditor::AddDecoration( Actor& actor, bool needsClipping )
-{
-  if( actor )
-  {
-    if( needsClipping )
-    {
-      mClippingDecorationActors.push_back( actor );
-    }
-    else
-    {
-      Self().Add( actor );
-    }
-  }
-}
-
 void TextEditor::RequestTextRelayout()
 {
   RelayoutRequest();
@@ -1261,6 +1247,11 @@ void TextEditor::TextChanged()
   mTextChangedSignal.Emit( handle );
 }
 
+void TextEditor::MaxLengthReached()
+{
+  // Nothing to do as TextEditor doesn't emit a max length reached signal.
+}
+
 void TextEditor::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
 {
   Dali::Toolkit::TextEditor handle( GetOwner() );
@@ -1315,9 +1306,19 @@ void TextEditor::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
   mInputStyleChangedSignal.Emit( handle, editorInputStyleMask );
 }
 
-void TextEditor::MaxLengthReached()
+void TextEditor::AddDecoration( Actor& actor, bool needsClipping )
 {
-  // Nothing to do as TextEditor doesn't emit a max length reached signal.
+  if( actor )
+  {
+    if( needsClipping )
+    {
+      mClippingDecorationActors.push_back( actor );
+    }
+    else
+    {
+      Self().Add( actor );
+    }
+  }
 }
 
 void TextEditor::OnStageConnect( Dali::Actor actor )
@@ -1353,31 +1354,23 @@ void TextEditor::GetHandleImagePropertyValue(  Property::Value& value, Text::Han
   }
 }
 
-void TextEditor::EnableClipping( bool clipping, const Vector2& size )
+void TextEditor::EnableClipping( const Vector2& size )
 {
-  if( clipping )
+  // Not worth to created clip actor if width or height is equal to zero.
+  if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
   {
-    // Not worth to created clip actor if width or height is equal to zero.
-    if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
+    if( !mClipper )
     {
-      if( !mClipper )
-      {
-        Actor self = Self();
+      Actor self = Self();
 
-        mClipper = Clipper::New( size );
-        self.Add( mClipper->GetRootActor() );
-        self.Add( mClipper->GetImageView() );
-      }
-      else if ( mClipper )
-      {
-        mClipper->Refresh( size );
-      }
+      mClipper = Clipper::New( size );
+      self.Add( mClipper->GetRootActor() );
+      self.Add( mClipper->GetImageView() );
+    }
+    else if ( mClipper )
+    {
+      mClipper->Refresh( size );
     }
-  }
-  else
-  {
-    // Note - this will automatically remove the root actor & the image view
-    mClipper.Reset();
   }
 }
 
index cb40406..2d7190b 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H__
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-editor.h>
 #include <dali-toolkit/internal/text/clipping/text-clipper.h>
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/text-control-interface.h>
+#include <dali-toolkit/internal/text/text-editable-control-interface.h>
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
 
-// EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
-
 namespace Dali
 {
 
@@ -42,7 +43,7 @@ namespace Internal
 /**
  * @brief A control which renders a long text string with styles.
  */
-class TextEditor : public Control, public Text::ControlInterface
+class TextEditor : public Control, public Text::ControlInterface, public Text::EditableControlInterface
 {
 public:
 
@@ -157,15 +158,12 @@ private: // From Control
 // From ControlInterface
 
   /**
-   * @copydoc Text::ControlInterface::AddDecoration()
-   */
-  virtual void AddDecoration( Actor& actor, bool needsClipping );
-
-  /**
    * @copydoc Text::ControlInterface::RequestTextRelayout()
    */
   virtual void RequestTextRelayout();
 
+// From EditableControlInterface
+
   /**
    * @copydoc Text::ControlInterface::TextChanged()
    */
@@ -181,6 +179,11 @@ private: // From Control
    */
   virtual void InputStyleChanged( Text::InputStyle::Mask inputStyleMask );
 
+  /**
+   * @copydoc Text::ControlInterface::AddDecoration()
+   */
+  virtual void AddDecoration( Actor& actor, bool needsClipping );
+
 private: // Implementation
 
   /**
@@ -205,10 +208,9 @@ private: // Implementation
   /**
    * @brief Enable or disable clipping.
    *
-   * @param[in] clipping True if clipping should be enabled.
    * @param[in] size The area to clip within.
    */
-  void EnableClipping( bool clipping, const Vector2& size );
+  void EnableClipping( const Vector2& size );
 
   /**
    * @brief Callback when keyboard is shown/hidden.
@@ -299,4 +301,4 @@ inline const Toolkit::Internal::TextEditor& GetImpl( const Toolkit::TextEditor&
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H__
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_EDITOR_H
index e0d75ce..6e679e3 100644 (file)
@@ -1114,7 +1114,7 @@ void TextField::OnInitialize()
 {
   Actor self = Self();
 
-  mController = Text::Controller::New( *this );
+  mController = Text::Controller::New( this, this );
 
   // When using the vector-based rendering, the size of the GLyphs are different
   TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
@@ -1222,7 +1222,7 @@ void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
       mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
     }
 
-    EnableClipping( ( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy ), size );
+    EnableClipping( size );
     RenderText( updateTextType );
   }
 
@@ -1246,7 +1246,7 @@ void TextField::OnRelayout( const Vector2& size, RelayoutContainer& container )
   }
 }
 
-  void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
+void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
 {
   Actor self = Self();
   Actor renderableActor;
@@ -1416,21 +1416,6 @@ bool TextField::OnKeyEvent( const KeyEvent& event )
   return mController->KeyEvent( event );
 }
 
-void TextField::AddDecoration( Actor& actor, bool needsClipping )
-{
-  if( actor )
-  {
-    if( needsClipping )
-    {
-      mClippingDecorationActors.push_back( actor );
-    }
-    else
-    {
-      Self().Add( actor );
-    }
-  }
-}
-
 void TextField::RequestTextRelayout()
 {
   RelayoutRequest();
@@ -1442,6 +1427,12 @@ void TextField::TextChanged()
   mTextChangedSignal.Emit( handle );
 }
 
+void TextField::MaxLengthReached()
+{
+  Dali::Toolkit::TextField handle( GetOwner() );
+  mMaxLengthReachedSignal.Emit( handle );
+}
+
 void TextField::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
 {
   Dali::Toolkit::TextField handle( GetOwner() );
@@ -1492,6 +1483,21 @@ void TextField::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
   mInputStyleChangedSignal.Emit( handle, fieldInputStyleMask );
 }
 
+void TextField::AddDecoration( Actor& actor, bool needsClipping )
+{
+  if( actor )
+  {
+    if( needsClipping )
+    {
+      mClippingDecorationActors.push_back( actor );
+    }
+    else
+    {
+      Self().Add( actor );
+    }
+  }
+}
+
 void TextField::OnStageConnect( Dali::Actor actor )
 {
   if ( mHasBeenStaged )
@@ -1504,12 +1510,6 @@ void TextField::OnStageConnect( Dali::Actor actor )
   }
 }
 
-void TextField::MaxLengthReached()
-{
-  Dali::Toolkit::TextField handle( GetOwner() );
-  mMaxLengthReachedSignal.Emit( handle );
-}
-
 ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
@@ -1531,9 +1531,9 @@ void TextField::GetHandleImagePropertyValue(  Property::Value& value, Text::Hand
   }
 }
 
-void TextField::EnableClipping( bool clipping, const Vector2& size )
+void TextField::EnableClipping( const Vector2& size )
 {
-  if( clipping )
+  if( Dali::Toolkit::TextField::EXCEED_POLICY_CLIP == mExceedPolicy )
   {
     // Not worth to created clip actor if width or height is equal to zero.
     if( size.width > Math::MACHINE_EPSILON_1000 && size.height > Math::MACHINE_EPSILON_1000 )
index 558cced..e40c647 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H__
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-field.h>
 #include <dali-toolkit/internal/text/clipping/text-clipper.h>
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/text-control-interface.h>
+#include <dali-toolkit/internal/text/text-editable-control-interface.h>
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/rendering/text-renderer.h>
 
-// EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/clipboard-event-notifier.h>
-
 namespace Dali
 {
 
@@ -42,7 +43,7 @@ namespace Internal
 /**
  * @brief A control which renders a short text string.
  */
-class TextField : public Control, public Text::ControlInterface
+class TextField : public Control, public Text::ControlInterface, public Text::EditableControlInterface
 {
 public:
 
@@ -162,15 +163,12 @@ private: // From Control
 // From ControlInterface
 
   /**
-   * @copydoc Text::ControlInterface::AddDecoration()
-   */
-  virtual void AddDecoration( Actor& actor, bool needsClipping );
-
-  /**
    * @copydoc Text::ControlInterface::RequestTextRelayout()
    */
   virtual void RequestTextRelayout();
 
+// From EditableControlInterface
+
   /**
    * @copydoc Text::ControlInterface::TextChanged()
    */
@@ -186,6 +184,11 @@ private: // From Control
    */
   virtual void InputStyleChanged( Text::InputStyle::Mask inputStyleMask );
 
+  /**
+   * @copydoc Text::ControlInterface::AddDecoration()
+   */
+  virtual void AddDecoration( Actor& actor, bool needsClipping );
+
 private: // Implementation
 
   /**
@@ -210,10 +213,9 @@ private: // Implementation
   /**
    * @brief Enable or disable clipping.
    *
-   * @param[in] clipping True if clipping should be enabled.
    * @param[in] size The area to clip within.
    */
-  void EnableClipping( bool clipping, const Vector2& size );
+  void EnableClipping( const Vector2& size );
 
   /**
    * @brief Callback when keyboard is shown/hidden.
@@ -306,4 +308,4 @@ inline const Toolkit::Internal::TextField& GetImpl( const Toolkit::TextField& te
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H__
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_FIELD_H
index bf8c866..955e0f2 100644 (file)
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-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>
+#include <dali-toolkit/public-api/visuals/text-visual-properties.h>
 #include <dali-toolkit/internal/text/text-effects-style.h>
-#include <dali-toolkit/internal/text/text-font-style.h>
-#include <dali-toolkit/internal/text/text-view.h>
-#include <dali-toolkit/internal/text/text-definitions.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 
 using Dali::Toolkit::Text::LayoutEngine;
-using Dali::Toolkit::Text::Backend;
 
 namespace Dali
 {
@@ -57,22 +51,6 @@ namespace
   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
 #endif
 
-const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
-{
-  { "BEGIN",  Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN  },
-  { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
-  { "END",    Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END    },
-};
-const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
-
-const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
-{
-  { "TOP",    Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP    },
-  { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
-  { "BOTTOM", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_BOTTOM },
-};
-const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
-
 // Type registration
 BaseHandle Create()
 {
@@ -109,7 +87,33 @@ DALI_PROPERTY_REGISTRATION( Toolkit, TextLabel, "outline",              STRING,
 
 DALI_TYPE_REGISTRATION_END()
 
-
+const int TEXT_VISUAL_PROPERTY_TABLE[] = {
+  Dali::Toolkit::TextVisual::Property::RENDERING_BACKEND,
+  Dali::Toolkit::TextVisual::Property::TEXT,
+  Dali::Toolkit::TextVisual::Property::FONT_FAMILY,
+  Dali::Toolkit::TextVisual::Property::FONT_STYLE,
+  Dali::Toolkit::TextVisual::Property::POINT_SIZE,
+  Dali::Toolkit::TextVisual::Property::MULTI_LINE,
+  Dali::Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT,
+  Dali::Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT,
+  Dali::Toolkit::TextVisual::Property::TEXT_COLOR,
+  Dali::Toolkit::TextVisual::Property::SHADOW,
+  Dali::Toolkit::TextVisual::Property::SHADOW,
+  Dali::Toolkit::TextVisual::Property::UNDERLINE,
+  Dali::Toolkit::TextVisual::Property::UNDERLINE,
+  Dali::Toolkit::TextVisual::Property::UNDERLINE,
+  Dali::Toolkit::TextVisual::Property::ENABLE_MARKUP,
+  Dali::Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL,
+  Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED,
+  Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT,
+  Dali::Toolkit::TextVisual::Property::AUTO_SCROLL_GAP,
+  Dali::Toolkit::TextVisual::Property::LINE_SPACING,
+  Dali::Toolkit::TextVisual::Property::UNDERLINE,
+  Dali::Toolkit::TextVisual::Property::SHADOW,
+  Dali::Toolkit::TextVisual::Property::EMBOSS,
+  Dali::Toolkit::TextVisual::Property::OUTLINE,
+  Dali::Toolkit::TextVisual::Property::BATCHING_ENABLED
+};
 
 } // namespace
 
@@ -134,298 +138,10 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
 
   if( label )
   {
-    TextLabel& impl( GetImpl( label ) );
-    switch( index )
-    {
-      case Toolkit::TextLabel::Property::RENDERING_BACKEND:
-      {
-        int backend = value.Get< int >();
-
-#ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
-        if( Text::RENDERING_VECTOR_BASED == backend )
-        {
-          backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering
-        }
-#endif
-        if( impl.mRenderingBackend != backend )
-        {
-          impl.mRenderingBackend = backend;
-          impl.mRenderer.Reset();
-
-          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 );
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::TEXT:
-      {
-        if( impl.mController )
-        {
-          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 >();
-
-          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:
-      {
-        SetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
-        break;
-      }
-      case Toolkit::TextLabel::Property::POINT_SIZE:
-      {
-        if( impl.mController )
-        {
-          const float pointSize = value.Get< float >();
-
-          if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
-          {
-            impl.mController->SetDefaultPointSize( pointSize );
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::MULTI_LINE:
-      {
-        if( impl.mController )
-        {
-          impl.mController->SetMultiLineEnabled( value.Get< bool >() );
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
-      {
-        if( impl.mController )
-        {
-          LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
-          if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( value.Get< std::string >().c_str(),
-                                                                                             HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                                             HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
-                                                                                             alignment ) )
-          {
-            impl.mController->SetHorizontalAlignment( alignment );
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
-      {
-        if( impl.mController )
-        {
-          LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
-          if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( value.Get< std::string >().c_str(),
-                                                                                           VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                                                           VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
-                                                                                           alignment ) )
-          {
-            impl.mController->SetVerticalAlignment( alignment );
-          }
-        }
-        break;
-      }
-
-      case Toolkit::TextLabel::Property::TEXT_COLOR:
-      {
-        if( impl.mController )
-        {
-          const Vector4 textColor = value.Get< Vector4 >();
-          if( impl.mController->GetTextColor() != textColor )
-          {
-            impl.mController->SetTextColor( textColor );
-            impl.mRenderer.Reset();
-          }
-        }
-        break;
-      }
-
-      case Toolkit::TextLabel::Property::SHADOW_OFFSET:
-      {
-        if( impl.mController )
-        {
-          const Vector2 shadowOffset = value.Get< Vector2 >();
-          if ( impl.mController->GetShadowOffset() != shadowOffset )
-          {
-            impl.mController->SetShadowOffset( shadowOffset );
-            impl.mRenderer.Reset();
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::SHADOW_COLOR:
-      {
-        if( impl.mController )
-        {
-          const Vector4 shadowColor = value.Get< Vector4 >();
-          if ( impl.mController->GetShadowColor() != shadowColor )
-          {
-            impl.mController->SetShadowColor( shadowColor );
-            impl.mRenderer.Reset();
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::UNDERLINE_COLOR:
-      {
-        if( impl.mController )
-        {
-          const Vector4 color = value.Get< Vector4 >();
-          if ( impl.mController->GetUnderlineColor() != color )
-          {
-            impl.mController->SetUnderlineColor( color );
-            impl.mRenderer.Reset();
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::UNDERLINE_ENABLED:
-      {
-        if( impl.mController )
-        {
-          const bool enabled = value.Get< bool >();
-          if ( impl.mController->IsUnderlineEnabled() != enabled )
-          {
-            impl.mController->SetUnderlineEnabled( enabled );
-            impl.mRenderer.Reset();
-          }
-        }
-        break;
-      }
+    TextLabel& impl = GetImpl( label );
 
-      case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT:
-      {
-        if( impl.mController )
-        {
-          float height = value.Get< float >();
-          if( fabsf( impl.mController->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 )
-          {
-            impl.mController->SetUnderlineHeight( height );
-            impl.mRenderer.Reset();
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::ENABLE_MARKUP:
-      {
-        if( impl.mController )
-        {
-          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() )
-          {
-             // If request is disable (false) and auto scrolling is enabled then need to stop it
-             if ( enableAutoScroll == false )
-             {
-               if( impl.mTextScroller )
-               {
-                 impl.mTextScroller->SetLoopCount( 0 ); // Causes the current animation to finish playing (0)
-               }
-             }
-             // If request is enable (true) then start autoscroll as not already running
-             else
-             {
-               impl.mController->GetLayoutEngine().SetTextEllipsisEnabled( false );
-               impl.mController->SetAutoScrollEnabled( enableAutoScroll );
-             }
-          }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED:
-      {
-        if( !impl.mTextScroller )
-        {
-          impl.mTextScroller = Text::TextScroller::New( impl );
-        }
-        impl.mTextScroller->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>() );
-        break;
-      }
-      case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP:
-      {
-        if( !impl.mTextScroller )
-        {
-          impl.mTextScroller = Text::TextScroller::New( impl );
-        }
-        impl.mTextScroller->SetGap( value.Get<float>() );
-        break;
-      }
-      case Toolkit::TextLabel::Property::LINE_SPACING:
-      {
-        if( impl.mController )
-        {
-          const float lineSpacing = value.Get<float>();
-          impl.mController->SetDefaultLineSpacing( lineSpacing );
-          impl.mRenderer.Reset();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::UNDERLINE:
-      {
-        const bool update = SetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        if( update )
-        {
-          impl.mRenderer.Reset();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::SHADOW:
-      {
-        const bool update = SetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        if( update )
-        {
-          impl.mRenderer.Reset();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::EMBOSS:
-      {
-        const bool update = SetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        if( update )
-        {
-          impl.mRenderer.Reset();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::OUTLINE:
-      {
-        const bool update = SetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        if( update )
-        {
-          impl.mRenderer.Reset();
-        }
-        break;
-      }
-    }
+    // Sets the property to the to the text visual.
+    impl.mVisual.SetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX], value );
   }
 }
 
@@ -437,204 +153,127 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
 
   if( label )
   {
-    TextLabel& impl( GetImpl( label ) );
-    switch( index )
+    TextLabel& impl = GetImpl( label );
+
+    if( ( Toolkit::TextLabel::Property::SHADOW_OFFSET == index ) ||
+        ( Toolkit::TextLabel::Property::SHADOW_COLOR == index ) ||
+        ( Toolkit::TextLabel::Property::UNDERLINE_ENABLED == index ) ||
+        ( Toolkit::TextLabel::Property::UNDERLINE_COLOR == index ) ||
+        ( Toolkit::TextLabel::Property::UNDERLINE_HEIGHT == index ) )
     {
-      case Toolkit::TextLabel::Property::RENDERING_BACKEND:
-      {
-        value = impl.mRenderingBackend;
-        break;
-      }
-      case Toolkit::TextLabel::Property::TEXT:
-      {
-        if( impl.mController )
-        {
-          std::string text;
-          impl.mController->GetText( text );
-          value = text;
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::FONT_FAMILY:
-      {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultFontFamily();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::FONT_STYLE:
-      {
-        GetFontStyleProperty( impl.mController, value, Text::FontStyle::DEFAULT );
-        break;
-      }
-      case Toolkit::TextLabel::Property::POINT_SIZE:
-      {
-        if( impl.mController )
-        {
-          value = impl.mController->GetDefaultPointSize();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::MULTI_LINE:
-      {
-        if( impl.mController )
-        {
-          value = impl.mController->IsMultiLineEnabled();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
+      // TODO : Branch to be removed when the deprecated properties are finally removed.
+      value = impl.mVisual.GetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX] );
+
+      switch( index )
       {
-        if( impl.mController )
+        case Toolkit::TextLabel::Property::SHADOW_OFFSET: // Converts the deprecated property to the new one.
         {
-          const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
-                                                                                                                HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
-          if( name )
+          bool colorDefined = false;
+          Vector4 color;
+          bool offsetDefined = false;
+          Vector2 offset;
+          const bool empty = Text::ParseProperties( value.Get<std::string>(),
+                                                    colorDefined,
+                                                    color,
+                                                    offsetDefined,
+                                                    offset );
+
+          if( !empty )
           {
-            value = std::string( name );
+            value = offset;
           }
+          break;
         }
-        break;
-      }
-      case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
-      {
-        if( impl.mController )
+        case Toolkit::TextLabel::Property::SHADOW_COLOR: // Converts the deprecated property to the new one.
         {
-          const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetVerticalAlignment(),
-                                                                                                              VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                                                                              VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
-          if( name )
+          bool colorDefined = false;
+          Vector4 color;
+          bool offsetDefined = false;
+          Vector2 offset;
+          const bool empty = Text::ParseProperties( value.Get<std::string>(),
+                                                    colorDefined,
+                                                    color,
+                                                    offsetDefined,
+                                                    offset );
+
+          if( !empty )
           {
-            value = std::string( name );
+            value = color;
           }
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::TEXT_COLOR:
-      {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetTextColor();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::SHADOW_OFFSET:
-      {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetShadowOffset();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::SHADOW_COLOR:
-      {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetShadowColor();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::UNDERLINE_COLOR:
-      {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetUnderlineColor();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::UNDERLINE_ENABLED:
-      {
-        if ( impl.mController )
-        {
-          value = impl.mController->IsUnderlineEnabled();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT:
-      {
-        if ( impl.mController )
-        {
-          value = impl.mController->GetUnderlineHeight();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::ENABLE_MARKUP:
-      {
-        if( impl.mController )
-        {
-          value = impl.mController->IsMarkupProcessorEnabled();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::ENABLE_AUTO_SCROLL:
-      {
-        if( impl.mController )
-        {
-          value = impl.mController->IsAutoScrollEnabled();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::AUTO_SCROLL_SPEED:
-      {
-        TextLabel& impl( GetImpl( label ) );
-        if ( impl.mTextScroller )
-        {
-          value = impl.mTextScroller->GetSpeed();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::AUTO_SCROLL_LOOP_COUNT:
-      {
-        if( impl.mController )
-        {
-          TextLabel& impl( GetImpl( label ) );
-          if ( impl.mTextScroller )
+          break;
+        }
+        case Toolkit::TextLabel::Property::UNDERLINE_ENABLED: // Converts the deprecated property to the new one.
+        {
+          bool enabled = false;
+          bool colorDefined = false;
+          Vector4 color;
+          bool heightDefined = false;
+          float height = 0.f;
+          const bool empty = Text::ParseProperties( value.Get<std::string>(),
+                                                    enabled,
+                                                    colorDefined,
+                                                    color,
+                                                    heightDefined,
+                                                    height );
+
+          if( !empty )
           {
-            value = impl.mTextScroller->GetLoopCount();
+            value = enabled;
           }
+          break;
+        }
+        case Toolkit::TextLabel::Property::UNDERLINE_COLOR: // Converts the deprecated property to the new one.
+        {
+          bool enabled = false;
+          bool colorDefined = false;
+          Vector4 color;
+          bool heightDefined = false;
+          float height = 0.f;
+          const bool empty = Text::ParseProperties( value.Get<std::string>(),
+                                                    enabled,
+                                                    colorDefined,
+                                                    color,
+                                                    heightDefined,
+                                                    height );
+
+          if( !empty && colorDefined )
+          {
+            value = color;
+          }
+          break;
+        }
+        case Toolkit::TextLabel::Property::UNDERLINE_HEIGHT: // Converts the deprecated property to the new one.
+        {
+          bool enabled = false;
+          bool colorDefined = false;
+          Vector4 color;
+          bool heightDefined = false;
+          float height = 0.f;
+          const bool empty = Text::ParseProperties( value.Get<std::string>(),
+                                                    enabled,
+                                                    colorDefined,
+                                                    color,
+                                                    heightDefined,
+                                                    height );
+
+          if( !empty && heightDefined )
+          {
+            value = height;
+          }
+          break;
         }
-        break;
-      }
-      case Toolkit::TextLabel::Property::AUTO_SCROLL_GAP:
-      {
-        TextLabel& impl( GetImpl( label ) );
-        if ( impl.mTextScroller )
-        {
-          value = impl.mTextScroller->GetGap();
-        }
-        break;
-      }
-      case Toolkit::TextLabel::Property::LINE_SPACING:
-      {
-        if( impl.mController )
+        default:
         {
-          value = impl.mController->GetDefaultLineSpacing();
+          // Nothing to do.
+          break;
         }
-        break;
-      }
-      case Toolkit::TextLabel::Property::UNDERLINE:
-      {
-        GetUnderlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        break;
-      }
-      case Toolkit::TextLabel::Property::SHADOW:
-      {
-        GetShadowProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        break;
-      }
-      case Toolkit::TextLabel::Property::EMBOSS:
-      {
-        GetEmbossProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        break;
-      }
-      case Toolkit::TextLabel::Property::OUTLINE:
-      {
-        GetOutlineProperties( impl.mController, value, Text::EffectStyle::DEFAULT );
-        break;
       }
     }
+    else
+    {
+      // Retrieves the property from the text visual.
+      value = impl.mVisual.GetProperty( TEXT_VISUAL_PROPERTY_TABLE[index - Toolkit::TextLabel::PROPERTY_START_INDEX] );
+    }
   }
 
   return value;
@@ -644,23 +283,23 @@ void TextLabel::OnInitialize()
 {
   Actor self = Self();
 
-  mController = Text::Controller::New( *this );
+  // Creates the text's visual.
+  Property::Map visualMap;
+  visualMap[Toolkit::Visual::Property::TYPE] = Toolkit::Visual::TEXT;
+  visualMap[Toolkit::TextVisual::Property::RENDERING_BACKEND] = static_cast<int>( DEFAULT_RENDERING_BACKEND );
+
+  mVisual =  Toolkit::VisualFactory::Get().CreateVisual( visualMap );
+  RegisterVisual( Toolkit::TextLabel::Property::TEXT, self, mVisual );
 
-  // When using the vector-based rendering, the size of the GLyphs are different
-  TextAbstraction::GlyphType glyphType = (Text::RENDERING_VECTOR_BASED == mRenderingBackend) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
-  mController->SetGlyphType( glyphType );
+  Internal::Visual::Base& visualBase = Toolkit::GetImplementation( mVisual );
+  TextVisual* textVisual = static_cast<TextVisual*>( &visualBase );
+
+  // Sets the text's control interface.
+  textVisual->SetTextControlInterface( this );
 
   // Use height-for-width negotiation by default
   self.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::WIDTH );
   self.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
-
-  // Enable the text ellipsis.
-  LayoutEngine& engine = mController->GetLayoutEngine();
-
-  engine.SetTextEllipsisEnabled( true );   // If false then text larger than control will overflow
-  engine.SetCursorWidth( 0u ); // Do not layout space for the cursor.
-
-  self.OnStageSignal().Connect( this, &TextLabel::OnStageConnect );
 }
 
 void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
@@ -674,10 +313,11 @@ void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::
       // Property system did not set the font so should update it.
       const std::string& newFont = GetImpl( styleManager ).GetDefaultFontFamily();
       DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnStyleChange StyleChange::DEFAULT_FONT_CHANGE newFont(%s)\n", newFont.c_str() );
-      mController->UpdateAfterFontChange( newFont );
+
+      const std::string fontString = "{\"family\":\"" + newFont + "\",\"type\":\"system\"}";
+      mVisual.SetProperty( Toolkit::TextVisual::Property::FONT_FAMILY, fontString );
       break;
     }
-
     case StyleChange::DEFAULT_FONT_SIZE_CHANGE:
     {
       GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
@@ -693,29 +333,22 @@ void TextLabel::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::
 
 Vector3 TextLabel::GetNaturalSize()
 {
-  return mController->GetNaturalSize();
+  Vector2 naturalSize;
+  mVisual.GetNaturalSize( naturalSize );
+
+  return Vector3( naturalSize );
 }
 
 float TextLabel::GetHeightForWidth( float width )
 {
-  return mController->GetHeightForWidth( width );
+  return mVisual.GetHeightForWidth( width );
 }
 
 void TextLabel::OnRelayout( const Vector2& size, RelayoutContainer& container )
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::OnRelayout\n" );
 
-  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
-
-  if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) ||
-      !mRenderer )
-  {
-    if( !mRenderer )
-    {
-      mRenderer = Backend::Get().NewRenderer( mRenderingBackend );
-    }
-    RenderText();
-  }
+  mVisual.SetSize( size );
 }
 
 void TextLabel::RequestTextRelayout()
@@ -723,115 +356,16 @@ void TextLabel::RequestTextRelayout()
   RelayoutRequest();
 }
 
-void TextLabel::RenderText()
-{
-  DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::RenderText IsAutoScrollEnabled[%s] [%p]\n", ( mController->IsAutoScrollEnabled())?"true":"false", this );
-
-  Actor self = Self();
-  Actor renderableActor;
-
-  if( mRenderer )
-  {
-    renderableActor = mRenderer->Render( mController->GetView(), DepthIndex::TEXT );
-  }
-
-  if( renderableActor != mRenderableActor )
-  {
-    UnparentAndReset( mRenderableActor );
-
-    if( renderableActor )
-    {
-      const Vector2& scrollOffset = mController->GetScrollPosition();
-      renderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
-
-      self.Add( renderableActor );
-    }
-    mRenderableActor = renderableActor;
-
-    if ( mController->IsAutoScrollEnabled() )
-    {
-      SetUpAutoScrolling();
-    }
-  }
-}
-
-void TextLabel::SetUpAutoScrolling()
-{
-  const Size& controlSize = mController->GetView().GetControlSize();
-  const Size offScreenSize = GetNaturalSize().GetVectorXY(); // As relayout of text may not be done at this point natural size is used to get size. Single line scrolling only.
-  const float alignmentOffset = mController->GetAutoScrollLineAlignment();
-  const Text::CharacterDirection direction = mController->GetAutoScrollDirection();
-
-  DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling alignmentOffset[%f] offScreenSize[%f,%f] controlSize[%f,%f]\n",
-                 alignmentOffset, offScreenSize.x,offScreenSize.y , controlSize.x,controlSize.y );
-
-  if ( !mTextScroller )
-  {
-    DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::SetUpAutoScrolling Creating default TextScoller\n" );
-
-    // If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults
-    mTextScroller = Text::TextScroller::New( *this );
-  }
-  mTextScroller->SetParameters( mRenderableActor, controlSize, offScreenSize, direction, alignmentOffset );
-
-  Actor self = Self();
-  self.Add( mTextScroller->GetScrollingText() );
-  self.Add( mTextScroller->GetSourceCamera() );
-}
-
-void TextLabel::OnStageConnect( Dali::Actor actor )
-{
-  if ( mHasBeenStaged )
-  {
-    RenderText();
-  }
-  else
-  {
-    mHasBeenStaged = true;
-  }
-}
-
-void TextLabel::AddDecoration( Actor& actor, bool needsClipping )
-{
-  // TextLabel does not show decorations
-}
-
 void TextLabel::OnStageConnection( int depth )
 {
   // Call the Control::OnStageConnection() to set the depth of the background.
   Control::OnStageConnection( depth );
 
-  // The depth of the text renderer is set in the RenderText() called from OnRelayout().
-}
-
-void TextLabel::TextChanged()
-{
-  // TextLabel does not provide a signal for this.
-}
-
-void TextLabel::MaxLengthReached()
-{
-  // Pure Virtual from TextController Interface, only needed when inputting text
-}
-
-void TextLabel::InputStyleChanged( Text::InputStyle::Mask inputStyleMask )
-{
-  // TextLabel does not provide a signal for this.
-}
-
-void TextLabel::ScrollingFinished()
-{
-  // Pure Virtual from TextScroller Interface
-  DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::ScrollingFinished\n");
-  mController->SetAutoScrollEnabled( false );
-  mController->GetLayoutEngine().SetTextEllipsisEnabled( true );
-  RequestTextRelayout();
+  // The depth of the text renderer is set by the text-visual called from OnRelayout().
 }
 
 TextLabel::TextLabel()
-: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
-  mRenderingBackend( DEFAULT_RENDERING_BACKEND ),
-  mHasBeenStaged( false )
+: Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) )
 {
 }
 
index 298ba1a..bdc587d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H__
-#define __DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H__
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
-#include <dali-toolkit/internal/text/text-controller.h>
-#include <dali-toolkit/internal/text/text-scroller-interface.h>
-#include <dali-toolkit/internal/text/rendering/text-renderer.h>
-#include <dali-toolkit/internal/text/text-scroller.h>
+#include <dali-toolkit/internal/text/text-control-interface.h>
+#include <dali-toolkit/internal/visuals/text/text-visual.h>
 
 namespace Dali
 {
@@ -38,7 +36,7 @@ namespace Internal
 /**
  * @brief A control which renders a short text string.
  */
-class TextLabel : public Control, public Text::ControlInterface, public Text::ScrollerInterface
+class TextLabel : public Control, public Text::ControlInterface
 {
 public:
 
@@ -95,42 +93,17 @@ private: // From Control
   virtual float GetHeightForWidth( float width );
 
   /**
-   * @copydoc Text::ControlInterface::AddDecoration()
-   */
-  virtual void AddDecoration( Actor& actor, bool needsClipping );
-
-  /**
    * @copydoc Control::OnStageConnection()
    */
   virtual void OnStageConnection( int depth );
 
+// From ControlInterface
+
   /**
    * @copydoc Text::ControlInterface::RequestTextRelayout()
    */
   virtual void RequestTextRelayout();
 
-  /**
-   * @copydoc Text::ControlInterface::TextChanged()
-   */
-  virtual void TextChanged();
-
-  /**
-   * @copydoc Text::ControlInterface::MaxLengthReached()
-   */
-  virtual void MaxLengthReached();
-
-  /**
-   * @copydoc Text::ControlInterface::InputStyleChanged()
-   */
-  virtual void InputStyleChanged( Text::InputStyle::Mask inputStyleMask );
-
-private: // from TextScroller
-
-  /**
-   * @copydoc Text::ScrollerInterface::ScrollingFinished()
-   */
-  virtual void ScrollingFinished();
-
 private: // Implementation
 
   /**
@@ -149,27 +122,9 @@ private:
   TextLabel(const TextLabel&);
   TextLabel& operator=(const TextLabel& rhs);
 
-  // Connection needed to re-render text, when a Text Label returns to the stage
-  void OnStageConnect( Dali::Actor actor );
-
-  /**
-   * @brief Render view, create and attach actor(s) to this Text Label
-   */
-  void RenderText();
-
-  /**
-   * @brief Set up Autoscrolling
-   */
-  void SetUpAutoScrolling();
-
 private: // Data
 
-  Text::ControllerPtr mController;
-  Text::RendererPtr mRenderer;
-  Text::TextScrollerPtr mTextScroller;
-  Actor mRenderableActor;
-  int mRenderingBackend;
-  bool mHasBeenStaged:1;
+  Toolkit::Visual::Base mVisual;
 };
 
 } // namespace Internal
@@ -198,4 +153,4 @@ inline const Toolkit::Internal::TextLabel& GetImpl( const Toolkit::TextLabel& te
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H__
+#endif // DALI_TOOLKIT_INTERNAL_TEXT_LABEL_H
index 8437cef..57b4dbf 100644 (file)
@@ -29,6 +29,7 @@ toolkit_src_files = \
    $(toolkit_src_dir)/visuals/primitive/primitive-visual.cpp \
    $(toolkit_src_dir)/visuals/svg/svg-rasterize-thread.cpp \
    $(toolkit_src_dir)/visuals/svg/svg-visual.cpp \
+   $(toolkit_src_dir)/visuals/text/text-visual.cpp \
    $(toolkit_src_dir)/visuals/wireframe/wireframe-visual.cpp \
    $(toolkit_src_dir)/visuals/transition-data-impl.cpp \
    $(toolkit_src_dir)/controls/alignment/alignment-impl.cpp \
@@ -107,13 +108,13 @@ toolkit_src_files = \
    $(toolkit_src_dir)/text/property-string-parser.cpp \
    $(toolkit_src_dir)/text/segmentation.cpp \
    $(toolkit_src_dir)/text/shaper.cpp \
-   $(toolkit_src_dir)/text/text-control-interface.cpp \
    $(toolkit_src_dir)/text/text-controller.cpp \
    $(toolkit_src_dir)/text/text-controller-impl.cpp \
    $(toolkit_src_dir)/text/text-effects-style.cpp \
    $(toolkit_src_dir)/text/text-font-style.cpp \
    $(toolkit_src_dir)/text/text-io.cpp \
    $(toolkit_src_dir)/text/text-scroller.cpp \
+   $(toolkit_src_dir)/text/text-scroller-data.cpp \
    $(toolkit_src_dir)/text/text-scroller-interface.cpp \
    $(toolkit_src_dir)/text/text-view.cpp \
    $(toolkit_src_dir)/text/text-view-interface.cpp \
index 3c02c27..8af6140 100644 (file)
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/common/constants.h>
+#include <dali/public-api/math/vector2.h>
 #include <stdlib.h>
+#include <sstream>
+#include <iomanip>
 
 namespace Dali
 {
@@ -33,9 +36,10 @@ namespace Text
 
 namespace
 {
-const char WHITE_SPACE       = 0x20; // ASCII value of the white space.
-const char LAST_UPPER_CASE   = 0x5b; // ASCII value of the one after the last upper case character (Z).
-const char TO_LOWER_CASE     = 32;   // Value to add to a upper case character to transform it into a lower case.
+const char WHITE_SPACE      = 0x20; // ASCII value of the white space.
+const char FIRST_UPPER_CASE = 0x41; // ASCII value of the one after the first upper case character (A).
+const char LAST_UPPER_CASE  = 0x5b; // ASCII value of the one after the last upper case character (Z).
+const char TO_LOWER_CASE    = 32;   // Value to add to a upper case character to transform it into a lower case.
 
 const char WEB_COLOR_TOKEN( '#' );
 const char* const HEX_COLOR_TOKEN( "0x" );
@@ -65,8 +69,9 @@ bool TokenComparison( const std::string& string1, const char* const stringBuffer
 
   for( std::size_t index = 0; index < stringSize; ++index )
   {
-    char character = *( stringBuffer2 + index );
-    if( *( stringBuffer1 + index ) != ( ( ( character < LAST_UPPER_CASE ) && ( '0' != character ) ) ? character + TO_LOWER_CASE : character ) )
+    const char character = *( stringBuffer2 + index );
+    const bool toLower = ( character < LAST_UPPER_CASE ) && ( character >= FIRST_UPPER_CASE );
+    if( *( stringBuffer1 + index ) != ( toLower ? character + TO_LOWER_CASE : character ) )
     {
       return false;
     }
@@ -75,10 +80,16 @@ bool TokenComparison( const std::string& string1, const char* const stringBuffer
   return true;
 }
 
-void SkipWhiteSpace( const char*& markupStringBuffer,
-                     const char* const markupStringEndBuffer )
+void SkipWhiteSpace( const char*& stringBuffer,
+                     const char* const stringEndBuffer )
 {
-  for( ; ( WHITE_SPACE >= *markupStringBuffer ) && ( markupStringBuffer < markupStringEndBuffer ); ++markupStringBuffer );
+  for( ; ( WHITE_SPACE >= *stringBuffer ) && ( stringBuffer < stringEndBuffer ); ++stringBuffer );
+}
+
+void JumpToWhiteSpace( const char*& stringBuffer,
+                       const char* const stringEndBuffer )
+{
+  for( ; ( WHITE_SPACE != *stringBuffer ) && ( stringBuffer < stringEndBuffer ); ++stringBuffer );
 }
 
 unsigned int StringToHex( const char* const uintStr )
@@ -91,6 +102,13 @@ float StringToFloat( const char* const floatStr )
   return static_cast<float>( strtod( floatStr, NULL ) );
 }
 
+void FloatToString( float value, std::string& floatStr )
+{
+  std::stringstream ss;
+  ss << value;
+  floatStr = ss.str();
+}
+
 void UintColorToVector4( unsigned int color, Vector4& retColor )
 {
   retColor.a = static_cast<float>( ( color & 0xFF000000 ) >> 24u ) / 255.f;
@@ -160,6 +178,112 @@ void ColorStringToVector4( const char* const colorStr, Length length, Vector4& r
   }
 }
 
+void Vector4ToColorString( const Vector4& value, std::string& vector2Str )
+{
+  if( Color::BLACK == value )
+  {
+    vector2Str = BLACK_COLOR;
+    return;
+  }
+
+  if( Color::WHITE == value )
+  {
+    vector2Str = WHITE_COLOR;
+    return;
+  }
+
+  if( Color::RED == value )
+  {
+    vector2Str = RED_COLOR;
+    return;
+  }
+
+  if( Color::GREEN == value )
+  {
+    vector2Str = GREEN_COLOR;
+    return;
+  }
+
+  if( Color::BLUE == value )
+  {
+    vector2Str = BLUE_COLOR;
+    return;
+  }
+
+  if( Color::YELLOW == value )
+  {
+    vector2Str = YELLOW_COLOR;
+    return;
+  }
+
+  if( Color::MAGENTA == value )
+  {
+    vector2Str = MAGENTA_COLOR;
+    return;
+  }
+
+  if( Color::CYAN == value )
+  {
+    vector2Str = CYAN_COLOR;
+    return;
+  }
+
+  if( Color::TRANSPARENT == value )
+  {
+    vector2Str = TRANSPARENT_COLOR;
+    return;
+  }
+
+  const unsigned int alpha = static_cast<unsigned int>( 255.f * value.a );
+  const unsigned int red = static_cast<unsigned int>( 255.f * value.r );
+  const unsigned int green = static_cast<unsigned int>( 255.f * value.g );
+  const unsigned int blue = static_cast<unsigned int>( 255.f * value.b );
+
+  std::stringstream ss;
+  const unsigned int size = 2u * sizeof( unsigned char );
+
+  ss << "0x"
+     << std::setfill('0') << std::setw( size )
+     << std::hex << alpha
+     << std::setfill('0') << std::setw( size )
+     << std::hex << red
+     << std::setfill('0') << std::setw( size )
+     << std::hex << green
+     << std::setfill('0') << std::setw( size )
+     << std::hex << blue;
+  vector2Str = ss.str();
+}
+
+void StringToVector2( const char* const vectorStr, Length length, Vector2& vector2 )
+{
+  // Points to the first character of the string.
+  const char* strBuffer = vectorStr;
+
+  // Points to the first character of the 'x' value.
+  const char* const xBuffer = strBuffer;
+
+  // Jumps to the next white space.
+  JumpToWhiteSpace( strBuffer, strBuffer + length );
+
+  // Points to the first character of the 'y' value.
+  const char* const yBuffer = strBuffer;
+
+  // Converts the shadow's offset to float.
+  vector2.x = StringToFloat( xBuffer );
+  vector2.y = StringToFloat( yBuffer );
+}
+
+void Vector2ToString( const Vector2& value, std::string& vector2Str )
+{
+  FloatToString( value.x, vector2Str );
+  vector2Str += " ";
+
+  std::string yStr;
+  FloatToString( value.y, yStr );
+
+  vector2Str += yStr;
+}
+
 } // namespace Text
 
 } // namespace Toolkit
index 62be6c8..45f586c 100644 (file)
@@ -28,6 +28,7 @@
 namespace Dali
 {
 
+struct Vector2;
 struct Vector4;
 
 namespace Toolkit
@@ -78,11 +79,20 @@ bool TokenComparison( const std::string& string1, const char* const stringBuffer
 /**
  * @brief Skips any unnecessary white space.
  *
- * @param[in,out] markupStringBuffer The mark-up string buffer. It's a const iterator pointing the current character.
- * @param[in] markupStringEndBuffer Pointer to one character after the end of the mark-up string buffer.
+ * @param[in,out] stringBuffer The string buffer. It's a const iterator pointing the current character.
+ * @param[in] stringEndBuffer Pointer to one character after the end of the string buffer.
  */
-void SkipWhiteSpace( const char*& markupStringBuffer,
-                     const char* const markupStringEndBuffer );
+void SkipWhiteSpace( const char*& stringBuffer,
+                     const char* const stringEndBuffer );
+
+/**
+ * @Brief Jumps to the next white space.
+ *
+ * @param[in,out] stringBuffer The string buffer. It's a const iterator pointing the current character.
+ * @param[in] stringEndBuffer Pointer to one character after the end of the string buffer.
+ */
+void JumpToWhiteSpace( const char*& stringBuffer,
+                       const char* const stringEndBuffer );
 
 /**
  * @brief Converts a string into an hexadecimal unsigned int.
@@ -103,6 +113,14 @@ unsigned int StringToHex( const char* const uintStr );
 float StringToFloat( const char* const floatStr );
 
 /**
+ * @brief Converts a float into a string.
+ *
+ * @param[in] value The float value.
+ * @param[out] floatStr The string.
+ */
+void FloatToString( float value, std::string& floatStr );
+
+/**
  * @brief Converts an ARGB color packed in 4 byte unsigned int into a Vector4 color used in Dali.
  *
  * @param[in] color An ARGB color packed in an unsigned int.
@@ -114,7 +132,7 @@ void UintColorToVector4( unsigned int color, Vector4& retColor );
  * @brief Converts a color packed inside a string into an ARGB Vector4 color.
  *
  * The string color could be in hexadecimal ( 0xFF0000FF ), webcolor ( #0000FF or #00F ) or some constant values:
- * black, white, red, green, blue, yellow, magenta, cyan, transparent.
+ * black, white, red, green, blue, yellow, magenta, cyan or transparent.
  *
  * @param[in] colorStr A color packed inside a string.
  * @param[in] length The length of the color string.
@@ -122,6 +140,35 @@ void UintColorToVector4( unsigned int color, Vector4& retColor );
  */
 void ColorStringToVector4( const char* const colorStr, Length length, Vector4& retColor );
 
+/**
+ * @brief Converts a color packed in a Vector4 into a string.
+ *
+ * Constant colors will be converted to the strings black, white, red, green, blue, yellow, magenta, cyan or transparent.
+ *
+ * If is not a constant color it will be converted to a string with hexadecimal ARGB content.
+ *
+ * @param[in] value The color value.
+ * @param[out] colorStr The string.
+ */
+void Vector4ToColorString( const Vector4& value, std::string& vector2Str );
+
+/**
+ * @brief Converts a two dimension vector packed inside a string into a Vector2.
+ *
+ * @param[in] vectorStr The two dimension vector packed inside a string.
+ * @param[in] length The length of the string.
+ * @param[out] vector2 The Vector2.
+ */
+void StringToVector2( const char* const vectorStr, Length length, Vector2& vector2 );
+
+/**
+ * @brief Converts a Vector2 into a string.
+ *
+ * @param[in] value The vector2 value.
+ * @param[out] vector2Str The string.
+ */
+void Vector2ToString( const Vector2& value, std::string& vector2Str );
+
 } // namespace Text
 
 } // namespace Toolkit
index 42b1050..2aa05e9 100644 (file)
@@ -79,27 +79,6 @@ void ParsePropertyString( const std::string& property, Property::Map& map )
   }
 }
 
-void StringOffsetToVector2( const std::string& offsetStr,
-                            Vector2& offset )
-{
-  offset = Vector2::ZERO;
-
-  unsigned int wsIndex = 0u;
-  for( std::string::const_iterator it = offsetStr.begin(),
-         endIt = offsetStr.end();
-       it != endIt;
-       ++it, ++wsIndex )
-  {
-    if( *it == ' ' )
-    {
-      break;
-    }
-  }
-
-  offset[0] = StringToFloat( offsetStr.c_str() );
-  offset[1] = StringToFloat( offsetStr.c_str() + wsIndex );
-}
-
 } //namespace Text
 
 } //namespace Toolkit
index b6ebf27..19d78b7 100644 (file)
@@ -56,16 +56,6 @@ void CreatePropertyMap( const TreeNode* const node, Property::Map& map );
  */
 void ParsePropertyString( const std::string& property, Property::Map& map );
 
-/**
- * @brief Converts an offset packed inside a string into a Vector2.
- *
- * @param[in] offsetStr The offset packed inside a string.
- * @param[out] offset The offset packed in a Vector2.
- *
- */
-void StringOffsetToVector2( const std::string& offsetStr,
-                            Vector2& offset );
-
 } //namespace Text
 
 } //namespace Toolkit
index f5346e0..ce5af88 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H__
-#define __DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H__
+#ifndef DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H
+#define DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
  *
  */
 
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/text/input-style.h>
-
 namespace Dali
 {
 
-class Actor;
-
 namespace Toolkit
 {
 
@@ -40,44 +35,15 @@ class ControlInterface
 public:
 
   /**
-   * @brief Constructor.
-   */
-  ControlInterface();
-
-  /**
    * @brief Virtual destructor.
    */
-  virtual ~ControlInterface();
-
-  /**
-   * @brief Add a decoration.
-   *
-   * @param[in] decoration The actor displaying a decoration.
-   * @param[in] needsClipping Whether the actor needs clipping.
-   */
-  virtual void AddDecoration( Actor& actor, bool needsClipping ) = 0;
+  virtual ~ControlInterface()
+  {}
 
   /**
    * @brief Called to request a text relayout.
    */
   virtual void RequestTextRelayout() = 0;
-
-  /**
-   * @brief Called to signal that text has been inserted or deleted.
-   */
-  virtual void TextChanged() = 0;
-
-  /**
-   * @brief Called when the number of characters to be inserted exceeds the maximum limit
-   */
-  virtual void MaxLengthReached() = 0;
-
-  /**
-   * @brief Called to signal that input style has been changed.
-   *
-   * @param[in] inputStyleMask Mask with the bits of the input style that has changed.
-   */
-  virtual void InputStyleChanged( InputStyle::Mask inputStyleMask ) = 0;
 };
 
 } // namespace Text
@@ -86,4 +52,4 @@ public:
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H__
+#endif // DALI_TOOLKIT_TEXT_CONTROL_INTERFACE_H
index 5769fac..7b3f2d6 100644 (file)
@@ -31,6 +31,7 @@
 #include <dali-toolkit/internal/text/multi-language-support.h>
 #include <dali-toolkit/internal/text/segmentation.h>
 #include <dali-toolkit/internal/text/shaper.h>
+#include <dali-toolkit/internal/text/text-control-interface.h>
 #include <dali-toolkit/internal/text/text-run-container.h>
 
 namespace
@@ -2749,7 +2750,10 @@ void Controller::Impl::ScrollTextToMatchCursor( const CursorInfo& cursorInfo )
 
 void Controller::Impl::RequestRelayout()
 {
-  mControlInterface.RequestTextRelayout();
+  if( NULL != mControlInterface )
+  {
+    mControlInterface->RequestTextRelayout();
+  }
 }
 
 } // namespace Text
index 9b17fa7..608ea7d 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_H__
-#define __DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_H__
+#ifndef DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_H
+#define DALI_TOOLKIT_TEXT_CONTROLLER_IMPL_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
@@ -26,6 +26,7 @@
 #include <dali-toolkit/internal/text/input-style.h>
 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
 #include <dali-toolkit/internal/text/logical-model-impl.h>
+#include <dali-toolkit/internal/text/text-scroller-data.h>
 #include <dali-toolkit/internal/text/text-controller.h>
 #include <dali-toolkit/internal/text/text-view.h>
 #include <dali-toolkit/internal/text/visual-model-impl.h>
@@ -285,8 +286,10 @@ struct OutlineDefaults
 
 struct Controller::Impl
 {
-  Impl( ControlInterface& controlInterface )
+  Impl( ControlInterface* controlInterface,
+        EditableControlInterface* editableControlInterface )
   : mControlInterface( controlInterface ),
+    mEditableControlInterface( editableControlInterface ),
     mLogicalModel(),
     mVisualModel(),
     mFontDefaults( NULL ),
@@ -295,6 +298,7 @@ struct Controller::Impl
     mEmbossDefaults( NULL ),
     mOutlineDefaults( NULL ),
     mEventData( NULL ),
+    mAutoScrollData( NULL ),
     mFontClient(),
     mClipboard(),
     mView(),
@@ -302,14 +306,14 @@ struct Controller::Impl
     mLayoutEngine(),
     mModifyEvents(),
     mTextColor( Color::BLACK ),
+    mScrollPosition(),
     mTextUpdateInfo(),
     mOperationsPending( NO_OPERATION ),
     mMaximumNumberOfCharacters( 50u ),
     mRecalculateNaturalSize( true ),
     mMarkupProcessorEnabled( false ),
     mClipboardHideEnabled( true ),
-    mAutoScrollEnabled( false ),
-    mAutoScrollDirectionRTL( false )
+    mIsAutoScrollEnabled( false )
   {
     mLogicalModel = LogicalModel::New();
     mVisualModel  = VisualModel::New();
@@ -336,10 +340,13 @@ struct Controller::Impl
     delete mEmbossDefaults;
     delete mOutlineDefaults;
     delete mEventData;
+    delete mAutoScrollData;
   }
 
+  // Text Controller Implementation.
+
   /**
-   * @brief Request a relayout using the ControlInterface.
+   * @copydoc Text::Controller::RequestRelayout()
    */
   void RequestRelayout();
 
@@ -686,7 +693,8 @@ private:
 
 public:
 
-  ControlInterface& mControlInterface;     ///< Reference to the text controller.
+  ControlInterface* mControlInterface;     ///< Reference to the text controller.
+  EditableControlInterface* mEditableControlInterface; ///< Reference to the editable text controller.
   LogicalModelPtr mLogicalModel;           ///< Pointer to the logical model.
   VisualModelPtr  mVisualModel;            ///< Pointer to the visual model.
   FontDefaults* mFontDefaults;             ///< Avoid allocating this when the user does not specify a font.
@@ -695,6 +703,7 @@ public:
   EmbossDefaults* mEmbossDefaults;         ///< Avoid allocating this when the user does not specify emboss parameters.
   OutlineDefaults* mOutlineDefaults;       ///< Avoid allocating this when the user does not specify outline parameters.
   EventData* mEventData;                   ///< Avoid allocating everything for text input until EnableTextInput().
+  ScrollerData* mAutoScrollData;           ///< Avoid allocating this when the user does not specify the auto text scrolling feature.
   TextAbstraction::FontClient mFontClient; ///< Handle to the font client.
   Clipboard mClipboard;                    ///< Handle to the system clipboard
   View mView;                              ///< The view interface to the rendering back-end.
@@ -713,10 +722,8 @@ public:
 
   bool mRecalculateNaturalSize:1;          ///< Whether the natural size needs to be recalculated.
   bool mMarkupProcessorEnabled:1;          ///< Whether the mark-up procesor is enabled.
-  bool mClipboardHideEnabled:1;            ///< Whether the ClipboardHide function work or not
-  bool mAutoScrollEnabled:1;               ///< Whether auto text scrolling is enabled.
-  CharacterDirection mAutoScrollDirectionRTL:1;  ///< Direction of auto scrolling, true if rtl
-
+  bool mClipboardHideEnabled:1;            ///< Whether the ClipboardHide function work or not.
+  bool mIsAutoScrollEnabled:1;             ///< Whether auto text scrolling is enabled.
 };
 
 } // namespace Text
@@ -725,4 +732,4 @@ public:
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_CONTROLLER_H__
+#endif // DALI_TOOLKIT_TEXT_CONTROLLER_H
index 6dfb99e..769d0e0 100644 (file)
@@ -31,6 +31,7 @@
 #include <dali-toolkit/internal/text/layouts/layout-parameters.h>
 #include <dali-toolkit/internal/text/markup-processor.h>
 #include <dali-toolkit/internal/text/text-controller-impl.h>
+#include <dali-toolkit/internal/text/text-editable-control-interface.h>
 
 namespace
 {
@@ -100,11 +101,28 @@ FontDescriptionRun& UpdateSelectionFontStyleRun( EventData* eventData,
 
 // public : Constructor.
 
-ControllerPtr Controller::New( ControlInterface& controlInterface )
+ControllerPtr Controller::New()
+{
+  return ControllerPtr( new Controller() );
+}
+
+ControllerPtr Controller::New( ControlInterface* controlInterface )
 {
   return ControllerPtr( new Controller( controlInterface ) );
 }
 
+ControllerPtr Controller::New( ControlInterface* controlInterface,
+                               EditableControlInterface* editableControlInterface )
+{
+  return ControllerPtr( new Controller( controlInterface,
+                                        editableControlInterface ) );
+}
+
+void Controller::SetTextControlInterface( ControlInterface* controlInterface )
+{
+  mImpl->mControlInterface = controlInterface;
+}
+
 // public : Configure the text controller.
 
 void Controller::EnableTextInput( DecoratorPtr decorator )
@@ -140,9 +158,9 @@ void Controller::SetAutoScrollEnabled( bool enable )
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled[%s] SingleBox[%s]-> [%p]\n", (enable)?"true":"false", ( mImpl->mLayoutEngine.GetLayout() == LayoutEngine::SINGLE_LINE_BOX)?"true":"false", this );
 
-  if ( mImpl->mLayoutEngine.GetLayout() == LayoutEngine::SINGLE_LINE_BOX )
+  if( mImpl->mLayoutEngine.GetLayout() == LayoutEngine::SINGLE_LINE_BOX )
   {
-    if ( enable )
+    if( enable )
     {
       DALI_LOG_INFO( gLogFilter, Debug::General, "Controller::SetAutoScrollEnabled for SINGLE_LINE_BOX\n" );
       mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending |
@@ -152,6 +170,10 @@ void Controller::SetAutoScrollEnabled( bool enable )
                                                                UPDATE_DIRECTION          |
                                                                REORDER );
 
+      if( NULL == mImpl->mAutoScrollData )
+      {
+        mImpl->mAutoScrollData = new ScrollerData();
+      }
     }
     else
     {
@@ -163,39 +185,104 @@ void Controller::SetAutoScrollEnabled( bool enable )
                                                                REORDER );
     }
 
-    mImpl->mAutoScrollEnabled = enable;
+    mImpl->mIsAutoScrollEnabled = enable;
     mImpl->RequestRelayout();
   }
   else
   {
     DALI_LOG_WARNING( "Attempted AutoScrolling on a non SINGLE_LINE_BOX, request ignored\n" );
-    mImpl->mAutoScrollEnabled = false;
+    mImpl->mIsAutoScrollEnabled = false;
   }
 }
 
 bool Controller::IsAutoScrollEnabled() const
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::IsAutoScrollEnabled[%s]\n", (mImpl->mAutoScrollEnabled)?"true":"false" );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Controller::IsAutoScrollEnabled[%s]\n", mImpl->mIsAutoScrollEnabled?"true":"false" );
+
+  return mImpl->mIsAutoScrollEnabled;
+}
+
+void Controller::SetAutoscrollSpeed( int scrollSpeed )
+{
+  if( NULL == mImpl->mAutoScrollData )
+  {
+    mImpl->mAutoScrollData = new ScrollerData();
+  }
+
+  mImpl->mAutoScrollData->mScrollSpeed = scrollSpeed;
+}
+
+int Controller::GetAutoScrollSpeed() const
+{
+  if( NULL != mImpl->mAutoScrollData )
+  {
+    return mImpl->mAutoScrollData->mScrollSpeed;
+  }
+
+  return 0;
+}
+
+void Controller::SetAutoScrollLoopCount( int loopCount )
+{
+  if( NULL == mImpl->mAutoScrollData )
+  {
+    mImpl->mAutoScrollData = new ScrollerData();
+  }
+
+  mImpl->mAutoScrollData->mLoopCount = loopCount;
+}
+
+int Controller::GetAutoScrollLoopCount() const
+{
+  if( NULL != mImpl->mAutoScrollData )
+  {
+    return mImpl->mAutoScrollData->mLoopCount;
+  }
 
-  return mImpl->mAutoScrollEnabled;
+  return 0;
 }
 
-CharacterDirection Controller::GetAutoScrollDirection() const
+void Controller::SetAutoScrollWrapGap( float wrapGap )
 {
-  return mImpl->mAutoScrollDirectionRTL;
+  if( NULL == mImpl->mAutoScrollData )
+  {
+    mImpl->mAutoScrollData = new ScrollerData();
+  }
+
+  mImpl->mAutoScrollData->mWrapGap = wrapGap;
 }
 
-float Controller::GetAutoScrollLineAlignment() const
+float Controller::GetAutoScrollWrapGap() const
 {
-  float offset = 0.f;
+  if( NULL != mImpl->mAutoScrollData )
+  {
+    return mImpl->mAutoScrollData->mWrapGap;
+  }
+
+  return 0.f;
+}
 
-  if( mImpl->mVisualModel &&
-      ( 0u != mImpl->mVisualModel->mLines.Count() ) )
+const ScrollerData* const Controller::GetAutoScrollData()
+{
+  if( NULL != mImpl->mAutoScrollData )
   {
-    offset = ( *mImpl->mVisualModel->mLines.Begin() ).alignmentOffset;
+    // Need to update the data with the latest layout.
+    if( mImpl->mVisualModel )
+    {
+      mImpl->mAutoScrollData->mControlSize = mImpl->mVisualModel->mControlSize;
+      mImpl->mAutoScrollData->mOffscreenSize = GetNaturalSize().GetVectorXY();
+
+      mImpl->mAutoScrollData->mAlignmentOffset = 0.f;
+      if( 0u != mImpl->mVisualModel->mLines.Count() )
+      {
+        mImpl->mAutoScrollData->mAlignmentOffset = ( *mImpl->mVisualModel->mLines.Begin() ).alignmentOffset;
+      }
+    }
+
+    return mImpl->mAutoScrollData;
   }
 
-  return offset;
+  return NULL;
 }
 
 void Controller::SetHorizontalScrollEnabled( bool enable )
@@ -460,8 +547,11 @@ void Controller::SetText( const std::string& text )
     mImpl->mEventData->mEventQueue.clear();
   }
 
-  // Do this last since it provides callbacks into application code
-  mImpl->mControlInterface.TextChanged();
+  // Do this last since it provides callbacks into application code.
+  if( NULL != mImpl->mEditableControlInterface )
+  {
+    mImpl->mEditableControlInterface->TextChanged();
+  }
 }
 
 void Controller::GetText( std::string& text ) const
@@ -742,26 +832,6 @@ const Vector4& Controller::GetShadowColor() const
   return mImpl->mVisualModel->GetShadowColor();
 }
 
-void Controller::SetDefaultShadowProperties( const std::string& shadowProperties )
-{
-  if( NULL == mImpl->mShadowDefaults )
-  {
-    mImpl->mShadowDefaults = new ShadowDefaults();
-  }
-
-  mImpl->mShadowDefaults->properties = shadowProperties;
-}
-
-const std::string& Controller::GetDefaultShadowProperties() const
-{
-  if( NULL != mImpl->mShadowDefaults )
-  {
-    return mImpl->mShadowDefaults->properties;
-  }
-
-  return EMPTY_STRING;
-}
-
 void Controller::SetUnderlineColor( const Vector4& color )
 {
   mImpl->mVisualModel->SetUnderlineColor( color );
@@ -798,26 +868,6 @@ float Controller::GetUnderlineHeight() const
   return mImpl->mVisualModel->GetUnderlineHeight();
 }
 
-void Controller::SetDefaultUnderlineProperties( const std::string& underlineProperties )
-{
-  if( NULL == mImpl->mUnderlineDefaults )
-  {
-    mImpl->mUnderlineDefaults = new UnderlineDefaults();
-  }
-
-  mImpl->mUnderlineDefaults->properties = underlineProperties;
-}
-
-const std::string& Controller::GetDefaultUnderlineProperties() const
-{
-  if( NULL != mImpl->mUnderlineDefaults )
-  {
-    return mImpl->mUnderlineDefaults->properties;
-  }
-
-  return EMPTY_STRING;
-}
-
 void Controller::SetDefaultEmbossProperties( const std::string& embossProperties )
 {
   if( NULL == mImpl->mEmbossDefaults )
@@ -1262,7 +1312,7 @@ const std::string& Controller::GetInputShadowProperties() const
     return mImpl->mEventData->mInputStyle.shadowProperties;
   }
 
-  return GetDefaultShadowProperties();
+  return EMPTY_STRING;
 }
 
 void Controller::SetInputUnderlineProperties( const std::string& underlineProperties )
@@ -1280,7 +1330,7 @@ const std::string& Controller::GetInputUnderlineProperties() const
     return mImpl->mEventData->mInputStyle.underlineProperties;
   }
 
-  return GetDefaultUnderlineProperties();
+  return EMPTY_STRING;
 }
 
 void Controller::SetInputEmbossProperties( const std::string& embossProperties )
@@ -1477,7 +1527,7 @@ float Controller::GetHeightForWidth( float width )
 
 Controller::UpdateTextType Controller::Relayout( const Size& size )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->Controller::Relayout %p size %f,%f, autoScroll[%s]\n", this, size.width, size.height, (mImpl->mAutoScrollEnabled)?"true":"false"  );
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->Controller::Relayout %p size %f,%f, autoScroll[%s]\n", this, size.width, size.height, mImpl->mIsAutoScrollEnabled ?"true":"false"  );
 
   UpdateTextType updateTextType = NONE_UPDATED;
 
@@ -1583,6 +1633,11 @@ Controller::UpdateTextType Controller::Relayout( const Size& size )
   return updateTextType;
 }
 
+void Controller::RequestRelayout()
+{
+  mImpl->RequestRelayout();
+}
+
 // public : Input style change signals.
 
 bool Controller::IsInputStyleChangedSignalsQueueEmpty()
@@ -1605,8 +1660,11 @@ void Controller::ProcessInputStyleChangedSignals()
   {
     const InputStyle::Mask mask = *it;
 
-    // Emit the input style changed signal.
-    mImpl->mControlInterface.InputStyleChanged( mask );
+    if( NULL != mImpl->mEditableControlInterface )
+    {
+      // Emit the input style changed signal.
+      mImpl->mEditableControlInterface->InputStyleChanged( mask );
+    }
   }
 
   mImpl->mEventData->mInputStyleChangedQueue.Clear();
@@ -1731,10 +1789,11 @@ bool Controller::KeyEvent( const Dali::KeyEvent& keyEvent )
     mImpl->RequestRelayout();
   }
 
-  if( textChanged )
+  if( textChanged &&
+      ( NULL != mImpl->mEditableControlInterface ) )
   {
     // Do this last since it provides callbacks into application code
-    mImpl->mControlInterface.TextChanged();
+    mImpl->mEditableControlInterface->TextChanged();
   }
 
   return true;
@@ -1965,10 +2024,11 @@ ImfManager::ImfCallbackData Controller::OnImfEvent( ImfManager& imfManager, cons
 
   ImfManager::ImfCallbackData callbackData( ( retrieveText || retrieveCursor ), cursorPosition, text, false );
 
-  if( requestRelayout )
+  if( requestRelayout &&
+      ( NULL != mImpl->mEditableControlInterface ) )
   {
     // Do this last since it provides callbacks into application code
-    mImpl->mControlInterface.TextChanged();
+    mImpl->mEditableControlInterface->TextChanged();
   }
 
   return callbackData;
@@ -2001,7 +2061,10 @@ void Controller::GetTargetSize( Vector2& targetSize )
 
 void Controller::AddDecoration( Actor& actor, bool needsClipping )
 {
-  mImpl->mControlInterface.AddDecoration( actor, needsClipping );
+  if( NULL != mImpl->mEditableControlInterface )
+  {
+    mImpl->mEditableControlInterface->AddDecoration( actor, needsClipping );
+  }
 }
 
 void Controller::DecorationEvent( HandleType handleType, HandleState state, float x, float y )
@@ -2088,7 +2151,11 @@ void Controller::TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Butt
       mImpl->mEventData->mScrollAfterDelete = true;
 
       mImpl->RequestRelayout();
-      mImpl->mControlInterface.TextChanged();
+
+      if( NULL != mImpl->mEditableControlInterface )
+      {
+        mImpl->mEditableControlInterface->TextChanged();
+      }
       break;
     }
     case Toolkit::TextSelectionPopup::COPY:
@@ -2135,6 +2202,17 @@ void Controller::TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Butt
   }
 }
 
+// private : Inherit from TextScroller.
+
+void Controller::ScrollingFinished()
+{
+  // Pure Virtual from TextScroller Interface
+  SetAutoScrollEnabled( false );
+  GetLayoutEngine().SetTextEllipsisEnabled( true );
+
+  mImpl->RequestRelayout();
+}
+
 // private : Update.
 
 void Controller::InsertText( const std::string& text, Controller::InsertType type )
@@ -2375,8 +2453,11 @@ void Controller::InsertText( const std::string& text, Controller::InsertType typ
 
     mImpl->ResetImfManager();
 
-    // Do this last since it provides callbacks into application code
-    mImpl->mControlInterface.MaxLengthReached();
+    if( NULL != mImpl->mEditableControlInterface )
+    {
+      // Do this last since it provides callbacks into application code
+      mImpl->mEditableControlInterface->MaxLengthReached();
+    }
   }
 }
 
@@ -2386,8 +2467,11 @@ void Controller::PasteText( const std::string& stringToPaste )
   mImpl->ChangeState( EventData::EDITING );
   mImpl->RequestRelayout();
 
-  // Do this last since it provides callbacks into application code
-  mImpl->mControlInterface.TextChanged();
+  if( NULL != mImpl->mEditableControlInterface )
+  {
+    // Do this last since it provides callbacks into application code
+    mImpl->mEditableControlInterface->TextChanged();
+  }
 }
 
 bool Controller::RemoveText( int cursorOffset,
@@ -2594,7 +2678,10 @@ bool Controller::DoRelayout( const Size& size,
 
       if ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) )
       {
-        mImpl->mAutoScrollDirectionRTL = false;
+        if( NULL != mImpl->mAutoScrollData )
+        {
+          mImpl->mAutoScrollData->mAutoScrollDirectionRTL = false;
+        }
       }
 
       // Reorder the lines
@@ -2630,9 +2717,11 @@ bool Controller::DoRelayout( const Size& size,
           if ( ( NO_OPERATION != ( UPDATE_DIRECTION & operations ) ) && ( numberOfLines > 0 ) )
           {
             const LineRun* const firstline = mImpl->mVisualModel->mLines.Begin();
-            if ( firstline )
+            if( firstline &&
+                mImpl->mIsAutoScrollEnabled &&
+                ( NULL != mImpl->mAutoScrollData ) )
             {
-              mImpl->mAutoScrollDirectionRTL = firstline->direction;
+              mImpl->mAutoScrollData->mAutoScrollDirectionRTL = firstline->direction;
             }
           }
         }
@@ -2664,7 +2753,7 @@ bool Controller::DoRelayout( const Size& size,
 #if defined(DEBUG_ENABLED)
   std::string currentText;
   GetText( currentText );
-  DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::DoRelayout [%p] mImpl->mAutoScrollDirectionRTL[%s] [%s]\n", this, (mImpl->mAutoScrollDirectionRTL)?"true":"false",  currentText.c_str() );
+  DALI_LOG_INFO( gLogFilter, Debug::Concise, "Controller::DoRelayout [%p] mImpl->mAutoScrollDirectionRTL[%s] [%s]\n", this, ( ( NULL != mImpl->mAutoScrollData ) && mImpl->mAutoScrollData->mAutoScrollDirectionRTL)?"true":"false",  currentText.c_str() );
 #endif
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "<--Controller::DoRelayout, view updated %s\n", ( viewUpdated ? "true" : "false" ) );
   return viewUpdated;
@@ -3011,10 +3100,22 @@ void Controller::ResetScrollPosition()
 
 // private : Private contructors & copy operator.
 
-Controller::Controller( ControlInterface& controlInterface )
+Controller::Controller()
 : mImpl( NULL )
 {
-  mImpl = new Controller::Impl( controlInterface );
+  mImpl = new Controller::Impl( NULL, NULL );
+}
+
+Controller::Controller( ControlInterface* controlInterface )
+{
+  mImpl = new Controller::Impl( controlInterface, NULL );
+}
+
+Controller::Controller( ControlInterface* controlInterface,
+                        EditableControlInterface* editableControlInterface )
+{
+  mImpl = new Controller::Impl( controlInterface,
+                                editableControlInterface );
 }
 
 // The copy constructor and operator are left unimplemented.
index 07e1665..ce5c51a 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef __DALI_TOOLKIT_TEXT_CONTROLLER_H__
-#define __DALI_TOOLKIT_TEXT_CONTROLLER_H__
+#ifndef DALI_TOOLKIT_TEXT_CONTROLLER_H
+#define DALI_TOOLKIT_TEXT_CONTROLLER_H
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
@@ -26,7 +26,7 @@
 #include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup-callback-interface.h>
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/layouts/layout-engine.h>
-#include <dali-toolkit/internal/text/text-control-interface.h>
+#include <dali-toolkit/internal/text/text-scroller-interface.h>
 
 namespace Dali
 {
@@ -38,10 +38,12 @@ namespace Text
 {
 
 class Controller;
+class ControlInterface;
+class EditableControlInterface;
 class View;
+struct ScrollerData;
 
 typedef IntrusivePtr<Controller> ControllerPtr;
-typedef Dali::Toolkit::Text::ControlInterface ControlInterface;
 
 /**
  * @brief A Text Controller is used by UI Controls which display text.
@@ -54,7 +56,7 @@ typedef Dali::Toolkit::Text::ControlInterface ControlInterface;
  *
  * The text selection popup button callbacks are as well handled via the TextSelectionPopupCallbackInterface interface.
  */
-class Controller : public RefObject, public Decorator::ControllerInterface, public TextSelectionPopupCallbackInterface
+class Controller : public RefObject, public Decorator::ControllerInterface, public TextSelectionPopupCallbackInterface, public Text::ScrollerInterface
 {
 public: // Enumerated types.
 
@@ -123,10 +125,36 @@ public: // Constructor.
   /**
    * @brief Create a new instance of a Controller.
    *
-   * @param[in] controlInterface An interface used to request a text relayout.
    * @return A pointer to a new Controller.
    */
-  static ControllerPtr New( ControlInterface& controlInterface );
+  static ControllerPtr New();
+
+  /**
+   * @brief Create a new instance of a Controller.
+   *
+   * @param[in] controlInterface The control's interface.
+   *
+   * @return A pointer to a new Controller.
+   */
+  static ControllerPtr New( ControlInterface* controlInterface );
+
+  /**
+   * @brief Create a new instance of a Controller.
+   *
+   * @param[in] controlInterface The control's interface.
+   * @param[in] editableControlInterface The editable control's interface.
+   *
+   * @return A pointer to a new Controller.
+   */
+  static ControllerPtr New( ControlInterface* controlInterface,
+                            EditableControlInterface* editableControlInterface );
+
+  /**
+   * @brief Sets the text-control interface.
+   *
+   * @param[in] controlInterface The text-control interface.
+   */
+  void SetTextControlInterface( ControlInterface* controlInterface );
 
 public: // Configure the text controller.
 
@@ -182,17 +210,53 @@ public: // Configure the text controller.
   bool IsAutoScrollEnabled() const;
 
   /**
-   * @brief Get direction of the text from the first line of text,
-   * @return bool rtl (right to left) is true
+   * @brief Sets the speed the text should automatically scroll at.
+   *
+   * @param[in] scrollSpeed The speed of scrolling in pixels per second.
+   */
+  void SetAutoscrollSpeed( int scrollSpeed );
+
+  /**
+   * @brief Retrieves the auto scroll speed.
+   *
+   * @return The auto scroll speed in pixels per second.
+   */
+  int GetAutoScrollSpeed() const;
+
+  /**
+   * @brief Sets the number of loops the text should scroll.
+   *
+   * @param[in] loopCount The number of loops.
+   */
+  void SetAutoScrollLoopCount( int loopCount );
+
+  /**
+   * @brief Retrieves the number of loops the text should scroll.
+   *
+   * @return The numebr of loops.
+   */
+  int GetAutoScrollLoopCount() const;
+
+  /**
+   * @brief Sets the gap before text wraps around when scrolling.
+   *
+   * @param[in] wrapGap The gap in pixels.
+   */
+  void SetAutoScrollWrapGap( float wrapGap );
+
+  /**
+   * @brief Retrieves the gap before text wraps around when scrolling.
+   *
+   * @return The gap in pixels.
    */
-  CharacterDirection GetAutoScrollDirection() const;
+  float GetAutoScrollWrapGap() const;
 
   /**
-   * @brief Get the alignment offset of the first line of text.
+   * @brief Retrieves the text's autoscroll data.
    *
-   * @return The alignment offset.
+   * @return The text's autoscroll data.
    */
-  float GetAutoScrollLineAlignment() const;
+  const ScrollerData* const GetAutoScrollData();
 
   /**
    * @brief Enables the horizontal scrolling.
@@ -480,22 +544,6 @@ public: // Default style & Input style
   const Vector4& GetShadowColor() const;
 
   /**
-   * @brief Sets the shadow's properties string.
-   *
-   * @note The string is stored to be recovered.
-   *
-   * @param[in] shadowProperties The shadow's properties string.
-   */
-  void SetDefaultShadowProperties( const std::string& shadowProperties );
-
-  /**
-   * @brief Retrieves the shadow's properties string.
-   *
-   * @return The shadow's properties string.
-   */
-  const std::string& GetDefaultShadowProperties() const;
-
-  /**
    * @brief Set the underline color.
    *
    * @param[in] color color of underline.
@@ -538,22 +586,6 @@ public: // Default style & Input style
   float GetUnderlineHeight() const;
 
   /**
-   * @brief Sets the underline's properties string.
-   *
-   * @note The string is stored to be recovered.
-   *
-   * @param[in] underlineProperties The underline's properties string.
-   */
-  void SetDefaultUnderlineProperties( const std::string& underlineProperties );
-
-  /**
-   * @brief Retrieves the underline's properties string.
-   *
-   * @return The underline's properties string.
-   */
-  const std::string& GetDefaultUnderlineProperties() const;
-
-  /**
    * @brief Sets the emboss's properties string.
    *
    * @note The string is stored to be recovered.
@@ -821,6 +853,11 @@ public: // Relayout.
    */
   UpdateTextType Relayout( const Size& size );
 
+  /**
+   * @brief Request a relayout using the ControlInterface.
+   */
+  void RequestRelayout();
+
 public: // Input style change signals.
 
   /**
@@ -919,6 +956,13 @@ protected: // Inherit from TextSelectionPopup::TextPopupButtonCallbackInterface.
    */
   virtual void TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::Buttons button );
 
+private: // Inherit from TextScroller
+
+  /**
+   * @copydoc Text::ScrollerInterface::ScrollingFinished()
+   */
+  virtual void ScrollingFinished();
+
 private: // Update.
 
   /**
@@ -1058,7 +1102,18 @@ private: // Private contructors & copy operator.
   /**
    * @brief Private constructor.
    */
-  Controller( ControlInterface& controlInterface );
+  Controller();
+
+  /**
+   * @brief Private constructor.
+   */
+  Controller( ControlInterface* controlInterface );
+
+  /**
+   * @brief Private constructor.
+   */
+  Controller( ControlInterface* controlInterface,
+              EditableControlInterface* editableControlInterface );
 
   // Undefined
   Controller( const Controller& handle );
@@ -1085,4 +1140,4 @@ private:
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_CONTROLLER_H__
+#endif // DALI_TOOLKIT_TEXT_CONTROLLER_H
diff --git a/dali-toolkit/internal/text/text-editable-control-interface.h b/dali-toolkit/internal/text/text-editable-control-interface.h
new file mode 100644 (file)
index 0000000..e54704c
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef DALI_TOOLKIT_TEXT_EDITABLE_CONTROL_INTERFACE_H
+#define DALI_TOOLKIT_TEXT_EDITABLE_CONTROL_INTERFACE_H
+
+/*
+ * Copyright (c) 2016 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/input-style.h>
+
+namespace Dali
+{
+
+class Actor;
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief An interface that the Text::Controller uses to notify about text changes and add decoration to the text control.
+ */
+class EditableControlInterface
+{
+public:
+
+  /**
+   * @brief Virtual destructor.
+   */
+  virtual ~EditableControlInterface()
+  {}
+
+  /**
+   * @brief Called to signal that text has been inserted or deleted.
+   */
+  virtual void TextChanged() = 0;
+
+  /**
+   * @brief Called when the number of characters to be inserted exceeds the maximum limit
+   */
+  virtual void MaxLengthReached() = 0;
+
+  /**
+   * @brief Called to signal that input style has been changed.
+   *
+   * @param[in] inputStyleMask Mask with the bits of the input style that has changed.
+   */
+  virtual void InputStyleChanged( InputStyle::Mask inputStyleMask ) = 0;
+
+  /**
+   * @brief Add a decoration.
+   *
+   * @param[in] decoration The actor displaying a decoration.
+   * @param[in] needsClipping Whether the actor needs clipping.
+   */
+  virtual void AddDecoration( Actor& actor, bool needsClipping ) = 0;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_EDITABLE_CONTROL_INTERFACE_H
index 31580a2..083cf47 100644 (file)
@@ -35,72 +35,137 @@ namespace
 {
 const std::string COLOR_KEY( "color" );
 const std::string OFFSET_KEY( "offset" );
-const std::string THICKNESS_KEY( "thickness" );
+const std::string HEIGHT_KEY( "height" );
+const std::string ENABLE_KEY( "enable" );
+const std::string TRUE_TOKEN( "true" );
 }
 
-bool SetUnderlineProperties( ControllerPtr controller, const Property::Value& value, EffectStyle::Type type )
+bool ParseProperties( const std::string& shadowProperties,
+                      bool& colorDefined,
+                      Vector4& color,
+                      bool& offsetDefined,
+                      Vector2& offset )
 {
-  bool update = false;
+  // Parses and applies the style.
+  Property::Map map;
+  Text::ParsePropertyString( shadowProperties, map );
 
-  if( controller )
+  const bool empty = map.Empty();
+
+  if( !empty )
   {
-    const std::string properties = value.Get< std::string >();
+    /// Color key.
+    Property::Value* colorValue = map.Find( COLOR_KEY );
 
-    switch( type )
+    colorDefined = colorValue != NULL;
+    if( colorDefined )
     {
-      case EffectStyle::DEFAULT:
-      {
-        // Stores the default underline's properties string to be recovered by the GetUnderlineProperties() function.
-        controller->SetDefaultUnderlineProperties( properties );
-        break;
-      }
-      case EffectStyle::INPUT:
-      {
-        // Stores the input underline's properties string to be recovered by the GetUnderlineProperties() function.
-        controller->SetInputUnderlineProperties( properties );
-        break;
-      }
+      const std::string colorStr = colorValue->Get<std::string>();
+
+      Text::ColorStringToVector4( colorStr.c_str(), colorStr.size(), color );
     }
 
-    // Parses and applies the style.
-    Property::Map map;
-    ParsePropertyString( properties, map );
+    /// Offset key.
+    Property::Value* offsetValue = map.Find( OFFSET_KEY );
 
-    if( !map.Empty() )
+    offsetDefined = offsetValue != NULL;
+    if( offsetDefined )
     {
-      /// Color key
-      Property::Value* colorValue = map.Find( COLOR_KEY );
+      const std::string offsetStr = offsetValue->Get<std::string>();
 
-      Vector4 color;
-      const bool colorDefined = colorValue != NULL;
-      if( colorDefined )
-      {
-        const std::string colorStr = colorValue->Get<std::string>();
+      StringToVector2( offsetStr.c_str(), offsetStr.size(), offset );
+    }
+  }
 
-        ColorStringToVector4( colorStr.c_str(), colorStr.size(), color );
-      }
+  return empty;
+}
+
+bool ParseProperties( const std::string& underlineProperties,
+                      bool& enabled,
+                      bool& colorDefined,
+                      Vector4& color,
+                      bool& heightDefined,
+                      float& height )
+{
+  // Parses and applies the style.
+  Property::Map map;
+  Text::ParsePropertyString( underlineProperties, map );
 
-      /// Thickness key
-      Property::Value* thicknessValue = map.Find( THICKNESS_KEY );
+  const bool empty = map.Empty();
 
-      float thickness = 0.f;
-      const bool thicknessDefined = thicknessValue != NULL;
-      if( thicknessDefined )
-      {
-        const std::string thicknessStr = thicknessValue->Get<std::string>();
+  if( !empty )
+  {
+    /// Enable key.
+    Property::Value* enableValue = map.Find( ENABLE_KEY );
 
-        thickness = StringToFloat( thicknessStr.c_str() );
-      }
+    enabled = false;
+    const bool enabledDefined = enableValue != NULL;
+    if( enabledDefined )
+    {
+      const std::string enableStr = enableValue->Get<std::string>();
+      enabled = Text::TokenComparison( TRUE_TOKEN, enableStr.c_str(), enableStr.size() );
+    }
+
+    /// Color key.
+    Property::Value* colorValue = map.Find( COLOR_KEY );
 
+    colorDefined = colorValue != NULL;
+    if( colorDefined )
+    {
+      const std::string colorStr = colorValue->Get<std::string>();
+
+      Text::ColorStringToVector4( colorStr.c_str(), colorStr.size(), color );
+    }
+
+    /// Height key.
+    Property::Value* heightValue = map.Find( HEIGHT_KEY );
+
+    height = 0.f;
+    heightDefined = heightValue != NULL;
+    if( heightDefined )
+    {
+      const std::string heightStr = heightValue->Get<std::string>();
+
+      height = StringToFloat( heightStr.c_str() );
+    }
+  }
+
+  return empty;
+}
+
+bool SetUnderlineProperties( ControllerPtr controller, const Property::Value& value, EffectStyle::Type type )
+{
+  bool update = false;
+
+  if( controller )
+  {
+    const std::string properties = value.Get<std::string>();
+
+    bool enabled = false;
+    bool colorDefined = false;
+    Vector4 color;
+    bool heightDefined = false;
+    float height = 0.f;
+
+    const bool empty = ParseProperties( properties,
+                                        enabled,
+                                        colorDefined,
+                                        color,
+                                        heightDefined,
+                                        height );
+
+    if( !empty )
+    {
       switch( type )
       {
         case EffectStyle::DEFAULT:
         {
-          if( !controller->IsUnderlineEnabled() )
+          if( enabled != controller->IsUnderlineEnabled() )
           {
-            controller->SetUnderlineEnabled( true );
+            controller->SetUnderlineEnabled( enabled );
             update = true;
           }
+
           // Sets the default underline values.
           if( colorDefined && ( controller->GetUnderlineColor() != color ) )
           {
@@ -108,9 +173,9 @@ bool SetUnderlineProperties( ControllerPtr controller, const Property::Value& va
             update = true;
           }
 
-          if( thicknessDefined &&  fabsf( controller->GetUnderlineHeight() - thickness ) > Math::MACHINE_EPSILON_1000 )
+          if( heightDefined && ( fabsf( controller->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 ) )
           {
-            controller->SetUnderlineHeight( thickness );
+            controller->SetUnderlineHeight( height );
             update = true;
           }
           break;
@@ -125,11 +190,25 @@ bool SetUnderlineProperties( ControllerPtr controller, const Property::Value& va
     }
     else
     {
-      // Disable underline.
-      if( controller->IsUnderlineEnabled() )
+      switch( type )
       {
-        controller->SetUnderlineEnabled( false );
-        update = true;
+        case EffectStyle::DEFAULT:
+        {
+          // Disable underline.
+          if( controller->IsUnderlineEnabled() )
+          {
+            controller->SetUnderlineEnabled( false );
+            update = true;
+          }
+          break;
+        }
+        case EffectStyle::INPUT:
+        {
+          // Sets the input underline values.
+          // TODO: to be implemented.
+          controller->SetInputUnderlineProperties( properties );
+          break;
+        }
       }
     }
   }
@@ -145,7 +224,23 @@ void GetUnderlineProperties( ControllerPtr controller, Property::Value& value, E
     {
       case EffectStyle::DEFAULT:
       {
-        value = controller->GetDefaultUnderlineProperties();
+        const bool enabled = controller->IsUnderlineEnabled();
+        const Vector4& color = controller->GetUnderlineColor();
+        const float height = controller->GetUnderlineHeight();
+
+        std::string underlineProperties = "{\"enable\":";
+        const std::string enabledStr = enabled ? "true" : "false";
+        underlineProperties += "\"" + enabledStr + "\",";
+
+        std::string colorStr;
+        Vector4ToColorString( color, colorStr );
+        underlineProperties += "\"color\":\"" + colorStr + "\",";
+
+        std::string heightStr;
+        FloatToString( height, heightStr );
+        underlineProperties += "\"height\":\"" + heightStr + "\"}";
+
+        value = underlineProperties;
         break;
       }
       case EffectStyle::INPUT:
@@ -165,52 +260,19 @@ bool SetShadowProperties( ControllerPtr controller, const Property::Value& value
   {
     const std::string properties = value.Get< std::string >();
 
-    switch( type )
-    {
-      case EffectStyle::DEFAULT:
-      {
-        // Stores the default shadow's properties string to be recovered by the GetShadowProperties() function.
-        controller->SetDefaultShadowProperties( properties );
-        break;
-      }
-      case EffectStyle::INPUT:
-      {
-        // Stores the input shadow's properties string to be recovered by the GetShadowProperties() function.
-        controller->SetInputShadowProperties( properties );
-        break;
-      }
-    }
+    bool colorDefined = false;
+    Vector4 color;
+    bool offsetDefined = false;
+    Vector2 offset;
 
-    // Parses and applies the style.
-    Property::Map map;
-    ParsePropertyString( properties, map );
+    const bool empty = ParseProperties( properties,
+                                        colorDefined,
+                                        color,
+                                        offsetDefined,
+                                        offset );
 
-    if( !map.Empty() )
+    if( !empty )
     {
-      /// Color key
-      Property::Value* colorValue = map.Find( COLOR_KEY );
-
-      Vector4 color;
-      const bool colorDefined = colorValue != NULL;
-      if( colorDefined )
-      {
-        const std::string colorStr = colorValue->Get<std::string>();
-
-        ColorStringToVector4( colorStr.c_str(), colorStr.size(), color );
-      }
-
-      /// Offset key
-      Property::Value* offsetValue = map.Find( OFFSET_KEY );
-
-      Vector2 offset;
-      const bool offsetDefined = offsetValue != NULL;
-      if( offsetDefined )
-      {
-        const std::string offsetStr = offsetValue->Get<std::string>();
-
-        StringOffsetToVector2( offsetStr, offset );
-      }
-
       switch( type )
       {
         case EffectStyle::DEFAULT:
@@ -237,6 +299,28 @@ bool SetShadowProperties( ControllerPtr controller, const Property::Value& value
         }
       }
     }
+    else
+    {
+      switch( type )
+      {
+        case EffectStyle::DEFAULT:
+        {
+          // Disable shadow.
+          if( Vector2::ZERO != controller->GetShadowOffset() )
+          {
+            controller->SetShadowOffset( Vector2::ZERO );
+          }
+          break;
+        }
+        case EffectStyle::INPUT:
+        {
+          // Sets the input shadow values.
+          // TODO: to be implemented.
+          controller->SetInputShadowProperties( properties );
+          break;
+        }
+      }
+    }
   }
 
   return update;
@@ -250,7 +334,20 @@ void GetShadowProperties( ControllerPtr controller, Property::Value& value, Effe
     {
       case EffectStyle::DEFAULT:
       {
-        value = controller->GetDefaultShadowProperties();
+        const Vector4& color = controller->GetShadowColor();
+        const Vector2& offset = controller->GetShadowOffset();
+
+        std::string shadowProperties = "{";
+
+        std::string colorStr;
+        Vector4ToColorString( color, colorStr );
+        shadowProperties += "\"color\":\"" + colorStr + "\",";
+
+        std::string offsetStr;
+        Vector2ToString( offset, offsetStr );
+        shadowProperties += "\"offset\":\"" + offsetStr + "\"}";
+
+        value = shadowProperties;
         break;
       }
       case EffectStyle::INPUT:
index 9feb75c..fb21fe9 100644 (file)
  *
  */
 
-// EXTERNAL INCLUDES
-#include <dali/devel-api/scripting/scripting.h>
-
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/text-controller.h>
-#include <dali-toolkit/internal/text/text-definitions.h>
 
 namespace Dali
 {
@@ -44,6 +40,36 @@ namespace EffectStyle
 };
 
 /**
+ * @brief Parses the shadow properties.
+ *
+ * @param[out] colorDefined Whether the shadow's color is defined.
+ * @param[out] color The shadow's color.
+ * @param[out] offsetDefined Whether the shadow's offset is defined.
+ * @param[out] offset The shadow's offset.
+ */
+bool ParseProperties( const std::string& shadowProperties,
+                      bool& colorDefined,
+                      Vector4& color,
+                      bool& offsetDefined,
+                      Vector2& offset );
+
+/**
+ * @brief Parses the underline properties.
+ *
+ * @param[out] enabled Whether the underline is enabled.
+ * @param[out] colorDefined Whether the underline's color is defined.
+ * @param[out] color The underline's color.
+ * @param[out] heightDefined Whether the underline's height is defined.
+ * @param[out] height The underline's height.
+ */
+bool ParseProperties( const std::string& underlineProperties,
+                      bool& enabled,
+                      bool& colorDefined,
+                      Vector4& color,
+                      bool& heightDefined,
+                      float& height );
+
+/**
  * @brief Sets the underline properties.
  *
  * @param[in] controller The text's controller.
index 6fff87e..b3b9e84 100644 (file)
@@ -23,6 +23,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/property-string-parser.h>
+#include <dali-toolkit/internal/text/markup-processor-helper-functions.h>
 
 namespace Dali
 {
@@ -39,6 +40,10 @@ const std::string STYLE_KEY( "style" );
 const std::string WEIGHT_KEY( "weight" );
 const std::string WIDTH_KEY( "width" );
 const std::string SLANT_KEY( "slant" );
+const std::string FAMILY_KEY( "family" );
+const std::string TYPE_KEY( "type" );
+
+const std::string SYSTEM_TOKEN( "system" );
 
 #if defined(DEBUG_ENABLED)
 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_CONTROLS");
@@ -46,6 +51,59 @@ Debug::Filter* gLogFilter = Debug::Filter::New(Debug::Concise, true, "LOG_TEXT_C
 
 } // namespace
 
+void SetFontFamilyProperty( ControllerPtr controller, const Property::Value& value )
+{
+  if( controller )
+  {
+    const std::string fontFamilyValue = value.Get<std::string>();
+
+    if( fontFamilyValue.empty() )
+    {
+      // Resets the default's font family name.
+      controller->SetDefaultFontFamily( "" );
+      return;
+    }
+
+    Property::Map map;
+    ParsePropertyString( fontFamilyValue, map );
+
+    if( map.Empty() )
+    {
+      // There is no map. The font has been passed as a font's family name with no format.
+      controller->SetDefaultFontFamily( fontFamilyValue );
+    }
+    else
+    {
+      /// Family key
+      Property::Value* familyValue = map.Find( FAMILY_KEY );
+
+      std::string fontFamilyName;
+      if( NULL != familyValue )
+      {
+        fontFamilyName = familyValue->Get<std::string>();
+      }
+
+      /// Type key
+      Property::Value* typeValue = map.Find( TYPE_KEY );
+
+      std::string typeStr;
+      if( NULL != typeValue )
+      {
+        typeStr = typeValue->Get<std::string>();
+      }
+
+      if( TokenComparison( SYSTEM_TOKEN, typeStr.c_str(), typeStr.size() ) )
+      {
+        controller->UpdateAfterFontChange( fontFamilyName );
+      }
+      else
+      {
+        controller->SetDefaultFontFamily( fontFamilyName );
+      }
+    }
+  }
+}
+
 void SetFontStyleProperty( ControllerPtr controller, const Property::Value& value, FontStyle::Type type )
 {
   if( controller )
index 425131d..e74bcfb 100644 (file)
@@ -23,7 +23,6 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/text-controller.h>
-#include <dali-toolkit/internal/text/text-definitions.h>
 
 namespace Dali
 {
@@ -90,6 +89,14 @@ namespace FontStyle
 };
 
 /**
+ * @brief Sets the font family property.
+ *
+ * @param[in] controller The text's controller.
+ * @param[in] value The value of the font's family.
+ */
+void SetFontFamilyProperty( ControllerPtr controller, const Property::Value& value );
+
+/**
  * @brief Sets the font's style property.
  *
  * @param[in] controller The text's controller.
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
@@ -15,8 +15,8 @@
  *
  */
 
-// CLASS HEADER
-#include <dali-toolkit/internal/text/text-control-interface.h>
+// FILE HEADER
+#include <dali-toolkit/internal/text/text-scroller-data.h>
 
 namespace Dali
 {
@@ -27,13 +27,18 @@ namespace Toolkit
 namespace Text
 {
 
-ControlInterface::ControlInterface()
-{
-}
+const int MINIMUM_SCROLL_SPEED = 1;
 
-ControlInterface::~ControlInterface()
-{
-}
+ScrollerData::ScrollerData()
+: mScrollSpeed( MINIMUM_SCROLL_SPEED ),
+  mLoopCount( 1 ),
+  mWrapGap( 0.f ),
+  mAlignmentOffset( 0.f ),
+  mAutoScrollDirectionRTL( false )
+{}
+
+ScrollerData::~ScrollerData()
+{}
 
 } // namespace Text
 
diff --git a/dali-toolkit/internal/text/text-scroller-data.h b/dali-toolkit/internal/text/text-scroller-data.h
new file mode 100644 (file)
index 0000000..3ba08c9
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef DALI_TOOLKIT_TEXT_SCROLLER_DATA_H
+#define DALI_TOOLKIT_TEXT_SCROLLER_DATA_H
+
+/*
+ * Copyright (c) 2016 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/math/vector2.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/text-definitions.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+extern const int MINIMUM_SCROLL_SPEED; // Speed should be set by Property system.
+
+/**
+ * @brief Stores the autoscroll data.
+ */
+struct ScrollerData
+{
+  ScrollerData();
+  ~ScrollerData();
+
+  Size               mControlSize;            ///< The size of the control to scroll within.
+  Size               mOffscreenSize;          ///< The size of the sourceActor.
+  int                mScrollSpeed;            ///< Speed which text should automatically scroll at.
+  int                mLoopCount;              ///< Number of time the text should scroll.
+  float              mWrapGap;                ///< Gap before text wraps around when scrolling.
+  float              mAlignmentOffset;        ///< The alignment offset of the first line of text to be scrolled.
+  CharacterDirection mAutoScrollDirectionRTL; ///< Direction of auto scrolling, true if rtl.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_SCROLLER_H
+
index d2f9348..ee1d241 100644 (file)
@@ -31,6 +31,7 @@
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/text-scroller-interface.h>
+#include <dali-toolkit/internal/text/text-scroller-data.h>
 
 namespace Dali
 {
@@ -38,6 +39,11 @@ namespace Dali
 namespace Toolkit
 {
 
+namespace Text
+{
+extern const int MINIMUM_SCROLL_SPEED;
+} // namespace
+
 namespace
 {
 
@@ -45,8 +51,6 @@ namespace
   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_SCROLLING");
 #endif
 
-const int MINIMUM_SCROLL_SPEED = 1; // Speed should be set by Property system.
-
 const char* VERTEX_SHADER_SCROLL = DALI_COMPOSE_SHADER(
   attribute mediump vec2 aPosition;\n
   varying highp vec2 vTexCoord;\n
@@ -195,50 +199,6 @@ TextScrollerPtr TextScroller::New( ScrollerInterface& scrollerInterface )
   return textScroller;
 }
 
-void TextScroller::SetGap( int gap )
-{
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetGap gap[%d]\n", gap );
-  mWrapGap = static_cast<float>(gap);
-}
-
-int TextScroller::GetGap() const
-{
-  return static_cast<int>(mWrapGap);
-}
-
-void TextScroller::SetSpeed( int scrollSpeed )
-{
-  mScrollSpeed = std::max( MINIMUM_SCROLL_SPEED, scrollSpeed );
-}
-
-int TextScroller::GetSpeed() const
-{
-  return mScrollSpeed;
-}
-
-void TextScroller::SetLoopCount( int loopCount )
-{
-  if ( loopCount > 0 )
-  {
-    mLoopCount = loopCount;
-  }
-
-  if (  mScrollAnimation && mScrollAnimation.GetState() == Animation::PLAYING )
-  {
-    if ( loopCount == 0 ) // Request to stop looping
-    {
-      DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetLoopCount Single loop forced\n" );
-      mScrollAnimation.SetLoopCount( 1 ); // As animation already playing this allows the current animation to finish instead of trying to stop mid-way
-    }
-  }
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetLoopCount [%d] Status[%s]\n", mLoopCount, (loopCount)?"looping":"stop" );
-}
-
-int TextScroller::GetLoopCount() const
-{
-  return mLoopCount;
-}
-
 Actor TextScroller::GetSourceCamera() const
 {
   return mOffscreenCameraActor;
@@ -249,11 +209,9 @@ Actor TextScroller::GetScrollingText() const
   return mScrollingTextActor;
 }
 
-TextScroller::TextScroller( ScrollerInterface& scrollerInterface ) : mScrollerInterface( scrollerInterface ),
-                            mScrollDeltaIndex( Property::INVALID_INDEX ),
-                            mScrollSpeed( MINIMUM_SCROLL_SPEED ),
-                            mLoopCount( 1 ),
-                            mWrapGap( 0.0f )
+TextScroller::TextScroller( ScrollerInterface& scrollerInterface )
+: mScrollerInterface( scrollerInterface ),
+  mScrollDeltaIndex( Property::INVALID_INDEX )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller Default Constructor\n" );
 }
@@ -263,49 +221,71 @@ TextScroller::~TextScroller()
   CleanUp();
 }
 
-void TextScroller::SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, float alignmentOffset )
+void TextScroller::StartScrolling( Actor sourceActor,
+                                   const ScrollerData& data )
 {
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters controlSize[%f,%f] offscreenSize[%f,%f] direction[%d] alignmentOffset[%f]\n",
-                 controlSize.x, controlSize.y, offScreenSize.x, offScreenSize.y, direction, alignmentOffset );
-
-  FrameBufferImage offscreenRenderTargetForText = FrameBufferImage::New( offScreenSize.width, offScreenSize.height, Pixel::RGBA8888 );
+  DALI_LOG_INFO( gLogFilter,
+                 Debug::Verbose,
+                 "TextScroller::StartScrolling controlSize[%f,%f] offscreenSize[%f,%f] direction[%d] alignmentOffset[%f]\n",
+                 data.mControlSize.x, data.mControlSize.y,
+                 data.mOffscreenSize.x, data.mOffscreenSize.y,
+                 data.mAutoScrollDirectionRTL,
+                 data.mAlignmentOffset );
+
+  FrameBufferImage offscreenRenderTargetForText = FrameBufferImage::New( data.mOffscreenSize.width, data.mOffscreenSize.height, Pixel::RGBA8888 );
   Renderer renderer;
 
-  CreateCameraActor( offScreenSize, mOffscreenCameraActor );
+  CreateCameraActor( data.mOffscreenSize, mOffscreenCameraActor );
   CreateRenderer( offscreenRenderTargetForText, renderer );
   CreateRenderTask( sourceActor, mOffscreenCameraActor, offscreenRenderTargetForText, mRenderTask );
 
   // Reposition camera to match alignment of target, RTL text has direction=true
-  if ( direction )
+  if( data.mAutoScrollDirectionRTL )
   {
-    mOffscreenCameraActor.SetX( alignmentOffset + offScreenSize.width*0.5f );
+    mOffscreenCameraActor.SetX( data.mAlignmentOffset + data.mOffscreenSize.width * 0.5f );
   }
   else
   {
-    mOffscreenCameraActor.SetX( offScreenSize.width * 0.5f );
+    mOffscreenCameraActor.SetX( data.mOffscreenSize.width * 0.5f );
   }
 
-  mOffscreenCameraActor.SetY( offScreenSize.height * 0.5f );
+  mOffscreenCameraActor.SetY( data.mOffscreenSize.height * 0.5f );
 
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters mWrapGap[%f]\n", mWrapGap )
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetParameters mWrapGap[%f]\n", data.mWrapGap )
 
   mScrollingTextActor = Actor::New();
   mScrollingTextActor.AddRenderer( renderer );
-  mScrollingTextActor.RegisterProperty( "uTextureSize", offScreenSize );
-  mScrollingTextActor.RegisterProperty( "uRtl", ((direction)?1.0f:0.0f) );
-  mScrollingTextActor.RegisterProperty( "uGap", mWrapGap );
-  mScrollingTextActor.SetSize( controlSize.width, std::min( offScreenSize.height, controlSize.height ) );
+  mScrollingTextActor.RegisterProperty( "uTextureSize", data.mOffscreenSize );
+  mScrollingTextActor.RegisterProperty( "uRtl", ( data.mAutoScrollDirectionRTL ? 1.f : 0.f ) );
+  mScrollingTextActor.RegisterProperty( "uGap", data.mWrapGap );
+  mScrollingTextActor.SetSize( data.mControlSize.width, std::min( data.mOffscreenSize.height, data.mControlSize.height ) );
   mScrollDeltaIndex = mScrollingTextActor.RegisterProperty( "uDelta", 0.0f );
 
-  float scrollAmount = std::max( offScreenSize.width + mWrapGap, controlSize.width );
-  float scrollDuration =  scrollAmount / mScrollSpeed;
+  float scrollAmount = std::max( data.mOffscreenSize.width + data.mWrapGap, data.mControlSize.width );
+  float scrollSpeed = std::max( MINIMUM_SCROLL_SPEED, data.mScrollSpeed );
+  float scrollDuration =  scrollAmount / scrollSpeed;
 
-  if ( direction  )
+  if( data.mAutoScrollDirectionRTL )
   {
      scrollAmount = -scrollAmount; // reverse direction of scrollung
   }
 
-  StartScrolling( scrollAmount, scrollDuration, mLoopCount );
+  mScrollAnimation = Animation::New( scrollDuration );
+  mScrollAnimation.AnimateTo( Property( mScrollingTextActor, mScrollDeltaIndex ), scrollAmount );
+  mScrollAnimation.SetEndAction( Animation::Discard );
+  mScrollAnimation.SetLoopCount( data.mLoopCount );
+  mScrollAnimation.FinishedSignal().Connect( this, &TextScroller::AutoScrollAnimationFinished );
+  mScrollAnimation.Play();
+}
+
+void TextScroller::StopScrolling()
+{
+  if( mScrollAnimation &&
+      ( mScrollAnimation.GetState() == Animation::PLAYING ) )
+  {
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::SetLoopCount Single loop forced\n" );
+    mScrollAnimation.SetLoopCount( 1 ); // As animation already playing this allows the current animation to finish instead of trying to stop mid-way
+  }
 }
 
 void TextScroller::AutoScrollAnimationFinished( Dali::Animation& animation )
@@ -315,18 +295,6 @@ void TextScroller::AutoScrollAnimationFinished( Dali::Animation& animation )
   mScrollerInterface.ScrollingFinished();
 }
 
-void TextScroller::StartScrolling( float scrollAmount, float scrollDuration, int loopCount )
-{
-  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextScroller::StartScrolling scrollAmount[%f] scrollDuration[%f], loop[%d] speed[%d]\n", scrollAmount, scrollDuration, loopCount, mScrollSpeed );
-
-  mScrollAnimation = Animation::New( scrollDuration );
-  mScrollAnimation.AnimateTo( Property( mScrollingTextActor, mScrollDeltaIndex ), scrollAmount );
-  mScrollAnimation.SetEndAction( Animation::Discard );
-  mScrollAnimation.SetLoopCount( loopCount );
-  mScrollAnimation.FinishedSignal().Connect( this, &TextScroller::AutoScrollAnimationFinished );
-  mScrollAnimation.Play();
-}
-
 void TextScroller::CleanUp()
 {
   if ( Stage::IsInstalled() )
index 17824b6..a40be3f 100644 (file)
@@ -37,6 +37,7 @@ namespace Text
 
 class TextScroller;
 class ScrollerInterface;
+struct ScrollerData;
 
 typedef IntrusivePtr<TextScroller> TextScrollerPtr;
 
@@ -46,7 +47,6 @@ typedef IntrusivePtr<TextScroller> TextScrollerPtr;
 class TextScroller : public RefObject, public ConnectionTracker
 {
 public:
-
   /**
    * @brief Text Scrolling helper, used to automatically scroll text, SetParameters should be called before scrolling is needed.
    * CleanUp removes the Scrolling actors from stage whilst keeping the Scroller object alive and preserving Speed, Gap and Loop count.
@@ -56,52 +56,19 @@ public:
   static TextScrollerPtr New( ScrollerInterface& scrollerInterface );
 
   /**
-   * @brief Set parameters relating to source required for scrolling
+   * @brief Starts the text scrolling.
    *
    * @param[in] sourceActor source actor to be scrolled
-   * @param[in] controlSize size of the control to scroll within
-   * @param[in] offScreenSize size of the sourceActor
-   * @param[in] direction text direction true for right to left text
-   * @param[in] alignmentOffset alignment of source text
+   * @param[in] data Parameters needed to set up the text scrolling.
    *
    */
-  void SetParameters( Actor sourceActor, const Size& controlSize, const Size& offScreenSize, CharacterDirection direction, float alignmentOffset );
-
-  /**
-   * @brief Set the gap distance to elapse before the text wraps around
-   * @param[in] gap distance to elapse
-   */
-  void SetGap( int gap );
-
-  /**
-   * @brief Get the distance before scrolling wraps
-   * @return gap distance to elapse
-   */
-  int GetGap() const;
-
-  /**
-   * @brief Set speed the text should scroll
-   * @param[in] scrollSpeed pixels per second
-   */
-  void SetSpeed( int scrollSpeed );
+  void StartScrolling( Actor sourceActor,
+                       const ScrollerData& data );
 
   /**
-   * @brief Get the speed of text scrolling
-   * @return speed in pixels per second
+   * @brief Stops the text scrolling.
    */
-  int GetSpeed() const;
-
-  /**
-   * @brief Set the number of times the text scrolling should loop, can stop current scrolling by passing in 0;
-   * @param[in] loopCount number of times the scrolled text should loop, 0 to stop scrolling
-   */
-  void SetLoopCount( int loopCount );
-
-  /**
-   * @brief Get the number of loops
-   * @return int number of loops
-   */
-  int GetLoopCount() const;
+  void StopScrolling();
 
   /**
    * @brief Get the camera used to look at source, should be added to the parent of target actor.
@@ -140,14 +107,6 @@ private: // Implementation
   void AutoScrollAnimationFinished( Dali::Animation& animation );
 
   /**
-   * @brief variables required to set up scrolling animation
-   * @param[in] scrollAmount distance to animate text for the given duration
-   * @param[in] scrollDuration duration of aninmation
-   * @param[in] loopCount number of times to loop the scrolling text
-   */
-  void StartScrolling( float scrollAmount, float scrollDuration, int loopCount );
-
-  /**
    * @brief When scrolling ended, the actors are cleaned up so no longer staged.
    */
   void CleanUp();
@@ -161,10 +120,6 @@ private:
   Property::Index    mScrollDeltaIndex;         // Property used by shader to represent distance to scroll
   Animation          mScrollAnimation;          // Animation used to update the mScrollDeltaIndex
 
-  int   mScrollSpeed;            ///< Speed which text should automatically scroll at
-  int   mLoopCount;              ///< Number of time the text should scroll
-  float mWrapGap;                ///< Gap before text wraps around when scrolling
-
 }; // TextScroller class
 
 } // namespace Text
index 0c27103..ba326d0 100644 (file)
@@ -102,6 +102,11 @@ const char* FRAGMENT_SHADER_ANTI_ALIASING = DALI_COMPOSE_SHADER(
 );
 }
 
+BorderVisualPtr BorderVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new BorderVisual( factoryCache );
+}
+
 BorderVisual::BorderVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
   mBorderColor( Color::TRANSPARENT ),
index c1e30d8..3fce5d6 100644 (file)
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <dali/public-api/rendering/geometry.h>
+#include <dali/public-api/common/intrusive-ptr.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
@@ -33,6 +34,9 @@ namespace Toolkit
 namespace Internal
 {
 
+class BorderVisual;
+typedef IntrusivePtr< BorderVisual > BorderVisualPtr;
+
 /**
  * The visual which renders a solid color to the control's quad border fixed to a specified size.
  *
@@ -44,12 +48,21 @@ namespace Internal
  * | borderSize      | FLOAT       |
  * | antiAliasing    | BOOLEAN     |
  */
-
 class BorderVisual : public Visual::Base
 {
 public:
 
   /**
+   * @brief Create a new border visual.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
+   */
+  static BorderVisualPtr New( VisualFactoryCache& factoryCache );
+
+protected:
+
+  /**
    * @brief Constructor.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
@@ -61,8 +74,6 @@ public:
    */
   virtual ~BorderVisual();
 
-protected:
-
   /**
    * @copydoc Visual::Base::DoInitialize
    */
index a1ef6d2..8736d54 100644 (file)
@@ -65,6 +65,11 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
 );
 }
 
+ColorVisualPtr ColorVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new ColorVisual( factoryCache );
+}
+
 ColorVisual::ColorVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
   mMixColorIndex( Property::INVALID_INDEX )
index 88fb152..6552ac6 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_COLOR_VISUAL_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
@@ -18,6 +18,9 @@
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 
@@ -30,6 +33,9 @@ namespace Toolkit
 namespace Internal
 {
 
+class ColorVisual;
+typedef IntrusivePtr< ColorVisual > ColorVisualPtr;
+
 /**
  * The visual which renders a solid color to the control's quad
  *
@@ -44,16 +50,12 @@ class ColorVisual: public Visual::Base
 public:
 
   /**
-   * @brief Constructor.
+   * @brief Create a new color visual.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
    */
-  ColorVisual( VisualFactoryCache& factoryCache );
-
-  /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
-   */
-  virtual ~ColorVisual();
+  static ColorVisualPtr New( VisualFactoryCache& factoryCache );
 
 public:  // from Visual
 
@@ -80,6 +82,18 @@ public:  // from Visual
 protected:
 
   /**
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   */
+  ColorVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~ColorVisual();
+
+  /**
    * @copydoc Visual::Base::DoInitialize
    */
   virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
index f30ff03..b662821 100644 (file)
@@ -185,6 +185,10 @@ Dali::WrapMode::Type GetWrapMode( Toolkit::GradientVisual::SpreadMethod::Type sp
 
 } // unnamed namespace
 
+GradientVisualPtr GradientVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new GradientVisual( factoryCache );
+}
 
 GradientVisual::GradientVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
index 1726c51..5171b12 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_GRADIENT_VISUAL_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
@@ -18,6 +18,9 @@
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/visuals/gradient/gradient.h>
@@ -33,6 +36,8 @@ namespace Internal
 {
 
 class Gradient;
+class GradientVisual;
+typedef IntrusivePtr< GradientVisual > GradientVisualPtr;
 
 /**
  * The visual which renders smooth transition of colors to the control's quad.
@@ -80,16 +85,12 @@ public:
   };
 
   /**
-   * @brief Constructor.
+   * @brief Create a new gradient visual.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
    */
-  GradientVisual( VisualFactoryCache& factoryCache );
-
-  /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
-   */
-  ~GradientVisual();
+  static GradientVisualPtr New( VisualFactoryCache& factoryCache );
 
 public:  // from Visual
 
@@ -114,6 +115,19 @@ public:  // from Visual
   virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index );
 
 protected:
+
+  /**
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   */
+  GradientVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~GradientVisual();
+
   /**
    * @copydoc Visual::Base::DoInitialize
    */
index 46244aa..973355a 100644 (file)
@@ -85,11 +85,16 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
   }\n
 );
 
-} //unnamed namespace
+} // unnamed namespace
+
+BatchImageVisualPtr BatchImageVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new BatchImageVisual( factoryCache );
+}
 
 BatchImageVisual::BatchImageVisual( VisualFactoryCache& factoryCache )
-  : Visual::Base( factoryCache ),
-    mDesiredSize()
+: Visual::Base( factoryCache ),
+  mDesiredSize()
 {
 }
 
index e5536e9..7151100 100644 (file)
  *
  */
 
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+
 // INTERNAL HEADER
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
 #include <dali-toolkit/internal/visuals/image-atlas-manager.h>
 
-// EXTERNAL INCLUDES
-#include <dali/public-api/images/resource-image.h>
-
 namespace Dali
 {
 namespace Toolkit
@@ -32,21 +32,20 @@ namespace Toolkit
 namespace Internal
 {
 
+class BatchImageVisual;
+typedef IntrusivePtr< BatchImageVisual > BatchImageVisualPtr;
+
 class BatchImageVisual: public Visual::Base, public ConnectionTracker
 {
 public:
 
   /**
-   * @brief Constructor.
+   * @brief Create a new batch-image visual.
    *
-   * @param[in] factoryCache The VisualFactoryCache object
-   */
-  BatchImageVisual( VisualFactoryCache& factoryCache );
-
-  /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
    */
-  ~BatchImageVisual();
+  static BatchImageVisualPtr New( VisualFactoryCache& factoryCache );
 
 public:  // from Visual
 
@@ -78,6 +77,18 @@ public:  // from Visual
 protected:
 
   /**
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache The VisualFactoryCache object
+   */
+  BatchImageVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  ~BatchImageVisual();
+
+  /**
    * @copydoc Visua::Base::DoInitialize
    */
   virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
index f4652dd..0cfdfc8 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 // CLASS HEADER
-#include "image-visual.h"
+#include <dali-toolkit/internal/visuals/image/image-visual.h>
 
 // EXTERNAL HEADER
 #include <cstring> // for strncasecmp
@@ -186,19 +186,92 @@ Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridS
   return geometry;
 }
 
-} //unnamed namespace
+} // unnamed namespace
+
+ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new ImageVisual( factoryCache );
+}
+
+ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache,
+                                 const std::string& imageUrl,
+                                 ImageDimensions size,
+                                 FittingMode::Type fittingMode,
+                                 Dali::SamplingMode::Type samplingMode )
+{
+  return new ImageVisual( factoryCache, imageUrl, size, fittingMode, samplingMode );
+}
+
+ImageVisualPtr ImageVisual::New( VisualFactoryCache& factoryCache, const Image& image )
+{
+  return new ImageVisual( factoryCache, image );
+}
 
 ImageVisual::ImageVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
+  mImage(),
+  mPixels(),
+  mTextureSet(),
+  mPixelArea( FULL_TEXTURE_RECT ),
+  mPlacementActor(),
+  mImageUrl(),
+  mNativeFragmentShaderCode(),
+  mDesiredSize(),
+  mFittingMode( FittingMode::DEFAULT ),
+  mSamplingMode( SamplingMode::DEFAULT ),
+  mWrapModeU( WrapMode::DEFAULT ),
+  mWrapModeV( WrapMode::DEFAULT ),
+  mNativeImageFlag( false )
+{
+}
+
+ImageVisual::ImageVisual( VisualFactoryCache& factoryCache,
+                          const std::string& imageUrl,
+                          ImageDimensions size,
+                          FittingMode::Type fittingMode,
+                          Dali::SamplingMode::Type samplingMode )
+: Visual::Base( factoryCache ),
+  mImage(),
+  mPixels(),
+  mTextureSet(),
+  mPixelArea( FULL_TEXTURE_RECT ),
+  mPlacementActor(),
+  mImageUrl( imageUrl ),
+  mNativeFragmentShaderCode(),
+  mDesiredSize( size ),
+  mFittingMode( fittingMode ),
+  mSamplingMode( samplingMode ),
+  mWrapModeU( WrapMode::DEFAULT ),
+  mWrapModeV( WrapMode::DEFAULT ),
+  mNativeImageFlag( false )
+{
+}
+
+ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, const Image& image )
+: Visual::Base( factoryCache ),
+  mImage( image ),
+  mPixels(),
   mPixelArea( FULL_TEXTURE_RECT ),
+  mPlacementActor(),
+  mImageUrl(),
+  mNativeFragmentShaderCode(),
   mDesiredSize(),
   mFittingMode( FittingMode::DEFAULT ),
   mSamplingMode( SamplingMode::DEFAULT ),
   mWrapModeU( WrapMode::DEFAULT ),
   mWrapModeV( WrapMode::DEFAULT ),
-  mNativeFragmentShaderCode( ),
   mNativeImageFlag( false )
 {
+  NativeImage newNativeImage = NativeImage::DownCast( image );
+  if( newNativeImage )
+  {
+    SetNativeFragmentShaderCode( newNativeImage );
+    mNativeImageFlag = true;
+  }
+  else
+  {
+    mNativeImageFlag = false;
+  }
 }
 
 ImageVisual::~ImageVisual()
@@ -221,13 +294,17 @@ void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
     Property::Value* fittingValue = propertyMap.Find( Toolkit::ImageVisual::Property::FITTING_MODE, IMAGE_FITTING_MODE );
     if( fittingValue )
     {
-      Scripting::GetEnumerationProperty( *fittingValue, FITTING_MODE_TABLE, FITTING_MODE_TABLE_COUNT, mFittingMode );
+      int value;
+      Scripting::GetEnumerationProperty( *fittingValue, FITTING_MODE_TABLE, FITTING_MODE_TABLE_COUNT, value );
+      mFittingMode = Dali::FittingMode::Type( value );
     }
 
     Property::Value* samplingValue = propertyMap.Find( Toolkit::ImageVisual::Property::SAMPLING_MODE, IMAGE_SAMPLING_MODE );
     if( samplingValue )
     {
-      Scripting::GetEnumerationProperty( *samplingValue, SAMPLING_MODE_TABLE, SAMPLING_MODE_TABLE_COUNT, mSamplingMode );
+      int value;
+      Scripting::GetEnumerationProperty( *samplingValue, SAMPLING_MODE_TABLE, SAMPLING_MODE_TABLE_COUNT, value );
+      mSamplingMode = Dali::SamplingMode::Type( value );
     }
 
     int desiredWidth = 0;
@@ -253,13 +330,17 @@ void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
     Property::Value* wrapModeValueU = propertyMap.Find( Toolkit::ImageVisual::Property::WRAP_MODE_U, IMAGE_WRAP_MODE_U );
     if( wrapModeValueU )
     {
-      Scripting::GetEnumerationProperty( *wrapModeValueU, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, mWrapModeU );
+      int value;
+      Scripting::GetEnumerationProperty( *wrapModeValueU, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, value );
+      mWrapModeU = Dali::WrapMode::Type( value );
     }
 
     Property::Value* wrapModeValueV = propertyMap.Find( Toolkit::ImageVisual::Property::WRAP_MODE_V, IMAGE_WRAP_MODE_V );
     if( wrapModeValueV )
     {
-      Scripting::GetEnumerationProperty( *wrapModeValueV, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, mWrapModeV );
+      int value;
+      Scripting::GetEnumerationProperty( *wrapModeValueV, WRAP_MODE_TABLE, WRAP_MODE_TABLE_COUNT, value );
+      mWrapModeV = Dali::WrapMode::Type( value );
     }
 
     mDesiredSize = ImageDimensions( desiredWidth, desiredHeight );
@@ -282,22 +363,9 @@ void ImageVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
 
   // if sync loading is required, the loading should start immediately when new image url is set or the actor is off stage
   // ( for on-stage actor with image url unchanged, resource loading is already finished)
-  if( ( !mImpl->mRenderer || imageURLValue) && IsSynchronousResourceLoading() )
+  if( imageURLValue && IsSynchronousResourceLoading() )
   {
-    DoSynchronousResourceLoading();
-  }
-
-  // remove old renderer if exit
-  if( mImpl->mRenderer )
-  {
-    if( actor ) //remove old renderer from actor
-    {
-      actor.RemoveRenderer( mImpl->mRenderer );
-    }
-    if( !oldImageUrl.empty() ) //clean old renderer from cache
-    {
-      CleanCache( oldImageUrl );
-    }
+    LoadResourceSynchronously();
   }
 
   NativeImage nativeImage = NativeImage::DownCast( mImage );
@@ -339,7 +407,7 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize ) const
   naturalSize = Vector2::ZERO;
 }
 
-Renderer ImageVisual::CreateRenderer() const
+void ImageVisual::CreateRenderer()
 {
   Geometry geometry;
   Shader shader;
@@ -348,7 +416,8 @@ Renderer ImageVisual::CreateRenderer() const
   // Renderer can't be shared between NativeImage and other image types.
   if( !mNativeFragmentShaderCode.empty() )
   {
-    return CreateNativeImageRenderer();
+    CreateNativeImageRenderer();
+    return;
   }
 
   if( !mImpl->mCustomShader )
@@ -378,12 +447,13 @@ Renderer ImageVisual::CreateRenderer() const
     }
   }
 
-  Renderer renderer = Renderer::New( geometry, shader );
-
-  return renderer;
+  mImpl->mRenderer = Renderer::New( geometry, shader );
+  // apply the texture set as well so it's only done in one place
+  DALI_ASSERT_DEBUG( mTextureSet );
+  mImpl->mRenderer.SetTextures( mTextureSet );
 }
 
-Renderer ImageVisual::CreateNativeImageRenderer() const
+void ImageVisual::CreateNativeImageRenderer()
 {
   Geometry geometry;
   Shader shader;
@@ -407,10 +477,10 @@ Renderer ImageVisual::CreateNativeImageRenderer() const
     }
   }
 
-  TextureSet textureSet = TextureSet::New();
-  Renderer renderer = Renderer::New( geometry, shader );
-  renderer.SetTextures( textureSet );
-  return renderer;
+  mImpl->mRenderer = Renderer::New( geometry, shader );
+  // apply the texture set as well so it's only done in one place
+  DALI_ASSERT_DEBUG( mTextureSet );
+  mImpl->mRenderer.SetTextures( mTextureSet );
 }
 
 
@@ -419,7 +489,7 @@ bool ImageVisual::IsSynchronousResourceLoading() const
   return mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING;
 }
 
-void ImageVisual::DoSynchronousResourceLoading()
+void ImageVisual::LoadResourceSynchronously()
 {
   if( !mImageUrl.empty() )
   {
@@ -429,64 +499,49 @@ void ImageVisual::DoSynchronousResourceLoading()
   }
 }
 
-Image ImageVisual::LoadImage( const std::string& url, bool synchronousLoading )
+void ImageVisual::CreateTextureSet( Vector4& textureRect, const std::string& url, bool synchronousLoading, bool attemptAtlasing )
 {
-  if( synchronousLoading )
-  {
-    if( !mPixels )
-    {
-      // use broken image
-      return VisualFactoryCache::GetBrokenVisualImage();
-    }
-    Atlas image = Atlas::New( mPixels.GetWidth(), mPixels.GetHeight(), mPixels.GetPixelFormat() );
-    image.Upload( mPixels, 0, 0 );
-    return image;
-  }
-  else
-  {
-    ResourceImage resourceImage = Dali::ResourceImage::New( url, mDesiredSize, mFittingMode, mSamplingMode );
-    resourceImage.LoadingFinishedSignal().Connect( this, &ImageVisual::OnImageLoaded );
-    return resourceImage;
-  }
-}
-
-TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::string& url, bool synchronousLoading )
-{
-  TextureSet textureSet;
   textureRect = FULL_TEXTURE_RECT;
   if( synchronousLoading )
   {
     if( !mPixels )
     {
       // use broken image
-      textureSet = TextureSet::New();
-      TextureSetImage( textureSet, 0u, VisualFactoryCache::GetBrokenVisualImage() );
+      mTextureSet = TextureSet::New();
+      TextureSetImage( mTextureSet, 0u, VisualFactoryCache::GetBrokenVisualImage() );
     }
     else
     {
-      textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, mPixels );
-      mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
-      if( !textureSet ) // big image, no atlasing
+      if( attemptAtlasing )
+      {
+        mTextureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, mPixels );
+        mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
+      }
+      if( !mTextureSet ) // big image, no atlasing or atlasing failed
       {
         mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
-        Atlas image = Atlas::New( mPixels.GetWidth(), mPixels.GetHeight(), mPixels.GetPixelFormat() );
-        image.Upload( mPixels, 0, 0 );
-        textureSet = TextureSet::New();
-        TextureSetImage( textureSet, 0u, image );
+        Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, mPixels.GetPixelFormat(),
+                                        mPixels.GetWidth(), mPixels.GetHeight() );
+        texture.Upload( mPixels );
+        mTextureSet = TextureSet::New();
+        mTextureSet.SetTexture( 0u, texture );
       }
     }
   }
   else
   {
-    textureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, url, mDesiredSize, mFittingMode, true, this );
-    mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
-    if( !textureSet ) // big image, no atlasing
+    if( attemptAtlasing )
+    {
+      mTextureSet = mFactoryCache.GetAtlasManager()->Add(textureRect, url, mDesiredSize, mFittingMode, true, this );
+      mImpl->mFlags |= Impl::IS_ATLASING_APPLIED;
+    }
+    if( !mTextureSet ) // big image, no atlasing or atlasing failed
     {
       mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
       ResourceImage resourceImage = Dali::ResourceImage::New( url, mDesiredSize, mFittingMode, mSamplingMode );
       resourceImage.LoadingFinishedSignal().Connect( this, &ImageVisual::OnImageLoaded );
-      textureSet = TextureSet::New();
-      TextureSetImage( textureSet, 0u, resourceImage );
+      mTextureSet = TextureSet::New();
+      TextureSetImage( mTextureSet, 0u, resourceImage );
     }
   }
 
@@ -494,10 +549,8 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, const std::strin
   {
     Sampler sampler = Sampler::New();
     sampler.SetWrapMode(  mWrapModeU, mWrapModeV  );
-    textureSet.SetSampler( 0u, sampler );
+    mTextureSet.SetSampler( 0u, sampler );
   }
-
-  return textureSet;
 }
 
 void ImageVisual::InitializeRenderer( const std::string& imageUrl )
@@ -528,11 +581,10 @@ void ImageVisual::InitializeRenderer( const std::string& imageUrl )
     if( !mImpl->mRenderer ) // new renderer is needed
     {
       Vector4 atlasRect;
-      TextureSet textureSet = CreateTextureSet(atlasRect, imageUrl, IsSynchronousResourceLoading() );
-      Geometry geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
-      Shader shader( GetImageShader(mFactoryCache, mImpl->mFlags & Impl::IS_ATLASING_APPLIED, defaultWrapMode) );
-      mImpl->mRenderer = Renderer::New( geometry, shader );
-      mImpl->mRenderer.SetTextures( textureSet );
+      // texture set has to be created first as we need to know if atlasing succeeded or not
+      // when selecting the shader
+      CreateTextureSet( atlasRect, imageUrl, IsSynchronousResourceLoading(), true );
+      CreateRenderer();
 
       if( mImpl->mFlags & Impl::IS_ATLASING_APPLIED ) // the texture is packed inside atlas
       {
@@ -556,9 +608,9 @@ void ImageVisual::InitializeRenderer( const std::string& imageUrl )
   {
     // for custom shader or remote image, renderer is not cached and atlas is not applied
     mImpl->mFlags &= ~Impl::IS_FROM_CACHE;
-    mImpl->mRenderer = CreateRenderer();
-    Image image = LoadImage( imageUrl, IsSynchronousResourceLoading() );
-    ApplyImageToSampler( image );
+    Vector4 atlasRect; // ignored in this case
+    CreateTextureSet( atlasRect, imageUrl, IsSynchronousResourceLoading(), false );
+    CreateRenderer();
   }
 }
 
@@ -566,7 +618,9 @@ void ImageVisual::InitializeRenderer( const Image& image )
 {
   mImpl->mFlags &= ~Impl::IS_FROM_CACHE;
 
-  mImpl->mRenderer = CreateRenderer();
+  // don't reuse CreateTextureSet
+  mTextureSet = TextureSet::New();
+  CreateRenderer();
 
   if( image )
   {
@@ -626,6 +680,7 @@ void ImageVisual::DoSetOffStage( Actor& actor )
     mImpl->mRenderer.Reset();
   }
   mPlacementActor.Reset();
+  mTextureSet.Reset(); // release texture when going offstage
 }
 
 void ImageVisual::DoCreatePropertyMap( Property::Map& map ) const
@@ -709,145 +764,16 @@ Shader ImageVisual::GetImageShader( VisualFactoryCache& factoryCache, bool atlas
   return shader;
 }
 
-void ImageVisual::SetImage( Actor& actor, const std::string& imageUrl, ImageDimensions size, Dali::FittingMode::Type fittingMode, Dali::SamplingMode::Type samplingMode )
-{
-  if( mImageUrl != imageUrl )
-  {
-    std::string oldImageUrl = mImageUrl;
-    mImageUrl = imageUrl;
-    mDesiredSize = size;
-    mFittingMode = fittingMode;
-    mSamplingMode = samplingMode;
-    mImage.Reset();
-
-    if( IsSynchronousResourceLoading() )
-    {
-      DoSynchronousResourceLoading();
-    }
-
-    if( mImpl->mRenderer )
-    {
-      if( GetIsFromCache() ) // if renderer is from cache, remove the old one
-      {
-        //remove old renderer
-        if( actor )
-        {
-          actor.RemoveRenderer( mImpl->mRenderer );
-        }
-
-        //clean the cache
-        if( !oldImageUrl.empty() )
-        {
-          CleanCache(oldImageUrl);
-        }
-
-        if( actor && actor.OnStage() ) // if actor on stage, create a new renderer and apply to actor
-        {
-          SetOnStage(actor);
-        }
-      }
-      else // if renderer is not from cache, reuse the same renderer and only change the texture
-      {
-        Image image = LoadImage( imageUrl, IsSynchronousResourceLoading() );
-        ApplyImageToSampler( image );
-      }
-    }
-  }
-}
-
-void ImageVisual::SetImage( Actor& actor, const Image& image )
-{
-  if( mImage != image )
-  {
-    NativeImage newNativeImage = NativeImage::DownCast( image );
-    bool newRendererFlag = true;
-
-    if( newNativeImage && !mNativeImageFlag )
-    {
-      SetNativeFragmentShaderCode( newNativeImage );
-    }
-
-    if( ( newNativeImage && mNativeImageFlag ) || ( !newNativeImage && !mNativeImageFlag ) )
-    {
-      newRendererFlag = false;
-    }
-
-    if( newNativeImage )
-    {
-      mNativeImageFlag = true;
-    }
-    else
-    {
-      mNativeFragmentShaderCode.clear();
-      mNativeImageFlag = false;
-    }
-
-    mImage = image;
-
-    if( mImpl->mRenderer )
-    {
-      // if renderer is from cache, remove the old one, and create new renderer
-      if( GetIsFromCache() )
-      {
-        //remove old renderer
-        if( actor )
-        {
-          actor.RemoveRenderer( mImpl->mRenderer );
-        }
-
-        //clean the cache
-        if( !mImageUrl.empty() )
-        {
-          CleanCache(mImageUrl);
-        }
-        mImageUrl.clear();
-
-        if( actor && actor.OnStage() ) // if actor on stage, create a new renderer and apply to actor
-        {
-          SetOnStage(actor);
-        }
-      }
-      // if input image is nativeImage and mImage is regular image or the reverse, remove the old one, and create new renderer
-      else if( newRendererFlag )
-      {
-        //remove old renderer
-        if( actor )
-        {
-          actor.RemoveRenderer( mImpl->mRenderer );
-        }
-
-        if( actor && actor.OnStage() ) // if actor on stage, create a new renderer and apply to actor
-        {
-          SetOnStage(actor);
-        }
-      }
-      else // if renderer is not from cache, reuse the same renderer and only change the texture
-      {
-        ApplyImageToSampler( image );
-      }
-    }
-
-    mImageUrl.clear();
-    mDesiredSize = ImageDimensions();
-    mFittingMode = FittingMode::DEFAULT;
-    mSamplingMode = SamplingMode::DEFAULT;
-  }
-}
-
 void ImageVisual::ApplyImageToSampler( const Image& image )
 {
   if( image )
   {
-    TextureSet textureSet = mImpl->mRenderer.GetTextures();
-    if( !textureSet )
-    {
-      textureSet = TextureSet::New();
-      mImpl->mRenderer.SetTextures( textureSet );
-    }
-    TextureSetImage( textureSet, 0u, image );
+    DALI_ASSERT_DEBUG( mTextureSet ); // texture set should always exist by this time
+
+    TextureSetImage( mTextureSet, 0u, image );
     Sampler sampler = Sampler::New();
     sampler.SetWrapMode(  mWrapModeU, mWrapModeV  );
-    textureSet.SetSampler( 0u, sampler );
+    mTextureSet.SetSampler( 0u, sampler );
   }
 }
 
@@ -865,20 +791,21 @@ void ImageVisual::OnImageLoaded( ResourceImage image )
 
 void ImageVisual::CleanCache(const std::string& url)
 {
-  TextureSet textureSet = mImpl->mRenderer.GetTextures();
-
-  Vector4 atlasRect( 0.f, 0.f, 1.f, 1.f );
-  Property::Index index = mImpl->mRenderer.GetPropertyIndex( ATLAS_RECT_UNIFORM_NAME );
-  if( index != Property::INVALID_INDEX )
+  if( IsFromCache() )
   {
-    Property::Value atlasRectValue = mImpl->mRenderer.GetProperty( index );
-    atlasRectValue.Get( atlasRect );
-  }
+    Vector4 atlasRect( 0.f, 0.f, 1.f, 1.f );
+    Property::Index index = mImpl->mRenderer.GetPropertyIndex( ATLAS_RECT_UNIFORM_NAME );
+    if( index != Property::INVALID_INDEX )
+    {
+      Property::Value atlasRectValue = mImpl->mRenderer.GetProperty( index );
+      atlasRectValue.Get( atlasRect );
+    }
 
-  mImpl->mRenderer.Reset();
-  if( mFactoryCache.CleanRendererCache( url ) && index != Property::INVALID_INDEX )
-  {
-    mFactoryCache.GetAtlasManager()->Remove( textureSet, atlasRect );
+    mImpl->mRenderer.Reset();
+    if( mFactoryCache.CleanRendererCache( url ) && index != Property::INVALID_INDEX )
+    {
+      mFactoryCache.GetAtlasManager()->Remove( mTextureSet, atlasRect );
+    }
   }
 }
 
index 3079c93..24d652b 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_IMAGE_VISUAL_H
 
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2016 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.
  *
  */
 
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/visuals/visual-base-impl.h>
-#include <dali-toolkit/devel-api/image-loader/atlas-upload-observer.h>
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/images/image.h>
 #include <dali/public-api/images/image-operations.h>
 #include <dali/public-api/images/resource-image.h>
 #include <dali/devel-api/object/weak-handle.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/devel-api/image-loader/atlas-upload-observer.h>
+
 namespace Dali
 {
 
@@ -79,16 +80,37 @@ class ImageVisual: public Visual::Base, public ConnectionTracker, public AtlasUp
 public:
 
   /**
-   * @brief Constructor.
+   * @brief Create a new image visual.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
+   */
+  static ImageVisualPtr New( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief Create a new image visual with a URL.
+   *
+   * The visual will load the Image asynchronously when the associated actor is put on stage, and destroy the image when it is off stage
    *
    * @param[in] factoryCache The VisualFactoryCache object
+   * @param[in] imageUrl The URL of the image resource to use
+   * @param[in] size The width and height to fit the loaded image to.
+   * @param[in] fittingMode The FittingMode of the resource to load
+   * @param[in] samplingMode The SamplingMode of the resource to load
    */
-  ImageVisual( VisualFactoryCache& factoryCache );
+  static ImageVisualPtr New( VisualFactoryCache& factoryCache,
+                             const std::string& imageUrl,
+                             ImageDimensions size = ImageDimensions(),
+                             FittingMode::Type fittingMode = FittingMode::DEFAULT,
+                             Dali::SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR );
 
   /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
+   * @brief Create a new image visual with an Image type.
+   *
+   * @param[in] factoryCache The VisualFactoryCache object
+   * @param[in] image The image to use
    */
-  ~ImageVisual();
+  static ImageVisualPtr New( VisualFactoryCache& factoryCache, const Image& image );
 
 public:  // from Visual
 
@@ -113,6 +135,44 @@ public:  // from Visual
   virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index );
 
 protected:
+
+  /**
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache The VisualFactoryCache object
+   */
+  ImageVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief Constructor with a URL.
+   *
+   * The visual will load the Image asynchronously when the associated actor is put on stage, and destroy the image when it is off stage
+   *
+   * @param[in] factoryCache The VisualFactoryCache object
+   * @param[in] imageUrl The URL of the image resource to use
+   * @param[in] size The width and height to fit the loaded image to.
+   * @param[in] fittingMode The FittingMode of the resource to load
+   * @param[in] samplingMode The SamplingMode of the resource to load
+   */
+  ImageVisual( VisualFactoryCache& factoryCache,
+               const std::string& imageUrl,
+               ImageDimensions size,
+               FittingMode::Type fittingMode,
+               Dali::SamplingMode::Type samplingMode );
+
+  /**
+   * @brief Constructor with an Image type.
+   *
+   * @param[in] factoryCache The VisualFactoryCache object
+   * @param[in] image The image to use
+   */
+  ImageVisual( VisualFactoryCache& factoryCache, const Image& image );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~ImageVisual();
+
   /**
    * @copydoc Visual::Base::DoInitialize
    */
@@ -139,30 +199,6 @@ public:
   static Shader GetImageShader( VisualFactoryCache& factoryCache, bool atlasing, bool defaultTextureWrapping );
 
   /**
-   * @brief Sets the image of this visual to the resource at imageUrl
-   * The visual will load the Image asynchronously when the associated actor is put on stage, and destroy the image when it is off stage
-   *
-   * @param[in] actor The Actor the renderer is applied to if, empty if the renderer has not been applied to any Actor
-   * @param[in] imageUrl The URL of the image resource to use
-   * @param[in] size The width and height to fit the loaded image to.
-   * @param[in] fittingMode The FittingMode of the resource to load
-   * @param[in] samplingMode The SamplingMode of the resource to load
-   */
-  void SetImage( Actor& actor,
-                 const std::string& imageUrl,
-                 ImageDimensions size=ImageDimensions(),
-                 FittingMode::Type fittingMode = FittingMode::DEFAULT,
-                 Dali::SamplingMode::Type samplingMode = SamplingMode::BOX_THEN_LINEAR );
-
-  /**
-   * @brief Sets the image to be rendered by this visual
-   *
-   * @param[in] actor The Actor the renderer is applied to if, empty if the renderer has not been applied to any Actor
-   * @param[in] image The image to use
-   */
-  void SetImage( Actor& actor, const Image& image );
-
-  /**
    * @copydoc AtlasUploadObserver::UploadCompleted
    *
    * To avoid rendering garbage pixels, renderer should be added to actor after the resources are ready.
@@ -195,43 +231,33 @@ private:
 
   /**
    * @brief Creates the Dali::Renderer (potentially from the renderer cache), initializing it
-   *
-   * @return Returns the created Dali::Renderer
    */
-  Renderer CreateRenderer() const;
+  void CreateRenderer();
 
   /**
    * @brief Creates the Dali::Renderer for NativeImage with custom sampler type and prefix, initializing it
-   *
-   * @return Returns the created Dali::Renderer
    */
-  Renderer CreateNativeImageRenderer() const;
+  void CreateNativeImageRenderer();
 
   /**
    * @brief Query whether resources requires to be loaded synchronously.
-   * @return Returns true if synchronoud resource loading is required, false otherwise.
+   * @return Returns true if synchronous resource loading is required, false otherwise.
    */
   bool IsSynchronousResourceLoading() const;
 
   /**
-   * @brief Do the synchronous resource loading
-   */
-  void DoSynchronousResourceLoading();
-
-  /**
-   * Load the image.
-   * @param[in] url The URL of the image resource to use.
-   * @param[in] synchronousLoading If true, the resource is loaded synchronously, otherwise asynchronously.
+   * @brief Load the resource synchronously
    */
-  Image LoadImage( const std::string& url, bool synchronousLoading );
+  void LoadResourceSynchronously();
 
   /**
-   * Load the image and create a texture set to hold the texture, with automatic atlasing applied.
-   * @param [out] textureRect The texture area of the resource image in the atlas.
+   * Creates the texture set and adds the texture to it
+   * @param[out] textureRect The texture area of the texture in the atlas.
    * @param[in] url The URL of the image resource to use.
    * @param[in] synchronousLoading If true, the resource is loaded synchronously, otherwise asynchronously.
+   * @param[in] attemptAtlasing If true will attempt atlasing, otherwise create unique texture
    */
-  TextureSet CreateTextureSet( Vector4& textureRect, const std::string& url, bool synchronousLoading );
+  void CreateTextureSet( Vector4& textureRect, const std::string& url, bool synchronousLoading, bool attemptAtlasing );
 
   /**
    * Callback function of image resource loading succeed
@@ -256,20 +282,21 @@ private:
   void SetNativeFragmentShaderCode( Dali::NativeImage& nativeImage );
 
 private:
+
   Image mImage;
   PixelData mPixels;
+  TextureSet mTextureSet;
   Vector4 mPixelArea;
   WeakHandle<Actor> mPlacementActor;
-
   std::string mImageUrl;
-  Dali::ImageDimensions mDesiredSize;
-  Dali::FittingMode::Type mFittingMode;
-  Dali::SamplingMode::Type mSamplingMode;
-  Dali::WrapMode::Type mWrapModeU;
-  Dali::WrapMode::Type mWrapModeV;
-
   std::string mNativeFragmentShaderCode;
-  bool mNativeImageFlag;
+
+  Dali::ImageDimensions mDesiredSize;
+  Dali::FittingMode::Type mFittingMode:3;
+  Dali::SamplingMode::Type mSamplingMode:4;
+  Dali::WrapMode::Type mWrapModeU:3;
+  Dali::WrapMode::Type mWrapModeV:3;
+  bool mNativeImageFlag:1;
 };
 
 } // namespace Internal
index 5f8d4e0..28ff3d1 100644 (file)
@@ -288,7 +288,12 @@ const char* NORMAL_MAP_FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
   }\n
 );
 
-} // namespace
+} // unnamed namespace
+
+MeshVisualPtr MeshVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new MeshVisual( factoryCache );
+}
 
 MeshVisual::MeshVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
index a05f848..1762f46 100644 (file)
@@ -21,6 +21,7 @@
 // EXTERNAL INCLUDES
 #include <fstream>
 #include <string.h>
+#include <dali/public-api/common/intrusive-ptr.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/mesh-visual-properties.h>
@@ -36,6 +37,9 @@ namespace Toolkit
 namespace Internal
 {
 
+class MeshVisual;
+typedef IntrusivePtr< MeshVisual > MeshVisualPtr;
+
 /**
  * The visual which renders a 3D object to the control's quad
  *
@@ -56,16 +60,12 @@ class MeshVisual: public Visual::Base
 public:
 
   /**
-   * @brief Constructor.
+   * @brief Create a new mesh visual.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
    */
-  MeshVisual( VisualFactoryCache& factoryCache );
-
-  /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
-   */
-  virtual ~MeshVisual();
+  static MeshVisualPtr New( VisualFactoryCache& factoryCache );
 
 public:  // from Visual
 
@@ -92,6 +92,18 @@ public:  // from Visual
 protected:
 
   /**
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   */
+  MeshVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~MeshVisual();
+
+  /**
    * @copydoc Visual::Base::DoInitialize
    */
   virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
index 77d522e..036f978 100644 (file)
@@ -200,9 +200,41 @@ void RegisterStretchProperties( Renderer& renderer, const char * uniformName, co
 
 /////////////////NPatchVisual////////////////
 
-NPatchVisual::NPatchVisual( VisualFactoryCache& factoryCache )
+NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new NPatchVisual( factoryCache );
+}
+
+NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache, const std::string& imageUrl, bool borderOnly )
+{
+  NPatchVisual* nPatchVisual = new NPatchVisual( factoryCache, borderOnly );
+  nPatchVisual->mImageUrl = imageUrl;
+
+  NinePatchImage image = NinePatchImage::New( imageUrl );
+  nPatchVisual->InitializeFromImage( image );
+
+  return nPatchVisual;
+}
+
+NPatchVisualPtr NPatchVisual::New( VisualFactoryCache& factoryCache, NinePatchImage image, bool borderOnly )
+{
+  NPatchVisual* nPatchVisual = new NPatchVisual( factoryCache, borderOnly );
+  nPatchVisual->mImage = image;
+
+  nPatchVisual->InitializeFromImage( image );
+
+  return nPatchVisual;
+}
+
+NPatchVisual::NPatchVisual( VisualFactoryCache& factoryCache, bool borderOnly )
 : Visual::Base( factoryCache ),
-  mBorderOnly( false )
+  mImage(),
+  mCroppedImage(),
+  mImageUrl(),
+  mStretchPixelsX(),
+  mStretchPixelsY(),
+  mImageSize(),
+  mBorderOnly( borderOnly )
 {
 }
 
@@ -452,60 +484,6 @@ void NPatchVisual::ChangeRenderer( bool oldBorderOnly, size_t oldGridX, size_t o
   }
 }
 
-void NPatchVisual::SetImage( const std::string& imageUrl, bool borderOnly )
-{
-  bool oldBorderOnly = mBorderOnly;
-  size_t oldGridX = mStretchPixelsX.Size();
-  size_t oldGridY = mStretchPixelsY.Size();
-
-  mBorderOnly = borderOnly;
-  mImage.Reset();
-  if( mImageUrl == imageUrl )
-  {
-    return;
-  }
-
-  mImageUrl = imageUrl;
-  if( mImpl->mRenderer )
-  {
-    NinePatchImage nPatch = NinePatchImage::New( mImageUrl );
-    InitializeFromImage( nPatch );
-
-    ChangeRenderer( oldBorderOnly, oldGridX, oldGridY );
-
-    if( mCroppedImage )
-    {
-      ApplyImageToSampler();
-    }
-  }
-}
-
-void NPatchVisual::SetImage( NinePatchImage image, bool borderOnly )
-{
-  bool oldBorderOnly = mBorderOnly;
-  size_t oldGridX = mStretchPixelsX.Size();
-  size_t oldGridY = mStretchPixelsY.Size();
-
-  mBorderOnly = borderOnly;
-  mImageUrl.empty();
-  if( mImage == image )
-  {
-    return;
-  }
-
-  mImage = image;
-  if( mImpl->mRenderer )
-  {
-    InitializeFromImage( mImage );
-    ChangeRenderer( oldBorderOnly, oldGridX, oldGridY );
-
-    if( mCroppedImage )
-    {
-      ApplyImageToSampler();
-    }
-  }
-}
-
 void NPatchVisual::InitializeFromImage( NinePatchImage nPatch )
 {
   mCroppedImage = nPatch.CreateCroppedBufferImage();
index 366d2b5..07918ee 100644 (file)
  *
  */
 
-// INTERNAL INCLUDES
-#include <dali-toolkit/internal/visuals/visual-base-impl.h>
-
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/images/image.h>
 #include <dali/public-api/images/image-operations.h>
 #include <dali/devel-api/images/nine-patch-image.h>
@@ -29,6 +27,9 @@
 #include <dali/public-api/rendering/sampler.h>
 #include <dali/public-api/rendering/shader.h>
 
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
+
 namespace Dali
 {
 
@@ -38,6 +39,9 @@ namespace Toolkit
 namespace Internal
 {
 
+class NPatchVisual;
+typedef IntrusivePtr< NPatchVisual > NPatchVisualPtr;
+
 /**
  * The visual which renders an 9 patch image to the control's quad
  *
@@ -54,16 +58,32 @@ class NPatchVisual: public Visual::Base
 public:
 
   /**
-   * @brief Constructor.
+   * @brief Create a new n-patch visual.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
    */
-  NPatchVisual( VisualFactoryCache& factoryCache );
+  static NPatchVisualPtr New( VisualFactoryCache& factoryCache );
 
   /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
+   * @brief Create an N-patch visual using an image URL.
+   *
+   * The visual will load the image synchronously when the associated actor is put on stage, and destroy the image when it is off stage
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @param[in] imageUrl The URL to 9 patch image resource to use
+   * @param[in] borderOnly A Flag to indicate if the image should omit the centre of the n-patch and only render the border
+   */
+  static NPatchVisualPtr New( VisualFactoryCache& factoryCache, const std::string& imageUrl, bool borderOnly = false );
+
+  /**
+   * @brief Create an N-patch visual with a NinePatchImage resource.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @param[in] image The NinePatchImage to use
+   * @param[in] borderOnly A Flag to indicate if the image should omit the centre of the n-patch and only render the border
    */
-  ~NPatchVisual();
+  static NPatchVisualPtr New( VisualFactoryCache& factoryCache, NinePatchImage image, bool borderOnly = false );
 
 public:  // from Visual
 
@@ -90,38 +110,32 @@ public:  // from Visual
 protected:
 
   /**
-   * @copydoc Visual::Base::DoInitialize
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @param[in] borderOnly A Flag to indicate if the image should omit the centre of the n-patch and only render the border
    */
-  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
+  NPatchVisual( VisualFactoryCache& factoryCache, bool borderOnly = false );
 
   /**
-   * @copydoc Visual::Base::DoSetOnStage
+   * @brief A reference counted object may only be deleted by calling Unreference().
    */
-  virtual void DoSetOnStage( Actor& actor );
+  virtual ~NPatchVisual();
 
   /**
-   * @copydoc Visual::Base::DoSetOffStage
+   * @copydoc Visual::Base::DoInitialize
    */
-  virtual void DoSetOffStage( Actor& actor );
-
-public:
+  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
 
   /**
-   * @brief Sets the 9 patch image of this visual to the resource at imageUrl
-   * The visual will load the image synchronously when the associated actor is put on stage, and destroy the image when it is off stage
-   *
-   * @param[in] imageUrl The URL to 9 patch image resource to use
-   * @param[in] borderOnly A Flag to indicate if the image should omit the centre of the n-patch and only render the border
+   * @copydoc Visual::Base::DoSetOnStage
    */
-  void SetImage( const std::string& imageUrl, bool borderOnly = false );
+  virtual void DoSetOnStage( Actor& actor );
 
   /**
-   * @brief Sets the 9 patch image of this viusal to the 9 patch image
-   *
-   * @param[in] image The NinePatchImage to use
-   * @param[in] borderOnly A Flag to indicate if the image should omit the centre of the n-patch and only render the border
+   * @copydoc Visual::Base::DoSetOffStage
    */
-  void SetImage( NinePatchImage image, bool borderOnly = false );
+  virtual void DoSetOffStage( Actor& actor );
 
 private:
 
index 956714b..6142ad1 100644 (file)
@@ -160,7 +160,12 @@ const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
   }\n
 );
 
-} // namespace
+} // unnamed namespace
+
+PrimitiveVisualPtr PrimitiveVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new PrimitiveVisual( factoryCache );
+}
 
 PrimitiveVisual::PrimitiveVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
index 04f1d3d..59979f8 100644 (file)
@@ -44,6 +44,8 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
 
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/visuals/primitive-visual-properties.h>
@@ -58,6 +60,9 @@ namespace Toolkit
 namespace Internal
 {
 
+class PrimitiveVisual;
+typedef IntrusivePtr< PrimitiveVisual > PrimitiveVisualPtr;
+
 /**
  * The visual which renders a simple 3D shape to the control's quad
  *
@@ -97,16 +102,12 @@ class PrimitiveVisual: public Visual::Base
 public:
 
   /**
-   * @brief Constructor.
+   * @brief Create a new primitive visual.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
    */
-  PrimitiveVisual( VisualFactoryCache& factoryCache );
-
-  /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
-   */
-  virtual ~PrimitiveVisual();
+  static PrimitiveVisualPtr New( VisualFactoryCache& factoryCache );
 
 public:  // from Visual
 
@@ -138,6 +139,18 @@ public:  // from Visual
 protected:
 
   /**
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   */
+  PrimitiveVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~PrimitiveVisual();
+
+  /**
    * @copydoc Visual::Base::DoInitialize
    */
   virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
index 6c0bcfb..f3ad956 100644 (file)
@@ -53,10 +53,24 @@ namespace Toolkit
 namespace Internal
 {
 
+SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new SvgVisual( factoryCache );
+}
+
+SvgVisualPtr SvgVisual::New( VisualFactoryCache& factoryCache, const std::string& imageUrl, ImageDimensions size )
+{
+  SvgVisual* svgVisual = new SvgVisual( factoryCache );
+  svgVisual->ParseFromUrl( imageUrl, size );
+  return svgVisual;
+}
+
 SvgVisual::SvgVisual( VisualFactoryCache& factoryCache )
 : Visual::Base( factoryCache ),
   mAtlasRect( FULL_TEXTURE_RECT ),
-  mParsedImage( NULL )
+  mImageUrl(),
+  mParsedImage( NULL ),
+  mPlacementActor()
 {
   // the rasterized image is with pre-multiplied alpha format
   mImpl->mFlags |= Impl::IS_PREMULTIPLIED_ALPHA;
@@ -78,7 +92,7 @@ void SvgVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
     std::string imageUrl;
     if( imageURLValue->Get( imageUrl ) )
     {
-      SetImage( imageUrl );
+      ParseFromUrl( imageUrl );
     }
     else
     {
@@ -133,7 +147,7 @@ void SvgVisual::GetNaturalSize( Vector2& naturalSize ) const
 
 void SvgVisual::SetSize( const Vector2& size )
 {
-  if(mImpl->mSize != size && mParsedImage && GetIsOnStage() )
+  if(mImpl->mSize != size && mParsedImage && IsOnStage() )
   {
     AddRasterizationTask( size );
   }
@@ -161,30 +175,18 @@ Dali::Property::Value SvgVisual::DoGetProperty( Dali::Property::Index index )
   return Dali::Property::Value();
 }
 
-void SvgVisual::SetImage( const std::string& imageUrl, ImageDimensions size )
+void SvgVisual::ParseFromUrl( const std::string& imageUrl, ImageDimensions size )
 {
-  if( mImageUrl != imageUrl )
-  {
-    mImageUrl = imageUrl;
-
-    NSVGimage* parsedImageOld = mParsedImage;
+  mImageUrl = imageUrl;
 
-    Vector2 dpi = Stage::GetCurrent().GetDpi();
-    float meanDpi = (dpi.height + dpi.width) * 0.5f;
-    mParsedImage = nsvgParseFromFile(mImageUrl.c_str(), UNITS, meanDpi);
+  Vector2 dpi = Stage::GetCurrent().GetDpi();
+  float meanDpi = (dpi.height + dpi.width) * 0.5f;
+  mParsedImage = nsvgParseFromFile( imageUrl.c_str(), UNITS, meanDpi );
 
-    if( size.GetWidth() != 0u && size.GetHeight() != 0u)
-    {
-      mImpl->mSize.x = size.GetWidth();
-      mImpl->mSize.y = size.GetHeight();
-    }
-
-    if( mImpl->mSize != Vector2::ZERO && GetIsOnStage() )
-    {
-      AddRasterizationTask( mImpl->mSize );
-    }
-
-    mFactoryCache.GetSVGRasterizationThread()->DeleteImage( parsedImageOld );
+  if( size.GetWidth() != 0u && size.GetHeight() != 0u)
+  {
+    mImpl->mSize.x = size.GetWidth();
+    mImpl->mSize.y = size.GetHeight();
   }
 }
 
@@ -203,7 +205,7 @@ void SvgVisual::AddRasterizationTask( const Vector2& size )
 
 void SvgVisual::ApplyRasterizedImage( PixelData rasterizedPixelData )
 {
-  if( GetIsOnStage()  )
+  if( IsOnStage()  )
   {
     TextureSet currentTextureSet = mImpl->mRenderer.GetTextures();
     if( mAtlasRect != FULL_TEXTURE_RECT )
@@ -225,8 +227,9 @@ void SvgVisual::ApplyRasterizedImage( PixelData rasterizedPixelData )
     }
     else // no atlasing
     {
-      Atlas texture = Atlas::New( rasterizedPixelData.GetWidth(), rasterizedPixelData.GetHeight() );
-      texture.Upload( rasterizedPixelData, 0, 0 );
+      Texture texture = Texture::New( Dali::TextureType::TEXTURE_2D, Pixel::RGBA8888,
+                                      rasterizedPixelData.GetWidth(), rasterizedPixelData.GetHeight() );
+      texture.Upload( rasterizedPixelData );
       mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
 
       if( mAtlasRect == FULL_TEXTURE_RECT )
@@ -244,7 +247,7 @@ void SvgVisual::ApplyRasterizedImage( PixelData rasterizedPixelData )
 
       if( textureSet )
       {
-        TextureSetImage( textureSet, 0u, texture );
+        textureSet.SetTexture( 0, texture );
       }
     }
 
index c040f47..5dbd24e 100644 (file)
@@ -18,7 +18,8 @@
  *
  */
 
-//EXTERNAL INCLUDES
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/devel-api/object/weak-handle.h>
 
 // INTERNAL INCLUDES
@@ -35,6 +36,9 @@ namespace Toolkit
 namespace Internal
 {
 
+class SvgVisual;
+typedef IntrusivePtr< SvgVisual > SvgVisualPtr;
+
 /**
  * The visual which renders a svg image
  *
@@ -50,16 +54,24 @@ class SvgVisual: public Visual::Base
 public:
 
   /**
-   * @brief Constructor.
+   * @brief Create a new SVG visual.
    *
    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
    */
-  SvgVisual( VisualFactoryCache& factoryCache );
+  static SvgVisualPtr New( VisualFactoryCache& factoryCache );
 
   /**
-   * @brief A reference counted object may only be deleted by calling Unreference().
+   * @brief Create the SVG Visual using the image URL.
+   *
+   * The visual will parse the SVG image once it is set.
+   * And rasterize it into BufferImage synchronously when the associated actor is put on stage, and destroy the BufferImage when it is off stage
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @param[in] imageUrl The URL to svg resource to use
+   * @param[in] size The required size for the SVG
    */
-  ~SvgVisual();
+  static SvgVisualPtr New( VisualFactoryCache& factoryCache, const std::string& imageUrl, ImageDimensions size = ImageDimensions() );
 
 public:  // from Visual
 
@@ -91,6 +103,18 @@ public:  // from Visual
 protected:
 
   /**
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   */
+  SvgVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~SvgVisual();
+
+  /**
    * @copydoc Visual::Base::DoInitialize
    */
   virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
@@ -108,15 +132,6 @@ protected:
 public:
 
   /**
-   * @brief Sets the svg image of this visual to the resource at imageUrl
-   * The visual will parse the svg image once it is set.
-   * And rasterize it into BufferImage synchronously when the associated actor is put on stage, and destroy the BufferImage when it is off stage
-   *
-   * @param[in] imageUrl The URL to svg resource to use
-   */
-  void SetImage( const std::string& imageUrl, ImageDimensions size = ImageDimensions() );
-
-  /**
    * @bried Apply the rasterized image to the visual.
    *
    * @param[in] rasterizedPixelData The pixel buffer with the rasterized pixels
@@ -124,6 +139,15 @@ public:
   void ApplyRasterizedImage( PixelData rasterizedPixelData );
 
 private:
+
+  /**
+   * @brief Parses the SVG Image from the set URL.
+   *
+   * @param[in] imageUrl The URL of the image to parse the SVG from.
+   * @param[in] size The required size of the SVG
+   */
+  void ParseFromUrl( const std::string& imageUrl, ImageDimensions size = ImageDimensions() );
+
   /**
    * @bried Rasterize the svg with the given size, and add it to the visual.
    *
diff --git a/dali-toolkit/internal/visuals/text/text-visual.cpp b/dali-toolkit/internal/visuals/text/text-visual.cpp
new file mode 100644 (file)
index 0000000..3f9dd1e
--- /dev/null
@@ -0,0 +1,874 @@
+/*
+ * Copyright (c) 2016 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include <dali-toolkit/internal/visuals/text/text-visual.h>
+
+// EXTERNAL HEADER
+#include <dali/devel-api/scripting/enum-helper.h>
+// #include <dali/devel-api/scripting/scripting.h>
+
+// INTERNAL HEADER
+#include <dali-toolkit/public-api/text/rendering-backend.h>
+#include <dali-toolkit/public-api/visuals/text-visual-properties.h>
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/internal/text/rendering/text-backend.h>
+#include <dali-toolkit/internal/text/text-view.h>
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
+#include <dali-toolkit/internal/text/text-font-style.h>
+#include <dali-toolkit/internal/text/text-effects-style.h>
+
+using Dali::Toolkit::Text::LayoutEngine;
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+namespace
+{
+
+// Property names.
+const char * const RENDERING_BACKEND_PROPERTY( "renderingBackend" );
+const char * const TEXT_PROPERTY( "text" );
+const char * const FONT_FAMILY_PROPERTY( "fontFamily" );
+const char * const FONT_STYLE_PROPERTY( "fontStyle" );
+const char * const POINT_SIZE_PROPERTY( "pointSize" );
+const char * const MULTI_LINE_PROPERTY( "multiLine" );
+const char * const HORIZONTAL_ALIGNMENT_PROPERTY( "horizontalAlignment" );
+const char * const VERTICAL_ALIGNMENT_PROPERTY( "verticalAlignment" );
+const char * const TEXT_COLOR_PROPERTY( "textColor" );
+const char * const ENABLE_MARKUP_PROPERTY( "enableMarkup" );
+const char * const ENABLE_AUTO_SCROLL_PROPERTY( "enableAutoScroll" );
+const char * const AUTO_SCROLL_SPEED_PROPERTY( "autoScrollSpeed" );
+const char * const AUTO_SCROLL_LOOP_COUNT_PROPERTY( "autoScrollLoopCount" );
+const char * const AUTO_SCROLL_GAP_PROPERTY( "autoScrollGap" );
+const char * const LINE_SPACING_PROPERTY( "lineSpacing" );
+const char * const UNDERLINE_PROPERTY( "underline" );
+const char * const SHADOW_PROPERTY( "shadow" );
+const char * const OUTLINE_PROPERTY( "outline" );
+const char * const BATCHING_ENABLED_PROPERTY( "batchingEnabled" );
+
+const Scripting::StringEnum HORIZONTAL_ALIGNMENT_STRING_TABLE[] =
+{
+  { "BEGIN",  Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_BEGIN  },
+  { "CENTER", Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_CENTER },
+  { "END",    Toolkit::Text::LayoutEngine::HORIZONTAL_ALIGN_END    },
+};
+const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
+
+const Scripting::StringEnum VERTICAL_ALIGNMENT_STRING_TABLE[] =
+{
+  { "TOP",    Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_TOP    },
+  { "CENTER", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_CENTER },
+  { "BOTTOM", Toolkit::Text::LayoutEngine::VERTICAL_ALIGN_BOTTOM },
+};
+const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
+
+std::string GetHorizontalAlignment( LayoutEngine::HorizontalAlignment alignment )
+{
+  const char* name = Scripting::GetEnumerationName<Toolkit::Text::LayoutEngine::HorizontalAlignment>( alignment,
+                                                                                                      HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                                      HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+
+  return std::string( name );
+}
+
+std::string GetVerticalAlignment( LayoutEngine::VerticalAlignment alignment )
+{
+  const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( alignment,
+                                                                                                      VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                                      VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+
+  return std::string( name );
+}
+
+const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
+  attribute mediump vec2 aPosition;\n
+  uniform mediump mat4 uMvpMatrix;\n
+  uniform mediump vec3 uSize;\n
+  uniform mediump vec4 pixelArea;
+  varying mediump vec2 vTexCoord;\n
+  \n
+  void main()\n
+  {\n
+    mediump vec4 vertexPosition = vec4(aPosition, 0.0, 1.0);\n
+    vertexPosition.xyz *= uSize;\n
+    vertexPosition = uMvpMatrix * vertexPosition;\n
+    \n
+    vTexCoord = pixelArea.xy+pixelArea.zw*(aPosition + vec2(0.5) );\n
+    gl_Position = vertexPosition;\n
+  }\n
+);
+
+const char* FRAGMENT_SHADER_ATLAS_CLAMP = DALI_COMPOSE_SHADER(
+    varying mediump vec2 vTexCoord;\n
+    uniform sampler2D sTexture;\n
+    uniform mediump vec4 uAtlasRect;\n
+    uniform lowp vec4 uColor;\n
+    \n
+    void main()\n
+    {\n
+      mediump vec2 texCoord = clamp( mix( uAtlasRect.xy, uAtlasRect.zw, vTexCoord ), uAtlasRect.xy, uAtlasRect.zw );\n
+      gl_FragColor = texture2D( sTexture, texCoord ) * uColor;\n
+    }\n
+);
+
+Geometry CreateGeometry( VisualFactoryCache& factoryCache, ImageDimensions gridSize )
+{
+  Geometry geometry;
+
+  if( gridSize == ImageDimensions( 1, 1 ) )
+  {
+    geometry = factoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
+    if( !geometry )
+    {
+      geometry =  VisualFactoryCache::CreateQuadGeometry();
+      factoryCache.SaveGeometry( VisualFactoryCache::QUAD_GEOMETRY, geometry );
+    }
+  }
+  else
+  {
+    geometry = VisualFactoryCache::CreateGridGeometry( gridSize );
+  }
+
+  return geometry;
+}
+
+} // unnamed namespace
+
+TextVisualPtr TextVisual::New( VisualFactoryCache& factoryCache )
+{
+  return new TextVisual( factoryCache );
+}
+
+void TextVisual::SetTextControlInterface( Text::ControlInterface* controlInterface )
+{
+  if( mController )
+  {
+    mController->SetTextControlInterface( controlInterface );
+  }
+}
+
+void TextVisual::SetSize( const Vector2& size )
+{
+  const Text::Controller::UpdateTextType updateTextType = mController->Relayout( size );
+
+  if( ( Text::Controller::NONE_UPDATED != ( Text::Controller::MODEL_UPDATED & updateTextType ) ) ||
+      !mRenderer )
+  {
+    if( !mRenderer )
+    {
+      mRenderer = Text::Backend::Get().NewRenderer( mRenderingBackend );
+    }
+
+    RenderText();
+  }
+}
+
+float TextVisual::GetHeightForWidth( float width ) const
+{
+  return mController->GetHeightForWidth( width );
+}
+
+void TextVisual::GetNaturalSize( Vector2& naturalSize ) const
+{
+  naturalSize = mController->GetNaturalSize().GetVectorXY();
+}
+
+void TextVisual::DoCreatePropertyMap( Property::Map& map ) const
+{
+  Property::Value value;
+
+  map.Clear();
+  map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::Visual::TEXT );
+
+  map.Insert( Toolkit::TextVisual::Property::RENDERING_BACKEND, mRenderingBackend );
+
+  std::string text;
+  mController->GetText( text );
+  map.Insert( Toolkit::TextVisual::Property::TEXT, text );
+
+  map.Insert( Toolkit::TextVisual::Property::FONT_FAMILY, mController->GetDefaultFontFamily() );
+
+  GetFontStyleProperty( mController, value, Text::FontStyle::DEFAULT );
+  map.Insert( Toolkit::TextVisual::Property::FONT_STYLE, value );
+
+  map.Insert( Toolkit::TextVisual::Property::POINT_SIZE, mController->GetDefaultPointSize() );
+
+  map.Insert( Toolkit::TextVisual::Property::MULTI_LINE, mController->IsMultiLineEnabled() );
+
+  map.Insert( Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT, GetHorizontalAlignment( mController->GetHorizontalAlignment() ) );
+
+  map.Insert( Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT, GetVerticalAlignment( mController->GetVerticalAlignment() ) );
+
+  map.Insert( Toolkit::TextVisual::Property::TEXT_COLOR, mController->GetTextColor() );
+
+  map.Insert( Toolkit::TextVisual::Property::ENABLE_MARKUP, mController->IsMarkupProcessorEnabled() );
+
+  map.Insert( Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL, mController->IsAutoScrollEnabled() );
+
+  map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED, mController->GetAutoScrollSpeed() );
+
+  map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT, mController->GetAutoScrollLoopCount() );
+
+  map.Insert( Toolkit::TextVisual::Property::AUTO_SCROLL_GAP, mController->GetAutoScrollWrapGap() );
+
+  map.Insert( Toolkit::TextVisual::Property::LINE_SPACING, mController->GetDefaultLineSpacing() );
+
+  GetUnderlineProperties( mController, value, Text::EffectStyle::DEFAULT );
+  map.Insert( Toolkit::TextVisual::Property::UNDERLINE, value );
+
+  GetShadowProperties( mController, value, Text::EffectStyle::DEFAULT );
+  map.Insert( Toolkit::TextVisual::Property::SHADOW, value );
+
+  GetOutlineProperties( mController, value, Text::EffectStyle::DEFAULT );
+  map.Insert( Toolkit::TextVisual::Property::OUTLINE, value );
+
+  map.Insert( Toolkit::TextVisual::Property::BATCHING_ENABLED, false ); // TODO
+}
+
+TextVisual::TextVisual( VisualFactoryCache& factoryCache )
+: Visual::Base( factoryCache ),
+  mController( Text::Controller::New() ),
+  mRenderingBackend( Toolkit::Text::DEFAULT_RENDERING_BACKEND ),
+  mHasBeenStaged( false )
+{
+}
+
+TextVisual::~TextVisual()
+{
+}
+
+void TextVisual::DoInitialize( Actor& actor, const Property::Map& propertyMap )
+{
+  mSelf = actor;
+
+  for( Property::Map::SizeType index = 0u, count = propertyMap.Count(); index < count; ++index )
+  {
+    const KeyValuePair& keyValue = propertyMap.GetKeyValue( index );
+
+    switch( keyValue.first.type )
+    {
+      case Property::Key::INDEX:
+      {
+        if( Toolkit::Visual::Property::TYPE != keyValue.first.indexKey ) // Toolkit::Visual::Property::TYPE is not a TextVisual's property.
+        {
+          DoSetProperty( keyValue.first.indexKey, keyValue.second );
+        }
+        break;
+      }
+      case Property::Key::STRING:
+      {
+        if( keyValue.first.stringKey == RENDERING_BACKEND_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::RENDERING_BACKEND, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == TEXT_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::TEXT, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == FONT_FAMILY_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::FONT_FAMILY, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == FONT_STYLE_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::FONT_STYLE, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == POINT_SIZE_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::POINT_SIZE, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == MULTI_LINE_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::MULTI_LINE, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == HORIZONTAL_ALIGNMENT_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == VERTICAL_ALIGNMENT_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == TEXT_COLOR_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::TEXT_COLOR, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == ENABLE_MARKUP_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::ENABLE_MARKUP, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == ENABLE_AUTO_SCROLL_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == AUTO_SCROLL_SPEED_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == AUTO_SCROLL_LOOP_COUNT_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == AUTO_SCROLL_GAP_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::AUTO_SCROLL_GAP, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == LINE_SPACING_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::LINE_SPACING, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == UNDERLINE_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::UNDERLINE, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == SHADOW_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::SHADOW, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == OUTLINE_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::OUTLINE, keyValue.second );
+        }
+        else if( keyValue.first.stringKey == BATCHING_ENABLED_PROPERTY )
+        {
+          DoSetProperty( Toolkit::TextVisual::Property::BATCHING_ENABLED, keyValue.second );
+        }
+        break;
+      }
+    }
+  }
+
+  // Retrieve the layout engine to set whether to elide the text and set the cursor's width.
+  Text::LayoutEngine& engine = mController->GetLayoutEngine();
+
+  // Elide the text if it exceeds the boundaries.
+  engine.SetTextEllipsisEnabled( true );
+
+  // Sets 0 as cursor's width.
+  engine.SetCursorWidth( 0u ); // Do not layout space for the cursor.
+}
+
+void TextVisual::DoSetOnStage( Actor& actor )
+{
+  // TODO Create the actual renderer(s) for the text!!!!
+  //      Will crash if no mImpl->mRenderer is set.
+  Geometry geometry;
+  Shader shader;
+
+  geometry = CreateGeometry( mFactoryCache, ImageDimensions( 1, 1 ) );
+
+  shader = mFactoryCache.GetShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP );
+  if( !shader )
+  {
+    shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER_ATLAS_CLAMP );
+    mFactoryCache.SaveShader( VisualFactoryCache::IMAGE_SHADER_ATLAS_DEFAULT_WRAP, shader );
+  }
+
+  mImpl->mRenderer = Renderer::New( geometry, shader );
+
+  mSelf = actor;
+
+  if( mHasBeenStaged )
+  {
+    RenderText();
+  }
+  else
+  {
+    mHasBeenStaged = true;
+  }
+}
+
+void TextVisual::DoSetOffStage( Actor& actor )
+{
+  mSelf.Reset();
+}
+
+void TextVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
+{
+  switch( index )
+  {
+    case Toolkit::TextVisual::Property::RENDERING_BACKEND:
+    {
+      int backend = propertyValue.Get<int>();
+
+#ifndef ENABLE_VECTOR_BASED_TEXT_RENDERING
+      if( Text::RENDERING_VECTOR_BASED == backend )
+      {
+        backend = TextAbstraction::BITMAP_GLYPH; // Fallback to bitmap-based rendering
+      }
+#endif
+      if( mRenderingBackend != backend )
+      {
+        mRenderingBackend = backend;
+        mRenderer.Reset();
+
+        // When using the vector-based rendering, the size of the GLyphs are different
+        TextAbstraction::GlyphType glyphType = ( Text::RENDERING_VECTOR_BASED == mRenderingBackend ) ? TextAbstraction::VECTOR_GLYPH : TextAbstraction::BITMAP_GLYPH;
+        mController->SetGlyphType( glyphType );
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::TEXT:
+    {
+      mController->SetText( propertyValue.Get<std::string>() );
+      break;
+    }
+    case Toolkit::TextVisual::Property::FONT_FAMILY:
+    {
+      SetFontFamilyProperty( mController, propertyValue );
+      break;
+    }
+    case Toolkit::TextVisual::Property::FONT_STYLE:
+    {
+      SetFontStyleProperty( mController, propertyValue, Text::FontStyle::DEFAULT );
+      break;
+    }
+    case Toolkit::TextVisual::Property::POINT_SIZE:
+    {
+      const float pointSize = propertyValue.Get<float>();
+
+      if( !Equals( mController->GetDefaultPointSize(), pointSize ) )
+      {
+        mController->SetDefaultPointSize( pointSize );
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::MULTI_LINE:
+    {
+      mController->SetMultiLineEnabled( propertyValue.Get<bool>() );
+      break;
+    }
+    case Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT:
+    {
+      LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
+      if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( propertyValue.Get< std::string >().c_str(),
+                                                                                         HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                         HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                                         alignment ) )
+      {
+        mController->SetHorizontalAlignment( alignment );
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT:
+    {
+      LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
+      if( Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( propertyValue.Get< std::string >().c_str(),
+                                                                                       VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                       VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                                       alignment ) )
+      {
+        mController->SetVerticalAlignment( alignment );
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::TEXT_COLOR:
+    {
+      const Vector4 textColor = propertyValue.Get< Vector4 >();
+      if( mController->GetTextColor() != textColor )
+      {
+        mController->SetTextColor( textColor );
+        mRenderer.Reset();
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::ENABLE_MARKUP:
+    {
+      const bool enableMarkup = propertyValue.Get<bool>();
+      mController->SetMarkupProcessorEnabled( enableMarkup );
+      break;
+    }
+    case Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL:
+    {
+      const bool enableAutoScroll = propertyValue.Get<bool>();
+
+      // If request to auto scroll is the same as current state then do nothing.
+      if( enableAutoScroll != mController->IsAutoScrollEnabled() )
+      {
+        // If request is disable (false) and auto scrolling is enabled then need to stop it
+        if( !enableAutoScroll )
+        {
+          StopTextAutoScrolling(); // Causes the current animation to finish playing.
+        }
+        // If request is enable (true) then start autoscroll as not already running
+        else
+        {
+          mController->GetLayoutEngine().SetTextEllipsisEnabled( false );
+          mController->SetAutoScrollEnabled( enableAutoScroll );
+          mController->RequestRelayout();
+        }
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED:
+    {
+      mController->SetAutoscrollSpeed( propertyValue.Get<int>() );
+      break;
+    }
+    case Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT:
+    {
+      const int loopCount = propertyValue.Get<int>();
+      if( loopCount > 0 )
+      {
+        mController->SetAutoScrollLoopCount( loopCount );
+      }
+      else
+      {
+        StopTextAutoScrolling(); // Causes the current animation to finish playing.
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::AUTO_SCROLL_GAP:
+    {
+      mController->SetAutoScrollWrapGap( propertyValue.Get<float>() );
+      break;
+    }
+    case Toolkit::TextVisual::Property::LINE_SPACING:
+    {
+      const float lineSpacing = propertyValue.Get<float>();
+      mController->SetDefaultLineSpacing( lineSpacing );
+      mRenderer.Reset();
+      break;
+    }
+    case Toolkit::TextVisual::Property::UNDERLINE:
+    {
+      // TODO : This switch can be removed when the deprecated SHADOW_OFFSET and SHADOW_COLOR properties are finally removed.
+      //        Only the code for the STRING case should be kept.
+      switch( propertyValue.GetType() )
+      {
+        case Property::VECTOR4:
+        {
+          const Vector4 color = propertyValue.Get<Vector4>();
+          if( mController->GetUnderlineColor() != color )
+          {
+            mController->SetUnderlineColor( color );
+            mRenderer.Reset();
+          }
+          break;
+        }
+        case Property::FLOAT:
+        {
+          float height = propertyValue.Get<float>();
+          if( fabsf( mController->GetUnderlineHeight() - height ) > Math::MACHINE_EPSILON_1000 )
+          {
+            mController->SetUnderlineHeight( height );
+            mRenderer.Reset();
+          }
+          break;
+        }
+        case Property::BOOLEAN:
+        {
+          const bool enabled = propertyValue.Get<bool>();
+          if( mController->IsUnderlineEnabled() != enabled )
+          {
+            mController->SetUnderlineEnabled( enabled );
+            mRenderer.Reset();
+          }
+          break;
+        }
+        case Property::STRING:
+        {
+          const bool update = SetUnderlineProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
+          if( update )
+          {
+            mRenderer.Reset();
+          }
+          break;
+        }
+        default:
+        {
+          // Nothing to do.
+          break;
+        }
+      }
+
+      break;
+    }
+    case Toolkit::TextVisual::Property::SHADOW:
+    {
+      // TODO : This switch can be removed when the deprecated SHADOW_OFFSET and SHADOW_COLOR properties are finally removed.
+      //        Only the code for the STRING case should be kept.
+      switch( propertyValue.GetType() )
+      {
+        case Property::VECTOR2:
+        {
+          const Vector2 shadowOffset = propertyValue.Get<Vector2>();
+          if( mController->GetShadowOffset() != shadowOffset )
+          {
+            mController->SetShadowOffset( shadowOffset );
+            mRenderer.Reset();
+          }
+          break;
+        }
+        case Property::VECTOR4:
+        {
+          const Vector4 shadowColor = propertyValue.Get<Vector4>();
+          if( mController->GetShadowColor() != shadowColor )
+          {
+            mController->SetShadowColor( shadowColor );
+            mRenderer.Reset();
+          }
+          break;
+        }
+        case Property::STRING:
+        {
+          const bool update = SetShadowProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
+          if( update )
+          {
+            mRenderer.Reset();
+          }
+          break;
+        }
+        default:
+        {
+          // Nothing to do.
+          break;
+        }
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::EMBOSS:
+    {
+      const bool update = SetEmbossProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
+      if( update )
+      {
+        mRenderer.Reset();
+     }
+      break;
+    }
+    case Toolkit::TextVisual::Property::OUTLINE:
+    {
+      const bool update = SetOutlineProperties( mController, propertyValue, Text::EffectStyle::DEFAULT );
+      if( update )
+      {
+        mRenderer.Reset();
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::BATCHING_ENABLED:
+    {
+      // TODO
+      break;
+    }
+    default:
+    {
+      // Should not arrive here.
+      DALI_ASSERT_DEBUG( false );
+    }
+  }
+}
+
+Dali::Property::Value TextVisual::DoGetProperty( Dali::Property::Index index )
+{
+  Dali::Property::Value value;
+
+  switch( index )
+  {
+    case Toolkit::TextVisual::Property::RENDERING_BACKEND:
+    {
+      value = mRenderingBackend;
+      break;
+    }
+    case Toolkit::TextVisual::Property::TEXT:
+    {
+      std::string text;
+      mController->GetText( text );
+      value = text;
+      break;
+    }
+    case Toolkit::TextVisual::Property::FONT_FAMILY:
+    {
+      value = mController->GetDefaultFontFamily();
+      break;
+    }
+    case Toolkit::TextVisual::Property::FONT_STYLE:
+    {
+      GetFontStyleProperty( mController, value, Text::FontStyle::DEFAULT );
+      break;
+    }
+    case Toolkit::TextVisual::Property::POINT_SIZE:
+    {
+      value = mController->GetDefaultPointSize();
+      break;
+    }
+    case Toolkit::TextVisual::Property::MULTI_LINE:
+    {
+      value = mController->IsMultiLineEnabled();
+      break;
+    }
+    case Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT:
+    {
+      const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( mController->GetHorizontalAlignment(),
+                                                                                                            HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                                            HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+      if( name )
+      {
+        value = std::string( name );
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT:
+    {
+      const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( mController->GetVerticalAlignment(),
+                                                                                                          VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                                          VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+      if( name )
+      {
+        value = std::string( name );
+      }
+      break;
+    }
+    case Toolkit::TextVisual::Property::TEXT_COLOR:
+    {
+      value = mController->GetTextColor();
+      break;
+    }
+    case Toolkit::TextVisual::Property::ENABLE_MARKUP:
+    {
+      value = mController->IsMarkupProcessorEnabled();
+      break;
+    }
+    case Toolkit::TextVisual::Property::ENABLE_AUTO_SCROLL:
+    {
+      value = mController->IsAutoScrollEnabled();
+      break;
+    }
+    case Toolkit::TextVisual::Property::AUTO_SCROLL_SPEED:
+    {
+      value = mController->GetAutoScrollSpeed();
+      break;
+    }
+    case Toolkit::TextVisual::Property::AUTO_SCROLL_LOOP_COUNT:
+    {
+      value = mController->GetAutoScrollLoopCount();
+      break;
+    }
+    case Toolkit::TextVisual::Property::AUTO_SCROLL_GAP:
+    {
+      value = mController->GetAutoScrollWrapGap();
+      break;
+    }
+    case Toolkit::TextVisual::Property::LINE_SPACING:
+    {
+      value = mController->GetDefaultLineSpacing();
+      break;
+    }
+    case Toolkit::TextVisual::Property::UNDERLINE:
+    {
+      GetUnderlineProperties( mController, value, Text::EffectStyle::DEFAULT );
+      break;
+    }
+    case Toolkit::TextVisual::Property::SHADOW:
+    {
+      GetShadowProperties( mController, value, Text::EffectStyle::DEFAULT );
+      break;
+    }
+    case Toolkit::TextVisual::Property::EMBOSS:
+    {
+      GetEmbossProperties( mController, value, Text::EffectStyle::DEFAULT );
+      break;
+    }
+    case Toolkit::TextVisual::Property::OUTLINE:
+    {
+      GetOutlineProperties( mController, value, Text::EffectStyle::DEFAULT );
+      break;
+    }
+    case Toolkit::TextVisual::Property::BATCHING_ENABLED:
+    {
+      // TODO
+      break;
+    }
+    default:
+    {
+      // Should not arrive here.
+      DALI_ASSERT_DEBUG( false );
+    }
+  }
+
+  return value;
+}
+
+void TextVisual::RenderText()
+{
+  Actor renderableActor;
+
+  if( mRenderer )
+  {
+    renderableActor = mRenderer->Render( mController->GetView(), Toolkit::DepthIndex::TEXT );
+  }
+
+  if( renderableActor != mRenderableActor )
+  {
+    UnparentAndReset( mRenderableActor );
+
+    if( renderableActor )
+    {
+      const Vector2& scrollOffset = mController->GetScrollPosition();
+      renderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
+
+      mSelf.Add( renderableActor );
+    }
+    mRenderableActor = renderableActor;
+
+    if( mController->IsAutoScrollEnabled() )
+    {
+      SetUpAutoScrolling();
+    }
+  }
+}
+
+void TextVisual::StopTextAutoScrolling()
+{
+  if( mTextScroller )
+  {
+    mTextScroller->StopScrolling();
+  }
+}
+
+void TextVisual::SetUpAutoScrolling()
+{
+  const Text::ScrollerData* const data = mController->GetAutoScrollData();
+
+  if( NULL != data )
+  {
+    if( !mTextScroller )
+    {
+      // If speed, loopCount or gap not set via property system then will need to create a TextScroller with defaults
+      mTextScroller = Text::TextScroller::New( *mController );
+    }
+
+    mTextScroller->StartScrolling( mRenderableActor,
+                                   *data );
+
+    mSelf.Add( mTextScroller->GetScrollingText() );
+    mSelf.Add( mTextScroller->GetSourceCamera() );
+  }
+}
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/visuals/text/text-visual.h b/dali-toolkit/internal/visuals/text/text-visual.h
new file mode 100644 (file)
index 0000000..c609990
--- /dev/null
@@ -0,0 +1,187 @@
+#ifndef DALI_TOOLKIT_INTERNAL_TEXT_VISUAL_H
+#define DALI_TOOLKIT_INTERNAL_TEXT_VISUAL_H
+
+/*
+ * Copyright (c) 2016 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/text/rendering/text-renderer.h>
+#include <dali-toolkit/internal/text/text-controller.h>
+#include <dali-toolkit/internal/text/text-scroller.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Internal
+{
+
+class TextVisual;
+typedef IntrusivePtr< TextVisual > TextVisualPtr;
+
+/**
+ * The visual which renders text
+ *
+ * The following properties are optional:
+ *
+ * | %Property Name      | Type    |
+ * |---------------------|---------|
+ * | renderingBackend    | INTEGER |
+ * | text                | STRING  |
+ * | fontFamily          | STRING  |
+ * | fontStyle           | STRING  |
+ * | pointSize           | FLOAT   |
+ * | multiLine           | BOOLEAN |
+ * | horizontalAlignment | STRING  |
+ * | verticalAlignment   | STRING  |
+ * | textColor           | VECTOR4 |
+ * | enableMarkup        | BOOLEAN |
+ * | enableAutoScroll    | BOOLEAN |
+ * | autoScrollSpeed     | INTEGER |
+ * | autoScrollLoopCount | INTEGER |
+ * | autoScrollGap       | INTEGER |
+ * | lineSpacing         | FLOAT   |
+ * | underline           | STRING  |
+ * | shadow              | STRING  |
+ * | outline             | STRING  |
+ * | batchingEnabled     | BOOLEAN |
+ *
+ */
+class TextVisual : public Visual::Base
+{
+public:
+
+  /**
+   * @brief Create a new text visual.
+   *
+   * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
+   * @return A smart-pointer to the newly allocated visual.
+   */
+  static TextVisualPtr New( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief Sets the text control interface which is needed to communicate with a control.
+   * @param[in] controlInterface Pointer to the control-interface.
+   */
+  void SetTextControlInterface( Text::ControlInterface* controlInterface );
+
+public: // from Visual::Base
+
+  /**
+   * @copydoc Visual::Base::GetHeightForWidth()
+   */
+  float GetHeightForWidth( float width ) const;
+
+  /**
+   * @copydoc Visual::Base::GetNaturalSize()
+   */
+  virtual void SetSize( const Vector2& size );
+
+  /**
+   * @copydoc Visual::Base::GetNaturalSize()
+   */
+  virtual void GetNaturalSize( Vector2& naturalSize ) const;
+
+  /**
+   * @copydoc Visual::Base::CreatePropertyMap()
+   */
+  virtual void DoCreatePropertyMap( Property::Map& map ) const;
+
+protected:
+
+  /**
+   * @brief Constructor.
+   *
+   * @param[in] factoryCache The VisualFactoryCache object
+   */
+  TextVisual( VisualFactoryCache& factoryCache );
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   */
+  virtual ~TextVisual();
+
+  // from Visual::Base
+
+  /**
+   * @copydoc Visual::Base::DoInitialize()
+   */
+  virtual void DoInitialize( Actor& actor, const Property::Map& propertyMap );
+
+  /**
+   * @copydoc Visual::Base::DoSetOnStage()
+   */
+  virtual void DoSetOnStage( Actor& actor );
+
+  /**
+   * @copydoc Visual::Base::DoSetOffStage()
+   */
+  virtual void DoSetOffStage( Actor& actor );
+
+  /**
+   *@copydoc Visual::Base::DoSetProperty
+   */
+  virtual void DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
+
+  /**
+   * @copydoc Visual::Base::DoGetProperty
+   */
+  virtual Dali::Property::Value DoGetProperty( Dali::Property::Index index );
+
+private:
+
+  /**
+   * @brief Render view, create and attach actor(s) to this TextView.
+   * @todo In a next patch a new text render back-end won't add extra actors.
+   */
+  void RenderText();
+
+  /**
+   * @brief Stops the text auto scroll.
+   */
+  void StopTextAutoScrolling();
+
+  /**
+   * @brief Set up Autoscrolling.
+   */
+  void SetUpAutoScrolling();
+
+private:
+  Text::ControllerPtr          mController;               ///< The text's controller.
+  Actor                        mSelf;
+
+  Text::RendererPtr            mRenderer;
+  Text::TextScrollerPtr        mTextScroller;
+  Actor                        mRenderableActor;
+
+  int mRenderingBackend;
+  bool mHasBeenStaged           : 1;
+};
+
+} // namespace Internal
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif /* DALI_TOOLKIT_INTERNAL_TEXT_VISUAL_H */
index 922f561..48df29a 100644 (file)
@@ -94,6 +94,11 @@ const Vector2& Visual::Base::GetSize() const
   return mImpl->mSize;
 }
 
+float Visual::Base::GetHeightForWidth( float width ) const
+{
+  return 0.f;
+}
+
 void Visual::Base::GetNaturalSize( Vector2& naturalSize ) const
 {
   naturalSize = Vector2::ZERO;
@@ -126,7 +131,7 @@ void Visual::Base::SetOnStage( Actor& actor )
 
 void Visual::Base::SetOffStage( Actor& actor )
 {
-  if( GetIsOnStage() )
+  if( IsOnStage() )
   {
     DoSetOffStage( actor );
 
@@ -134,6 +139,16 @@ void Visual::Base::SetOffStage( Actor& actor )
   }
 }
 
+void Visual::Base::CreatePropertyMap( Property::Map& map ) const
+{
+  DoCreatePropertyMap( map );
+
+  if( mImpl->mCustomShader )
+  {
+    mImpl->mCustomShader->CreatePropertyMap( map );
+  }
+}
+
 void Visual::Base::EnablePreMultipliedAlpha( bool preMultipled )
 {
   if(preMultipled)
@@ -162,22 +177,12 @@ void Visual::Base::DoSetOffStage( Actor& actor )
   mImpl->mRenderer.Reset();
 }
 
-void Visual::Base::CreatePropertyMap( Property::Map& map ) const
-{
-  DoCreatePropertyMap( map );
-
-  if( mImpl->mCustomShader )
-  {
-    mImpl->mCustomShader->CreatePropertyMap( map );
-  }
-}
-
-bool Visual::Base::GetIsOnStage() const
+bool Visual::Base::IsOnStage() const
 {
   return mImpl->mFlags & Impl::IS_ON_STAGE;
 }
 
-bool Visual::Base::GetIsFromCache() const
+bool Visual::Base::IsFromCache() const
 {
   return mImpl->mFlags & Impl::IS_FROM_CACHE;
 }
index 5c48c1d..475a5fa 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 // EXTERNAL INCLUDES
+#include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/images/image-operations.h>
 #include <dali/public-api/object/base-object.h>
 #include <dali/public-api/rendering/shader.h>
@@ -95,6 +96,11 @@ public:
   const Vector2& GetSize() const;
 
   /**
+   * @copydoc Toolkit::Visual::Base::GetHeightForWidth
+   */
+  virtual float GetHeightForWidth( float width ) const;
+
+  /**
    * @copydoc Toolkit::Visual::Base::GetNaturalSize
    */
   virtual void GetNaturalSize( Vector2& naturalSize ) const;
@@ -130,7 +136,7 @@ public:
    *
    * @param[in] preMultipled whether alpha is pre-multiplied.
    */
-  void EnablePreMultipliedAlpha(  bool preMultipled );
+  void EnablePreMultipliedAlpha( bool preMultipled );
 
   /**
    * @brief Query whether alpha is pre-multiplied.
@@ -204,19 +210,20 @@ protected:
   virtual void DoSetOffStage( Actor& actor );
 
 protected:
+
   /**
    * @brief Gets the on stage state for this Visual
    *
    * @return Returns true if this Visual is on stage, false if it is off the stage
    */
-  bool GetIsOnStage() const;
+  bool IsOnStage() const;
 
   /**
    * @brief Gets whether the Dali::Renderer is from a shared cache (and therefore any modifications will affect other users of that renderer)
    *
    * @return Returns true if the renderer is from shared cache, false otherwise
    */
-  bool GetIsFromCache() const;
+  bool IsFromCache() const;
 
 protected:
   /**
@@ -250,6 +257,8 @@ protected:
   VisualFactoryCache& mFactoryCache;
 };
 
+typedef IntrusivePtr<Base> BasePtr;
+
 } // namspace Visual
 
 } // namespace Internal
index 6baaec2..c7a9f33 100644 (file)
@@ -38,6 +38,7 @@
 #include <dali-toolkit/internal/visuals/npatch/npatch-visual.h>
 #include <dali-toolkit/internal/visuals/primitive/primitive-visual.h>
 #include <dali-toolkit/internal/visuals/svg/svg-visual.h>
+#include <dali-toolkit/internal/visuals/text/text-visual.h>
 #include <dali-toolkit/internal/visuals/wireframe/wireframe-visual.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
 #include <dali-toolkit/internal/visuals/visual-factory-resolve-url.h>
@@ -99,10 +100,10 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
   // Return a new WireframeVisual if we have debug enabled
   if( mDebugEnabled )
   {
-    return Toolkit::Visual::Base( new WireframeVisual( *( mFactoryCache.Get() ) ) );
+    return Toolkit::Visual::Base( WireframeVisual::New( *( mFactoryCache.Get() ) ).Get() );
   }
 
-  Visual::Base* visualPtr = NULL;
+  Visual::BasePtr visualPtr;
 
   Property::Value* typeValue = propertyMap.Find( Toolkit::Visual::Property::TYPE, VISUAL_TYPE );
   Toolkit::Visual::Type visualType = Toolkit::Visual::IMAGE; // Default to IMAGE type.
@@ -115,19 +116,19 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
   {
     case Toolkit::Visual::BORDER:
     {
-      visualPtr = new BorderVisual( *( mFactoryCache.Get() ) );
+      visualPtr = BorderVisual::New( *( mFactoryCache.Get() ) );
       break;
     }
 
     case Toolkit::Visual::COLOR:
     {
-      visualPtr = new ColorVisual( *( mFactoryCache.Get() ) );
+      visualPtr = ColorVisual::New( *( mFactoryCache.Get() ) );
       break;
     }
 
     case Toolkit::Visual::GRADIENT:
     {
-      visualPtr = new GradientVisual( *( mFactoryCache.Get() ) );
+      visualPtr = GradientVisual::New( *( mFactoryCache.Get() ) );
       break;
     }
 
@@ -141,11 +142,11 @@ Toolkit::Visual::Base VisualFactory::CreateVisual( const Property::Map& property
         UrlType::Type type = ResolveUrlType( imageUrl );
         if( UrlType::N_PATCH == type )
         {
-          visualPtr =&