include/oox/export/drawingml.hxx         |    3 
 oox/source/drawingml/fillproperties.cxx  |    4 -
 oox/source/export/drawingml.cxx          |  109 ++++++++++++++++++++++++++++++-
 sd/qa/unit/data/odp/repeatBitmapMode.odp |binary
 sd/qa/unit/export-tests-ooxml2.cxx       |   25 +++++++
 5 files changed, 138 insertions(+), 3 deletions(-)

New commits:
commit 405cd10aab717f31b8dd0210f10f1cb4059230a5
Author:     Tibor Nagy <nagy.tib...@nisz.hu>
AuthorDate: Fri Nov 18 12:06:59 2022 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Fri Nov 25 17:48:59 2022 +0100

    tdf#152069 tdf#108356 PPTX export: fix missing tile properties
    
    of background image patterns defined by a:tile.
    
    Note: factor "3.6" comes from EMU.
    
    Change-Id: I5da532ff9ad63fd6c236a58933a31dcd96cf5156
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142913
    Tested-by: László Németh <nem...@numbertext.org>
    Reviewed-by: László Németh <nem...@numbertext.org>
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143286
    Tested-by: Jenkins

diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx
index 9f28a5891306..e4ba170300d6 100644
--- a/include/oox/export/drawingml.hxx
+++ b/include/oox/export/drawingml.hxx
@@ -274,6 +274,9 @@ public:
     void WriteXGraphicStretch(css::uno::Reference<css::beans::XPropertySet> 
const & rXPropSet,
                               css::uno::Reference<css::graphic::XGraphic> 
const & rxGraphic);
 
+    void WriteXGraphicTile(css::uno::Reference<css::beans::XPropertySet> 
const& rXPropSet,
+                           css::uno::Reference<css::graphic::XGraphic> const& 
rxGraphic);
+
     void WriteLinespacing(const css::style::LineSpacing& rLineSpacing, float 
fFirstCharHeight);
 
     OUString WriteXGraphicBlip(css::uno::Reference<css::beans::XPropertySet> 
const & rXPropSet,
diff --git a/oox/source/drawingml/fillproperties.cxx 
b/oox/source/drawingml/fillproperties.cxx
index 144c67fa5caf..9ae39b8cfa48 100644
--- a/oox/source/drawingml/fillproperties.cxx
+++ b/oox/source/drawingml/fillproperties.cxx
@@ -832,9 +832,9 @@ void FillProperties::pushToPropMap( ShapePropertyMap& 
rPropMap,
                             rPropMap.setProperty( 
ShapeProperty::FillBitmapSizeY, nFillBmpSizeY );
 
                             // offset of the first bitmap tile (given as 
EMUs), convert to percent
-                            sal_Int16 nTileOffsetX = getDoubleIntervalValue< 
sal_Int16 >( maBlipProps.moTileOffsetX.get( 0 ) / 3.6 / aOriginalSize.Width, 0, 
100 );
+                            sal_Int16 nTileOffsetX = getDoubleIntervalValue< 
sal_Int16 >( std::round( maBlipProps.moTileOffsetX.get( 0 ) / 3.6 / 
aOriginalSize.Width ), 0, 100 );
                             rPropMap.setProperty( 
ShapeProperty::FillBitmapOffsetX, nTileOffsetX );
-                            sal_Int16 nTileOffsetY = getDoubleIntervalValue< 
sal_Int16 >( maBlipProps.moTileOffsetY.get( 0 ) / 3.6 / aOriginalSize.Height, 
0, 100 );
+                            sal_Int16 nTileOffsetY = getDoubleIntervalValue< 
sal_Int16 >( std::round( maBlipProps.moTileOffsetY.get( 0 ) / 3.6 / 
aOriginalSize.Height ), 0, 100 );
                             rPropMap.setProperty( 
ShapeProperty::FillBitmapOffsetY, nTileOffsetY );
                         }
                     }
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index ea44c4237ff0..53137523999a 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -100,6 +100,7 @@
 #include <com/sun/star/container/XNamed.hpp>
 #include <com/sun/star/drawing/XDrawPages.hpp>
 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/RectanglePoint.hpp>
 
 #include <comphelper/propertyvalue.hxx>
 #include <comphelper/random.hxx>
@@ -1614,7 +1615,7 @@ void 
DrawingML::WriteXGraphicBlipMode(uno::Reference<beans::XPropertySet> const
     switch (eBitmapMode)
     {
     case BitmapMode_REPEAT:
-        mpFS->singleElementNS(XML_a, XML_tile);
+        WriteXGraphicTile(rXPropSet, rxGraphic);
         break;
     case BitmapMode_STRETCH:
         WriteXGraphicStretch(rXPropSet, rxGraphic);
@@ -1837,6 +1838,112 @@ void 
DrawingML::WriteXGraphicStretch(uno::Reference<beans::XPropertySet> const &
     mpFS->endElementNS(XML_a, XML_stretch);
 }
 
+static OUString lclConvertRectanglePointToToken(RectanglePoint eRectanglePoint)
+{
+    OUString sAlignment;
+    switch (eRectanglePoint)
+    {
+        case RectanglePoint_LEFT_TOP:
+            sAlignment = "tl";
+            break;
+        case RectanglePoint_MIDDLE_TOP:
+            sAlignment = "t";
+            break;
+        case RectanglePoint_RIGHT_TOP:
+            sAlignment = "tr";
+            break;
+        case RectanglePoint_LEFT_MIDDLE:
+            sAlignment = "l";
+            break;
+        case RectanglePoint_MIDDLE_MIDDLE:
+            sAlignment = "ctr";
+            break;
+        case RectanglePoint_RIGHT_MIDDLE:
+            sAlignment = "r";
+            break;
+        case RectanglePoint_LEFT_BOTTOM:
+            sAlignment = "bl";
+            break;
+        case RectanglePoint_MIDDLE_BOTTOM:
+            sAlignment = "b";
+            break;
+        case RectanglePoint_RIGHT_BOTTOM:
+            sAlignment = "br";
+            break;
+        default:
+            break;
+    }
+    return sAlignment;
+}
+
+void DrawingML::WriteXGraphicTile(uno::Reference<beans::XPropertySet> const& 
rXPropSet,
+                                  uno::Reference<graphic::XGraphic> const& 
rxGraphic)
+{
+    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));
+    sal_Int32 nOffsetX = 0;
+    if (GetProperty(rXPropSet, "FillBitmapPositionOffsetX"))
+        nOffsetX = (*o3tl::doAccess<sal_Int32>(mAny)) * aOriginalSize.Width() 
* 3.6;
+
+    sal_Int32 nOffsetY = 0;
+    if (GetProperty(rXPropSet, "FillBitmapPositionOffsetY"))
+        nOffsetY = (*o3tl::doAccess<sal_Int32>(mAny)) * aOriginalSize.Height() 
* 3.6;
+
+    // convert the X size of bitmap to a percentage
+    sal_Int32 nSizeX = 0;
+    if (GetProperty(rXPropSet, "FillBitmapSizeX"))
+    {
+        mAny >>= nSizeX;
+        if (nSizeX > 0)
+            nSizeX = double(nSizeX) / aOriginalSize.Width() * 100000;
+        else if (nSizeX < 0)
+            nSizeX *= 1000;
+        else
+            nSizeX = 100000;
+    }
+
+    // convert the Y size of bitmap to a percentage
+    sal_Int32 nSizeY = 0;
+    if (GetProperty(rXPropSet, "FillBitmapSizeY"))
+    {
+        mAny >>= nSizeY;
+        if (nSizeY > 0)
+            nSizeY = double(nSizeY) / aOriginalSize.Height() * 100000;
+        else if (nSizeY < 0)
+            nSizeY *= 1000;
+        else
+            nSizeY = 100000;
+    }
+
+    // if the "Scale" setting is checked in the images settings dialog.
+    if (nSizeX < 0 && nSizeY < 0)
+    {
+        Reference<drawing::XDrawPagesSupplier> xDPS(GetFB()->getModel(), 
UNO_QUERY_THROW);
+        Reference<drawing::XDrawPages> xDrawPages(xDPS->getDrawPages(), 
UNO_SET_THROW);
+        // in this case, the size of the first slide is enough, because all 
slides are the same size
+        Reference<XDrawPage> xDrawPage(xDrawPages->getByIndex(0), UNO_QUERY);
+        css::uno::Reference<css::beans::XPropertySet> mXPagePropSet(xDrawPage, 
UNO_QUERY);
+        double nPageWidth, nPageHeight;
+        mXPagePropSet->getPropertyValue("Width") >>= nPageWidth;
+        mXPagePropSet->getPropertyValue("Height") >>= nPageHeight;
+        nSizeX = nPageWidth / aOriginalSize.Width() * std::abs(nSizeX);
+        nSizeY = nPageHeight / aOriginalSize.Height() * std::abs(nSizeY);
+    }
+
+    OUString sRectanglePoint;
+    if (GetProperty(rXPropSet, "FillBitmapRectanglePoint"))
+        sRectanglePoint = 
lclConvertRectanglePointToToken(*o3tl::doAccess<RectanglePoint>(mAny));
+
+    mpFS->singleElementNS(XML_a, XML_tile, XML_tx, OUString::number(nOffsetX), 
XML_ty,
+                          OUString::number(nOffsetY), XML_sx, 
OUString::number(nSizeX), XML_sy,
+                          OUString::number(nSizeY), XML_algn, sRectanglePoint);
+}
+
 namespace
 {
 bool IsTopGroupObj(const uno::Reference<drawing::XShape>& xShape)
diff --git a/sd/qa/unit/data/odp/repeatBitmapMode.odp 
b/sd/qa/unit/data/odp/repeatBitmapMode.odp
new file mode 100644
index 000000000000..b3d829930487
Binary files /dev/null and b/sd/qa/unit/data/odp/repeatBitmapMode.odp differ
diff --git a/sd/qa/unit/export-tests-ooxml2.cxx 
b/sd/qa/unit/export-tests-ooxml2.cxx
index b11e38011e74..c17be51c1bf1 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -70,6 +70,7 @@ static void assertMotionPath(std::u16string_view rStr1, 
std::u16string_view rStr
 class SdOOXMLExportTest2 : public SdModelTestBaseXML
 {
 public:
+    void testRepeatBitmapMode();
     void testTdf151492();
     void testTdf149697();
     void testTdf149126();
@@ -140,6 +141,7 @@ public:
 
     CPPUNIT_TEST_SUITE(SdOOXMLExportTest2);
 
+    CPPUNIT_TEST(testRepeatBitmapMode);
     CPPUNIT_TEST(testTdf151492);
     CPPUNIT_TEST(testTdf149697);
     CPPUNIT_TEST(testTdf149126);
@@ -216,6 +218,29 @@ public:
     }
 };
 
+void SdOOXMLExportTest2::testRepeatBitmapMode()
+{
+    ::sd::DrawDocShellRef xDocShRef
+        = 
loadURL(m_directories.getURLFromSrc(u"/sd/qa/unit/data/odp/repeatBitmapMode.odp"),
 ODP);
+    utl::TempFile tempFile;
+    xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile);
+
+    xmlDocUniquePtr pXmlDocContent1 = parseExport(tempFile, 
"ppt/slides/slide1.xml");
+    assertXPath(pXmlDocContent1, 
"/p:sld/p:cSld/p:bg/p:bgPr/a:blipFill/a:tile", "tx", "1269669");
+    assertXPath(pXmlDocContent1, 
"/p:sld/p:cSld/p:bg/p:bgPr/a:blipFill/a:tile", "ty", "186051");
+    assertXPath(pXmlDocContent1, 
"/p:sld/p:cSld/p:bg/p:bgPr/a:blipFill/a:tile", "sx", "100000");
+    assertXPath(pXmlDocContent1, 
"/p:sld/p:cSld/p:bg/p:bgPr/a:blipFill/a:tile", "sy", "100000");
+    assertXPath(pXmlDocContent1, 
"/p:sld/p:cSld/p:bg/p:bgPr/a:blipFill/a:tile", "algn", "tr");
+
+    // if the "Scale" setting is checked in the images settings dialog.
+    xmlDocUniquePtr pXmlDocContent2 = parseExport(tempFile, 
"ppt/slides/slide2.xml");
+    assertXPath(pXmlDocContent2, 
"/p:sld/p:cSld/p:bg/p:bgPr/a:blipFill/a:tile", "tx", "0");
+    assertXPath(pXmlDocContent2, 
"/p:sld/p:cSld/p:bg/p:bgPr/a:blipFill/a:tile", "ty", "0");
+    assertXPath(pXmlDocContent2, 
"/p:sld/p:cSld/p:bg/p:bgPr/a:blipFill/a:tile", "sx", "682760");
+    assertXPath(pXmlDocContent2, 
"/p:sld/p:cSld/p:bg/p:bgPr/a:blipFill/a:tile", "sy", "639983");
+    assertXPath(pXmlDocContent2, 
"/p:sld/p:cSld/p:bg/p:bgPr/a:blipFill/a:tile", "algn", "ctr");
+}
+
 void SdOOXMLExportTest2::testTdf151492()
 {
     ::sd::DrawDocShellRef xDocShRef

Reply via email to