Merge "Update README for dali-swig" into devel/master
authordongsug song <dongsug.song@samsung.com>
Wed, 23 Nov 2016 12:12:02 +0000 (04:12 -0800)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Wed, 23 Nov 2016 12:12:03 +0000 (04:12 -0800)
125 files changed:
automated-tests/src/dali-toolkit-internal/CMakeLists.txt
automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.cpp [moved from automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-model.cpp with 76% similarity]
automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-utils.h [moved from automated-tests/src/dali-toolkit-internal/dali-toolkit-test-utils/toolkit-text-model.h with 73% similarity]
automated-tests/src/dali-toolkit-internal/utc-Dali-BidirectionalSupport.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-LogicalModel.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Controller.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Cursor.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Layout.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Markup.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Shaping.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Typesetter.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit-internal/utc-Dali-Text-ViewModel.cpp [new file with mode: 0644]
automated-tests/src/dali-toolkit-internal/utc-Dali-VisualModel.cpp
automated-tests/src/dali-toolkit-internal/utc-Dali-Visuals.cpp
automated-tests/src/dali-toolkit-styling/CMakeLists.txt
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-harness.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-event-thread-callback.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-event-thread-callback.h
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/toolkit-text-abstraction.cpp
automated-tests/src/dali-toolkit/utc-Dali-AsyncImageLoader.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageAtlas.cpp
automated-tests/src/dali-toolkit/utc-Dali-ImageView.cpp
automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.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
build/tizen/dali-toolkit/Makefile.am
build/tizen/docs-internal/dali-internal.doxy.in
build/tizen/docs/dali.doxy.in
build/tizen/plugins/csharp/Makefile.am
dali-toolkit/dali-toolkit.h
dali-toolkit/devel-api/file.list
dali-toolkit/devel-api/visual-factory/visual-base.cpp
dali-toolkit/devel-api/visual-factory/visual-base.h
dali-toolkit/devel-api/visuals/text-visual-properties.h [new file with mode: 0644]
dali-toolkit/devel-api/visuals/visual-properties-devel.h [new file with mode: 0644]
dali-toolkit/internal/controls/image-view/image-view-impl.cpp
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/file.list
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp
dali-toolkit/internal/image-loader/async-image-loader-impl.cpp
dali-toolkit/internal/image-loader/image-load-thread.cpp
dali-toolkit/internal/image-loader/image-load-thread.h
dali-toolkit/internal/text/layouts/layout-alignment.h [moved from dali-toolkit/internal/text/text-scroller-interface.cpp with 52% similarity]
dali-toolkit/internal/text/layouts/layout-engine.cpp
dali-toolkit/internal/text/layouts/layout-engine.h
dali-toolkit/internal/text/layouts/layout-parameters.h
dali-toolkit/internal/text/multi-language-support-impl.cpp
dali-toolkit/internal/text/rendering/text-typesetter.cpp [new file with mode: 0644]
dali-toolkit/internal/text/rendering/text-typesetter.h [new file with mode: 0644]
dali-toolkit/internal/text/rendering/view-model.cpp [new file with mode: 0644]
dali-toolkit/internal/text/rendering/view-model.h [new file with mode: 0644]
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-model-interface.h [new file with mode: 0644]
dali-toolkit/internal/text/text-model.cpp [new file with mode: 0644]
dali-toolkit/internal/text/text-model.h [new file with mode: 0644]
dali-toolkit/internal/text/text-scroller-interface.h
dali-toolkit/internal/text/visual-model-impl.cpp
dali-toolkit/internal/text/visual-model-impl.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/mesh/mesh-visual.cpp
dali-toolkit/internal/visuals/mesh/mesh-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
dali-toolkit/internal/visuals/text/text-visual.h
dali-toolkit/internal/visuals/transition-data-impl.cpp
dali-toolkit/internal/visuals/visual-base-data-impl.cpp
dali-toolkit/internal/visuals/visual-base-data-impl.h
dali-toolkit/internal/visuals/visual-base-impl.cpp
dali-toolkit/internal/visuals/visual-base-impl.h
dali-toolkit/internal/visuals/visual-factory-cache.cpp
dali-toolkit/internal/visuals/visual-factory-cache.h
dali-toolkit/internal/visuals/visual-factory-impl.cpp
dali-toolkit/internal/visuals/wireframe/wireframe-visual.cpp
dali-toolkit/internal/visuals/wireframe/wireframe-visual.h
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/controls/image-view/image-view.h
dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h
dali-toolkit/public-api/controls/video-view/video-view.h
dali-toolkit/public-api/dali-toolkit-version.cpp
dali-toolkit/public-api/file.list
dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h
dali-toolkit/public-api/image-loader/async-image-loader.h
dali-toolkit/public-api/image-loader/sync-image-loader.cpp
dali-toolkit/public-api/image-loader/sync-image-loader.h
dali-toolkit/public-api/visuals/text-visual-properties.h [deleted file]
dali-toolkit/public-api/visuals/visual-properties.h
packaging/dali-addon.spec
packaging/dali-csharp-wrapper.spec
packaging/dali-toolkit.spec
plugins/dali-swig/Makefile.am
plugins/dali-swig/SWIG/dali-gc.i [new file with mode: 0644]
plugins/dali-swig/SWIG/dali.i
plugins/dali-swig/SWIG/events/application-event.i
plugins/dali-swig/examples/firstscreen/App.cs
plugins/dali-swig/examples/firstscreen/Constants.cs
plugins/dali-swig/examples/firstscreen/FocusData.cs
plugins/dali-swig/examples/firstscreen/FocusEffect.cs
plugins/dali-swig/examples/firstscreen/IFocusEffect.cs
plugins/dali-swig/examples/firstscreen/Program.cs
plugins/dali-swig/examples/firstscreen/ScrollContainer.cs
plugins/dali-swig/examples/firstscreen/firstscreen.csproj [new file with mode: 0644]
plugins/dali-swig/examples/firstscreen/firstscreen.sln [new file with mode: 0644]
plugins/dali-swig/manual/cpp/callbackbase_wrap.cpp [new file with mode: 0644]
plugins/dali-swig/manual/csharp/DisposeQueue.cs [new file with mode: 0644]
plugins/dali-swig/manual/csharp/KeyboardFocusManager.cs
plugins/dali-swig/manual/csharp/KeyboardPreFocusChangeSignal.cs
plugins/dali-swig/manual/csharp/ManualPINVOKE.cs

index 4a9a003..99ee1db 100644 (file)
@@ -21,6 +21,8 @@ SET(TC_SOURCES
  utc-Dali-VisualFactoryResolveUrl.cpp
  utc-Dali-Visuals.cpp
  utc-Dali-Text-Markup.cpp
+ utc-Dali-Text-Typesetter.cpp
+ utc-Dali-Text-ViewModel.cpp
 )
 
 # Append list of test harness files (Won't get parsed for test cases)
@@ -53,7 +55,7 @@ LIST(APPEND TC_SOURCES
    ../dali-toolkit/dali-toolkit-test-utils/test-render-controller.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-trace-call-stack.cpp
    ../dali-toolkit/dali-toolkit-test-utils/test-native-image.cpp
-   dali-toolkit-test-utils/toolkit-text-model.cpp
+   dali-toolkit-test-utils/toolkit-text-utils.cpp
 )
 
 
  *
  */
 
-#include "toolkit-text-model.h"
+// FILE HEADER
+#include "toolkit-text-utils.h"
 
 // EXTERNAL INCLUDES
+#include <limits>
 #include <dali/devel-api/text-abstraction/font-client.h>
 
 // INTERNAL INCLUDES
@@ -260,25 +262,26 @@ void CreateTextModel( const std::string& text,
   }
 
   // 9) Layout the text
-  LayoutEngine layoutEngine;
+  Layout::Engine layoutEngine;
   layoutEngine.SetMetrics( metrics );
-  layoutEngine.SetLayout( LayoutEngine::MULTI_LINE_BOX );
+  layoutEngine.SetLayout( Layout::Engine::MULTI_LINE_BOX );
 
   // Set the layout parameters.
   const Vector<GlyphIndex>& charactersToGlyph = visualModel->mCharactersToGlyph;
   const Vector<Length>& glyphsPerCharacter = visualModel->mGlyphsPerCharacter;
 
-  LayoutParameters layoutParameters( textArea,
-                                     utf32Characters.Begin(),
-                                     lineBreakInfo.Begin(),
-                                     wordBreakInfo.Begin(),
-                                     ( 0u != characterDirections.Count() ) ? characterDirections.Begin() : NULL,
-                                     glyphs.Begin(),
-                                     glyphsToCharactersMap.Begin(),
-                                     charactersPerGlyph.Begin(),
-                                     charactersToGlyph.Begin(),
-                                     glyphsPerCharacter.Begin(),
-                                     numberOfGlyphs );
+  Layout::Parameters layoutParameters( textArea,
+                                       utf32Characters.Begin(),
+                                       lineBreakInfo.Begin(),
+                                       wordBreakInfo.Begin(),
+                                       ( 0u != characterDirections.Count() ) ? characterDirections.Begin() : NULL,
+                                       glyphs.Begin(),
+                                       glyphsToCharactersMap.Begin(),
+                                       charactersPerGlyph.Begin(),
+                                       charactersToGlyph.Begin(),
+                                       glyphsPerCharacter.Begin(),
+                                       numberOfGlyphs,
+                                       Layout::HORIZONTAL_ALIGN_BEGIN );
 
   Vector<LineRun>& lines = visualModel->mLines;
 
@@ -296,7 +299,8 @@ void CreateTextModel( const std::string& text,
   layoutEngine.LayoutText( layoutParameters,
                            glyphPositions,
                            lines,
-                           layoutSize );
+                           layoutSize,
+                           false );
 
   // 10) Reorder the lines
   if( 0u != bidirectionalInfo.Count() )
@@ -333,10 +337,91 @@ void CreateTextModel( const std::string& text,
     layoutEngine.Align( textArea,
                         0u,
                         numberOfCharacters,
+                        Layout::HORIZONTAL_ALIGN_BEGIN,
                         lines );
   }
 }
 
+void ConfigureTextLabel( ControllerPtr controller )
+{
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+  fontClient.SetDpi( 93u, 93u );
+
+  // Set the text layout as multi-line.
+  controller->GetLayoutEngine().SetLayout( Layout::Engine::MULTI_LINE_BOX );
+
+  // Set cursor's width to zero.
+  controller->GetLayoutEngine().SetCursorWidth( 0 );
+
+  // Disables the text input.
+  controller->EnableTextInput( NULL );
+
+  // Disables the vertical scrolling.
+  controller->SetVerticalScrollEnabled( false );
+
+  // Disables the horizontal scrolling.
+  controller->SetHorizontalScrollEnabled( false );
+
+  // Enable the text elide.
+  controller->SetTextElideEnabled( true );
+}
+
+void ConfigureTextField( ControllerPtr controller )
+{
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+  fontClient.SetDpi( 93u, 93u );
+
+  // Creates a decorator.
+  Text::DecoratorPtr decorator = Text::Decorator::New( *controller,
+                                                       *controller );
+
+  // Set the text layout as multi-line.
+  controller->GetLayoutEngine().SetLayout( Layout::Engine::SINGLE_LINE_BOX );
+
+  // Enables the text input.
+  controller->EnableTextInput( decorator );
+
+  // Enables the vertical scrolling after the text input has been enabled.
+  controller->SetVerticalScrollEnabled( false );
+
+  // Disables the horizontal scrolling.
+  controller->SetHorizontalScrollEnabled( true );
+
+  // No maximum number of characters.
+  controller->SetMaximumNumberOfCharacters( 50u );
+
+  // Disable the text elide.
+  controller->SetTextElideEnabled( false );
+}
+
+void ConfigureTextEditor( ControllerPtr controller )
+{
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+  fontClient.SetDpi( 93u, 93u );
+
+  // Creates a decorator.
+  Text::DecoratorPtr decorator = Text::Decorator::New( *controller,
+                                                       *controller );
+
+  // Set the text layout as multi-line.
+  controller->GetLayoutEngine().SetLayout( Layout::Engine::MULTI_LINE_BOX );
+
+  // Enables the text input.
+  controller->EnableTextInput( decorator );
+
+  // Enables the vertical scrolling after the text input has been enabled.
+  controller->SetVerticalScrollEnabled( true );
+
+  // Disables the horizontal scrolling.
+  controller->SetHorizontalScrollEnabled( false );
+
+  // No maximum number of characters.
+  controller->SetMaximumNumberOfCharacters( std::numeric_limits<Length>::max() );
+
+  // Disable the text elide.
+  controller->SetTextElideEnabled( false );
+}
+
 } // namespace Text
 
 } // namespace Toolkit
@@ -1,5 +1,5 @@
-#ifndef __DALI_TOOLKIT_TEXT_MODEL_H__
-#define __DALI_TOOLKIT_TEXT_MODEL_H__
+#ifndef __DALI_TOOLKIT_TEXT_UTILS_H__
+#define __DALI_TOOLKIT_TEXT_UTILS_H__
 
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
  *
  */
 
-// EXTERNAL INCLUDES
-
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/logical-model-impl.h>
 #include <dali-toolkit/internal/text/metrics.h>
 #include <dali-toolkit/internal/text/visual-model-impl.h>
+#include <dali-toolkit/internal/text/text-controller.h>
 
 namespace Dali
 {
@@ -70,10 +69,31 @@ void CreateTextModel( const std::string& text,
                       VisualModelPtr& visualModel,
                       MetricsPtr& metrics );
 
+/**
+ * @brief Configures the text @p controller similarly to the one configured by the text-label.
+ *
+ * @param[in,out] The text controller to configure.
+ */
+void ConfigureTextLabel( ControllerPtr controller );
+
+/**
+ * @brief Configures the text @p controller similarly to the one configured by the text-field.
+ *
+ * @param[in,out] The text controller to configure.
+ */
+void ConfigureTextField( ControllerPtr controller );
+
+/**
+ * @brief Configures the text @p controller similarly to the one configured by the text-editor.
+ *
+ * @param[in,out] The text controller to configure.
+ */
+void ConfigureTextEditor( ControllerPtr controller );
+
 } // namespace Text
 
 } // namespace Toolkit
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_MODEL_H__
+#endif // __DALI_TOOLKIT_TEXT_UTILS_H__
index 629e4f3..37b5277 100644 (file)
@@ -24,7 +24,7 @@
 #include <dali-toolkit/internal/text/text-run-container.h>
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
-#include <toolkit-text-model.h>
+#include <toolkit-text-utils.h>
 
 using namespace Dali;
 using namespace Toolkit;
index 25a724c..f8df615 100644 (file)
@@ -22,7 +22,7 @@
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/internal/text/text-run-container.h>
 #include <dali-toolkit/dali-toolkit.h>
-#include <toolkit-text-model.h>
+#include <toolkit-text-utils.h>
 
 
 using namespace Dali;
index cdb29f9..b92f090 100644 (file)
 
 #include <stdlib.h>
 #include <limits>
-#include <unistd.h>
 
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
+#include <toolkit-text-utils.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>
@@ -43,34 +43,6 @@ const char* const OPTION_CLIPBOARD("optionClipboard");      // "Clipboard" popup
 
 const Size CONTROL_SIZE( 300.f, 60.f );
 
-const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
-
-class ControlImpl : public ControlInterface, public Text::EditableControlInterface
-{
-public:
-  ControlImpl()
-  : ControlInterface()
-  {}
-
-  virtual ~ControlImpl()
-  {}
-
-  virtual void AddDecoration( Actor& actor, bool needsClipping )
-  {}
-
-  virtual void RequestTextRelayout()
-  {}
-
-  virtual void TextChanged()
-  {}
-
-  virtual void MaxLengthReached()
-  {}
-
-  virtual void InputStyleChanged( InputStyle::Mask inputStyleMask )
-  {}
-};
-
 std::string gClipboardText;
 void ContentSelectedCallback( ClipboardEventNotifier& notifier )
 {
@@ -86,9 +58,73 @@ int UtcDaliTextController(void)
 
   // Creates a text controller.
   ControllerPtr controller = Controller::New();
+  DALI_TEST_CHECK( controller );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextControllerSetGetScrollEnabled(void)
+{
+  tet_infoline(" UtcDaliTextControllerSetGetScrollEnabled");
+  ToolkitTestApplication application;
 
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
   DALI_TEST_CHECK( controller );
 
+  // Configures the text controller similarly to the text-editor.
+  ConfigureTextEditor( controller );
+
+  DALI_TEST_CHECK( !controller->IsHorizontalScrollEnabled() );
+  DALI_TEST_CHECK( controller->IsVerticalScrollEnabled() );
+
+  // Configures the text controller similarly to the text-field.
+  ConfigureTextField( controller );
+
+  DALI_TEST_CHECK( controller->IsHorizontalScrollEnabled() );
+  DALI_TEST_CHECK( !controller->IsVerticalScrollEnabled() );
+
+  // Configures the text controller similarly to the text-label.
+  ConfigureTextLabel( controller );
+
+  DALI_TEST_CHECK( !controller->IsHorizontalScrollEnabled() );
+  DALI_TEST_CHECK( !controller->IsVerticalScrollEnabled() );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextControllerSetIsTextElide(void)
+{
+  tet_infoline(" UtcDaliTextControllerSetIsTextElide");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+  DALI_TEST_CHECK( controller );
+
+  // Configures the text controller similarly to the text-editor.
+  ConfigureTextEditor( controller );
+  DALI_TEST_EQUALS( false, controller->IsTextElideEnabled(), TEST_LOCATION );
+
+  controller->SetTextElideEnabled( true );
+  DALI_TEST_EQUALS( true, controller->IsTextElideEnabled(), TEST_LOCATION );
+
+  // Configures the text controller similarly to the text-field.
+  ConfigureTextField( controller );
+  DALI_TEST_EQUALS( false, controller->IsTextElideEnabled(), TEST_LOCATION );
+
+  controller->SetTextElideEnabled( true );
+  DALI_TEST_EQUALS( true, controller->IsTextElideEnabled(), TEST_LOCATION );
+
+  // Configures the text controller similarly to the text-label.
+  ConfigureTextLabel( controller );
+  DALI_TEST_EQUALS( true, controller->IsTextElideEnabled(), TEST_LOCATION );
+
+  controller->SetTextElideEnabled( false );
+  DALI_TEST_EQUALS( false, controller->IsTextElideEnabled(), TEST_LOCATION );
+
   tet_result(TET_PASS);
   END_TEST;
 }
@@ -100,7 +136,6 @@ int UtcDaliTextControllerEnableCursorBlinking(void)
 
   // Creates a text controller.
   ControllerPtr controller = Controller::New();
-
   DALI_TEST_CHECK( controller );
 
   // There is no text input enabled.
index 195c81b..1755b8b 100644 (file)
@@ -22,7 +22,7 @@
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/internal/text/cursor-helper-functions.h>
 #include <dali-toolkit/dali-toolkit.h>
-#include <toolkit-text-model.h>
+#include <toolkit-text-utils.h>
 
 
 using namespace Dali;
index 4d42843..80c4631 100644 (file)
@@ -24,7 +24,7 @@
 #include <dali-toolkit/internal/text/text-run-container.h>
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
-#include <toolkit-text-model.h>
+#include <toolkit-text-utils.h>
 
 using namespace Dali;
 using namespace Toolkit;
@@ -51,7 +51,7 @@ struct LayoutTextData
   float*               positions;
   unsigned int         numberOfLines;
   LineRun*             lines;
-  LayoutEngine::Layout layout;
+  Layout::Engine::Type layout;
   unsigned int         startIndex;
   unsigned int         numberOfGlyphs;
   bool                 ellipsis:1;
@@ -152,24 +152,24 @@ bool LayoutTextTest( const LayoutTextData& data )
                         glyphPositions.Begin() + data.startIndex + data.numberOfGlyphs );
 
   // 3) Layout
-  LayoutEngine engine;
+  Layout::Engine engine;
   engine.SetMetrics( metrics );
-  engine.SetTextEllipsisEnabled( data.ellipsis );
   engine.SetLayout( data.layout );
 
   const Length totalNumberOfGlyphs = visualModel->mGlyphs.Count();
 
-  LayoutParameters layoutParameters( data.textArea,
-                                     logicalModel->mText.Begin(),
-                                     logicalModel->mLineBreakInfo.Begin(),
-                                     logicalModel->mWordBreakInfo.Begin(),
-                                     ( 0u != logicalModel->mCharacterDirections.Count() ) ? logicalModel->mCharacterDirections.Begin() : NULL,
-                                     visualModel->mGlyphs.Begin(),
-                                     visualModel->mGlyphsToCharacters.Begin(),
-                                     visualModel->mCharactersPerGlyph.Begin(),
-                                     visualModel->mCharactersToGlyph.Begin(),
-                                     visualModel->mGlyphsPerCharacter.Begin(),
-                                     totalNumberOfGlyphs );
+  Layout::Parameters layoutParameters( data.textArea,
+                                       logicalModel->mText.Begin(),
+                                       logicalModel->mLineBreakInfo.Begin(),
+                                       logicalModel->mWordBreakInfo.Begin(),
+                                       ( 0u != logicalModel->mCharacterDirections.Count() ) ? logicalModel->mCharacterDirections.Begin() : NULL,
+                                       visualModel->mGlyphs.Begin(),
+                                       visualModel->mGlyphsToCharacters.Begin(),
+                                       visualModel->mCharactersPerGlyph.Begin(),
+                                       visualModel->mCharactersToGlyph.Begin(),
+                                       visualModel->mGlyphsPerCharacter.Begin(),
+                                       totalNumberOfGlyphs,
+                                       Layout::HORIZONTAL_ALIGN_BEGIN );
 
   layoutParameters.isLastNewParagraph = isLastNewParagraph;
 
@@ -184,7 +184,8 @@ bool LayoutTextTest( const LayoutTextData& data )
   const bool updated = engine.LayoutText( layoutParameters,
                                           glyphPositions,
                                           lines,
-                                          layoutSize );
+                                          layoutSize,
+                                          data.ellipsis );
 
   // 4) Compare the results.
 
@@ -369,20 +370,21 @@ bool ReLayoutRightToLeftLinesTest( const ReLayoutRightToLeftLinesData& data )
                    metrics );
 
   // 2) Call the ReLayoutRightToLeftLines() method.
-  LayoutEngine engine;
+  Layout::Engine engine;
   engine.SetMetrics( metrics );
 
-  LayoutParameters layoutParameters( data.textArea,
-                                     logicalModel->mText.Begin(),
-                                     logicalModel->mLineBreakInfo.Begin(),
-                                     logicalModel->mWordBreakInfo.Begin(),
-                                     ( 0u != logicalModel->mCharacterDirections.Count() ) ? logicalModel->mCharacterDirections.Begin() : NULL,
-                                     visualModel->mGlyphs.Begin(),
-                                     visualModel->mGlyphsToCharacters.Begin(),
-                                     visualModel->mCharactersPerGlyph.Begin(),
-                                     visualModel->mCharactersToGlyph.Begin(),
-                                     visualModel->mGlyphsPerCharacter.Begin(),
-                                     visualModel->mGlyphs.Count() );
+  Layout::Parameters layoutParameters( data.textArea,
+                                       logicalModel->mText.Begin(),
+                                       logicalModel->mLineBreakInfo.Begin(),
+                                       logicalModel->mWordBreakInfo.Begin(),
+                                       ( 0u != logicalModel->mCharacterDirections.Count() ) ? logicalModel->mCharacterDirections.Begin() : NULL,
+                                       visualModel->mGlyphs.Begin(),
+                                       visualModel->mGlyphsToCharacters.Begin(),
+                                       visualModel->mCharactersPerGlyph.Begin(),
+                                       visualModel->mCharactersToGlyph.Begin(),
+                                       visualModel->mGlyphsPerCharacter.Begin(),
+                                       visualModel->mGlyphs.Count(),
+                                       Layout::HORIZONTAL_ALIGN_BEGIN  );
 
   layoutParameters.numberOfBidirectionalInfoRuns = logicalModel->mBidirectionalLineInfo.Count();
   layoutParameters.lineBidirectionalInfoRunsBuffer = logicalModel->mBidirectionalLineInfo.Begin();
@@ -424,17 +426,17 @@ bool ReLayoutRightToLeftLinesTest( const ReLayoutRightToLeftLinesData& data )
 
 struct AlignData
 {
-  std::string                       description;
-  std::string                       text;
-  Size                              textArea;
-  unsigned int                      numberOfFonts;
-  FontDescriptionRun*               fontDescriptions;
-  LayoutEngine::HorizontalAlignment horizontalAlignment;
-  LayoutEngine::VerticalAlignment   verticalAlignment;
-  unsigned int                      startIndex;
-  unsigned int                      numberOfCharacters;
-  unsigned int                      numberOfLines;
-  float*                            lineOffsets;
+  std::string                 description;
+  std::string                 text;
+  Size                        textArea;
+  unsigned int                numberOfFonts;
+  FontDescriptionRun*         fontDescriptions;
+  Layout::HorizontalAlignment horizontalAlignment;
+  Layout::VerticalAlignment   verticalAlignment;
+  unsigned int                startIndex;
+  unsigned int                numberOfCharacters;
+  unsigned int                numberOfLines;
+  float*                      lineOffsets;
 };
 
 bool AlignTest( const AlignData& data )
@@ -477,15 +479,13 @@ bool AlignTest( const AlignData& data )
                    metrics );
 
   // Call the Align method.
-  LayoutEngine engine;
+  Layout::Engine engine;
   engine.SetMetrics( metrics );
 
-  engine.SetHorizontalAlignment( data.horizontalAlignment );
-  engine.SetVerticalAlignment( data.verticalAlignment );
-
   engine.Align( data.textArea,
                 data.startIndex,
                 data.numberOfCharacters,
+                data.horizontalAlignment,
                 visualModel->mLines );
 
   // Compare results.
@@ -556,61 +556,12 @@ int UtcDaliTextLayoutSetGetLayout(void)
   ToolkitTestApplication application;
   tet_infoline(" UtcDaliTextLayoutSetGetLayout");
 
