Merge "Changes for std::vector removal from api" into tizen
authorKimmo Hoikka <kimmo.hoikka@samsung.com>
Fri, 29 May 2015 17:38:53 +0000 (10:38 -0700)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Fri, 29 May 2015 17:38:53 +0000 (10:38 -0700)
61 files changed:
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/test-platform-abstraction.h
automated-tests/src/dali-toolkit/utc-Dali-ControlImpl.cpp
automated-tests/src/dali-toolkit/utc-Dali-ItemLayout.cpp
automated-tests/src/dali-toolkit/utc-Dali-KeyboardFocusManager.cpp
build/tizen/docs/dali_doxygen.css
dali-toolkit/internal/controls/popup/popup-impl.cpp
dali-toolkit/internal/controls/popup/popup-impl.h
dali-toolkit/internal/controls/scrollable/item-view/depth-layout.cpp
dali-toolkit/internal/controls/scrollable/item-view/depth-layout.h
dali-toolkit/internal/controls/scrollable/item-view/grid-layout.cpp
dali-toolkit/internal/controls/scrollable/item-view/grid-layout.h
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.cpp
dali-toolkit/internal/controls/scrollable/item-view/item-view-impl.h
dali-toolkit/internal/controls/table-view/table-view-impl.cpp
dali-toolkit/internal/controls/table-view/table-view-impl.h
dali-toolkit/internal/controls/text-controls/text-field-impl.cpp
dali-toolkit/internal/controls/text-controls/text-field-impl.h
dali-toolkit/internal/controls/text-controls/text-label-impl.cpp
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.cpp
dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/public-api/controls/control-impl.cpp
dali-toolkit/public-api/controls/control-impl.h
dali-toolkit/public-api/controls/control.h
dali-toolkit/public-api/controls/scrollable/item-view/item-layout.cpp
dali-toolkit/public-api/controls/scrollable/item-view/item-layout.h
dali-toolkit/public-api/focus-manager/keyboard-focus-manager.cpp
dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h
docs/content/figures/image-scaling/cards.jpg [new file with mode: 0644]
docs/content/figures/image-scaling/concept-rectangles.svg [new file with mode: 0644]
docs/content/figures/image-scaling/dog.jpg [new file with mode: 0644]
docs/content/figures/image-scaling/door.jpg [new file with mode: 0644]
docs/content/figures/image-scaling/example-fitting-mode-options.svg [new file with mode: 0644]
docs/content/figures/image-scaling/example-scale-to-fill-problem.svg [new file with mode: 0644]
docs/content/figures/image-scaling/example-scale-to-fill-sequence.svg [new file with mode: 0644]
docs/content/figures/image-scaling/gallery-large-12.jpg [new file with mode: 0644]
docs/content/figures/image-scaling/liberty.jpg [new file with mode: 0644]
docs/content/figures/image-scaling/phone-transparent-screen.png [new file with mode: 0644]
docs/content/figures/image-scaling/phone.png [new file with mode: 0644]
docs/content/images/image-scaling/concept-rectangles.jpg [new file with mode: 0644]
docs/content/images/image-scaling/demo-fitting-sampling.jpg [new file with mode: 0644]
docs/content/images/image-scaling/demo-sampling-modes.jpg [new file with mode: 0644]
docs/content/images/image-scaling/example-scale-to-fill-problem.jpg [new file with mode: 0644]
docs/content/images/image-scaling/example-scale-to-fill-sequence.jpg [new file with mode: 0644]
docs/content/images/image-scaling/fitting-mode-options.jpg [new file with mode: 0644]
docs/content/images/image-scaling/sampling_modes_box.png [new file with mode: 0644]
docs/content/images/image-scaling/sampling_modes_box_then_linear.png [new file with mode: 0644]
docs/content/images/image-scaling/sampling_modes_box_then_nearest.png [new file with mode: 0644]
docs/content/images/image-scaling/sampling_modes_linear.png [new file with mode: 0644]
docs/content/images/image-scaling/sampling_modes_nearest.png [new file with mode: 0644]
docs/content/images/image-scaling/sampling_modes_no_filter.png [new file with mode: 0644]
docs/content/main.md
docs/content/programming-guide/image-actor.h
docs/content/shared-javascript-and-cpp-documentation/resource-image-scaling.md [new file with mode: 0644]
docs/content/shared-javascript-and-cpp-documentation/texture-compression.md
plugins/dali-script-v8/src/image/resource-image-api.cpp
plugins/dali-script-v8/src/signals/signal-manager.cpp
plugins/dali-script-v8/src/toolkit/focus-manager/keyboard-focus-manager-api.cpp
plugins/dali-script-v8/src/toolkit/focus-manager/keyboard-focus-manager-wrapper.cpp
plugins/dali-script-v8/src/toolkit/focus-manager/keyboard-focus-manager-wrapper.h

index 2fce6a2..c083fef 100644 (file)
@@ -21,7 +21,7 @@
 // EXTERNAL INCLUDES
 #include <stdint.h>
 #include <cstring>
-#include <dali/devel-api/images/image-operations.h>
+#include <dali/public-api/images/image-operations.h>
 
 // INTERNAL INCLUDES
 #include <dali/devel-api/common/set-wrapper.h>
index 310a19f..f3aa937 100644 (file)
@@ -934,7 +934,7 @@ int UtcDaliControlImplGetNextKeyboardFocusableActorP(void)
   Toolkit::Internal::Control& controlImpl = Toolkit::Internal::GetImplementation( dummy );
 
   Actor currentFocusedActor;
-  Actor result = controlImpl.GetNextKeyboardFocusableActor( currentFocusedActor, Control::Left, false );
+  Actor result = controlImpl.GetNextKeyboardFocusableActor( currentFocusedActor, Control::KeyboardFocus::LEFT, false );
 
   DALI_TEST_EQUALS( result, currentFocusedActor, TEST_LOCATION );
 
index 8dd9e24..67a2287 100644 (file)
@@ -295,7 +295,7 @@ int UtcDaliItemLayoutSetAndGetOrientation(void)
 
   DALI_TEST_EQUALS(position, 0.0f, TEST_LOCATION);
 
-  int focusItem = layout->GetNextFocusItemID(0, TOTAL_ITEM_NUMBER, Control::Left, true);
+  int focusItem = layout->GetNextFocusItemID(0, TOTAL_ITEM_NUMBER, Control::KeyboardFocus::LEFT, true);
 
   DALI_TEST_CHECK(focusItem != 0);
 
@@ -352,8 +352,8 @@ int UtcDaliItemLayoutGetNextFocusItemID(void)
 
   TestItemLayoutPtr layout = TestItemLayout::New();
   DALI_TEST_CHECK( layout );
-  DALI_TEST_EQUALS(layout->GetNextFocusItemID(0, 100, Control::Left, true), 99, TEST_LOCATION );
-  DALI_TEST_EQUALS(layout->GetNextFocusItemID(110, 100, Control::Right, true), 0, TEST_LOCATION );
+  DALI_TEST_EQUALS(layout->GetNextFocusItemID(0, 100, Control::KeyboardFocus::LEFT, true), 99, TEST_LOCATION );
+  DALI_TEST_EQUALS(layout->GetNextFocusItemID(110, 100, Control::KeyboardFocus::RIGHT, true), 0, TEST_LOCATION );
 
   END_TEST;
 }
index 05f0e26..e902ec0 100644 (file)
@@ -51,11 +51,11 @@ public:
   : mSignalVerified(signalReceived),
     mCurrentFocusedActor(),
     mProposedActorToFocus(),
-    mDirection(Control::Left)
+    mDirection(Control::KeyboardFocus::LEFT)
   {
   }
 
-  Actor Callback(Actor currentFocusedActor, Actor proposedActorToFocus, Control::KeyboardFocusNavigationDirection direction)
+  Actor Callback(Actor currentFocusedActor, Actor proposedActorToFocus, Control::KeyboardFocus::Direction direction)
   {
     tet_infoline("Verifying PreFocusChangeCallback()");
 
@@ -73,13 +73,13 @@ public:
     mSignalVerified = false;
     mCurrentFocusedActor = Actor();
     mProposedActorToFocus = Actor();
-    mDirection = Control::Left;
+    mDirection = Control::KeyboardFocus::LEFT;
   }
 
   bool& mSignalVerified;
   Actor mCurrentFocusedActor;
   Actor mProposedActorToFocus;
-  Control::KeyboardFocusNavigationDirection mDirection;
+  Control::KeyboardFocus::Direction mDirection;
 };
 
 // Functors to test whether focus changed signal is emitted when the keyboard focus is changed
@@ -295,13 +295,13 @@ int UtcDaliKeyboardFocusManagerMoveFocus(void)
   Stage::GetCurrent().Add(second);
 
   // Move the focus to the right
-  DALI_TEST_CHECK(manager.MoveFocus(Control::Right) == false);
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == false);
 
   // Because no layout control in the stage and no actor is focused, it should emit the PreFocusChange signal
   DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
   DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == Actor());
   DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
-  DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::Right);
+  DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::KeyboardFocus::RIGHT);
   preFocusChangeCallback.Reset();
 
   // Check that the focus is set on the first actor
@@ -313,13 +313,13 @@ int UtcDaliKeyboardFocusManagerMoveFocus(void)
   focusChangedCallback.Reset();
 
   // Move the focus towards right
-  DALI_TEST_CHECK(manager.MoveFocus(Control::Right) == false);
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == false);
 
   // Because no layout control in the stage and the first actor is focused, it should emit the PreFocusChange signal
   DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
   DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == first);
   DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
-  DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::Right);
+  DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::KeyboardFocus::RIGHT);
   preFocusChangeCallback.Reset();
 
   // Check that the focus is set on the second actor
@@ -331,13 +331,13 @@ int UtcDaliKeyboardFocusManagerMoveFocus(void)
   focusChangedCallback.Reset();
 
   // Move the focus towards up
-  DALI_TEST_CHECK(manager.MoveFocus(Control::Up) == false);
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::UP) == false);
 
   // Because no layout control in the stage and no actor is focused, it should emit the PreFocusChange signal
   DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
   DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == second);
   DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
-  DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::Up);
+  DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::KeyboardFocus::UP);
   preFocusChangeCallback.Reset();
   DALI_TEST_CHECK(!focusChangedCallback.mSignalVerified);
 
@@ -368,7 +368,7 @@ int UtcDaliKeyboardFocusManagerMoveFocus(void)
   focusChangedCallback.Reset();
 
   // Move the focus towards right
-  DALI_TEST_CHECK(manager.MoveFocus(Control::Right) == true);
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::RIGHT) == true);
   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == second);
   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == first);
@@ -376,7 +376,7 @@ int UtcDaliKeyboardFocusManagerMoveFocus(void)
   focusChangedCallback.Reset();
 
   // Move the focus towards down
-  DALI_TEST_CHECK(manager.MoveFocus(Control::Down) == true);
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::DOWN) == true);
   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == fourth);
   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == second);
@@ -384,7 +384,7 @@ int UtcDaliKeyboardFocusManagerMoveFocus(void)
   focusChangedCallback.Reset();
 
   // Move the focus towards left
-  DALI_TEST_CHECK(manager.MoveFocus(Control::Left) == true);
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == true);
   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == third);
   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == fourth);
@@ -392,7 +392,7 @@ int UtcDaliKeyboardFocusManagerMoveFocus(void)
   focusChangedCallback.Reset();
 
   // Move the focus towards up
-  DALI_TEST_CHECK(manager.MoveFocus(Control::Up) == true);
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::UP) == true);
   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == third);
@@ -400,12 +400,12 @@ int UtcDaliKeyboardFocusManagerMoveFocus(void)
   focusChangedCallback.Reset();
 
   // Move the focus towards left. The focus move will fail as no way to move it upwards
-  DALI_TEST_CHECK(manager.MoveFocus(Control::Left) == false);
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == false);
   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == first);
   DALI_TEST_CHECK(preFocusChangeCallback.mSignalVerified);
   DALI_TEST_CHECK(preFocusChangeCallback.mCurrentFocusedActor == first);
   DALI_TEST_CHECK(preFocusChangeCallback.mProposedActorToFocus == Actor());
-  DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::Left);
+  DALI_TEST_CHECK(preFocusChangeCallback.mDirection == Control::KeyboardFocus::LEFT);
   preFocusChangeCallback.Reset();
   DALI_TEST_CHECK(!focusChangedCallback.mSignalVerified);
 
@@ -414,7 +414,7 @@ int UtcDaliKeyboardFocusManagerMoveFocus(void)
   DALI_TEST_CHECK(manager.GetFocusGroupLoop() == true);
 
   // Move the focus towards left again. The focus should move to the fourth actor.
-  DALI_TEST_CHECK(manager.MoveFocus(Control::Left) == true);
+  DALI_TEST_CHECK(manager.MoveFocus(Control::KeyboardFocus::LEFT) == true);
   DALI_TEST_CHECK(manager.GetCurrentFocusActor() == fourth);
   DALI_TEST_CHECK(focusChangedCallback.mSignalVerified);
   DALI_TEST_CHECK(focusChangedCallback.mOriginalFocusedActor == first);
index 9bc0ef4..4b68ddf 100644 (file)
@@ -3,3 +3,7 @@
    text-align: left;
    margin-left: 50px;
 }
+
+div.image img {
+  max-width: 50em;
+}
index dd4c3d5..719cfe9 100755 (executable)
@@ -810,7 +810,7 @@ float Popup::GetWidthForHeight( float height )
   return GetNaturalSize().width;
 }
 
-Actor Popup::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
+Actor Popup::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
 {
   Actor nextFocusableActor( currentFocusedActor );
 
@@ -853,7 +853,7 @@ Actor Popup::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::C
       {
         switch ( direction )
         {
-          case Toolkit::Control::Left:
+          case Toolkit::Control::KeyboardFocus::LEFT:
           {
             if ( iter == focusableActors.begin() )
             {
@@ -865,7 +865,7 @@ Actor Popup::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::C
             }
             break;
           }
-          case Toolkit::Control::Right:
+          case Toolkit::Control::KeyboardFocus::RIGHT:
           {
             if ( iter == focusableActors.end() - 1 )
             {
@@ -878,7 +878,7 @@ Actor Popup::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::C
             break;
           }
 
-          case Toolkit::Control::Up:
+          case Toolkit::Control::KeyboardFocus::UP:
           {
             if ( *iter == mContent )
             {
@@ -905,7 +905,7 @@ Actor Popup::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::C
             break;
           }
 
-          case Toolkit::Control::Down:
+          case Toolkit::Control::KeyboardFocus::DOWN:
           {
             if ( mContent && mContent.IsKeyboardFocusable() )
             {
index 3d361fe..099e5e6 100755 (executable)
@@ -279,7 +279,7 @@ private:
   /**
    * @copydoc Control::GetNextKeyboardFocusableActor()
    */
-  Actor GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled);
+  Actor GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled);
 
   /**
    * Create the root actor for the footer
index 34838ad..2fa572d 100644 (file)
@@ -567,11 +567,11 @@ float DepthLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLay
   return scrollTo;
 }
 
-int DepthLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
+int DepthLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
 {
   switch( direction )
   {
-    case Toolkit::Control::Left:
+    case Toolkit::Control::KeyboardFocus::LEFT:
     {
       itemID--;
       if( itemID < 0 )
@@ -580,7 +580,7 @@ int DepthLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Con
       }
       break;
     }
-    case Toolkit::Control::Up:
+    case Toolkit::Control::KeyboardFocus::UP:
     {
       itemID += mImpl->mNumberOfColumns;
       if( itemID >= maxItems )
@@ -589,7 +589,7 @@ int DepthLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Con
       }
       break;
     }
-    case Toolkit::Control::Right:
+    case Toolkit::Control::KeyboardFocus::RIGHT:
     {
       itemID++;
       if( itemID >= maxItems )
@@ -598,7 +598,7 @@ int DepthLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Con
       }
       break;
     }
-    case Toolkit::Control::Down:
+    case Toolkit::Control::KeyboardFocus::DOWN:
     {
       itemID -= mImpl->mNumberOfColumns;
       if( itemID < 0 )
index 1d16a03..c1f18f9 100644 (file)
@@ -156,7 +156,7 @@ public:
   /**
    * @copydoc ItemLayout::GetNextFocusItemID()
    */
-  virtual int GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled);
+  virtual int GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled);
 
 private:
 
index 020bbcf..9339f0a 100644 (file)
@@ -676,11 +676,11 @@ Vector3 GridLayout::GetItemPosition(int itemID, float currentLayoutPosition, con
   return itemPosition;
 }
 
-int GridLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
+int GridLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
 {
   switch( direction )
   {
-    case Toolkit::Control::Left:
+    case Toolkit::Control::KeyboardFocus::LEFT:
     {
       itemID--;
       if( itemID < 0 )
@@ -689,7 +689,7 @@ int GridLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Cont
       }
       break;
     }
-    case Toolkit::Control::Up:
+    case Toolkit::Control::KeyboardFocus::UP:
     {
       itemID -= mImpl->mNumberOfColumns;
       if( itemID < 0 )
@@ -698,7 +698,7 @@ int GridLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Cont
       }
       break;
     }
-    case Toolkit::Control::Right:
+    case Toolkit::Control::KeyboardFocus::RIGHT:
     {
       itemID++;
       if( itemID >= maxItems )
@@ -707,7 +707,7 @@ int GridLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Cont
       }
       break;
     }
-    case Toolkit::Control::Down:
+    case Toolkit::Control::KeyboardFocus::DOWN:
     {
       itemID += mImpl->mNumberOfColumns;
       if( itemID >= maxItems )
index 0031559..b2b3bd9 100644 (file)
@@ -199,7 +199,7 @@ public:
   /**
    * @copydoc ItemLayout::GetNextFocusItemID()
    */
-  virtual int GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled);
+  virtual int GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled);
 
 private:
 
index 972d04f..e56760f 100644 (file)
@@ -1201,7 +1201,7 @@ bool ItemView::OnAccessibilityPan(PanGesture gesture)
   return true;
 }
 
