Merge "DALi Version 1.2.49" into devel/master
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 21 Jul 2017 13:27:45 +0000 (13:27 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Fri, 21 Jul 2017 13:27:45 +0000 (13:27 +0000)
17 files changed:
automated-tests/src/dali-toolkit/utc-Dali-ImageVisual.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextEditor.cpp
automated-tests/src/dali-toolkit/utc-Dali-TextField.cpp
dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h
dali-toolkit/devel-api/controls/text-controls/text-field-devel.h
dali-toolkit/devel-api/visuals/image-visual-properties-devel.h
dali-toolkit/internal/controls/text-controls/text-editor-impl.cpp
dali-toolkit/internal/text/text-controller-impl.cpp
dali-toolkit/internal/text/text-controller-impl.h
dali-toolkit/internal/text/text-controller.cpp
dali-toolkit/internal/text/text-controller.h
dali-toolkit/internal/visuals/image/image-visual.cpp
dali-toolkit/internal/visuals/image/image-visual.h
dali-toolkit/internal/visuals/texture-manager.cpp
dali-toolkit/internal/visuals/texture-manager.h
dali-toolkit/internal/visuals/visual-string-constants.cpp
dali-toolkit/internal/visuals/visual-string-constants.h

index 25779d5..2d846e7 100644 (file)
@@ -1125,3 +1125,63 @@ int UtcDaliImageVisualRemoteAlphaMask(void)
 
   END_TEST;
 }
+
+
+int UtcDaliImageVisualAlphaMaskCrop(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline( "Request image visual with an Alpha mask and scale/cropping" );
+
+  VisualFactory factory = VisualFactory::Get();
+  DALI_TEST_CHECK( factory );
+
+  Property::Map propertyMap;
+  propertyMap.Insert( Visual::Property::TYPE,  Visual::IMAGE );
+  propertyMap.Insert( ImageVisual::Property::URL,  TEST_LARGE_IMAGE_FILE_NAME );
+  propertyMap.Insert( DevelImageVisual::Property::ALPHA_MASK_URL, TEST_MASK_IMAGE_FILE_NAME );
+  propertyMap.Insert( DevelImageVisual::Property::MASK_CONTENT_SCALE, 1.6f );
+  propertyMap.Insert( DevelImageVisual::Property::CROP_TO_MASK, true );
+
+  Visual::Base visual = factory.CreateVisual( propertyMap );
+  DALI_TEST_CHECK( visual );
+
+  Property::Map testMap;
+  visual.CreatePropertyMap(testMap);
+  DALI_TEST_EQUALS( *testMap.Find(DevelImageVisual::Property::ALPHA_MASK_URL),Property::Value(TEST_MASK_IMAGE_FILE_NAME), TEST_LOCATION );
+  DALI_TEST_EQUALS( *testMap.Find(DevelImageVisual::Property::MASK_CONTENT_SCALE), Property::Value(1.6f), TEST_LOCATION );
+  DALI_TEST_EQUALS( *testMap.Find(DevelImageVisual::Property::CROP_TO_MASK),Property::Value(true), TEST_LOCATION );
+
+  // For tesing the LoadResourceFunc is called, a big image size should be set, so the atlasing is not applied.
+  // Image with a size smaller than 512*512 will be uploaded as a part of the atlas.
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  TraceCallStack& textureTrace = gl.GetTextureTrace();
+  textureTrace.Enable(true);
+
+  DummyControl actor = DummyControl::New();
+  DummyControlImpl& dummyImpl = static_cast<DummyControlImpl&>(actor.GetImplementation());
+  dummyImpl.RegisterVisual( Control::CONTROL_PROPERTY_END_INDEX + 1, visual );
+
+  actor.SetSize( 200.f, 200.f );
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 0u, TEST_LOCATION );
+  DALI_TEST_EQUALS( DevelControl::IsResourceReady( actor ), false, TEST_LOCATION );
+
+  Stage::GetCurrent().Add( actor );
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( Test::WaitForEventThreadTrigger( 2 ), true, TEST_LOCATION );
+
+  application.SendNotification();
+  application.Render();
+
+  Vector2 size;
+  visual.GetNaturalSize(size);
+
+  DALI_TEST_EQUALS( size, Vector2( 100.0f, 100.0f ), 0.001f, TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetRendererCount(), 1u, TEST_LOCATION );
+  DALI_TEST_EQUALS( textureTrace.FindMethod("BindTexture"), true, TEST_LOCATION );
+  DALI_TEST_EQUALS( DevelControl::IsResourceReady( actor ), true, TEST_LOCATION );
+
+  END_TEST;
+}
index 70e229c..d884271 100644 (file)
@@ -26,7 +26,6 @@
 #include <dali/integration-api/events/pan-gesture-event.h>
 #include <dali-toolkit-test-suite-utils.h>
 #include <dali-toolkit/dali-toolkit.h>
-#include <dali-toolkit/devel-api/controls/control-devel.h>
 #include <dali-toolkit/devel-api/controls/text-controls/text-editor-devel.h>
 
 using namespace Dali;
@@ -767,12 +766,6 @@ int UtcDaliTextEditorSetPropertyP(void)
   editor.SetProperty( DevelTextEditor::Property::PLACEHOLDER_TEXT, "Setting Placeholder Text" );
   DALI_TEST_EQUALS( editor.GetProperty<std::string>( DevelTextEditor::Property::PLACEHOLDER_TEXT ), std::string("Setting Placeholder Text"), TEST_LOCATION );
 
-  // Check placeholder text properties when focused.
-  editor.SetProperty( DevelControl::Property::STATE, "FOCUSED" );
-  editor.SetProperty( DevelTextEditor::Property::PLACEHOLDER_TEXT, "Setting Focused Placeholder Text" );
-  DALI_TEST_EQUALS( editor.GetProperty<int>( DevelControl::Property::STATE ), (int)DevelControl::FOCUSED, TEST_LOCATION );
-  DALI_TEST_EQUALS( editor.GetProperty<std::string>( DevelTextEditor::Property::PLACEHOLDER_TEXT ), std::string("Setting Focused Placeholder Text"), TEST_LOCATION );
-
   // Check placeholder text's color property.
   editor.SetProperty( DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR, Color::RED );
   DALI_TEST_EQUALS( editor.GetProperty<Vector4>( DevelTextEditor::Property::PLACEHOLDER_TEXT_COLOR ), Color::RED, TEST_LOCATION );
@@ -786,6 +779,7 @@ int UtcDaliTextEditorSetPropertyP(void)
   Property::Map placeholderPixelSizeMapGet;
   Property::Map placeholderFontstyleMap;
   placeholderPixelSizeMapSet["placeholderText"] = "Setting Placeholder Text";
+  placeholderPixelSizeMapSet["placeholderTextFocused"] = "Setting Placeholder Text Focused";
   placeholderPixelSizeMapSet["placeholderColor"] = Color::BLUE;
   placeholderPixelSizeMapSet["placeholderFontFamily"] = "Arial";
   placeholderPixelSizeMapSet["placeholderPixelSize"] = 15.0f;
@@ -802,6 +796,7 @@ int UtcDaliTextEditorSetPropertyP(void)
   Property::Map placeholderMapSet;
   Property::Map placeholderMapGet;
   placeholderMapSet["placeholderText"] = "Setting Placeholder Text";
+  placeholderMapSet["placeholderTextFocused"] = "Setting Placeholder Text Focused";
   placeholderMapSet["placeholderColor"] = Color::RED;
   placeholderMapSet["placeholderFontFamily"] = "Arial";
   placeholderMapSet["placeholderPointSize"] = 12.0f;
index b1f4d07..6c7e8d1 100644 (file)
@@ -860,6 +860,7 @@ int UtcDaliTextFieldSetPropertyP(void)
   Property::Map placeholderPixelSizeMapGet;
   Property::Map placeholderFontstyleMap;
   placeholderPixelSizeMapSet["placeholderText"] = "Setting Placeholder Text";
+  placeholderPixelSizeMapSet["placeholderTextFocused"] = "Setting Placeholder Text Focused";
   placeholderPixelSizeMapSet["placeholderColor"] = Color::BLUE;
   placeholderPixelSizeMapSet["placeholderFontFamily"] = "Arial";
   placeholderPixelSizeMapSet["placeholderPixelSize"] = 15.0f;
@@ -876,6 +877,7 @@ int UtcDaliTextFieldSetPropertyP(void)
   Property::Map placeholderMapSet;
   Property::Map placeholderMapGet;
   placeholderMapSet["placeholderText"] = "Setting Placeholder Text";
+  placeholderMapSet["placeholderTextFocused"] = "Setting Placeholder Text Focused";
   placeholderMapSet["placeholderColor"] = Color::RED;
   placeholderMapSet["placeholderFontFamily"] = "Arial";
   placeholderMapSet["placeholderPointSize"] = 12.0f;
index e09207c..b2dc43a 100644 (file)
@@ -145,14 +145,15 @@ namespace Property
        * @code
        *   Property::Map propertyMap;
        *   propertyMap["placeholderText"] = "Setting Placeholder Text";
+       *   propertyMap["placeholderTextFocused"] = "Setting Placeholder Text Focused";
        *   propertyMap["placeholderColor"] = Color::RED;
        *   propertyMap["placeholderFontFamily"] = "Arial";
        *   propertyMap["placeholderPointSize"] = 12.0f;
        *
        *   Property::Map fontStyleMap;
-       *   fontstyleMap.Insert( "weight", "bold" );
-       *   fontstyleMap.Insert( "width", "condensed" );
-       *   fontstyleMap.Insert( "slant", "italic" );
+       *   fontStyleMap.Insert( "weight", "bold" );
+       *   fontStyleMap.Insert( "width", "condensed" );
+       *   fontStyleMap.Insert( "slant", "italic" );
        *   propertyMap["placeholderFontStyle"] = fontStyleMap;
        *
        *   editor.SetProperty( DevelTextEditor::Property::PLACEHOLDER, propertyMap );
index b678508..9ff0b2c 100644 (file)
@@ -111,14 +111,15 @@ namespace Property
        * @code
        *   Property::Map propertyMap;
        *   propertyMap["placeholderText"] = "Setting Placeholder Text";
+       *   propertyMap["placeholderTextFocused"] = "Setting Placeholder Text Focused";
        *   propertyMap["placeholderColor"] = Color::RED;
        *   propertyMap["placeholderFontFamily"] = "Arial";
        *   propertyMap["placeholderPointSize"] = 12.0f;
        *
        *   Property::Map fontStyleMap;
-       *   fontstyleMap.Insert( "weight", "bold" );
-       *   fontstyleMap.Insert( "width", "condensed" );
-       *   fontstyleMap.Insert( "slant", "italic" );
+       *   fontStyleMap.Insert( "weight", "bold" );
+       *   fontStyleMap.Insert( "width", "condensed" );
+       *   fontStyleMap.Insert( "slant", "italic" );
        *   propertyMap["placeholderFontStyle"] = fontStyleMap;
        *
        *   field.SetProperty( DevelTextField::Property::PLACEHOLDER, propertyMap );