-  LayoutEngine engine;
-
-  DALI_TEST_CHECK( LayoutEngine::SINGLE_LINE_BOX == engine.GetLayout() );
-
-  engine.SetLayout( LayoutEngine::MULTI_LINE_BOX );
-  DALI_TEST_CHECK( LayoutEngine::MULTI_LINE_BOX == engine.GetLayout() );
-
-  tet_result(TET_PASS);
-  END_TEST;
-}
-
-int UtcDaliTextLayoutSetGetTextEllipsisEnabled(void)
-{
-  ToolkitTestApplication application;
-  tet_infoline(" UtcDaliTextLayoutSetGetTextEllipsisEnabled");
-
-  LayoutEngine engine;
-
-  DALI_TEST_CHECK( !engine.GetTextEllipsisEnabled() );
-
-  engine.SetTextEllipsisEnabled( true );
-  DALI_TEST_CHECK( engine.GetTextEllipsisEnabled() );
-
-  tet_result(TET_PASS);
-  END_TEST;
-}
-
-int UtcDaliTextLayoutSetGetHorizontalAlignment(void)
-{
-  ToolkitTestApplication application;
-  tet_infoline(" ");
-
-  LayoutEngine engine;
+  Layout::Engine engine;
 
-  DALI_TEST_CHECK( LayoutEngine::HORIZONTAL_ALIGN_BEGIN == engine.GetHorizontalAlignment() );
-
-  engine.SetHorizontalAlignment( LayoutEngine::HORIZONTAL_ALIGN_END );
-  DALI_TEST_CHECK( LayoutEngine::HORIZONTAL_ALIGN_END == engine.GetHorizontalAlignment() );
-
-  tet_result(TET_PASS);
-  END_TEST;
-}
-
-int UtcDaliTextLayoutSetGetVerticalAlignment(void)
-{
-  ToolkitTestApplication application;
-  tet_infoline(" UtcDaliTextLayoutSetGetVerticalAlignment");
-
-  LayoutEngine engine;
-
-  DALI_TEST_CHECK( LayoutEngine::VERTICAL_ALIGN_TOP == engine.GetVerticalAlignment() );
-
-  engine.SetVerticalAlignment( LayoutEngine::VERTICAL_ALIGN_TOP );
-  DALI_TEST_CHECK( LayoutEngine::VERTICAL_ALIGN_TOP == engine.GetVerticalAlignment() );
+  DALI_TEST_CHECK( Layout::Engine::SINGLE_LINE_BOX == engine.GetLayout() );
 
+  engine.SetLayout( Layout::Engine::MULTI_LINE_BOX );
+  DALI_TEST_CHECK( Layout::Engine::MULTI_LINE_BOX == engine.GetLayout() );
 
   tet_result(TET_PASS);
   END_TEST;
@@ -621,7 +572,7 @@ int UtcDaliTextLayoutSetGetCursorWidth(void)
   ToolkitTestApplication application;
   tet_infoline(" ");
 
-  LayoutEngine engine;
+  Layout::Engine engine;
 
   DALI_TEST_EQUALS( 1, engine.GetCursorWidth(), TEST_LOCATION );
 
@@ -651,7 +602,7 @@ int UtcDaliTextLayoutNoText(void)
     NULL,
     0u,
     NULL,
-    LayoutEngine::MULTI_LINE_BOX,
+    Layout::Engine::MULTI_LINE_BOX,
     0u,
     0u,
     false,
@@ -705,7 +656,7 @@ int UtcDaliTextLayoutSmallTextArea01(void)
     NULL,
     0u,
     NULL,
-    LayoutEngine::MULTI_LINE_BOX,
+    Layout::Engine::MULTI_LINE_BOX,
     0u,
     11u,
     false,
@@ -775,7 +726,7 @@ int UtcDaliTextLayoutSmallTextArea02(void)
     positions,
     1u,
     lines.Begin(),
-    LayoutEngine::SINGLE_LINE_BOX,
+    Layout::Engine::SINGLE_LINE_BOX,
     0u,
     11u,
     false,
@@ -918,7 +869,7 @@ int UtcDaliTextLayoutMultilineText01(void)
     positions,
     5u,
     lines.Begin(),
-    LayoutEngine::MULTI_LINE_BOX,
+    Layout::Engine::MULTI_LINE_BOX,
     0u,
     48u,
     false,
@@ -1126,7 +1077,7 @@ int UtcDaliTextLayoutMultilineText02(void)
     positions,
     6u,
     lines.Begin(),
-    LayoutEngine::MULTI_LINE_BOX,
+    Layout::Engine::MULTI_LINE_BOX,
     0u,
     55u,
     false,
@@ -1227,7 +1178,7 @@ int UtcDaliTextLayoutMultilineText03(void)
     positions,
     3u,
     lines.Begin(),
-    LayoutEngine::MULTI_LINE_BOX,
+    Layout::Engine::MULTI_LINE_BOX,
     0u,
     29u,
     false,
@@ -1313,7 +1264,7 @@ int UtcDaliTextLayoutMultilineText04(void)
     positions,
     2u,
     lines.Begin(),
-    LayoutEngine::MULTI_LINE_BOX,
+    Layout::Engine::MULTI_LINE_BOX,
     0u,
     13u,
     false,
@@ -1427,7 +1378,7 @@ int UtcDaliTextLayoutMultilineText05(void)
     positions,
     2u,
     lines.Begin(),
-    LayoutEngine::MULTI_LINE_BOX,
+    Layout::Engine::MULTI_LINE_BOX,
     0u,
     17u,
     false,
@@ -1983,7 +1934,7 @@ int UtcDaliTextUpdateLayout01(void)
     positions,
     19u,
     lines.Begin(),
-    LayoutEngine::MULTI_LINE_BOX,
+    Layout::Engine::MULTI_LINE_BOX,
     0u,
     64u,
     false,
@@ -2539,7 +2490,7 @@ int UtcDaliTextUpdateLayout02(void)
     positions,
     19u,
     lines.Begin(),
-    LayoutEngine::MULTI_LINE_BOX,
+    Layout::Engine::MULTI_LINE_BOX,
     64u,
     64u,
     false,
@@ -3095,7 +3046,7 @@ int UtcDaliTextUpdateLayout03(void)
     positions,
     19u,
     lines.Begin(),
-    LayoutEngine::MULTI_LINE_BOX,
+    Layout::Engine::MULTI_LINE_BOX,
     128u,
     64u,
     false,
@@ -3171,7 +3122,7 @@ int UtcDaliTextLayoutEllipsis01(void)
     positions,
     1u,
     lines.Begin(),
-    LayoutEngine::SINGLE_LINE_BOX,
+    Layout::Engine::SINGLE_LINE_BOX,
     0u,
     51u,
     true,
@@ -3261,7 +3212,7 @@ int UtcDaliTextLayoutEllipsis02(void)
     positions,
     2u,
     lines.Begin(),
-    LayoutEngine::MULTI_LINE_BOX,
+    Layout::Engine::MULTI_LINE_BOX,
     0u,
     51u,
     true,
@@ -3403,7 +3354,7 @@ int UtcDaliTextLayoutEllipsis03(void)
     positions,
     1u,
     lines.Begin(),
-    LayoutEngine::SINGLE_LINE_BOX,
+    Layout::Engine::SINGLE_LINE_BOX,
     0u,
     72u,
     true,
@@ -3559,7 +3510,7 @@ int UtcDaliTextLayoutEllipsis04(void)
     positions,
     2u,
     lines.Begin(),
-    LayoutEngine::MULTI_LINE_BOX,
+    Layout::Engine::MULTI_LINE_BOX,
     0u,
     72u,
     true,
@@ -3633,7 +3584,7 @@ int UtcDaliTextLayoutEllipsis05(void)
     positions,
     1u,
     lines.Begin(),
-    LayoutEngine::MULTI_LINE_BOX,
+    Layout::Engine::MULTI_LINE_BOX,
     0u,
     11u,
     true,
@@ -4186,8 +4137,8 @@ int UtcDaliTextAlign01(void)
     textArea,
     6u,
     fontDescriptionRuns.Begin(),
-    LayoutEngine::HORIZONTAL_ALIGN_BEGIN,
-    LayoutEngine::VERTICAL_ALIGN_TOP,
+    Layout::HORIZONTAL_ALIGN_BEGIN,
+    Layout::VERTICAL_ALIGN_TOP,
     0u,
     22u,
     6u,
@@ -4305,8 +4256,8 @@ int UtcDaliTextAlign02(void)
     textArea,
     6u,
     fontDescriptionRuns.Begin(),
-    LayoutEngine::HORIZONTAL_ALIGN_BEGIN,
-    LayoutEngine::VERTICAL_ALIGN_TOP,
+    Layout::HORIZONTAL_ALIGN_BEGIN,
+    Layout::VERTICAL_ALIGN_TOP,
     22u,
     26u,
     6u,
@@ -4424,8 +4375,8 @@ int UtcDaliTextAlign03(void)
     textArea,
     6u,
     fontDescriptionRuns.Begin(),
-    LayoutEngine::HORIZONTAL_ALIGN_BEGIN,
-    LayoutEngine::VERTICAL_ALIGN_TOP,
+    Layout::HORIZONTAL_ALIGN_BEGIN,
+    Layout::VERTICAL_ALIGN_TOP,
     48u,
     26u,
     6u,
@@ -4543,8 +4494,8 @@ int UtcDaliTextAlign04(void)
     textArea,
     6u,
     fontDescriptionRuns.Begin(),
-    LayoutEngine::HORIZONTAL_ALIGN_CENTER,
-    LayoutEngine::VERTICAL_ALIGN_TOP,
+    Layout::HORIZONTAL_ALIGN_CENTER,
+    Layout::VERTICAL_ALIGN_TOP,
     0u,
     22u,
     6u,
@@ -4662,8 +4613,8 @@ int UtcDaliTextAlign05(void)
     textArea,
     6u,
     fontDescriptionRuns.Begin(),
-    LayoutEngine::HORIZONTAL_ALIGN_CENTER,
-    LayoutEngine::VERTICAL_ALIGN_TOP,
+    Layout::HORIZONTAL_ALIGN_CENTER,
+    Layout::VERTICAL_ALIGN_TOP,
     22u,
     26u,
     6u,
@@ -4781,8 +4732,8 @@ int UtcDaliTextAlign06(void)
     textArea,
     6u,
     fontDescriptionRuns.Begin(),
-    LayoutEngine::HORIZONTAL_ALIGN_CENTER,
-    LayoutEngine::VERTICAL_ALIGN_TOP,
+    Layout::HORIZONTAL_ALIGN_CENTER,
+    Layout::VERTICAL_ALIGN_TOP,
     48u,
     26u,
     6u,
@@ -4900,8 +4851,8 @@ int UtcDaliTextAlign07(void)
     textArea,
     6u,
     fontDescriptionRuns.Begin(),
-    LayoutEngine::HORIZONTAL_ALIGN_END,
-    LayoutEngine::VERTICAL_ALIGN_TOP,
+    Layout::HORIZONTAL_ALIGN_END,
+    Layout::VERTICAL_ALIGN_TOP,
     0u,
     22u,
     6u,
@@ -5019,8 +4970,8 @@ int UtcDaliTextAlign08(void)
     textArea,
     6u,
     fontDescriptionRuns.Begin(),
-    LayoutEngine::HORIZONTAL_ALIGN_END,
-    LayoutEngine::VERTICAL_ALIGN_TOP,
+    Layout::HORIZONTAL_ALIGN_END,
+    Layout::VERTICAL_ALIGN_TOP,
     22u,
     26u,
     6u,
@@ -5138,8 +5089,8 @@ int UtcDaliTextAlign09(void)
     textArea,
     6u,
     fontDescriptionRuns.Begin(),
-    LayoutEngine::HORIZONTAL_ALIGN_END,
-    LayoutEngine::VERTICAL_ALIGN_TOP,
+    Layout::HORIZONTAL_ALIGN_END,
+    Layout::VERTICAL_ALIGN_TOP,
     48u,
     26u,
     6u,
@@ -5154,3 +5105,18 @@ int UtcDaliTextAlign09(void)
   tet_result(TET_PASS);
   END_TEST;
 }
+
+int UtcDaliTextLayoutSetGetDefaultLineSpacing(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliTextLayoutSetGetDefaultLineSpacing");
+
+  Layout::Engine engine;
+  DALI_TEST_EQUALS( 0.f, engine.GetDefaultLineSpacing(), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  engine.SetDefaultLineSpacing( 10.f );
+  DALI_TEST_EQUALS( 10.f, engine.GetDefaultLineSpacing(), Math::MACHINE_EPSILON_1000, TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
index 23f7e51..87db667 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
-#include <toolkit-text-model.h>
+#include <toolkit-text-utils.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>
index 7b319fb..e4464fd 100644 (file)
@@ -21,7 +21,7 @@
 #include <dali-toolkit/internal/text/shaper.h>
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
-#include <toolkit-text-model.h>
+#include <toolkit-text-utils.h>
 
 using namespace Dali;
 using namespace Toolkit;
diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Typesetter.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-Typesetter.cpp
new file mode 100644 (file)
index 0000000..63f9a22
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * 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 <unistd.h>
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <toolkit-text-utils.h>
+#include <dali-toolkit/internal/text/rendering/text-typesetter.h>
+#include <dali-toolkit/internal/text/rendering/view-model.h>
+#include <dali-toolkit/internal/text/text-controller.h>
+
+using namespace Dali;
+using namespace Toolkit;
+using namespace Text;
+
+namespace
+{
+const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
+const PointSize26Dot6 EMOJI_FONT_SIZE = 62u * 64u;
+} // namespace
+
+int UtcDaliTextTypesetter(void)
+{
+  tet_infoline(" UtcDaliTextTypesetter");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
+  DALI_TEST_CHECK( typesetter );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextTypesetterGetViewModel(void)
+{
+  tet_infoline(" UtcDaliTextTypesetter");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
+  DALI_TEST_CHECK( typesetter );
+
+  // Tests the view model has been created.
+  ViewModel* model = typesetter->GetViewModel();
+  DALI_TEST_CHECK( NULL != model );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextRenderingControllerRender(void)
+{
+  tet_infoline(" UtcDaliTextRenderingControllerRender");
+  ToolkitTestApplication application;
+
+  // Load some fonts.
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+
+  char* pathNamePtr = get_current_dir_name();
+  const std::string pathName( pathNamePtr );
+  free( pathNamePtr );
+
+  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenColorEmoji.ttf", EMOJI_FONT_SIZE );
+  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Configures the text controller similarly to the text-label.
+  ConfigureTextLabel( controller );
+
+  // Sets the text.
+  controller->SetMarkupProcessorEnabled( true );
+  controller->SetText( "<font family='TizenSansRegular'>Hello world </font><font family='TizenColorEmoji'>\xF0\x9F\x98\x81</font>" );
+
+  // Creates the text's model and relais-out the text.
+  const Size relayoutSize( 120.f, 60.f );
+  controller->Relayout( relayoutSize );
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr renderingController = Typesetter::New( controller->GetTextModel() );
+  DALI_TEST_CHECK( renderingController );
+
+  // Renders the text and creates the final bitmap.
+  PixelData bitmap = renderingController->Render( relayoutSize );
+  DALI_TEST_CHECK( bitmap );
+
+  DALI_TEST_EQUALS( 120u, bitmap.GetWidth(), TEST_LOCATION );
+  DALI_TEST_EQUALS( 60u, bitmap.GetHeight(), TEST_LOCATION );
+  DALI_TEST_EQUALS( Pixel::RGBA8888, bitmap.GetPixelFormat(), TEST_LOCATION );
+
+  // Changes vertical alignment.
+  controller->SetVerticalAlignment( Layout::VERTICAL_ALIGN_CENTER );
+  controller->Relayout( relayoutSize );
+
+  // Renders the text and creates the final bitmap.
+  bitmap = renderingController->Render( relayoutSize );
+  DALI_TEST_CHECK( bitmap );
+
+  DALI_TEST_EQUALS( 120u, bitmap.GetWidth(), TEST_LOCATION );
+  DALI_TEST_EQUALS( 60u, bitmap.GetHeight(), TEST_LOCATION );
+  DALI_TEST_EQUALS( Pixel::RGBA8888, bitmap.GetPixelFormat(), TEST_LOCATION );
+
+  controller->SetVerticalAlignment( Layout::VERTICAL_ALIGN_BOTTOM );
+  controller->Relayout( relayoutSize );
+
+  // Renders the text and creates the final bitmap.
+  bitmap = renderingController->Render( relayoutSize );
+  DALI_TEST_CHECK( bitmap );
+
+  DALI_TEST_EQUALS( 120u, bitmap.GetWidth(), TEST_LOCATION );
+  DALI_TEST_EQUALS( 60u, bitmap.GetHeight(), TEST_LOCATION );
+  DALI_TEST_EQUALS( Pixel::RGBA8888, bitmap.GetPixelFormat(), TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
diff --git a/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-ViewModel.cpp b/automated-tests/src/dali-toolkit-internal/utc-Dali-Text-ViewModel.cpp
new file mode 100644 (file)
index 0000000..422e6ac
--- /dev/null
@@ -0,0 +1,653 @@
+/*
+ * 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 <unistd.h>
+
+#include <dali-toolkit-test-suite-utils.h>
+#include <dali-toolkit/dali-toolkit.h>
+#include <toolkit-text-utils.h>
+#include <dali-toolkit/internal/text/font-description-run.h>
+#include <dali-toolkit/internal/text/rendering/text-typesetter.h>
+#include <dali-toolkit/internal/text/rendering/view-model.h>
+#include <dali-toolkit/internal/text/text-controller.h>
+
+using namespace Dali;
+using namespace Toolkit;
+using namespace Text;
+
+namespace
+{
+
+const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
+
+const Size CONTROL_SIZE( 200.f, 400.f );
+const Size CONTROL_SMALL_SIZE( 50.f, 100.f );
+const char* LOREM_IPSUM = "Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.\n"
+  "Usu ne nisl maiorum iudicabit, veniam epicurei oporteat eos an.\n"
+  "Ne nec nulla regione albucius, mea doctus delenit ad!\n"
+  "Et everti blandit adversarium mei, eam porro neglegentur suscipiantur an.\n"
+  "Quidam corpora at duo. An eos possim scripserit?\n\n"
+  "Aťqui dicant sěnťenťíae aň vel!\n"
+  "Vis viris médiocrem elaboraret ét, verear civibus moderatius ex duo!\n"
+  "Án veri laborě iňtěgré quó, mei aď poššit lobortis, mei prompťa čonsťitůťó eů.\n"
+  "Aliquip sanctůs delicáta quí ěá, et natum aliquam est?\n"
+  "Asšúm sapěret usu ůť.\n"
+  "Síť ut apeirián laboramúš percipitur, sůas hařum ín éos?\n";
+const Vector2 LOREM_SCROLL_POSITION( 0.f, -208.f );
+const Length LOREM_NUMBER_OF_LINES = 32u;
+const Length LOREM_NUMBER_OF_LINES_ELIDED = 21u;
+const Length LOREM_NUMBER_OF_GLYPHS = 632;
+const Length LOREM_NUMBER_OF_GLYPHS_ELIDED = 397u;
+
+// The expected layout size for UtcDaliTextViewModelGetLayoutSize
+const Size LAYOUT_SIZE( 190.f, 48.f );
+
+// The expected color indices for UtcDaliTextViewModelGetColors
+const ColorIndex COLOR_INDICES[] = { 0u, 0u, 0u, 0u, 0u, 0u, 1u, 1u, 1u, 2u, 2u, 2u, 2u, 2u, 1u, 1u, 1u, 1u, 1u, 3u, 1u, 1u, 1u, 0u, 0u, 0u, 0u };
+const Length NUMBER_OF_COLORS = 3u;
+const Vector4 COLORS[] = { Color::RED, Color::BLUE, Color::GREEN };
+
+struct ElideData
+{
+  std::string  description;
+  std::string  text;
+  Vector2      size;
+  unsigned int numberOfLines;
+  unsigned int numberOfGlyphs;
+  float*       positions;
+};
+
+bool ElideTest( const ElideData& data )
+{
+  std::cout << "  testing : " << data.description << std::endl;
+
+  // Load some fonts.
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+  fontClient.SetDpi( 93u, 93u );
+
+  char* pathNamePtr = get_current_dir_name();
+  const std::string pathName( pathNamePtr );
+  free( pathNamePtr );
+
+  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
+  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansHebrewRegular.ttf" );
+  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansArabicRegular.ttf" );
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
+  DALI_TEST_CHECK( typesetter );
+
+  // Tests the view model has been created.
+  ViewModel* model = typesetter->GetViewModel();
+  DALI_TEST_CHECK( NULL != model );
+
+  // Configures the text controller similarly to the text-label.
+  ConfigureTextLabel( controller );
+
+  // Sets a text and relais-out.
+  controller->SetMarkupProcessorEnabled( true );
+
+  controller->SetText( data.text );
+  controller->Relayout( data.size );
+
+  // Elide the glyphs.
+  model->ElideGlyphs();
+
+  if( data.numberOfLines != model->GetNumberOfLines() )
+  {
+    std::cout << "  different number of lines : " << model->GetNumberOfLines() << ", expected : " << data.numberOfLines << std::endl;
+    return false;
+  }
+
+  if( data.numberOfGlyphs != model->GetNumberOfGlyphs() )
+  {
+    std::cout << "  different number of glyphs : " << model->GetNumberOfGlyphs() << ", expected : " << data.numberOfGlyphs << std::endl;
+    return false;
+  }
+
+  const Vector2* const layoutBuffer = model->GetLayout();
+  const Length numberOfLines = model->GetNumberOfLines();
+
+  if( numberOfLines != 0u )
+  {
+    const LineRun& lastLine = *( model->GetLines() + numberOfLines - 1u );
+    const Length numberOfLastLineGlyphs = data.numberOfGlyphs - lastLine.glyphRun.glyphIndex;
+
+    std::cout << "  last line alignment offset : " << lastLine.alignmentOffset << std::endl;
+
+    for( unsigned int index = 0u; index < numberOfLastLineGlyphs; ++index )
+    {
+      if( *( data.positions + index ) != ( lastLine.alignmentOffset + ( *( layoutBuffer + lastLine.glyphRun.glyphIndex + index ) ).x ) )
+      {
+        std::cout << "  different layout :";
+        for( unsigned int i = 0; i < numberOfLastLineGlyphs; ++i )
+        {
+          std::cout << " " << ( lastLine.alignmentOffset + ( *( layoutBuffer + lastLine.glyphRun.glyphIndex + i ) ).x );
+        }
+        std::cout << std::endl;
+        std::cout << "          expected :";
+        for( unsigned int i = 0; i < numberOfLastLineGlyphs; ++i )
+        {
+          std::cout << " " << *( data.positions + i );
+        }
+        std::cout << std::endl;
+        return false;
+      }
+    }
+  }
+
+  return true;
+}
+
+} // namespace
+
+int UtcDaliTextViewModel(void)
+{
+  tet_infoline(" UtcDaliTextViewModel");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
+  DALI_TEST_CHECK( typesetter );
+
+  // Tests the view model has been created.
+  ViewModel* model = typesetter->GetViewModel();
+  DALI_TEST_CHECK( NULL != model );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextViewModelGetControlSize(void)
+{
+  tet_infoline(" UtcDaliTextViewModelGetControlSize");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
+  DALI_TEST_CHECK( typesetter );
+
+  // Tests the view model has been created.
+  ViewModel* model = typesetter->GetViewModel();
+  DALI_TEST_CHECK( NULL != model );
+
+  // Configures the text controller similarly to the text-editor.
+  ConfigureTextEditor( controller );
+
+  // The text has not been laid-out. The stored control's size should be zero.
+  DALI_TEST_EQUALS( Size::ZERO, model->GetControlSize(), TEST_LOCATION );
+
+  // Sets a text and relais-out.
+  controller->SetText( "Hello world" );
+  controller->Relayout( CONTROL_SIZE );
+
+  // The control's size should be stored now.
+  DALI_TEST_EQUALS( CONTROL_SIZE, model->GetControlSize(), TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextViewModelGetLayoutSize(void)
+{
+  tet_infoline(" UtcDaliTextViewModelGetLayoutSize");
+  ToolkitTestApplication application;
+
+  // Load some fonts.
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+  fontClient.SetDpi( 93u, 93u );
+
+  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();
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
+  DALI_TEST_CHECK( typesetter );
+
+  // Tests the view model has been created.
+  ViewModel* model = typesetter->GetViewModel();
+  DALI_TEST_CHECK( NULL != model );
+
+  // Configures the text controller similarly to the text-editor.
+  ConfigureTextEditor( controller );
+
+  // The text has not been laid-out. The stored control's size should be zero.
+  DALI_TEST_EQUALS( Size::ZERO, model->GetLayoutSize(), TEST_LOCATION );
+
+  // Sets a text and relais-out.
+  controller->SetMarkupProcessorEnabled( true );
+  controller->SetText( "<font family='TizenSansRegular' size='10'>Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.</font>" );
+  controller->Relayout( CONTROL_SIZE );
+
+  // The control's size should be stored now.
+  DALI_TEST_EQUALS( LAYOUT_SIZE, model->GetLayoutSize(), TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextViewModelGetScrollPosition(void)
+{
+  tet_infoline(" UtcDaliTextViewModelGetScrollPosition");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
+  DALI_TEST_CHECK( typesetter );
+
+  // Tests the view model has been created.
+  ViewModel* model = typesetter->GetViewModel();
+  DALI_TEST_CHECK( NULL != model );
+
+  // Configures the text controller similarly to the text-editor.
+  ConfigureTextEditor( controller );
+
+  // No text has been set. The scroll position should be zero.
+  DALI_TEST_EQUALS( Vector2::ZERO, model->GetScrollPosition(), TEST_LOCATION );
+
+  // Gains the keyboard focus, sets a big text and relais-out.
+  controller->KeyboardFocusGainEvent();
+  controller->SetText( LOREM_IPSUM );
+  controller->Relayout( CONTROL_SIZE );
+
+  // The text should be scrolled to the end.
+  DALI_TEST_EQUALS( LOREM_SCROLL_POSITION, model->GetScrollPosition(), TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextViewModelGetAlignment(void)
+{
+  tet_infoline(" UtcDaliTextViewModelGetAlignment");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
+  DALI_TEST_CHECK( typesetter );
+
+  // Tests the view model has been created.
+  ViewModel* model = typesetter->GetViewModel();
+  DALI_TEST_CHECK( NULL != model );
+
+  DALI_TEST_EQUALS( Layout::HORIZONTAL_ALIGN_BEGIN, model->GetHorizontalAlignment(), TEST_LOCATION );
+  DALI_TEST_EQUALS( Layout::VERTICAL_ALIGN_TOP, model->GetVerticalAlignment(), TEST_LOCATION );
+
+  controller->SetHorizontalAlignment( Layout::HORIZONTAL_ALIGN_CENTER );
+  controller->SetVerticalAlignment( Layout::VERTICAL_ALIGN_CENTER );
+
+  DALI_TEST_EQUALS( Layout::HORIZONTAL_ALIGN_CENTER, model->GetHorizontalAlignment(), TEST_LOCATION );
+  DALI_TEST_EQUALS( Layout::VERTICAL_ALIGN_CENTER, model->GetVerticalAlignment(), TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextViewModelIsTextElideEnabled(void)
+{
+  tet_infoline(" UtcDaliTextViewModelIsTextElideEnabled");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
+  DALI_TEST_CHECK( typesetter );
+
+  // Tests the view model has been created.
+  ViewModel* model = typesetter->GetViewModel();
+  DALI_TEST_CHECK( NULL != model );
+
+  // Configures the text controller similarly to the text-editor.
+  ConfigureTextEditor( controller );
+
+  // Elide text should be disabled.
+  DALI_TEST_CHECK( !model->IsTextElideEnabled() );
+
+  // Configures the text controller similarly to the text-label.
+  ConfigureTextLabel( controller );
+
+  // Elide text should be enabled.
+  DALI_TEST_CHECK( model->IsTextElideEnabled() );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextViewModelGetLines(void)
+{
+  tet_infoline(" UtcDaliTextViewModelGetLines");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
+  DALI_TEST_CHECK( typesetter );
+
+  // Tests the view model has been created.
+  ViewModel* model = typesetter->GetViewModel();
+  DALI_TEST_CHECK( NULL != model );
+
+  // Configures the text controller similarly to the text-editor.
+  ConfigureTextEditor( controller );
+
+  // The number of lines should be zero.
+  DALI_TEST_EQUALS( 0u, model->GetNumberOfLines(), TEST_LOCATION );
+  DALI_TEST_CHECK( NULL == model->GetLines() );
+
+  // Sets a text and relais-out.
+  controller->SetText( LOREM_IPSUM );
+  controller->Relayout( CONTROL_SIZE );
+
+  DALI_TEST_EQUALS( LOREM_NUMBER_OF_LINES, model->GetNumberOfLines(), TEST_LOCATION );
+  DALI_TEST_CHECK( NULL != model->GetLines() );
+
+  // Configures the text controller similarly to the text-label.
+  ConfigureTextLabel( controller );
+
+  // Relais-out for the text-label configuration.
+  controller->Relayout( Size( 100.f, 100.f) ); // Change the size to force a relayout.
+  controller->Relayout( CONTROL_SIZE );
+
+  DALI_TEST_EQUALS( LOREM_NUMBER_OF_LINES_ELIDED, model->GetNumberOfLines(), TEST_LOCATION );
+  DALI_TEST_CHECK( NULL != model->GetLines() );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextViewModelGetGlyphsLayout(void)
+{
+  tet_infoline(" UtcDaliTextViewModelGetGlyphsLayout");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
+  DALI_TEST_CHECK( typesetter );
+
+  // Tests the view model has been created.
+  ViewModel* model = typesetter->GetViewModel();
+  DALI_TEST_CHECK( NULL != model );
+
+  // Configures the text controller similarly to the text-editor.
+  ConfigureTextEditor( controller );
+
+  // The number of glyphs should be zero.
+  DALI_TEST_EQUALS( 0u, model->GetNumberOfGlyphs(), TEST_LOCATION );
+  DALI_TEST_CHECK( NULL == model->GetGlyphs() );
+  DALI_TEST_CHECK( NULL == model->GetLayout() );
+
+  // Sets a text and relais-out.
+  controller->SetText( LOREM_IPSUM );
+  controller->Relayout( CONTROL_SIZE );
+
+  DALI_TEST_EQUALS( LOREM_NUMBER_OF_GLYPHS, model->GetNumberOfGlyphs(), TEST_LOCATION );
+  DALI_TEST_CHECK( NULL != model->GetGlyphs() );
+  DALI_TEST_CHECK( NULL != model->GetLayout() );
+
+  // Configures the text controller similarly to the text-label.
+  ConfigureTextLabel( controller );
+
+  // Relais-out for the text-label configuration.
+  controller->Relayout( Size( 100.f, 100.f) ); // Change the size to force a relayout.
+  controller->Relayout( CONTROL_SIZE );
+
+  // Elide the glyphs.
+  model->ElideGlyphs();
+
+  DALI_TEST_EQUALS( LOREM_NUMBER_OF_GLYPHS_ELIDED, model->GetNumberOfGlyphs(), TEST_LOCATION );
+  DALI_TEST_CHECK( NULL != model->GetGlyphs() );
+  DALI_TEST_CHECK( NULL != model->GetLayout() );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextViewModelGetColors(void)
+{
+  tet_infoline(" UtcDaliTextViewModelGetColors");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
+  DALI_TEST_CHECK( typesetter );
+
+  // Tests the view model has been created.
+  ViewModel* model = typesetter->GetViewModel();
+  DALI_TEST_CHECK( NULL != model );
+
+  // Configures the text controller similarly to the text-label.
+  ConfigureTextLabel( controller );
+
+  // Sets a text and relais-out.
+  controller->SetMarkupProcessorEnabled( true );
+  controller->SetText( "Lorem <color value='red'>ips<color value='blue'>um do</color>lor s<color value='green'>i</color>t a</color>met." );
+  controller->Relayout( CONTROL_SIZE );
+
+  DALI_TEST_EQUALS( Color::BLACK, model->GetDefaultColor(), TEST_LOCATION );
+
+  const ColorIndex* const colorIndicesBuffer = model->GetColorIndices();
+
+  const Length numberOfGlyphs = model->GetNumberOfGlyphs();
+  for( ColorIndex index = 0u; index < numberOfGlyphs; ++index )
+  {
+    DALI_TEST_EQUALS( COLOR_INDICES[index], *( colorIndicesBuffer + index ), TEST_LOCATION );
+  }
+
+  const Vector4* const colors = model->GetColors();
+  for( unsigned int index = 0u; index < NUMBER_OF_COLORS; ++index )
+  {
+    DALI_TEST_EQUALS( COLORS[index], *( colors + index ), TEST_LOCATION );
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextViewModelElideText01(void)
+{
+  tet_infoline(" UtcDaliTextViewModelElideText01");
+  ToolkitTestApplication application;
+
+  // Creates a text controller.
+  ControllerPtr controller = Controller::New();
+
+  // Tests the rendering controller has been created.
+  TypesetterPtr typesetter = Typesetter::New( controller->GetTextModel() );
+  DALI_TEST_CHECK( typesetter );
+
+  // Tests the view model has been created.
+  ViewModel* model = typesetter->GetViewModel();
+  DALI_TEST_CHECK( NULL != model );
+
+  // Configures the text controller similarly to the text-editor.
+  ConfigureTextEditor( controller );
+
+  // The number of glyphs should be zero.
+  DALI_TEST_EQUALS( 0u, model->GetNumberOfGlyphs(), TEST_LOCATION );
+  DALI_TEST_EQUALS( 0u, model->GetNumberOfLines(), TEST_LOCATION );
+  DALI_TEST_CHECK( NULL == model->GetGlyphs() );
+  DALI_TEST_CHECK( NULL == model->GetLayout() );
+
+  // Sets a text and relais-out.
+  controller->SetText( LOREM_IPSUM );
+  controller->Relayout( CONTROL_SIZE );
+
+  // Keep the pointers to the glyphs and layout.
+  // As the text is not elided with this configuration, the pointers shoud be the same after calling the ElideGlyphs() method.
+  const GlyphInfo* const glyphsModel = model->GetGlyphs();
+  const Vector2* layoutsModel = model->GetLayout();
+
+  // Elide the glyphs. Text shouldn't be elided with this configuration.
+  model->ElideGlyphs();
+
+  DALI_TEST_CHECK( glyphsModel == model->GetGlyphs() );
+  DALI_TEST_CHECK( layoutsModel == model->GetLayout() );
+
+  DALI_TEST_EQUALS( LOREM_NUMBER_OF_GLYPHS, model->GetNumberOfGlyphs(), TEST_LOCATION );
+  DALI_TEST_EQUALS( LOREM_NUMBER_OF_LINES, model->GetNumberOfLines(), TEST_LOCATION );
+
+  // Configures the text controller similarly to the text-label.
+  ConfigureTextLabel( controller );
+
+  // Clear the text and relais-out.
+  controller->SetText( "" );
+  controller->Relayout( CONTROL_SIZE );
+
+  DALI_TEST_EQUALS( 0u, model->GetNumberOfGlyphs(), TEST_LOCATION );
+  DALI_TEST_EQUALS( 0u, model->GetNumberOfLines(), TEST_LOCATION );
+
+  // Elide the glyphs. Should not add the ellipsis glyph.
+  model->ElideGlyphs();
+
+  DALI_TEST_EQUALS( 0u, model->GetNumberOfGlyphs(), TEST_LOCATION );
+
+  // Sets a text that doesn't need to be elided.
+  controller->SetText( "Hello\n" );
+  controller->Relayout( CONTROL_SIZE );
+
+  // Elide the glyphs.
+  model->ElideGlyphs();
+
+  DALI_TEST_EQUALS( 6u, model->GetNumberOfGlyphs(), TEST_LOCATION );
+  DALI_TEST_EQUALS( 2u, model->GetNumberOfLines(), TEST_LOCATION );
+
+  // Sets a text and relais-out.
+  controller->SetText( LOREM_IPSUM );
+  controller->Relayout( CONTROL_SIZE );
+
+  // Elide the glyphs.
+  model->ElideGlyphs();
+
+  DALI_TEST_EQUALS( LOREM_NUMBER_OF_GLYPHS_ELIDED, model->GetNumberOfGlyphs(), TEST_LOCATION );
+  DALI_TEST_EQUALS( LOREM_NUMBER_OF_LINES_ELIDED, model->GetNumberOfLines(), TEST_LOCATION );
+  const GlyphInfo* const glyphs = model->GetGlyphs();
+  const Vector2* layouts = model->GetLayout();
+  DALI_TEST_CHECK( NULL != glyphs );
+  DALI_TEST_CHECK( NULL != layouts );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
+
+int UtcDaliTextViewModelElideText02(void)
+{
+  tet_infoline(" UtcDaliTextViewModelElideText02");
+
+  Size textSize00( 100.f, 100.f );
+
+  Size textSize01( 80.f, 100.f );
+  float positions01[] = { 0.f, 10.f, 16.f, 26.f, 35.f, 38.f, 46.f, 56.f };
+
+  Size textSize02( 80.f, 100.f );
+  float positions02[] = { 72.f, 63.f, 54.f, 50.f, 43.f, 38.f, 30.f, 11.f };
+
+  Size textSize03( 80.f, 100.f );
+  float positions03[] = { 77.f, 76.f, 71.f, 62.f, 60.f, 52.f, 47.f, 42.f, 39.f, 35.f, 32.f, 13.f };
+
+  Size textSize04( 80.f, 10.f );
+  float positions04[] = { 2.f };
+
+  struct ElideData data[] =
+  {
+    {
+      "void text",
+      "",
+      textSize00,
+      0u,
+      0u,
+      NULL
+    },
+    {
+      "Latin script",
+      "<font family='TizenSans'>Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.</font>",
+      textSize01,
+      5u,
+      42u,
+      positions01
+    },
+    {
+      "Hebrew script",
+      "<font family='TizenSansHebrew'>צעד על לשון המלצת לאחרונה, אם לכאן שנורו סרבול מדע, קרן דת שפות להפוך.</font>",
+      textSize02,
+      5u,
+      49u,
+      positions02
+    },
+    {
+      "Arabic script",
+      "<font family='TizenSansArabic'>عل النفط ديسمبر الإمداد بال, بين وترك شعار هو. لمّ من المبرمة النفط بالسيطرة, أم يتم تحرّك وبغطاء, عدم في لإعادة وإقامة رجوعهم.</font>",
+      textSize03,
+      5u,
+      79u,
+      positions03
+    },
+    {
+      "Small control size, no line fits.",
+      "<font family='TizenSans'>Lorem ipsum dolor sit amet, aeque definiebas ea mei, posse iracundia ne cum.</font>",
+      textSize04,
+      1u,
+      1u,
+      positions04
+    }
+  };
+  const unsigned int numberOfTests = 5u;
+
+  for( unsigned int index = 0u; index < numberOfTests; ++index )
+  {
+    ToolkitTestApplication application;
+    if( !ElideTest( data[index] ) )
+    {
+      tet_result(TET_FAIL);
+    }
+  }
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
index 11b09f1..a13b4d8 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
-#include <toolkit-text-model.h>
+#include <toolkit-text-utils.h>
 
 
 using namespace Dali;
index a4bfbcb..b8ccf57 100644 (file)
 
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
+#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
 #include <dali-toolkit/internal/visuals/wireframe/wireframe-visual.h>
+#include <dali-toolkit/dali-toolkit.h>
 
 using namespace Dali::Toolkit::Internal;
 
@@ -70,3 +73,51 @@ int UtcDaliWireframeVisual(void)
   tet_result(TET_PASS);
   END_TEST;
 }
+
+int UtcDaliTextVisual(void)
+{
+  tet_infoline(" UtcDaliTextVisual");
+  ToolkitTestApplication application;
+
+  Stage stage = Stage::GetCurrent();
+
+  Dali::Toolkit::Control control = Dali::Toolkit::Control::New();
+  control.SetParentOrigin( ParentOrigin::CENTER );
+
+  Dali::Property::Map map;
+  map[ Dali::Toolkit::Visual::Property::TYPE ] = Dali::Toolkit::DevelVisual::TEXT;
+  map[ Dali::Toolkit::TextVisual::Property::ENABLE_MARKUP ] = true;
+  std::string markupText( "<color value='blue'><font size='50'>H</font></color>ello <color value='blue'><font size='50'>w</font></color>orld" );
+  map[ Dali::Toolkit::TextVisual::Property::TEXT ] = markupText;
+  map[ Dali::Toolkit::TextVisual::Property::TEXT_COLOR ] = Dali::Vector4( 0.25f, 0.25f, 0.5f, 1.f );
+  map[ Dali::Toolkit::TextVisual::Property::FONT_FAMILY ] = "TizenSansRegular";
+  map[ Dali::Toolkit::TextVisual::Property::POINT_SIZE ] = 30.f;
+  map[ Dali::Toolkit::TextVisual::Property::HORIZONTAL_ALIGNMENT ] = "CENTER";
+  map[ Dali::Toolkit::TextVisual::Property::VERTICAL_ALIGNMENT ] = "CENTER";
+
+  control.SetProperty( Dali::Toolkit::Control::Property::BACKGROUND, map );
+
+  stage.Add( control );
+
+  try
+  {
+    application.SendNotification();
+    application.Render();
+  }
+  catch( ... )
+  {
+    tet_result(TET_FAIL);
+  }
+
+  // The renderer should be removed.
+  control.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
+  control.SetSize( 1.f, 0.f );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( 0u, control.GetRendererCount(), TEST_LOCATION );
+
+  tet_result(TET_PASS);
+  END_TEST;
+}
index d8d55f8..caa901e 100644 (file)
@@ -54,6 +54,7 @@ LIST(APPEND TC_SOURCES
 PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
   dali-core
   dali-toolkit
+  dali-adaptor
 )
 
 PKG_CHECK_MODULES(DALI_ADAPTOR REQUIRED
index 6fcc10d..ae4132b 100644 (file)
@@ -19,6 +19,8 @@
 
 #include <dali-toolkit/dali-toolkit.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
+#include <dali-toolkit/devel-api/visual-factory/devel-visual-properties.h>
+#include <dali-toolkit/devel-api/align-enums.h>
 
 namespace Dali
 {
@@ -88,11 +90,23 @@ DummyControlImpl::~DummyControlImpl()
 void DummyControlImpl::RegisterVisual( Property::Index index, Toolkit::Visual::Base visual )
 {
   Control::RegisterVisual( index, visual );
+
+  VisualIndices::iterator iter = std::find( mRegisteredVisualIndices.begin(), mRegisteredVisualIndices.end(), index );
+  if( iter == mRegisteredVisualIndices.end() )
+  {
+    mRegisteredVisualIndices.push_back(index);
+  }
 }
 
 void DummyControlImpl::RegisterVisual( Property::Index index, Toolkit::Visual::Base visual, bool enabled )
 {
   Control::RegisterVisual( index, visual, enabled );
+
+  VisualIndices::iterator iter = std::find( mRegisteredVisualIndices.begin(), mRegisteredVisualIndices.end(), index );
+  if( iter == mRegisteredVisualIndices.end() )
+  {
+    mRegisteredVisualIndices.push_back(index);
+  }
 }
 
 void DummyControlImpl::UnregisterVisual( Property::Index index )
@@ -115,6 +129,7 @@ bool DummyControlImpl::IsVisualEnabled( Property::Index index )
   return Control::IsVisualEnabled( index );
 }
 
+
 Animation DummyControlImpl::CreateTransition( const Toolkit::TransitionData& transition )
 {
   return Control::CreateTransition( transition );
@@ -189,6 +204,24 @@ bool DummyControlImplOverride::OnKeyEvent(const KeyEvent& event) { keyEventCalle
 void DummyControlImplOverride::OnKeyInputFocusGained() { keyInputFocusGained = true; }
 void DummyControlImplOverride::OnKeyInputFocusLost() { keyInputFocusLost = true; }
 
+void DummyControlImplOverride::OnRelayout( const Vector2& size, RelayoutContainer& container )
+{
+  Property::Map transformMap;
+  transformMap
+    .Add( Toolkit::VisualProperty::Transform::Property::OFFSET, Vector2(0.0f, 0.0f) )
+    .Add( Toolkit::VisualProperty::Transform::Property::SIZE, Vector2(1.0f, 1.0f) )
+    .Add( Toolkit::VisualProperty::Transform::Property::ORIGIN, Toolkit::Align::CENTER )
+    .Add( Toolkit::VisualProperty::Transform::Property::ANCHOR_POINT, Toolkit::Align::CENTER )
+    .Add( Toolkit::VisualProperty::Transform::Property::OFFSET_SIZE_MODE, Vector4::ZERO );
+
+  for( VisualIndices::iterator iter = mRegisteredVisualIndices.begin(); iter != mRegisteredVisualIndices.end() ; ++iter )
+  {
+    Visual::Base visual = GetVisual(*iter);
+    visual.SetTransformAndSize( transformMap, size );
+  }
+}
+
+
 DummyControl DummyControl::New( bool override )
 {
   DummyControl control;
index 04847d1..95b4126 100644 (file)
@@ -84,6 +84,8 @@ public:
   void CustomSlot1( Actor actor );
 
   bool mCustomSlot1Called;
+  typedef std::vector<Property::Index> VisualIndices;
+  VisualIndices mRegisteredVisualIndices;
 
 protected:
 
@@ -135,6 +137,7 @@ private: // From CustomActorImpl
   virtual bool OnKeyEvent(const KeyEvent& event);
   virtual void OnKeyInputFocusGained();
   virtual void OnKeyInputFocusLost();
+  virtual void OnRelayout( const Vector2& size, RelayoutContainer& container );
 
 public:
 
index 332ddaa..76b391b 100644 (file)
@@ -329,8 +329,9 @@ void Usage(const char* program)
   printf("Usage: \n"
          "   %s <testcase name>\t\t Execute a test case\n"
          "   %s \t\t Execute all test cases in parallel\n"
-         "   %s -r\t\t Execute all test cases in parallel, rerunning failed test cases\n",
-         program, program, program);
+         "   %s -r\t\t Execute all test cases in parallel, rerunning failed test cases\n"
+         "   %s -s\t\t Execute all test cases serially\n",
+         program, program, program, program);
 }
 
 } // namespace
index f77cdde..b809b87 100644 (file)
 #include <cstddef>
 #include <semaphore.h>
 #include <math.h>
+#include <ctime>
 #include <climits>
+#include <cstdio>
+#include <unistd.h>
 
 namespace Dali
 {
@@ -63,14 +66,18 @@ void EventThreadCallback::Trigger()
   }
 }
 
-void EventThreadCallback::WaitingForTrigger(unsigned int count)
+bool EventThreadCallback::WaitingForTrigger(unsigned int count, unsigned int seconds)
 {
   if(  mImpl->triggeredCount >= count )
   {
-    return;
+    return true;
   }
+  struct timespec now;
+  clock_gettime( CLOCK_REALTIME, &now );
+  now.tv_sec += seconds;
   mImpl->expectedCount = count;
-  sem_wait( &(mImpl->mySemaphore) );
+  int error = sem_timedwait( &(mImpl->mySemaphore), &now );
+  return error != 0;
 }
 
 CallbackBase* EventThreadCallback::GetCallback()
@@ -84,3 +91,46 @@ EventThreadCallback* EventThreadCallback::Get()
 }
 
 }
+
+namespace Test
+{
+
+bool WaitForEventThreadTrigger( int triggerCount )
+{
+  bool success = true;
+  const int TEST_TIMEOUT(30);
+
+  struct timespec startTime;
+  struct timespec now;
+  clock_gettime( CLOCK_REALTIME, &startTime );
+  now.tv_sec = startTime.tv_sec;
+  now.tv_nsec = startTime.tv_nsec;
+
+  Dali::EventThreadCallback* eventTrigger = NULL;
+  while( eventTrigger == NULL )
+  {
+    eventTrigger = Dali::EventThreadCallback::Get();
+    clock_gettime( CLOCK_REALTIME, &now );
+    if( now.tv_sec - startTime.tv_sec > TEST_TIMEOUT )
+    {
+      success = false;
+      break;
+    }
+    usleep(10);
+  }
+  if( eventTrigger != NULL )
+  {
+    Dali::CallbackBase* callback = eventTrigger->GetCallback();
+    eventTrigger->WaitingForTrigger( triggerCount, TEST_TIMEOUT - (now.tv_sec - startTime.tv_sec) );
+    Dali::CallbackBase::Execute( *callback );
+  }
+
+  clock_gettime( CLOCK_REALTIME, &now );
+  if( now.tv_sec > startTime.tv_sec + 1 )
+  {
+    fprintf(stderr, "WaitForEventThreadTrigger took %ld seconds\n", now.tv_sec - startTime.tv_sec );
+  }
+  return success;
+}
+
+}
index d67ca24..a0303be 100644 (file)
@@ -36,7 +36,7 @@ public:
 
   void Trigger();
 
-  void WaitingForTrigger(unsigned int count);
+  bool WaitingForTrigger(unsigned int count, unsigned int seconds );
 
   CallbackBase* GetCallback();
 
@@ -58,4 +58,19 @@ private:
 
 }
 
+namespace Test
+{
+
+/**
+ * Wait for the tested code to create an event trigger, then
+ * wait for triggerCount Trigger calls to occur, and execute the trigger
+ * callback afterwards.
+ *
+ * Will wait for a maximum of 30s before failing the test and returning.
+ */
+bool WaitForEventThreadTrigger( int triggerCount );
+
+}
+
+
 #endif /* __DALI_TOOLKIT_EVENT_THREAD_CALLBACK_H__ */
index d06ba71..df25aaa 100644 (file)
@@ -152,6 +152,7 @@ public:
   void GetFontMetrics( FontId fontId, FontMetrics& metrics ){}
   GlyphIndex GetGlyphIndex( FontId fontId, Character charcode ){return 0;}
   bool GetGlyphMetrics( GlyphInfo* array, uint32_t size, bool horizontal ){return true;}
+  void CreateBitmap( FontId fontId, GlyphIndex glyphIndex, Dali::TextAbstraction::FontClient::GlyphBufferData& data ){}
   PixelData CreateBitmap( FontId fontId, GlyphIndex glyphIndex ){return PixelData();}
   void CreateVectorBlob( FontId fontId, GlyphIndex glyphIndex, VectorBlob*& blob,
                          unsigned int& blobLength, unsigned int& nominalWidth, unsigned int& nominalHeight )
@@ -159,6 +160,7 @@ public:
     blobLength = 0;
   }
   const GlyphInfo& GetEllipsisGlyph( PointSize26Dot6 pointSize ){return mGlyphInfo;}
+  bool IsColorGlyph( FontId fontId, GlyphIndex glyphIndex ){return false;}
 private:
   unsigned int mDpiHorizontal;
   unsigned int mDpiVertical;
@@ -356,6 +358,14 @@ FontClient::FontClient( const FontClient& handle )
 {
 }
 
+FontClient::GlyphBufferData::GlyphBufferData()
+{
+}
+
+FontClient::GlyphBufferData::~GlyphBufferData()
+{
+}
+
 FontClient& FontClient::operator=( const FontClient& handle )
 {
   BaseHandle::operator=( handle );
@@ -462,12 +472,16 @@ bool FontClient::GetGlyphMetrics( GlyphInfo* array, uint32_t size, GlyphType typ
   return GetImplementation(*this).GetGlyphMetrics( array, size, horizontal );
 }
 
+void FontClient::CreateBitmap( FontId fontId, GlyphIndex glyphIndex, Dali::TextAbstraction::FontClient::GlyphBufferData& data )
+{
+  GetImplementation(*this).CreateBitmap( fontId, glyphIndex, data );
+}
+
 PixelData FontClient::CreateBitmap( FontId fontId, GlyphIndex glyphIndex )
 {
   return GetImplementation(*this).CreateBitmap( fontId, glyphIndex );
 }
 
-
 void FontClient::CreateVectorBlob( FontId fontId,
                                    GlyphIndex glyphIndex,
                                    VectorBlob*& blob,
@@ -483,6 +497,11 @@ const GlyphInfo& FontClient::GetEllipsisGlyph( PointSize26Dot6 pointSize )
   return GetImplementation(*this).GetEllipsisGlyph( pointSize );
 }
 
+bool FontClient::IsColorGlyph( FontId fontId, GlyphIndex glyphIndex )
+{
+  return GetImplementation(*this).IsColorGlyph( fontId, glyphIndex );
+}
+
 FontClient::FontClient( Internal::FontClient* internal )
 : BaseHandle( internal )
 {
index 74dcc73..6e99e48 100644 (file)
@@ -174,12 +174,7 @@ int UtcDaliAsyncImageLoaderLoadAndLoadedSignal(void)
   uint32_t id02 = loader.Load( gImage_50_RGBA, ImageDimensions( 25, 25 ) );
   uint32_t id03 = loader.Load( gImage_128_RGB, ImageDimensions( 100, 100 ), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, true );
 
-  EventThreadCallback* eventTrigger = EventThreadCallback::Get();
-  CallbackBase* callback = eventTrigger->GetCallback();
-
-  eventTrigger->WaitingForTrigger( 3 );// waiting until all three images are loaded
-
-  CallbackBase::Execute( *callback );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 3 ), true, TEST_LOCATION );
 
   application.SendNotification();
   application.Render();
@@ -205,12 +200,7 @@ int UtcDaliAsyncImageLoaderCancel(void)
   uint32_t id02 = loader.Load( gImage_50_RGBA, ImageDimensions( 25, 25 ) );
   uint32_t id03 = loader.Load( gImage_128_RGB, ImageDimensions( 100, 100 ), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR, true );
 
-  EventThreadCallback* eventTrigger = EventThreadCallback::Get();
-  CallbackBase* callback = eventTrigger->GetCallback();
-
-  eventTrigger->WaitingForTrigger( 3 ); // waiting until images are loaded
-
-  CallbackBase::Execute( *callback );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 3 ), true, TEST_LOCATION );
 
   application.SendNotification();
   application.Render();
@@ -248,4 +238,3 @@ int UtcDaliAsyncImageLoaderCancelAll(void)
 
   END_TEST;
 }
-
index 5fe744f..0bee5e5 100644 (file)
@@ -207,12 +207,7 @@ int UtcDaliImageAtlasUploadP(void)
   Vector4 textureRect3;
   atlas.Upload( textureRect3, gImage_128_RGB, ImageDimensions(128, 128) );
 
-  EventThreadCallback* eventTrigger = EventThreadCallback::Get();
-  CallbackBase* callback = eventTrigger->GetCallback();
-
-  eventTrigger->WaitingForTrigger( 3 );// waiting until all three images are loaded
-
-  CallbackBase::Execute( *callback );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 3 ), true, TEST_LOCATION );
 
   application.SendNotification();
   application.Render(RENDER_FRAME_INTERVAL);
@@ -262,8 +257,6 @@ int UtcDaliImageAtlasUploadWithObserver01(void)
   TestApplication application;
   ImageAtlas atlas = ImageAtlas::New( 200, 200 );
 
-  EventThreadCallback* eventTrigger = EventThreadCallback::Get();
-  CallbackBase* callback = eventTrigger->GetCallback();
 
   gCountOfTestFuncCall = 0;
   TestUploadObserver uploadObserver;
@@ -276,8 +269,7 @@ int UtcDaliImageAtlasUploadWithObserver01(void)
   atlas.Upload( textureRect3, gImage_128_RGB, ImageDimensions(128, 128), FittingMode::DEFAULT, true, &uploadObserver );
 
   // waiting until all three images are loaded and uploaded to atlas
-  eventTrigger->WaitingForTrigger( 3 );
-  CallbackBase::Execute( *callback );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 3 ), true, TEST_LOCATION );
   application.SendNotification();
   application.Render(RENDER_FRAME_INTERVAL);
 
@@ -292,9 +284,6 @@ int UtcDaliImageAtlasUploadWithObserver02(void)
   TestApplication application;
   ImageAtlas atlas = ImageAtlas::New( 200, 200 );
 
-  EventThreadCallback* eventTrigger = EventThreadCallback::Get();
-  CallbackBase* callback = eventTrigger->GetCallback();
-
   gCountOfTestFuncCall = 0;
   TestUploadObserver* uploadObserver = new TestUploadObserver;
 
@@ -309,8 +298,8 @@ int UtcDaliImageAtlasUploadWithObserver02(void)
   delete uploadObserver;
 
  // waiting until all three images are loaded and uploaded to atlas
-  eventTrigger->WaitingForTrigger( 3 );
-  CallbackBase::Execute( *callback );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 3 ), true, TEST_LOCATION );
+
   application.Render(RENDER_FRAME_INTERVAL);
   application.SendNotification();
 
@@ -382,20 +371,19 @@ int UtcDaliImageAtlasImageView(void)
 
   ImageView imageView1 = ImageView::New( gImage_34_RGBA, ImageDimensions(34, 34) );
   ImageView imageView2 = ImageView::New( gImage_50_RGBA, ImageDimensions(50, 50) );
-  Stage::GetCurrent().Add( imageView1 );
-  Stage::GetCurrent().Add( imageView2 );
 
-  EventThreadCallback* eventTrigger = EventThreadCallback::Get();
-  while( eventTrigger == NULL) // waiting uintil the ImageAtlas is created by ImageAtlasManager
-  {
-    usleep(10);
-    eventTrigger = EventThreadCallback::Get();
-  }
-  CallbackBase* callback = eventTrigger->GetCallback();
+  // ImageView doesn't do size negotiation properly: it only listens to OnSizeSet:
+  imageView1.SetSize( 100, 100 );
+  imageView2.SetSize( 100, 100 );
+  imageView1.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
+  imageView2.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
 
-  eventTrigger->WaitingForTrigger( 2 );// waiting until both images are loaded
+  application.GetPlatform().SetClosestImageSize(  Vector2(34, 34) );
+  Stage::GetCurrent().Add( imageView1 );
+  application.GetPlatform().SetClosestImageSize(  Vector2(50, 50) );
+  Stage::GetCurrent().Add( imageView2 );
 
-  CallbackBase::Execute( *callback );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 2 ), true, TEST_LOCATION );
 
   application.SendNotification();
   application.Render(RENDER_FRAME_INTERVAL);
@@ -426,10 +414,10 @@ int UtcDaliImageAtlasImageView(void)
   application.SendNotification();
   application.Render(RENDER_FRAME_INTERVAL);
   ImageView imageView3 = ImageView::New( gImage_128_RGB, ImageDimensions(100, 100) );
+  application.GetPlatform().SetClosestImageSize(  Vector2(100, 100) );
   Stage::GetCurrent().Add( imageView3 );
 
-  eventTrigger->WaitingForTrigger( 3 ); // waiting for the third image loaded
-  CallbackBase::Execute( *callback );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 3 ), true, TEST_LOCATION );
 
   application.SendNotification();
   application.Render(RENDER_FRAME_INTERVAL);
index 12c3f17..2ff700b 100644 (file)
@@ -384,7 +384,7 @@ int UtcDaliImageViewAsyncLoadingWithoutAltasing(void)
   END_TEST;
 }
 
-int UtcDaliImageViewAsyncLoadingWithAltasing(void)
+int UtcDaliImageViewAsyncLoadingWithAtlasing(void)
 {
   ToolkitTestApplication application;
 
@@ -393,13 +393,10 @@ int UtcDaliImageViewAsyncLoadingWithAltasing(void)
   callStack.Reset();
   callStack.Enable(true);
 
-  BitmapLoader::ResetLatestCreated();
   ImageView imageView = ImageView::New( gImage_34_RGBA, ImageDimensions( 34, 34 ) );
 
   // By default, Aysnc loading is used
   // loading is not started if the actor is offStage
-  BitmapLoader loader = BitmapLoader::GetLatestCreated();
-  DALI_TEST_CHECK( !loader );
 
   Stage::GetCurrent().Add( imageView );
   application.SendNotification();
@@ -407,20 +404,8 @@ int UtcDaliImageViewAsyncLoadingWithAltasing(void)
   application.Render(16);
   application.SendNotification();
 
-  // loading started
-  loader = BitmapLoader::GetLatestCreated();
-  DALI_TEST_CHECK( loader );
-
-  // worker thread is created
-  EventThreadCallback* eventTrigger = EventThreadCallback::Get();
-  DALI_TEST_CHECK( eventTrigger );
-
-  loader.WaitForLoading();// waiting until the image to be loaded
-  DALI_TEST_CHECK( loader.IsLoaded() );
-
-  eventTrigger->WaitingForTrigger( 1 );
-  CallbackBase* callback = eventTrigger->GetCallback();
-  CallbackBase::Execute( *callback );
+  // loading started, this waits for the loader thread for max 30 seconds
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
 
   application.SendNotification();
   application.Render(16);
index 95a6eb5..6ef6e9e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 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.
@@ -175,8 +175,19 @@ public:
   Actor mActivatedActor;
 };
 
-} // namespace
+// Used to connect to signals via the ConnectSignal Handle method
+struct CallbackFunctor
+{
+  CallbackFunctor()
+  {
+  }
 
+  void operator()()
+  {
+  }
+};
+
+} // namespace
 
 int UtcDaliKeyboardFocusManagerGet(void)
 {
@@ -668,3 +679,19 @@ int UtcDaliKeyboardFocusManagerSignalFocusGroupChanged(void)
   focusGroupChangedCallback.Reset();
   END_TEST;
 }
+
+int UtcDaliKeyboardFocusManagerSignals(void)
+{
+  ToolkitTestApplication application;
+
+  KeyboardFocusManager manager = KeyboardFocusManager::Get();
+  DALI_TEST_CHECK( manager );
+
+  ConnectionTracker* testTracker = new ConnectionTracker();
+  DALI_TEST_EQUALS( true, manager.ConnectSignal( testTracker, "keyboardPreFocusChange", CallbackFunctor() ), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, manager.ConnectSignal( testTracker, "keyboardFocusChanged", CallbackFunctor() ), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, manager.ConnectSignal( testTracker, "keyboardFocusGroupChanged", CallbackFunctor() ), TEST_LOCATION );
+  DALI_TEST_EQUALS( true, manager.ConnectSignal( testTracker, "keyboardFocusedActorEnterKey", CallbackFunctor() ), TEST_LOCATION );
+
+  END_TEST;
+}
index 022695d..dd9a805 100644 (file)
@@ -1442,3 +1442,93 @@ int utcDaliTextEditorEvent03(void)
 
   END_TEST;
 }
+
+int utcDaliTextEditorEvent04(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" utcDaliTextEditorEvent04");
+
+  // Checks if the highlight actor is created.
+
+  TextEditor editor = TextEditor::New();
+  DALI_TEST_CHECK( editor );
+
+  Stage::GetCurrent().Add( editor );
+
+  editor.SetProperty( TextEditor::Property::TEXT, "Hello\nworl" );
+  editor.SetProperty( TextEditor::Property::POINT_SIZE, 10.f );
+  editor.SetSize( 100.f, 50.f );
+  editor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  editor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+
+  // Avoid a crash when core load gl resources.
+  application.GetGlAbstraction().SetCheckFramebufferStatusResult( GL_FRAMEBUFFER_COMPLETE );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Tap on the text editor
+  application.ProcessEvent( GenerateTap( Gesture::Possible, 1u, 1u, Vector2( 3.f, 25.0f ) ) );
+  application.ProcessEvent( GenerateTap( Gesture::Started, 1u, 1u, Vector2( 3.f, 25.0f ) ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Move at the end of the text.
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_DOWN, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_DOWN, 0, 0, Integration::KeyEvent::Down ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  for( unsigned int index = 0u; index < 10u; ++index )
+  {
+    application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down ) );
+    application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_RIGHT, 0, 0, Integration::KeyEvent::Down ) );
+
+    // Render and notify
+    application.SendNotification();
+    application.Render();
+  }
+
+  // Add a character
+  application.ProcessEvent( GenerateKey( "d", "d", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( "Hello\nworld", editor.GetProperty<std::string>( TextEditor::Property::TEXT ), TEST_LOCATION );
+
+  // Add some key events
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_UP, 0, 0, Integration::KeyEvent::Down ) );
+  application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_UP, 0, 0, Integration::KeyEvent::Down ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  for( unsigned int index = 0u; index < 10u; ++index )
+  {
+    application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down ) );
+    application.ProcessEvent( GenerateKey( "", "", DALI_KEY_CURSOR_LEFT, 0, 0, Integration::KeyEvent::Down ) );
+
+    // Render and notify
+    application.SendNotification();
+    application.Render();
+  }
+
+  // Add a character
+  application.ProcessEvent( GenerateKey( " ", " ", 0, 0, 0, Integration::KeyEvent::Down ) );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( " Hello\nworld", editor.GetProperty<std::string>( TextEditor::Property::TEXT ), TEST_LOCATION );
+
+  END_TEST;
+}
index 1045ad4..6f04d64 100644 (file)
@@ -17,6 +17,8 @@
 
 #include <iostream>
 #include <stdlib.h>
+#include <unistd.h>
+
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
 
@@ -63,6 +65,8 @@ const char* const PROPERTY_NAME_EMBOSS = "emboss";
 const char* const PROPERTY_NAME_OUTLINE = "outline";
 
 const int DEFAULT_RENDERING_BACKEND = Dali::Toolkit::Text::DEFAULT_RENDERING_BACKEND;
+const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
+const unsigned int EMOJI_FONT_SIZE = 3968u;
 
 bool DaliTestCheckMaps( const Property::Map& fontStyleMapGet, const Property::Map& fontStyleMapSet )
 {
@@ -471,46 +475,21 @@ int UtcDaliToolkitTextLabelLanguagesP(void)
   application.SendNotification();
   application.Render();
 
-  END_TEST;
-}
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
 
-int UtcDaliToolkitTextLabelVectorBasedP(void)
-{
-  ToolkitTestApplication application;
-  tet_infoline(" UtcDaliToolkitTextLabelVectorBasedP");
+  char* pathNamePtr = get_current_dir_name();
+  const std::string pathName( pathNamePtr );
+  free( pathNamePtr );
 
-  TestGlAbstraction& glAbstraction = application.GetGlAbstraction();
-  glAbstraction.EnableTextureCallTrace( true );
+  fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenColorEmoji.ttf", EMOJI_FONT_SIZE );
 
-  TextLabel label = TextLabel::New();
-  label.SetParentOrigin( ParentOrigin::CENTER );
-  label.SetSize( Stage::GetCurrent().GetSize() );
-  label.SetProperty( TextLabel::Property::TEXT, "Hello World" );
-  label.SetProperty( TextLabel::Property::POINT_SIZE, 10.0f );
-  label.SetProperty( TextLabel::Property::RENDERING_BACKEND, Toolkit::Text::RENDERING_VECTOR_BASED );
-  Stage::GetCurrent().Add( label );
-
-  application.SendNotification();
-  application.Render();
-
-  // Test that the vector data is uploaded to atlas
-  DALI_TEST_CHECK( glAbstraction.GetTextureTrace().FindMethod("TexSubImage2D") );
-  glAbstraction.GetTextureTrace().Reset();
-
-  // Add another label with the same text in a different point-size
-  TextLabel label2 = TextLabel::New();
-  label2.SetProperty( TextLabel::Property::TEXT, "Hello World" );
-  label2.SetProperty( TextLabel::Property::POINT_SIZE, 13.0f );
-  label2.SetProperty( TextLabel::Property::RENDERING_BACKEND, Toolkit::Text::RENDERING_VECTOR_BASED );
-  Stage::GetCurrent().Add( label2 );
+  const std::string emojis = "<font family='TizenColorEmoji'>\xF0\x9F\x98\x81 \xF0\x9F\x98\x82 \xF0\x9F\x98\x83 \xF0\x9F\x98\x84</font>";
+  label.SetProperty( TextLabel::Property::ENABLE_MARKUP, true );
+  label.SetProperty( TextLabel::Property::TEXT, emojis );
 
   application.SendNotification();
   application.Render();
 
-  // Test that no additional vector data was uploaded to atlas
-  // i.e. the same vector data can be used to render any point-size
-  DALI_TEST_CHECK( ! glAbstraction.GetTextureTrace().FindMethod("TexSubImage2D") );
-
   END_TEST;
 }
 