-Actor ItemView::GetNextKeyboardFocusableActor(Actor actor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
+Actor ItemView::GetNextKeyboardFocusableActor(Actor actor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
 {
   Actor nextFocusActor;
   if(mActiveLayout)
index 995e4eb..16f0b0a 100644 (file)
@@ -364,7 +364,7 @@ private: // From Control
   /**
    * @copydoc Toolkit::Control::GetNextKeyboardFocusableActor()
    */
-  virtual Actor GetNextKeyboardFocusableActor(Actor actor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled);
+  virtual Actor GetNextKeyboardFocusableActor(Actor actor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled);
 
   /**
    * @copydoc Toolkit::Control::OnKeyboardFocusChangeCommitted()
index 5a49cf4..bd96f77 100644 (file)
@@ -1142,7 +1142,7 @@ TableView::~TableView()
   // nothing to do
 }
 
-Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
+Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
 {
   Actor nextFocusableActor;
 
@@ -1165,7 +1165,7 @@ Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolki
 
       switch ( direction )
       {
-        case Toolkit::Control::Left:
+        case Toolkit::Control::KeyboardFocus::LEFT:
         {
           if(--currentColumn < 0)
           {
@@ -1178,7 +1178,7 @@ Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolki
           }
           break;
         }
-        case Toolkit::Control::Right:
+        case Toolkit::Control::KeyboardFocus::RIGHT:
         {
           if(++currentColumn > numberOfColumns - 1)
           {
@@ -1191,7 +1191,7 @@ Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolki
           }
           break;
         }
-        case Toolkit::Control::Up:
+        case Toolkit::Control::KeyboardFocus::UP:
         {
           if(--currentRow < 0)
           {
@@ -1200,7 +1200,7 @@ Actor TableView::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolki
           }
           break;
         }
-        case Toolkit::Control::Down:
+        case Toolkit::Control::KeyboardFocus::DOWN:
 
         {
           if(++currentRow > numberOfRows - 1)
index be41e47..d1d8aef 100644 (file)
@@ -261,7 +261,7 @@ private: // From Control
   /**
    * @copydoc Control::GetNextKeyboardFocusableActor
    */
-  virtual Actor GetNextKeyboardFocusableActor( Actor currentFocusedActor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled );
+  virtual Actor GetNextKeyboardFocusableActor( Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled );
 
   /**
    * @copydoc Control::GetNaturalSize()
index 2d07c1e..11ec5c2 100644 (file)
@@ -159,6 +159,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
         {
           impl.mRenderingBackend = backend;
           impl.mRenderer.Reset();
+          impl.RequestTextRelayout();
         }
         break;
       }
@@ -166,7 +167,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          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 );
@@ -177,7 +178,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          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( PLACEHOLDER_TYPE_INACTIVE, text );
@@ -188,7 +189,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          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( PLACEHOLDER_TYPE_ACTIVE, text );
@@ -199,13 +200,12 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          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() );
 
           if( impl.mController->GetDefaultFontFamily() != fontFamily )
           {
             impl.mController->SetDefaultFontFamily( fontFamily );
-            impl.RequestTextRelayout();
           }
         }
         break;
@@ -214,13 +214,12 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          std::string fontStyle = value.Get< std::string >();
+          const std::string fontStyle = value.Get< std::string >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p FONT_STYLE %s\n", impl.mController.Get(), fontStyle.c_str() );
 
           if( impl.mController->GetDefaultFontStyle() != fontStyle )
           {
             impl.mController->SetDefaultFontStyle( fontStyle );
-            impl.RequestTextRelayout();
           }
         }
         break;
@@ -229,13 +228,12 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          float pointSize = value.Get< float >();
+          const float pointSize = value.Get< float >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p FONT_STYLE %f\n", impl.mController.Get(), pointSize );
 
           if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
           {
             impl.mController->SetDefaultPointSize( pointSize );
-            impl.RequestTextRelayout();
           }
         }
         break;
@@ -249,19 +247,14 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          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 %f\n", impl.mController.Get(), alignStr.c_str() );
 
-          LayoutEngine& engine = impl.mController->GetLayoutEngine();
-          LayoutEngine::HorizontalAlignment alignment = Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
+          const LayoutEngine::HorizontalAlignment alignment = Scripting::GetEnumeration< LayoutEngine::HorizontalAlignment >( alignStr.c_str(),
                                                                                                                         HORIZONTAL_ALIGNMENT_STRING_TABLE,
                                                                                                                         HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
 
-          if( engine.GetHorizontalAlignment() != alignment )
-          {
-            engine.SetHorizontalAlignment( alignment );
-            impl.RequestTextRelayout();
-          }
+          impl.mController->SetHorizontalAlignment( alignment );
         }
         break;
       }
@@ -269,48 +262,43 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          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 %f\n", impl.mController.Get(), alignStr.c_str() );
 
-          LayoutEngine& engine = impl.mController->GetLayoutEngine();
           LayoutEngine::VerticalAlignment alignment = Scripting::GetEnumeration< LayoutEngine::VerticalAlignment >( alignStr.c_str(),
                                                                                                                     VERTICAL_ALIGNMENT_STRING_TABLE,
                                                                                                                     VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
 
-          if( engine.GetVerticalAlignment() != alignment )
-          {
-            engine.SetVerticalAlignment( alignment );
-            impl.RequestTextRelayout();
-          }
+          impl.mController->SetVerticalAlignment( alignment );
         }
         break;
       }
       case Toolkit::TextField::Property::TEXT_COLOR:
       {
-        if ( impl.mController )
+        if( impl.mController )
         {
-          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->GetTextColor() != textColor )
           {
             impl.mController->SetTextColor( textColor );
-            impl.RequestTextRelayout();
+            impl.mRenderer.Reset();
           }
         }
         break;
       }
       case Toolkit::TextField::Property::PLACEHOLDER_TEXT_COLOR:
       {
-        if ( impl.mController )
+        if( impl.mController )
         {
-          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 )
+          if( impl.mController->GetPlaceholderTextColor() != textColor )
           {
             impl.mController->SetPlaceholderTextColor( textColor );
-            impl.RequestTextRelayout();
+            impl.mRenderer.Reset();
           }
         }
         break;
@@ -319,13 +307,13 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          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 )
           {
             impl.mController->SetShadowOffset( shadowOffset );
-            impl.RequestTextRelayout();
+            impl.mRenderer.Reset();
           }
         }
         break;
@@ -334,13 +322,13 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          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 )
           {
             impl.mController->SetShadowColor( shadowColor );
-            impl.RequestTextRelayout();
+            impl.mRenderer.Reset();
           }
         }
         break;
@@ -349,10 +337,11 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mDecorator )
         {
-          Vector4 color = value.Get< Vector4 >();
+          const Vector4 color = value.Get< Vector4 >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p PRIMARY_CURSOR_COLOR %f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
           impl.mDecorator->SetColor( PRIMARY_CURSOR, color );
+          impl.RequestTextRelayout();
         }
         break;
       }
@@ -360,10 +349,11 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mDecorator )
         {
-          Vector4 color = value.Get< Vector4 >();
+          const Vector4 color = value.Get< Vector4 >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SECONDARY_CURSOR_COLOR %f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
           impl.mDecorator->SetColor( SECONDARY_CURSOR, color );
+          impl.RequestTextRelayout();
         }
         break;
       }
@@ -371,10 +361,11 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          bool enable = value.Get< bool >();
+          const bool enable = value.Get< bool >();
           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p ENABLE_CURSOR_BLINK %d\n", impl.mController.Get(), enable );
 
           impl.mController->SetEnableCursorBlink( enable );
+          impl.RequestTextRelayout();
         }
         break;
       }
@@ -382,7 +373,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mDecorator )
         {
-          float interval = value.Get< float >();
+          const float interval = value.Get< float >();
           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), interval );
 
           impl.mDecorator->SetCursorBlinkInterval( interval );
@@ -393,7 +384,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mDecorator )
         {
-          float duration = value.Get< float >();
+          const float duration = value.Get< float >();
           DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p CURSOR_BLINK_INTERVAL %f\n", impl.mController.Get(), duration );
 
           impl.mDecorator->SetCursorBlinkDuration( duration );
@@ -402,29 +393,31 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextField::Property::GRAB_HANDLE_IMAGE:
       {
-        ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+        const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_IMAGE %s\n", impl.mController.Get(), image.GetUrl().c_str() );
 
         if( impl.mDecorator )
         {
           impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_RELEASED, image );
+          impl.RequestTextRelayout();
         }
         break;
       }
       case Toolkit::TextField::Property::GRAB_HANDLE_PRESSED_IMAGE:
       {
-        ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+        const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p GRAB_HANDLE_PRESSED_IMAGE %s\n", impl.mController.Get(), image.GetUrl().c_str() );
 
         if( impl.mDecorator )
         {
           impl.mDecorator->SetHandleImage( GRAB_HANDLE, HANDLE_IMAGE_PRESSED, image );
+          impl.RequestTextRelayout();
         }
         break;
       }
       case Toolkit::TextField::Property::SCROLL_THRESHOLD:
       {
-        float threshold = value.Get< float >();
+        const float threshold = value.Get< float >();
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SCROLL_THRESHOLD %f\n", impl.mController.Get(), threshold );
 
         if( impl.mDecorator )
@@ -435,7 +428,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextField::Property::SCROLL_SPEED:
       {
-        float speed = value.Get< float >();
+        const float speed = value.Get< float >();
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SCROLL_SPEED %f\n", impl.mController.Get(), speed );
 
         if( impl.mDecorator )
@@ -446,56 +439,61 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_LEFT:
       {
-        ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+        const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_IMAGE_LEFT %f\n", impl.mController.Get(), image.GetUrl().c_str() );
 
         if( impl.mDecorator )
         {
           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
+          impl.RequestTextRelayout();
         }
         break;
       }
       case Toolkit::TextField::Property::SELECTION_HANDLE_IMAGE_RIGHT:
       {
-        ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+        const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_IMAGE_RIGHT %f\n", impl.mController.Get(), image.GetUrl().c_str() );
 
         if( impl.mDecorator )
         {
           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_RELEASED, image );
+          impl.RequestTextRelayout();
         }
         break;
       }
       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_LEFT:
       {
-        ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+        const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_PRESSED_IMAGE_LEFT %f\n", impl.mController.Get(), image.GetUrl().c_str() );
 
         if( impl.mDecorator )
         {
           impl.mDecorator->SetHandleImage( LEFT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, image );
+          impl.RequestTextRelayout();
         }
         break;
       }
       case Toolkit::TextField::Property::SELECTION_HANDLE_PRESSED_IMAGE_RIGHT:
       {
-        ResourceImage image = ResourceImage::New( value.Get< std::string >() );
+        const ResourceImage image = ResourceImage::New( value.Get< std::string >() );
         DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField %p SELECTION_HANDLE_PRESSED_IMAGE_RIGHT %f\n", impl.mController.Get(), image.GetUrl().c_str() );
 
         if( impl.mDecorator )
         {
           impl.mDecorator->SetHandleImage( RIGHT_SELECTION_HANDLE, HANDLE_IMAGE_PRESSED, image );
+          impl.RequestTextRelayout();
         }
         break;
       }
       case Toolkit::TextField::Property::SELECTION_HIGHLIGHT_COLOR:
       {
-        Vector4 color = value.Get< Vector4 >();
+        const Vector4 color = value.Get< Vector4 >();
         DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p SELECTION_HIGHLIGHT_COLOR %f,%f\n", impl.mController.Get(), color.r, color.g, color.b, color.a );
 
         if( impl.mDecorator )
         {
           impl.mDecorator->SetHighlightColor( color );
+          impl.RequestTextRelayout();
         }
         break;
       }
@@ -503,10 +501,11 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mDecorator )
         {
-          Rect<int> box = value.Get< Rect<int> >();
+          const Rect<int> box = value.Get< Rect<int> >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p DECORATION_BOUNDING_BOX %d,%d %dx%d\n", impl.mController.Get(), box.x, box.y, box.width, box.height );
 
           impl.mDecorator->SetBoundingBox( box );
+          impl.RequestTextRelayout();
         }
         break;
       }
@@ -514,7 +513,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          int max = value.Get< int >();
+          const int max = value.Get< int >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextField %p MAX_LENGTH %d\n", impl.mController.Get(), max );
 
           impl.mController->SetMaximumNumberOfCharacters( max );
@@ -523,8 +522,7 @@ void TextField::SetProperty( BaseObject* object, Property::Index index, const Pr
       }
       case Toolkit::TextField::Property::INPUT_METHOD_SETTINGS:
       {
-        // Empty implementation for now.
-        Property::Map map = value.Get<Property::Map>();
+        const Property::Map map = value.Get<Property::Map>();
         VirtualKeyboard::ApplySettings( map );
         break;
       }
@@ -580,6 +578,30 @@ Property::Value TextField::GetProperty( BaseObject* object, Property::Index inde
         }
         break;
       }
+      case Toolkit::TextField::Property::FONT_FAMILY:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetDefaultFontFamily();
+        }
+        break;
+      }
+      case Toolkit::TextField::Property::FONT_STYLE:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetDefaultFontStyle();
+        }
+        break;
+      }
+      case Toolkit::TextField::Property::POINT_SIZE:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetDefaultPointSize();
+        }
+        break;
+      }
       case Toolkit::TextField::Property::EXCEED_POLICY:
       {
         value = impl.mExceedPolicy;
@@ -1002,55 +1024,7 @@ bool TextField::OnKeyEvent( const KeyEvent& event )
 ImfManager::ImfCallbackData TextField::OnImfEvent( Dali::ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
 {
   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextField::OnImfEvent %p eventName %d\n", mController.Get(), imfEvent.eventName );
-
-  bool update( false );
-
-  std::string text;
-  unsigned int cursorPosition( 0 );
-
-  switch ( imfEvent.eventName )
-  {
-    case ImfManager::COMMIT:
-    {
-      mController->InsertText( imfEvent.predictiveString, Text::Controller::COMMIT );
-      break;
-    }
-    case ImfManager::PREEDIT:
-    {
-      mController->InsertText( imfEvent.predictiveString, Text::Controller::PRE_EDIT );
-      update = true;
-      break;
-    }
-    case ImfManager::DELETESURROUNDING:
-    {
-      mController->RemoveText( imfEvent.cursorOffset, imfEvent.numberOfChars );
-      break;
-    }
-    case ImfManager::GETSURROUNDING:
-    {
-      mController->GetText( text );
-      cursorPosition = mController->GetLogicalCursorPosition();
-
-      imfManager.SetSurroundingText( text );
-      imfManager.SetCursorPosition( cursorPosition );
-      break;
-    }
-    case ImfManager::VOID:
-    {
-      // do nothing
-      break;
-    }
-  } // end switch
-
-  if( ImfManager::GETSURROUNDING != imfEvent.eventName )
-  {
-    mController->GetText( text );
-    cursorPosition = mController->GetLogicalCursorPosition();
-  }
-
-  ImfManager::ImfCallbackData callbackData( update, cursorPosition, text, false );
-
-  return callbackData;
+  return mController->OnImfEvent( imfManager, imfEvent );
 }
 
 void TextField::RequestTextRelayout()
index 32a0d67..5e0df24 100644 (file)
@@ -18,9 +18,6 @@
  *
  */
 
-// EXTERNAL INCLUDES
-#include <dali/devel-api/adaptor-framework/imf-manager.h>
-
 // INTERNAL INCLUDES
 #include <dali-toolkit/public-api/controls/control-impl.h>
 #include <dali-toolkit/public-api/controls/text-controls/text-field.h>
@@ -140,11 +137,7 @@ private: // From Control
   virtual bool OnKeyEvent(const KeyEvent& event);
 
   /**
-   * @brief Event received from IMF manager
-   *
-   * @param[in] imfManager The IMF manager.
-   * @param[in] imfEvent The event received.
-   * @return A data struture indicating if update is needed, cursor position and current text.
+   * @copydoc Dali::Toolkit::Text::Controller::(ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent)
    */
   ImfManager::ImfCallbackData OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent );
 
index 423a8ae..35761df 100644 (file)
@@ -120,7 +120,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
     {
       case Toolkit::TextLabel::Property::RENDERING_BACKEND:
       {
-        int backend = value.Get< int >();
+        const int backend = value.Get< int >();
 
         if( impl.mRenderingBackend != backend )
         {
@@ -135,7 +135,6 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
         if( impl.mController )
         {
           impl.mController->SetText( value.Get< std::string >() );
-          impl.RequestTextRelayout();
         }
         break;
       }
@@ -143,12 +142,11 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          std::string fontFamily = value.Get< std::string >();
+          const std::string fontFamily = value.Get< std::string >();
 
           if( impl.mController->GetDefaultFontFamily() != fontFamily )
           {
             impl.mController->SetDefaultFontFamily( fontFamily );
-            impl.RequestTextRelayout();
           }
         }
         break;
@@ -157,12 +155,11 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          std::string fontStyle = value.Get< std::string >();
+          const std::string fontStyle = value.Get< std::string >();
 
           if( impl.mController->GetDefaultFontStyle() != fontStyle )
           {
             impl.mController->SetDefaultFontStyle( fontStyle );
-            impl.RequestTextRelayout();
           }
         }
         break;
@@ -171,12 +168,11 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          float pointSize = value.Get< float >();
+          const float pointSize = value.Get< float >();
 
           if( !Equals( impl.mController->GetDefaultPointSize(), pointSize ) )
           {
             impl.mController->SetDefaultPointSize( pointSize );
-            impl.RequestTextRelayout();
           }
         }
         break;
@@ -185,55 +181,44 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          LayoutEngine& engine = impl.mController->GetLayoutEngine();
-          LayoutEngine::Layout layout = value.Get< bool >() ? LayoutEngine::MULTI_LINE_BOX : LayoutEngine::SINGLE_LINE_BOX;
-
-          if( engine.GetLayout() != layout )
-          {
-            engine.SetLayout( layout );
-            impl.RequestTextRelayout();
-          }
+          impl.mController->SetMultiLineEnabled( value.Get< bool >() );
         }
         break;
       }
       case Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT:
       {
-        LayoutEngine& engine = impl.mController->GetLayoutEngine();
-        const LayoutEngine::HorizontalAlignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( value.Get< std::string >().c_str(),
-                                                                                                                                           HORIZONTAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                                           HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
-
-        if( engine.GetHorizontalAlignment() != alignment )
+        if( impl.mController )
         {
-          engine.SetHorizontalAlignment( alignment );
-          impl.RequestTextRelayout();
+          const LayoutEngine::HorizontalAlignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::HorizontalAlignment >( value.Get< std::string >().c_str(),
+                                                                                                                                             HORIZONTAL_ALIGNMENT_STRING_TABLE,
+                                                                                                                                             HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT );
+
+          impl.mController->SetHorizontalAlignment( alignment );
         }
         break;
       }
       case Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT:
       {
-        LayoutEngine& engine = impl.mController->GetLayoutEngine();
-        const LayoutEngine::VerticalAlignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( value.Get< std::string >().c_str(),
-                                                                                                                                       VERTICAL_ALIGNMENT_STRING_TABLE,
-                                                                                                                                       VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
-
-        if( engine.GetVerticalAlignment() != alignment )
+        if( impl.mController )
         {
-          engine.SetVerticalAlignment( alignment );
-          impl.RequestTextRelayout();
+          const LayoutEngine::VerticalAlignment alignment = Scripting::GetEnumeration< Toolkit::Text::LayoutEngine::VerticalAlignment >( value.Get< std::string >().c_str(),
+                                                                                                                                         VERTICAL_ALIGNMENT_STRING_TABLE,
+                                                                                                                                         VERTICAL_ALIGNMENT_STRING_TABLE_COUNT );
+
+          impl.mController->SetVerticalAlignment( alignment );
         }
         break;
       }
 
       case Toolkit::TextLabel::Property::TEXT_COLOR:
       {
-        if ( impl.mController )
+        if( impl.mController )
         {
-          Vector4 textColor = value.Get< Vector4 >();
-          if ( impl.mController->GetTextColor() != textColor )
+          const Vector4 textColor = value.Get< Vector4 >();
+          if( impl.mController->GetTextColor() != textColor )
           {
             impl.mController->SetTextColor( textColor );
-            impl.RequestTextRelayout();
+            impl.mRenderer.Reset();
           }
         }
         break;
@@ -243,11 +228,11 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          Vector2 shadowOffset = value.Get< Vector2 >();
+          const Vector2 shadowOffset = value.Get< Vector2 >();
           if ( impl.mController->GetShadowOffset() != shadowOffset )
           {
             impl.mController->SetShadowOffset( shadowOffset );
-            impl.RequestTextRelayout();
+            impl.mRenderer.Reset();
           }
         }
         break;
@@ -256,11 +241,11 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          Vector4 shadowColor = value.Get< Vector4 >();
+          const Vector4 shadowColor = value.Get< Vector4 >();
           if ( impl.mController->GetShadowColor() != shadowColor )
           {
             impl.mController->SetShadowColor( shadowColor );
-            impl.RequestTextRelayout();
+            impl.mRenderer.Reset();
           }
         }
         break;
@@ -269,11 +254,11 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          Vector4 color = value.Get< Vector4 >();
+          const Vector4 color = value.Get< Vector4 >();
           if ( impl.mController->GetUnderlineColor() != color )
           {
             impl.mController->SetUnderlineColor( color );
-            impl.RequestTextRelayout();
+            impl.mRenderer.Reset();
           }
         }
         break;
