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");

Reply via email to