index c0bb0b1..14e8a19 100644 (file)
@@ -24,6 +24,8 @@
 #include <dali/public-api/rendering/shader.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/visual-factory/devel-visual-properties.h>
+#include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
+#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
 #include <dali-toolkit/devel-api/align-enums.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include "dummy-control.h"
@@ -42,6 +44,18 @@ const char* TEST_RESOURCE_LOCATION = TEST_RESOURCE_DIR "/";
 
 const std::string DEFAULT_FONT_DIR( "/resources/fonts" );
 
+Property::Map DefaultTransform()
+{
+  Property::Map transformMap;
+  transformMap
+    .Add( Toolkit::VisualProperty::Transform::Property::OFFSET, Vector2(0.0f, 0.0f) )
+    .Add( Toolkit::VisualProperty::Transform::Property::SIZE, Vector2(1.0f, 1.0f) )
+    .Add( Toolkit::VisualProperty::Transform::Property::ORIGIN, Toolkit::Align::CENTER )
+    .Add( Toolkit::VisualProperty::Transform::Property::ANCHOR_POINT, Toolkit::Align::CENTER )
+    .Add( Toolkit::VisualProperty::Transform::Property::OFFSET_SIZE_MODE, Vector4::ZERO );
+  return transformMap;
+}
+
 bool DaliTestCheckMaps( const Property::Map& fontStyleMapGet, const Property::Map& fontStyleMapSet )
 {
   if( fontStyleMapGet.Count() == fontStyleMapSet.Count() )
@@ -173,24 +187,25 @@ int UtcDaliVisualSize(void)
   tet_infoline( "UtcDaliVisualGetNaturalSize" );
 
   VisualFactory factory = VisualFactory::Get();
-  Vector2 visualSize( 20.f, 30.f );
+  Vector2 controlSize( 20.f, 30.f );
   Vector2 naturalSize;
 
   // color colorVisual
   Dali::Property::Map map;
   map[ Visual::Property::TYPE ] = Visual::COLOR;
   map[ ColorVisual::Property::MIX_COLOR ] = Color::MAGENTA;
+
   Visual::Base colorVisual = factory.CreateVisual( map );
-  colorVisual.SetSize( visualSize );
-  DALI_TEST_EQUALS( colorVisual.GetSize(), visualSize, TEST_LOCATION );
+  colorVisual.SetTransformAndSize(DefaultTransform(), controlSize );
+
   colorVisual.GetNaturalSize(naturalSize);
   DALI_TEST_EQUALS( naturalSize, Vector2::ZERO, TEST_LOCATION );
 
   // image visual
   Image image = ResourceImage::New(TEST_IMAGE_FILE_NAME, ImageDimensions(100, 200));
   Visual::Base imageVisual = factory.CreateVisual( image );
-  imageVisual.SetSize( visualSize );
-  DALI_TEST_EQUALS( imageVisual.GetSize(), visualSize, TEST_LOCATION );
+  imageVisual.SetTransformAndSize(DefaultTransform(), controlSize );
+
   imageVisual.GetNaturalSize(naturalSize);
   DALI_TEST_EQUALS( naturalSize, Vector2(100.f, 200.f), TEST_LOCATION );
 
@@ -203,8 +218,7 @@ int UtcDaliVisualSize(void)
   map[ BorderVisual::Property::COLOR  ] = Color::RED;
   map[ BorderVisual::Property::SIZE   ] = borderSize;
   Visual::Base borderVisual = factory.CreateVisual( map );
-  borderVisual.SetSize( visualSize );
-  DALI_TEST_EQUALS( borderVisual.GetSize(), visualSize, TEST_LOCATION );
+  borderVisual.SetTransformAndSize(DefaultTransform(), controlSize );
   borderVisual.GetNaturalSize(naturalSize);
   DALI_TEST_EQUALS( naturalSize, Vector2::ZERO, TEST_LOCATION );
 
@@ -221,15 +235,13 @@ int UtcDaliVisualSize(void)
   stopColors.PushBack( Color::GREEN );
   propertyMap.Insert(GradientVisual::Property::STOP_COLOR,   stopColors);
   Visual::Base gradientVisual = factory.CreateVisual(propertyMap);
-  gradientVisual.SetSize( visualSize );
-  DALI_TEST_EQUALS( gradientVisual.GetSize(), visualSize, TEST_LOCATION );
+  gradientVisual.SetTransformAndSize(DefaultTransform(), controlSize );
   gradientVisual.GetNaturalSize(naturalSize);
   DALI_TEST_EQUALS( naturalSize, Vector2::ZERO,TEST_LOCATION );
 
   // svg visual
   Visual::Base svgVisual = factory.CreateVisual( TEST_SVG_FILE_NAME, ImageDimensions() );
-  svgVisual.SetSize( visualSize );
-  DALI_TEST_EQUALS( svgVisual.GetSize(), visualSize, TEST_LOCATION );
+  svgVisual.SetTransformAndSize(DefaultTransform(), controlSize );
   svgVisual.GetNaturalSize(naturalSize);
   // TEST_SVG_FILE:
   //  <svg width="100" height="100">
@@ -239,7 +251,6 @@ int UtcDaliVisualSize(void)
 
   // 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
 
@@ -252,8 +263,7 @@ int UtcDaliVisualSize(void)
   propertyMap.Insert( ImageVisual::Property::URL, TEST_IMAGE_FILE_NAME );
   propertyMap.Insert( ImageVisual::Property::BATCHING_ENABLED, true );
   Visual::Base batchImageVisual = factory.CreateVisual( propertyMap );
-  batchImageVisual.SetSize( visualSize );
-  DALI_TEST_EQUALS( batchImageVisual.GetSize(), visualSize, TEST_LOCATION );
+  batchImageVisual.SetTransformAndSize(DefaultTransform(), controlSize );
   batchImageVisual.GetNaturalSize( naturalSize );
   DALI_TEST_EQUALS( naturalSize, Vector2( 80.0f, 160.0f ), TEST_LOCATION );
 
@@ -270,7 +280,7 @@ int UtcDaliVisualSize(void)
   fontClient.GetFontId( pathName + DEFAULT_FONT_DIR + "/tizen/TizenSansRegular.ttf" );
 
   propertyMap.Clear();
-  propertyMap.Insert( Visual::Property::TYPE, Visual::TEXT );
+  propertyMap.Insert( Visual::Property::TYPE, DevelVisual::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 );
@@ -940,7 +950,7 @@ int UtcDaliVisualGetPropertyMap10(void)
   VisualFactory factory = VisualFactory::Get();
 
   Property::Map propertyMap;
-  propertyMap.Insert( Visual::Property::TYPE, Visual::TEXT );
+  propertyMap.Insert( Visual::Property::TYPE, DevelVisual::TEXT );
   propertyMap.Insert( "renderingBackend", static_cast<int>( Toolkit::Text::DEFAULT_RENDERING_BACKEND ) );
   propertyMap.Insert( "text", "Hello world" );
   propertyMap.Insert( "fontFamily", "TizenSans" );
@@ -955,9 +965,6 @@ int UtcDaliVisualGetPropertyMap10(void)
   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;
@@ -966,11 +973,7 @@ int UtcDaliVisualGetPropertyMap10(void)
   //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 );
+  DALI_TEST_EQUALS( value->Get<int>(), (int)DevelVisual::TEXT, TEST_LOCATION );
 
   value = resultMap.Find( TextVisual::Property::TEXT, Property::STRING );
   DALI_TEST_CHECK( value );
@@ -1011,17 +1014,6 @@ int UtcDaliVisualGetPropertyMap10(void)
   DALI_TEST_CHECK( value );
   DALI_TEST_CHECK( !value->Get<bool>() );
 
-  value = resultMap.Find( TextVisual::Property::ENABLE_AUTO_SCROLL, Property::BOOLEAN );
-  DALI_TEST_CHECK( !value );
-
-  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;
 }
 
@@ -1677,3 +1669,44 @@ int UtcDaliVisualRendererRemovalAndReAddition(void)
 
   END_TEST;
 }
+
+
+
+int UtcDaliVisualTextVisualRender(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "UtcDaliVisualTextVisualRender" );
+
+  VisualFactory factory = VisualFactory::Get();
+  Property::Map propertyMap;
+  propertyMap.Insert( Visual::Property::TYPE, DevelVisual::TEXT );
+  propertyMap.Insert( "renderingBackend", static_cast<int>( Toolkit::Text::DEFAULT_RENDERING_BACKEND ) );
+  propertyMap.Insert( "text", "Hello world" );
+  propertyMap.Insert( "fontFamily", "TizenSans" );
+
+  Property::Map fontStyleMapSet;
+  fontStyleMapSet.Insert( "weight", "bold" );
+  propertyMap.Insert( "fontStyle", fontStyleMapSet );
+
+  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 );
+  Visual::Base textVisual = factory.CreateVisual( propertyMap );
+  textVisual.SetDepthIndex( 1.f );
+
+  DummyControl dummyControl = DummyControl::New(true);
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(dummyControl.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, textVisual );
+  DALI_TEST_EQUALS( dummyControl.GetRendererCount(), 0, TEST_LOCATION );
+
+  dummyControl.SetSize(200.f, 200.f);
+
+  Stage::GetCurrent().Add( dummyControl );
+  application.SendNotification();
+  application.Render();
+
+  END_TEST;
+}
index 7d36ae6..ae8761f 100644 (file)
@@ -23,6 +23,8 @@
 #include <dali/public-api/rendering/texture-set.h>
 #include <dali/public-api/rendering/shader.h>
 #include <dali/devel-api/images/nine-patch-image.h>
+#include <dali-toolkit/devel-api/align-enums.h>
+#include <dali-toolkit/devel-api/visual-factory/devel-visual-properties.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/dali-toolkit.h>
 #include "dummy-control.h"
@@ -47,6 +49,18 @@ static const char* gImage_34_RGBA = TEST_RESOURCE_DIR "/icon-edit.png";
 // resolution: 600*600, pixel format: RGB888
 static const char* gImage_600_RGB = TEST_RESOURCE_DIR "/test-image-600.jpg";
 
+Property::Map DefaultTransform()
+{
+  Property::Map transformMap;
+  transformMap
+    .Add( Toolkit::VisualProperty::Transform::Property::OFFSET, Vector2(0.0f, 0.0f) )
+    .Add( Toolkit::VisualProperty::Transform::Property::SIZE, Vector2(1.0f, 1.0f) )
+    .Add( Toolkit::VisualProperty::Transform::Property::ORIGIN, Toolkit::Align::CENTER )
+    .Add( Toolkit::VisualProperty::Transform::Property::ANCHOR_POINT, Toolkit::Align::CENTER )
+    .Add( Toolkit::VisualProperty::Transform::Property::OFFSET_SIZE_MODE, Vector4::ZERO );
+  return transformMap;
+}
+
 Integration::Bitmap* CreateBitmap( unsigned int imageWidth, unsigned int imageHeight, unsigned int initialColor, Pixel::Format pixelFormat )
 {
   Integration::Bitmap* bitmap = Integration::Bitmap::New( Integration::Bitmap::BITMAP_2D_PACKED_PIXELS, ResourcePolicy::OWNED_RETAIN );
@@ -372,7 +386,7 @@ int UtcDaliVisualFactoryGetBorderVisual1(void)
   dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
   actor.SetSize(200.f, 200.f);
   Stage::GetCurrent().Add( actor );
-  visual.SetSize(Vector2(200.f, 200.f));
+  visual.SetTransformAndSize(DefaultTransform(), Vector2(200.f, 200.f));
 
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
   int blendMode = actor.GetRendererAt(0u).GetProperty<int>( Renderer::Property::BLEND_MODE );
@@ -420,7 +434,7 @@ int UtcDaliVisualFactoryGetBorderVisual2(void)
   dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
   actor.SetSize(200.f, 200.f);
   Stage::GetCurrent().Add( actor );
-  visual.SetSize(Vector2(200.f, 200.f));
+  visual.SetTransformAndSize(DefaultTransform(), Vector2(200.f, 200.f));
 
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
 
@@ -971,9 +985,8 @@ int UtcDaliVisualFactoryGetNPatchVisual3(void)
 
   ResourceImage image = ResourceImage::New(TEST_NPATCH_FILE_NAME);
   Visual::Base nPatchVisual = factory.CreateVisual( image );
-  Vector2 visualSize( 20.f, 30.f ), naturalSize(0,0);
-  nPatchVisual.SetSize( visualSize );
-  DALI_TEST_EQUALS( nPatchVisual.GetSize(), visualSize, TEST_LOCATION );
+  Vector2 controlSize( 20.f, 30.f ), naturalSize(0,0);
+  nPatchVisual.SetTransformAndSize(DefaultTransform(), controlSize );
   nPatchVisual.GetNaturalSize( naturalSize );
   DALI_TEST_EQUALS( naturalSize, Vector2( ninePatchImageWidth-2, ninePatchImageHeight-2 ), TEST_LOCATION );
 
@@ -1124,7 +1137,7 @@ int UtcDaliVisualFactoryGetSvgVisual(void)
   dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
   actor.SetSize( 200.f, 200.f );
   Stage::GetCurrent().Add( actor );
-  visual.SetSize( Vector2(200.f, 200.f) );
+  visual.SetTransformAndSize(DefaultTransform(), Vector2(200.f, 200.f) );
 
   application.SendNotification();
   application.Render();
@@ -1132,11 +1145,7 @@ int UtcDaliVisualFactoryGetSvgVisual(void)
   // 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 );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
 
   // renderer is added to actor
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
@@ -1163,8 +1172,9 @@ int UtcDaliVisualFactoryGetSvgVisualLarge(void)
   TraceCallStack& textureTrace = gl.GetTextureTrace();
   textureTrace.Enable(true);
 
-  DummyControl actor = DummyControl::New();
+  DummyControl actor = DummyControl::New(true);
   DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  actor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS ); // Only rasterizes when it knows control size.
   dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
   Stage::GetCurrent().Add( actor );
 
@@ -1174,11 +1184,7 @@ int UtcDaliVisualFactoryGetSvgVisualLarge(void)
   // 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 );
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 1 ), true, TEST_LOCATION );
 
   // renderer is added to actor
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
@@ -1209,7 +1215,7 @@ void MeshVisualLoadsCorrectlyTest( Property::Map& propertyMap, ToolkitTestApplic
   dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
   actor.SetSize( 200.f, 200.f );
   Stage::GetCurrent().Add( actor );
-  visual.SetSize( Vector2( 200.f, 200.f ) );
+  visual.SetTransformAndSize(DefaultTransform(), Vector2( 200.f, 200.f ) );
 
   //Ensure set on stage.
   DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
@@ -1256,7 +1262,7 @@ void MeshVisualDoesNotLoadCorrectlyTest( Property::Map& propertyMap, ToolkitTest
   dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
   actor.SetSize( 200.f, 200.f );
   Stage::GetCurrent().Add( actor );
-  visual.SetSize( Vector2( 200.f, 200.f ) );
+  visual.SetTransformAndSize(DefaultTransform(),  Vector2( 200.f, 200.f ) );
 
   //Ensure set on stage.
   DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
@@ -1538,7 +1544,7 @@ void TestPrimitiveVisualWithProperties( Property::Map& propertyMap, ToolkitTestA
 
   actor.SetSize( 200.f, 200.f );
   Stage::GetCurrent().Add( actor );
-  visual.SetSize( Vector2( 200.f, 200.f ) );
+  visual.SetTransformAndSize(DefaultTransform(),  Vector2( 200.f, 200.f ) );
 
   //Ensure set on stage.
   DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
@@ -1959,7 +1965,7 @@ int UtcDaliVisualFactoryGetBatchImageVisual1(void)
 
   actor.SetSize( 200.0f, 200.0f );
   Stage::GetCurrent().Add( actor );
-  visual.SetSize( Vector2( 200.0f, 200.0f ) );
+  visual.SetTransformAndSize(DefaultTransform(),  Vector2( 200.0f, 200.0f ) );
 
   // Test SetOnStage().
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
@@ -2008,7 +2014,7 @@ int UtcDaliVisualFactoryGetBatchImageVisual2(void)
 
   actor.SetSize( 200.0f, 200.0f );
   Stage::GetCurrent().Add( actor );
-  visual.SetSize( Vector2( 200.0f, 200.0f ) );
+  visual.SetTransformAndSize(DefaultTransform(),  Vector2( 200.0f, 200.0f ) );
 
   // Test SetOnStage().
   DALI_TEST_CHECK( actor.GetRendererCount() == 1u );
index 166feb4..38f4c89 100644 (file)
@@ -118,6 +118,7 @@ develapitransitioneffectsdir =  $(develapidir)/transition-effects
 develapitoolbardir =            $(develapicontrolsdir)/tool-bar
 develapitextselectionpopupdir = $(develapicontrolsdir)/text-controls
 develapivisualfactorydir =      $(develapidir)/visual-factory
+develapivisualsdir =            $(develapidir)/visuals
 
 # devel headers
 develapi_HEADERS =                  $(devel_api_header_files)
@@ -135,6 +136,7 @@ develapipageturnview_HEADERS =      $(devel_api_page_turn_view_header_files)
 develapipopup_HEADERS =             $(devel_api_popup_header_files)
 develapiprogressbar_HEADERS =       $(devel_api_progress_bar_header_files)
 develapivisualfactory_HEADERS =     $(devel_api_visual_factory_header_files)
+develapivisuals_HEADERS =           $(devel_api_visuals_header_files)
 develapiscripting_HEADERS =         $(devel_api_scripting_header_files)
 develapishadowview_HEADERS =        $(devel_api_shadow_view_header_files)
 develapishadereffects_HEADERS =     $(devel_api_shader_effects_header_files)
index b4c92ce..fce6213 100644 (file)
@@ -351,28 +351,55 @@ ALIASES += clip{3}="\dontinclude \1 \n \skip \2 \n \until \3"
 # For Open Source DALi API Reference
 ALIASES += SINCE_1_0="@since 1.0"
 ALIASES += SINCE_1_1="@since 1.1"
+ALIASES += SINCE_1_2="@since 1.2"
+
+# Extra tags for Tizen 3.0
+ALIASES += SINCE_1_2_2="@since 1.2.2"
+ALIASES += SINCE_1_2_4="@since 1.2.4"
+ALIASES += SINCE_1_2_5="@since 1.2.5"
+ALIASES += SINCE_1_2_10="@since 1.2.10"
+ALIASES += SINCE_1_2_14="@since 1.2.14"
 
 ALIASES += DEPRECATED_1_0="@deprecated Deprecated since 1.0"
 ALIASES += DEPRECATED_1_1="@deprecated Deprecated since 1.1"
+ALIASES += DEPRECATED_1_2_10="@deprecated Deprecated since 1.2.10"
+ALIASES += DEPRECATED_1_2="@deprecated Deprecated since 1.2"
 
 ALIASES += PLATFORM=""
 ALIASES += PRIVLEVEL_PLATFORM=""
+ALIASES += PRIVLEVEL_PUBLIC=""
 ALIASES += PRIVILEGE_KEYGRAB=""
+ALIASES += PRIVILEGE_DISPLAY=""
+ALIASES += REMARK_INTERNET=""
+ALIASES += REMARK_STORAGE=""
 
 ############################################
 ## For Tizen Native API Reference
 #ALIASES += SINCE_1_0="\par Since:\n 2.4, DALi version 1.0"
 #ALIASES += SINCE_1_1="\par Since:\n 3.0, DALi version 1.1"
+#ALIASES += SINCE_1_2="\par Since:\n 4.0, DALi version 1.2"
+
+## Extra tags for Tizen 3.0
+#ALIASES += SINCE_1_2_2="\par Since:\n 3.0, DALi version 1.2.2"
+#ALIASES += SINCE_1_2_4="\par Since:\n 3.0, DALi version 1.2.4"
+#ALIASES += SINCE_1_2_5="\par Since:\n 3.0, DALi version 1.2.5"
+#ALIASES += SINCE_1_2_10="\par Since:\n 3.0, DALi version 1.2.10"
+#ALIASES += SINCE_1_2_14="\par Since:\n 3.0, DALi version 1.2.14"
 
 ## DALi has no deprecated API in Tizen 2.4 because it's DALi's first release.
 ## Thus deprecated APIs in DALi 1.0.xx will be deprecated in Tizen 3.0.
 #ALIASES += DEPRECATED_1_0="@deprecated Deprecated since 3.0, DALi version 1.0"
 #ALIASES += DEPRECATED_1_1="@deprecated Deprecated since 3.0, DALi version 1.1"
+#ALIASES += DEPRECATED_1_2_10="@deprecated Deprecated since 3.0, DALi version 1.2.10"
+#ALIASES += DEPRECATED_1_2="@deprecated Deprecated since 4.0, DALi version 1.2"
 
 #ALIASES += PLATFORM="@platform"
 #ALIASES += PRIVLEVEL_PLATFORM="\par Privilege Level:\n platform"
+#ALIASES += PRIVLEVEL_PUBLIC="\par Privilege Level:\n public"
 #ALIASES += PRIVILEGE_KEYGRAB="\par Privilege:\n http://tizen.org/privilege/keygrab"
-
+#ALIASES += PRIVILEGE_DISPLAY="\par Privilege:\n http://tizen.org/privilege/display"
+#ALIASES += REMARK_INTERNET="@remarks %http://tizen.org/privilege/internet is needed if @a url is a http or https address."
+#ALIASES += REMARK_STORAGE="@remarks %http://tizen.org/privilege/mediastorage is needed if @a url is relevant to media storage. @remarks %http://tizen.org/privilege/externalstorage is needed if @a url is relevant to external storage."
 
 # This tag can be used to specify a number of word-keyword mappings (TCL only).
 # A mapping has the form "name=value". For example adding "class=itcl::class"
index 6007065..69e8acb 100644 (file)
@@ -364,6 +364,7 @@ ALIASES += PRIVLEVEL_PUBLIC=""
 ALIASES += PRIVILEGE_KEYGRAB=""
 ALIASES += PRIVILEGE_DISPLAY=""
 ALIASES += REMARK_INTERNET=""
+ALIASES += REMARK_STORAGE=""
 
 ############################################
 ## For Tizen Native API Reference
@@ -391,7 +392,7 @@ ALIASES += REMARK_INTERNET=""
 #ALIASES += PRIVILEGE_KEYGRAB="\par Privilege:\n http://tizen.org/privilege/keygrab"
 #ALIASES += PRIVILEGE_DISPLAY="\par Privilege:\n http://tizen.org/privilege/display"
 #ALIASES += REMARK_INTERNET="@remarks %http://tizen.org/privilege/internet is needed if @a url is a http or https address."
-
+#ALIASES += REMARK_STORAGE="@remarks %http://tizen.org/privilege/mediastorage is needed if @a url is relevant to media storage. @remarks %http://tizen.org/privilege/externalstorage is needed if @a url is relevant to external storage."
 
 # This tag can be used to specify a number of word-keyword mappings (TCL only).
 # A mapping has the form "name=value". For example adding "class=itcl::class"
index 8aa499a..0e32717 100755 (executable)
@@ -18,13 +18,14 @@ BUILT_SOURCES = \
           $(dali_swig_dir)/automatic/cpp/dali_wrap.cpp \
           $(dali_swig_dir)/automatic/cpp/dali_wrap.h \
           $(dali_swig_dir)/manual/cpp/keyboard_focus_manager_wrap.cpp \
-          $(dali_swig_dir)/manual/cpp/view-wrapper-impl-wrap.cpp
+          $(dali_swig_dir)/manual/cpp/view-wrapper-impl-wrap.cpp \
+          $(dali_swig_dir)/manual/cpp/callbackbase_wrap.cpp
 
 all-local:
 gbs-local: libNDalic.so NDali.dll
 
-libNDalic.so: $(dali_swig_dir)/automatic/cpp/dali_wrap.o $(dali_swig_dir)/manual/cpp/keyboard_focus_manager_wrap.o $(dali_swig_dir)/manual/cpp/view-wrapper-impl-wrap.o
-       $(CXX) -shared $(dali_swig_dir)/automatic/cpp/dali_wrap.o $(dali_swig_dir)/manual/cpp/keyboard_focus_manager_wrap.o $(dali_swig_dir)/manual/cpp/view-wrapper-impl-wrap.o -o $(dali_swig_dir)/libNDalic.so $(DALICORE_LIBS) $(DALIADAPTOR_LIBS) $(DALITOOLKIT_LIBS)
+libNDalic.so: $(dali_swig_dir)/automatic/cpp/dali_wrap.o $(dali_swig_dir)/manual/cpp/keyboard_focus_manager_wrap.o $(dali_swig_dir)/manual/cpp/view-wrapper-impl-wrap.o $(dali_swig_dir)/manual/cpp/callbackbase_wrap.o
+       $(CXX) -shared $(dali_swig_dir)/automatic/cpp/dali_wrap.o $(dali_swig_dir)/manual/cpp/keyboard_focus_manager_wrap.o $(dali_swig_dir)/manual/cpp/view-wrapper-impl-wrap.o $(dali_swig_dir)/manual/cpp/callbackbase_wrap.o -o $(dali_swig_dir)/libNDalic.so $(DALICORE_LIBS) $(DALIADAPTOR_LIBS) $(DALITOOLKIT_LIBS)
 
 $(dali_swig_dir)/automatic/cpp/dali_wrap.o: $(BUILT_SOURCES)
        $(CXX) -c -fpic $(CXXFLAGS) $(DALICORE_CFLAGS) $(DALIADAPTOR_CFLAGS) $(DALITOOLKIT_CFLAGS) $(dali_swig_dir)/automatic/cpp/dali_wrap.cpp -o $(dali_swig_dir)/automatic/cpp/dali_wrap.o
@@ -35,6 +36,9 @@ $(dali_swig_dir)/manual/cpp/keyboard_focus_manager_wrap.o: $(BUILT_SOURCES)
 $(dali_swig_dir)/manual/cpp/view-wrapper-impl-wrap.o: $(BUILT_SOURCES)
        $(CXX) -c -fpic $(CXXFLAGS) $(DALICORE_CFLAGS) $(DALIADAPTOR_CFLAGS) $(DALITOOLKIT_CFLAGS) $(dali_swig_dir)/manual/cpp/view-wrapper-impl-wrap.cpp -o $(dali_swig_dir)/manual/cpp/view-wrapper-impl-wrap.o
 
+$(dali_swig_dir)/manual/cpp/callbackbase_wrap.cpp.o: $(BUILT_SOURCES)
+       $(CXX) -c -fpic $(CXXFLAGS) $(DALICORE_CFLAGS) $(DALIADAPTOR_CFLAGS) $(DALITOOLKIT_CFLAGS) $(dali_swig_dir)/manual/cpp/callbackbase_wrap.cpp -o $(dali_swig_dir)/manual/cpp/callbackbase_wrap.o
+
 NDali.dll: $(BUILT_SOURCES)
 #      mcs -nologo -target:library -out:$(dali_swig_dir)/NDali.dll $(dali_swig_dir)/automatic/csharp/*.cs $(dali_swig_dir)/manual/csharp/*.cs
 
index ba7e85b..c155cc2 100644 (file)
@@ -64,7 +64,6 @@
 #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 a0cd28a..26846a0 100755 (executable)
@@ -84,6 +84,10 @@ devel_api_visual_factory_header_files = \
   $(devel_api_src_dir)/visual-factory/visual-factory.h \
   $(devel_api_src_dir)/visual-factory/visual-base.h
 
+devel_api_visuals_header_files = \
+  $(devel_api_src_dir)/visuals/text-visual-properties.h \
+  $(devel_api_src_dir)/visuals/visual-properties-devel.h
+
 devel_api_shadow_view_header_files = \
   $(devel_api_src_dir)/controls/shadow-view/shadow-view.h
 
index c5b822d..790a3e7 100644 (file)
@@ -61,14 +61,9 @@ const std::string& Visual::Base::GetName()
   return GetImplementation( *this ).GetName();
 }
 
-void Visual::Base::SetSize( const Vector2& size )
+void Visual::Base::SetTransformAndSize( const Property::Map& transform, Size controlSize )
 {
-  GetImplementation( *this ).SetSize( size );
-}
-
-const Vector2& Visual::Base::GetSize() const
-{
-  return GetImplementation( *this ).GetSize();
+  GetImplementation( *this ).SetTransformAndSize( transform, controlSize );
 }
 
 float Visual::Base::GetHeightForWidth( float width ) const
index 7cfadbf..8b0f576 100644 (file)
@@ -128,18 +128,12 @@ public:
   const std::string& GetName();
 
   /**
-   * @brief Set the size of the painting area.
+   * @brief Sets the transform and the control size
    *
-   * @param[in] size The size of the painting area.
+   * @param[in] transform A property map describing the transform
+   * @param[in] controlSize The size of the parent control for visuals that need to scale internally.
    */
-  void SetSize( const Vector2& size );
-
-  /**
-   * @brief Get the size of the painting area.
-   *
-   * @return The size of the visual's painting area.
-   */
-  const Vector2& GetSize() const;
+  void SetTransformAndSize( const Dali::Property::Map& transform, Size controlSize );
 
   /**
    * @brief Returns the height for a given width.
@@ -153,7 +147,11 @@ public:
   /**
    * @brief Return the natural size of the visual.
    *
-   * Deriving classes stipulate the natural size and by default a visual has a ZERO natural size.
+   * Deriving classes stipulate the natural size and by default a
+   * visual has a ZERO natural size.
+   *
+   * @note A visual may not actually have a natural size until it has
+   * been placed on stage and acquired all it's resources.
    *
    * @param[out] naturalSize The visual's natural size
    */
diff --git a/dali-toolkit/devel-api/visuals/text-visual-properties.h b/dali-toolkit/devel-api/visuals/text-visual-properties.h
new file mode 100644 (file)
index 0000000..dfb91ec
--- /dev/null
@@ -0,0 +1,101 @@
+#ifndef DALI_TOOLKIT_TEXT_VISUAL_PROPERTIES_H
+#define DALI_TOOLKIT_TEXT_VISUAL_PROPERTIES_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/public-api/toolkit-property-index-ranges.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace TextVisual
+{
+
+namespace Property
+{
+
+enum
+{
+  /**
+   * @brief The text to display in UTF-8 format,
+   * @details name "text", type STRING
+   */
+  TEXT = VISUAL_PROPERTY_START_INDEX,
+
+  /**
+   * @brief The requested font family to use,
+   * @details name "fontFamily", type STRING
+   */
+  FONT_FAMILY,
+
+  /**
+   * @brief The requested font style to use,
+   * @details name "fontStyle", type MAP
+   */
+  FONT_STYLE,
+
+  /**
+   * @brief The size of font in points
+   * @details name "pointSize", type FLOAT
+   */
+  POINT_SIZE,
+
+  /**
+   * @brief The single-line or multi-line layout option
+   * @details name "multiLine", type BOOLEAN, default false
+   */
+  MULTI_LINE,
+
+  /**
+   * @brief The line horizontal alignment
+   * @details name "horizontalAlignment", type STRING,  values "BEGIN", "CENTER", "END", default BEGIN
+   */
+  HORIZONTAL_ALIGNMENT,
+
+  /**
+   * @brief The line vertical alignment
+   * @details name "verticalAlignment", type STRING,  values "TOP",   "CENTER", "BOTTOM", default TOP
+   */
+  VERTICAL_ALIGNMENT,
+
+  /**
+   * @brief The color of the text
+   * @details name "textColor", type VECTOR4
+   */
+  TEXT_COLOR,
+
+  /**
+   * @brief  Whether the mark-up processing is enabled
+   * @details name "enableMarkup", type BOOLEAN
+   */
+  ENABLE_MARKUP,
+};
+
+} // namespace Property
+
+} // namespace TextVisual
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_VISUAL_PROPERTIES_H
diff --git a/dali-toolkit/devel-api/visuals/visual-properties-devel.h b/dali-toolkit/devel-api/visuals/visual-properties-devel.h
new file mode 100644 (file)
index 0000000..08f5c3a
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef DALI_TOOLKIT_VISUAL_PROPERTIES_DEVEL_H
+#define DALI_TOOLKIT_VISUAL_PROPERTIES_DEVEL_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/public-api/visuals/visual-properties.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace DevelVisual
+{
+
+/**
+ * @brief All the visual types.
+ */
+enum Type
+{
+  BORDER = Dali::Toolkit::Visual::BORDER,
+  COLOR = Dali::Toolkit::Visual::COLOR,
+  GRADIENT = Dali::Toolkit::Visual::GRADIENT,
+  IMAGE = Dali::Toolkit::Visual::IMAGE,
+  MESH = Dali::Toolkit::Visual::MESH,
+  PRIMITIVE = Dali::Toolkit::Visual::PRIMITIVE,
+  WIREFRAME = Dali::Toolkit::Visual::WIREFRAME,
+  TEXT = Dali::Toolkit::Visual::WIREFRAME + 1, ///< Renders text.
+};
+
+} // namespace DevelVisual
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_VISUAL_PROPERTIES_DEVEL_H
index 3c19992..f19f390 100644 (file)
@@ -15,6 +15,7 @@
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
 #include <dali-toolkit/internal/visuals/visual-base-impl.h>
+#include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
 
 namespace Dali
 {
@@ -42,6 +43,19 @@ DALI_PROPERTY_REGISTRATION( Toolkit, ImageView, "preMultipliedAlpha", BOOLEAN, P
 DALI_ANIMATABLE_PROPERTY_REGISTRATION_WITH_DEFAULT( Toolkit, ImageView, "pixelArea", Vector4(0.f, 0.f, 1.f, 1.f), PIXEL_AREA )
 DALI_TYPE_REGISTRATION_END()
 
+
+void SetDefaultTransformMap( Property::Map& transformMap )
+{
+  transformMap.Clear();
+  transformMap
+    .Add( Toolkit::Visual::DevelProperty::Transform::Property::OFFSET, Vector2(0.0f, 0.0f) )
+    .Add( Toolkit::Visual::DevelProperty::Transform::Property::SIZE, Vector2(1.0f, 1.0f) )
+    .Add( Toolkit::Visual::DevelProperty::Transform::Property::ORIGIN, Toolkit::Align::CENTER )
+    .Add( Toolkit::Visual::DevelProperty::Transform::Property::ANCHOR_POINT, Toolkit::Align::CENTER )
+    .Add( Toolkit::Visual::DevelProperty::Transform::Property::OFFSET_SIZE_MODE, Vector4::ZERO );
+
+}
+
 } // anonymous namespace
 
 using namespace Dali;
@@ -138,9 +152,13 @@ void ImageView::SetImage( const std::string& url, ImageDimensions size )
     }
 
     mVisual =  Toolkit::VisualFactory::Get().CreateVisual( url, size );
-    RegisterVisual( Toolkit::ImageView::Property::IMAGE, mVisual  );
+    RegisterVisual( Toolkit::ImageView::Property::IMAGE, mVisual );
 
-    mVisual.SetSize( mSizeSet );
+    // This transform fills the control
+    // Should provide a transform that handles aspect ratio according to image size
+    Property::Map transformMap;
+    SetDefaultTransformMap( transformMap );
+    mVisual.SetTransformAndSize( transformMap, mSizeSet );
 
     RelayoutRequest();
   }
@@ -239,7 +257,12 @@ void ImageView::OnSizeSet( const Vector3& targetSize )
   if( mVisual )
   {
     Vector2 size( targetSize );
-    mVisual.SetSize( size );
+
+    // This transform fills the control
+    // Should provide a transform that handles aspect ratio according to image size
+    Property::Map transformMap;
+    SetDefaultTransformMap( transformMap );
+    mVisual.SetTransformAndSize( transformMap, size );
   }
 }
 