@@ -282,11 +267,11 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
       {
         if( impl.mController )
         {
-          bool enabled = value.Get< bool >();
+          const bool enabled = value.Get< bool >();
           if ( impl.mController->IsUnderlineEnabled() != enabled )
           {
             impl.mController->SetUnderlineEnabled( enabled );
-            impl.RequestTextRelayout();
+            impl.mRenderer.Reset();
           }
         }
         break;
@@ -300,7 +285,7 @@ void TextLabel::SetProperty( BaseObject* object, Property::Index index, const Pr
           if ( impl.mController->GetUnderlineHeight() != height )
           {
             impl.mController->SetUnderlineHeight( height );
-            impl.RequestTextRelayout();
+            impl.mRenderer.Reset();
           }
         }
         break;
@@ -335,11 +320,35 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
         }
         break;
       }
+      case Toolkit::TextLabel::Property::FONT_FAMILY:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetDefaultFontFamily();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::FONT_STYLE:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetDefaultFontStyle();
+        }
+        break;
+      }
+      case Toolkit::TextLabel::Property::POINT_SIZE:
+      {
+        if( impl.mController )
+        {
+          value = impl.mController->GetDefaultPointSize();
+        }
+        break;
+      }
       case Toolkit::TextLabel::Property::MULTI_LINE:
       {
         if( impl.mController )
         {
-          value = static_cast<bool>( LayoutEngine::MULTI_LINE_BOX == impl.mController->GetLayoutEngine().GetLayout() );
+          value = impl.mController->IsMultiLineEnabled();
         }
         break;
       }
@@ -347,7 +356,7 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       {
         if( impl.mController )
         {
-          value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetLayoutEngine().GetHorizontalAlignment(),
+          value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::HorizontalAlignment >( impl.mController->GetHorizontalAlignment(),
                                                                                                                   HORIZONTAL_ALIGNMENT_STRING_TABLE,
                                                                                                                   HORIZONTAL_ALIGNMENT_STRING_TABLE_COUNT ) );
         }
@@ -357,7 +366,7 @@ Property::Value TextLabel::GetProperty( BaseObject* object, Property::Index inde
       {
         if( impl.mController )
         {
-          value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetLayoutEngine().GetVerticalAlignment(),
+          value = std::string( Scripting::GetEnumerationName< Toolkit::Text::LayoutEngine::VerticalAlignment >( impl.mController->GetVerticalAlignment(),
                                                                                                                 VERTICAL_ALIGNMENT_STRING_TABLE,
                                                                                                                 VERTICAL_ALIGNMENT_STRING_TABLE_COUNT ) );
         }
index 4f4bf57..fb20d56 100644 (file)
@@ -216,7 +216,7 @@ Toolkit::Control KeyboardFocusManager::GetParentLayoutControl(Actor actor) const
   return Toolkit::Control::DownCast(parent);
 }
 
-bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocusNavigationDirection direction)
+bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocus::Direction direction)
 {
   Actor currentFocusActor = GetCurrentFocusActor();
 
@@ -257,7 +257,7 @@ bool KeyboardFocusManager::MoveFocus(Toolkit::Control::KeyboardFocusNavigationDi
   return succeed;
 }
 
-bool KeyboardFocusManager::DoMoveFocusWithinLayoutControl(Toolkit::Control control, Actor actor, Toolkit::Control::KeyboardFocusNavigationDirection direction)
+bool KeyboardFocusManager::DoMoveFocusWithinLayoutControl(Toolkit::Control control, Actor actor, Toolkit::Control::KeyboardFocus::Direction direction)
 {
   // Ask the control for the next actor to focus
   Actor nextFocusableActor = GetImplementation( control ).GetNextKeyboardFocusableActor(actor, direction, mFocusGroupLoopEnabled);
@@ -329,7 +329,7 @@ bool KeyboardFocusManager::DoMoveFocusToNextFocusGroup(bool forward)
   {
     // If the current focus group has a parent layout control, we can probably automatically
     // move the focus to the next focus group in the forward or backward direction.
-    Toolkit::Control::KeyboardFocusNavigationDirection direction = forward ? Toolkit::Control::Right : Toolkit::Control::Left;
+    Toolkit::Control::KeyboardFocus::Direction direction = forward ? Toolkit::Control::KeyboardFocus::RIGHT : Toolkit::Control::KeyboardFocus::LEFT;
     succeed = DoMoveFocusWithinLayoutControl(parentLayoutControl, GetCurrentFocusActor(), direction);
     parentLayoutControl = GetParentLayoutControl(parentLayoutControl);
   }
@@ -542,7 +542,7 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
         else
         {
           // Move the focus towards left
-          MoveFocus(Toolkit::Control::Left);
+          MoveFocus(Toolkit::Control::KeyboardFocus::LEFT);
         }
 
         isFocusStartableKey = true;
@@ -565,7 +565,7 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
         else
         {
           // Move the focus towards right
-          MoveFocus(Toolkit::Control::Right);
+          MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT);
         }
       }
       else
@@ -586,7 +586,7 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
       else
       {
         // Move the focus towards up
-        MoveFocus(Toolkit::Control::Up);
+        MoveFocus(Toolkit::Control::KeyboardFocus::UP);
       }
 
       isFocusStartableKey = true;
@@ -601,7 +601,7 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
       else
       {
         // Move the focus towards down
-        MoveFocus(Toolkit::Control::Down);
+        MoveFocus(Toolkit::Control::KeyboardFocus::DOWN);
       }
 
       isFocusStartableKey = true;
