oox/inc/drawingml/fillproperties.hxx | 2 oox/source/drawingml/fillproperties.cxx | 89 ++++++++++++++++++++++++++------ oox/source/drawingml/shape.cxx | 6 +- oox/source/ppt/slidepersist.cxx | 7 ++ oox/source/shape/WpsContext.cxx | 3 - sd/qa/unit/data/pptx/tdf153466.pptx |binary sd/qa/unit/import-tests.cxx | 20 +++++++ 7 files changed, 110 insertions(+), 17 deletions(-)
New commits: commit a41dbf0bd726613204d975fb4fc5e50c23d61410 Author: Tibor Nagy <nagy.tib...@nisz.hu> AuthorDate: Wed Mar 8 16:26:10 2023 +0100 Commit: László Németh <nem...@numbertext.org> CommitDate: Mon Mar 27 08:32:50 2023 +0000 tdf#153466 PPTX import: fix "Custom position/size" background image Custom sized background with the value "tile" was imported as "stretched", losing the preset size. Restore also the exported preset positions, and map the other values to the preset positions supported by OpenDocument/Impress. Follow-up to commit 11451781d4c562f506a3aae3732e35b92387b4db (tdf#153105 PPTX export: fix "Custom position/size" background image) Change-Id: Ibf9b487ecd31b3ad7b06bda668c51e6b7a98c4af Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148482 Tested-by: László Németh <nem...@numbertext.org> Reviewed-by: László Németh <nem...@numbertext.org> diff --git a/oox/inc/drawingml/fillproperties.hxx b/oox/inc/drawingml/fillproperties.hxx index 828c858e12f2..3323907fcad8 100644 --- a/oox/inc/drawingml/fillproperties.hxx +++ b/oox/inc/drawingml/fillproperties.hxx @@ -24,6 +24,7 @@ #include <com/sun/star/beans/PropertyValue.hpp> #include <com/sun/star/geometry/IntegerRectangle2D.hpp> +#include <com/sun/star/awt/Size.hpp> #include <com/sun/star/uno/Any.hxx> #include <com/sun/star/uno/Reference.hxx> #include <oox/drawingml/color.hxx> @@ -147,6 +148,7 @@ struct FillProperties const GraphicHelper& rGraphicHelper, sal_Int32 nShapeRotation = 0, ::Color nPhClr = API_RGB_TRANSPARENT, + const css::awt::Size& rSize = {}, sal_Int16 nPhClrTheme = -1, bool bFlipH = false, bool bFlipV = false, diff --git a/oox/source/drawingml/fillproperties.cxx b/oox/source/drawingml/fillproperties.cxx index d193653d7189..98a048d7f8ac 100644 --- a/oox/source/drawingml/fillproperties.cxx +++ b/oox/source/drawingml/fillproperties.cxx @@ -423,9 +423,10 @@ Color FillProperties::getBestSolidColor() const return aSolidColor; } -void FillProperties::pushToPropMap( ShapePropertyMap& rPropMap, - const GraphicHelper& rGraphicHelper, sal_Int32 nShapeRotation, ::Color nPhClr, sal_Int16 nPhClrTheme, - bool bFlipH, bool bFlipV, bool bIsCustomShape) const +void FillProperties::pushToPropMap(ShapePropertyMap& rPropMap, const GraphicHelper& rGraphicHelper, + sal_Int32 nShapeRotation, ::Color nPhClr, + const css::awt::Size& rSize, sal_Int16 nPhClrTheme, bool bFlipH, + bool bFlipV, bool bIsCustomShape) const { if( !moFillType.has_value() ) return; @@ -824,7 +825,6 @@ void FillProperties::pushToPropMap( ShapePropertyMap& rPropMap, { // bitmap mode (single, repeat, stretch) BitmapMode eBitmapMode = lclGetBitmapMode( maBlipProps.moBitmapMode.value_or( XML_TOKEN_INVALID ) ); - rPropMap.setProperty( ShapeProperty::FillBitmapMode, eBitmapMode ); // additional settings for repeated bitmap if( eBitmapMode == BitmapMode_REPEAT ) @@ -872,21 +872,82 @@ void FillProperties::pushToPropMap( ShapePropertyMap& rPropMap, // Negative GraphicCrop values means "crop" here. bool bNeedCrop = aGraphCrop.Left <= 0 && aGraphCrop.Right <= 0 && aGraphCrop.Top <= 0 && aGraphCrop.Bottom <= 0; - if(bIsCustomShape && bHasCropValues && bNeedCrop) + if (bHasCropValues) { - // Physically crop the image - // In this case, don't set the PROP_GraphicCrop because that - // would lead to applying the crop twice after roundtrip - xGraphic = lclCropGraphic(xGraphic, CropQuotientsFromFillRect(aFillRect)); - if (rPropMap.supportsProperty(ShapeProperty::FillBitmapName)) - rPropMap.setProperty(ShapeProperty::FillBitmapName, xGraphic); + if (bIsCustomShape && bNeedCrop) + { + // Physically crop the image + // In this case, don't set the PROP_GraphicCrop because that + // would lead to applying the crop twice after roundtrip + xGraphic = lclCropGraphic(xGraphic, CropQuotientsFromFillRect(aFillRect)); + if (rPropMap.supportsProperty(ShapeProperty::FillBitmapName)) + rPropMap.setProperty(ShapeProperty::FillBitmapName, xGraphic); + else + rPropMap.setProperty(ShapeProperty::FillBitmap, xGraphic); + } + else if ((aFillRect.X1 != 0 && aFillRect.X2 != 0 + && aFillRect.X1 != aFillRect.X2) + || (aFillRect.Y1 != 0 && aFillRect.Y2 != 0 + && aFillRect.Y1 != aFillRect.Y2)) + { + rPropMap.setProperty(PROP_GraphicCrop, aGraphCrop); + } else - rPropMap.setProperty(ShapeProperty::FillBitmap, xGraphic); + { + double nL = aFillRect.X1 / static_cast<double>(MAX_PERCENT); + double nT = aFillRect.Y1 / static_cast<double>(MAX_PERCENT); + double nR = aFillRect.X2 / static_cast<double>(MAX_PERCENT); + double nB = aFillRect.Y2 / static_cast<double>(MAX_PERCENT); + + sal_Int32 nSizeX; + if (nL || nR) + nSizeX = rSize.Width * (1 - (nL + nR)); + else + nSizeX = rSize.Width; + rPropMap.setProperty(ShapeProperty::FillBitmapSizeX, nSizeX); + + sal_Int32 nSizeY; + if (nT || nB) + nSizeY = rSize.Height * (1 - (nT + nB)); + else + nSizeY = rSize.Height; + rPropMap.setProperty(ShapeProperty::FillBitmapSizeY, nSizeY); + + RectanglePoint eRectPoint; + if (!aFillRect.X1 && aFillRect.X2) + { + if (!aFillRect.Y1 && aFillRect.Y2) + eRectPoint = lclGetRectanglePoint(XML_tl); + else if (aFillRect.Y1 && !aFillRect.Y2) + eRectPoint = lclGetRectanglePoint(XML_bl); + else + eRectPoint = lclGetRectanglePoint(XML_l); + } + else if (aFillRect.X1 && !aFillRect.X2) + { + if (!aFillRect.Y1 && aFillRect.Y2) + eRectPoint = lclGetRectanglePoint(XML_tr); + else if (aFillRect.Y1 && !aFillRect.Y2) + eRectPoint = lclGetRectanglePoint(XML_br); + else + eRectPoint = lclGetRectanglePoint(XML_r); + } + else + { + if (!aFillRect.Y1 && aFillRect.Y2) + eRectPoint = lclGetRectanglePoint(XML_t); + else if (aFillRect.Y1 && !aFillRect.Y2) + eRectPoint = lclGetRectanglePoint(XML_b); + else + eRectPoint = lclGetRectanglePoint(XML_ctr); + } + rPropMap.setProperty(ShapeProperty::FillBitmapRectanglePoint, eRectPoint); + eBitmapMode = BitmapMode_NO_REPEAT; + } } - else - rPropMap.setProperty(PROP_GraphicCrop, aGraphCrop); } } + rPropMap.setProperty(ShapeProperty::FillBitmapMode, eBitmapMode); } if (maBlipProps.moAlphaModFix.has_value()) diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 18e087dc2207..b8cac0d8f385 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -719,6 +719,7 @@ static void lcl_copyCharPropsToShape(const uno::Reference<drawing::XShape>& xSha rCharProps.maFillProperties.pushToPropMap(aFillShapeProps, rFilter.getGraphicHelper(), /*nShapeRotation*/ 0, /*nPhClr*/ API_RGB_TRANSPARENT, + /*aShapeSize*/ css::awt::Size(0, 0), /*nPhClrTheme*/ -1, /*bFlipH*/ false, /*bFlipV*/ false, /*bIsCustomShape*/ true); @@ -1286,7 +1287,10 @@ Reference< XShape > const & Shape::createAndInsert( if (getFillProperties().moFillType.has_value() && getFillProperties().moFillType.value() == XML_grpFill) getFillProperties().assignUsed(aFillProperties); if(!bIsCroppedGraphic) - aFillProperties.pushToPropMap( aShapeProps, rGraphicHelper, mnRotation, nFillPhClr, nFillPhClrTheme, mbFlipH, mbFlipV, bIsCustomShape ); + aFillProperties.pushToPropMap(aShapeProps, rGraphicHelper, mnRotation, nFillPhClr, + css::awt::Size(aShapeRectHmm.Width, aShapeRectHmm.Height), + nFillPhClrTheme, mbFlipH, mbFlipV, bIsCustomShape); + LineProperties aLineProperties = getActualLineProperties(pTheme); aLineProperties.pushToPropMap( aShapeProps, rGraphicHelper, nLinePhClr, nLinePhClrTheme); EffectProperties aEffectProperties = getActualEffectProperties(pTheme); diff --git a/oox/source/ppt/slidepersist.cxx b/oox/source/ppt/slidepersist.cxx index 7298eea1247c..bb673b52442e 100644 --- a/oox/source/ppt/slidepersist.cxx +++ b/oox/source/ppt/slidepersist.cxx @@ -193,11 +193,16 @@ void SlidePersist::createBackground( const XmlFilterBase& rFilterBase ) ::Color nPhClr = maBackgroundColor.isUsed() ? maBackgroundColor.getColor( rFilterBase.getGraphicHelper() ) : API_RGB_TRANSPARENT; + css::awt::Size aSize; + Reference< css::beans::XPropertySet > xSet(mxPage, UNO_QUERY); + xSet->getPropertyValue("Width") >>= aSize.Width; + xSet->getPropertyValue("Height") >>= aSize.Height; + oox::drawingml::ShapePropertyIds aPropertyIds = oox::drawingml::ShapePropertyInfo::DEFAULT.mrPropertyIds; aPropertyIds[oox::drawingml::ShapeProperty::FillGradient] = PROP_FillGradientName; oox::drawingml::ShapePropertyInfo aPropInfo( aPropertyIds, true, false, true, false, false ); oox::drawingml::ShapePropertyMap aPropMap( rFilterBase.getModelObjectHelper(), aPropInfo ); - mpBackgroundPropertiesPtr->pushToPropMap( aPropMap, rFilterBase.getGraphicHelper(), 0, nPhClr ); + mpBackgroundPropertiesPtr->pushToPropMap( aPropMap, rFilterBase.getGraphicHelper(), 0, nPhClr, aSize); PropertySet( mxPage ).setProperty( PROP_Background, aPropMap.makePropertySet() ); } } diff --git a/oox/source/shape/WpsContext.cxx b/oox/source/shape/WpsContext.cxx index ca87085165d8..e207f185d8fc 100644 --- a/oox/source/shape/WpsContext.cxx +++ b/oox/source/shape/WpsContext.cxx @@ -931,7 +931,8 @@ void WpsContext::onEndElement() = lcl_generateFillPropertiesFromTextProps(aTextPropMap); aCreatedFillProperties.pushToPropMap(aFillShapeProps, getFilter().getGraphicHelper(), /*nShapeRotation*/ 0, - /*nPhClr*/ API_RGB_TRANSPARENT, /*nPhClrTheme*/ -1, + /*nPhClr*/ API_RGB_TRANSPARENT, + /*aShapeSize*/ css::awt::Size(0, 0), /*nPhClrTheme*/ -1, pCustomShape->IsMirroredX(), pCustomShape->IsMirroredY(), /*bIsCustomShape*/ true); lcl_applyShapePropsToShape(xShapePropertySet, aFillShapeProps); diff --git a/sd/qa/unit/data/pptx/tdf153466.pptx b/sd/qa/unit/data/pptx/tdf153466.pptx new file mode 100644 index 000000000000..8900083ba7bf Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf153466.pptx differ diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx index a52947493de8..d934b963f6ef 100644 --- a/sd/qa/unit/import-tests.cxx +++ b/sd/qa/unit/import-tests.cxx @@ -52,6 +52,7 @@ #include <com/sun/star/presentation/XCustomPresentationSupplier.hpp> #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp> #include <com/sun/star/drawing/ConnectorType.hpp> +#include <com/sun/star/drawing/RectanglePoint.hpp> #include <stlpool.hxx> #include <unotools/syslocaleoptions.hxx> @@ -190,6 +191,25 @@ CPPUNIT_TEST_FIXTURE(SdImportTest, testDocumentLayout) } } +CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf153466) +{ + createSdImpressDoc("pptx/tdf153466.pptx"); + + uno::Reference<drawing::XDrawPagesSupplier> xDoc(mxComponent, uno::UNO_QUERY_THROW); + uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xPageSet(xPage, uno::UNO_QUERY_THROW); + uno::Reference<beans::XPropertySet> xBackground( + xPageSet->getPropertyValue("Background").get<uno::Reference<beans::XPropertySet>>()); + + com::sun::star::drawing::RectanglePoint aRectanglePoint; + xBackground->getPropertyValue("FillBitmapRectanglePoint") >>= aRectanglePoint; + CPPUNIT_ASSERT_EQUAL(drawing::RectanglePoint::RectanglePoint_RIGHT_BOTTOM, aRectanglePoint); + + uno::Reference<beans::XPropertySet> xShape(getShapeFromPage(0, 0), uno::UNO_SET_THROW); + xShape->getPropertyValue("FillBitmapRectanglePoint") >>= aRectanglePoint; + CPPUNIT_ASSERT_EQUAL(drawing::RectanglePoint::RectanglePoint_LEFT_MIDDLE, aRectanglePoint); +} + CPPUNIT_TEST_FIXTURE(SdImportTest, testTdf152434) { createSdImpressDoc("pptx/tdf152434.pptx");