index 299ef5d..81696b7 100644 (file)
@@ -65,9 +65,9 @@ namespace
 
 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    },
+  { "BEGIN",  Toolkit::Text::Layout::HORIZONTAL_ALIGN_BEGIN  },
+  { "CENTER", Toolkit::Text::Layout::HORIZONTAL_ALIGN_CENTER },
+  { "END",    Toolkit::Text::Layout::HORIZONTAL_ALIGN_END    },
 };
 const unsigned int HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE ) / sizeof( HORIZONTAL_ALIGNMENT_STRING_TABLE[0] );
 
@@ -173,7 +173,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         if( impl.mController )
         {
-          const std::string text = value.Get< std::string >();
+          const std::string& text = value.Get< std::string >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p TEXT %s\n", impl.mController.Get(), text.c_str() );
 
           impl.mController->SetText( text );
@@ -184,12 +184,12 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         if( impl.mController )
         {
-          const Vector4 textColor = value.Get< Vector4 >();
+          const Vector4& textColor = value.Get< Vector4 >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
 
-          if( impl.mController->GetTextColor() != textColor )
+          if( impl.mController->GetDefaultColor() != textColor )
           {
-            impl.mController->SetTextColor( textColor );
+            impl.mController->SetDefaultColor( textColor );
             impl.mController->SetInputColor( textColor );
             impl.mRenderer.Reset();
           }
@@ -200,7 +200,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         if( impl.mController )
         {
-          const std::string fontFamily = value.Get< std::string >();
+          const std::string& fontFamily = value.Get< std::string >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
           impl.mController->SetDefaultFontFamily( fontFamily );
         }
@@ -229,14 +229,14 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         if( impl.mController )
         {
-          const std::string alignStr = value.Get< std::string >();
+          const std::string& alignStr = value.Get< std::string >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p HORIZONTAL_ALIGNMENT %s\n", impl.mController.Get(), alignStr.c_str() );
 
-          LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
-          if( Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
-                                                                              HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                              HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
-                                                                              alignment ) )
+          Layout::HorizontalAlignment alignment( Layout::HORIZONTAL_ALIGN_BEGIN );
+          if( Scripting::GetEnumeration< Layout::HorizontalAlignment >( alignStr.c_str(),
+                                                                        HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                        HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                        alignment ) )
           {
             impl.mController->SetHorizontalAlignment( alignment );
           }
@@ -269,7 +269,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         if( impl.mDecorator )
         {
-          const Vector4 color = value.Get< Vector4 >();
+          const Vector4& color = value.Get< Vector4 >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
           impl.mDecorator->SetCursorColor( PRIMARY_CURSOR, color );
@@ -281,7 +281,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         if( impl.mDecorator )
         {
-          const Vector4 color = value.Get< Vector4 >();
+          const Vector4& color = value.Get< Vector4 >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
           impl.mDecorator->SetCursorColor( SECONDARY_CURSOR, color );
@@ -441,7 +441,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         if( impl.mDecorator )
         {
-          const Rect<int> box = value.Get< Rect<int> >();
+          const Rect<int>& box = value.Get< Rect<int> >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height );
 
           impl.mDecorator->SetBoundingBox( box );
@@ -464,7 +464,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         if( impl.mController )
         {
-          const Vector4 inputColor = value.Get< Vector4 >();
+          const Vector4& inputColor = value.Get< Vector4 >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), inputColor.r, inputColor.g, inputColor.b, inputColor.a );
 
           impl.mController->SetInputColor( inputColor );
@@ -475,7 +475,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
       {
         if( impl.mController )
         {
-          const std::string fontFamily = value.Get< std::string >();
+          const std::string& fontFamily = value.Get< std::string >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
           impl.mController->SetInputFontFamily( fontFamily );
         }
@@ -624,7 +624,7 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
       {
         if ( impl.mController )
         {
-          value = impl.mController->GetTextColor();
+          value = impl.mController->GetDefaultColor();
         }
         break;
       }
@@ -653,9 +653,9 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
       {
         if( impl.mController )
         {
-          const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
-                                                                                                                HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+          const char* name = Scripting::GetEnumerationName< Toolkit::Text::Layout::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
+                                                                                                          HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                                          HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
           if( name )
           {
             value = std::string( name );
@@ -938,7 +938,7 @@ void TextEditor::OnInitialize()
   mDecorator = Text::Decorator::New( *mController,
                                      *mController );
 
-  mController->GetLayoutEngine().SetLayout( LayoutEngine::MULTI_LINE_BOX );
+  mController->GetLayoutEngine().SetLayout( Layout::Engine::MULTI_LINE_BOX );
 
   // Enables the text input.
   mController->EnableTextInput( mDecorator );
@@ -1088,7 +1088,7 @@ void TextEditor::RenderText( Text::Controller::UpdateTextType updateTextType )
 
   if( mRenderableActor )
   {
-    const Vector2& scrollOffset = mController->GetScrollPosition();
+    const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition();
 
     mRenderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
 
index 4723b33..e95ac99 100644 (file)
@@ -63,17 +63,17 @@ namespace
 
 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    },
+  { "BEGIN",  Toolkit::Text::Layout::HORIZONTAL_ALIGN_BEGIN  },
+  { "CENTER", Toolkit::Text::Layout::HORIZONTAL_ALIGN_CENTER },
+  { "END",    Toolkit::Text::Layout::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 },
+  { "TOP",    Toolkit::Text::Layout::VERTICAL_ALIGN_TOP    },
+  { "CENTER", Toolkit::Text::Layout::VERTICAL_ALIGN_CENTER },
+  { "BOTTOM", Toolkit::Text::Layout::VERTICAL_ALIGN_BOTTOM },
 };
 const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
 
@@ -199,7 +199,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const std::string text = value.Get< std::string >();
+          const std::string& text = value.Get< std::string >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p TEXT %s\n", impl.mController.Get(), text.c_str() );
 
           impl.mController->SetText( text );
@@ -210,7 +210,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const std::string text = value.Get< std::string >();
+          const std::string& text = value.Get< std::string >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str() );
 
           impl.mController->SetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
@@ -221,7 +221,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const std::string text = value.Get< std::string >();
+          const std::string& text = value.Get< std::string >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_FOCUSED %s\n", impl.mController.Get(), text.c_str() );
 
           impl.mController->SetPlaceholderText( Controller::PLACEHOLDER_TYPE_ACTIVE, text );
@@ -232,7 +232,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const std::string fontFamily = value.Get< std::string >();
+          const std::string& fontFamily = value.Get< std::string >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
           impl.mController->SetDefaultFontFamily( fontFamily );
         }
@@ -277,14 +277,14 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const std::string alignStr = value.Get< std::string >();
+          const std::string& alignStr = value.Get< std::string >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p HORIZONTAL_ALIGNMENT %s\n", impl.mController.Get(), alignStr.c_str() );
 
-          LayoutEngine::HorizontalAlignment alignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN );
-          if( Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
-                                                                              HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                              HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
-                                                                              alignment ) )
+          Layout::HorizontalAlignment alignment( Layout::HORIZONTAL_ALIGN_BEGIN );
+          if( Scripting::GetEnumeration< Layout::HorizontalAlignment >( alignStr.c_str(),
+                                                                        HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                        HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                        alignment ) )
           {
             impl.mController->SetHorizontalAlignment( alignment );
           }
@@ -295,14 +295,14 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const std::string alignStr = value.Get< std::string >();
+          const std::string& alignStr = value.Get< std::string >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p VERTICAL_ALIGNMENT %s\n", impl.mController.Get(), alignStr.c_str() );
 
-          LayoutEngine::VerticalAlignment alignment( LayoutEngine::VERTICAL_ALIGN_BOTTOM );
-          if( Scripting::GetEnumeration< LayoutEngine::VerticalAlignment >( alignStr.c_str(),
-                                                                            VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                                            VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
-                                                                            alignment ) )
+          Layout::VerticalAlignment alignment( Layout::VERTICAL_ALIGN_BOTTOM );
+          if( Scripting::GetEnumeration< Layout::VerticalAlignment >( alignStr.c_str(),
+                                                                      VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                      VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                      alignment ) )
           {
             impl.mController->SetVerticalAlignment( alignment );
           }
@@ -313,12 +313,12 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const Vector4 textColor = value.Get< Vector4 >();
+          const Vector4& textColor = value.Get< Vector4 >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
 
-          if( impl.mController->GetTextColor() != textColor )
+          if( impl.mController->GetDefaultColor() != textColor )
           {
-            impl.mController->SetTextColor( textColor );
+            impl.mController->SetDefaultColor( textColor );
             impl.mController->SetInputColor( textColor );
             impl.mRenderer.Reset();
           }
@@ -329,7 +329,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const Vector4 textColor = value.Get< Vector4 >();
+          const Vector4& textColor = value.Get< Vector4 >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PLACEHOLDER_TEXT_COLOR %f,%f,%f,%f\n", impl.mController.Get(), textColor.r, textColor.g, textColor.b, textColor.a );
 
           if( impl.mController->GetPlaceholderTextColor() != textColor )
@@ -344,7 +344,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const Vector2 shadowOffset = value.Get< Vector2 >();
+          const Vector2& shadowOffset = value.Get< Vector2 >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SHADOW_OFFSET %f,%f\n", impl.mController.Get(), shadowOffset.x, shadowOffset.y );
 
           if ( impl.mController->GetShadowOffset() != shadowOffset )
@@ -359,7 +359,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const Vector4 shadowColor = value.Get< Vector4 >();
+          const Vector4& shadowColor = value.Get< Vector4 >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SHADOW_COLOR %f,%f,%f,%f\n", impl.mController.Get(), shadowColor.r, shadowColor.g, shadowColor.b, shadowColor.a );
 
           if ( impl.mController->GetShadowColor() != shadowColor )
@@ -374,7 +374,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mDecorator )
         {
-          const Vector4 color = value.Get< Vector4 >();
+          const Vector4& color = value.Get< Vector4 >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PRIMARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
           impl.mDecorator->SetCursorColor( PRIMARY_CURSOR, color );
@@ -386,7 +386,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mDecorator )
         {
-          const Vector4 color = value.Get< Vector4 >();
+          const Vector4& color = value.Get< Vector4 >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SECONDARY_CURSOR_COLOR %f,%f,%f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
           impl.mDecorator->SetCursorColor( SECONDARY_CURSOR, color );
@@ -608,7 +608,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const std::string fontFamily = value.Get< std::string >();
+          const std::string& fontFamily = value.Get< std::string >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p INPUT_FONT_FAMILY %s\n", impl.mController.Get(), fontFamily.c_str() );
           impl.mController->SetInputFontFamily( fontFamily );
         }
@@ -791,9 +791,9 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       {
         if( impl.mController )
         {
-          const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
-                                                                                                                HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+          const char* name = Scripting::GetEnumerationName< Toolkit::Text::Layout::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
+                                                                                                          HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                                          HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
           if( name )
           {
             value = std::string( name );
@@ -803,11 +803,11 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       }
       case Toolkit::TextField::Property::VERTICAL_ALIGNMENT:
       {
-        if( impl.mController )
+        if( impl.mController ) 
         {
-          const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetLayoutEngine().GetVerticalAlignment(),
-                                                                                                              VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                                                                              VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+          const char* name = Scripting::GetEnumerationName< Toolkit::Text::Layout::VerticalAlignment >( impl.mController->GetVerticalAlignment(),
+                                                                                                        VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                                        VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
           if( name )
           {
             value = std::string( name );
@@ -819,7 +819,7 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
       {
         if ( impl.mController )
         {
-          value = impl.mController->GetTextColor();
+          value = impl.mController->GetDefaultColor();
         }
         break;
       }
@@ -1123,7 +1123,7 @@ void TextField::OnInitialize()
   mDecorator = Text::Decorator::New( *mController,
                                      *mController );
 
-  mController->GetLayoutEngine().SetLayout( LayoutEngine::SINGLE_LINE_BOX );
+  mController->GetLayoutEngine().SetLayout( Layout::Engine::SINGLE_LINE_BOX );
 
   // Enables the text input.
   mController->EnableTextInput( mDecorator );
@@ -1267,7 +1267,7 @@ void TextField::RenderText( Text::Controller::UpdateTextType updateTextType )
 
   if( mRenderableActor )
   {
-    const Vector2& scrollOffset = mController->GetScrollPosition();
+    const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition();
 
     mRenderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
 
index 094e755..0129388 100644 (file)
@@ -33,7 +33,7 @@
 #include <dali-toolkit/internal/text/text-definitions.h>
 #include <dali-toolkit/internal/styling/style-manager-impl.h>
 
-using Dali::Toolkit::Text::LayoutEngine;
+using namespace Dali::Toolkit::Text;
 
 namespace Dali
 {
@@ -58,17 +58,17 @@ namespace
 
 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    },
+  { "BEGIN",  Toolkit::Text::Layout::HORIZONTAL_ALIGN_BEGIN  },
+  { "CENTER", Toolkit::Text::Layout::HORIZONTAL_ALIGN_CENTER },
+  { "END",    Toolkit::Text::Layout::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 },
+  { "TOP",    Toolkit::Text::Layout::VERTICAL_ALIGN_TOP    },
+  { "CENTER", Toolkit::Text::Layout::VERTICAL_ALIGN_CENTER },
+  { "BOTTOM", Toolkit::Text::Layout::VERTICAL_ALIGN_BOTTOM },
 };
 const unsigned int VERTICAL_ALIGNMENT_STRING_TABLE_COUNT = sizeof( VERTICAL_ALIGNMENT_STRING_TABLE ) / sizeof( VERTICAL_ALIGNMENT_STRING_TABLE[0] );
 
@@ -170,7 +170,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const std::string fontFamily = value.Get< std::string >();
+          const std::string& fontFamily = value.Get< std::string >();
 
           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextLabel::SetProperty Property::FONT_FAMILY newFont(%s)\n", fontFamily.c_str() );
           impl.mController->SetDefaultFontFamily( fontFamily );
@@ -207,11 +207,11 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         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 ) )
+          Layout::HorizontalAlignment alignment( Layout::HORIZONTAL_ALIGN_BEGIN );
+          if( Scripting::GetEnumeration< Toolkit::Text::Layout::HorizontalAlignment >( value.Get< std::string >().c_str(),
+                                                                                       HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                       HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                                       alignment ) )
           {
             impl.mController->SetHorizontalAlignment( alignment );
           }
@@ -222,11 +222,11 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         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 ) )
+          Layout::VerticalAlignment alignment( Layout::VERTICAL_ALIGN_BOTTOM );
+          if( Scripting::GetEnumeration< Toolkit::Text::Layout::VerticalAlignment >( value.Get< std::string >().c_str(),
+                                                                                     VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                     VERTICAL_ALIGNMENT_STRING_TABLE_COUNT,
+                                                                                     alignment ) )
           {
             impl.mController->SetVerticalAlignment( alignment );
           }
@@ -238,10 +238,10 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const Vector4 textColor = value.Get< Vector4 >();
-          if( impl.mController->GetTextColor() != textColor )
+          const Vector4& textColor = value.Get< Vector4 >();
+          if( impl.mController->GetDefaultColor() != textColor )
           {
-            impl.mController->SetTextColor( textColor );
+            impl.mController->SetDefaultColor( textColor );
             impl.mRenderer.Reset();
           }
         }
@@ -252,7 +252,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const Vector2 shadowOffset = value.Get< Vector2 >();
+          const Vector2& shadowOffset = value.Get< Vector2 >();
           if ( impl.mController->GetShadowOffset() != shadowOffset )
           {
             impl.mController->SetShadowOffset( shadowOffset );
@@ -265,7 +265,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const Vector4 shadowColor = value.Get< Vector4 >();
+          const Vector4& shadowColor = value.Get< Vector4 >();
           if ( impl.mController->GetShadowColor() != shadowColor )
           {
             impl.mController->SetShadowColor( shadowColor );
@@ -278,7 +278,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          const Vector4 color = value.Get< Vector4 >();
+          const Vector4& color = value.Get< Vector4 >();
           if ( impl.mController->GetUnderlineColor() != color )
           {
             impl.mController->SetUnderlineColor( color );
@@ -342,7 +342,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
              // If request is enable (true) then start autoscroll as not already running
              else
              {
-               impl.mController->GetLayoutEngine().SetTextEllipsisEnabled( false );
+               impl.mController->SetTextElideEnabled( false );
                impl.mController->SetAutoScrollEnabled( enableAutoScroll );
              }
           }
@@ -485,9 +485,9 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       {
         if( impl.mController )
         {
-          const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
-                                                                                                                HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+          const char* name = Scripting::GetEnumerationName< Toolkit::Text::Layout::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
+                                                                                                          HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                                          HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
           if( name )
           {
             value = std::string( name );
@@ -499,9 +499,9 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       {
         if( impl.mController )
         {
-          const char* name = Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetVerticalAlignment(),
-                                                                                                              VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                                                                              VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+          const char* name = Scripting::GetEnumerationName< Toolkit::Text::Layout::VerticalAlignment >( impl.mController->GetVerticalAlignment(),
+                                                                                                        VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                                        VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
           if( name )
           {
             value = std::string( name );
@@ -513,7 +513,7 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       {
         if ( impl.mController )
         {
-          value = impl.mController->GetTextColor();
+          value = impl.mController->GetDefaultColor();
         }
         break;
       }
@@ -652,9 +652,9 @@ void TextLabel::OnInitialize()
   self.SetResizePolicy( ResizePolicy::DIMENSION_DEPENDENCY, Dimension::HEIGHT );
 
   // Enable the text ellipsis.
-  LayoutEngine& engine = mController->GetLayoutEngine();
+  mController->SetTextElideEnabled( true );   // If false then text larger than control will overflow
 
-  engine.SetTextEllipsisEnabled( true );   // If false then text larger than control will overflow
+  Layout::Engine& engine = mController->GetLayoutEngine();
   engine.SetCursorWidth( 0u ); // Do not layout space for the cursor.
 
   self.OnStageSignal().Connect( this, &TextLabel::OnStageConnect );
@@ -737,7 +737,7 @@ void TextLabel::RenderText()
 
     if( renderableActor )
     {
-      const Vector2& scrollOffset = mController->GetScrollPosition();
+      const Vector2& scrollOffset = mController->GetTextModel()->GetScrollPosition();
       renderableActor.SetPosition( scrollOffset.x, scrollOffset.y );
 
       self.Add( renderableActor );
@@ -800,7 +800,7 @@ void TextLabel::ScrollingFinished()
   // Pure Virtual from TextScroller Interface
   DALI_LOG_INFO( gLogFilter, Debug::General, "TextLabel::ScrollingFinished\n");
   mController->SetAutoScrollEnabled( false );
-  mController->GetLayoutEngine().SetTextEllipsisEnabled( true );
+  mController->SetTextElideEnabled( true );
   RequestTextRelayout();
 }
 
index 1e78bf6..994faaf 100644 (file)
@@ -114,8 +114,8 @@ toolkit_src_files = \
    $(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-model.cpp \
    $(toolkit_src_dir)/text/text-scroller.cpp \
-   $(toolkit_src_dir)/text/text-scroller-interface.cpp \
    $(toolkit_src_dir)/text/text-view.cpp \
    $(toolkit_src_dir)/text/text-view-interface.cpp \
    $(toolkit_src_dir)/text/visual-model-impl.cpp \
@@ -132,6 +132,8 @@ toolkit_src_files = \
    $(toolkit_src_dir)/text/rendering/atlas/atlas-manager-impl.cpp \
    $(toolkit_src_dir)/text/rendering/atlas/atlas-mesh-factory.cpp \
    $(toolkit_src_dir)/text/rendering/text-backend-impl.cpp \
+   $(toolkit_src_dir)/text/rendering/text-typesetter.cpp \
+   $(toolkit_src_dir)/text/rendering/view-model.cpp \
    $(toolkit_src_dir)/transition-effects/cube-transition-effect-impl.cpp \
    $(toolkit_src_dir)/transition-effects/cube-transition-cross-effect-impl.cpp \
    $(toolkit_src_dir)/transition-effects/cube-transition-fold-effect-impl.cpp \
index 3f9a81d..54d8afa 100644 (file)
@@ -707,17 +707,17 @@ bool KeyboardFocusManager::DoConnectSignal( BaseObject* object, ConnectionTracke
   Dali::BaseHandle handle( object );
 
   bool connected( true );
-  KeyboardFocusManager* manager = dynamic_cast<KeyboardFocusManager*>( object );
+  KeyboardFocusManager* manager = static_cast< KeyboardFocusManager* >( object ); // TypeRegistry guarantees that this is the correct type.
 
   if( 0 == strcmp( signalName.c_str(), SIGNAL_PRE_FOCUS_CHANGE ) )
   {
     manager->PreFocusChangeSignal().Connect( tracker, functor );
   }
-  if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUS_CHANGED ) )
+  else if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUS_CHANGED ) )
   {
     manager->FocusChangedSignal().Connect( tracker, functor );
   }
-  if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUS_GROUP_CHANGED ) )
+  else if( 0 == strcmp( signalName.c_str(), SIGNAL_FOCUS_GROUP_CHANGED ) )
   {
     manager->FocusGroupChangedSignal().Connect( tracker, functor );
   }
index 06065b7..1fbef38 100644 (file)
@@ -19,7 +19,6 @@
 #include "async-image-loader-impl.h"
 
 // EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/bitmap-loader.h>
 #include <dali/integration-api/adaptors/adaptor.h>
 
 namespace Dali
@@ -62,9 +61,7 @@ uint32_t AsyncImageLoader::Load( const std::string& url,
     mIsLoadThreadStarted = true;
   }
 
-  BitmapLoader loader = BitmapLoader::New( url, dimensions, fittingMode, samplingMode, orientationCorrection );
-
-  mLoadThread.AddTask( new LoadingTask( ++mLoadTaskId, loader ) );
+  mLoadThread.AddTask( new LoadingTask( ++mLoadTaskId, url, dimensions, fittingMode, samplingMode, orientationCorrection ) );
 
   return mLoadTaskId;
 }
@@ -88,7 +85,7 @@ void AsyncImageLoader::ProcessLoadedImage()
 {
   while( LoadingTask *next =  mLoadThread.NextCompletedTask() )
   {
-    mLoadedSignal.Emit( next->id, next->loader.GetPixelData() );
+    mLoadedSignal.Emit( next->id, next->pixelData );
     delete next;
   }
 }
index 11e251a..d0b504d 100644 (file)
@@ -18,6 +18,9 @@
 // CLASS HEADER
 #include "image-load-thread.h"
 
+// EXTERNAL INCLUDES
+#include <dali/devel-api/adaptor-framework/image-loading.h>
+
 namespace Dali
 {
 
@@ -27,12 +30,24 @@ namespace Toolkit
 namespace Internal
 {
 
-LoadingTask::LoadingTask(uint32_t id, BitmapLoader loader )
-: loader( loader ),
-  id( id )
+LoadingTask::LoadingTask( uint32_t id, const std::string& url, ImageDimensions dimensions,
+                          FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection )
+: pixelData(),
+  url( url ),
+  id( id ),
+  dimensions( dimensions ),
+  fittingMode( fittingMode ),
+  samplingMode( samplingMode ),
+  orientationCorrection( orientationCorrection )
+{
+}
+
+void LoadingTask::Load()
 {
+  pixelData = Dali::LoadImageFromFile( url, dimensions, fittingMode, samplingMode, orientationCorrection );
 }
 
+
 ImageLoadThread::ImageLoadThread( EventThreadCallback* trigger )
 : mTrigger( trigger )
 {
@@ -52,7 +67,7 @@ void ImageLoadThread::Run()
 {
   while( LoadingTask* task = NextTaskToProcess() )
   {
-    task->loader.Load();
+    task->Load();
     AddCompletedTask( task );
   }
 }
@@ -150,8 +165,6 @@ void ImageLoadThread::AddCompletedTask( LoadingTask* task )
   mTrigger->Trigger();
 }
 
-
-
 } // namespace Internal
 
 } // namespace Toolkit
index 85ea419..f46d435 100644 (file)
 // EXTERNAL INCLUDES
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/images/image-operations.h>
+#include <dali/public-api/images/pixel-data.h>
 #include <dali/devel-api/threading/conditional-wait.h>
 #include <dali/devel-api/threading/mutex.h>
 #include <dali/devel-api/threading/thread.h>
-#include <dali/devel-api/adaptor-framework/bitmap-loader.h>
 #include <dali/devel-api/adaptor-framework/event-thread-callback.h>
 
+
 namespace Dali
 {
 
@@ -42,8 +44,20 @@ struct LoadingTask
 {
   /**
    * Constructor.
+   * @param [in] id of the task
+   * @param [in] url The URL of the image file to load.
+   * @param [in] size The width and height to fit the loaded image to, 0.0 means whole image
+   * @param [in] fittingMode The method used to fit the shape of the image before loading to the shape defined by the size parameter.
+   * @param [in] samplingMode The filtering method used when sampling pixels from the input image while fitting it to desired size.
+   * @param [in] orientationCorrection Reorient the image to respect any orientation metadata in its header.
    */
-  LoadingTask( uint32_t id, BitmapLoader loader );
+  LoadingTask( uint32_t id, const std::string& url, ImageDimensions dimensions,
+               FittingMode::Type fittingMode, SamplingMode::Type samplingMode, bool orientationCorrection );
+
+  /**
+   * Load the image
+   */
+  void Load();
 
 private:
 
@@ -55,8 +69,14 @@ private:
 
 public:
 
-  BitmapLoader loader;    ///< The loader used to load the bitmap from URL
-  uint32_t     id;        ///< The id associated with this task.
+  PixelData pixelData;             ///< pixelData handle after successfull load
+  std::string url;                 ///< url of the image to load
+  uint32_t     id;                 ///< The unique id associated with this task.
+  ImageDimensions dimensions;      ///< dimensions to load
+  FittingMode::Type fittingMode;   ///< fitting options
+  SamplingMode::Type samplingMode; ///< sampling options
+  bool orientationCorrection:1;    ///< if orientation correction is needed
+
 };
 
 
@@ -1,3 +1,6 @@
+#ifndef DALI_TOOLKIT_TEXT_LAYOUT_ALIGNMENT_H
+#define DALI_TOOLKIT_TEXT_LAYOUT_ALIGNMENT_H
+
 /*
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
  *
@@ -15,9 +18,6 @@
  *
  */
 
-// CLASS HEADER
-#include <dali-toolkit/internal/text/text-scroller-interface.h>
-
 namespace Dali
 {
 
@@ -27,16 +27,38 @@ namespace Toolkit
 namespace Text
 {
 
-ScrollerInterface::ScrollerInterface()
+namespace Layout
 {
-}
 
-ScrollerInterface::~ScrollerInterface()
+/**
+ * @brief Speficies the horizontal alignment.
+ *
+ * BEGIN is on the left for Left To Right languages whereas is right for Right To Left.
+ * Similarly, END is on the right for Left To Right languages and left for Right To Left.
+ */
+enum HorizontalAlignment
 {
-}
+  HORIZONTAL_ALIGN_BEGIN,
+  HORIZONTAL_ALIGN_CENTER,
+  HORIZONTAL_ALIGN_END
+};
+
+/**
+ * @brief Speficies the vertical alignment.
+ */
+enum VerticalAlignment
+{
+  VERTICAL_ALIGN_TOP,
+  VERTICAL_ALIGN_CENTER,
+  VERTICAL_ALIGN_BOTTOM
+};
+
+} // namespace Layout
 
 } // namespace Text
 
 } // namespace Toolkit
 
 } // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_LAYOUT_ALIGNMENT_H
index 717c752..148ff58 100644 (file)
@@ -38,6 +38,9 @@ namespace Toolkit
 namespace Text
 {
 
+namespace Layout
+{
+
 namespace
 {
 
@@ -99,15 +102,12 @@ struct LineLayout
   float          descender;          ///< The minimum descender of all fonts in the line.
 };
 
-struct LayoutEngine::Impl
+struct Engine::Impl
 {
   Impl()
-  : mLayout( LayoutEngine::SINGLE_LINE_BOX ),
-    mHorizontalAlignment( LayoutEngine::HORIZONTAL_ALIGN_BEGIN ),
-    mVerticalAlignment( LayoutEngine::VERTICAL_ALIGN_TOP ),
+  : mLayout( Layout::Engine::SINGLE_LINE_BOX ),
     mCursorWidth( CURSOR_WIDTH ),
-    mDefaultLineSpacing( LINE_SPACING ),
-    mEllipsisEnabled( false )
+    mDefaultLineSpacing( LINE_SPACING )
   {
   }
 
@@ -187,7 +187,7 @@ struct LayoutEngine::Impl
    * @param[in,out] paragraphDirection in: the current paragraph's direction, out: the next paragraph's direction. Is set after a must break.
    * @param[in] completelyFill Whether to completely fill the line ( even if the last word exceeds the boundaries ).
    */
-  void GetLineLayoutForBox( const LayoutParameters& parameters,
+  void GetLineLayoutForBox( const Parameters& parameters,
                             LineLayout& lineLayout,
                             CharacterDirection& paragraphDirection,
                             bool completelyFill )
@@ -538,7 +538,7 @@ struct LayoutEngine::Impl
    *
    * return Whether the line is ellipsized.
    */
-  bool EllipsisLine( const LayoutParameters& layoutParameters,
+  bool EllipsisLine( const Parameters& layoutParameters,
                      const LineLayout& layout,
                      Size& layoutSize,
                      LineRun* linesBuffer,
@@ -620,7 +620,7 @@ struct LayoutEngine::Impl
    * @param[in,out] numberOfLines The number of laid-out lines.
    * @param[in] isLastLine Whether the laid-out line is the last one.
    */
-  void UpdateTextLayout( const LayoutParameters& layoutParameters,
+  void UpdateTextLayout( const Parameters& layoutParameters,
                          const LineLayout& layout,
                          Size& layoutSize,
                          LineRun* linesBuffer,
@@ -678,7 +678,7 @@ struct LayoutEngine::Impl
    * @param[in,out] linesBuffer Pointer to the line's buffer.
    * @param[in,out] numberOfLines The number of laid-out lines.
    */
-  void UpdateTextLayout( const LayoutParameters& layoutParameters,
+  void UpdateTextLayout( const Parameters& layoutParameters,
                          CharacterIndex characterIndex,
                          GlyphIndex glyphIndex,
                          Size& layoutSize,
@@ -742,7 +742,7 @@ struct LayoutEngine::Impl
    * @param[in] characterOffset The offset to be added to the runs of characters.
    * @param[in] glyphOffset The offset to be added to the runs of glyphs.
    */
-  void UpdateLineIndexOffsets( const LayoutParameters& layoutParameters,
+  void UpdateLineIndexOffsets( const Parameters& layoutParameters,
                                Vector<LineRun>& lines,
                                Length characterOffset,
                                Length glyphOffset )
@@ -763,10 +763,11 @@ struct LayoutEngine::Impl
     }
   }
 
-  bool LayoutText( const LayoutParameters& layoutParameters,
+  bool LayoutText( const Parameters& layoutParameters,
                    Vector<Vector2>& glyphPositions,
                    Vector<LineRun>& lines,
-                   Size& layoutSize )
+                   Size& layoutSize,
+                   bool elideTextEnabled )
   {
     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "-->LayoutText\n" );
     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  box size %f, %f\n", layoutParameters.boundingBox.width, layoutParameters.boundingBox.height );
@@ -890,7 +891,7 @@ struct LayoutEngine::Impl
       DALI_LOG_INFO( gLogFilter, Debug::Verbose, "  pen y %f\n", penY );
 
       bool ellipsis = false;
-      if( mEllipsisEnabled )
+      if( elideTextEnabled )
       {
         // Does the ellipsis of the last line.
         ellipsis = EllipsisLine( layoutParameters,
@@ -1014,7 +1015,7 @@ struct LayoutEngine::Impl
     return true;
   }
 
-  void ReLayoutRightToLeftLines( const LayoutParameters& layoutParameters,
+  void ReLayoutRightToLeftLines( const Parameters& layoutParameters,
                                  CharacterIndex startIndex,
                                  Length numberOfCharacters,
                                  Vector<Vector2>& glyphPositions )
@@ -1076,6 +1077,7 @@ struct LayoutEngine::Impl
   void Align( const Size& size,
               CharacterIndex startIndex,
               Length numberOfCharacters,
+              HorizontalAlignment horizontalAlignment,
               Vector<LineRun>& lines )
   {
     const CharacterIndex lastCharacterPlusOne = startIndex + numberOfCharacters;
@@ -1102,18 +1104,20 @@ struct LayoutEngine::Impl
       // Calculate the line's alignment offset accordingly with the align option,
       // the box width, line length, and the paragraph's direction.
       CalculateHorizontalAlignment( size.width,
+                                    horizontalAlignment,
                                     line );
     }
   }
 
   void CalculateHorizontalAlignment( float boxWidth,
+                                     HorizontalAlignment horizontalAlignment,
                                      LineRun& line )
   {
     line.alignmentOffset = 0.f;
     const bool isRTL = RTL == line.direction;
     float lineLength = line.width;
 
-    HorizontalAlignment alignment = mHorizontalAlignment;
+    HorizontalAlignment alignment = horizontalAlignment;
     if( isRTL )
     {
       // Swap the alignment type if the line is right to left.
@@ -1191,100 +1195,67 @@ struct LayoutEngine::Impl
     line.ellipsis = false;
   }
 
-  LayoutEngine::Layout mLayout;
-  LayoutEngine::HorizontalAlignment mHorizontalAlignment;
-  LayoutEngine::VerticalAlignment mVerticalAlignment;
+  Type mLayout;
   float mCursorWidth;
   float mDefaultLineSpacing;
 
   IntrusivePtr<Metrics> mMetrics;
-
-  bool mEllipsisEnabled:1;
 };
 
-LayoutEngine::LayoutEngine()
+Engine::Engine()
 : mImpl( NULL )
 {
-  mImpl = new LayoutEngine::Impl();
+  mImpl = new Engine::Impl();
 }
 
-LayoutEngine::~LayoutEngine()
+Engine::~Engine()
 {
   delete mImpl;
 }
 
-void LayoutEngine::SetMetrics( MetricsPtr& metrics )
+void Engine::SetMetrics( MetricsPtr& metrics )
 {
   mImpl->mMetrics = metrics;
 }
 
-void LayoutEngine::SetLayout( Layout layout )
+void Engine::SetLayout( Type layout )
 {
   mImpl->mLayout = layout;
 }
 
-LayoutEngine::Layout LayoutEngine::GetLayout() const
+Engine::Type Engine::GetLayout() const
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "GetLayout[%d]\n", mImpl->mLayout);
   return mImpl->mLayout;
 }
 
-void LayoutEngine::SetTextEllipsisEnabled( bool enabled )
-{
-  DALI_LOG_INFO( gLogFilter, Debug::General, "-->LayoutEngine::SetTextEllipsisEnabled[%s]\n", (enabled)?"true":"false" );
-  mImpl->mEllipsisEnabled = enabled;
-}
-
-bool LayoutEngine::GetTextEllipsisEnabled() const
-{
-  return mImpl->mEllipsisEnabled;
-}
-
-void LayoutEngine::SetHorizontalAlignment( HorizontalAlignment alignment )
-{
-  mImpl->mHorizontalAlignment = alignment;
-}
-
-LayoutEngine::HorizontalAlignment LayoutEngine::GetHorizontalAlignment() const
-{
-  return mImpl->mHorizontalAlignment;
-}
-
-void LayoutEngine::SetVerticalAlignment( VerticalAlignment alignment )
-{
-  mImpl->mVerticalAlignment = alignment;
-}
-
-LayoutEngine::VerticalAlignment LayoutEngine::GetVerticalAlignment() const
-{
-  return mImpl->mVerticalAlignment;
-}
-
-void LayoutEngine::SetCursorWidth( int width )
+void Engine::SetCursorWidth( int width )
 {
   mImpl->mCursorWidth = static_cast<float>( width );
 }
 
-int LayoutEngine::GetCursorWidth() const
+int Engine::GetCursorWidth() const
 {
   return static_cast<int>( mImpl->mCursorWidth );
 }
 
-bool LayoutEngine::LayoutText( const LayoutParameters& layoutParameters,
-                               Vector<Vector2>& glyphPositions,
-                               Vector<LineRun>& lines,
-                               Size& layoutSize )
+bool Engine::LayoutText( const Parameters& layoutParameters,
+                         Vector<Vector2>& glyphPositions,
+                         Vector<LineRun>& lines,
+                         Size& layoutSize,
+                         bool elideTextEnabled )
 {
   return mImpl->LayoutText( layoutParameters,
                             glyphPositions,
                             lines,
-                            layoutSize );
+                            layoutSize,
+                            elideTextEnabled );
 }
 
-void LayoutEngine::ReLayoutRightToLeftLines( const LayoutParameters& layoutParameters,
-                                             CharacterIndex startIndex,
-                                             Length numberOfCharacters,
-                                             Vector<Vector2>& glyphPositions )
+void Engine::ReLayoutRightToLeftLines( const Parameters& layoutParameters,
+                                       CharacterIndex startIndex,
+                                       Length numberOfCharacters,
+                                       Vector<Vector2>& glyphPositions )
 {
   mImpl->ReLayoutRightToLeftLines( layoutParameters,
                                    startIndex,
@@ -1292,27 +1263,31 @@ void LayoutEngine::ReLayoutRightToLeftLines( const LayoutParameters& layoutParam
                                    glyphPositions );
 }
 
-void LayoutEngine::Align( const Size& size,
-                          CharacterIndex startIndex,
-                          Length numberOfCharacters,
-                          Vector<LineRun>& lines )
+void Engine::Align( const Size& size,
+                    CharacterIndex startIndex,
+                    Length numberOfCharacters,
+                    Layout::HorizontalAlignment horizontalAlignment,
+                    Vector<LineRun>& lines )
 {
   mImpl->Align( size,
                 startIndex,
                 numberOfCharacters,
+                horizontalAlignment,
                 lines );
 }
 
-void LayoutEngine::SetDefaultLineSpacing( float lineSpacing )
+void Engine::SetDefaultLineSpacing( float lineSpacing )
 {
   mImpl->mDefaultLineSpacing = lineSpacing;
 }
 
-float LayoutEngine::GetDefaultLineSpacing() const
+float Engine::GetDefaultLineSpacing() const
 {
   return mImpl->mDefaultLineSpacing;
 }
 
+} // namespace Layout
+
 } // namespace Text
 
 } // namespace Toolkit
index 79daa23..71768ee 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_TOOLKIT_TEXT_LAYOUT_ENGINE_H__
-#define __DALI_TOOLKIT_TEXT_LAYOUT_ENGINE_H__
+#ifndef DALI_TOOLKIT_TEXT_LAYOUT_ENGINE_H
+#define DALI_TOOLKIT_TEXT_LAYOUT_ENGINE_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.
@@ -23,6 +23,7 @@
 #include <dali/public-api/math/vector2.h>
 
 // INTERNAL INCLUDE
+#include <dali-toolkit/internal/text/layouts/layout-alignment.h>
 #include <dali-toolkit/internal/text/line-run.h>
 #include <dali-toolkit/internal/text/metrics.h>
 
@@ -35,44 +36,33 @@ namespace Toolkit
 namespace Text
 {
 
-struct LayoutParameters;
+namespace Layout
+{
+
+struct Parameters;
 
 /**
  * @brief LayoutEngine is responsible for calculating the visual position of glyphs in layout.
  */
-class LayoutEngine
+class Engine
 {
 public:
 
-  enum Layout
+  enum Type
   {
     SINGLE_LINE_BOX,
     MULTI_LINE_BOX
   };
 
-  enum HorizontalAlignment
-  {
-    HORIZONTAL_ALIGN_BEGIN,
-    HORIZONTAL_ALIGN_CENTER,
-    HORIZONTAL_ALIGN_END
-  };
-
-  enum VerticalAlignment
-  {
-    VERTICAL_ALIGN_TOP,
-    VERTICAL_ALIGN_CENTER,
-    VERTICAL_ALIGN_BOTTOM
-  };
-
   /**
    * @brief Create a new instance of a LayoutEngine.
    */
-  LayoutEngine();
+  Engine();
 
   /**
    * @brief Virtual destructor.
    */
-  ~LayoutEngine();
+  ~Engine();
 
   /**
    * @brief Provide the wrapper around FontClient used to get metrics
@@ -86,54 +76,14 @@ public:
    *
    * @param[in] layout The required layout.
    */
-  void SetLayout( Layout layout );
+  void SetLayout( Type layout );
 
   /**
    * @brief Query the required layout.
    *
    * @return The required layout.
    */
-  Layout GetLayout() const;
-
-  /**
-   * @brief Enable or disable the text ellipsis.
-   *
-   * @param[in] enabled Whether to enable the text ellipsis.
-   */
-  void SetTextEllipsisEnabled( bool enabled );
-
-  /**
-   * @return Whether the text ellipsis is enabled.
-   */
-  bool GetTextEllipsisEnabled() const;
-
-  /**
-   * @brief Choose the required text horizontal alignment.
-   *
-   * @param[in] alignment The required alignment.
-   */
-  void SetHorizontalAlignment( HorizontalAlignment alignment );
-
-  /**
-   * @brief Query the required text horizontal alignment.
-   *
-   * @return The required alignment.
-   */
-  HorizontalAlignment GetHorizontalAlignment() const;
-
-  /**
-   * @brief Choose the required text vertical alignment.
-   *
-   * @param[in] alignment The required alignment.
-   */
-  void SetVerticalAlignment( VerticalAlignment alignment );
-
-  /**
-   * @brief Query the required text vertical alignment.
-   *
-   * @return The required alignment.
-   */
-  VerticalAlignment GetVerticalAlignment() const;
+  Type GetLayout() const;
 
   /**
    * @brief Sets the width of the cursor.
@@ -156,13 +106,15 @@ public:
    * @param[out] glyphPositions The positions of all the glyphs.
    * @param[out] lines The laid-out lines.
    * @param[out] layoutSize The size of the text after it has been laid-out.
+   * @param[in] elideTextEnabled Whether the text elide is enabled.
    *
    * @return \e true if the text has been re-laid-out. \e false means the given width is too small to layout even a single character.
    */
-  bool LayoutText( const LayoutParameters& layoutParameters,
+  bool LayoutText( const Parameters& layoutParameters,
                    Vector<Vector2>& glyphPositions,
                    Vector<LineRun>& lines,
-                   Size& layoutSize );
+                   Size& layoutSize,
+                   bool elideTextEnabled );
 
   /**
    * @brief Re-lays out those lines with right to left characters.
@@ -174,7 +126,7 @@ public:
    * @param[in] numberOfCharacters The number of characters.
    * @param[in,out] glyphPositions The positions of all the glyphs.
    */
-  void ReLayoutRightToLeftLines( const LayoutParameters& layoutParameters,
+  void ReLayoutRightToLeftLines( const Parameters& layoutParameters,
                                  CharacterIndex startIndex,
                                  Length numberOfCharacters,
                                  Vector<Vector2>& glyphPositions );
@@ -185,11 +137,13 @@ public:
    * @param[in] size The size of the container where the text is laid-out.
    * @param[in] startIndex Character index of the line from where the lines are aligned.
    * @param[in] numberOfCharacters The number of characters.
+   * @param[in] horizontalAlignment The horizontal alignment.
    * @param[in,out] lines The laid-out lines.
    */
   void Align( const Size& size,
               CharacterIndex startIndex,
               Length numberOfCharacters,
+              Layout::HorizontalAlignment horizontalAlignment,
               Vector<LineRun>& lines );
 
   /**
@@ -209,20 +163,23 @@ public:
 private:
 
   // Undefined
-  LayoutEngine( const LayoutEngine& handle );
+  Engine( const Engine& handle );
 
   // Undefined
-  LayoutEngine& operator=( const LayoutEngine& handle );
+  Engine& operator=( const Engine& handle );
 
 private:
 
   struct Impl;
   Impl* mImpl;
 };
+
+} // namespace Layout
+
 } // namespace Text
 
 } // namespace Toolkit
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_LAYOUT_ENGINE_H__
+#endif // DALI_TOOLKIT_TEXT_LAYOUT_ENGINE_H
index 8d875bf..f62191f 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef __DALI_TOOLKIT_TEXT_LAYOUT_PARAMETERS_H__
-#define __DALI_TOOLKIT_TEXT_LAYOUT_PARAMETERS_H__
+#ifndef DALI_TOOLKIT_TEXT_LAYOUT_PARAMETERS_H
+#define DALI_TOOLKIT_TEXT_LAYOUT_PARAMETERS_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.
@@ -35,10 +35,13 @@ namespace Text
 
 struct BidirectionalLineInfoRun;
 
+namespace Layout
+{
+
 /**
  * @brief Struct used to pass parameters.
  */
-struct LayoutParameters
+struct Parameters
 {
   /**
    * Constructor with the needed parameters to layout the text.
@@ -54,18 +57,20 @@ struct LayoutParameters
    * @param[in] charactersToGlyphsBuffer Vector with indices pointing the first glyph of each character.
    * @param[in] glyphsPerCharacterBuffer Vector with the number of glyphs shaped from the character.
    * @param[in] totalNumberOfGlyphs The number of glyphs.
+   * @param[in] horizontalAlignment The horizontal alignment.
    */
-  LayoutParameters( const Vector2& boundingBox,
-                    const Character* const textBuffer,
-                    const LineBreakInfo* const lineBreakInfoBuffer,
-                    const WordBreakInfo* const wordBreakInfoBuffer,
-                    const CharacterDirection* const characterDirectionBuffer,
-                    const GlyphInfo* const glyphsBuffer,
-                    const CharacterIndex* const glyphsToCharactersBuffer,
-                    const Length* const charactersPerGlyphBuffer,
-                    const GlyphIndex* const charactersToGlyphsBuffer,
-                    const Length* const glyphsPerCharacterBuffer,
-                    Length totalNumberOfGlyphs )
+  Parameters( const Vector2& boundingBox,
+              const Character* const textBuffer,
+              const LineBreakInfo* const lineBreakInfoBuffer,
+              const WordBreakInfo* const wordBreakInfoBuffer,
+              const CharacterDirection* const characterDirectionBuffer,
+              const GlyphInfo* const glyphsBuffer,
+              const CharacterIndex* const glyphsToCharactersBuffer,
+              const Length* const charactersPerGlyphBuffer,
+              const GlyphIndex* const charactersToGlyphsBuffer,
+              const Length* const glyphsPerCharacterBuffer,
+              Length totalNumberOfGlyphs,
+              HorizontalAlignment horizontalAlignment )
   : boundingBox( boundingBox ),
     textBuffer( textBuffer ),
     lineBreakInfoBuffer( lineBreakInfoBuffer ),
@@ -81,6 +86,7 @@ struct LayoutParameters
     startGlyphIndex( 0u ),
     numberOfGlyphs( 0u ),
     totalNumberOfGlyphs( totalNumberOfGlyphs ),
+    horizontalAlignment( horizontalAlignment ),
     startLineIndex( 0u ),
     estimatedNumberOfLines( 0u ),
     isLastNewParagraph( false )
@@ -101,15 +107,18 @@ struct LayoutParameters
   GlyphIndex                      startGlyphIndex;                 ///< Index to the first glyph to layout.
   Length                          numberOfGlyphs;                  ///< The number of glyphs to layout.
   Length                          totalNumberOfGlyphs;             ///< The number of glyphs.
+  HorizontalAlignment             horizontalAlignment;             ///< The horizontal alignment.
   LineIndex                       startLineIndex;                  ///< The line index where to insert the new lines.
   Length                          estimatedNumberOfLines;          ///< The estimated number of lines.
   bool                            isLastNewParagraph;              ///< Whether the last character is a new paragraph character.
 };
 
+} // namespace Layout
+
 } // namespace Text
 
 } // namespace Toolkit
 
 } // namespace Dali
 
-#endif // __DALI_TOOLKIT_TEXT_LAYOUT_PARAMETERS_H__
+#endif // DALI_TOOLKIT_TEXT_LAYOUT_PARAMETERS_H
index 32e7c38..260bd5a 100644 (file)
@@ -589,10 +589,8 @@ void MultilanguageSupport::ValidateFonts( const Vector<Character>& text,
           if( isValidFont &&
               isEmojiScript )
           {
-            const PixelData bitmap = fontClient.CreateBitmap( fontId, glyphIndex );
-
-            // For color emojis, the font is valid if the bitmap is RGBA.
-            isValidFont = bitmap && ( Pixel::BGRA8888 == bitmap.GetPixelFormat() );
+            // For color emojis, the font is valid if the glyph is a color glyph (the bitmap is RGBA).
+            isValidFont = fontClient.IsColorGlyph( fontId, glyphIndex );
           }
 
           // If there is a valid font, cache it.
diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.cpp b/dali-toolkit/internal/text/rendering/text-typesetter.cpp
new file mode 100644 (file)
index 0000000..62e3b14
--- /dev/null
@@ -0,0 +1,285 @@
+/*
+ * 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/text/rendering/text-typesetter.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/text-abstraction/font-client.h>
+#include <memory.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/rendering/view-model.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+namespace
+{
+
+/**
+ * @brief Data struct used to set the buffer of the glyph's bitmap into the final bitmap's buffer.
+ */
+struct GlyphData
+{
+  uint32_t*                                    bitmapBuffer;     ///< The buffer of the whole bitmap. The format is RGBA8888.
+  Vector2*                                     position;         ///< The position of the glyph.
+  TextAbstraction::FontClient::GlyphBufferData glyphBitmap;      ///< The glyph's bitmap.
+  unsigned int                                 width;            ///< The bitmap's width.
+  unsigned int                                 height;           ///< The bitmap's height.
+  int                                          horizontalOffset; ///< The horizontal offset to be added to the 'x' glyph's position.
+  int                                          verticalOffset;   ///< The vertical offset to be added to the 'y' glyph's position.
+};
+
+/**
+ * @brief Sets the glyph's buffer into the bitmap's buffer.
+ *
+ * @param[in] data Struct which contains the glyph's data and the bitmap's data.
+ * @param[in] position The position of the glyph.
+ * @param[in] color The color of the glyph.
+ */
+void TypesetGlyph( const GlyphData& data,
+                   const Vector2* const position,
+                   const Vector4* const color )
+{
+  if( ( 0u == data.glyphBitmap.width ) || ( 0u == data.glyphBitmap.height ) )
+  {
+    // Nothing to do if the width or height of the buffer is zero.
+    return;
+  }
+
+  const int widthMinusOne = static_cast<int>( data.width - 1u );
+  const int heightMinusOne = static_cast<int>( data.height - 1u );
+
+  // Whether the given glyph is a color one.
+  const bool isColorGlyph = Pixel::BGRA8888 == data.glyphBitmap.format;
+
+  // Pointer to the color glyph if there is one.
+  const uint32_t* const colorGlyphBuffer = isColorGlyph ? reinterpret_cast<uint32_t*>( data.glyphBitmap.buffer ) : NULL;
+
+  // Pack the given color into a 32bit buffer. The alpha channel will be updated later for each pixel.
+  // The format is RGBA8888.
+  uint32_t packedColor = 0u;
+  uint8_t* packedColorBuffer = reinterpret_cast<uint8_t*>( &packedColor );
+  *( packedColorBuffer + 2 ) = static_cast<uint8_t>( color->b * 255.f );
+  *( packedColorBuffer + 1 ) = static_cast<uint8_t>( color->g * 255.f );
+    *packedColorBuffer       = static_cast<uint8_t>( color->r * 255.f );
+
+  // Initial vertical offset.
+  const int yOffset = data.verticalOffset + position->y;
+
+  // Traverse the pixels of the glyph line per line.
+  for( int lineIndex = 0, glyphHeight = static_cast<int>( data.glyphBitmap.height ); lineIndex < glyphHeight; ++lineIndex )
+  {
+    const int yOffsetIndex = yOffset + lineIndex;
+    if( ( 0 > yOffsetIndex ) || ( yOffsetIndex > heightMinusOne ) )
+    {
+      // Do not write out of bounds.
+      break;
+    }
+
+    const int verticalOffset = yOffsetIndex * data.width;
+    const int xOffset = data.horizontalOffset + position->x;
+    const int glyphBufferOffset = lineIndex * static_cast<int>( data.glyphBitmap.width );
+    for( int index = 0, glyphWidth = static_cast<int>( data.glyphBitmap.width ); index < glyphWidth; ++index )
+    {
+      const int xOffsetIndex = xOffset + index;
+      if( ( 0 > xOffsetIndex ) || ( xOffsetIndex > widthMinusOne ) )
+      {
+        // Don't write out of bounds.
+        break;
+      }
+
+      if( isColorGlyph )
+      {
+        // Retrieves the color from the glyph. The format is BGRA8888.
+        uint32_t packedColorGlyph = *( colorGlyphBuffer + glyphBufferOffset + index );
+
+        // Update the alpha channel.
+        uint8_t* packedColorGlyphBuffer = reinterpret_cast<uint8_t*>( &packedColorGlyph );
+        std::swap( *packedColorGlyphBuffer, *( packedColorGlyphBuffer + 2u ) ); // Swap B and R.
+        *( packedColorGlyphBuffer + 3u ) = static_cast<uint8_t>( color->a * static_cast<float>( *( packedColorGlyphBuffer + 3u ) ) );
+
+        // Set the color into the final pixel buffer.
+        *( data.bitmapBuffer + verticalOffset + xOffsetIndex ) = packedColorGlyph;
+      }
+      else
+      {
+        // Update the alpha channel.
+        const uint8_t alpha = *( data.glyphBitmap.buffer + glyphBufferOffset + index );
+        *( packedColorBuffer + 3u ) = static_cast<uint8_t>( color->a * static_cast<float>( alpha ) );
+
+        // Set the color into the final pixel buffer.
+        *( data.bitmapBuffer + verticalOffset + xOffsetIndex ) = packedColor;
+      }
+    }
+  }
+}
+
+} // namespace
+
+TypesetterPtr Typesetter::New( const ModelInterface* const model )
+{
+  return TypesetterPtr( new Typesetter( model ) );
+}
+
+ViewModel* Typesetter::GetViewModel()
+{
+  return mModel;
+}
+
+PixelData Typesetter::Render( const Vector2& size )
+{
+  // @todo. This initial implementation for a TextLabel has only one visible page.
+
+  // Elides the text if needed.
+  mModel->ElideGlyphs();
+
+  // Retrieves the layout size.
+  const Size& layoutSize = mModel->GetLayoutSize();
+
+  // Set the offset for the vertical alignment.
+  int penY = 0u;
+
+  switch( mModel->GetVerticalAlignment() )
+  {
+    case Layout::VERTICAL_ALIGN_TOP:
+    {
+      // No offset to add.
+      break;
+    }
+    case Layout::VERTICAL_ALIGN_CENTER:
+    {
+      penY = static_cast<int>( 0.5f * ( size.height - layoutSize.height ) );
+      break;
+    }
+    case Layout::VERTICAL_ALIGN_BOTTOM:
+    {
+      penY = static_cast<int>( size.height - layoutSize.height );
+      break;
+    }
+  }
+
+  // Retrieve lines, glyphs, positions and colors from the view model.
+  const Length modelNumberOfLines = mModel->GetNumberOfLines();
+  const LineRun* const modelLinesBuffer = mModel->GetLines();
+  const Length numberOfGlyphs = mModel->GetNumberOfGlyphs();
+  const GlyphInfo* const glyphsBuffer = mModel->GetGlyphs();
+  const Vector2* const positionBuffer = mModel->GetLayout();
+  const Vector4* const colorsBuffer = mModel->GetColors();
+  const ColorIndex* const colorIndexBuffer = mModel->GetColorIndices();
+
+  // Whether to use the default color.
+  const bool useDefaultColor = NULL == colorsBuffer;
+  const Vector4& defaultColor = mModel->GetDefaultColor();
+
+  // Create and initialize the pixel buffer.
+  GlyphData glyphData;
+  glyphData.verticalOffset = penY;
+
+  glyphData.width = static_cast<unsigned int>( size.width );
+  glyphData.height = static_cast<unsigned int>( size.height );
+  const unsigned int bufferSizeInt = glyphData.width * glyphData.height;
+  const unsigned int bufferSizeChar = 4u * bufferSizeInt;
+  glyphData.bitmapBuffer = new uint32_t[ bufferSizeInt ]; // This array will get deleted by PixelData because of the DELETE_ARRAY parameter.
+  memset( glyphData.bitmapBuffer, 0u, bufferSizeChar );
+
+  PixelData pixelData = PixelData::New( reinterpret_cast<uint8_t*>( glyphData.bitmapBuffer ),
+                                        bufferSizeChar,
+                                        glyphData.width,
+                                        glyphData.height,
+                                        Pixel::RGBA8888, // The format is RGBA8888 because is the format accepted by the image atlas manager.
+                                        PixelData::DELETE_ARRAY );
+
+  // Get a handle of the font client. Used to retrieve the bitmaps of the glyphs.
+  TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+
+  // Traverses the lines of the text.
+  for( LineIndex lineIndex = 0u; lineIndex < modelNumberOfLines; ++lineIndex )
+  {
+    const LineRun& line = *( modelLinesBuffer + lineIndex );
+
+    // Sets the horizontal offset of the line.
+    glyphData.horizontalOffset = static_cast<int>( line.alignmentOffset );
+
+    // Increases the vertical offset with the line's ascender.
+    glyphData.verticalOffset += static_cast<int>( line.ascender );
+
+    // Traverses the glyphs of the line.
+    const GlyphIndex endGlyphIndex = std::min( numberOfGlyphs, line.glyphRun.glyphIndex + line.glyphRun.numberOfGlyphs );
+    for( GlyphIndex glyphIndex = line.glyphRun.glyphIndex; glyphIndex < endGlyphIndex; ++glyphIndex )
+    {
+      // Retrieve the glyph's info.
+      const GlyphInfo* const glyphInfo = glyphsBuffer + glyphIndex;
+
+      if( ( glyphInfo->width < Math::MACHINE_EPSILON_1000 ) ||
+          ( glyphInfo->height < Math::MACHINE_EPSILON_1000 ) )
+      {
+        // Nothing to do if the glyph's width or height is zero.
+        continue;
+      }
+
+      // Retrieves the glyph's position.
+      const Vector2* const position = positionBuffer + glyphIndex;
+
+      // Retrieves the glyph's color.
+      const ColorIndex colorIndex = *( colorIndexBuffer + glyphIndex );
+      const Vector4* const color = ( useDefaultColor || ( 0u == colorIndex ) ) ? &defaultColor : colorsBuffer + ( colorIndex - 1u );
+
+      // Retrieves the glyph's bitmap.
+      glyphData.glyphBitmap.buffer = NULL;
+      fontClient.CreateBitmap( glyphInfo->fontId,
+                               glyphInfo->index,
+                               glyphData.glyphBitmap );
+
+      // Sets the glyph's bitmap into the bitmap of the whole text.
+      if( NULL != glyphData.glyphBitmap.buffer )
+      {
+        TypesetGlyph( glyphData,
+                      position,
+                      color );
+      }
+    }
+
+    // Increases the vertical offset with the line's descender.
+    glyphData.verticalOffset += static_cast<int>( -line.descender );
+  }
+
+  return pixelData;
+}
+
+Typesetter::Typesetter( const ModelInterface* const model )
+: mModel( new ViewModel( model ) )
+{
+}
+
+Typesetter::~Typesetter()
+{
+  delete mModel;
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/rendering/text-typesetter.h b/dali-toolkit/internal/text/rendering/text-typesetter.h
new file mode 100644 (file)
index 0000000..62d9d94
--- /dev/null
@@ -0,0 +1,114 @@
+#ifndef DALI_TOOLKIT_TEXT_TYPESETTER_H
+#define DALI_TOOLKIT_TEXT_TYPESETTER_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>
+#include <dali/public-api/object/ref-object.h>
+#include <dali/public-api/images/pixel-data.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+class ModelInterface;
+class ViewModel;
+class Typesetter;
+
+typedef IntrusivePtr<Typesetter> TypesetterPtr;
+
+/**
+ * @brief This class is responsible of controlling the data flow of the text's rendering process.
+ */
+class Typesetter : public RefObject
+{
+public: // Constructor.
+  /**
+   * @brief Creates a Typesetter instance.
+   *
+   * The typesetter composes the final text retrieving the glyphs and the
+   * styles from the text's model.
+   *
+   * @param[in] model Pointer to the text's data model.
+   */
+  static TypesetterPtr New( const ModelInterface* const model );
+
+public:
+  /**
+   * @brief Retrieves the pointer to the view model.
+   *
+   * @return A pointer to the view model.
+   */
+  ViewModel* GetViewModel();
+
+  /**
+   * @brief Renders the text.
+   *
+   * Does the following operations:
+   * - Finds the visible pages needed to be rendered.
+   * - Elide glyphs if needed.
+   * - Retrieves the data buffers from the text model.
+   * - Creates the pixel data used to generate the final image with the given size.
+   * - Traverse the visible glyphs, retrieve their bitmaps and compose the final pixel data.
+   *
+   * @param[in] size The renderer size.
+   *
+   * @return A pixel data with the text rendered.
+   */
+  PixelData Render( const Vector2& size );
+
+private:
+  /**
+   * @brief Private constructor.
+   *
+   * @param[in] model Pointer to the text's data model.
+   */
+  Typesetter( const ModelInterface* const model );
+
+  // Declared private and left undefined to avoid copies.
+  Typesetter( const Typesetter& handle );
+
+  // Declared private and left undefined to avoid copies.
+  Typesetter& operator=( const Typesetter& handle );
+
+protected:
+
+  /**
+   * @brief A reference counted object may only be deleted by calling Unreference().
+   *
+   * Destroys the visual model.
+   */
+  virtual ~Typesetter();
+
+private:
+   ViewModel* mModel;
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_TYPESETTER_H
diff --git a/dali-toolkit/internal/text/rendering/view-model.cpp b/dali-toolkit/internal/text/rendering/view-model.cpp
new file mode 100644 (file)
index 0000000..5636506
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * 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/text/rendering/view-model.h>
+
+// EXTERNAL INCLUDES
+#include <memory.h>
+#include <dali/devel-api/text-abstraction/font-client.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/line-run.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+ViewModel::ViewModel( const ModelInterface* const model )
+: mModel( model ),
+  mElidedGlyphs(),
+  mElidedLayout(),
+  mIsTextElided( false )
+{
+}
+
+ViewModel::~ViewModel()
+{
+}
+
+const Size& ViewModel::GetControlSize() const
+{
+  return mModel->GetControlSize();
+}
+
+const Size& ViewModel::GetLayoutSize() const
+{
+  return mModel->GetLayoutSize();
+}
+
+const Vector2& ViewModel::GetScrollPosition() const
+{
+  return mModel->GetScrollPosition();
+}
+
+Layout::HorizontalAlignment ViewModel::GetHorizontalAlignment() const
+{
+  return mModel->GetHorizontalAlignment();
+}
+
+Layout::VerticalAlignment ViewModel::GetVerticalAlignment() const
+{
+  return mModel->GetVerticalAlignment();
+}
+
+bool ViewModel::IsTextElideEnabled() const
+{
+  return mModel->IsTextElideEnabled();
+}
+
+Length ViewModel::GetNumberOfLines() const
+{
+  return mModel->GetNumberOfLines();
+}
+
+const LineRun* const ViewModel::GetLines() const
+{
+  return mModel->GetLines();
+}
+
+Length ViewModel::GetNumberOfGlyphs() const
+{
+  if( mIsTextElided && mModel->IsTextElideEnabled() )
+  {
+     return mElidedGlyphs.Count();
+  }
+  else
+  {
+    return mModel->GetNumberOfGlyphs();
+  }
+
+  return 0u;
+}
+
+const GlyphInfo* const ViewModel::GetGlyphs() const
+{
+  if( mIsTextElided && mModel->IsTextElideEnabled() )
+  {
+    return mElidedGlyphs.Begin();
+  }
+  else
+  {
+    return mModel->GetGlyphs();
+  }
+
+  return NULL;
+}
+
+const Vector2* const ViewModel::GetLayout() const
+{
+  if( mIsTextElided && mModel->IsTextElideEnabled() )
+  {
+    return mElidedLayout.Begin();
+  }
+  else
+  {
+    return mModel->GetLayout();
+  }
+
+  return NULL;
+}
+
+const Vector4* const ViewModel::GetColors() const
+{
+  return mModel->GetColors();
+}
+
+const ColorIndex* const ViewModel::GetColorIndices() const
+{
+  return mModel->GetColorIndices();
+}
+
+const Vector4& ViewModel::GetDefaultColor() const
+{
+  return mModel->GetDefaultColor();
+}
+
+void ViewModel::ElideGlyphs()
+{
+  mIsTextElided = false;
+
+  if( mModel->IsTextElideEnabled() )
+  {
+    const Length numberOfLines = mModel->GetNumberOfLines();
+    if( 0u != numberOfLines )
+    {
+      const LineRun* const lines = mModel->GetLines();
+
+      const LineRun& lastLine = *( lines + ( numberOfLines - 1u ) );
+      const Length numberOfLaidOutGlyphs = lastLine.glyphRun.glyphIndex + lastLine.glyphRun.numberOfGlyphs;
+
+      if( lastLine.ellipsis && ( 0u != numberOfLaidOutGlyphs ) )
+      {
+        mIsTextElided = true;
+        TextAbstraction::FontClient fontClient = TextAbstraction::FontClient::Get();
+
+        const GlyphInfo* const glyphs = mModel->GetGlyphs();
+        const Vector2* const positions = mModel->GetLayout();
+
+        // Copy the glyphs to be elided.
+        mElidedGlyphs.Resize( numberOfLaidOutGlyphs );
+        mElidedLayout.Resize( numberOfLaidOutGlyphs );
+
+        GlyphInfo* elidedGlyphsBuffer = mElidedGlyphs.Begin();
+        Vector2* elidedPositionsBuffer = mElidedLayout.Begin();
+
+        memcpy( elidedGlyphsBuffer, glyphs, numberOfLaidOutGlyphs * sizeof( GlyphInfo ) );
+        memcpy( elidedPositionsBuffer, positions, numberOfLaidOutGlyphs * sizeof( Vector2 ) );
+
+        const Size& controlSize = mModel->GetControlSize();
+
+        if( ( 1u == numberOfLines ) &&
+            ( lastLine.ascender - lastLine.descender > controlSize.height ) )
+        {
+          // Get the first glyph which is going to be replaced and the ellipsis glyph.
+          GlyphInfo& glyphToRemove = *elidedGlyphsBuffer;
+          const GlyphInfo& ellipsisGlyph = fontClient.GetEllipsisGlyph( fontClient.GetPointSize( glyphToRemove.fontId ) );
+
+          // Change the 'x' and 'y' position of the ellipsis glyph.
+          Vector2& position = *elidedPositionsBuffer;
+
+          position.x = ellipsisGlyph.xBearing;
+          position.y = -lastLine.ascender + controlSize.height - ellipsisGlyph.yBearing;
+
+          // Replace the glyph by the ellipsis glyph and resize the buffers.
+          glyphToRemove = ellipsisGlyph;
+
+          mElidedGlyphs.Resize( 1u );
+          mElidedLayout.Resize( 1u );
+
+          return;
+        }
+
+        // firstPenX, penY and firstPenSet are used to position the ellipsis glyph if needed.
+        float firstPenX = 0.f; // Used if rtl text is elided.
+        float penY = 0.f;
+        bool firstPenSet = false;
+
+        // Add the ellipsis glyph.
+        bool inserted = false;
+        float removedGlypsWidth = 0.f;
+        Length numberOfRemovedGlyphs = 0u;
+        GlyphIndex index = numberOfLaidOutGlyphs - 1u;
+
+        // The ellipsis glyph has to fit in the place where the last glyph(s) is(are) removed.
+        while( !inserted )
+        {
+          const GlyphInfo& glyphToRemove = *( elidedGlyphsBuffer + index );
+
+          if( 0u != glyphToRemove.fontId )
+          {
+            // i.e. The font id of the glyph shaped from the '\n' character is zero.
+
+            // Need to reshape the glyph as the font may be different in size.
+            const GlyphInfo& ellipsisGlyph = fontClient.GetEllipsisGlyph( fontClient.GetPointSize( glyphToRemove.fontId ) );
+
+            if( !firstPenSet )
+            {
+              const Vector2& position = *( elidedPositionsBuffer + index );
+
+              // Calculates the penY of the current line. It will be used to position the ellipsis glyph.
+              penY = position.y + glyphToRemove.yBearing;
+
+              // Calculates the first penX which will be used if rtl text is elided.
+              firstPenX = position.x - glyphToRemove.xBearing;
+              if( firstPenX < -ellipsisGlyph.xBearing )
+              {
+                // Avoids to exceed the bounding box when rtl text is elided.
+                firstPenX = -ellipsisGlyph.xBearing;
+              }
+
+              removedGlypsWidth = -ellipsisGlyph.xBearing;
+
+              firstPenSet = true;
+            }
+
+            removedGlypsWidth += std::min( glyphToRemove.advance, ( glyphToRemove.xBearing + glyphToRemove.width ) );
+
+            // Calculate the width of the ellipsis glyph and check if it fits.
+            const float ellipsisGlyphWidth = ellipsisGlyph.width + ellipsisGlyph.xBearing;
+
+            if( ellipsisGlyphWidth < removedGlypsWidth )
+            {
+              GlyphInfo& glyphInfo = *( elidedGlyphsBuffer + index );
+              Vector2& position = *( elidedPositionsBuffer + index );
+              position.x -= ( 0.f > glyphInfo.xBearing ) ? glyphInfo.xBearing : 0.f;
+
+              // Replace the glyph by the ellipsis glyph.
+              glyphInfo = ellipsisGlyph;
+
+              // Change the 'x' and 'y' position of the ellipsis glyph.
+
+              if( position.x > firstPenX )
+              {
+                position.x = firstPenX + removedGlypsWidth - ellipsisGlyphWidth;
+              }
+
+              position.x += ellipsisGlyph.xBearing;
+              position.y = penY - ellipsisGlyph.yBearing;
+
+              inserted = true;
+            }
+          }
+
+          if( !inserted )
+          {
+            if( index > 0u )
+            {
+              --index;
+            }
+            else
+            {
+              // No space for the ellipsis.
+              inserted = true;
+            }
+            ++numberOfRemovedGlyphs;
+          }
+        } // while( !inserted )
+
+          // 'Removes' all the glyphs after the ellipsis glyph.
+        const Length numberOfGlyphs = numberOfLaidOutGlyphs - numberOfRemovedGlyphs;
+        mElidedGlyphs.Resize( numberOfGlyphs );
+        mElidedLayout.Resize( numberOfGlyphs );
+      }
+    }
+  }
+}
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
diff --git a/dali-toolkit/internal/text/rendering/view-model.h b/dali-toolkit/internal/text/rendering/view-model.h
new file mode 100644 (file)
index 0000000..8038820
--- /dev/null
@@ -0,0 +1,152 @@
+#ifndef DALI_TOOLKIT_TEXT_VIEW_MODEL_H
+#define DALI_TOOLKIT_TEXT_VIEW_MODEL_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/dali-vector.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/internal/text/text-model-interface.h>
+
+namespace Dali
+{
+
+namespace Toolkit
+{
+
+namespace Text
+{
+
+/**
+ * @brief Responsible of creating and store temporary modifications of the text model.
+ * i.e. The elide of text.
+ */
+class ViewModel : public ModelInterface
+{
+public:
+  /**
+   * @brief Constructor.
+   *
+   * Keeps the pointer to the text's model. It initializes all the members of the class to their defaults.
+   *
+   * @param[in] model Pointer to the text's model interface.
+   */
+  ViewModel( const ModelInterface* const model );
+
+  /**
+   * @brief Virtual destructor.
+   *
+   * It's a default destructor.
+   */
+  virtual ~ViewModel();
+
+  /**
+   * @copydoc ModelInterface::GetControlSize()
+   */
+  virtual const Size& GetControlSize() const;
+
+  /**
+   * @copydoc ModelInterface::GetLayoutSize()
+   */
+  virtual const Size& GetLayoutSize() const;
+
+  /**
+   * @copydoc ModelInterface::GetScrollPosition()
+   */
+  virtual const Vector2& GetScrollPosition() const;
+
+  /**
+   * @copydoc ModelInterface::GetHorizontalAlignment()
+   */
+  virtual Layout::HorizontalAlignment GetHorizontalAlignment() const;
+
+  /**
+   * @copydoc ModelInterface::GetVerticalAlignment()
+   */
+  virtual Layout::VerticalAlignment GetVerticalAlignment() const;
+
+  /**
+   * @copydoc ModelInterface::IsTextElideEnabled()
+   */
+  virtual bool IsTextElideEnabled() const;
+
+  /**
+   * @copydoc ModelInterface::GetNumberOfLines()
+   */
+  virtual Length GetNumberOfLines() const;
+
+  /**
+   * @copydoc ModelInterface::GetLines()
+   */
+  virtual const LineRun* const GetLines() const;
+
+  /**
+   * @copydoc ModelInterface::GetNumberOfGlyphs()
+   */
+  virtual Length GetNumberOfGlyphs() const;
+
+  /**
+   * @copydoc ModelInterface::GetGlyphs()
+   */
+  virtual const GlyphInfo* const GetGlyphs() const;
+
+  /**
+   * @copydoc ModelInterface::GetLayout()
+   */
+  virtual const Vector2* const GetLayout() const;
+
+  /**
+   * @copydoc ModelInterface::GetColors()
+   */
+  virtual const Vector4* const GetColors() const;
+
+  /**
+   * @copydoc ModelInterface::GetColorIndices()
+   */
+  virtual const ColorIndex* const GetColorIndices() const;
+
+  /**
+   * @copydoc ModelInterface::GetDefaultColor()
+   */
+  virtual const Vector4& GetDefaultColor() const;
+
+  /**
+   * @brief Does the text elide.
+   *
+   * It stores a copy of the visible glyphs and removes as many glyphs as needed
+   * from the last visible line to add the ellipsis glyph.
+   *
+   * It stores as well a copy of the positions for each visible glyph.
+   */
+  void ElideGlyphs();
+
+private:
+  const ModelInterface* const mModel;            ///< Pointer to the text's model.
+  Vector<GlyphInfo>           mElidedGlyphs;     ///< Stores the glyphs of the elided text.
+  Vector<Vector2>             mElidedLayout;     ///< Stores the positions of each glyph of the elided text.
+  bool                        mIsTextElided : 1; ///< Whether the text has been elided.
+};
+
+} // namespace Text
+
+} // namespace Toolkit
+
+} // namespace Dali
+
+#endif // DALI_TOOLKIT_TEXT_VIEW_MODEL_H
index ee7c4ac..85f48ec 100644 (file)
@@ -277,7 +277,7 @@ bool Controller::Impl::ProcessInputEvents()
     const CharacterIndex styleIndex = ( mEventData->mPrimaryCursorPosition > 0u ) ? mEventData->mPrimaryCursorPosition - 1u : 0u;
 
     // Retrieve the style from the style runs stored in the logical model.
-    mLogicalModel->RetrieveStyle( styleIndex, mEventData->mInputStyle );
+    mModel->mLogicalModel->RetrieveStyle( styleIndex, mEventData->mInputStyle );
 
     // Compare if the input style has changed.
     const bool hasInputStyleChanged = !currentInputStyle.Equal( mEventData->mInputStyle );
@@ -329,8 +329,8 @@ void Controller::Impl::NotifyImfMultiLineStatus()
 {
   if ( mEventData )
   {
-    LayoutEngine::Layout layout = mLayoutEngine.GetLayout();
-    mEventData->mImfManager.NotifyTextInputMultiLine( layout == LayoutEngine::MULTI_LINE_BOX );
+    Text::Layout::Engine::Type layout = mLayoutEngine.GetLayout();
+    mEventData->mImfManager.NotifyTextInputMultiLine( layout == Text::Layout::Engine::MULTI_LINE_BOX );
   }
 }
 
@@ -359,9 +359,9 @@ Length Controller::Impl::GetNumberOfWhiteSpaces( CharacterIndex index ) const
   Length numberOfWhiteSpaces = 0u;
 
   // Get the buffer to the text.
-  Character* utf32CharacterBuffer = mLogicalModel->mText.Begin();
+  Character* utf32CharacterBuffer = mModel->mLogicalModel->mText.Begin();
 
-  const Length totalNumberOfCharacters = mLogicalModel->mText.Count();
+  const Length totalNumberOfCharacters = mModel->mLogicalModel->mText.Count();
   for( ; index < totalNumberOfCharacters; ++index, ++numberOfWhiteSpaces )
   {
     if( !TextAbstraction::IsWhiteSpace( *( utf32CharacterBuffer + index ) ) )
@@ -376,12 +376,12 @@ Length Controller::Impl::GetNumberOfWhiteSpaces( CharacterIndex index ) const
 void Controller::Impl::GetText( CharacterIndex index, std::string& text ) const
 {
   // Get the total number of characters.
-  Length numberOfCharacters = mLogicalModel->mText.Count();
+  Length numberOfCharacters = mModel->mLogicalModel->mText.Count();
 
   // Retrieve the text.
   if( 0u != numberOfCharacters )
   {
-    Utf32ToUtf8( mLogicalModel->mText.Begin() + index, numberOfCharacters - index, text );
+    Utf32ToUtf8( mModel->mLogicalModel->mText.Begin() + index, numberOfCharacters - index, text );
   }
 }
 
@@ -392,7 +392,7 @@ void Controller::Impl::CalculateTextUpdateIndices( Length& numberOfCharacters )
   mTextUpdateInfo.mStartLineIndex = 0u;
   numberOfCharacters = 0u;
 
-  const Length numberOfParagraphs = mLogicalModel->mParagraphInfo.Count();
+  const Length numberOfParagraphs = mModel->mLogicalModel->mParagraphInfo.Count();
   if( 0u == numberOfParagraphs )
   {
     mTextUpdateInfo.mParagraphCharacterIndex = 0u;
@@ -416,8 +416,8 @@ void Controller::Impl::CalculateTextUpdateIndices( Length& numberOfCharacters )
       numberOfCharacters = 0u;
       mTextUpdateInfo.mRequestedNumberOfCharacters = mTextUpdateInfo.mNumberOfCharactersToAdd - mTextUpdateInfo.mNumberOfCharactersToRemove;
 
-      mTextUpdateInfo.mStartGlyphIndex = mVisualModel->mGlyphs.Count();
-      mTextUpdateInfo.mStartLineIndex = mVisualModel->mLines.Count() - 1u;
+      mTextUpdateInfo.mStartGlyphIndex = mModel->mVisualModel->mGlyphs.Count();
+      mTextUpdateInfo.mStartLineIndex = mModel->mVisualModel->mLines.Count() - 1u;
 
       // Nothing else to do;
       return;
@@ -436,19 +436,19 @@ void Controller::Impl::CalculateTextUpdateIndices( Length& numberOfCharacters )
     {
       numberOfCharactersToUpdate = ( mTextUpdateInfo.mNumberOfCharactersToRemove > 0u ) ? mTextUpdateInfo.mNumberOfCharactersToRemove : 1u;
     }
-    mLogicalModel->FindParagraphs( mTextUpdateInfo.mCharacterIndex,
-                                   numberOfCharactersToUpdate,
-                                   paragraphsToBeUpdated );
+    mModel->mLogicalModel->FindParagraphs( mTextUpdateInfo.mCharacterIndex,
+                                           numberOfCharactersToUpdate,
+                                           paragraphsToBeUpdated );
   }
 
   if( 0u != paragraphsToBeUpdated.Count() )
   {
     const ParagraphRunIndex firstParagraphIndex = *( paragraphsToBeUpdated.Begin() );
-    const ParagraphRun& firstParagraph = *( mLogicalModel->mParagraphInfo.Begin() + firstParagraphIndex );
+    const ParagraphRun& firstParagraph = *( mModel->mLogicalModel->mParagraphInfo.Begin() + firstParagraphIndex );
     mTextUpdateInfo.mParagraphCharacterIndex = firstParagraph.characterRun.characterIndex;
 
     ParagraphRunIndex lastParagraphIndex = *( paragraphsToBeUpdated.End() - 1u );
-    const ParagraphRun& lastParagraph = *( mLogicalModel->mParagraphInfo.Begin() + lastParagraphIndex );
+    const ParagraphRun& lastParagraph = *( mModel->mLogicalModel->mParagraphInfo.Begin() + lastParagraphIndex );
 
     if( ( mTextUpdateInfo.mNumberOfCharactersToRemove > 0u ) &&                                            // Some character are removed.
         ( lastParagraphIndex < numberOfParagraphs - 1u ) &&                                                // There is a next paragraph.
@@ -456,7 +456,7 @@ void Controller::Impl::CalculateTextUpdateIndices( Length& numberOfCharacters )
           ( mTextUpdateInfo.mCharacterIndex + mTextUpdateInfo.mNumberOfCharactersToRemove ) ) )
     {
       // The new paragraph character of the last updated paragraph has been removed so is going to be merged with the next one.
-      const ParagraphRun& lastParagraph = *( mLogicalModel->mParagraphInfo.Begin() + lastParagraphIndex + 1u );
+      const ParagraphRun& lastParagraph = *( mModel->mLogicalModel->mParagraphInfo.Begin() + lastParagraphIndex + 1u );
 
       numberOfCharacters = lastParagraph.characterRun.characterIndex + lastParagraph.characterRun.numberOfCharacters - mTextUpdateInfo.mParagraphCharacterIndex;
     }
@@ -467,45 +467,45 @@ void Controller::Impl::CalculateTextUpdateIndices( Length& numberOfCharacters )
   }
 
   mTextUpdateInfo.mRequestedNumberOfCharacters = numberOfCharacters + mTextUpdateInfo.mNumberOfCharactersToAdd - mTextUpdateInfo.mNumberOfCharactersToRemove;
-  mTextUpdateInfo.mStartGlyphIndex = *( mVisualModel->mCharactersToGlyph.Begin() + mTextUpdateInfo.mParagraphCharacterIndex );
+  mTextUpdateInfo.mStartGlyphIndex = *( mModel->mVisualModel->mCharactersToGlyph.Begin() + mTextUpdateInfo.mParagraphCharacterIndex );
 }
 
 void Controller::Impl::ClearFullModelData( OperationsMask operations )
 {
   if( NO_OPERATION != ( GET_LINE_BREAKS & operations ) )
   {
-    mLogicalModel->mLineBreakInfo.Clear();
-    mLogicalModel->mParagraphInfo.Clear();
+    mModel->mLogicalModel->mLineBreakInfo.Clear();
+    mModel->mLogicalModel->mParagraphInfo.Clear();
   }
 
   if( NO_OPERATION != ( GET_WORD_BREAKS & operations ) )
   {
-    mLogicalModel->mLineBreakInfo.Clear();
+    mModel->mLogicalModel->mLineBreakInfo.Clear();
   }
 
   if( NO_OPERATION != ( GET_SCRIPTS & operations ) )
   {
-    mLogicalModel->mScriptRuns.Clear();
+    mModel->mLogicalModel->mScriptRuns.Clear();
   }
 
   if( NO_OPERATION != ( VALIDATE_FONTS & operations ) )
   {
-    mLogicalModel->mFontRuns.Clear();
+    mModel->mLogicalModel->mFontRuns.Clear();
   }
 
-  if( 0u != mLogicalModel->mBidirectionalParagraphInfo.Count() )
+  if( 0u != mModel->mLogicalModel->mBidirectionalParagraphInfo.Count() )
   {
     if( NO_OPERATION != ( BIDI_INFO & operations ) )
     {
-      mLogicalModel->mBidirectionalParagraphInfo.Clear();
-      mLogicalModel->mCharacterDirections.Clear();
+      mModel->mLogicalModel->mBidirectionalParagraphInfo.Clear();
+      mModel->mLogicalModel->mCharacterDirections.Clear();
     }
 
     if( NO_OPERATION != ( REORDER & operations ) )
     {
       // Free the allocated memory used to store the conversion table in the bidirectional line info run.
-      for( Vector<BidirectionalLineInfoRun>::Iterator it = mLogicalModel->mBidirectionalLineInfo.Begin(),
-             endIt = mLogicalModel->mBidirectionalLineInfo.End();
+      for( Vector<BidirectionalLineInfoRun>::Iterator it = mModel->mLogicalModel->mBidirectionalLineInfo.Begin(),
+             endIt = mModel->mLogicalModel->mBidirectionalLineInfo.End();
            it != endIt;
            ++it )
       {
@@ -514,28 +514,28 @@ void Controller::Impl::ClearFullModelData( OperationsMask operations )
         free( bidiLineInfo.visualToLogicalMap );
         bidiLineInfo.visualToLogicalMap = NULL;
       }
-      mLogicalModel->mBidirectionalLineInfo.Clear();
+      mModel->mLogicalModel->mBidirectionalLineInfo.Clear();
     }
   }
 
   if( NO_OPERATION != ( SHAPE_TEXT & operations ) )
   {
-    mVisualModel->mGlyphs.Clear();
-    mVisualModel->mGlyphsToCharacters.Clear();
-    mVisualModel->mCharactersToGlyph.Clear();
-    mVisualModel->mCharactersPerGlyph.Clear();
-    mVisualModel->mGlyphsPerCharacter.Clear();
-    mVisualModel->mGlyphPositions.Clear();
+    mModel->mVisualModel->mGlyphs.Clear();
+    mModel->mVisualModel->mGlyphsToCharacters.Clear();
+    mModel->mVisualModel->mCharactersToGlyph.Clear();
+    mModel->mVisualModel->mCharactersPerGlyph.Clear();
+    mModel->mVisualModel->mGlyphsPerCharacter.Clear();
+    mModel->mVisualModel->mGlyphPositions.Clear();
   }
 
   if( NO_OPERATION != ( LAYOUT & operations ) )
   {
-    mVisualModel->mLines.Clear();
+    mModel->mVisualModel->mLines.Clear();
   }
 
   if( NO_OPERATION != ( COLOR & operations ) )
   {
-    mVisualModel->mColorIndices.Clear();
+    mModel->mVisualModel->mColorIndices.Clear();
   }
 }
 
@@ -546,23 +546,23 @@ void Controller::Impl::ClearCharacterModelData( CharacterIndex startIndex, Chara
   if( NO_OPERATION != ( GET_LINE_BREAKS & operations ) )
   {
     // Clear the line break info.
-    LineBreakInfo* lineBreakInfoBuffer = mLogicalModel->mLineBreakInfo.Begin();
+    LineBreakInfo* lineBreakInfoBuffer = mModel->mLogicalModel->mLineBreakInfo.Begin();
 
-    mLogicalModel->mLineBreakInfo.Erase( lineBreakInfoBuffer + startIndex,
-                                         lineBreakInfoBuffer + endIndexPlusOne );
+    mModel->mLogicalModel->mLineBreakInfo.Erase( lineBreakInfoBuffer + startIndex,
+                                                 lineBreakInfoBuffer + endIndexPlusOne );
 
     // Clear the paragraphs.
     ClearCharacterRuns( startIndex,
                         endIndex,
-                        mLogicalModel->mParagraphInfo );
+                        mModel->mLogicalModel->mParagraphInfo );
   }
 
   if( NO_OPERATION != ( GET_WORD_BREAKS & operations ) )
   {
     // Clear the word break info.
-    WordBreakInfo* wordBreakInfoBuffer = mLogicalModel->mWordBreakInfo.Begin();
+    WordBreakInfo* wordBreakInfoBuffer = mModel->mLogicalModel->mWordBreakInfo.Begin();
 
-    mLogicalModel->mWordBreakInfo.Erase( wordBreakInfoBuffer + startIndex,
+    mModel->mLogicalModel->mWordBreakInfo.Erase( wordBreakInfoBuffer + startIndex,
                                          wordBreakInfoBuffer + endIndexPlusOne );
   }
 
@@ -571,7 +571,7 @@ void Controller::Impl::ClearCharacterModelData( CharacterIndex startIndex, Chara
     // Clear the scripts.
     ClearCharacterRuns( startIndex,
                         endIndex,
-                        mLogicalModel->mScriptRuns );
+                        mModel->mLogicalModel->mScriptRuns );
   }
 
   if( NO_OPERATION != ( VALIDATE_FONTS & operations ) )
@@ -579,36 +579,36 @@ void Controller::Impl::ClearCharacterModelData( CharacterIndex startIndex, Chara
     // Clear the fonts.
     ClearCharacterRuns( startIndex,
                         endIndex,
-                        mLogicalModel->mFontRuns );
+                        mModel->mLogicalModel->mFontRuns );
   }
 
-  if( 0u != mLogicalModel->mBidirectionalParagraphInfo.Count() )
+  if( 0u != mModel->mLogicalModel->mBidirectionalParagraphInfo.Count() )
   {
     if( NO_OPERATION != ( BIDI_INFO & operations ) )
     {
       // Clear the bidirectional paragraph info.
       ClearCharacterRuns( startIndex,
                           endIndex,
-                          mLogicalModel->mBidirectionalParagraphInfo );
+                          mModel->mLogicalModel->mBidirectionalParagraphInfo );
 
       // Clear the character's directions.
-      CharacterDirection* characterDirectionsBuffer = mLogicalModel->mCharacterDirections.Begin();
+      CharacterDirection* characterDirectionsBuffer = mModel->mLogicalModel->mCharacterDirections.Begin();
 
-      mLogicalModel->mCharacterDirections.Erase( characterDirectionsBuffer + startIndex,
-                                                 characterDirectionsBuffer + endIndexPlusOne );
+      mModel->mLogicalModel->mCharacterDirections.Erase( characterDirectionsBuffer + startIndex,
+                                                         characterDirectionsBuffer + endIndexPlusOne );
     }
 
     if( NO_OPERATION != ( REORDER & operations ) )
     {
-      uint32_t startRemoveIndex = mLogicalModel->mBidirectionalLineInfo.Count();
+      uint32_t startRemoveIndex = mModel->mLogicalModel->mBidirectionalLineInfo.Count();
       uint32_t endRemoveIndex = startRemoveIndex;
       ClearCharacterRuns( startIndex,
                           endIndex,
-                          mLogicalModel->mBidirectionalLineInfo,
+                          mModel->mLogicalModel->mBidirectionalLineInfo,
                           startRemoveIndex,
                           endRemoveIndex );
 
-      BidirectionalLineInfoRun* bidirectionalLineInfoBuffer = mLogicalModel->mBidirectionalLineInfo.Begin();
+      BidirectionalLineInfoRun* bidirectionalLineInfoBuffer = mModel->mLogicalModel->mBidirectionalLineInfo.Begin();
 
       // Free the allocated memory used to store the conversion table in the bidirectional line info run.
       for( Vector<BidirectionalLineInfoRun>::Iterator it = bidirectionalLineInfoBuffer + startRemoveIndex,
@@ -622,8 +622,8 @@ void Controller::Impl::ClearCharacterModelData( CharacterIndex startIndex, Chara
         bidiLineInfo.visualToLogicalMap = NULL;
       }
 
-      mLogicalModel->mBidirectionalLineInfo.Erase( bidirectionalLineInfoBuffer + startRemoveIndex,
-                                                   bidirectionalLineInfoBuffer + endRemoveIndex );
+      mModel->mLogicalModel->mBidirectionalLineInfo.Erase( bidirectionalLineInfoBuffer + startRemoveIndex,
+                                                           bidirectionalLineInfoBuffer + endRemoveIndex );
     }
   }
 }
@@ -634,8 +634,8 @@ void Controller::Impl::ClearGlyphModelData( CharacterIndex startIndex, Character
   const Length numberOfCharactersRemoved = endIndexPlusOne - startIndex;
 
   // Convert the character index to glyph index before deleting the character to glyph and the glyphs per character buffers.
-  GlyphIndex* charactersToGlyphBuffer = mVisualModel->mCharactersToGlyph.Begin();
-  Length* glyphsPerCharacterBuffer = mVisualModel->mGlyphsPerCharacter.Begin();
+  GlyphIndex* charactersToGlyphBuffer = mModel->mVisualModel->mCharactersToGlyph.Begin();
+  Length* glyphsPerCharacterBuffer = mModel->mVisualModel->mGlyphsPerCharacter.Begin();
 
   const GlyphIndex endGlyphIndexPlusOne = *( charactersToGlyphBuffer + endIndex ) + *( glyphsPerCharacterBuffer + endIndex );
   const Length numberOfGlyphsRemoved = endGlyphIndexPlusOne - mTextUpdateInfo.mStartGlyphIndex;
@@ -644,7 +644,7 @@ void Controller::Impl::ClearGlyphModelData( CharacterIndex startIndex, Character
   {
     // Update the character to glyph indices.
     for( Vector<GlyphIndex>::Iterator it =  charactersToGlyphBuffer + endIndexPlusOne,
-           endIt =  charactersToGlyphBuffer + mVisualModel->mCharactersToGlyph.Count();
+           endIt =  charactersToGlyphBuffer + mModel->mVisualModel->mCharactersToGlyph.Count();
          it != endIt;
          ++it )
     {
@@ -653,23 +653,23 @@ void Controller::Impl::ClearGlyphModelData( CharacterIndex startIndex, Character
     }
 
     // Clear the character to glyph conversion table.
-    mVisualModel->mCharactersToGlyph.Erase( charactersToGlyphBuffer + startIndex,
-                                            charactersToGlyphBuffer + endIndexPlusOne );
+    mModel->mVisualModel->mCharactersToGlyph.Erase( charactersToGlyphBuffer + startIndex,
+                                                    charactersToGlyphBuffer + endIndexPlusOne );
 
     // Clear the glyphs per character table.
-    mVisualModel->mGlyphsPerCharacter.Erase( glyphsPerCharacterBuffer + startIndex,
-                                             glyphsPerCharacterBuffer + endIndexPlusOne );
+    mModel->mVisualModel->mGlyphsPerCharacter.Erase( glyphsPerCharacterBuffer + startIndex,
+                                                     glyphsPerCharacterBuffer + endIndexPlusOne );
 
     // Clear the glyphs buffer.
-    GlyphInfo* glyphsBuffer = mVisualModel->mGlyphs.Begin();
-    mVisualModel->mGlyphs.Erase( glyphsBuffer + mTextUpdateInfo.mStartGlyphIndex,
-                                 glyphsBuffer + endGlyphIndexPlusOne );
+    GlyphInfo* glyphsBuffer = mModel->mVisualModel->mGlyphs.Begin();
+    mModel->mVisualModel->mGlyphs.Erase( glyphsBuffer + mTextUpdateInfo.mStartGlyphIndex,
+                                         glyphsBuffer + endGlyphIndexPlusOne );
 
-    CharacterIndex* glyphsToCharactersBuffer = mVisualModel->mGlyphsToCharacters.Begin();
+    CharacterIndex* glyphsToCharactersBuffer = mModel->mVisualModel->mGlyphsToCharacters.Begin();
 
     // Update the glyph to character indices.
     for( Vector<CharacterIndex>::Iterator it = glyphsToCharactersBuffer + endGlyphIndexPlusOne,
-           endIt = glyphsToCharactersBuffer + mVisualModel->mGlyphsToCharacters.Count();
+           endIt = glyphsToCharactersBuffer + mModel->mVisualModel->mGlyphsToCharacters.Count();
          it != endIt;
          ++it )
     {
@@ -678,55 +678,55 @@ void Controller::Impl::ClearGlyphModelData( CharacterIndex startIndex, Character
     }
 
     // Clear the glyphs to characters buffer.
-    mVisualModel->mGlyphsToCharacters.Erase( glyphsToCharactersBuffer + mTextUpdateInfo.mStartGlyphIndex,
-                                             glyphsToCharactersBuffer  + endGlyphIndexPlusOne );
+    mModel->mVisualModel->mGlyphsToCharacters.Erase( glyphsToCharactersBuffer + mTextUpdateInfo.mStartGlyphIndex,
+                                                     glyphsToCharactersBuffer  + endGlyphIndexPlusOne );
 
     // Clear the characters per glyph buffer.
-    Length* charactersPerGlyphBuffer = mVisualModel->mCharactersPerGlyph.Begin();
-    mVisualModel->mCharactersPerGlyph.Erase( charactersPerGlyphBuffer + mTextUpdateInfo.mStartGlyphIndex,
-                                             charactersPerGlyphBuffer + endGlyphIndexPlusOne );
+    Length* charactersPerGlyphBuffer = mModel->mVisualModel->mCharactersPerGlyph.Begin();
+    mModel->mVisualModel->mCharactersPerGlyph.Erase( charactersPerGlyphBuffer + mTextUpdateInfo.mStartGlyphIndex,
+                                                     charactersPerGlyphBuffer + endGlyphIndexPlusOne );
 
     // Clear the positions buffer.
-    Vector2* positionsBuffer = mVisualModel->mGlyphPositions.Begin();
-    mVisualModel->mGlyphPositions.Erase( positionsBuffer + mTextUpdateInfo.mStartGlyphIndex,
-                                         positionsBuffer + endGlyphIndexPlusOne );
+    Vector2* positionsBuffer = mModel->mVisualModel->mGlyphPositions.Begin();
+    mModel->mVisualModel->mGlyphPositions.Erase( positionsBuffer + mTextUpdateInfo.mStartGlyphIndex,
+                                                 positionsBuffer + endGlyphIndexPlusOne );
   }
 
   if( NO_OPERATION != ( LAYOUT & operations ) )
   {
     // Clear the lines.
-    uint32_t startRemoveIndex = mVisualModel->mLines.Count();
+    uint32_t startRemoveIndex = mModel->mVisualModel->mLines.Count();
     uint32_t endRemoveIndex = startRemoveIndex;
     ClearCharacterRuns( startIndex,
                         endIndex,
-                        mVisualModel->mLines,
+                        mModel->mVisualModel->mLines,
                         startRemoveIndex,
                         endRemoveIndex );
 
     // Will update the glyph runs.
-    startRemoveIndex = mVisualModel->mLines.Count();
+    startRemoveIndex = mModel->mVisualModel->mLines.Count();
     endRemoveIndex = startRemoveIndex;
     ClearGlyphRuns( mTextUpdateInfo.mStartGlyphIndex,
                     endGlyphIndexPlusOne - 1u,
-                    mVisualModel->mLines,
+                    mModel->mVisualModel->mLines,
                     startRemoveIndex,
                     endRemoveIndex );
 
     // Set the line index from where to insert the new laid-out lines.
     mTextUpdateInfo.mStartLineIndex = startRemoveIndex;
 
-    LineRun* linesBuffer = mVisualModel->mLines.Begin();
-    mVisualModel->mLines.Erase( linesBuffer + startRemoveIndex,
-                                linesBuffer + endRemoveIndex );
+    LineRun* linesBuffer = mModel->mVisualModel->mLines.Begin();
+    mModel->mVisualModel->mLines.Erase( linesBuffer + startRemoveIndex,
+                                        linesBuffer + endRemoveIndex );
   }
 
   if( NO_OPERATION != ( COLOR & operations ) )
   {
-    if( 0u != mVisualModel->mColorIndices.Count() )
+    if( 0u != mModel->mVisualModel->mColorIndices.Count() )
     {
-      ColorIndex* colorIndexBuffer = mVisualModel->mColorIndices.Begin();
-      mVisualModel->mColorIndices.Erase( colorIndexBuffer + mTextUpdateInfo.mStartGlyphIndex,
-                                         colorIndexBuffer + endGlyphIndexPlusOne );
+      ColorIndex* colorIndexBuffer = mModel->mVisualModel->mColorIndices.Begin();
+      mModel->mVisualModel->mColorIndices.Erase( colorIndexBuffer + mTextUpdateInfo.mStartGlyphIndex,
+                                                 colorIndexBuffer + endGlyphIndexPlusOne );
     }
   }
 }
@@ -749,9 +749,9 @@ void Controller::Impl::ClearModelData( CharacterIndex startIndex, CharacterIndex
   }
 
   // The estimated number of lines. Used to avoid reallocations when layouting.
-  mTextUpdateInfo.mEstimatedNumberOfLines = std::max( mVisualModel->mLines.Count(), mLogicalModel->mParagraphInfo.Count() );
+  mTextUpdateInfo.mEstimatedNumberOfLines = std::max( mModel->mVisualModel->mLines.Count(), mModel->mLogicalModel->mParagraphInfo.Count() );
 
-  mVisualModel->ClearCaches();
+  mModel->mVisualModel->ClearCaches();
 }
 
 bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
@@ -767,7 +767,7 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
     return false;
   }
 
-  Vector<Character>& utf32Characters = mLogicalModel->mText;
+  Vector<Character>& utf32Characters = mModel->mLogicalModel->mText;
 
   const Length numberOfCharacters = utf32Characters.Count();
 
@@ -790,7 +790,7 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
   // Whether the model is updated.
   bool updated = false;
 
-  Vector<LineBreakInfo>& lineBreakInfo = mLogicalModel->mLineBreakInfo;
+  Vector<LineBreakInfo>& lineBreakInfo = mModel->mLogicalModel->mLineBreakInfo;
   const Length requestedNumberOfCharacters = mTextUpdateInfo.mRequestedNumberOfCharacters;
 
   if( NO_OPERATION != ( GET_LINE_BREAKS & operations ) )
@@ -807,12 +807,12 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
                       lineBreakInfo );
 
     // Create the paragraph info.
-    mLogicalModel->CreateParagraphInfo( startIndex,
-                                        requestedNumberOfCharacters );
+    mModel->mLogicalModel->CreateParagraphInfo( startIndex,
+                                                requestedNumberOfCharacters );
     updated = true;
   }
 
-  Vector<WordBreakInfo>& wordBreakInfo = mLogicalModel->mWordBreakInfo;
+  Vector<WordBreakInfo>& wordBreakInfo = mModel->mLogicalModel->mWordBreakInfo;
   if( NO_OPERATION != ( GET_WORD_BREAKS & operations ) )
   {
     // Retrieves the word break info. The word break info is used to layout the text (where to wrap the text in lines).
@@ -828,8 +828,8 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
   const bool getScripts = NO_OPERATION != ( GET_SCRIPTS & operations );
   const bool validateFonts = NO_OPERATION != ( VALIDATE_FONTS & operations );
 
-  Vector<ScriptRun>& scripts = mLogicalModel->mScriptRuns;
-  Vector<FontRun>& validFonts = mLogicalModel->mFontRuns;
+  Vector<ScriptRun>& scripts = mModel->mLogicalModel->mScriptRuns;
+  Vector<FontRun>& validFonts = mModel->mLogicalModel->mFontRuns;
 
   if( getScripts || validateFonts )
   {
@@ -849,7 +849,7 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
     if( validateFonts )
     {
       // Validate the fonts set through the mark-up string.
-      Vector<FontDescriptionRun>& fontDescriptionRuns = mLogicalModel->mFontDescriptionRuns;
+      Vector<FontDescriptionRun>& fontDescriptionRuns = mModel->mLogicalModel->mFontDescriptionRuns;
 
       // Get the default font's description.
       TextAbstraction::FontDescription defaultFontDescription;
@@ -876,10 +876,10 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
 
   Vector<Character> mirroredUtf32Characters;
   bool textMirrored = false;
-  const Length numberOfParagraphs = mLogicalModel->mParagraphInfo.Count();
+  const Length numberOfParagraphs = mModel->mLogicalModel->mParagraphInfo.Count();
   if( NO_OPERATION != ( BIDI_INFO & operations ) )
   {
-    Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = mLogicalModel->mBidirectionalParagraphInfo;
+    Vector<BidirectionalParagraphInfoRun>& bidirectionalInfo = mModel->mLogicalModel->mBidirectionalParagraphInfo;
     bidirectionalInfo.Reserve( numberOfParagraphs );
 
     // Calculates the bidirectional info for the whole paragraph if it contains right to left scripts.
@@ -893,7 +893,7 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
     if( 0u != bidirectionalInfo.Count() )
     {
       // Only set the character directions if there is right to left characters.
-      Vector<CharacterDirection>& directions = mLogicalModel->mCharacterDirections;
+      Vector<CharacterDirection>& directions = mModel->mLogicalModel->mCharacterDirections;
       GetCharactersDirection( bidirectionalInfo,
                               numberOfCharacters,
                               startIndex,
@@ -913,14 +913,14 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
     else
     {
       // There is no right to left characters. Clear the directions vector.
-      mLogicalModel->mCharacterDirections.Clear();
+      mModel->mLogicalModel->mCharacterDirections.Clear();
     }
     updated = true;
   }
 
-  Vector<GlyphInfo>& glyphs = mVisualModel->mGlyphs;
-  Vector<CharacterIndex>& glyphsToCharactersMap = mVisualModel->mGlyphsToCharacters;
-  Vector<Length>& charactersPerGlyph = mVisualModel->mCharactersPerGlyph;
+  Vector<GlyphInfo>& glyphs = mModel->mVisualModel->mGlyphs;
+  Vector<CharacterIndex>& glyphsToCharactersMap = mModel->mVisualModel->mGlyphsToCharacters;
+  Vector<Length>& charactersPerGlyph = mModel->mVisualModel->mCharactersPerGlyph;
   Vector<GlyphIndex> newParagraphGlyphs;
   newParagraphGlyphs.Reserve( numberOfParagraphs );
 
@@ -942,8 +942,8 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
                newParagraphGlyphs );
 
     // Create the 'number of glyphs' per character and the glyph to character conversion tables.
-    mVisualModel->CreateGlyphsPerCharacterTable( startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters );
-    mVisualModel->CreateCharacterToGlyphTable( startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters );
+    mModel->mVisualModel->CreateGlyphsPerCharacterTable( startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters );
+    mModel->mVisualModel->CreateCharacterToGlyphTable( startIndex, mTextUpdateInfo.mStartGlyphIndex, requestedNumberOfCharacters );
     updated = true;
   }
 
@@ -970,25 +970,25 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
   if( NO_OPERATION != ( COLOR & operations ) )
   {
     // Set the color runs in glyphs.
-    SetColorSegmentationInfo( mLogicalModel->mColorRuns,
-                              mVisualModel->mCharactersToGlyph,
-                              mVisualModel->mGlyphsPerCharacter,
+    SetColorSegmentationInfo( mModel->mLogicalModel->mColorRuns,
+                              mModel->mVisualModel->mCharactersToGlyph,
+                              mModel->mVisualModel->mGlyphsPerCharacter,
                               startIndex,
                               mTextUpdateInfo.mStartGlyphIndex,
                               requestedNumberOfCharacters,
-                              mVisualModel->mColors,
-                              mVisualModel->mColorIndices );
+                              mModel->mVisualModel->mColors,
+                              mModel->mVisualModel->mColorIndices );
 
     updated = true;
   }
 
   if( ( NULL != mEventData ) &&
       mEventData->mPreEditFlag &&
-      ( 0u != mVisualModel->mCharactersToGlyph.Count() ) )
+      ( 0u != mModel->mVisualModel->mCharactersToGlyph.Count() ) )
   {
     // Add the underline for the pre-edit text.
-    const GlyphIndex* const charactersToGlyphBuffer = mVisualModel->mCharactersToGlyph.Begin();
-    const Length* const glyphsPerCharacterBuffer = mVisualModel->mGlyphsPerCharacter.Begin();
+    const GlyphIndex* const charactersToGlyphBuffer = mModel->mVisualModel->mCharactersToGlyph.Begin();
+    const Length* const glyphsPerCharacterBuffer = mModel->mVisualModel->mGlyphsPerCharacter.Begin();
 
     const GlyphIndex glyphStart = *( charactersToGlyphBuffer + mEventData->mPreEditStartPosition );
     const CharacterIndex lastPreEditCharacter = mEventData->mPreEditStartPosition + ( ( mEventData->mPreEditLength > 0u ) ? mEventData->mPreEditLength - 1u : 0u );
@@ -1000,11 +1000,11 @@ bool Controller::Impl::UpdateModel( OperationsMask operationsRequired )
     underlineRun.numberOfGlyphs = 1u + glyphEnd - glyphStart;
 
     // TODO: At the moment the underline runs are only for pre-edit.
-    mVisualModel->mUnderlineRuns.PushBack( underlineRun );
+    mModel->mVisualModel->mUnderlineRuns.PushBack( underlineRun );
   }
 
   // The estimated number of lines. Used to avoid reallocations when layouting.
-  mTextUpdateInfo.mEstimatedNumberOfLines = std::max( mVisualModel->mLines.Count(), mLogicalModel->mParagraphInfo.Count() );
+  mTextUpdateInfo.mEstimatedNumberOfLines = std::max( mModel->mVisualModel->mLines.Count(), mModel->mLogicalModel->mParagraphInfo.Count() );
 
   // Set the previous number of characters for the next time the text is updated.
   mTextUpdateInfo.mPreviousNumberOfCharacters = numberOfCharacters;
@@ -1117,7 +1117,7 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event )
   }
   else if( Dali::DALI_KEY_CURSOR_RIGHT == keyCode )
   {
-    if( mLogicalModel->mText.Count() > mEventData->mPrimaryCursorPosition )
+    if( mModel->mLogicalModel->mText.Count() > mEventData->mPrimaryCursorPosition )
     {
       mEventData->mPrimaryCursorPosition = CalculateNewCursorIndex( mEventData->mPrimaryCursorPosition );
     }
@@ -1132,7 +1132,7 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event )
       characterIndex = mEventData->mPrimaryCursorPosition - 1u;
     }
 
-    const LineIndex lineIndex = mVisualModel->GetLineOfCharacter( characterIndex );
+    const LineIndex lineIndex = mModel->mVisualModel->GetLineOfCharacter( characterIndex );
 
     if( lineIndex > 0u )
     {
@@ -1142,14 +1142,14 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event )
                          cursorInfo );
 
       // Get the line above.
-      const LineRun& line = *( mVisualModel->mLines.Begin() + ( lineIndex - 1u ) );
+      const LineRun& line = *( mModel->mVisualModel->mLines.Begin() + ( lineIndex - 1u ) );
 
       // Get the next hit 'y' point.
       const float hitPointY = cursorInfo.lineOffset - 0.5f * ( line.ascender - line.descender );
 
       // Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index.
-      mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mVisualModel,
-                                                                        mLogicalModel,
+      mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mModel->mVisualModel,
+                                                                        mModel->mLogicalModel,
                                                                         mMetrics,
                                                                         mEventData->mCursorHookPositionX,
                                                                         hitPointY );
@@ -1165,9 +1165,9 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event )
       characterIndex = mEventData->mPrimaryCursorPosition - 1u;
     }
 
-    const LineIndex lineIndex = mVisualModel->GetLineOfCharacter( characterIndex );
+    const LineIndex lineIndex = mModel->mVisualModel->GetLineOfCharacter( characterIndex );
 
-    if( lineIndex + 1u < mVisualModel->mLines.Count() )
+    if( lineIndex + 1u < mModel->mVisualModel->mLines.Count() )
     {
       // Retrieve the cursor position info.
       CursorInfo cursorInfo;
@@ -1175,14 +1175,14 @@ void Controller::Impl::OnCursorKeyEvent( const Event& event )
                          cursorInfo );
 
       // Get the line below.
-      const LineRun& line = *( mVisualModel->mLines.Begin() + lineIndex + 1u );
+      const LineRun& line = *( mModel->mVisualModel->mLines.Begin() + lineIndex + 1u );
 
       // Get the next hit 'y' point.
       const float hitPointY = cursorInfo.lineOffset + cursorInfo.lineHeight + 0.5f * ( line.ascender - line.descender );
 
       // Use the cursor hook position 'x' and the next hit 'y' position to calculate the new cursor index.
-      mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mVisualModel,
-                                                                        mLogicalModel,
+      mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mModel->mVisualModel,
+                                                                        mModel->mLogicalModel,
                                                                         mMetrics,
                                                                         mEventData->mCursorHookPositionX,
                                                                         hitPointY );
@@ -1205,14 +1205,14 @@ void Controller::Impl::OnTapEvent( const Event& event )
       if( IsShowingRealText() )
       {
         // Convert from control's coords to text's coords.
-        const float xPosition = event.p2.mFloat - mScrollPosition.x;
-        const float yPosition = event.p3.mFloat - mScrollPosition.y;
+        const float xPosition = event.p2.mFloat - mModel->mScrollPosition.x;
+        const float yPosition = event.p3.mFloat - mModel->mScrollPosition.y;
 
         // Keep the tap 'x' position. Used to move the cursor.
         mEventData->mCursorHookPositionX = xPosition;
 
-        mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mVisualModel,
-                                                                          mLogicalModel,
+        mEventData->mPrimaryCursorPosition = Text::GetClosestCursorIndex( mModel->mVisualModel,
+                                                                          mModel->mLogicalModel,
                                                                           mMetrics,
                                                                           xPosition,
                                                                           yPosition );
@@ -1269,13 +1269,13 @@ void Controller::Impl::OnPanEvent( const Event& event )
     }
     case Gesture::Continuing:
     {
-      const Vector2& layoutSize = mVisualModel->GetLayoutSize();
-      const Vector2 currentScroll = mScrollPosition;
+      const Vector2& layoutSize = mModel->mVisualModel->GetLayoutSize();
+      const Vector2 currentScroll = mModel->mScrollPosition;
 
       if( isHorizontalScrollEnabled )
       {
         const float displacementX = event.p2.mFloat;
-        mScrollPosition.x += displacementX;
+        mModel->mScrollPosition.x += displacementX;
 
         ClampHorizontalScroll( layoutSize );
       }
@@ -1283,12 +1283,12 @@ void Controller::Impl::OnPanEvent( const Event& event )
       if( isVerticalScrollEnabled )
       {
         const float displacementY = event.p3.mFloat;
-        mScrollPosition.y += displacementY;
+        mModel->mScrollPosition.y += displacementY;
 
         ClampVerticalScroll( layoutSize );
       }
 
-      mEventData->mDecorator->UpdatePositions( mScrollPosition - currentScroll );
+      mEventData->mDecorator->UpdatePositions( mModel->mScrollPosition - currentScroll );
       break;
     }
     case Gesture::Finished:
@@ -1311,6 +1311,7 @@ void Controller::Impl::OnLongPressEvent( const Event& event )
   {
     ChangeState ( EventData::EDITING_WITH_POPUP );
     mEventData->mDecoratorUpdated = true;
+    mEventData->mUpdateInputStyle = true;
   }
 }
 
@@ -1329,12 +1330,12 @@ void Controller::Impl::OnHandleEvent( const Event& event )
   if( HANDLE_PRESSED == state )
   {
     // Convert from decorator's coords to text's coords.
-    const float xPosition = event.p2.mFloat - mScrollPosition.x;
-    const float yPosition = event.p3.mFloat - mScrollPosition.y;
+    const float xPosition = event.p2.mFloat - mModel->mScrollPosition.x;
+    const float yPosition = event.p3.mFloat - mModel->mScrollPosition.y;
 
     // Need to calculate the handle's new position.
-    const CharacterIndex handleNewPosition = Text::GetClosestCursorIndex( mVisualModel,
-                                                                          mLogicalModel,
+    const CharacterIndex handleNewPosition = Text::GetClosestCursorIndex( mModel->mVisualModel,
+                                                                          mModel->mLogicalModel,
                                                                           mMetrics,
                                                                           xPosition,
                                                                           yPosition );
@@ -1403,11 +1404,11 @@ void Controller::Impl::OnHandleEvent( const Event& event )
     if( handleStopScrolling || isSmoothHandlePanEnabled )
     {
       // Convert from decorator's coords to text's coords.
-      const float xPosition = event.p2.mFloat - mScrollPosition.x;
-      const float yPosition = event.p3.mFloat - mScrollPosition.y;
+      const float xPosition = event.p2.mFloat - mModel->mScrollPosition.x;
+      const float yPosition = event.p3.mFloat - mModel->mScrollPosition.y;
 
-      handlePosition = Text::GetClosestCursorIndex( mVisualModel,
-                                                    mLogicalModel,
+      handlePosition = Text::GetClosestCursorIndex( mModel->mVisualModel,
+                                                    mModel->mLogicalModel,
                                                     mMetrics,
                                                     xPosition,
                                                     yPosition );
@@ -1474,17 +1475,17 @@ void Controller::Impl::OnHandleEvent( const Event& event )
   {
     const float xSpeed = event.p2.mFloat;
     const float ySpeed = event.p3.mFloat;
-    const Vector2& layoutSize = mVisualModel->GetLayoutSize();
-    const Vector2 currentScrollPosition = mScrollPosition;
+    const Vector2& layoutSize = mModel->mVisualModel->GetLayoutSize();
+    const Vector2 currentScrollPosition = mModel->mScrollPosition;
 
-    mScrollPosition.x += xSpeed;
-    mScrollPosition.y += ySpeed;
+    mModel->mScrollPosition.x += xSpeed;
+    mModel->mScrollPosition.y += ySpeed;
 
     ClampHorizontalScroll( layoutSize );
     ClampVerticalScroll( layoutSize );
 
     bool endOfScroll = false;
-    if( Vector2::ZERO == ( currentScrollPosition - mScrollPosition ) )
+    if( Vector2::ZERO == ( currentScrollPosition - mModel->mScrollPosition ) )
     {
       // Notify the decorator there is no more text to scroll.
       // The decorator won't send more scroll events.
@@ -1509,7 +1510,7 @@ void Controller::Impl::OnHandleEvent( const Event& event )
       if( mEventData->mDecorator->IsHorizontalScrollEnabled() )
       {
         // Position the grag handle close to either the left or right edge.
-        position.x = scrollRightDirection ? 0.f : mVisualModel->mControlSize.width;
+        position.x = scrollRightDirection ? 0.f : mModel->mVisualModel->mControlSize.width;
       }
 
       if( mEventData->mDecorator->IsVerticalScrollEnabled() )
@@ -1517,16 +1518,16 @@ void Controller::Impl::OnHandleEvent( const Event& event )
         position.x = mEventData->mCursorHookPositionX;
 
         // Position the grag handle close to either the top or bottom edge.
-        position.y = scrollBottomDirection ? 0.f : mVisualModel->mControlSize.height;
+        position.y = scrollBottomDirection ? 0.f : mModel->mVisualModel->mControlSize.height;
       }
 
       // Get the new handle position.
       // The grab handle's position is in decorator's coords. Need to transforms to text's coords.
-      const CharacterIndex handlePosition = Text::GetClosestCursorIndex( mVisualModel,
-                                                                         mLogicalModel,
+      const CharacterIndex handlePosition = Text::GetClosestCursorIndex( mModel->mVisualModel,
+                                 &