@@ -687,7 +687,7 @@ void KeyboardFocusManager::OnKeyEvent(const KeyEvent& event)
     {
       // No actor is focused but keyboard focus is activated by the key press
       // Let's try to move the initial focus
-      MoveFocus(Toolkit::Control::Right);
+      MoveFocus(Toolkit::Control::KeyboardFocus::RIGHT);
     }
     else if(mFocusIndicatorActor)
     {
index 1cd958a..bc456c2 100644 (file)
@@ -65,7 +65,7 @@ public:
   /**
    * @copydoc Toolkit::KeyboardFocusManager::MoveFocus
    */
-  bool MoveFocus(Toolkit::Control::KeyboardFocusNavigationDirection direction);
+  bool MoveFocus(Toolkit::Control::KeyboardFocus::Direction direction);
 
   /**
    * @copydoc Toolkit::KeyboardFocusManager::ClearFocus
@@ -171,7 +171,7 @@ private:
    * @param direction The direction of focus movement
    * @return Whether the focus is successful or not
    */
-  bool DoMoveFocusWithinLayoutControl(Toolkit::Control control, Actor actor, Toolkit::Control::KeyboardFocusNavigationDirection direction);
+  bool DoMoveFocusWithinLayoutControl(Toolkit::Control control, Actor actor, Toolkit::Control::KeyboardFocus::Direction direction);
 
   /**
    * Move the focus to the first focusable actor in the next focus group in the forward
index adf4e75..e07e29c 100644 (file)
@@ -79,7 +79,7 @@ void Controller::SetText( const std::string& text )
   // Remove the previously set text
   ResetText();
 
-  if( ! text.empty() )
+  if( !text.empty() )
   {
     //  Convert text into UTF-32
     Vector<Character>& utf32Characters = mImpl->mLogicalModel->mText;
@@ -104,12 +104,20 @@ void Controller::SetText( const std::string& text )
 
     // Update the rest of the model during size negotiation
     mImpl->QueueModifyEvent( ModifyEvent::TEXT_REPLACED );
+
+    // The natural size needs to be re-calculated.
+    mImpl->mRecalculateNaturalSize = true;
+
+    // Apply modifications to the model
+    mImpl->mOperationsPending = ALL_OPERATIONS;
   }
   else
   {
     ShowPlaceholderText();
   }
 
+  mImpl->RequestRelayout();
+
   if( mImpl->mEventData )
   {
     // Cancel previously queued events
@@ -285,9 +293,11 @@ void Controller::SetTextColor( const Vector4& textColor )
 {
   mImpl->mTextColor = textColor;
 
-  if( ! mImpl->IsShowingPlaceholderText() )
+  if( !mImpl->IsShowingPlaceholderText() )
   {
     mImpl->mVisualModel->SetTextColor( textColor );
+
+    mImpl->RequestRelayout();
   }
 }
 
@@ -351,6 +361,7 @@ void Controller::SetPlaceholderTextColor( const Vector4& textColor )
   if( mImpl->IsShowingPlaceholderText() )
   {
     mImpl->mVisualModel->SetTextColor( textColor );
+    mImpl->RequestRelayout();
   }
 }
 
@@ -367,6 +378,8 @@ const Vector4& Controller::GetPlaceholderTextColor() const
 void Controller::SetShadowOffset( const Vector2& shadowOffset )
 {
   mImpl->mVisualModel->SetShadowOffset( shadowOffset );
+
+  mImpl->RequestRelayout();
 }
 
 const Vector2& Controller::GetShadowOffset() const
@@ -377,6 +390,8 @@ const Vector2& Controller::GetShadowOffset() const
 void Controller::SetShadowColor( const Vector4& shadowColor )
 {
   mImpl->mVisualModel->SetShadowColor( shadowColor );
+
+  mImpl->RequestRelayout();
 }
 
 const Vector4& Controller::GetShadowColor() const
@@ -387,6 +402,8 @@ const Vector4& Controller::GetShadowColor() const
 void Controller::SetUnderlineColor( const Vector4& color )
 {
   mImpl->mVisualModel->SetUnderlineColor( color );
+
+  mImpl->RequestRelayout();
 }
 
 const Vector4& Controller::GetUnderlineColor() const
@@ -397,6 +414,8 @@ const Vector4& Controller::GetUnderlineColor() const
 void Controller::SetUnderlineEnabled( bool enabled )
 {
   mImpl->mVisualModel->SetUnderlineEnabled( enabled );
+
+  mImpl->RequestRelayout();
 }
 
 bool Controller::IsUnderlineEnabled() const
@@ -407,6 +426,8 @@ bool Controller::IsUnderlineEnabled() const
 void Controller::SetUnderlineHeight( float height )
 {
   mImpl->mVisualModel->SetUnderlineHeight( height );
+
+  mImpl->RequestRelayout();
 }
 
 float Controller::GetUnderlineHeight() const
@@ -847,6 +868,9 @@ bool Controller::DoRelayout( const Size& size,
         }
       } // REORDER
 
+      // TODO: I'm working on a patch that changes the LayoutEngine::Align() method.
+      //       The layoutParameters is not needed and this call can be moved outside the if().
+      //       Then there is no need to do the layout again to change the alignment.
       if( ALIGN & operations )
       {
         mImpl->mLayoutEngine.Align( layoutParameters,
@@ -871,6 +895,86 @@ bool Controller::DoRelayout( const Size& size,
   return viewUpdated;
 }
 
+void Controller::SetMultiLineEnabled( bool enable )
+{
+  const LayoutEngine::Layout layout = enable ? LayoutEngine::MULTI_LINE_BOX : LayoutEngine::SINGLE_LINE_BOX;
+
+  if( layout != mImpl->mLayoutEngine.GetLayout() )
+  {
+    // Set the layout type.
+    mImpl->mLayoutEngine.SetLayout( layout );
+
+    // Set the flags to redo the layout operations
+    const OperationsMask layoutOperations =  static_cast<OperationsMask>( LAYOUT             |
+                                                                          UPDATE_ACTUAL_SIZE |
+                                                                          ALIGN              |
+                                                                          REORDER );
+
+    mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending | layoutOperations );
+
+    mImpl->RequestRelayout();
+  }
+}
+
+bool Controller::IsMultiLineEnabled() const
+{
+  return LayoutEngine::MULTI_LINE_BOX == mImpl->mLayoutEngine.GetLayout();
+}
+
+void Controller::SetHorizontalAlignment( LayoutEngine::HorizontalAlignment alignment )
+{
+  if( alignment != mImpl->mLayoutEngine.GetHorizontalAlignment() )
+  {
+    // Set the alignment.
+    mImpl->mLayoutEngine.SetHorizontalAlignment( alignment );
+
+    // Set the flag to redo the alignment operation.
+    // TODO : Is not needed re-layout and reorder again but with the current implementation it is.
+    //        Im working on a different patch to fix an issue with the alignment. When that patch
+    //        is in, this issue can be fixed.
+    const OperationsMask layoutOperations =  static_cast<OperationsMask>( LAYOUT             |
+                                                                          UPDATE_ACTUAL_SIZE |
+                                                                          ALIGN              |
+                                                                          REORDER );
+
+    mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending | layoutOperations );
+
+    mImpl->RequestRelayout();
+  }
+}
+
+LayoutEngine::HorizontalAlignment Controller::GetHorizontalAlignment() const
+{
+  return mImpl->mLayoutEngine.GetHorizontalAlignment();
+}
+
+void Controller::SetVerticalAlignment( LayoutEngine::VerticalAlignment alignment )
+{
+  if( alignment != mImpl->mLayoutEngine.GetVerticalAlignment() )
+  {
+    // Set the alignment.
+    mImpl->mLayoutEngine.SetVerticalAlignment( alignment );
+
+    // Set the flag to redo the alignment operation.
+    // TODO : Is not needed re-layout and reorder again but with the current implementation it is.
+    //        Im working on a different patch to fix an issue with the alignment. When that patch
+    //        is in, this issue can be fixed.
+    const OperationsMask layoutOperations =  static_cast<OperationsMask>( LAYOUT             |
+                                                                          UPDATE_ACTUAL_SIZE |
+                                                                          ALIGN              |
+                                                                          REORDER );
+
+    mImpl->mOperationsPending = static_cast<OperationsMask>( mImpl->mOperationsPending | layoutOperations );
+
+    mImpl->RequestRelayout();
+  }
+}
+
+LayoutEngine::VerticalAlignment Controller::GetVerticalAlignment() const
+{
+  return mImpl->mLayoutEngine.GetVerticalAlignment();
+}
+
 void Controller::CalculateTextAlignment( const Size& size )
 {
   // Get the direction of the first character.
@@ -1273,6 +1377,69 @@ void Controller::HandleEvent( HandleType handleType, HandleState state, float x,
   }
 }
 
+ImfManager::ImfCallbackData Controller::OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent )
+{
+  bool update( false );
+  bool requestRelayout = false;
+
+  std::string text;
+  unsigned int cursorPosition( 0 );
+
+  switch ( imfEvent.eventName )
+  {
+    case ImfManager::COMMIT:
+    {
+      InsertText( imfEvent.predictiveString, Text::Controller::COMMIT );
+      requestRelayout = true;
+      break;
+    }
+    case ImfManager::PREEDIT:
+    {
+      InsertText( imfEvent.predictiveString, Text::Controller::PRE_EDIT );
+      update = true;
+      requestRelayout = true;
+      break;
+    }
+    case ImfManager::DELETESURROUNDING:
+    {
+      RemoveText( imfEvent.cursorOffset, imfEvent.numberOfChars );
+      requestRelayout = true;
+      break;
+    }
+    case ImfManager::GETSURROUNDING:
+    {
+      GetText( text );
+      cursorPosition = GetLogicalCursorPosition();
+
+      imfManager.SetSurroundingText( text );
+      imfManager.SetCursorPosition( cursorPosition );
+      break;
+    }
+    case ImfManager::VOID:
+    {
+      // do nothing
+      break;
+    }
+  } // end switch
+
+  if( ImfManager::GETSURROUNDING != imfEvent.eventName )
+  {
+    GetText( text );
+    cursorPosition = GetLogicalCursorPosition();
+  }
+
+  if( requestRelayout )
+  {
+    mImpl->mOperationsPending = ALL_OPERATIONS;
+    mImpl->RequestRelayout();
+  }
+
+  ImfManager::ImfCallbackData callbackData( update, cursorPosition, text, false );
+
+  return callbackData;
+}
+
+
 Controller::~Controller()
 {
   delete mImpl;
@@ -1335,6 +1502,8 @@ void Controller::ShowPlaceholderText()
 
     // Apply modifications to the model
     mImpl->mOperationsPending = ALL_OPERATIONS;
+
+    // Update the rest of the model during size negotiation
     mImpl->QueueModifyEvent( ModifyEvent::TEXT_REPLACED );
   }
 }
index 63ec1c3..8a780a9 100644 (file)
@@ -20,6 +20,7 @@
 
 // EXTERNAL INCLUDES
 #include <string>
+#include <dali/devel-api/adaptor-framework/imf-manager.h>
 #include <dali/public-api/common/dali-vector.h>
 #include <dali/public-api/common/intrusive-ptr.h>
 #include <dali/public-api/events/gesture.h>
@@ -31,6 +32,7 @@
 // INTERNAL INCLUDES
 #include <dali-toolkit/internal/text/decorator/text-decorator.h>
 #include <dali-toolkit/internal/text/font-run.h>
+#include <dali-toolkit/internal/text/layouts/layout-engine.h>
 #include <dali-toolkit/internal/text/text-control-interface.h>
 #include <dali-toolkit/internal/text/text-view.h>
 
@@ -405,6 +407,38 @@ public:
                    Size& layoutSize );
 
   /**
+   * @brief Whether to enable the multi-line layout.
+   *
+   * @param[in] enable \e true enables the multi-line (by default)
+   */
+  void SetMultiLineEnabled( bool enable );
+
+  /**
+   * @return Whether the multi-line layout is enabled.
+   */
+  bool IsMultiLineEnabled() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::LayoutEngine::SetHorizontalAlignment()
+   */
+  void SetHorizontalAlignment( LayoutEngine::HorizontalAlignment alignment );
+
+  /**
+   * @copydoc Dali::Toolkit::Text::LayoutEngine::GetHorizontalAlignment()
+   */
+  LayoutEngine::HorizontalAlignment GetHorizontalAlignment() const;
+
+  /**
+   * @copydoc Dali::Toolkit::Text::LayoutEngine::SetVerticalAlignment()
+   */
+  void SetVerticalAlignment( LayoutEngine::VerticalAlignment alignment );
+
+  /**
+   * @copydoc Dali::Toolkit::Text::LayoutEngine::GetVerticalAlignment()
+   */
+  LayoutEngine::VerticalAlignment GetVerticalAlignment() const;
+
+  /**
    * @brief Calulates the alignment of the whole text inside the bounding box.
    *
    * @param[in] size The size of the bounding box.
@@ -474,6 +508,15 @@ public:
    */
   virtual void HandleEvent( HandleType handle, HandleState state, float x, float y );
 
+  /**
+   * @brief Event received from IMF manager
+   *
+   * @param[in] imfManager The IMF manager.
+   * @param[in] imfEvent The event received.
+   * @return A data struture indicating if update is needed, cursor position and current text.
+   */
+  ImfManager::ImfCallbackData OnImfEvent( ImfManager& imfManager, const ImfManager::ImfEventData& imfEvent );
+
 protected:
 
   /**
index f72e8b5..1c7d294 100644 (file)
@@ -734,7 +734,7 @@ bool Control::OnAccessibilityValueChange(bool isIncrease)
   return false; // Accessibility value change action is not handled by default
 }
 
-Actor Control::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
+Actor Control::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
 {
   return Actor();
 }
index ce46319..9deae8f 100644 (file)
@@ -493,7 +493,7 @@ public: // API for derived classes to override
    * @param[in] loopEnabled Whether the focus movement should be looped within the control.
    * @return the next keyboard focusable actor in this control or an empty handle if no actor can be focused.
    */
-  virtual Actor GetNextKeyboardFocusableActor( Actor currentFocusedActor, Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled );
+  virtual Actor GetNextKeyboardFocusableActor( Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled );
 
   /**
    * @brief Informs this control that its chosen focusable actor will be focused.
index 7742bb7..e7511a1 100644 (file)
@@ -94,12 +94,15 @@ public:
   /**
    * @brief Describes the direction to move the keyboard focus towards.
    */
-  enum KeyboardFocusNavigationDirection
+  struct KeyboardFocus
   {
-    Left,   ///< Move keyboard focus towards the left direction
-    Right,  ///< Move keyboard focus towards the right direction
-    Up,     ///< Move keyboard focus towards the up direction
-    Down    ///< Move keyboard focus towards the down direction
+    enum Direction
+    {
+      LEFT,   ///< Move keyboard focus towards the left direction
+      RIGHT,  ///< Move keyboard focus towards the right direction
+      UP,     ///< Move keyboard focus towards the up direction
+      DOWN    ///< Move keyboard focus towards the down direction
+    };
   };
 
   // Typedefs
index 39e09a3..0dc2bb4 100644 (file)
@@ -95,12 +95,12 @@ float ItemLayout::GetClosestOnScreenLayoutPosition(int itemID, float currentLayo
   return currentLayoutPosition;
 }
 
-int ItemLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled)
+int ItemLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
 {
   switch( direction )
   {
-    case Control::Left:
-    case Control::Up:
+    case Control::KeyboardFocus::LEFT:
+    case Control::KeyboardFocus::UP:
     {
       itemID--;
       if( itemID < 0 )
@@ -109,8 +109,8 @@ int ItemLayout::GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Cont
       }
       break;
     }
-    case Control::Right:
-    case Control::Down:
+    case Control::KeyboardFocus::RIGHT:
+    case Control::KeyboardFocus::DOWN:
     {
       itemID++;
       if( itemID >= maxItems )
index 5eda5d4..2ed5f1e 100644 (file)
@@ -304,7 +304,7 @@ public:
    * @param[in] loopEnabled Whether the KeyboardFocusManager is set to wrap around between first and last item
    * @return The next item ID.
    */
-  DALI_IMPORT_API virtual int GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocusNavigationDirection direction, bool loopEnabled);
+  DALI_IMPORT_API virtual int GetNextFocusItemID(int itemID, int maxItems, Dali::Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled);
 
   /**
    * @brief Query the flick speed factor of the layout while swipping.
index 316af96..2e0ffbe 100644 (file)
@@ -60,7 +60,7 @@ Actor KeyboardFocusManager::GetCurrentFocusActor()
   return GetImpl(*this).GetCurrentFocusActor();
 }
 
-bool KeyboardFocusManager::MoveFocus(Control::KeyboardFocusNavigationDirection direction)
+bool KeyboardFocusManager::MoveFocus(Control::KeyboardFocus::Direction direction)
 {
   return GetImpl(*this).MoveFocus(direction);
 }
index 68638a3..6afcd6b 100644 (file)
@@ -55,7 +55,7 @@ class DALI_IMPORT_API KeyboardFocusManager : public BaseHandle
 public:
 
   /// @brief Pre focus change signal
-  typedef Signal< Actor ( Actor, Actor, Control::KeyboardFocusNavigationDirection ) > PreFocusChangeSignalType;
+  typedef Signal< Actor ( Actor, Actor, Control::KeyboardFocus::Direction ) > PreFocusChangeSignalType;
 
   /// @brief Focus changed signal
   typedef Signal< void ( Actor, Actor ) > FocusChangedSignalType;
@@ -117,7 +117,7 @@ public:
    * @param direction The direction of focus movement
    * @return true if the movement was successful
    */
-  bool MoveFocus(Control::KeyboardFocusNavigationDirection direction);
+  bool MoveFocus(Control::KeyboardFocus::Direction direction);
 
   /**
    * @brief Clear the focus from the current focused actor if any, so
@@ -214,7 +214,7 @@ public: // Signals
    *
    * A callback of the following type may be connected:
    * @code
-   *   Actor YourCallbackName(Actor currentFocusedActor, Actor proposedActorToFocus, Control::KeyboardFocusNavigationDirection direction);
+   *   Actor YourCallbackName(Actor currentFocusedActor, Actor proposedActorToFocus, Control::KeyboardFocus::Direction direction);
    * @endcode
    * @pre The Object has been initialized.
    * @return The signal to connect to.
diff --git a/docs/content/figures/image-scaling/cards.jpg b/docs/content/figures/image-scaling/cards.jpg
new file mode 100644 (file)
index 0000000..9af5d02
Binary files /dev/null and b/docs/content/figures/image-scaling/cards.jpg differ
diff --git a/docs/content/figures/image-scaling/concept-rectangles.svg b/docs/content/figures/image-scaling/concept-rectangles.svg
new file mode 100644 (file)
index 0000000..0b4cebc
--- /dev/null
@@ -0,0 +1,909 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1052.3622"
+   height="744.09448"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.3.1 r9886"
+   sodipodi:docname="concept-rectangles.svg"
+   inkscape:export-filename="/tmp/page.png"
+   inkscape:export-xdpi="89.269394"
+   inkscape:export-ydpi="89.269394">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="DotL"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="DotL"
+       style="overflow:visible">
+      <path
+         id="path4335"
+         d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
+         transform="scale(0.8) translate(7.4, 1)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow2Mend"
+       style="overflow:visible;">
+      <path
+         id="path4301"
+         style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
+         d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+         transform="scale(0.6) rotate(180) translate(0,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Lend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow2Lend"
+       style="overflow:visible;">
+      <path
+         id="path4295"
+         style="fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
+         d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+         transform="scale(1.1) rotate(180) translate(1,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Lend"
+       style="overflow:visible;">
+      <path
+         id="path4277"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;"
+         transform="scale(0.8) rotate(180) translate(12.5,0)" />
+    </marker>
+    <linearGradient
+       id="linearGradient5404"
+       osb:paint="gradient">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop5406" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop5408" />
+    </linearGradient>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-0"
+       style="overflow:visible">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4301-1"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-1"
+       style="overflow:visible">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4301-7"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-2"
+       style="overflow:visible">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4301-75"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-08"
+       style="overflow:visible">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4301-71"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-5"
+       style="overflow:visible">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4301-6"
+         style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6,-0.6)" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="1"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.45254834"
+     inkscape:cx="743.41974"
+     inkscape:cy="837.71772"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:window-width="1920"
+     inkscape:window-height="1158"
+     inkscape:window-x="1200"
+     inkscape:window-y="418"
+     inkscape:window-maximized="1"
+     objecttolerance="4"
+     gridtolerance="4">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3181"
+       empspacing="4"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       spacingx="32px"
+       spacingy="32px" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-308.2677)">
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/image-scaling/cards.jpg"
+       xlink:href="cards.jpg"
+       y="-387.63782"
+       x="160"
+       id="image4157"
+       height="256"
+       width="256"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-30"
+       width="128"
+       height="192.00003"
+       x="128"
+       y="636.36212"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-30-3"
+       width="1.0498172e-05"
+       height="192"
+       x="191.99998"
+       y="188.36218"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:3.63730645;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-30-0"
+       width="96.000015"
+       height="1.7800441e-05"
+       x="143.99998"
+       y="508.36218"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-30-31"
+       width="192"
+       height="192"
+       x="512"
+       y="188.36212"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:3.14999795;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-30-34"
+       width="95.999939"
+       height="95.999954"
+       x="560"
+       y="460.36221"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-30-4"
+       width="128"
+       height="192.00003"
+       x="544"
+       y="636.36212"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4.27617979;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
+       d="m 224,284.36215 c 256,0 256,0 256,0"
+       id="path4268"
+       inkscape:connector-curvature="0"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
+       d="m 288,732.36221 c 224,0 224,0 224,0"
+       id="path4268-0"
+       inkscape:connector-curvature="0"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
+       d="m 280.67645,508.36215 c 224,0 247.40075,3e-5 247.40075,3e-5"
+       id="path4268-4"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4.19999981;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-mid:none;marker-end:none"
+       d="m 352,-99.6378 c 0,159.99998 0,383.99998 0,383.99998"
+       id="path5307"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4.19999981;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-mid:url(#DotL)"
+       d="m 320,-99.6378 0,607.99998"
+       id="path5879"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
+       d="m 688.3995,508.36218 c 224,0 239.6005,0 239.6005,0"
+       id="path4268-4-4"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4.19999981;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 704,732.36218 96,0 0,-224"
+       id="path6099"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccc"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4.19999981;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 736,284.36218 64,0 0,224 0,0 0,0"
+       id="path6101"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-30-4-1"
+       width="96"
+       height="96"
+       x="960"
+       y="460.32184"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-30-31-3"
+       width="256"
+       height="256"
+       x="160"
+       y="-387.63782"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4.19999981;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 864,508.36218 c 0,-511.9999802 0,-735.99998 0,-735.99998 l -416,0"
+       id="path6157"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccc"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/image-scaling/cards.jpg"
+       xlink:href="cards.jpg"
+       y="636.36243"
+       x="1423.9999"
+       id="image4157-4-5"
+       height="96.000244"
+       width="96.000244"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4.19999981;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
+       d="m 1088,508.36218 c 72.8302,0 192,0 192,0"
+       id="path4268-4-4-9"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot6201"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(128,1044.2677)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion6203"><rect
+           id="rect6205"
+           width="132.37465"
+           height="33.093662"
+           x="1085.7874"
+           y="-436.24619" /></flowRegion><flowPara
+         id="flowPara6207" /></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot6415"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(128,1044.2677)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion6417"><rect
+           id="rect6419"
+           width="129.22287"
+           height="96.129211"
+           x="-3.1517775"
+           y="-119.49255" /></flowRegion><flowPara
+         id="flowPara6421" /></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot6423"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(128,1044.2677)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion6425"><rect
+           id="rect6427"
+           width="129.22287"
+           height="111.8881"
+           x="0"
+           y="-117.91666" /></flowRegion><flowPara
+         id="flowPara6429"
+         style="font-weight:normal">Requested Size</flowPara></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot6431"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(-44.87499,5.9402098)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion6433"><rect
+           id="rect6435"
+           width="168.25861"
+           height="49.914528"
+           x="193.83432"
+           y="-119.49255" /></flowRegion><flowPara
+         id="flowPara6437">Raw size (e.)</flowPara></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot6439"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(128,1044.2677)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion6441"><rect
+           id="rect6443"
+           width="256"
+           height="89.944725"
+           x="352"
+           y="-119.90552"
+           ry="0" /></flowRegion><flowPara
+         id="flowPara6445">Target for fitting</flowPara></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot6447"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(114.89062,696.48284)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion6449"><rect
+           id="rect6451"
+           width="130.3277"
+           height="34.676437"
+           x="830.49335"
+           y="-116.34077" /></flowRegion><flowPara
+         id="flowPara6453">Fitted Size</flowPara></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot6455"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(285.45703,886.12794)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion6457"><rect
+           id="rect6459"
+           width="192"
+           height="52.511868"
+           x="1090.3438"
+           y="-113.69655" /></flowRegion><flowPara
+         id="flowPara6461">Scaled Pixels</flowPara></flowRoot>    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:6.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-30-3-0"
+       width="1.4271966"
+       height="8.0063074e-11"
+       x="192"
+       y="-3.6378176"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-30-31-3-4"
+       width="256"
+       height="256"
+       x="480"
+       y="-131.63782"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:none;stroke:#000000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.35555581;stroke-dasharray:4.19999981, 12.59999943;stroke-dashoffset:0"
+       id="rect6501-6"
+       width="320"
+       height="1184"
+       x="448"
+       y="-163.63782"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:none;stroke:#000000;stroke-width:4.2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.35555581000000003;stroke-dasharray:4.2,12.6;stroke-dashoffset:0"
+       id="rect6501"
+       width="192"
+       height="1024"
+       x="96"
+       y="-35.637817"
+       ry="0"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot6521"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(128,1044.2677)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion6523"><rect
+           id="rect6525"
+           width="16.714825"
+           height="34.543972"
+           x="603.96234"
+           y="-92.761055" /></flowRegion><flowPara
+         id="flowPara6527" /></flowRoot>    <path
+       style="fill:none;stroke:#000000;stroke-width:4.27617979;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-end:url(#Arrow2Mend)"
+       d="m 224,-3.6378202 c 192,0 199.26801,0 199.26801,0"
+       id="path4268-1"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4.19999981;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-mid:none;marker-end:none"
+       d="m 384,-99.63782 c 0,95.9999998 0,95.9999998 0,95.9999998"
+       id="path5307-3"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4.19999981;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 800,284.36218 c 0,-287.9999802 0,-287.9999802 0,-287.9999802 l -32,0"
+       id="path6571"
+       inkscape:connector-curvature="0"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#000000;stroke-width:4.19999981;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-mid:none;marker-end:none"
+       d="m 448,-291.6378 c 832,0 736,-2e-5 736,-2e-5 l 0,800"
+       id="path6573"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccc"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/image-scaling/cards.jpg"
+       xlink:href="cards.jpg"
+       y="444.36243"
+       x="1407.9999"
+       id="image4157-0"
+       height="128.00024"
+       width="128.00024"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/image-scaling/cards.jpg"
+       xlink:href="cards.jpg"
+       y="124.36218"
+       x="1344"
+       id="image4157-4"
+       height="256"
+       width="256"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot7007"
+       style="fill:black;stroke:none;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;fill-opacity:1;font-family:Sans;font-style:normal;font-weight:normal;font-size:24px;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;text-align:center"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion7009"><rect
+           id="rect7011"
+           width="14.182999"
+           height="64.611435"
+           x="1279.6217"
+           y="594.38507" /></flowRegion><flowPara
+         id="flowPara7013" /></flowRoot>    <rect
+       style="fill:none;stroke:#000000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.35555581;stroke-dasharray:4.2, 12.6;stroke-dashoffset:0"
+       id="rect6501-6-0"
+       width="320"
+       height="736.00024"
+       x="1312"
+       y="92.362183"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot7035"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(-34.212099,300.28395)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion7037"><rect
+           id="rect7039"
+           width="128.02527"
+           height="133.95055"
+           x="1151.9747"
+           y="361.1535" /></flowRegion><flowPara
+         id="flowPara7041">SamplingMode</flowPara></flowRoot>    <path
+       style="fill:none;stroke:#000000;stroke-width:4.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+       d="m 1184,328.09448 c 0,-128 0,-128 0,-128"
+       id="path7439"
+       inkscape:connector-curvature="0"
+       transform="translate(0,308.2677)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot7035-9"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(-351.98437,301.85984)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion7037-2"><rect
+           id="rect7039-7"
+           width="128.02527"
+           height="133.95055"
+           x="1151.9747"
+           y="361.1535" /></flowRegion><flowPara
+         id="flowPara7041-2">Fitting Mode</flowPara></flowRoot>    <path
+       style="fill:none;stroke:#000000;stroke-width:4.19999981;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       d="m 864,636.36218 c 0,-128 0,-128 0,-128"
+       id="path7439-2"
+       inkscape:connector-curvature="0"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:none;stroke:#000000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.35555576;stroke-dasharray:none;stroke-dashoffset:0"
+       id="rect7524"
+       width="88.249771"
+       height="73.972183"
+       x="821.03802"
+       y="350.12228"
+       transform="translate(0,308.2677)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"
+       ry="20.057787" />
+    <rect
+       style="fill:none;stroke:#000000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.3555557;stroke-dasharray:none;stroke-dashoffset:0"
+       id="rect7526"
+       width="128"
+       height="77.123962"
+       x="1120"
+       y="346.97052"
+       transform="translate(0,308.2677)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"
+       ry="23.400755" />
+    <text
+       xml:space="preserve"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="1482.6659"
+       y="403.63452"
+       id="text7530"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><tspan
+         sodipodi:role="line"
+         id="tspan7532"
+         x="1482.6659"
+         y="403.63452">k.</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="1472"
+       y="604.36218"
+       id="text7534"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><tspan
+         sodipodi:role="line"
+         id="tspan7536"
+         x="1472"
+         y="604.36218">l.</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="1472"
+       y="753.48798"
+       id="text7538"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><tspan
+         sodipodi:role="line"
+         id="tspan7540"
+         x="1472"
+         y="753.48798">m.</tspan></text>
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:none"
+       id="path7542"
+       sodipodi:cx="1424"
+       sodipodi:cy="-327.90552"
+       sodipodi:rx="16"
+       sodipodi:ry="16"
+       d="m 1440,-327.90552 c 0,8.83656 -7.1634,16 -16,16 -8.8366,0 -16,-7.16344 -16,-16 0,-8.83655 7.1634,-16 16,-16 8.8366,0 16,7.16345 16,16 z"
+       transform="matrix(0.5,0,0,0.5,472,672.43994)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:none"
+       id="path7542-2"
+       sodipodi:cx="1424"
+       sodipodi:cy="-327.90552"
+       sodipodi:rx="16"
+       sodipodi:ry="16"
+       d="m 1440,-327.90552 c 0,8.83656 -7.1634,16 -16,16 -8.8366,0 -16,-7.16344 -16,-16 0,-8.83655 7.1634,-16 16,-16 8.8366,0 16,7.16345 16,16 z"
+       transform="matrix(0.5,0,0,0.5,152,672.43994)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#000000;fill-opacity:1;stroke:none"
+       id="path7542-1"
+       sodipodi:cx="1424"
+       sodipodi:cy="-327.90552"
+       sodipodi:rx="16"
+       sodipodi:ry="16"
+       d="m 1440,-327.90552 c 0,8.83656 -7.1634,16 -16,16 -8.8366,0 -16,-7.16344 -16,-16 0,-8.83655 7.1634,-16 16,-16 8.8366,0 16,7.16345 16,16 z"
+       transform="matrix(0.5,0,0,0.5,88,672.51025)"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <text
+       xml:space="preserve"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="192"
+       y="34.160557"
+       id="text7530-8"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><tspan
+         sodipodi:role="line"
+         id="tspan7532-7"
+         x="192"
+         y="34.160557">a.</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="192"
+       y="414.78287"
+       id="text7530-8-1"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><tspan
+         sodipodi:role="line"
+         id="tspan7532-7-2"
+         x="192"
+         y="414.78287">b.</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="192"
+       y="546.16058"
+       id="text7530-8-6"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><tspan
+         sodipodi:role="line"
+         id="tspan7532-7-9"
+         x="192"
+         y="546.16058">c.</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="192"
+       y="866.16058"
+       id="text7530-8-7"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><tspan
+         sodipodi:role="line"
+         id="tspan7532-7-4"
+         x="192"
+         y="866.16058">d.</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="608"
+       y="162.16058"
+       id="text7530-8-3"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><tspan
+         sodipodi:role="line"
+         id="tspan7532-7-6"
+         x="608"
+         y="162.16058">f.</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="608"
+       y="418.16058"
+       id="text7530-8-33"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><tspan
+         sodipodi:role="line"
+         id="tspan7532-7-48"
+         x="608"
+         y="418.16058">g.</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="608"
+       y="596.53143"
+       id="text7530-8-0"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><tspan
+         sodipodi:role="line"
+         id="tspan7532-7-0"
+         x="608"
+         y="596.53143">h.</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="608"
+       y="866.16058"
+       id="text7530-8-68"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><tspan
+         sodipodi:role="line"
+         id="tspan7532-7-66"
+         x="608"
+         y="866.16058">i.</tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="1003.7878"
+       y="632.43921"
+       id="text7530-8-2"
+       sodipodi:linespacing="125%"
+       inkscape:export-filename="/tmp/concept-rectangles.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><tspan
+         sodipodi:role="line"
+         id="tspan7532-7-68"
+         x="1003.7878"
+         y="632.43921">j.</tspan></text>
+  </g>
+</svg>
diff --git a/docs/content/figures/image-scaling/dog.jpg b/docs/content/figures/image-scaling/dog.jpg
new file mode 100644 (file)
index 0000000..f7d2cc4
Binary files /dev/null and b/docs/content/figures/image-scaling/dog.jpg differ
diff --git a/docs/content/figures/image-scaling/door.jpg b/docs/content/figures/image-scaling/door.jpg
new file mode 100644 (file)
index 0000000..7317ea5
Binary files /dev/null and b/docs/content/figures/image-scaling/door.jpg differ
diff --git a/docs/content/figures/image-scaling/example-fitting-mode-options.svg b/docs/content/figures/image-scaling/example-fitting-mode-options.svg
new file mode 100644 (file)
index 0000000..f64443b
--- /dev/null
@@ -0,0 +1,547 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1052.3622"
+   height="744.09448"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.3.1 r9886"
+   sodipodi:docname="example-fitting-mode-options.svg"
+   inkscape:export-filename="/tmp/1.png"
+   inkscape:export-xdpi="89.269394"
+   inkscape:export-ydpi="89.269394">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient5404"
+       osb:paint="gradient">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop5406" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop5408" />
+    </linearGradient>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="1"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.63456256"
+     inkscape:cx="704.49723"
+     inkscape:cy="501.75416"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:window-width="1920"
+     inkscape:window-height="1158"
+     inkscape:window-x="1200"
+     inkscape:window-y="418"
+     inkscape:window-maximized="1"
+     objecttolerance="4"
+     gridtolerance="4">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3181"
+       empspacing="4"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       spacingx="32px"
+       spacingy="32px" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-308.2677)">
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/door.jpg"
+       xlink:href="door.jpg"
+       inkscape:export-ydpi="89.269394"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       width="256"
+       height="256"
+       id="image6106"
+       x="32"
+       y="92.362183" />
+    <g
+       id="g6199"
+       transform="matrix(0.75,0,0,0.75,158.83024,-448.90946)"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394">
+      <image
+         sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/door.jpg"
+         xlink:href="door.jpg"
+         inkscape:export-ydpi="89.269394"
+         inkscape:export-xdpi="89.269394"
+         inkscape:export-filename="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/shared-javascript-and-cpp-documentation/door-scale-to-fill2.png"
+         y="764.36218"
+         x="512"
+         id="image6106-0"
+         height="256"
+         width="256" />
+      <rect
+         y="764.36218"
+         x="719.81006"
+         height="258.6265"
+         width="51.309372"
+         id="rect6179"
+         style="fill:#ffffff;fill-opacity:1;stroke:none"
+         inkscape:export-filename="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/shared-javascript-and-cpp-documentation/door-scale-to-fill.png"
+         inkscape:export-xdpi="89.269394"
+         inkscape:export-ydpi="89.269394" />
+      <rect
+         y="764.36218"
+         x="512"
+         height="259.15176"
+         width="48.189934"
+         id="rect6179-2"
+         style="fill:#ffffff;fill-opacity:1;stroke:none"
+         inkscape:export-filename="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/shared-javascript-and-cpp-documentation/door-scale-to-fill.png"
+         inkscape:export-xdpi="89.269394"
+         inkscape:export-ydpi="89.269394" />
+      <rect
+         inkscape:export-ydpi="89.269394"
+         inkscape:export-xdpi="89.269394"
+         inkscape:export-filename="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/shared-javascript-and-cpp-documentation/door-scale-to-fill2.png"
+         y="764.36218"
+         x="560"
+         height="256.00003"
+         width="160"
+         id="rect3183-1-9-1-6"
+         style="fill:none;stroke:#ff0000;stroke-width:4.28426027;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+    </g>
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:3.21319532;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1"
+       width="120"
+       height="192.00003"
+       x="356"
+       y="124.36218"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/door.jpg"
+       xlink:href="door.jpg"
+       inkscape:export-ydpi="89.269394"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       width="120"
+       height="135.85014"
+       id="image6106-5"
+       x="804"
+       y="152.43707" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:3.21319532;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-4"
+       width="120"
+       height="192.00003"
+       x="804"
+       y="124.36212"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/door.jpg"
+       xlink:href="door.jpg"
+       inkscape:export-ydpi="89.269394"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       width="120"
+       height="135.85014"
+       id="image6106-5-3"
+       x="1030.3395"
+       y="152.43707" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:3.21319532;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-4-1"
+       width="120"
+       height="192.00003"
+       x="1030.3395"
+       y="124.36212"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/door.jpg"
+       xlink:href="door.jpg"
+       inkscape:export-ydpi="89.269394"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       width="192"
+       height="192"
+       id="image6106-4"
+       x="1218.3396"
+       y="124.36218" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:3.21319532;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-3"
+       width="120"
+       height="192.00003"
+       x="1254.3396"
+       y="124.36218"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/dog.jpg"
+       xlink:href="dog.jpg"
+       inkscape:export-ydpi="89.269394"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       width="256"
+       height="256"
+       id="image6359"
+       x="32"
+       y="412.36218" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:3.31857371;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-0"
+       width="128.00003"
+       height="192"
+       x="-604.36218"
+       y="320"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"
+       transform="matrix(0,-1,1,0,0,0)" />
+    <g
+       id="g6476"
+       transform="translate(-7.128906e-7,-384.82965)"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394">
+      <image
+         sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/dog.jpg"
+         xlink:href="dog.jpg"
+         y="829.19183"
+         x="544"
+         id="image6359-2"
+         height="192"
+         width="192" />
+      <rect
+         transform="translate(0,308.2677)"
+         y="520.09448"
+         x="544"
+         height="32"
+         width="192"
+         id="rect6470"
+         style="fill:#ffffff;fill-opacity:1;stroke:none" />
+      <rect
+         transform="translate(0,308.2677)"
+         y="680.09448"
+         x="541.66046"
+         height="33.94965"
+         width="196.67912"
+         id="rect6474"
+         style="fill:#ffffff;fill-opacity:1;stroke:none" />
+      <rect
+         transform="matrix(0,-1,1,0,0,0)"
+         inkscape:export-ydpi="89.269394"
+         inkscape:export-xdpi="89.269394"
+         inkscape:export-filename="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/shared-javascript-and-cpp-documentation/example-scale-to-fill-sequence.png"
+         y="544"
+         x="-989.19183"
+         height="192"
+         width="128.00003"
+         id="rect3183-1-9-1-0-2"
+         style="fill:none;stroke:#ff0000;stroke-width:3.31857371;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+    </g>
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/dog.jpg"
+       xlink:href="dog.jpg"
+       inkscape:export-ydpi="89.269394"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       width="192"
+       height="192"
+       id="image6359-2-2"
+       x="994.33954"
+       y="445.19183" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:3.31857371;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-0-4"
+       width="128.00003"
+       height="192"
+       x="-605.19183"
+       y="994.33954"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"
+       transform="matrix(0,-1,1,0,0,0)" />
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/dog.jpg"
+       xlink:href="dog.jpg"
+       inkscape:export-ydpi="89.269394"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       width="128"
+       height="128"
+       id="image6359-2-2-2"
+       x="1250.3396"
+       y="477.19183" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:3.31857371;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-0-0"
+       width="128.00003"
+       height="192"
+       x="-605.19183"
+       y="1218.3396"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"
+       transform="matrix(0,-1,1,0,0,0)" />
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/dog.jpg"
+       xlink:href="dog.jpg"
+       inkscape:export-ydpi="89.269394"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       width="128"
+       height="128"
+       id="image6359-2-2-2-1"
+       x="800"
+       y="476.36218" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:3.31857371;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9-1-0-0-6"
+       width="128.00003"
+       height="192"
+       x="-604.36218"
+       y="768"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"
+       transform="matrix(0,-1,1,0,0,0)" />
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot3024"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(0,244.2677)"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion3026"><rect
+           id="rect3028"
+           width="256.29398"
+           height="127.03266"
+           x="33.429649"
+           y="746.32312" /></flowRegion><flowPara
+         id="flowPara3030">Raw Image</flowPara></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot3032"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(0,244.2677)"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion3034"><rect
+           id="rect3036"
+           width="192.25842"
+           height="96.91716"
+           x="318.32953"
+           y="744.09448" /></flowRegion><flowPara
+         id="flowPara3038">Fitting Target</flowPara></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot3040"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(0,244.2677)"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion3042"><rect
+           id="rect3044"
+           width="192.25842"
+           height="91.40155"
+           x="542.89368"
+           y="744.88245" /></flowRegion><flowPara
+         id="flowPara3046">SCALE_TO_FILL</flowPara></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot3048"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(0,244.2677)"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion3050"><rect
+           id="rect3052"
+           width="193.83432"
+           height="96.91716"
+           x="767.45782"
+           y="744.09448" /></flowRegion><flowPara
+         id="flowPara3054">SHRINK_TO_FIT</flowPara></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot3056"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(0,244.2677)"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion3058"><rect
+           id="rect3060"
+           width="193.83432"
+           height="126.85905"
+           x="990.44611"
+           y="745.67035" /></flowRegion><flowPara
+         id="flowPara3062">FIT_WIDTH</flowPara></flowRoot>    <flowRoot
+       xml:space="preserve"
+       id="flowRoot3064"
+       style="font-size:24px;font-style:normal;font-weight:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       transform="translate(0,244.2677)"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394"><flowRegion
+         id="flowRegion3066"><rect
+           id="rect3068"
+           width="193.04637"
+           height="100.06894"
+           x="1215.7982"
+           y="744.88245" /></flowRegion><flowPara
+         id="flowPara3070">FIT_HEIGHT</flowPara></flowRoot>    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/liberty.jpg"
+       xlink:href="liberty.jpg"
+       inkscape:export-ydpi="89.269394"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       width="256"
+       height="256"
+       id="image3239"
+       x="32"
+       y="700.36218" />
+    <g
+       id="g4034"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394">
+      <rect
+         y="764.36218"
+         x="352"
+         height="128"
+         width="128"
+         id="rect3244"
+         style="fill:none;stroke:#ff0000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         inkscape:export-filename="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/shared-javascript-and-cpp-documentation/fitting-mode-options.png"
+         inkscape:export-xdpi="89.269394"
+         inkscape:export-ydpi="89.269394" />
+    </g>
+    <g
+       transform="translate(224,-1.9531262e-7)"
+       id="g4034-5"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394">
+      <image
+         sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/liberty.jpg"
+         xlink:href="liberty.jpg"
+         y="764.36218"
+         x="352"
+         id="image3239-9-8"
+         height="128"
+         width="128" />
+      <rect
+         y="764.36218"
+         x="352"
+         height="128"
+         width="128"
+         id="rect3244-5"
+         style="fill:none;stroke:#ff0000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+    </g>
+    <g
+       transform="translate(448,-1.9531262e-7)"
+       id="g4034-4"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394">
+      <image
+         sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/liberty.jpg"
+         xlink:href="liberty.jpg"
+         y="764.36218"
+         x="352"
+         id="image3239-9-88"
+         height="128"
+         width="128" />
+      <rect
+         y="764.36218"
+         x="352"
+         height="128"
+         width="128"
+         id="rect3244-9"
+         style="fill:none;stroke:#ff0000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+    </g>
+    <g
+       transform="translate(672,-1.9531262e-7)"
+       id="g4034-3"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394">
+      <image
+         sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/liberty.jpg"
+         xlink:href="liberty.jpg"
+         y="764.36218"
+         x="352"
+         id="image3239-9-85"
+         height="128"
+         width="128" />
+      <rect
+         y="764.36218"
+         x="352"
+         height="128"
+         width="128"
+         id="rect3244-8"
+         style="fill:none;stroke:#ff0000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+    </g>
+    <g
+       transform="translate(896,-1.9531262e-7)"
+       id="g4034-2"
+       inkscape:export-filename="/tmp/fitting-mode-options.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394">
+      <image
+         sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/liberty.jpg"
+         xlink:href="liberty.jpg"
+         y="764.36218"
+         x="352"
+         id="image3239-9-7"
+         height="128"
+         width="128" />
+      <rect
+         y="764.36218"
+         x="352"
+         height="128"
+         width="128"
+         id="rect3244-95"
+         style="fill:none;stroke:#ff0000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+    </g>
+  </g>
+</svg>
diff --git a/docs/content/figures/image-scaling/example-scale-to-fill-problem.svg b/docs/content/figures/image-scaling/example-scale-to-fill-problem.svg
new file mode 100644 (file)
index 0000000..fcdde97
--- /dev/null
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1052.3622"
+   height="744.09448"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.3.1 r9886"
+   sodipodi:docname="example-scale-to-fill-problem.svg"
+   inkscape:export-filename="/tmp/example-scale-to-fill-sequence.png"
+   inkscape:export-xdpi="89.269394"
+   inkscape:export-ydpi="89.269394">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient5404"
+       osb:paint="gradient">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop5406" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop5408" />
+    </linearGradient>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.94173904"
+     inkscape:cx="330.62812"
+     inkscape:cy="291.60912"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:window-width="1920"
+     inkscape:window-height="1158"
+     inkscape:window-x="1200"
+     inkscape:window-y="418"
+     inkscape:window-maximized="1"
+     objecttolerance="4"
+     gridtolerance="4">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3181"
+       empspacing="4"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       spacingx="32px"
+       spacingy="32px" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-308.2677)">
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/phone.png"
+       xlink:href="phone.png"
+       inkscape:export-ydpi="89.269394"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-filename="/tmp/image3087.png"
+       width="187"
+       height="348"
+       id="image3087"
+       x="736"
+       y="608.36218" />
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/gallery-large-12.jpg"
+       xlink:href="gallery-large-12.jpg"
+       inkscape:export-ydpi="89.269394"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-filename="/tmp/image3087.png"
+       width="512"
+       height="512"
+       id="image3178"
+       x="32"
+       y="508.36218" />
+    <rect
+       style="fill:#ffffff;fill-opacity:1;stroke-width:4.19999980999999956;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke:#ff0000;stroke-opacity:1"
+       id="rect3183"
+       width="154.95831"
+       height="254.03409"
+       x="753.73383"
+       y="347.32999"
+       transform="translate(0,308.2677)"
+       inkscape:export-filename="/tmp/image3087.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:none;fill-opacity:1;stroke:#ff0000;stroke-width:4.19999980999999956;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3957"
+       width="512"
+       height="512"
+       x="32"
+       y="200.09448"
+       transform="translate(0,308.2677)"
+       ry="0"
+       inkscape:export-filename="/tmp/image3087.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#ff0000;stroke-width:4.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+       d="M 554.87974,200.09448 C 736,345.39199 736,346.14284 736,346.14284"
+       id="path5414"
+       inkscape:connector-curvature="0"
+       transform="translate(0,308.2677)"
+       inkscape:export-filename="/tmp/image3087.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <path
+       style="fill:none;stroke:#ff0000;stroke-width:4.20000000000000018;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+       d="M 553.37804,712.09448 C 736,604.43598 736,604.43598 736,604.43598"
+       id="path5416"
+       inkscape:connector-curvature="0"
+       transform="translate(0,308.2677)"
+       inkscape:export-filename="/tmp/image3087.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+  </g>
+</svg>
diff --git a/docs/content/figures/image-scaling/example-scale-to-fill-sequence.svg b/docs/content/figures/image-scaling/example-scale-to-fill-sequence.svg
new file mode 100644 (file)
index 0000000..12d0eec
--- /dev/null
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="1052.3622"
+   height="744.09448"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.3.1 r9886"
+   sodipodi:docname="example-scale-to-fill-sequence.svg"
+   inkscape:export-filename="/tmp/example-scale-to-fill-problem.png"
+   inkscape:export-xdpi="89.269394"
+   inkscape:export-ydpi="89.269394">
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient5404"
+       osb:paint="gradient">
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="0"
+         id="stop5406" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:0;"
+         offset="1"
+         id="stop5408" />
+    </linearGradient>
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.94173902"
+     inkscape:cx="676.6218"
+     inkscape:cy="430.48889"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:window-width="1920"
+     inkscape:window-height="1158"
+     inkscape:window-x="1200"
+     inkscape:window-y="418"
+     inkscape:window-maximized="1"
+     objecttolerance="4"
+     gridtolerance="4">
+    <inkscape:grid
+       type="xygrid"
+       id="grid3181"
+       empspacing="4"
+       visible="true"
+       enabled="true"
+       snapvisiblegridlinesonly="true"
+       spacingx="32px"
+       spacingy="32px" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-308.2677)">
+    <rect
+       style="fill:none;fill-opacity:1;stroke:#ff0000;stroke-width:4.19999980999999956;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3957"
+       width="512"
+       height="512"
+       x="32"
+       y="200.09448"
+       transform="translate(0,308.2677)"
+       ry="0"
+       inkscape:export-filename="/tmp/rect3957.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/gallery-large-12.jpg"
+       xlink:href="gallery-large-12.jpg"
+       inkscape:export-ydpi="89.269394"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-filename="/tmp/rect3957.png"
+       width="512"
+       height="512"
+       id="image3178"
+       x="32"
+       y="508.36218" />
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/gallery-large-12.jpg"
+       xlink:href="gallery-large-12.jpg"
+       inkscape:export-ydpi="89.269394"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-filename="/tmp/rect3957.png"
+       width="256"
+       height="256"
+       id="image3178-6"
+       x="640"
+       y="636.36218" />
+    <rect
+       style="fill:none;stroke:#ff0000;stroke-width:4.19999981;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect5513"
+       width="256"
+       height="256"
+       x="640"
+       y="636.36218"
+       inkscape:export-filename="/tmp/rect3957.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <image
+       sodipodi:absref="/home/SERILOCAL/andrew.cox/git/opendali-features/dali-toolkit/docs/content/figures/gallery-large-12.jpg"
+       xlink:href="gallery-large-12.jpg"
+       inkscape:export-ydpi="89.269394"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-filename="/tmp/rect3957.png"
+       width="256"
+       height="256"
+       id="image3178-6-5"
+       x="992"
+       y="636.36218" />
+    <rect
+       style="fill:#000000;fill-opacity:0.74666664;stroke:none"
+       id="rect5554"
+       width="50.182735"
+       height="256"
+       x="992"
+       y="328.09448"
+       transform="translate(0,308.2677)"
+       inkscape:export-filename="/tmp/rect3957.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:#000000;fill-opacity:0.74666628;stroke:none"
+       id="rect5554-1"
+       width="50.182735"
+       height="256"
+       x="1197.8173"
+       y="636.36218"
+       inkscape:export-filename="/tmp/rect3957.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+    <rect
+       style="fill:none;fill-opacity:1;stroke:#ff0000;stroke-width:4.19999980999999956;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+       id="rect3183-1-9"
+       width="154.95831"
+       height="254.03409"
+       x="1043.3221"
+       y="637.48846"
+       inkscape:export-filename="/tmp/rect3957.png"
+       inkscape:export-xdpi="89.269394"
+       inkscape:export-ydpi="89.269394" />
+  </g>
+</svg>
diff --git a/docs/content/figures/image-scaling/gallery-large-12.jpg b/docs/content/figures/image-scaling/gallery-large-12.jpg
new file mode 100644 (file)
index 0000000..7173b85
Binary files /dev/null and b/docs/content/figures/image-scaling/gallery-large-12.jpg differ
diff --git a/docs/content/figures/image-scaling/liberty.jpg b/docs/content/figures/image-scaling/liberty.jpg
new file mode 100644 (file)
index 0000000..e42dba7
Binary files /dev/null and b/docs/content/figures/image-scaling/liberty.jpg differ
diff --git a/docs/content/figures/image-scaling/phone-transparent-screen.png b/docs/content/figures/image-scaling/phone-transparent-screen.png
new file mode 100644 (file)
index 0000000..e8a988b
Binary files /dev/null and b/docs/content/figures/image-scaling/phone-transparent-screen.png differ
diff --git a/docs/content/figures/image-scaling/phone.png b/docs/content/figures/image-scaling/phone.png
new file mode 100644 (file)
index 0000000..250b881
Binary files /dev/null and b/docs/content/figures/image-scaling/phone.png differ
diff --git a/docs/content/images/image-scaling/concept-rectangles.jpg b/docs/content/images/image-scaling/concept-rectangles.jpg
new file mode 100644 (file)
index 0000000..edd6eca
Binary files /dev/null and b/docs/content/images/image-scaling/concept-rectangles.jpg differ
diff --git a/docs/content/images/image-scaling/demo-fitting-sampling.jpg b/docs/content/images/image-scaling/demo-fitting-sampling.jpg
new file mode 100644 (file)
index 0000000..5d07fcd
Binary files /dev/null and b/docs/content/images/image-scaling/demo-fitting-sampling.jpg differ
diff --git a/docs/content/images/image-scaling/demo-sampling-modes.jpg b/docs/content/images/image-scaling/demo-sampling-modes.jpg
new file mode 100644 (file)
index 0000000..ffe94a8
Binary files /dev/null and b/docs/content/images/image-scaling/demo-sampling-modes.jpg differ
diff --git a/docs/content/images/image-scaling/example-scale-to-fill-problem.jpg b/docs/content/images/image-scaling/example-scale-to-fill-problem.jpg
new file mode 100644 (file)
index 0000000..33ed74f
Binary files /dev/null and b/docs/content/images/image-scaling/example-scale-to-fill-problem.jpg differ
diff --git a/docs/content/images/image-scaling/example-scale-to-fill-sequence.jpg b/docs/content/images/image-scaling/example-scale-to-fill-sequence.jpg
new file mode 100644 (file)
index 0000000..e432e76
Binary files /dev/null and b/docs/content/images/image-scaling/example-scale-to-fill-sequence.jpg differ
diff --git a/docs/content/images/image-scaling/fitting-mode-options.jpg b/docs/content/images/image-scaling/fitting-mode-options.jpg
new file mode 100644 (file)
index 0000000..3d085b8
Binary files /dev/null and b/docs/content/images/image-scaling/fitting-mode-options.jpg differ
diff --git a/docs/content/images/image-scaling/sampling_modes_box.png b/docs/content/images/image-scaling/sampling_modes_box.png
new file mode 100644 (file)
index 0000000..9e54e89
Binary files /dev/null and b/docs/content/images/image-scaling/sampling_modes_box.png differ
diff --git a/docs/content/images/image-scaling/sampling_modes_box_then_linear.png b/docs/content/images/image-scaling/sampling_modes_box_then_linear.png
new file mode 100644 (file)
index 0000000..cc32253
Binary files /dev/null and b/docs/content/images/image-scaling/sampling_modes_box_then_linear.png differ
diff --git a/docs/content/images/image-scaling/sampling_modes_box_then_nearest.png b/docs/content/images/image-scaling/sampling_modes_box_then_nearest.png
new file mode 100644 (file)
index 0000000..a1792f6
Binary files /dev/null and b/docs/content/images/image-scaling/sampling_modes_box_then_nearest.png differ
diff --git a/docs/content/images/image-scaling/sampling_modes_linear.png b/docs/content/images/image-scaling/sampling_modes_linear.png
new file mode 100644 (file)
index 0000000..a51c346
Binary files /dev/null and b/docs/content/images/image-scaling/sampling_modes_linear.png differ
diff --git a/docs/content/images/image-scaling/sampling_modes_nearest.png b/docs/content/images/image-scaling/sampling_modes_nearest.png
new file mode 100644 (file)
index 0000000..02d3391
Binary files /dev/null and b/docs/content/images/image-scaling/sampling_modes_nearest.png differ
diff --git a/docs/content/images/image-scaling/sampling_modes_no_filter.png b/docs/content/images/image-scaling/sampling_modes_no_filter.png
new file mode 100644 (file)
index 0000000..4825696
Binary files /dev/null and b/docs/content/images/image-scaling/sampling_modes_no_filter.png differ
index 61b3c75..38cd6c4 100644 (file)
@@ -97,6 +97,7 @@
 ### Application Optimization Guide
  + [Texture Atlases](@ref textureatlases)
  + [Texture Compression](@ref texturecompression)
+ + [Rescaling Images](@ref resourceimagescaling)
  + Performance & Debugging
  + [Performance Tips](@ref performancetips)
  + [Performance Profiling](@ref performanceprofiling)
index 437e5a8..73a1ada 100644 (file)
  * <h1 class="pg">Image Actor</h1>
  *
  * <h2 class="pg">Construction</h2>
- * The Image Actor is constructed by passing a Dali::Image object
+ * The Image Actor is constructed by passing a Dali::Image object.
+ * Dali::Image is an abstract base class with multiple derived classes.
+ * Dali::ResourceImage is used for the common case of loading an image
+ * from a file.
  *
  * @code
- * Dali::Image image = Image::New(myImageFilename);
- * Dali::ImageActor myImageActor = ImageActor::New(image);
+ * Dali::Image image = ResourceImage::New( myImageFilename );
+ * Dali::ImageActor myImageActor = ImageActor::New( image );
  * @endcode
  *
  * <h3 class="pg">Resizing at Load Time</h3>
  * An application loading images from an external source will often want to
  * display those images at a lower resolution than their native ones.
- * To support this, %Dali can resize an image at load time so that its in-memory
- * copy uses less space and its visual quality benefits from being prefiltered.
+ * To support this, %Dali can resize an image at load time so that its
+ * in-memory copy uses less space and its visual quality benefits from being
+ * prefiltered.
  * There are four algorithms which can be used to fit an image to a desired
  * rectangle, a desired width or a desired height
- * (see Dali::ImageAttributes::ScalingMode).
+ * (see Dali::FittingMode).
  *
  * Here is an example doing rescaling:
  *
  * @code
- * Dali::ImageAttributes attributes;
- * attributes.SetSize( 256, 192 );
- * attributes.SetScalingMode( Dali::ImageAttributes::ScaleToFill );
- * Dali::Image image = Dali::Image::New( filename, attributes );
+ * Dali::Image image = Dali::ResourceImage::New( filename, ImageDimensions( 240, 240 ), FittingMode::SCALE_TO_FILL );
  * @endcode
  *
- * This example sets the size and scaling mode appropriately for a large thumbnail
- * on an Dali::ImageAttributes instance and passes that to Dali::Image construction.
- * In general, to enable scaling on load, set-up a Dali::ImageAttributes object with
- * a non-zero width or height and one of the four scaling modes, and pass it into a
- * Dali::Image creator function as shown above.
+ * This example sets the size and fitting mode appropriately for a large thumbnail
+ * during Dali::ResourceImage construction.
+ * In general, to enable scaling on load, pass a non-zero width or height and
+ * one of the four fitting modes to the Dali::ResourceImage creator function
+ * as shown above.
  *
- * The scaling modes and a suggested use-case for each are as follows:
+ * The fitting modes and a suggested use-case for each are as follows:
  * <ol>
- *   <li> Dali::ImageAttributes::ShrinkToFit Full-screen image display: Limit loaded image resolution to device resolution.
- *   <li> Dali::ImageAttributes::ScaleToFill Thumbnail gallery grid: Limit loaded image resolution to screen tile.
- *   <li> Dali::ImageAttributes::FitWidth Image columns: Limit loaded image resolution to column.
- *   <li> Dali::ImageAttributes::FitHeight Image rows: Limit loaded image resolution to row height.
+ *   <li> Dali::FittingMode::SHRINK_TO_FIT Full-screen image display: Limit loaded image resolution to device resolution but show all of image.
+ *   <li> Dali::FittingMode::SCALE_TO_FILL Thumbnail gallery grid: Limit loaded image resolution to screen tile, filling whole tile but losing a few pixels to match the tile shape.
+ *   <li> Dali::FittingMode::FIT_WIDTH Image columns: Limit loaded image resolution to column.
+ *   <li> Dali::FittingMode::FIT_HEIGHT Image rows: Limit loaded image resolution to row height.
  * </ol>
  *
- * The dali-demo project contains a full example under <code>examples/image</code>.
+ * The dali-demo project contains a full example under
+ * <code>examples/image-scaling-and-filtering</code>
+ * and a specific sampling mode example under
+ * <code>examples/image-scaling-irregular-grid</code>.
+ *
+ * There are more details on this topic in the
+ * \link resourceimagescaling Rescaling Images \endlink
+ * section.
  *
  * <h2 class="pg">Style</h2>
  * The Actor can render an image in two different ways.<br>
  * @endcode
  *
  */
-
diff --git a/docs/content/shared-javascript-and-cpp-documentation/resource-image-scaling.md b/docs/content/shared-javascript-and-cpp-documentation/resource-image-scaling.md
new file mode 100644 (file)
index 0000000..08519a1
--- /dev/null
@@ -0,0 +1,360 @@
+/**
+ *
+[TOC]
+
+# Resource Image Scaling {#resourceimagescaling}
+
+## Introduction
+
+While common uses of images in DALi applications involve fixed sized images
+under the developer's control, e.g. for button backgrounds, in other cases such as galleries and wallpapers an application must display a variety of images and adapt to different screen sizes and densities.
+For these situations, DALi provides a facility to scale a `ResourceImage` while it is being loaded.
+
+Look at the following example.
+Let's say we are writing a home-screen application for a smartphone.
+Here we have a large, square image that we want to set as the wallpaper on a tall and narrow phone screen.
+We want to fill the screen without distorting the image or having black borders, and wasting as few pixels from the source image as possible.
+
+![ ](../assets/img/image-scaling/example-scale-to-fill-problem.jpg)
+![ ](example-scale-to-fill-problem.jpg)
+
+DALi provides the concept of a `FittingMode` to specify how a source image is mapped into a target rectangle, and the one we need here is `FittingMode::SCALE_TO_FILL` as it will cover all of the pixels of the target.
+A second concept of a `SamplingMode` controls how source image pixels are combined during the scaling and allows the developer to trade speed for quality.
+Since our image is to be loaded once and reused, we should use `SamplingMode::BOX_THEN_LINEAR` which is the highest quality option.
+We can pass the stage dimensions to the `ResourceImage` creator function as the desired rectangle and ask it to map the image to the screen as follows:
+
+~~~{.cpp}
+// C++
+ResourceImage image = ResourceImage::New(
+  "gallery-large-12.jpg",
+  Dali::ImageDimensions( stage.GetSize().x, stage.GetSize().y ),
+  Dali::FittingMode::SCALE_TO_FILL,
+  Dali::SamplingMode::BOX_THEN_LINEAR );
+~~~
+~~~{.js}
+// JavaScript
+// First get stage dimensions into stageX and stageY ...
+var image = new dali.ResourceImage( {
+  url: "gallery-large-12.jpg",
+  width: stageX,
+  height: stageY,
+  fitting-mode: "SCALE_TO_FILL",
+  sampling-mode: "BOX_THEN_LINEAR"
+});
+~~~
+
+In this case, `SCALE_TO_FILL` will perform this sequence of operations:
+
+| SCALE_TO_FILL Example |
+| ------------ |
+| ![ ](../assets/img/image-scaling/example-scale-to-fill-sequence.jpg) ![ ](example-scale-to-fill-sequence.jpg) |
+| <sub> **1.** *The source image.* **2.** *The source scaled-down to match the screen size.* **3.** *The borders of the image are trimmed to match the shape of the screen.* **4.** *The image fits exactly on the phone screen with no scaling required while rendering.* </sub> |
+
+
+## API Details {#resourceimagescalingapidetails}
+
+The new function of `ResourceImage` has the following scaling-related parameters:
+* **path**: Identifier for the image (allows raw image width and height to be retrieved).
+* **requested dimensions**: These are either `(0,0)`, a width, a height, or a (width, height) pair and either directly, or after reading the image raw dimensions and doing some math, define a target rectangle to fit the image to.
+* **fitting mode**: one of four strategies for mapping images onto the target rectangle.
+* **sampling mode** Different quality options for the scaling.
+
+### Target dimensions for fitting {#resourceimagescalingtargetdimensions}
+
+An application has several options for specifying the target rectangle for the image to be fitted to.
+The application may request dimensions through `ResourceImage::New()`:
+
+  1. `(0, 0)`, which is equivalent to not specifying any dimensions
+  2. `(x != 0, 0)` or `(0, y != 0)`, i.e. just one dimension specified
+  3. `(x != 0, y != 0)`, i.e. both dimensions specified
+
+In **case 1.** no scaling will be attempted.
+The image will be loaded at its raw dimensions.
+In **case 2.** the unspecified dimension will be derived from the specified one and the aspect ratio of the raw dimensions.
+This specified dimension and calculated dimension pair pass on as the target dimension for fitting.
+See more on this case [below](#resourceimagescalingzerodimensions).
+In **case 3.** the requested dimensions pass straight through to become the target for fitting.
+
+The result of this process is an `(x, y)` tuple defining a box to fit the image to in the next step.
+
+#### Examples {#resourceimagescalingtargetdimensionsexamples}
+If we have a `(320, 240)` image called "flower.jpg", we use these three options in code as below.
+
+**Case 1**:
+~~~{.cpp}
+// C++
+ResourceImage image1 = ResourceImage::New( "flower.png" );
+ResourceImage image2 = ResourceImage::New( "flower.png", ImageDimensions( 0, 0 ) );
+~~~
+~~~{.js}
+// JavaScript
+var image1 = new dali.ResourceImage( { url:"flower.png" } );
+var image2 = new dali.ResourceImage( { url:"flower.png", width:0, height:0 } );
+~~~
+In these two equivalent loads, the target dimensions will be `(320, 240)` so the image will be loaded at its raw dimensions without modification.
+
+**Case 2**:
+~~~{.cpp}
+// C++
+ResourceImage image1 = ResourceImage::New( "flower.png", ImageDimensions( 160, 0 ) );
+ResourceImage image2 = ResourceImage::New( "flower.png", ImageDimensions( 0, 120 ) );
+~~~
+~~~{.js}
+// JavaScript
+var image1 = new dali.ResourceImage( { url:"flower.png", width:160, height:0 } );
+var image2 = new dali.ResourceImage( { url:"flower.png", width:0, height:120 } );
+~~~
+In these loads, the target dimensions will be `(160, 120)` as the zero dimension is derived from the aspect ratio of the raw image.
+
+**Case 3**:
+~~~{.cpp}
+// C++
+ResourceImage image = ResourceImage::New( "flower.png", ImageDimensions( 111, 233 ) );
+~~~
+~~~{.js}
+// JavaScript
+var image = new dali.ResourceImage( { url:"flower.png", width:111, height:233 } );
+~~~
+In this load, the target dimensions will be `(111, 233)`.
+
+### Image Pixel Dimensions {#resourceimagescalingsamplingmodesdimensionflow}
+
+DALi derives the pixel width and height of loaded resource images from a sequence of calculations with four inputs:
+
+  1. The dimensions requested via `ResourceImage` new function, either of which may be passed as zeros
+  2. The dimensions of the raw image before loading
+  3. The fitting mode requested
+  4. The sampling mode requested
+
+The dimensions requested do not correspond 1:1 with the exact pixel width and height of the image once loaded: they are just one of the four inputs to the process which determines those dimensions.
+
+| Flow of image dimensions from API to loaded image |
+| ------------ |
+| ![ ](../assets/img/image-scaling/concept-rectangles.jpg) ![ ](concept-rectangles.jpg) |
+| <sub> *Image dimensions requested through the API are either absent (**a.**), a height (**b.**), a width (**c.**) or a full (width, height) pair (**d.**). In case **d.** this is the target for fitting (**i.**). In cases **a.**, **b.**, and **c.**, the raw image dimensions (**e.**) are also needed to define the target (examples: **f.**, **g.**, **h.**). This target, the **FittingMode**, and the raw size (**e.**), are used to derive the fitted size (**j.**). This is the size that a perfect scaling would achieve. This fitted size, the **Sampling Mode**, and the raw size (**e.**) are used to derive the final pixel width and height (**k.** **l.** **m.**, depending on **Sampling Mode**).* </sub> |
+
+The diagram above shows the key `(x,y)` image dimensions used by DALi in its load-time scaling pipeline visualized as rectangles.
+They are:
+
+  1. **Requested**: The dimensions passed by the app.
+  2. **Raw**: The dimensions stored in the resource.
+  3. **Target**: The box to fit the image into derived from 1. and 2.
+  4. **Fitted**: The ideal scaled-down size of the image.
+  5. **Scaled Pixels** The final pixel width and height resulting from the (possibly approximate) scaling.
+
+This should help to understand how the parameters given to DALi influence the final image loaded. The (x, y) passed define a *target* to the fit the image to rather than a new size for the image directly.
+The fitting mode defines a strategy for fitting the raw image to the target.
+The sampling mode has two options which cause the fitted dimensions to be exceeded, while the others cause it to be matched exactly.
+
+The pipeline from the values passed from the application to the *natural size* of the image is different. If no dimension is passed, the raw image size is read from the image resource. If only one dimension is passed, the explicitly set dimension will be used for the **natural size** and the unspecified dimension will match the actual loaded pixel dimension. When both are specified that becomes the 'natural size' even if it differs from the actual pixel dimensions loaded. This [requires some care in rendering to avoid distortion](#resourceimagescalingsamplingmodesrendernaturalsize).
+
+### Fitting an image's dimensions to the target box {#resourceimagescalingfittingmodes}
+
+DALi provides a number of strategies for mapping the pixels of an image onto the target box derived above.
+It provides a `FittingMode` enumeration to the developer to select a mapping or fitting approach.
+These are `SCALE_TO_FILL`, `SHRINK_TO_FIT`, `FIT_WIDTH`, and `FIT_HEIGHT` and their effect is best appreciated visually:
+
+| FittingMode Options |
+| ------------------- |
+| ![ ](../assets/img/image-scaling/fitting-mode-options.jpg) ![ ](fitting-mode-options.jpg) |
+| <sub> **Fitting modes**: *The top row shows the effect of each mode when a tall target rectangle is applied to a square image. The middle row applies a wide target to a square raw image. The bottom row uses a target with the same aspect ratio as the raw image. These examples show that `SCALE_TO_FILL` is the only option for which the dimensions of the fitted image result exactly match the target. The others are larger or smaller, with a different aspect ratio. `SHRINK_TO_FIT` is always equal to one of `FIT_WIDTH` or `FIT_HEIGHT`: in each case it is the minimum of them. As a special case, where the aspect ratio of raw image and target match, all fitting modes generate an exact match final image and are equivalent to each other.* </sub> |
+
+The operation of each of these modes is as follows:
+
+| `FittingMode` | **Operation** |
+| ------------- | --------- |
+| `SCALE_TO_FILL` | Centers the image on the target box and uniformly scales it so that it matches the target in one dimension and extends outside the target in the other. Chooses the dimension to match that results in the fewest pixels outside the target. Trims away the parts of the image outside the target box so as to match it exactly. |
+| `SHRINK_TO_FIT` | Centers the image on the target box and uniformly scales it so that it matches the target in one dimension and fits inside it in the other. |
+| `FIT_WIDTH` | Centers the image on the target box and uniformly scales it so that it matches the target width without regard for the target height. |
+| `FIT_HEIGHT` | Centers the image on the target box and uniformly scales it so that it matches the target in height and ignores the target width. |
+
+These modes differ only when the target box has a different aspect ratio to the raw image. Using this, if the application knows a priori what the image dimensions are, it can scale down the image by requesting dimensions that have the same aspect ratio as the raw dimensions:
+~~~{.cpp}
+// C++
+// Image on 'disk' is 320x240.
+ResourceImage image = ResourceImage::New( "flower.png", ImageDimensions( 32, 24 ) );
+// Image will be loaded at (32, 24), regardless of fitting mode.
+~~~
+~~~{.js}
+// JavaScript
+// Image on 'disk' is 320x240.
+var image = new dali.ResourceImage( { url:"flower.png", width:32, height:24});
+// Image will be loaded at (32, 24), regardless of fitting mode.
+~~~
+
+
+### Quality Versus Speed and Memory Options {#resourceimagescalingsamplingmodes}
+
+The process of scaling an image can be expensive in CPU cycles and add latency to the loading of each resource.
+To allow the developer to trade-off speed against quality for different use cases, DALi provides the `SamplingMode` enum, which can be passed to `ResourceImage::New()`.
+Two of these modes produce bitmaps which differ from the dimensions calculated by the fitting algorithm and so have a memory trade-off as well. The full set of modes is explained below.
+
+| `SamplingMode` | **Operation** |
+| ------------- | --------- |
+| `NEAREST` | Use simple point sampling when scaling. For each pixel in output image, just one pixel is chosen from the input image. This is the fastest, crudest option but suffers the worst from aliasing artifacts so should only be used for fast previews, or where the source image is known to have very low-frequency features. |
+| `LINEAR` | Uses a weighted bilinear filter with a `(2,2)` footprint when scaling. For each output pixel, four input pixels are averaged from the input image. This is a good quality option, equivalent to the GPU's filtering and works well at least down to a `0.5` scaling. |
+| `BOX` | Uses an iterated `(2,2)` box filter to repeatedly halve the image in both dimensions, averaging adjacent pixels until the the result is approximately right for the fitting target rectangle. For each output pixel some number of pixels from the sequence `[4,16,64,256,1024,...]` are averaged from the input image, where the number averaged depends on the degree of scaling requested. This provides a very high quality result and is free from aliasing artifacts because of the iterated averaging. *The resulting bitmap will not exactly match the dimensions calculated by the fitting mode but it will be within a factor of two of it and have the same aspect ratio as it.*   |
+| `BOX_THEN_NEAREST` | Applies the `BOX` mode to get within a factor of two of the fitted dimensions, and then finishes off with `NEAREST` to reach the exact dimensions. |
+| `BOX_THEN_LINEAR` | Applies the `BOX` mode to get within a factor of two of the fitted dimensions, and then finishes off with `LINEAR` to reach the exact dimensions. This is the slowest option and of equivalent quality to `BOX`. It is superior to `BOX` in that is uses an average of 62% of the memory and exactly matches the dimensions calculated by fitting. **This is the best mode for most use cases**.  |
+| `NO_FILTER` | Disables scaling altogether. In conjunction with `SCALE_TO_FILL` mode this can be useful as the edge trimming of that fitting mode is still applied. An example would be a gallery application, where a database of prescaled thumbnails of approximately the correct size need to be displayed in a regular grid of equal-sized cells, while being loaded at maximum speed. |
+
+Here are all the modes applied to scaling-down a `(640,720)` line art and text JPEG image to a `(218, 227)` thumbnail:
+
+|  |  | |
+| ---- | ---- | --- |
+| ![ ](../assets/img/image-scaling/sampling_modes_no_filter.png) ![ ](sampling_modes_no_filter.png) | ![ ](../assets/img/image-scaling/sampling_modes_nearest.png) ![ ](sampling_modes_nearest.png) | ![ ](../assets/img/image-scaling/sampling_modes_linear.png) ![ ](sampling_modes_linear.png) |
+| **NO_FILTER** | **NEAREST** | **LINEAR** |
+| ![ ](../assets/img/image-scaling/sampling_modes_box.png) ![ ](sampling_modes_box.png) | ![ ](../assets/img/image-scaling/sampling_modes_box_then_nearest.png) ![ ](sampling_modes_box_then_nearest.png) | ![ ](../assets/img/image-scaling/sampling_modes_box_then_linear.png) ![ ](sampling_modes_box_then_linear.png) |
+| **BOX** | **BOX_THEN_NEAREST** | **BOX_THEN_LINEAR** |
+
+These are screenshots, showing how the images are rendered in a DALi demo.
+There is an additional level of GPU bilinear filtering happening at render time.
+The best way to get a feel for the best sampling mode for different image types is to play with the [examples](#resourceimagescalingsamplingmodesexamples).
+
+In the following code example the same image is loaded to be a thumbnail but with differing quality, speed, and memory implications.
+~~~{.cpp}
+// C++
+ResourceImage image1 = ResourceImage::New( "flower.png",
+    ImageDimensions( 240, 240 ), FittingMode::SCALE_TO_FILL, SamplingMode::NEAREST );
+
+ResourceImage image2 = ResourceImage::New( "flower.png",
+    ImageDimensions( 240, 240 ), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER );
+
+ResourceImage image3 = ResourceImage::New( "flower.png",
+    ImageDimensions( 240, 240 ), FittingMode::SCALE_TO_FILL, SamplingMode::BOX );
+
+ResourceImage image4 = ResourceImage::New( "flower.png",
+    ImageDimensions( 240, 240 ), FittingMode::SCALE_TO_FILL, SamplingMode::BOX_THEN_LINEAR );
+~~~
+~~~{.js}
+// JavaScript
+var image1 = new dali.ResourceImage( {
+  url:"flower.png", width:240, height:240,
+  fitting-mode:"SCALE_TO_FILL", sampling-mode:"NEAREST"
+} );
+
+var image2 = new dali.ResourceImage( {
+  url:"flower.png", width:240, height:240,
+  fitting-mode:"SCALE_TO_FILL", sampling-mode:"NO_FILTER"
+} );
+
+var image3 = new dali.ResourceImage( {
+  url:"flower.png", width:240, height:240,
+  fitting-mode:"SCALE_TO_FILL", sampling-mode:"BOX"
+} );
+
+var image4 = new dali.ResourceImage( {
+  url:"flower.png", width:240, height:240,
+  fitting-mode:"SCALE_TO_FILL", sampling-mode:"BOX_THEN_LINEAR"
+} );
+~~~
+
+If we imagine flower.jpg is a 560*512 photo with high frequency details, the results of this are:
+* `image1` loads fast, uses minimal space, has poor quality.
+* `image2` loads even faster, uses 4.6 * minimal space, has good quality.
+* `image3` loads moderately slow, uses 1.3 * minimal space, has good quality.
+* `image4` loads slowest, uses minimal space, has good quality.
+
+Note that `BOX`, `BOX_THEN_NEAREST` and `BOX_THEN_LINEAR` can work particularly well for JPEG images as they can use fast downscaling typically built-in to the JPEG codec on supported platforms on the fly while decoding. In this case the caveats about using them having a speed trade-off given above do not apply.
+
+## Passing a Zero Dimension {#resourceimagescalingzerodimensions}
+Passing in a single zero dimension is effectively a shortcut for specifying `FIT_WIDTH` or `FIT_HEIGHT` `FittingMode`s. When a non-zero width and zero height are specified, the fitting done will be identical to the result using `FittingMode` `FIT_WIDTH`. When passing a zero width and non-zero height, the effect of applying the chosen `FittingMode` to the calculated target dimensions is always identical to applying the `FIT_HEIGHT` mode.
+
+* `ResourceImage::New( ImageDimensions( x, 0 ), <ANY_FITTING_MODE> )` =
+  `ResourceImage::New( ImageDimensions( x, <ANYTHING> ), FittingMode::FIT_WIDTH )`
+* `ResourceImage::New( ImageDimensions( 0, y ), <ANY_FITTING_MODE> )` =
+  `ResourceImage::New( ImageDimensions( <ANYTHING>, y), FittingMode::FIT_HEIGHT )`
+
+This falls out of the the fact that the fitting modes modes are strategies for the case when the aspect ratio of the raw image differs from the aspect ratio of the target dimensions, but the zero dimension behavior always ensures that the target dimensions have the same aspect ratio as the raw image's so the fitting modes are all equivalent.
+
+Therefore, if `(x!=0, y=0)`, fittingMode = `FIT_WIDTH`,
+and if `(x=0, y=!0)`, fittingMode = `FIT_HEIGHT`, irrespective of fitting mode passed by the application (if any).
+This shortcut is provided as a convenience to the developer and allows FIT_WIDTH or FIT_HEIGHT to be specified compactly:
+~~~{.cpp}
+// C++
+// FIT_WIDTH:
+ResourceImage image = ResourceImage::New("flower.png", ImageDimensions(x, 0));
+// FIT_HEIGHT:
+ResourceImage image = ResourceImage::New("flower.png", ImageDimensions(0, y));
+~~~
+~~~{.js}
+// JavaScript
+// FIT_WIDTH:
+var image = new dali.ResourceImage( {
+  url: "flower.png",
+  width: x,
+  height: 0
+});
+// FIT_HEIGHT:
+var image = new dali.ResourceImage( {
+  url: "flower.png",
+  width: 0,
+  height: y
+});
+~~~
+
+## Upscaling
+
+DALi refuses to upscale images at load time in order to conserve memory.
+If the application requests a size for an image that is larger than its raw dimensions, DALi will instead return an image with the same aspect ratio but limited to the largest dimensions that do not exceed the raw ones.
+Upscaling can still be effected at render time by setting the size of an actor to the desired size.
+
+## Compressed Textures and Scaling
+
+Compressed textures cannot be scaled at load time as their formats are designed to be uploaded directly to GPU memory. To achieve scaling of compressed textures, set the desired size on the attached `ImageActor` for scaling at render time instead.
+
+## Compensation for Natural Size != Pixel Width / Height {#resourceimagescalingsamplingmodesrendernaturalsize}
+
+Because the *natural size* of an image is
+[taken from the requested dimensions](#resourceimagescalingsamplingmodesdimensionflow)
+passed to `ResourceImage::New()` rather than passing through the same calculations that result in the eventual pixel width and height loaded,
+the *natural size* and pixel dimensions of an image will differ when loaded with scaling.
+It is inherent in the definition of fitting modes other than `SCALE_TO_FILL` not to match the requested dimensions, so in general, images loaded with them must have this mismatch between *natural size* and actual pixel width.
+
+It is not possible in general to draw a scaled resource image using its natural size as the `ImageActor`'s size without it appearing stretched in one dimension.
+This is the case for example by default with size negotiation in effect or when an image is simply passed to an actor at creation time.
+
+There are circumstance, however, in which the the natural size of a resource image loaded will exactly match its post-load pixel dimensions:
+
+1. No scaling is requested.
+1. The application chooses a combination of requested dimensions, fitting mode, and sampling mode which the scaling sub-system can match exactly. This is the case:
+   *  For all downscaling using `SCALE_TO_FILL` fitting mode and not using `BOX` or `NO_FILTER` sampling modes.
+   * The app uses `SHRINK_TO_FIT`, `FIT_WIDTH`, or `FIT_HEIGHT` and the requested dimensions passed-in are both smaller than the raw ones and have the same aspect ratio as them, and it is not using `BOX` or `NO_FILTER` sampling modes.
+
+In these cases the image may be used freely in layouts controlled by size negotiation.
+Additionally, if the requested size has the same aspect ratio as the eventual pixel array loaded, and the fitting mode is `SCALE_TO_FILL` or `BOX` and `NO_FILTER` sampling modes are avoided, even if they don't match in dimensions exactly, the eventual image will be drawn without aspect ratio distortion although it will be scaled at render time.
+
+The fitting and scaling modes [demo](#resourceimagescalingsamplingmodesexamples) allows this behavior to be be explored dynamically when the fitting mode is changed from `SCALE_TO_FILL`.
+
+The application can of course only pass dimensions which are just right if it happens to know the raw dimensions or if it accesses the the image resource and reads the raw dimensions from its header.
+
+The application can get a scaled resource image rendered correctly to screen with one of three strategies:
+
+  1. Use one of the special cases above.
+  2. Read the image header from disk, recreate the dimension deriving, fitting, and sampling logic described in this document, and use that to generate a pair of requested dimensions which match the eventual image dimensions.
+  3. Use the requested dimensions it really wants to but then read the image header from disk, recreate the dimension deriving, fitting, and sampling logic described in this document, and set the size of an `ImageActor` to that size explicitly rather than relying on the *natural size* of the image.
+
+## Examples {#resourceimagescalingsamplingmodesexamples}
+Load time image scaling is spread throughout the DALi examples.
+Search for `"ImageDimensions"` in the dali-demo project to see it used.
+There is also a specific demo to show all of the fitting and scaling modes.
+which lives in the demo project at `examples/image-scaling-and-filtering`.
+
+![ ](../assets/img/image-scaling/demo-fitting-sampling.jpg) ![ ](./demo-fitting-sampling.jpg)
+
+Touch the arrows in the top corners to changes image.
+Drag the green button in the corner of the image to change the requested size and trigger an immediate image reload.
+Use the buttons at the bottom of the screen to select any of the fitting and sampling modes from the popups which appear.
+This demo does not take any of the special measures [described above](#resourceimagescalingsamplingmodesrendernaturalsize) to correct for the natural size != pixel dimensions discrepancy so all fitting modes other than `SCALE_TO_FILL` show distortion.
+
+A second specific demo shows the effect of a filter mode on a single image loaded into various requested rectangles side by side.
+It can be found under `examples/image-scaling-irregular-grid`.
+
+![ ](../assets/img/image-scaling/demo-sampling-modes.jpg) ![ ](./demo-sampling-modes.jpg)
+
+Touch the button at top-left to change image.
+The button at top-right changes sampling mode.
+You will see strong differences between sampling modes where the image contains high frequency details such as hair and in the large black and white image, but much less in some others such as the Statue of Liberty which is mostly covered by a smooth gradient.
+
+@class _Guide_Resource_Image_Scaling
+*/
index a9910d5..7da51c6 100644 (file)
@@ -6,13 +6,15 @@
 
 Using compressing the textures will:
 
-- Speed up rendering in time the GPU == less power used due to less texture data being transferred.
+- Reduce memory bandwidth in rendering due to less texture data being transferred per frame.
+  - Reduces power consumption.
+  - Speeds up rendering.
 - Reduce texture memory usage.
-- Speed up load times. Smaller files mean quicker load times.
-  
+- Speed up load times. There is no CPU decoding step in loading: the file data can be copied directly to GPU memory.
+
 DALi supports the KTX file format.
-  
-You just load the compressed texture like you would any other image.
+
+You load the compressed texture just like you would any other image.
 
 ~~~{.cpp}
 // C++
@@ -23,27 +25,27 @@ ResourceImage image = ResourceImage::New("my_compressed_file.ktx");
 var image = new dali.ResourceImage( { url:"my_compressed_file.ktx"});
 
 ~~~
-  
+
 ### ARMS texture compression tool
 
 http://malideveloper.arm.com/develop-for-mali/tools/asset-creation/mali-gpu-texture-compression-tool/
-  
+
 Here is an example of using the ARM compression tool.
-  
+
 ![ ](../assets/img/texture-atlas/compression-options.jpg)
 ![ ](compression-options.jpg)
-  
+
 ![ ](../assets/img/texture-atlas/compression-example.jpg)
 ![ ](compression-example.jpg)
 
-  
+
 As shown above the ETC-1 compression format does not support alpha.
-  
-As a work around the tool will export the alpha as a seperate compressed image.
+
+As a work around the tool will export the alpha as a separate compressed image.
 
 In order to combine both the images you need to use a custom shader.
 Here is an example shader:
-  
+
 ~~~{.cpp}
 // C++ Code
   const char* const COMPRESSED_RGB_PLUS_SEPARATE_ALPHA_FRAGMENT_SOURCE =
@@ -73,7 +75,7 @@ Here is an example shader:
 
   imageActor.SetBlendMode(BlendingMode::ON);
 ~~~
-  
+
 ~~~{.js}
 // JavaScript code
 var fragSource = "  \
@@ -83,20 +85,20 @@ void main()                                                   \
     v4Color.a =  texture2D(sEffect, vTexCoord ).r;             \
    gl_FragColor = v4Color;                                     \
 }";
-  
+
 var shaderEffect = new dali.ShaderEffect( "", fragSource);
-  
+
 var atlasImageRGB = new dali.ResourceImage( { url:"ATLAS_RGB_FILENAME.KTX"} );
-  
+
 var atlasImageAlpha = new dali.ResourceImage( { url:"ATLAS_ALPHA_FILENAME.KTX"} );
-  
+
 shaderEffect.setEffectImage( atlasImageAlpha );
-  
+
 // to create Image Actor
 ImageActor  imageActor = ImageActor::New( mAtlasImageRGB, GetImagePosition( info) );
-  
+
 imageActor.setShaderEffect( shaderEffect );
-  
+
 imageActor.setBlendMode( dali.BLENDING_ON );
 ~~~
 
@@ -104,5 +106,3 @@ imageActor.setBlendMode( dali.BLENDING_ON );
 
 
 */
-
-
index b30b948..8e7df33 100644 (file)
@@ -19,7 +19,7 @@
 #include "resource-image-api.h"
 
 // EXTERNAL INCLUDES
-#include <dali/devel-api/images/image-operations.h>
+#include <dali/public-api/images/image-operations.h>
 
 // INTERNAL INCLUDES
 #include <v8-utils.h>
index 8adcabd..e5cfb67 100644 (file)
@@ -312,7 +312,7 @@ public:
 
   Actor PreFocusChangeSignal(Actor currentFocusedActor,
                              Actor proposedActorToFocus,
-                             Toolkit::Control::KeyboardFocusNavigationDirection direction  )
+                             Toolkit::Control::KeyboardFocus::Direction direction  )
   {
     std::vector< Dali::Any > arguments;
     Dali::Any returnValue = Actor();  // we want an actor as a return value
index d39276c..b43e703 100644 (file)
@@ -34,29 +34,29 @@ namespace // un named namespace
 {
 
 
-Toolkit::Control::KeyboardFocusNavigationDirection  GetDirection( std::string name,  v8::Isolate* isolate )
+Toolkit::Control::KeyboardFocus::Direction  GetDirection( std::string name,  v8::Isolate* isolate )
 {
   if( name == "left")
   {
-    return Dali::Toolkit::Control::Left;
+    return Dali::Toolkit::Control::KeyboardFocus::LEFT;
   }
   if( name == "right")
   {
-    return  Dali::Toolkit::Control::Right;
+    return  Dali::Toolkit::Control::KeyboardFocus::RIGHT;
   }
   if( name == "up")
   {
-    return  Dali::Toolkit::Control::Up;
+    return  Dali::Toolkit::Control::KeyboardFocus::UP;
   }
   if( name == "down")
   {
-    return  Dali::Toolkit::Control::Down;
+    return  Dali::Toolkit::Control::KeyboardFocus::DOWN;
   }
 
   DALI_SCRIPT_EXCEPTION( isolate,  "direction not found ( wanted left,right,up,down)" );
 
 
-  return Dali::Toolkit::Control::Up;
+  return Dali::Toolkit::Control::KeyboardFocus::UP;
 
 }
 }; //un-named namespace
@@ -124,7 +124,7 @@ void KeyboardFocusManagerApi::MoveFocus( const v8::FunctionCallbackInfo< v8::Val
     return;
   }
 
-  Toolkit::Control::KeyboardFocusNavigationDirection dir = GetDirection( direction, isolate );
+  Toolkit::Control::KeyboardFocus::Direction dir = GetDirection( direction, isolate );
 
   Toolkit::KeyboardFocusManager::Get().MoveFocus( dir );
 }
