diff --git a/python/core/composer/qgscomposerpicture.sip b/python/core/composer/qgscomposerpicture.sip
index 4238496a91a..ad0177b4bfb 100644
--- a/python/core/composer/qgscomposerpicture.sip
+++ b/python/core/composer/qgscomposerpicture.sip
@@ -117,6 +117,22 @@ class QgsComposerPicture: QgsComposerItem
*/
ResizeMode resizeMode() const;
+ /**Sets the picture's anchor point, which controls how it is placed
+ * within the picture item's frame.
+ * @param anchor anchor point for picture
+ * @note added in 2.3
+ * @see pictureAnchor
+ */
+ void setPictureAnchor( QgsComposerItem::ItemPositionMode anchor );
+
+ /**Returns the picture's current anchor, which controls how it is placed
+ * within the picture item's frame.
+ * @returns anchor point for picture
+ * @note added in 2.3
+ * @see setPictureAnchor
+ */
+ ItemPositionMode pictureAnchor() const;
+
/**Returns whether the picture item is using an expression for the image source.
* @returns true if the picture is using an expression for the source, false if
* it is using a single static file path for the source.
diff --git a/src/app/composer/qgscomposerpicturewidget.cpp b/src/app/composer/qgscomposerpicturewidget.cpp
index d8687a46cde..2373a4101a3 100644
--- a/src/app/composer/qgscomposerpicturewidget.cpp
+++ b/src/app/composer/qgscomposerpicturewidget.cpp
@@ -245,6 +245,29 @@ void QgsComposerPictureWidget::on_mResizeModeComboBox_currentIndexChanged( int i
//disable picture rotation for non-zoom modes
mRotationGroupBox->setEnabled( mPicture->resizeMode() == QgsComposerPicture::Zoom );
+
+ //disable anchor point control for certain zoom modes
+ if ( mPicture->resizeMode() == QgsComposerPicture::Zoom ||
+ mPicture->resizeMode() == QgsComposerPicture::Clip )
+ {
+ mAnchorPointComboBox->setEnabled( true );
+ }
+ else
+ {
+ mAnchorPointComboBox->setEnabled( false );
+ }
+}
+
+void QgsComposerPictureWidget::on_mAnchorPointComboBox_currentIndexChanged( int index )
+{
+ if ( !mPicture )
+ {
+ return;
+ }
+
+ mPicture->beginCommand( tr( "Picture placement changed" ) );
+ mPicture->setPictureAnchor(( QgsComposerItem::ItemPositionMode )index );
+ mPicture->endCommand();
}
void QgsComposerPictureWidget::on_mRadioPath_clicked()
@@ -422,12 +445,12 @@ void QgsComposerPictureWidget::setGuiElementValues()
mComposerMapComboBox->blockSignals( true );
mRotationFromComposerMapCheckBox->blockSignals( true );
mResizeModeComboBox->blockSignals( true );
+ mAnchorPointComboBox->blockSignals( true );
mRadioPath->blockSignals( true );
mRadioExpression->blockSignals( true );
mPictureExpressionLineEdit->blockSignals( true );
mPictureLineEdit->setText( mPicture->pictureFile() );
-// QRectF pictureRect = mPicture->rect();
mPictureRotationSpinBox->setValue( mPicture->pictureRotation() );
refreshMapComboBox();
@@ -455,6 +478,18 @@ void QgsComposerPictureWidget::setGuiElementValues()
//disable picture rotation for non-zoom modes
mRotationGroupBox->setEnabled( mPicture->resizeMode() == QgsComposerPicture::Zoom );
+ mAnchorPointComboBox->setCurrentIndex(( int )mPicture->pictureAnchor() );
+ //disable anchor point control for certain zoom modes
+ if ( mPicture->resizeMode() == QgsComposerPicture::Zoom ||
+ mPicture->resizeMode() == QgsComposerPicture::Clip )
+ {
+ mAnchorPointComboBox->setEnabled( true );
+ }
+ else
+ {
+ mAnchorPointComboBox->setEnabled( false );
+ }
+
mRadioPath->setChecked( !( mPicture->usePictureExpression() ) );
mRadioExpression->setChecked( mPicture->usePictureExpression() );
mPictureLineEdit->setEnabled( !( mPicture->usePictureExpression() ) );
@@ -469,6 +504,7 @@ void QgsComposerPictureWidget::setGuiElementValues()
mPictureLineEdit->blockSignals( false );
mComposerMapComboBox->blockSignals( false );
mResizeModeComboBox->blockSignals( false );
+ mAnchorPointComboBox->blockSignals( false );
mRadioPath->blockSignals( false );
mRadioExpression->blockSignals( false );
mPictureExpressionLineEdit->blockSignals( false );
diff --git a/src/app/composer/qgscomposerpicturewidget.h b/src/app/composer/qgscomposerpicturewidget.h
index 725b1e54c0e..e142fd37604 100644
--- a/src/app/composer/qgscomposerpicturewidget.h
+++ b/src/app/composer/qgscomposerpicturewidget.h
@@ -30,6 +30,7 @@ class QgsComposerPictureWidget: public QWidget, private Ui::QgsComposerPictureWi
Q_OBJECT
public:
+
QgsComposerPictureWidget( QgsComposerPicture* picture );
~QgsComposerPictureWidget();
@@ -47,6 +48,7 @@ class QgsComposerPictureWidget: public QWidget, private Ui::QgsComposerPictureWi
void on_mRotationFromComposerMapCheckBox_stateChanged( int state );
void on_mComposerMapComboBox_activated( const QString & text );
void on_mResizeModeComboBox_currentIndexChanged( int index );
+ void on_mAnchorPointComboBox_currentIndexChanged( int index );
void on_mRadioPath_clicked();
void on_mRadioExpression_clicked();
void setPictureExpression();
diff --git a/src/core/composer/qgscomposerpicture.cpp b/src/core/composer/qgscomposerpicture.cpp
index 12e2eb02ed6..22a30b83377 100644
--- a/src/core/composer/qgscomposerpicture.cpp
+++ b/src/core/composer/qgscomposerpicture.cpp
@@ -38,6 +38,7 @@ QgsComposerPicture::QgsComposerPicture( QgsComposition *composition ) :
mPictureRotation( 0 ),
mRotationMap( 0 ),
mResizeMode( QgsComposerPicture::Zoom ),
+ mPictureAnchor( UpperLeft ),
mPictureExpr( 0 )
{
mPictureWidth = rect().width();
@@ -50,6 +51,7 @@ QgsComposerPicture::QgsComposerPicture() : QgsComposerItem( 0 ),
mPictureRotation( 0 ),
mRotationMap( 0 ),
mResizeMode( QgsComposerPicture::Zoom ),
+ mPictureAnchor( UpperLeft ),
mPictureExpr( 0 )
{
mPictureHeight = rect().height();
@@ -90,40 +92,99 @@ void QgsComposerPicture::paint( QPainter* painter, const QStyleOptionGraphicsIte
//int newDpi = ( painter->device()->logicalDpiX() + painter->device()->logicalDpiY() ) / 2;
+ //picture resizing
if ( mMode != Unknown )
{
double boundRectWidthMM;
double boundRectHeightMM;
- double imageRectWidthMM;
- double imageRectHeightMM;
+ QRect imageRect;
if ( mResizeMode == QgsComposerPicture::Zoom || mResizeMode == QgsComposerPicture::ZoomResizeFrame )
{
boundRectWidthMM = mPictureWidth;
boundRectHeightMM = mPictureHeight;
- imageRectWidthMM = mImage.width();
- imageRectHeightMM = mImage.height();
+ imageRect = QRect( 0, 0, mImage.width(), mImage.height() );
}
else if ( mResizeMode == QgsComposerPicture::Stretch )
{
boundRectWidthMM = rect().width();
boundRectHeightMM = rect().height();
- imageRectWidthMM = mImage.width();
- imageRectHeightMM = mImage.height();
+ imageRect = QRect( 0, 0, mImage.width(), mImage.height() );
+ }
+ else if ( mResizeMode == QgsComposerPicture::Clip )
+ {
+ boundRectWidthMM = rect().width();
+ boundRectHeightMM = rect().height();
+ int imageRectWidthPixels = mImage.width();
+ int imageRectHeightPixels = mImage.height();
+ imageRect = clippedImageRect( boundRectWidthMM, boundRectHeightMM ,
+ QSize( imageRectWidthPixels, imageRectHeightPixels ) );
}
else
{
boundRectWidthMM = rect().width();
boundRectHeightMM = rect().height();
- imageRectWidthMM = rect().width() * mComposition->printResolution() / 25.4;
- imageRectHeightMM = rect().height() * mComposition->printResolution() / 25.4;
+ imageRect = QRect( 0, 0, rect().width() * mComposition->printResolution() / 25.4,
+ rect().height() * mComposition->printResolution() / 25.4 );
}
painter->save();
+ //zoom mode - calculate anchor point and rotation
if ( mResizeMode == Zoom )
{
- painter->translate( rect().width() / 2.0, rect().height() / 2.0 );
- painter->rotate( mPictureRotation );
- painter->translate( -boundRectWidthMM / 2.0, -boundRectHeightMM / 2.0 );
+ //TODO - allow placement modes with rotation set. for now, setting a rotation
+ //always places picture in center of frame
+ if ( mPictureRotation != 0 )
+ {
+ painter->translate( rect().width() / 2.0, rect().height() / 2.0 );
+ painter->rotate( mPictureRotation );
+ painter->translate( -boundRectWidthMM / 2.0, -boundRectHeightMM / 2.0 );
+ }
+ else
+ {
+ //shift painter to edge/middle of frame depending on placement
+ double diffX = rect().width() - boundRectWidthMM;
+ double diffY = rect().height() - boundRectHeightMM;
+
+ double dX = 0;
+ double dY = 0;
+ switch ( mPictureAnchor )
+ {
+ case UpperLeft:
+ case MiddleLeft:
+ case LowerLeft:
+ //nothing to do
+ break;
+ case UpperMiddle:
+ case Middle:
+ case LowerMiddle:
+ dX = diffX / 2.0;
+ break;
+ case UpperRight:
+ case MiddleRight:
+ case LowerRight:
+ dX = diffX;
+ break;
+ }
+ switch ( mPictureAnchor )
+ {
+ case UpperLeft:
+ case UpperMiddle:
+ case UpperRight:
+ //nothing to do
+ break;
+ case MiddleLeft:
+ case Middle:
+ case MiddleRight:
+ dY = diffY / 2.0;
+ break;
+ case LowerLeft:
+ case LowerMiddle:
+ case LowerRight:
+ dY = diffY;
+ break;
+ }
+ painter->translate( dX, dY );
+ }
}
if ( mMode == SVG )
@@ -132,7 +193,7 @@ void QgsComposerPicture::paint( QPainter* painter, const QStyleOptionGraphicsIte
}
else if ( mMode == RASTER )
{
- painter->drawImage( QRectF( 0, 0, boundRectWidthMM, boundRectHeightMM ), mImage, QRectF( 0, 0, imageRectWidthMM, imageRectHeightMM ) );
+ painter->drawImage( QRectF( 0, 0, boundRectWidthMM, boundRectHeightMM ), mImage, imageRect );
}
painter->restore();
@@ -146,6 +207,64 @@ void QgsComposerPicture::paint( QPainter* painter, const QStyleOptionGraphicsIte
}
}
+QRect QgsComposerPicture::clippedImageRect( double &boundRectWidthMM, double &boundRectHeightMM, QSize imageRectPixels )
+{
+ int boundRectWidthPixels = boundRectWidthMM * mComposition->printResolution() / 25.4;
+ int boundRectHeightPixels = boundRectHeightMM * mComposition->printResolution() / 25.4;
+
+ //update boundRectWidth/Height so that they exactly match pixel bounds
+ boundRectWidthMM = boundRectWidthPixels * 25.4 / mComposition->printResolution();
+ boundRectHeightMM = boundRectHeightPixels * 25.4 / mComposition->printResolution();
+
+ //calculate part of image which fits in bounds
+ int leftClip = 0;
+ int topClip = 0;
+
+ //calculate left crop
+ switch ( mPictureAnchor )
+ {
+ case UpperLeft:
+ case MiddleLeft:
+ case LowerLeft:
+ leftClip = 0;
+ break;
+ case UpperMiddle:
+ case Middle:
+ case LowerMiddle:
+ leftClip = ( imageRectPixels.width() - boundRectWidthPixels ) / 2;
+ break;
+ case UpperRight:
+ case MiddleRight:
+ case LowerRight:
+ leftClip = imageRectPixels.width() - boundRectWidthPixels;
+ break;
+ }
+
+ //calculate top crop
+ switch ( mPictureAnchor )
+ {
+ case UpperLeft:
+ case UpperMiddle:
+ case UpperRight:
+ topClip = 0;
+ break;
+ case MiddleLeft:
+ case Middle:
+ case MiddleRight:
+ topClip = ( imageRectPixels.height() - boundRectHeightPixels ) / 2;
+ break;
+ case LowerLeft:
+ case LowerMiddle:
+ case LowerRight:
+ topClip = imageRectPixels.height() - boundRectHeightPixels;
+ break;
+ }
+
+
+ return QRect( leftClip, topClip, boundRectWidthPixels, boundRectHeightPixels );
+
+}
+
void QgsComposerPicture::setPictureFile( const QString& path )
{
mSourceFile.setFileName( path );
@@ -525,6 +644,8 @@ bool QgsComposerPicture::writeXML( QDomElement& elem, QDomDocument & doc ) const
composerPictureElem.setAttribute( "pictureWidth", QString::number( mPictureWidth ) );
composerPictureElem.setAttribute( "pictureHeight", QString::number( mPictureHeight ) );
composerPictureElem.setAttribute( "resizeMode", QString::number(( int )mResizeMode ) );
+ composerPictureElem.setAttribute( "anchorPoint", QString::number(( int )mPictureAnchor ) );
+
if ( mUseSourceExpression )
{
composerPictureElem.setAttribute( "useExpression", "true" );
@@ -561,6 +682,7 @@ bool QgsComposerPicture::readXML( const QDomElement& itemElem, const QDomDocumen
mPictureWidth = itemElem.attribute( "pictureWidth", "10" ).toDouble();
mPictureHeight = itemElem.attribute( "pictureHeight", "10" ).toDouble();
mResizeMode = QgsComposerPicture::ResizeMode( itemElem.attribute( "resizeMode", "0" ).toInt() );
+ mPictureAnchor = QgsComposerItem::ItemPositionMode( itemElem.attribute( "anchorPoint", QString( QgsComposerItem::UpperLeft ) ).toInt() );
QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
if ( composerItemList.size() > 0 )
@@ -594,8 +716,6 @@ bool QgsComposerPicture::readXML( const QDomElement& itemElem, const QDomDocumen
QString fileName = QgsProject::instance()->readPath( itemElem.attribute( "file" ) );
mSourceFile.setFileName( fileName );
- refreshPicture();
-
//picture rotation
if ( itemElem.attribute( "pictureRotation", "0" ).toDouble() != 0 )
{
@@ -619,6 +739,8 @@ bool QgsComposerPicture::readXML( const QDomElement& itemElem, const QDomDocumen
QObject::connect( mRotationMap, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setRotation( double ) ) );
}
+ refreshPicture();
+
emit itemChanged();
return true;
}
@@ -635,6 +757,12 @@ int QgsComposerPicture::rotationMap() const
}
}
+void QgsComposerPicture::setPictureAnchor( QgsComposerItem::ItemPositionMode anchor )
+{
+ mPictureAnchor = anchor;
+ update();
+}
+
bool QgsComposerPicture::imageSizeConsideringRotation( double& width, double& height ) const
{
//kept for api compatibility with QGIS 2.0 - use mPictureRotation
diff --git a/src/core/composer/qgscomposerpicture.h b/src/core/composer/qgscomposerpicture.h
index ea1371c8664..63135bb0d48 100644
--- a/src/core/composer/qgscomposerpicture.h
+++ b/src/core/composer/qgscomposerpicture.h
@@ -141,6 +141,22 @@ class CORE_EXPORT QgsComposerPicture: public QgsComposerItem
*/
ResizeMode resizeMode() const { return mResizeMode; }
+ /**Sets the picture's anchor point, which controls how it is placed
+ * within the picture item's frame.
+ * @param anchor anchor point for picture
+ * @note added in 2.3
+ * @see pictureAnchor
+ */
+ void setPictureAnchor( QgsComposerItem::ItemPositionMode anchor );
+
+ /**Returns the picture's current anchor, which controls how it is placed
+ * within the picture item's frame.
+ * @returns anchor point for picture
+ * @note added in 2.3
+ * @see setPictureAnchor
+ */
+ ItemPositionMode pictureAnchor() const { return mPictureAnchor; }
+
/**Returns whether the picture item is using an expression for the image source.
* @returns true if the picture is using an expression for the source, false if
* it is using a single static file path for the source.
@@ -275,6 +291,7 @@ class CORE_EXPORT QgsComposerPicture: public QgsComposerItem
double mPictureHeight;
ResizeMode mResizeMode;
+ QgsComposerItem::ItemPositionMode mPictureAnchor;
QgsExpression* mPictureExpr;
@@ -286,6 +303,11 @@ class CORE_EXPORT QgsComposerPicture: public QgsComposerItem
/**sets up the picture item and connects to relevant signals*/
void init();
+
+ /**Returns part of a raster image which will be shown, given current picture
+ * anchor settings
+ */
+ QRect clippedImageRect( double &boundRectWidthMM, double &boundRectHeightMM, QSize imageRectPixels );
};
#endif
diff --git a/src/ui/qgscomposerpicturewidgetbase.ui b/src/ui/qgscomposerpicturewidgetbase.ui
index 188527a1b06..c431489b9f8 100644
--- a/src/ui/qgscomposerpicturewidgetbase.ui
+++ b/src/ui/qgscomposerpicturewidgetbase.ui
@@ -6,7 +6,7 @@
0
0
- 312
+ 315
572
@@ -52,8 +52,8 @@
0
0
- 310
- 549
+ 297
+ 589
@@ -69,13 +69,6 @@
false
- -
-
-
- Image source
-
-
-
-
-
@@ -109,36 +102,19 @@
- -
-
-
-
-
-
- Expression
-
-
-
- -
-
-
- -
-
-
-
- 0
- 0
-
-
-
- ...
-
-
-
- :/images/themes/default/mIconExpression.svg:/images/themes/default/mIconExpression.svg
-
-
-
-
+ -
+
+
+ Image source
+
+
+
+ -
+
+
+ Placement
+
+
-
@@ -176,6 +152,86 @@
+ -
+
+
-
+
+
+ Expression
+
+
+
+ -
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ ...
+
+
+
+ :/images/themes/default/mIconExpression.svg:/images/themes/default/mIconExpression.svg
+
+
+
+
+
+ -
+
+
-
+
+ Top left
+
+
+ -
+
+ Top center
+
+
+ -
+
+ Top right
+
+
+ -
+
+ Middle left
+
+
+ -
+
+ Middle
+
+
+ -
+
+ Middle right
+
+
+ -
+
+ Bottom left
+
+
+ -
+
+ Bottom center
+
+
+ -
+
+ Bottom right
+
+
+
+
diff --git a/tests/src/core/testqgscomposerpicture.cpp b/tests/src/core/testqgscomposerpicture.cpp
index e7cf3486105..1846f9fc3fd 100644
--- a/tests/src/core/testqgscomposerpicture.cpp
+++ b/tests/src/core/testqgscomposerpicture.cpp
@@ -43,6 +43,10 @@ class TestQgsComposerPicture: public QObject
void pictureResizeZoomAndResize();
void pictureResizeFrameToImage();
+ void pictureClipAnchor();
+ void pictureClipAnchorOversize();
+ void pictureZoomAnchor();
+
void pictureSvgZoom();
void pictureSvgStretch();
void pictureSvgZoomAndResize();
@@ -214,6 +218,56 @@ void TestQgsComposerPicture::pictureResizeFrameToImage()
mComposerPicture->setSceneRect( QRectF( 70, 70, 100, 100 ) );
}
+void TestQgsComposerPicture::pictureClipAnchor()
+{
+ //test picture anchor in Clip mode
+ mComposition->addComposerPicture( mComposerPicture );
+ mComposerPicture->setResizeMode( QgsComposerPicture::Clip );
+ mComposerPicture->setSceneRect( QRectF( 70, 70, 30, 50 ) );
+ mComposerPicture->setPictureAnchor( QgsComposerItem::LowerRight );
+
+ QgsCompositionChecker checker( "composerpicture_clip_anchor", mComposition );
+ QVERIFY( checker.testComposition( mReport, 0, 0 ) );
+
+ mComposition->removeItem( mComposerPicture );
+ mComposerPicture->setResizeMode( QgsComposerPicture::Zoom );
+ mComposerPicture->setPictureAnchor( QgsComposerItem::UpperLeft );
+ mComposerPicture->setSceneRect( QRectF( 70, 70, 100, 100 ) );
+}
+
+void TestQgsComposerPicture::pictureClipAnchorOversize()
+{
+ //test picture anchor in Clip mode
+ mComposition->addComposerPicture( mComposerPicture );
+ mComposerPicture->setResizeMode( QgsComposerPicture::Clip );
+ mComposerPicture->setSceneRect( QRectF( 70, 70, 150, 120 ) );
+ mComposerPicture->setPictureAnchor( QgsComposerItem::LowerMiddle );
+
+ QgsCompositionChecker checker( "expected_composerpicture_clip_anchoroversize", mComposition );
+ QVERIFY( checker.testComposition( mReport, 0, 0 ) );
+
+ mComposition->removeItem( mComposerPicture );
+ mComposerPicture->setResizeMode( QgsComposerPicture::Zoom );
+ mComposerPicture->setPictureAnchor( QgsComposerItem::UpperLeft );
+ mComposerPicture->setSceneRect( QRectF( 70, 70, 100, 100 ) );
+}
+
+void TestQgsComposerPicture::pictureZoomAnchor()
+{
+ //test picture anchor in Zoom mode
+ mComposition->addComposerPicture( mComposerPicture );
+ mComposerPicture->setResizeMode( QgsComposerPicture::Zoom );
+ mComposerPicture->setSceneRect( QRectF( 70, 10, 30, 100 ) );
+ mComposerPicture->setPictureAnchor( QgsComposerItem::LowerMiddle );
+
+ QgsCompositionChecker checker( "composerpicture_zoom_anchor", mComposition );
+ QVERIFY( checker.testComposition( mReport, 0, 100 ) );
+
+ mComposition->removeItem( mComposerPicture );
+ mComposerPicture->setPictureAnchor( QgsComposerItem::UpperLeft );
+ mComposerPicture->setSceneRect( QRectF( 70, 70, 100, 100 ) );
+}
+
void TestQgsComposerPicture::pictureSvgZoom()
{
//test picture resize Zoom mode
diff --git a/tests/testdata/control_images/expected_composerpicture_clip_anchor/expected_composerpicture_clip_anchor.png b/tests/testdata/control_images/expected_composerpicture_clip_anchor/expected_composerpicture_clip_anchor.png
new file mode 100644
index 00000000000..376e05363d1
Binary files /dev/null and b/tests/testdata/control_images/expected_composerpicture_clip_anchor/expected_composerpicture_clip_anchor.png differ
diff --git a/tests/testdata/control_images/expected_composerpicture_clip_anchoroversize/expected_composerpicture_clip_anchoroversize.png b/tests/testdata/control_images/expected_composerpicture_clip_anchoroversize/expected_composerpicture_clip_anchoroversize.png
new file mode 100644
index 00000000000..bc0ef1766c8
Binary files /dev/null and b/tests/testdata/control_images/expected_composerpicture_clip_anchoroversize/expected_composerpicture_clip_anchoroversize.png differ
diff --git a/tests/testdata/control_images/expected_composerpicture_expression/expected_composerpicture_expression.png b/tests/testdata/control_images/expected_composerpicture_expression/expected_composerpicture_expression.png
index 0a631778e2b..0cd6449a637 100644
Binary files a/tests/testdata/control_images/expected_composerpicture_expression/expected_composerpicture_expression.png and b/tests/testdata/control_images/expected_composerpicture_expression/expected_composerpicture_expression.png differ
diff --git a/tests/testdata/control_images/expected_composerpicture_itemrotation/expected_composerpicture_itemrotation.png b/tests/testdata/control_images/expected_composerpicture_itemrotation/expected_composerpicture_itemrotation.png
index 8443dbde4ce..3d0508e8c69 100644
Binary files a/tests/testdata/control_images/expected_composerpicture_itemrotation/expected_composerpicture_itemrotation.png and b/tests/testdata/control_images/expected_composerpicture_itemrotation/expected_composerpicture_itemrotation.png differ
diff --git a/tests/testdata/control_images/expected_composerpicture_resize_zoom/expected_composerpicture_resize_zoom.png b/tests/testdata/control_images/expected_composerpicture_resize_zoom/expected_composerpicture_resize_zoom.png
index 8778ecc521f..2ff89753ea6 100644
Binary files a/tests/testdata/control_images/expected_composerpicture_resize_zoom/expected_composerpicture_resize_zoom.png and b/tests/testdata/control_images/expected_composerpicture_resize_zoom/expected_composerpicture_resize_zoom.png differ
diff --git a/tests/testdata/control_images/expected_composerpicture_svg_zoom/expected_composerpicture_svg_zoom.png b/tests/testdata/control_images/expected_composerpicture_svg_zoom/expected_composerpicture_svg_zoom.png
index 0a631778e2b..0cd6449a637 100644
Binary files a/tests/testdata/control_images/expected_composerpicture_svg_zoom/expected_composerpicture_svg_zoom.png and b/tests/testdata/control_images/expected_composerpicture_svg_zoom/expected_composerpicture_svg_zoom.png differ
diff --git a/tests/testdata/control_images/expected_composerpicture_zoom_anchor/expected_composerpicture_zoom_anchor.png b/tests/testdata/control_images/expected_composerpicture_zoom_anchor/expected_composerpicture_zoom_anchor.png
new file mode 100644
index 00000000000..432644d42c0
Binary files /dev/null and b/tests/testdata/control_images/expected_composerpicture_zoom_anchor/expected_composerpicture_zoom_anchor.png differ