index 501e61c..ce15c21 100644 (file)
@@ -101,6 +101,23 @@ enum Type
    * @details Name "frameDelay", type Property::INTEGER, The number of milliseconds between each frame. Note, this is only used with the URLS property above.
    */
   FRAME_DELAY = WRAP_MODE_V + 6,
+
+  /**
+   * @brief The scale factor to apply to the content image before masking
+   * @details Name "maskContentScale", type Property::FLOAT, The scale factor
+   * to apply to the content before masking. Note, scaled images are cropped to
+   * the same size as the alpha mask.
+   */
+  MASK_CONTENT_SCALE = WRAP_MODE_V + 7,
+
+  /**
+   * @brief Whether to crop image to mask or scale mask to fit image
+   * @details Name "cropToMask", type Property::BOOLEAN, True if the image should
+   * be cropped to match the mask size, or false if the image should remain the same size.
+   * Note, if this is false, then the mask is scaled to fit the image before being applied.
+   */
+  CROP_TO_MASK = WRAP_MODE_V + 8,
+
 };
 
 } //namespace Property
index 1e4d168..e763f2c 100644 (file)
@@ -674,7 +674,7 @@ void TextEditor::SetProperty( BaseObject* object, Property::Index index, const P
           const std::string& text = value.Get< std::string >();
           DALI_LOG_INFO( gLogFilter, Debug::General, "TextEditor::OnPropertySet %p PLACEHOLDER_TEXT %s\n", impl.mController.Get(), text.c_str() );
 
-          impl.mController->SetPlaceholderText( text );
+          impl.mController->SetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
         }
         break;
       }
@@ -1060,7 +1060,7 @@ Property::Value TextEditor::GetProperty( BaseObject* object, Property::Index ind
         if( impl.mController )
         {
           std::string text;
-          impl.mController->GetPlaceholderText( text );
+          impl.mController->GetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
           value = text;
         }
         break;
index 532afed..fef0f70 100644 (file)
@@ -71,7 +71,6 @@ EventData::EventData( DecoratorPtr decorator )
 : mDecorator( decorator ),
   mImfManager(),
   mPlaceholderFont( NULL ),
-  mPlaceholderText(),
   mPlaceholderTextActive(),
   mPlaceholderTextInactive(),
   mPlaceholderTextColor( 0.8f, 0.8f, 0.8f, 0.8f ),
index f48ce13..054f4a7 100644 (file)
@@ -106,7 +106,6 @@ struct EventData
   DecoratorPtr       mDecorator;               ///< Pointer to the decorator.
   ImfManager         mImfManager;              ///< The Input Method Framework Manager.
   FontDefaults*      mPlaceholderFont;         ///< The placeholder default font.
-  std::string        mPlaceholderText;         ///< The text to display when the TextField is empty.
   std::string        mPlaceholderTextActive;   ///< The text to display when the TextField is empty with key-input focus.
   std::string        mPlaceholderTextInactive; ///< The text to display when the TextField is empty and inactive.
   Vector4            mPlaceholderTextColor;    ///< The in/active placeholder text color.
@@ -387,9 +386,10 @@ struct Controller::Impl
    */
   bool IsPlaceholderAvailable() const
   {
-    return ( mEventData && ( !mEventData->mPlaceholderText.empty() ||
-                             !mEventData->mPlaceholderTextInactive.empty() ||
-                             !mEventData->mPlaceholderTextActive.empty() ) );
+    return ( mEventData &&
+             ( !mEventData->mPlaceholderTextInactive.empty() ||
+               !mEventData->mPlaceholderTextActive.empty() )
+           );
   }
 
   bool IsShowingPlaceholderText() const
@@ -402,8 +402,7 @@ struct Controller::Impl
    */
   bool IsFocusedPlaceholderAvailable() const
   {
-    return ( mEventData && ( !mEventData->mPlaceholderTextActive.empty() ||
-                             !mEventData->mPlaceholderText.empty() ) );
+    return ( mEventData && !mEventData->mPlaceholderTextActive.empty() );
   }
 
   bool IsShowingRealText() const
index a0daf14..fbd26bf 100644 (file)
@@ -48,6 +48,7 @@ const float MAX_FLOAT = std::numeric_limits<float>::max();
 const std::string EMPTY_STRING("");
 
 const char * const PLACEHOLDER_TEXT = "placeholderText";
+const char * const PLACEHOLDER_TEXT_FOCUSED = "placeholderTextFocused";
 const char * const PLACEHOLDER_COLOR = "placeholderColor";
 const char * const PLACEHOLDER_FONT_FAMILY = "placeholderFontFamily";
 const char * const PLACEHOLDER_FONT_STYLE = "placeholderFontStyle";
@@ -531,22 +532,6 @@ void Controller::GetText( std::string& text ) const
   }
 }
 
-void Controller::SetPlaceholderText( const std::string& text )
-{
-  if( NULL != mImpl->mEventData )
-  {
-    mImpl->mEventData->mPlaceholderText = text;
-
-    // Update placeholder if there is no text
-    if( mImpl->IsShowingPlaceholderText() ||
-        ( 0u == mImpl->mModel->mLogicalModel->mText.Count() ) )
-    {
-      ShowPlaceholderText();
-    }
-  }
-}
-
-// This is overloading function for PLACEHOLDER_TEXT_FOCUSED in text-field
 void Controller::SetPlaceholderText( PlaceholderType type, const std::string& text )
 {
   if( NULL != mImpl->mEventData )
@@ -569,15 +554,6 @@ void Controller::SetPlaceholderText( PlaceholderType type, const std::string& te
   }
 }
 
-void Controller::GetPlaceholderText( std::string& text ) const
-{
-  if( NULL != mImpl->mEventData )
-  {
-    text = mImpl->mEventData->mPlaceholderText;
-  }
-}
-
-// This is overloading function for PLACEHOLDER_TEXT_FOCUSED in text-field
 void Controller::GetPlaceholderText( PlaceholderType type, std::string& text ) const
 {
   if( NULL != mImpl->mEventData )
@@ -1918,7 +1894,13 @@ void Controller::SetPlaceholderProperty( const Property::Map& map )
     {
       std::string text = "";
       value.Get( text );
-      SetPlaceholderText( text );
+      SetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
+    }
+    else if( key == PLACEHOLDER_TEXT_FOCUSED )
+    {
+      std::string text = "";
+      value.Get( text );
+      SetPlaceholderText( Controller::PLACEHOLDER_TYPE_ACTIVE, text );
     }
     else if( key == PLACEHOLDER_COLOR )
     {
@@ -1964,7 +1946,15 @@ void Controller::GetPlaceholderProperty( Property::Map& map )
 {
   if( NULL != mImpl->mEventData )
   {
-    map[ PLACEHOLDER_TEXT ] = mImpl->mEventData->mPlaceholderText;
+    if( !mImpl->mEventData->mPlaceholderTextActive.empty() )
+    {
+      map[ PLACEHOLDER_TEXT_FOCUSED ] = mImpl->mEventData->mPlaceholderTextActive;
+    }
+    if( !mImpl->mEventData->mPlaceholderTextInactive.empty() )
+    {
+      map[ PLACEHOLDER_TEXT ] = mImpl->mEventData->mPlaceholderTextInactive;
+    }
+
     map[ PLACEHOLDER_COLOR ] = mImpl->mEventData->mPlaceholderTextColor;
     map[ PLACEHOLDER_FONT_FAMILY ] = GetPlaceholderFontFamily();
 
@@ -3554,27 +3544,17 @@ void Controller::ShowPlaceholderText()
     const char* text( NULL );
     size_t size( 0 );
 
-    if( !mImpl->mEventData->mPlaceholderTextActive.empty() || !mImpl->mEventData->mPlaceholderTextInactive.empty() )
+    // TODO - Switch Placeholder text when changing state
+    if( ( EventData::INACTIVE != mImpl->mEventData->mState ) &&
+        ( 0u != mImpl->mEventData->mPlaceholderTextActive.c_str() ) )
     {
-      if( ( EventData::INACTIVE != mImpl->mEventData->mState ) &&
-          ( 0u != mImpl->mEventData->mPlaceholderTextActive.c_str() ) )
-      {
-        text = mImpl->mEventData->mPlaceholderTextActive.c_str();
-        size = mImpl->mEventData->mPlaceholderTextActive.size();
-      }
-      else
-      {
-        text = mImpl->mEventData->mPlaceholderTextInactive.c_str();
-        size = mImpl->mEventData->mPlaceholderTextInactive.size();
-      }
+      text = mImpl->mEventData->mPlaceholderTextActive.c_str();
+      size = mImpl->mEventData->mPlaceholderTextActive.size();
     }
     else
     {
-      if( 0u != mImpl->mEventData->mPlaceholderText.c_str() )
-      {
-        text = mImpl->mEventData->mPlaceholderText.c_str();
-        size = mImpl->mEventData->mPlaceholderText.size();
-      }
+      text = mImpl->mEventData->mPlaceholderTextInactive.c_str();
+      size = mImpl->mEventData->mPlaceholderTextInactive.size();
     }
 
     mImpl->mTextUpdateInfo.mCharacterIndex = 0u;
index 9c80fc7..3d7639d 100644 (file)
@@ -466,13 +466,6 @@ public: // Update.
   /**
    * @brief Replaces any placeholder text previously set.
    *
-   * @param[in] text A string of UTF-8 characters.
-   */
-  void SetPlaceholderText( const std::string& text );
-
-  /**
-   * @brief Replaces any placeholder text previously set.
-   *
    * @param[in] type Different placeholder-text can be shown when the control is active/inactive.
    * @param[in] text A string of UTF-8 characters.
    */
@@ -481,13 +474,6 @@ public: // Update.
   /**
    * @brief Retrieve any placeholder text previously set.
    *
-   * @param[out] A string of UTF-8 characters.
-   */
-  void GetPlaceholderText( std::string& text ) const;
-
-  /**
-   * @brief Retrieve any placeholder text previously set.
-   *
    * @param[in] type Different placeholder-text can be shown when the control is active/inactive.
    * @param[out] A string of UTF-8 characters.
    */
index 7ce2f23..b558cfd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@
 // EXTERNAL HEADERS
 #include <cstring> // for strlen()
 #include <dali/public-api/actors/layer.h>
+#include <dali/public-api/common/stage.h>
 #include <dali/public-api/images/resource-image.h>
 #include <dali/public-api/images/native-image.h>
 #include <dali/devel-api/images/texture-set-image.h>
@@ -261,10 +262,9 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache,
   mPixelArea( FULL_TEXTURE_RECT ),
   mPlacementActor(),
   mImageUrl( imageUrl ),
-  mAlphaMaskUrl(),
+  mMaskingData( NULL ),
   mDesiredSize( size ),
   mTextureId( TextureManager::INVALID_TEXTURE_ID ),
-  mAlphaMaskId( TextureManager::INVALID_TEXTURE_ID ),
   mFittingMode( fittingMode ),
   mSamplingMode( samplingMode ),
   mWrapModeU( WrapMode::DEFAULT ),
@@ -281,10 +281,9 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, const Image& image )
   mPixelArea( FULL_TEXTURE_RECT ),
   mPlacementActor(),
   mImageUrl(),
-  mAlphaMaskUrl(),
+  mMaskingData( NULL ),
   mDesiredSize(),
   mTextureId( TextureManager::INVALID_TEXTURE_ID ),
-  mAlphaMaskId( TextureManager::INVALID_TEXTURE_ID ),
   mFittingMode( FittingMode::DEFAULT ),
   mSamplingMode( SamplingMode::DEFAULT ),
   mWrapModeU( WrapMode::DEFAULT ),
@@ -296,11 +295,7 @@ ImageVisual::ImageVisual( VisualFactoryCache& factoryCache, const Image& image )
 
 ImageVisual::~ImageVisual()
 {
-  if( mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID )
-  {
-    TextureManager& textureManager = mFactoryCache.GetTextureManager();
-    textureManager.Remove( mAlphaMaskId );
-  }
+  delete mMaskingData;
 }
 
 void ImageVisual::DoSetProperties( const Property::Map& propertyMap )
@@ -355,16 +350,17 @@ void ImageVisual::DoSetProperties( const Property::Map& propertyMap )
       {
         DoSetProperty( Toolkit::DevelImageVisual::Property::ALPHA_MASK_URL, keyValue.second );
       }
+      else if ( keyValue.first == MASK_CONTENT_SCALE_NAME )
+      {
+        DoSetProperty( Toolkit::DevelImageVisual::Property::MASK_CONTENT_SCALE, keyValue.second );
+      }
+      else if ( keyValue.first == CROP_TO_MASK_NAME )
+      {
+        DoSetProperty( Toolkit::DevelImageVisual::Property::CROP_TO_MASK, keyValue.second );
+      }
     }
   }
 
-  if( mAlphaMaskUrl.IsValid() )
-  {
-    // Immediately trigger the alpha mask loading (it may just get a cached value)
-    TextureManager& textureManager = mFactoryCache.GetTextureManager();
-    mAlphaMaskId = textureManager.RequestMaskLoad( mAlphaMaskUrl );
-  }
-
   if( ( mImpl->mFlags & Impl::IS_SYNCHRONOUS_RESOURCE_LOADING ) && mImageUrl.IsValid() )
   {
     // if sync loading is required, the loading should start
@@ -478,10 +474,43 @@ void ImageVisual::DoSetProperty( Property::Index index, const Property::Value& v
       std::string alphaUrl;
       if( value.Get( alphaUrl ) )
       {
-        mAlphaMaskUrl = VisualUrl( alphaUrl );
+        AllocateMaskData();
+        // Immediately trigger the alpha mask loading (it may just get a cached value)
+        mMaskingData->SetImage( alphaUrl );
       }
       break;
     }
+
+    case Toolkit::DevelImageVisual::Property::MASK_CONTENT_SCALE:
+    {
+      float scale;
+      if( value.Get( scale ) )
+      {
+        AllocateMaskData();
+        mMaskingData->mContentScaleFactor = scale;
+      }
+      break;
+    }
+
+    case Toolkit::DevelImageVisual::Property::CROP_TO_MASK:
+    {
+      bool crop=false;
+      if( value.Get( crop ) )
+      {
+        AllocateMaskData();
+        mMaskingData->mCropToMask = crop;
+      }
+      break;
+    }
+  }
+}
+
+void ImageVisual::AllocateMaskData()
+{
+  if( mMaskingData == NULL )
+  {
+    TextureManager& textureManager = mFactoryCache.GetTextureManager();
+    mMaskingData = new MaskingData(textureManager);
   }
 }
 