index 0ab6ea9..5bab6a1 100644 (file)
@@ -109,26 +109,26 @@ v8::Local<v8::ObjectTemplate> KeyboardFocusManagerWrapper::GetKeyboardFocusManag
 }
 
 
-std::string KeyboardFocusManagerWrapper::GetDirectionName(  Toolkit::Control::KeyboardFocusNavigationDirection dir )
+std::string KeyboardFocusManagerWrapper::GetDirectionName(  Toolkit::Control::KeyboardFocus::Direction dir )
 {
   switch( dir )
   {
-    case Dali::Toolkit::Control::Left:
+    case Dali::Toolkit::Control::KeyboardFocus::LEFT:
     {
       return "left";
       break;
     }
-    case Dali::Toolkit::Control::Right:
+    case Dali::Toolkit::Control::KeyboardFocus::RIGHT:
     {
       return "right";
       break;
     }
-    case Dali::Toolkit::Control::Up:
+    case Dali::Toolkit::Control::KeyboardFocus::UP:
     {
       return "up";
       break;
     }
-    case Dali::Toolkit::Control::Down:
+    case Dali::Toolkit::Control::KeyboardFocus::DOWN:
     {
       return "down";
       break;
index 3889021..ae1dff3 100644 (file)
@@ -66,7 +66,7 @@ public:
 
   virtual SignalManager* GetSignalManager() { return &mSignalManager;}
 
-  static std::string GetDirectionName(  Toolkit::Control::KeyboardFocusNavigationDirection dir );
+  static std::string GetDirectionName(  Toolkit::Control::KeyboardFocus::Direction dir );
 
 private: