oox/inc/drawingml/fillproperties.hxx    |    2 
 oox/source/drawingml/fillproperties.cxx |   89 ++++++++++++++++++++++++++------
 oox/source/drawingml/shape.cxx          |    5 +
 oox/source/ppt/slidepersist.cxx         |    7 ++
 sd/qa/unit/data/pptx/tdf153466.pptx     |binary
 sd/qa/unit/import-tests.cxx             |   23 ++++++++
 6 files changed, 110 insertions(+), 16 deletions(-)

New commits:
commit d9e0c76a845857cc8fba32df01aadb5ac36541f6
Author:     Tibor Nagy <[email protected]>
AuthorDate: Wed Mar 8 16:26:10 2023 +0100
Commit:     Aron Budea <[email protected]>
CommitDate: Wed Jun 28 12:02:06 2023 +0200

    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 <[email protected]>
    Reviewed-by: László Németh <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153581
    Reviewed-by: Jaume Pujantell <[email protected]>
    Reviewed-by: Aron Budea <[email protected]>
    Tested-by: Aron Budea <[email protected]>

diff --git a/oox/inc/drawingml/fillproperties.hxx 
b/oox/inc/drawingml/fillproperties.hxx
index 532cb0ec3975..e4dddac659d9 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>
@@ -145,6 +146,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 50439e5458b5..6026af2773c3 100644
--- a/oox/source/drawingml/fillproperties.cxx
+++ b/oox/source/drawingml/fillproperties.cxx
@@ -391,9 +391,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() )
         return;
@@ -789,7 +790,6 @@ void FillProperties::pushToPropMap( ShapePropertyMap& 
rPropMap,
                 {
                     // bitmap mode (single, repeat, stretch)
                     BitmapMode eBitmapMode = lclGetBitmapMode( 
maBlipProps.moBitmapMode.get( XML_TOKEN_INVALID ) );
-                    rPropMap.setProperty( ShapeProperty::FillBitmapMode, 
eBitmapMode );
 
                     // additional settings for repeated bitmap
                     if( eBitmapMode == BitmapMode_REPEAT )
@@ -836,21 +836,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())
diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx
index ae564c91ccb8..0c834949550d 100644
--- a/oox/source/drawingml/shape.cxx
+++ b/oox/source/drawingml/shape.cxx
@@ -1166,7 +1166,10 @@ Reference< XShape > const & Shape::createAndInsert(
         if (getFillProperties().moFillType.has() && 
getFillProperties().moFillType.get() == 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 ae9f0f567a7c..593a176ac2a3 100644
--- a/oox/source/ppt/slidepersist.cxx
+++ b/oox/source/ppt/slidepersist.cxx
@@ -172,11 +172,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/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 e49892d3a738..97138af63f54 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -88,6 +88,7 @@
 #include <com/sun/star/xml/dom/XDocument.hpp>
 #include <com/sun/star/container/XNamed.hpp>
 #include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
+#include <com/sun/star/drawing/RectanglePoint.hpp>
 
 #include <stlpool.hxx>
 #include <comphelper/processfactory.hxx>
@@ -124,6 +125,7 @@ public:
     virtual void setUp() override;
 
     void testDocumentLayout();
+    void testTdf153466();
     void testTdf146223();
     void testTdf144918();
     void testTdf144917();
@@ -194,6 +196,7 @@ public:
     CPPUNIT_TEST_SUITE(SdImportTest);
 
     CPPUNIT_TEST(testDocumentLayout);
+    CPPUNIT_TEST(testTdf153466);
     CPPUNIT_TEST(testTdf146223);
     CPPUNIT_TEST(testTdf144918);
     CPPUNIT_TEST(testTdf144917);
@@ -342,6 +345,26 @@ void SdImportTest::testDocumentLayout()
     }
 }
 
+void SdImportTest::testTdf153466()
+{
+    sd::DrawDocShellRef xDocShRef
+        = 
loadURL(m_directories.getURLFromSrc(u"/sd/qa/unit/data/pptx/tdf153466.pptx"), 
PPTX);
+    uno::Reference<drawing::XDrawPagesSupplier> 
xDoc(xDocShRef->GetDoc()->getUnoModel(),
+                                                     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, 
xDocShRef));
+    xShape->getPropertyValue("FillBitmapRectanglePoint") >>= aRectanglePoint;
+    CPPUNIT_ASSERT_EQUAL(drawing::RectanglePoint::RectanglePoint_LEFT_MIDDLE, 
aRectanglePoint);
+}
+
 void SdImportTest::testTdf146223()
 {
     sd::DrawDocShellRef xDocShRef

Reply via email to