@@ -499,6 +528,18 @@ void ImageVisual::GetNaturalSize( Vector2& naturalSize )
     naturalSize.y = mDesiredSize.GetHeight();
     return;
   }
+
+  else if( mMaskingData != NULL && mMaskingData->mAlphaMaskUrl.IsValid() &&
+           mMaskingData->mCropToMask )
+  {
+    ImageDimensions dimensions = Dali::GetClosestImageSize( mMaskingData->mAlphaMaskUrl.GetUrl() );
+    if( dimensions != ImageDimensions( 0, 0 ) )
+    {
+      naturalSize.x = dimensions.GetWidth();
+      naturalSize.y = dimensions.GetHeight();
+    }
+    return;
+  }
   else if( mImageUrl.IsValid() && mImageUrl.GetLocation() == VisualUrl::LOCAL )
   {
     ImageDimensions dimensions = Dali::GetClosestImageSize( mImageUrl.GetUrl() );
@@ -688,16 +729,21 @@ TextureSet ImageVisual::CreateTextureSet( Vector4& textureRect, bool synchronous
     {
       mImpl->mFlags &= ~Impl::IS_ATLASING_APPLIED;
       TextureManager& textureManager = mFactoryCache.GetTextureManager();
-      if( mAlphaMaskId == TextureManager::INVALID_TEXTURE_ID )
+      if( mMaskingData == NULL )
       {
         mTextureId = textureManager.RequestLoad( mImageUrl, mDesiredSize, mFittingMode,
                                                  mSamplingMode, TextureManager::NO_ATLAS, this );
       }
       else
       {
-        mTextureId = textureManager.RequestLoad( mImageUrl, mAlphaMaskId, mDesiredSize,
+        mTextureId = textureManager.RequestLoad( mImageUrl,
+                                                 mMaskingData->mAlphaMaskId,
+                                                 mMaskingData->mContentScaleFactor,
+                                                 mDesiredSize,
                                                  mFittingMode, mSamplingMode,
-                                                 TextureManager::NO_ATLAS, this );
+                                                 TextureManager::NO_ATLAS,
+                                                 mMaskingData->mCropToMask,
+                                                 this );
       }
 
       TextureManager::LoadState loadState = textureManager.GetTextureState( mTextureId );
@@ -865,7 +911,12 @@ void ImageVisual::DoCreatePropertyMap( Property::Map& map ) const
   map.Insert( Toolkit::ImageVisual::Property::WRAP_MODE_V, mWrapModeV );
 
   map.Insert( Toolkit::DevelImageVisual::Property::ATLASING, mAttemptAtlasing );
-  map.Insert( Toolkit::DevelImageVisual::Property::ALPHA_MASK_URL, mAlphaMaskUrl.GetUrl() );
+  if( mMaskingData != NULL )
+  {
+    map.Insert( Toolkit::DevelImageVisual::Property::ALPHA_MASK_URL, mMaskingData->mAlphaMaskUrl.GetUrl() );
+    map.Insert( Toolkit::DevelImageVisual::Property::MASK_CONTENT_SCALE, mMaskingData->mContentScaleFactor );
+    map.Insert( Toolkit::DevelImageVisual::Property::CROP_TO_MASK, mMaskingData->mCropToMask );
+  }
 }
 
 void ImageVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
@@ -1023,6 +1074,36 @@ void ImageVisual::RemoveTexture(const std::string& url)
   }
 }
 
+
+ImageVisual::MaskingData::MaskingData( TextureManager& textureManager )
+: mTextureManager( textureManager ),
+  mAlphaMaskUrl(),
+  mAlphaMaskId( TextureManager::INVALID_TEXTURE_ID ),
+  mContentScaleFactor( 1.0f ),
+  mCropToMask( true )
+{
+}
+
+ImageVisual::MaskingData::~MaskingData()
+{
+  if( Stage::IsInstalled() )
+  {
+    // TextureManager could have been deleted before the actor that contains this
+    // ImageVisual is destroyed (e.g. due to stage shutdown). Ensure the stage
+    // is still valid before accessing texture manager.
+    if( mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID )
+    {
+      mTextureManager.Remove( mAlphaMaskId );
+    }
+  }
+}
+
+void ImageVisual::MaskingData::SetImage( const std::string& maskUrl )
+{
+  mAlphaMaskUrl = maskUrl;
+  mAlphaMaskId = mTextureManager.RequestMaskLoad( mAlphaMaskUrl );
+}
+
 } // namespace Internal
 
 } // namespace Toolkit
index ce03e6f..334406f 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_IMAGE_VISUAL_H
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -244,6 +244,11 @@ public:
 private:
 
   /**
+   * Allocate the mask data when a masking property is defined in the property map
+   */
+  void AllocateMaskData();
+
+  /**
    * @brief Applies the image to the texture set used for this renderer
    *
    * @param[in] image The Image to apply to the texture set used for this renderer
@@ -314,17 +319,28 @@ private:
   void DoSetProperty( Property::Index index, const Property::Value& value );
 
 private:
+  struct MaskingData
+  {
+    MaskingData( TextureManager& textureManager );
+    ~MaskingData();
+    void SetImage( const std::string& url );
+
+    TextureManager& mTextureManager;
+    VisualUrl mAlphaMaskUrl;
+    TextureManager::TextureId mAlphaMaskId;
+    float mContentScaleFactor;
+    bool mCropToMask;
+  };
 
   Image mImage;
   PixelData mPixels;
   Vector4 mPixelArea;
   WeakHandle<Actor> mPlacementActor;
   VisualUrl mImageUrl;
-  VisualUrl mAlphaMaskUrl;
+  MaskingData* mMaskingData;
 
   Dali::ImageDimensions mDesiredSize;
   TextureManager::TextureId mTextureId;
-  TextureManager::TextureId mAlphaMaskId;
 
   Dali::FittingMode::Type mFittingMode:3;
   Dali::SamplingMode::Type mSamplingMode:4;
@@ -334,6 +350,8 @@ private:
   bool mTextureLoading:1;  ///< True if the texture is being loaded asynchronously, or false when it has loaded.
 };
 
+
+
 } // namespace Internal
 
 } // namespace Toolkit
index b125a9e..824213e 100644 (file)
@@ -74,35 +74,39 @@ TextureManager::TextureId TextureManager::RequestLoad(
   const UseAtlas           useAtlas,
   TextureUploadObserver*   observer )
 {
-  return RequestLoadInternal( url, INVALID_TEXTURE_ID, desiredSize, fittingMode, samplingMode, useAtlas, UPLOAD_TO_TEXTURE, observer );
+  return RequestLoadInternal( url, INVALID_TEXTURE_ID, 1.0f, desiredSize, fittingMode, samplingMode, useAtlas, false, UPLOAD_TO_TEXTURE, observer );
 }
 
 TextureManager::TextureId TextureManager::RequestLoad(
   const VisualUrl&         url,
   TextureId                maskTextureId,
+  float                    contentScale,
   const ImageDimensions    desiredSize,
   FittingMode::Type        fittingMode,
   Dali::SamplingMode::Type samplingMode,
   const UseAtlas           useAtlas,
+  bool                     cropToMask,
   TextureUploadObserver*   observer )
 {
-  return RequestLoadInternal( url, maskTextureId, desiredSize, fittingMode, samplingMode, useAtlas, UPLOAD_TO_TEXTURE, observer );
+  return RequestLoadInternal( url, maskTextureId, contentScale, desiredSize, fittingMode, samplingMode, useAtlas, cropToMask, UPLOAD_TO_TEXTURE, observer );
 }
 
 TextureManager::TextureId TextureManager::RequestMaskLoad( const VisualUrl& maskUrl )
 {
   // Use the normal load procedure to get the alpha mask.
-  return RequestLoadInternal( maskUrl, INVALID_TEXTURE_ID, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, NO_ATLAS, KEEP_PIXEL_BUFFER, NULL );
+  return RequestLoadInternal( maskUrl, INVALID_TEXTURE_ID, 1.0f, ImageDimensions(), FittingMode::SCALE_TO_FILL, SamplingMode::NO_FILTER, NO_ATLAS, false, KEEP_PIXEL_BUFFER, NULL );
 }
 
 
 TextureManager::TextureId TextureManager::RequestLoadInternal(
   const VisualUrl&         url,
   TextureId                maskTextureId,
+  float                    contentScale,
   const ImageDimensions    desiredSize,
   FittingMode::Type        fittingMode,
   Dali::SamplingMode::Type samplingMode,
   UseAtlas                 useAtlas,
+  bool                     cropToMask,
   StorageType              storageType,
   TextureUploadObserver*   observer )
 {
@@ -129,8 +133,8 @@ TextureManager::TextureId TextureManager::RequestLoadInternal(
     // We need a new Texture.
     textureId = GenerateUniqueTextureId();
     mTextureInfoContainer.push_back( TextureInfo( textureId, maskTextureId, url.GetUrl(),
-                                                  desiredSize, fittingMode, samplingMode,
-                                                  false, useAtlas, textureHash ) );
+                                                  desiredSize, contentScale, fittingMode, samplingMode,
+                                                  false, cropToMask, useAtlas, textureHash ) );
     cacheIndex = mTextureInfoContainer.size() - 1u;
 
     DALI_LOG_INFO( gTextureManagerLogFilter, Debug::Concise, "TextureManager::RequestLoad( url=%s observer=%p ) New texture, cacheIndex:%d, textureId=%d\n", url.GetUrl().c_str(), observer, cacheIndex, textureId );
@@ -388,7 +392,7 @@ void TextureManager::PostLoad( TextureInfo& textureInfo, Devel::PixelBuffer& pix
         }
         else if( maskLoadState == LOAD_FINISHED )
         {
-          ApplyMask( pixelBuffer, textureInfo.maskTextureId );
+          ApplyMask( pixelBuffer, textureInfo.maskTextureId, textureInfo.scaleFactor, textureInfo.cropToMask );
           UploadTexture( pixelBuffer, textureInfo );
           NotifyObservers( textureInfo, true );
         }
@@ -436,7 +440,7 @@ void TextureManager::CheckForWaitingTexture( TextureInfo& maskTextureInfo )
 
       if( maskTextureInfo.loadState == LOAD_FINISHED )
       {
-        ApplyMask( pixelBuffer, maskTextureInfo.textureId );
+        ApplyMask( pixelBuffer, maskTextureInfo.textureId, textureInfo.scaleFactor, textureInfo.cropToMask );
         UploadTexture( pixelBuffer, textureInfo );
         NotifyObservers( textureInfo, true );
       }
@@ -450,11 +454,13 @@ void TextureManager::CheckForWaitingTexture( TextureInfo& maskTextureInfo )
   }
 }
 
-void TextureManager::ApplyMask( Devel::PixelBuffer& pixelBuffer, TextureId maskTextureId )
+void TextureManager::ApplyMask(
+  Devel::PixelBuffer& pixelBuffer, TextureId maskTextureId,
+  float contentScale, bool cropToMask )
 {
   int maskCacheIndex = GetCacheIndexFromId( maskTextureId );
   Devel::PixelBuffer maskPixelBuffer = mTextureInfoContainer[maskCacheIndex].pixelBuffer;
-  pixelBuffer.ApplyMask( maskPixelBuffer );
+  pixelBuffer.ApplyMask( maskPixelBuffer, contentScale, cropToMask );
 }
 
 void TextureManager::UploadTexture( Devel::PixelBuffer& pixelBuffer, TextureInfo& textureInfo )
index 04faf46..5e07735 100644 (file)
@@ -150,21 +150,26 @@ public:
    * When the client has finished with the Texture, Remove() should be called.
    *
    * @param[in] url               The URL of the image to load
+   * @param[in] maskTextureId     The texture id of an image to mask this with (can be INVALID if no masking required)
+   * @param[in] contentScale      The scale factor to apply to the image before masking
    * @param[in] desiredSize       The size the image is likely to appear at. This can be set to 0,0 for automatic
    * @param[in] fittingMode       The FittingMode to use
    * @param[in] samplingMode      The SamplingMode to use
    * @param[in] useAtlasing       Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
    *                              but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
+   * @param[in] cropToMask        Only used with masking, this will crop the scaled image to the mask size. If false, then the mask will be scaled to fit the image before being applied.
    * @param[in] observer          The client object should inherit from this and provide the "UploadCompleted" virtual.
    *                              This is called when an image load completes (or fails).
    * @return                      A TextureId to use as a handle to reference this Texture
    */
   TextureId RequestLoad( const VisualUrl&         url,
                          TextureId                maskTextureId,
+                         float                    contentScale,
                          const ImageDimensions    desiredSize,
                          FittingMode::Type        fittingMode,
                          Dali::SamplingMode::Type samplingMode,
                          const UseAtlas           useAtlasing,
+                         bool                     cropToMask,
                          TextureUploadObserver*   observer );
 
   /**
@@ -217,11 +222,13 @@ private:
    *
    * @param[in] url               The URL of the image to load
    * @param[in] maskTextureId     The texture id of an image to use as a mask. If no mask is required, then set to INVALID_TEXTURE_ID
+   * @param[in] contentScale      The scaling factor to apply to the content when masking
    * @param[in] desiredSize       The size the image is likely to appear at. This can be set to 0,0 for automatic
    * @param[in] fittingMode       The FittingMode to use
    * @param[in] samplingMode      The SamplingMode to use
    * @param[in] useAtlasing       Set to USE_ATLAS to attempt atlasing. If atlasing fails, the image will still be loaded, and marked successful,
    *                              but "useAtlasing" will be set to false in the "UploadCompleted" callback from the TextureManagerUploadObserver.
+   * @param[in] cropToMask        Whether to crop the target after masking, or scale the mask to the image before masking.
    * @param[in] storageType,      Whether the pixel data is stored in the cache or uploaded to the GPU
    * @param[in] observer          The client object should inherit from this and provide the "UploadCompleted" virtual.
    *                              This is called when an image load completes (or fails).
@@ -230,10 +237,12 @@ private:
   TextureId RequestLoadInternal(
     const VisualUrl&         url,
     TextureId                maskTextureId,
+    float                    contentScale,
     const ImageDimensions    desiredSize,
     FittingMode::Type        fittingMode,
     Dali::SamplingMode::Type samplingMode,
     UseAtlas                 useAtlas,
+    bool                     cropToMask,
     StorageType              storageType,
     TextureUploadObserver*   observer );
 
@@ -249,9 +258,11 @@ private:
                  TextureId maskTextureId,
                  const VisualUrl& url,
                  ImageDimensions desiredSize,
+                 float scaleFactor,
                  FittingMode::Type fittingMode,
                  Dali::SamplingMode::Type samplingMode,
                  bool loadSynchronously,
+                 bool cropToMask,
                  UseAtlas useAtlas,
                  TextureManager::TextureHash hash )
     : url( url ),
@@ -261,13 +272,15 @@ private:
       textureId( textureId ),
       maskTextureId( maskTextureId ),
       hash( hash ),
+      scaleFactor( scaleFactor ),
       referenceCount( 1u ),
       loadState( NOT_STARTED ),
       fittingMode( fittingMode ),
       samplingMode( samplingMode ),
       storageType( UPLOAD_TO_TEXTURE ),
       loadSynchronously( loadSynchronously ),
-      useAtlas( useAtlas )
+      useAtlas( useAtlas ),
+      cropToMask( cropToMask )
     {
     }
 
@@ -287,6 +300,7 @@ private:
     TextureId textureId;           ///< The TextureId associated with this Texture
     TextureId maskTextureId;       ///< The mask TextureId to be applied on load
     TextureManager::TextureHash hash; ///< The hash used to cache this Texture
+    float scaleFactor;             ///< The scale factor to apply to the Texture when masking
     int16_t referenceCount;        ///< The reference count of clients using this Texture
     LoadState loadState:3;         ///< The load state showing the load progress of the Texture
     FittingMode::Type fittingMode:2; ///< The requested FittingMode
@@ -294,6 +308,7 @@ private:
     StorageType storageType:1;     ///< CPU storage / GPU upload;
     bool loadSynchronously:1;      ///< True if synchronous loading was requested
     UseAtlas useAtlas:1;           ///< USE_ATLAS if an atlas was requested. This is updated to false if atlas is not used
+    bool cropToMask:1;             ///< true if the image should be cropped to the mask size.
   };
 
   // Structs:
@@ -390,8 +405,11 @@ private:
    * Apply the mask to the pixelBuffer.
    * @param[in] pixelBuffer The pixelBuffer to apply the mask to
    * @param[in] maskTextureId The texture id of the mask.
+   * @param[in] contentScale The factor to scale the content
+   * @param[in] cropToMask Whether to crop the content to the mask size
    */
-  void ApplyMask( Devel::PixelBuffer& pixelBuffer, TextureId maskTextureId );
+  void ApplyMask( Devel::PixelBuffer& pixelBuffer, TextureId maskTextureId,
+                  float contentScale, bool cropToMask );
 
   /**
    * Upload the texture specified in pixelBuffer to the appropriate location
@@ -446,7 +464,6 @@ private:
                             const FittingMode::Type fittingMode,
                             const Dali::SamplingMode::Type samplingMode, const UseAtlas useAtlas,
                             TextureId maskTextureId );
-
   /**
    * @brief Looks up a cached texture by its hash.
    * If found, the given parameters are used to check there is no hash-collision.
index 81af2a0..c47063f 100644 (file)
@@ -1,5 +1,5 @@
  /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -84,6 +84,8 @@ const char * const ANIMATED_IMAGE_URLS_NAME("urls");
 const char * const BATCH_SIZE_NAME("batchSize");
 const char * const CACHE_SIZE_NAME("cacheSize");
 const char * const FRAME_DELAY_NAME("frameDelay");
+const char * const MASK_CONTENT_SCALE_NAME("maskContentScale");
+const char * const CROP_TO_MASK_NAME("cropToMask");
 
 // Text visual
 const char * const TEXT_PROPERTY( "text" );
index 3bbb95e..4731f4a 100644 (file)
@@ -2,7 +2,7 @@
 #define DALI_TOOLKIT_INTERNAL_VISUAL_STRING_CONSTANTS_H
 
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -71,6 +71,8 @@ extern const char * const ANIMATED_IMAGE_URLS_NAME;
 extern const char * const BATCH_SIZE_NAME;
 extern const char * const CACHE_SIZE_NAME;
 extern const char * const FRAME_DELAY_NAME;
+extern const char * const MASK_CONTENT_SCALE_NAME;
+extern const char * const CROP_TO_MASK_NAME;
 
 // Text visual
 extern const char * const TEXT_PROPERTY;