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;
+}
#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;
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 );
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;
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;
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;
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;
* @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 );
* @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 );
* @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
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;
}
if( impl.mController )
{
std::string text;
- impl.mController->GetPlaceholderText( text );
+ impl.mController->GetPlaceholderText( Controller::PLACEHOLDER_TYPE_INACTIVE, text );
value = text;
}
break;
: mDecorator( decorator ),
mImfManager(),
mPlaceholderFont( NULL ),
- mPlaceholderText(),
mPlaceholderTextActive(),
mPlaceholderTextInactive(),
mPlaceholderTextColor( 0.8f, 0.8f, 0.8f, 0.8f ),
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.
*/
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
*/
bool IsFocusedPlaceholderAvailable() const
{
- return ( mEventData && ( !mEventData->mPlaceholderTextActive.empty() ||
- !mEventData->mPlaceholderText.empty() ) );
+ return ( mEventData && !mEventData->mPlaceholderTextActive.empty() );
}
bool IsShowingRealText() const
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";
}
}
-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 )
}
}
-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 )
{
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 )
{
{
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();
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;
/**
* @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.
*/
/**
* @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.
*/
/*
- * 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.
// 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>
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 ),
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 ),
ImageVisual::~ImageVisual()
{
- if( mAlphaMaskId != TextureManager::INVALID_TEXTURE_ID )
- {
- TextureManager& textureManager = mFactoryCache.GetTextureManager();
- textureManager.Remove( mAlphaMaskId );
- }
+ delete mMaskingData;
}
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
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);
}
}
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() );
{
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 );
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
}
}
+
+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
#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.
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
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;
bool mTextureLoading:1; ///< True if the texture is being loaded asynchronously, or false when it has loaded.
};
+
+
} // namespace Internal
} // namespace Toolkit
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 )
{
// 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 );
}
else if( maskLoadState == LOAD_FINISHED )
{
- ApplyMask( pixelBuffer, textureInfo.maskTextureId );
+ ApplyMask( pixelBuffer, textureInfo.maskTextureId, textureInfo.scaleFactor, textureInfo.cropToMask );
UploadTexture( pixelBuffer, textureInfo );
NotifyObservers( textureInfo, true );
}
if( maskTextureInfo.loadState == LOAD_FINISHED )
{
- ApplyMask( pixelBuffer, maskTextureInfo.textureId );
+ ApplyMask( pixelBuffer, maskTextureInfo.textureId, textureInfo.scaleFactor, textureInfo.cropToMask );
UploadTexture( pixelBuffer, textureInfo );
NotifyObservers( textureInfo, true );
}
}
}
-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 )
* 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 );
/**
*
* @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).
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 );
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 ),
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 )
{
}
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
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:
* 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
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.
/*
- * 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.
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" );
#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.
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;
const unsigned int TOOLKIT_MAJOR_VERSION = 1;
const unsigned int TOOLKIT_MINOR_VERSION = 2;
-const unsigned int TOOLKIT_MICRO_VERSION = 48;
+const unsigned int TOOLKIT_MICRO_VERSION = 49;
const char * const TOOLKIT_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
Name: dali-toolkit
Summary: The OpenGLES Canvas Core Library Toolkit
-Version: 1.2.48
+Version: 1.2.49
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT