+ Property::Map transformMap = Property::Map();
+
+ Extents padding = Self().GetProperty<Extents>( Toolkit::Control::Property::PADDING );
+
+ bool zeroPadding = ( padding == Extents() );
+
+ Vector2 naturalSize;
+ mVisual.GetNaturalSize( naturalSize );
+
+ Dali::LayoutDirection::Type layoutDirection = static_cast<Dali::LayoutDirection::Type>(
+ Self().GetProperty( Dali::Actor::Property::LAYOUT_DIRECTION ).Get<int>() );
+ if( Dali::LayoutDirection::RIGHT_TO_LEFT == layoutDirection )
+ {
+ std::swap( padding.start, padding.end );
+ }
+
+ // remove padding from the size to know how much is left for the visual
+ Vector2 finalSize = size - Vector2( padding.start + padding.end, padding.top + padding.bottom );
+ Vector2 finalOffset = Vector2( padding.start, padding.top );
+
+ ApplyFittingMode( finalSize, naturalSize, finalOffset, zeroPadding , transformMap );
+
+ mVisual.SetTransformAndSize( transformMap, size );
+
+ // mVisual is not updated util the resource is ready in the case of visual replacement.
+ // in this case, the Property Map must be initialized so that the previous value is not reused.
+ // after mVisual is updated, the correct value will be reset.
+ Toolkit::Visual::Base visual = DevelControl::GetVisual( *this, Toolkit::ImageView::Property::IMAGE );
+ if( visual && visual != mVisual )
+ {
+ visual.SetTransformAndSize( Property::Map(), size );
+ }
+ }
+}
+
+void ImageView::OnResourceReady( Toolkit::Control control )
+{
+ // Visual ready so update visual attached to this ImageView, following call to RelayoutRequest will use this visual.
+ mVisual = DevelControl::GetVisual( *this, Toolkit::ImageView::Property::IMAGE );
+ // Signal that a Relayout may be needed
+}
+
+void ImageView::SetTransformMapForFittingMode( Vector2 finalSize, Vector2 naturalSize, Vector2 finalOffset, Visual::FittingMode fittingMode, Property::Map& transformMap )
+{
+ switch(fittingMode)
+ {
+ case Visual::FittingMode::FIT_KEEP_ASPECT_RATIO:
+ {
+ auto availableVisualSize = finalSize;
+
+ // scale to fit the padded area
+ finalSize = naturalSize * std::min( ( naturalSize.width ? ( availableVisualSize.width / naturalSize.width ) : 0 ),
+ ( naturalSize.height ? ( availableVisualSize.height / naturalSize.height ) : 0 ) );
+
+ // calculate final offset within the padded area
+ finalOffset += ( availableVisualSize - finalSize ) * .5f;
+
+ // populate the transform map
+ transformMap.Add( Toolkit::Visual::Transform::Property::OFFSET, finalOffset )
+ .Add( Toolkit::Visual::Transform::Property::SIZE, finalSize );
+ break;
+ }
+ case Visual::FittingMode::OVER_FIT_KEEP_ASPECT_RATIO:
+ {
+ mImageViewPixelAreaSetByFittingMode = true;
+ auto availableVisualSize = finalSize;
+ finalSize = naturalSize * std::max( ( naturalSize.width ? ( availableVisualSize.width / naturalSize.width ) : 0 ),
+ ( naturalSize.height ? ( availableVisualSize.height / naturalSize.height ) : 0 ) );
+
+ auto originalOffset = finalOffset;
+ finalOffset += ( availableVisualSize - finalSize ) * .5f;
+
+ float x = abs( (availableVisualSize.width - finalSize.width ) / finalSize.width )* .5f;
+ float y = abs( (availableVisualSize.height - finalSize.height ) / finalSize.height ) * .5f;
+ float widthRatio = 1.f - abs( (availableVisualSize.width - finalSize.width ) / finalSize.width );
+ float heightRatio = 1.f - abs( (availableVisualSize.height - finalSize.height ) / finalSize.height );
+ Vector4 pixelArea = Vector4( x, y, widthRatio, heightRatio);
+ Self().SetProperty( Toolkit::ImageView::Property::PIXEL_AREA, pixelArea );
+
+ // populate the transform map
+ transformMap.Add( Toolkit::Visual::Transform::Property::OFFSET, originalOffset )
+ .Add( Toolkit::Visual::Transform::Property::SIZE, availableVisualSize );
+ break;
+ }
+ case Visual::FittingMode::CENTER:
+ {
+ auto availableVisualSize = finalSize;
+ if( availableVisualSize.width > naturalSize.width && availableVisualSize.height > naturalSize.height )
+ {
+ finalSize = naturalSize;
+ }
+ else
+ {
+ finalSize = naturalSize * std::min( ( naturalSize.width ? ( availableVisualSize.width / naturalSize.width ) : 0 ),
+ ( naturalSize.height ? ( availableVisualSize.height / naturalSize.height ) : 0 ) );
+ }
+
+ finalOffset += ( availableVisualSize - finalSize ) * .5f;
+
+ // populate the transform map
+ transformMap.Add( Toolkit::Visual::Transform::Property::OFFSET, finalOffset )
+ .Add( Toolkit::Visual::Transform::Property::SIZE, finalSize );
+ break;
+ }
+ case Visual::FittingMode::FILL:
+ {
+ transformMap.Add( Toolkit::Visual::Transform::Property::OFFSET, finalOffset )
+ .Add( Toolkit::Visual::Transform::Property::SIZE, finalSize );
+ break;
+ }
+ case Visual::FittingMode::FIT_WIDTH:
+ case Visual::FittingMode::FIT_HEIGHT:
+ {
+ // This FittingMode already converted
+ break;
+ }