include/oox/export/drawingml.hxx   |    4 +
 oox/source/export/drawingml.cxx    |   78 +++++++++++++++++++++++++++++++++++++
 sd/qa/unit/data/odp/tdf153105.odp  |binary
 sd/qa/unit/export-tests-ooxml3.cxx |   16 +++++++
 4 files changed, 98 insertions(+)

New commits:
commit 11451781d4c562f506a3aae3732e35b92387b4db
Author:     Tibor Nagy <[email protected]>
AuthorDate: Mon Feb 20 16:13:17 2023 +0100
Commit:     László Németh <[email protected]>
CommitDate: Tue Feb 28 11:21:12 2023 +0000

    tdf#153105 PPTX export: fix "Custom position/size" background image
    
    Map size and the 9 preset positions of the ODF background image
    style "Custom position/size" to the OOXML a:stretch/a:fillRect
    with the appropriate left/top/right/bottom arguments.
    
    Note: it seems, applying a:stretch or a:tile was not mandatory,
    but missing a:stretch resulted non-editable document in Office 365.
    
    Note: the import of the PPTX mapping hasn't been implemented, yet.
    
    Follow-up to commit e8335bac5690b6beccb5ca9b36281c89fb2f28f5
    "tdf#153107 OOXML export: fix scale of tile of shape background".
    
    Change-Id: Ie940ebc2610c5b75126da05678a04ed1552cacb3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147337
    Tested-by: László Németh <[email protected]>
    Reviewed-by: László Németh <[email protected]>

diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index 3613eb49cdd0..21914fbf57d1 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -281,6 +281,10 @@ public:
                            css::uno::Reference<css::graphic::XGraphic> const& 
rxGraphic,
                            css::awt::Size const& rSize);
 
+    void 
WriteXGraphicCustomPosition(css::uno::Reference<css::beans::XPropertySet> 
const& rXPropSet,
+                                     
css::uno::Reference<css::graphic::XGraphic> const& rxGraphic,
+                                     css::awt::Size const& rSize);
+
     void WriteLinespacing(const css::style::LineSpacing& rLineSpacing, float 
fFirstCharHeight);
 
     OUString WriteXGraphicBlip(css::uno::Reference<css::beans::XPropertySet> 
const & rXPropSet,
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 24463a2abf9d..d3fb8a3daf97 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -1584,6 +1584,9 @@ void 
DrawingML::WriteXGraphicBlipMode(uno::Reference<beans::XPropertySet> const
     case BitmapMode_STRETCH:
         WriteXGraphicStretch(rXPropSet, rxGraphic);
         break;
+    case BitmapMode_NO_REPEAT:
+        WriteXGraphicCustomPosition(rXPropSet, rxGraphic, rSize);
+        break;
     default:
         break;
     }
@@ -1923,6 +1926,81 @@ void 
DrawingML::WriteXGraphicTile(uno::Reference<beans::XPropertySet> const& rXP
                           OUString::number(nSizeY), XML_algn, sRectanglePoint);
 }
 
+void 
DrawingML::WriteXGraphicCustomPosition(uno::Reference<beans::XPropertySet> 
const& rXPropSet,
+                                            uno::Reference<graphic::XGraphic> 
const& rxGraphic,
+                                            css::awt::Size const& rSize)
+{
+    Graphic aGraphic(rxGraphic);
+    Size aOriginalSize(aGraphic.GetPrefSize());
+    const MapMode& rMapMode = aGraphic.GetPrefMapMode();
+    // if the original size is in pixel, convert it to mm100
+    if (rMapMode.GetMapUnit() == MapUnit::MapPixel)
+        aOriginalSize = 
Application::GetDefaultDevice()->PixelToLogic(aOriginalSize,
+                                                                      
MapMode(MapUnit::Map100thMM));
+    double nSizeX = 0;
+    if (GetProperty(rXPropSet, "FillBitmapSizeX"))
+    {
+        mAny >>= nSizeX;
+        if (nSizeX <= 0)
+        {
+            if (nSizeX == 0)
+                nSizeX = aOriginalSize.Width();
+            else
+                nSizeX /= 100; // percentage
+        }
+    }
+
+    double nSizeY = 0;
+    if (GetProperty(rXPropSet, "FillBitmapSizeY"))
+    {
+        mAny >>= nSizeY;
+        if (nSizeY <= 0)
+        {
+            if (nSizeY == 0)
+                nSizeY = aOriginalSize.Height();
+            else
+                nSizeY /= 100; // percentage
+        }
+    }
+
+    if (nSizeX < 0 && nSizeY < 0 && rSize.Width != 0 && rSize.Height != 0)
+    {
+        nSizeX = rSize.Width * std::abs(nSizeX);
+        nSizeY = rSize.Height * std::abs(nSizeY);
+    }
+
+    sal_Int32 nL = 0, nT = 0, nR = 0, nB = 0;
+    if (GetProperty(rXPropSet, "FillBitmapRectanglePoint"))
+    {
+        sal_Int32 nWidth = (1 - (nSizeX / rSize.Width)) * 100000;
+        sal_Int32 nHeight = (1 - (nSizeY / rSize.Height)) * 100000;
+
+        switch (*o3tl::doAccess<RectanglePoint>(mAny))
+        {
+            case RectanglePoint_LEFT_TOP:      nR = nWidth;          nB = 
nHeight;          break;
+            case RectanglePoint_RIGHT_TOP:     nL = nWidth;          nB = 
nHeight;          break;
+            case RectanglePoint_LEFT_BOTTOM:   nR = nWidth;          nT = 
nHeight;          break;
+            case RectanglePoint_RIGHT_BOTTOM:  nL = nWidth;          nT = 
nHeight;          break;
+            case RectanglePoint_LEFT_MIDDLE:   nR = nWidth;          nT = nB = 
nHeight / 2; break;
+            case RectanglePoint_RIGHT_MIDDLE:  nL = nWidth;          nT = nB = 
nHeight / 2; break;
+            case RectanglePoint_MIDDLE_TOP:    nB = nHeight;         nL = nR = 
nWidth / 2;  break;
+            case RectanglePoint_MIDDLE_BOTTOM: nT = nHeight;         nL = nR = 
nWidth / 2;  break;
+            case RectanglePoint_MIDDLE_MIDDLE: nL = nR = nWidth / 2; nT = nB = 
nHeight / 2; break;
+            default: break;
+        }
+    }
+
+    mpFS->startElementNS(XML_a, XML_stretch);
+
+    mpFS->singleElementNS(XML_a, XML_fillRect, XML_l,
+                          sax_fastparser::UseIf(OString::number(nL), nL != 0), 
XML_t,
+                          sax_fastparser::UseIf(OString::number(nT), nT != 0), 
XML_r,
+                          sax_fastparser::UseIf(OString::number(nR), nR != 0), 
XML_b,
+                          sax_fastparser::UseIf(OString::number(nB), nB != 0));
+
+    mpFS->endElementNS(XML_a, XML_stretch);
+}
+
 namespace
 {
 bool IsTopGroupObj(const uno::Reference<drawing::XShape>& xShape)
diff --git a/sd/qa/unit/data/odp/tdf153105.odp 
b/sd/qa/unit/data/odp/tdf153105.odp
new file mode 100644
index 000000000000..a5f765f9b084
Binary files /dev/null and b/sd/qa/unit/data/odp/tdf153105.odp differ
diff --git a/sd/qa/unit/export-tests-ooxml3.cxx 
b/sd/qa/unit/export-tests-ooxml3.cxx
index 96167204aecc..405170ffcdcf 100644
--- a/sd/qa/unit/export-tests-ooxml3.cxx
+++ b/sd/qa/unit/export-tests-ooxml3.cxx
@@ -49,6 +49,22 @@ public:
     int testTdf115005_FallBack_Images(bool bAddReplacementImages);
 };
 
+CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testTdf153105)
+{
+    createSdImpressDoc("odp/tdf153105.odp");
+    save("Impress Office Open XML");
+
+    xmlDocUniquePtr pXmlDoc1 = parseExport("ppt/slides/slide1.xml");
+    assertXPath(pXmlDoc1, 
"/p:sld/p:cSld/p:bg/p:bgPr/a:blipFill/a:stretch/a:fillRect", "l",
+                "20000");
+    assertXPath(pXmlDoc1, 
"/p:sld/p:cSld/p:bg/p:bgPr/a:blipFill/a:stretch/a:fillRect", "t",
+                "30000");
+    assertXPath(pXmlDoc1, 
"/p:sld/p:cSld/p:bg/p:bgPr/a:blipFill/a:stretch/a:fillRect", "r",
+                "20000");
+    assertXPath(pXmlDoc1, 
"/p:sld/p:cSld/p:bg/p:bgPr/a:blipFill/a:stretch/a:fillRect", "b",
+                "30000");
+}
+
 CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testTdf92222)
 {
     createSdImpressDoc("pptx/tdf92222.pptx");

Reply via email to