+ // 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;
+ }
+ }
+}
+
+void ImageView::ApplyFittingMode( Vector2 finalSize, Vector2 naturalSize, Vector2 finalOffset, bool zeroPadding , Property::Map& transformMap )
+{
+ Visual::FittingMode fittingMode = Toolkit::GetImplementation(mVisual).GetFittingMode();
+
+ // Reset PIXEL_AREA after using OVER_FIT_KEEP_ASPECT_RATIO
+ if( mImageViewPixelAreaSetByFittingMode )
+ {
+ Self().SetProperty( Toolkit::ImageView::Property::PIXEL_AREA, FULL_TEXTURE_RECT );
+ mImageViewPixelAreaSetByFittingMode = false;
+ }
+
+ if( ( !zeroPadding ) || // If padding is not zero
+ ( fittingMode != Visual::FittingMode::FILL ) )
+ {
+ mImageVisualPaddingSetByTransform = true;
+
+ // If FittingMode use FIT_WIDTH or FIT_HEIGTH, it need to change proper fittingMode
+ if( fittingMode == Visual::FittingMode::FIT_WIDTH )
+ {
+ fittingMode = ( finalSize.height / naturalSize.height ) < ( finalSize.width / naturalSize.width ) ? Visual::FittingMode::OVER_FIT_KEEP_ASPECT_RATIO : Visual::FittingMode::FIT_KEEP_ASPECT_RATIO;
+ }
+ else if( fittingMode == Visual::FittingMode::FIT_HEIGHT )
+ {
+ fittingMode = ( finalSize.height / naturalSize.height ) < ( finalSize.width / naturalSize.width ) ? Visual::FittingMode::FIT_KEEP_ASPECT_RATIO : Visual::FittingMode::OVER_FIT_KEEP_ASPECT_RATIO;
+ }
+
+ SetTransformMapForFittingMode( finalSize, naturalSize, finalOffset, fittingMode, transformMap );
+
+ // Set extra value for applying transformMap
+ transformMap.Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY,
+ Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) )
+ .Add( Toolkit::Visual::Transform::Property::ORIGIN, Toolkit::Align::TOP_BEGIN )
+ .Add( Toolkit::Visual::Transform::Property::ANCHOR_POINT, Toolkit::Align::TOP_BEGIN )
+ .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY,
+ Vector2( Toolkit::Visual::Transform::Policy::ABSOLUTE, Toolkit::Visual::Transform::Policy::ABSOLUTE ) );
+ }
+ else if ( mImageVisualPaddingSetByTransform && zeroPadding ) // Reset offset to zero only if padding applied previously
+ {
+ mImageVisualPaddingSetByTransform = false;
+ // Reset the transform map
+ transformMap.Add( Toolkit::Visual::Transform::Property::OFFSET, Vector2::ZERO )
+ .Add( Toolkit::Visual::Transform::Property::OFFSET_POLICY,
+ Vector2( Toolkit::Visual::Transform::Policy::RELATIVE, Toolkit::Visual::Transform::Policy::RELATIVE ) )
+ .Add( Toolkit::Visual::Transform::Property::SIZE, Vector2::ONE )
+ .Add( Toolkit::Visual::Transform::Property::SIZE_POLICY,
+ Vector2( Toolkit::Visual::Transform::Policy::RELATIVE, Toolkit::Visual::Transform::Policy::RELATIVE ) );
+ }