[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.2' - 11 commits - desktop/qa desktop/source filter/Configuration_filter.mk filter/source include/LibreOfficeKit sfx2/source svx/source

Tamás Zolnai (via logerrit) logerrit at kemper.freedesktop.org
Thu Jun 20 16:06:54 UTC 2019


 desktop/qa/desktop_lib/test_desktop_lib.cxx                  |    3 
 desktop/source/lib/init.cxx                                  |   64 +
 filter/Configuration_filter.mk                               |    4 
 filter/source/config/fragments/filters/calc_svg_Export.xcu   |   30 
 filter/source/config/fragments/filters/writer_svg_Export.xcu |   30 
 filter/source/svg/svgexport.cxx                              |  401 +++++++----
 filter/source/svg/svgfilter.cxx                              |  105 ++
 filter/source/svg/svgfilter.hxx                              |   48 -
 include/LibreOfficeKit/LibreOfficeKit.h                      |    3 
 include/LibreOfficeKit/LibreOfficeKit.hxx                    |   10 
 sfx2/source/control/unoctitm.cxx                             |    1 
 svx/source/svdraw/svdedtv1.cxx                               |   12 
 12 files changed, 577 insertions(+), 134 deletions(-)

New commits:
commit c472d8cf02daf0133ce00dabf6083633215bff48
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Fri Dec 14 17:36:41 2018 +0100
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Thu Jun 20 18:05:15 2019 +0200

    lok: Handle Special character menu item's state correctly in online
    
    Change-Id: Iaa962fe5a590ef16e710fdd49d02d564f10f0f9f
    Reviewed-on: https://gerrit.libreoffice.org/65188
    Tested-by: Jenkins
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
    (cherry picked from commit 13998b050f445bac3593a8bb77b7320d1be9990d)
    Reviewed-on: https://gerrit.libreoffice.org/65202
    Reviewed-by: Andras Timar <andras.timar at collabora.com>
    Tested-by: Andras Timar <andras.timar at collabora.com>
    (cherry picked from commit bd5f75d44a55c0608dc328ca74b19302955bf67f)

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 24957ac12e92..2b8a6f956d2f 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1875,7 +1875,8 @@ static void doc_iniUnoCommands ()
         OUString(".uno:TransformDialog"),
         OUString(".uno:InsertPageHeader"),
         OUString(".uno:InsertPageFooter"),
-        OUString(".uno:OnlineAutoFormat")
+        OUString(".uno:OnlineAutoFormat"),
+        OUString(".uno:InsertSymbol")
     };
 
     util::URL aCommandURL;
diff --git a/sfx2/source/control/unoctitm.cxx b/sfx2/source/control/unoctitm.cxx
index 2af30984afe9..94e4b16cc764 100644
--- a/sfx2/source/control/unoctitm.cxx
+++ b/sfx2/source/control/unoctitm.cxx
@@ -1062,6 +1062,7 @@ static void InterceptLOKStateChangeEvent(const SfxViewFrame* pViewFrame, const c
              aEvent.FeatureURL.Path == "InsertRowsAfter" ||
              aEvent.FeatureURL.Path == "InsertColumnsBefore" ||
              aEvent.FeatureURL.Path == "InsertColumnsAfter" ||
+             aEvent.FeatureURL.Path == "InsertSymbol" ||
              aEvent.FeatureURL.Path == "DeleteRows" ||
              aEvent.FeatureURL.Path == "DeleteColumns" ||
              aEvent.FeatureURL.Path == "DeleteTable" ||
commit 9db2214bf543249be549f4193124919aa94cc417
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Fri Mar 1 11:11:46 2019 +0100
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Thu Jun 20 18:05:15 2019 +0200

    tdf#123780: Fix SVG export of Writer images
    
    Used for LO online to generate preview.
    
    Change-Id: I25107bedecc5a60e6a3ac094b7defd5dcb822138
    Reviewed-on: https://gerrit.libreoffice.org/68543
    Tested-by: Jenkins
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
    (cherry picked from commit 5f4df4b39722b9b3aa45d669e932d054d264ffbf)

diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index 5cad38635871..74e451b3aac1 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -706,8 +706,6 @@ bool SVGFilter::implExportWriterTextGraphic( const Reference< view::XSelectionSu
         SdrGrafObj* pGraphicObj = new SdrGrafObj(pSvxDrawPage->GetSdrPage()->getSdrModelFromSdrPage(), aGraphic, tools::Rectangle( aPos, aSize ));
         uno::Reference< drawing::XShape > xShape = GetXShapeForSdrObject(pGraphicObj);
         uno::Reference< XPropertySet > xShapePropSet(xShape, uno::UNO_QUERY);
-        css::awt::Rectangle aBoundRect (aPos.X(), aPos.Y(), aSize.Width(), aSize.Height());
-        xShapePropSet->setPropertyValue("BoundRect", uno::Any(aBoundRect));
         xShapePropSet->setPropertyValue("Graphic", uno::Any(xGraphic));
 
         maShapeSelection = drawing::ShapeCollection::create(comphelper::getProcessComponentContext());
diff --git a/filter/source/svg/svgfilter.cxx b/filter/source/svg/svgfilter.cxx
index d2e18d5688c2..53b526f059d2 100644
--- a/filter/source/svg/svgfilter.cxx
+++ b/filter/source/svg/svgfilter.cxx
@@ -578,6 +578,13 @@ sal_Bool SVGFilter::filterWriterOrCalc( const Sequence< PropertyValue >& rDescri
     if (!xSelection.is())
         return false;
 
+    // Select only one draw page
+    uno::Reference< drawing::XDrawPagesSupplier > xDrawPagesSupplier( mxSrcDoc, uno::UNO_QUERY );
+    uno::Reference<drawing::XDrawPages> xDrawPages = xDrawPagesSupplier->getDrawPages();
+    uno::Reference< drawing::XDrawPage > xDrawPage( xDrawPages->getByIndex(0), uno::UNO_QUERY );
+    mSelectedPages.resize( 1 );
+    mSelectedPages[0] = xDrawPage;
+
     bool bGotSelection = xSelection->getSelection() >>= maShapeSelection;
 
     if (!bGotSelection)
@@ -591,13 +598,6 @@ sal_Bool SVGFilter::filterWriterOrCalc( const Sequence< PropertyValue >& rDescri
             return false;
     }
 
-    // Select only one draw page
-    uno::Reference< drawing::XDrawPagesSupplier > xDrawPagesSupplier( mxSrcDoc, uno::UNO_QUERY );
-    uno::Reference<drawing::XDrawPages> xDrawPages = xDrawPagesSupplier->getDrawPages();
-    uno::Reference< drawing::XDrawPage > xDrawPage( xDrawPages->getByIndex(0), uno::UNO_QUERY );
-    mSelectedPages.resize( 1 );
-    mSelectedPages[0] = xDrawPage;
-
     return implExport( rDescriptor );
 }
 
commit a33ab4be7747f6c84e66ee9e826b583d376de938
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Fri Dec 14 16:56:18 2018 +0100
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Thu Jun 20 18:05:15 2019 +0200

    lok: Implement SVG export of selected Writer image
    
    A Writer image does not behave similar to other
    shapes, so we need to generate a shape to get the
    export code working.
    
    Change-Id: Icfb25ceb40f73f1018d379863b836d8303e539f3
    Reviewed-on: https://gerrit.libreoffice.org/65176
    Tested-by: Jenkins
    Reviewed-by: Tamás Zolnai <tamas.zolnai at collabora.com>
    (cherry picked from commit d856ba77faa8db9300c99f7dcaa9101bdeca849b)

diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index b2ec3d307769..5cad38635871 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -31,6 +31,8 @@
 #include <com/sun/star/text/textfield/Type.hpp>
 #include <com/sun/star/util/MeasureUnit.hpp>
 #include <com/sun/star/xml/sax/Writer.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/ShapeCollection.hpp>
 
 #include <rtl/bootstrap.hxx>
 #include <svtools/miscopt.hxx>
@@ -52,6 +54,8 @@
 #include <xmloff/xmlnmspe.hxx>
 #include <xmloff/xmltoken.hxx>
 #include <xmloff/animationexport.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdpage.hxx>
 
 #include <memory>
 
@@ -532,7 +536,7 @@ bool SVGFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
         }
     }
 
-    if(mbWriterOrCalcFilter)
+    if(mbWriterFilter || mbCalcFilter)
        return implExportWriterOrCalc(xOStm);
 
     return implExportImpressOrDraw(xOStm);
@@ -674,6 +678,45 @@ bool SVGFilter::implExportWriterOrCalc( const Reference< XOutputStream >& rxOStm
     return bRet;
 }
 
+bool SVGFilter::implExportWriterTextGraphic( const Reference< view::XSelectionSupplier >& xSelectionSupplier )
+{
+    Any selection = xSelectionSupplier->getSelection();
+    uno::Reference<lang::XServiceInfo> xSelection;
+    selection >>= xSelection;
+    if (xSelection.is() && xSelection->supportsService("com.sun.star.text.TextGraphicObject"))
+    {
+        uno::Reference<beans::XPropertySet> xPropertySet(xSelection, uno::UNO_QUERY);
+        uno::Reference<graphic::XGraphic> xGraphic;
+        xPropertySet->getPropertyValue("Graphic") >>= xGraphic;
+
+        if (!xGraphic.is())
+            return false;
+
+        const Graphic aGraphic(xGraphic);
+
+        // Calculate size from Graphic
+        Point aPos( OutputDevice::LogicToLogic(aGraphic.GetPrefMapMode().GetOrigin(), aGraphic.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)) );
+        Size  aSize( OutputDevice::LogicToLogic(aGraphic.GetPrefSize(), aGraphic.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)) );
+
+        assert(mSelectedPages.size() == 1);
+        SvxDrawPage* pSvxDrawPage(SvxDrawPage::getImplementation(mSelectedPages[0]));
+        if(pSvxDrawPage == nullptr || pSvxDrawPage->GetSdrPage() == nullptr)
+            return false;
+
+        SdrGrafObj* pGraphicObj = new SdrGrafObj(pSvxDrawPage->GetSdrPage()->getSdrModelFromSdrPage(), aGraphic, tools::Rectangle( aPos, aSize ));
+        uno::Reference< drawing::XShape > xShape = GetXShapeForSdrObject(pGraphicObj);
+        uno::Reference< XPropertySet > xShapePropSet(xShape, uno::UNO_QUERY);
+        css::awt::Rectangle aBoundRect (aPos.X(), aPos.Y(), aSize.Width(), aSize.Height());
+        xShapePropSet->setPropertyValue("BoundRect", uno::Any(aBoundRect));
+        xShapePropSet->setPropertyValue("Graphic", uno::Any(xGraphic));
+
+        maShapeSelection = drawing::ShapeCollection::create(comphelper::getProcessComponentContext());
+        maShapeSelection->add(xShape);
+    }
+
+    return true;
+}
+
 
 Reference< XWriter > SVGFilter::implCreateExportDocumentHandler( const Reference< XOutputStream >& rxOStm )
 {
@@ -785,7 +828,7 @@ bool SVGFilter::implExportDocument()
         }
     }
 
-    if(mbWriterOrCalcFilter)
+    if(mbWriterFilter || mbCalcFilter)
         implExportDocumentHeaderWriterOrCalc(nDocX, nDocY, nDocWidth, nDocHeight);
     else
         implExportDocumentHeaderImpressOrDraw(nDocX, nDocY, nDocWidth, nDocHeight);
@@ -2058,7 +2101,23 @@ bool SVGFilter::implCreateObjectsFromShape( const Reference< css::drawing::XDraw
 
         if( pObj )
         {
-            const Graphic aGraphic(SdrExchangeView::GetObjGraphic(*pObj));
+            Graphic aGraphic(SdrExchangeView::GetObjGraphic(*pObj));
+
+            // Writer graphic shapes are handled differently
+            if( mbWriterFilter && aGraphic.GetType() == GraphicType::NONE )
+            {
+                if (rxShape->getShapeType() == "com.sun.star.drawing.GraphicObjectShape")
+                {
+                    uno::Reference<beans::XPropertySet> xPropertySet(rxShape, uno::UNO_QUERY);
+                    uno::Reference<graphic::XGraphic> xGraphic;
+                    xPropertySet->getPropertyValue("Graphic") >>= xGraphic;
+
+                    if (!xGraphic.is())
+                        return false;
+
+                    aGraphic = Graphic(xGraphic);
+                }
+            }
 
             if( aGraphic.GetType() != GraphicType::NONE )
             {
diff --git a/filter/source/svg/svgfilter.cxx b/filter/source/svg/svgfilter.cxx
index 93a27ba634b6..d2e18d5688c2 100644
--- a/filter/source/svg/svgfilter.cxx
+++ b/filter/source/svg/svgfilter.cxx
@@ -88,7 +88,9 @@ SVGFilter::SVGFilter( const Reference< XComponentContext >& rxCtx ) :
     mbExportShapeSelection(false),
     maFilterData(),
     mxDefaultPage(),
-    mbWriterOrCalcFilter(false),
+    mbWriterFilter(false),
+    mbCalcFilter(false),
+    mbImpressFilter(false),
     mpDefaultSdrPage( nullptr ),
     mpSdrModel( nullptr ),
     mbPresentation( false ),
@@ -107,7 +109,9 @@ SVGFilter::~SVGFilter()
 
 sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescriptor )
 {
-    mbWriterOrCalcFilter = false;
+    mbWriterFilter = false;
+    mbCalcFilter = false;
+    mbImpressFilter = false;
 
     if(mxDstDoc.is()) // Import works for Impress / draw only
         return filterImpressOrDraw(rDescriptor);
@@ -120,9 +124,19 @@ sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescripto
             {
                 OUString sFilterName;
                 rDescriptor[nInd].Value >>= sFilterName;
-                if(sFilterName != "impress_svg_Export")
+                if(sFilterName == "impress_svg_Export")
                 {
-                    mbWriterOrCalcFilter = true;
+                    mbImpressFilter = true;
+                    return filterImpressOrDraw(rDescriptor);
+                }
+                else if(sFilterName == "writer_svg_Export")
+                {
+                    mbWriterFilter = true;
+                    return filterWriterOrCalc(rDescriptor);
+                }
+                else if(sFilterName == "calc_svg_Export")
+                {
+                    mbCalcFilter = true;
                     return filterWriterOrCalc(rDescriptor);
                 }
                 break;
@@ -549,7 +563,7 @@ sal_Bool SVGFilter::filterWriterOrCalc( const Sequence< PropertyValue >& rDescri
         }
     }
 
-    if(!bSelectionOnly) // For Writer onéy the selection-only mode is supported
+    if(!bSelectionOnly) // For Writer only the selection-only mode is supported
         return false;
 
     uno::Reference<frame::XDesktop2> xDesktop(frame::Desktop::create(mxContext));
@@ -564,10 +578,18 @@ sal_Bool SVGFilter::filterWriterOrCalc( const Sequence< PropertyValue >& rDescri
     if (!xSelection.is())
         return false;
 
-    xSelection->getSelection() >>= maShapeSelection;
+    bool bGotSelection = xSelection->getSelection() >>= maShapeSelection;
 
-    if (!maShapeSelection)
-        return false;
+    if (!bGotSelection)
+    {
+        if (mbWriterFilter)
+        {
+            // For Writer we might have a non-shape graphic
+            bGotSelection = implExportWriterTextGraphic(xSelection);
+        }
+        if (!bGotSelection)
+            return false;
+    }
 
     // Select only one draw page
     uno::Reference< drawing::XDrawPagesSupplier > xDrawPagesSupplier( mxSrcDoc, uno::UNO_QUERY );
diff --git a/filter/source/svg/svgfilter.hxx b/filter/source/svg/svgfilter.hxx
index 435bd35073ff..683f3f1591f2 100644
--- a/filter/source/svg/svgfilter.hxx
+++ b/filter/source/svg/svgfilter.hxx
@@ -30,6 +30,7 @@
 #include <com/sun/star/lang/XComponent.hpp>
 #include <cppuhelper/implbase.hxx>
 #include <com/sun/star/xml/sax/XWriter.hpp>
+#include <com/sun/star/view/XSelectionSupplier.hpp>
 
 #include <osl/diagnose.h>
 #include <sal/log.hxx>
@@ -57,6 +58,7 @@ using namespace ::com::sun::star::document;
 using namespace ::com::sun::star::io;
 using namespace ::com::sun::star::lang;
 using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
 using namespace ::com::sun::star::xml::sax;
 
 #define SVG_EXPORT_ALLPAGES ((sal_Int32)-1)
@@ -211,7 +213,9 @@ private:
     Reference< css::drawing::XDrawPage >              mxDefaultPage;
     std::vector< Reference< css::drawing::XDrawPage > > mSelectedPages;
 
-    bool                                mbWriterOrCalcFilter;
+    bool                                mbWriterFilter;
+    bool                                mbCalcFilter;
+    bool                                mbImpressFilter;
 
 
     /// Impress / draw only members
@@ -235,6 +239,8 @@ private:
     bool                            implExport( const Sequence< PropertyValue >& rDescriptor );
     bool                            implExportImpressOrDraw( const Reference< XOutputStream >& rxOStm );
     bool                            implExportWriterOrCalc( const Reference< XOutputStream >& rxOStm );
+    bool                            implExportWriterTextGraphic( const Reference< view::XSelectionSupplier >& xSelectionSupplier );
+
     static Reference< XWriter >     implCreateExportDocumentHandler( const Reference< XOutputStream >& rxOStm );
 
     void                            implGetPagePropSet( const Reference< css::drawing::XDrawPage > & rxPage );
commit 96922b783f04a1be28083312b7f8a813d67bade4
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu Jun 20 16:54:24 2019 +0200
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Thu Jun 20 18:05:15 2019 +0200

    lok: Implement SVG export for Calc (SelectionOnly mode)
    
    (cherry picked from commit fc0d2f1510d34d675c35d57c21da82612053cf85)
    
    Change-Id: Ic305e5305890fd1efa3a3130e5216f9c672870e5

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index d335d804d9e2..24957ac12e92 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -2563,13 +2563,19 @@ static size_t doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char** pOu
         uno::Reference<io::XOutputStream> xOut = new utl::OOutputStreamWrapper(aOutStream);
 
         utl::MediaDescriptor aMediaDescriptor;
-        if (doc_getDocumentType(pThis) == LOK_DOCTYPE_PRESENTATION)
-        {
-            aMediaDescriptor["FilterName"] <<= OUString("impress_svg_Export");
-        }
-        else if(doc_getDocumentType(pThis) == LOK_DOCTYPE_TEXT)
+        switch (doc_getDocumentType(pThis))
         {
-            aMediaDescriptor["FilterName"] <<= OUString("writer_svg_Export");
+            case LOK_DOCTYPE_PRESENTATION:
+                aMediaDescriptor["FilterName"] <<= OUString("impress_svg_Export");
+                break;
+            case LOK_DOCTYPE_TEXT:
+                aMediaDescriptor["FilterName"] <<= OUString("writer_svg_Export");
+                break;
+            case LOK_DOCTYPE_SPREADSHEET:
+                aMediaDescriptor["FilterName"] <<= OUString("calc_svg_Export");
+                break;
+            default:
+                SAL_WARN("lok", "Failed to render shape selection: Document type is not supported");
         }
         aMediaDescriptor["SelectionOnly"] <<= true;
         aMediaDescriptor["OutputStream"] <<= xOut;
diff --git a/filter/Configuration_filter.mk b/filter/Configuration_filter.mk
index b56e0ae39bc8..97023325c94e 100644
--- a/filter/Configuration_filter.mk
+++ b/filter/Configuration_filter.mk
@@ -802,11 +802,13 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_writergraphics
 # fcfg_calcgraphics
 $(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_calcgraphics_types.xcu,filter/source/config/fragments/types,\
 	png_Portable_Network_Graphic \
+	svg_Scalable_Vector_Graphics \
 ))
 
 $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_calcgraphics_filters.xcu,filter/source/config/fragments/filters,\
 	calc_jpg_Export \
 	calc_png_Export \
+	calc_svg_Export \
 ))
 
 # fcfg_internalgraphics
diff --git a/filter/source/config/fragments/filters/calc_svg_Export.xcu b/filter/source/config/fragments/filters/calc_svg_Export.xcu
new file mode 100644
index 000000000000..703ce82e9778
--- /dev/null
+++ b/filter/source/config/fragments/filters/calc_svg_Export.xcu
@@ -0,0 +1,30 @@
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+-->
+    <node oor:name="calc_svg_Export" oor:op="replace">
+        <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER INTERNAL NOTINFILEDIALOG</value></prop>
+        <prop oor:name="UIComponent"/>
+        <prop oor:name="FilterService"><value>com.sun.star.comp.Draw.SVGFilter</value></prop>
+        <prop oor:name="UserData"><value></value></prop>
+        <prop oor:name="UIName">
+            <value xml:lang="en-US">SVG - Scalable Vector Graphics</value>
+        </prop>
+        <prop oor:name="FileFormatVersion"><value>0</value></prop>
+        <prop oor:name="Type"><value>svg_Scalable_Vector_Graphics</value></prop>
+        <prop oor:name="TemplateName"/>
+        <prop oor:name="DocumentService"><value>com.sun.star.sheet.SpreadsheetDocument</value></prop>
+    </node>
diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index be397e7ac74e..b2ec3d307769 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -532,13 +532,13 @@ bool SVGFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
         }
     }
 
-    if(mbWriterFilter)
-       return implExportWriter(xOStm);
+    if(mbWriterOrCalcFilter)
+       return implExportWriterOrCalc(xOStm);
 
-    return implExportImpressDraw(xOStm);
+    return implExportImpressOrDraw(xOStm);
 }
 
-bool SVGFilter::implExportImpressDraw( const Reference< XOutputStream >& rxOStm)
+bool SVGFilter::implExportImpressOrDraw( const Reference< XOutputStream >& rxOStm)
 {
     Reference< XComponentContext >        xContext( ::comphelper::getProcessComponentContext() ) ;
     bool                                  bRet = false;
@@ -630,7 +630,7 @@ bool SVGFilter::implExportImpressDraw( const Reference< XOutputStream >& rxOStm)
 }
 
 
-bool SVGFilter::implExportWriter( const Reference< XOutputStream >& rxOStm )
+bool SVGFilter::implExportWriterOrCalc( const Reference< XOutputStream >& rxOStm )
 {
     Reference< XComponentContext >        xContext( ::comphelper::getProcessComponentContext() ) ;
     bool                                  bRet = false;
@@ -785,10 +785,10 @@ bool SVGFilter::implExportDocument()
         }
     }
 
-    if(mbWriterFilter)
-        implExportDocumentHeaderWriter(nDocX, nDocY, nDocWidth, nDocHeight);
+    if(mbWriterOrCalcFilter)
+        implExportDocumentHeaderWriterOrCalc(nDocX, nDocY, nDocWidth, nDocHeight);
     else
-        implExportDocumentHeaderImpressDraw(nDocX, nDocY, nDocWidth, nDocHeight);
+        implExportDocumentHeaderImpressOrDraw(nDocX, nDocY, nDocWidth, nDocHeight);
 
 
     if( implLookForFirstVisiblePage() )  // OK! We found at least one visible page.
@@ -849,7 +849,7 @@ bool SVGFilter::implExportDocument()
     return bRet;
 }
 
-void SVGFilter::implExportDocumentHeaderImpressDraw(sal_Int32 nDocX, sal_Int32 nDocY,
+void SVGFilter::implExportDocumentHeaderImpressOrDraw(sal_Int32 nDocX, sal_Int32 nDocY,
                                                     sal_Int32 nDocWidth, sal_Int32 nDocHeight)
 {
     const Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
@@ -942,7 +942,7 @@ void SVGFilter::implExportDocumentHeaderImpressDraw(sal_Int32 nDocX, sal_Int32 n
     }
 }
 
-void SVGFilter::implExportDocumentHeaderWriter(sal_Int32 nDocX, sal_Int32 nDocY,
+void SVGFilter::implExportDocumentHeaderWriterOrCalc(sal_Int32 nDocX, sal_Int32 nDocY,
                                                sal_Int32 nDocWidth, sal_Int32 nDocHeight)
 {
     OUString aAttr;
diff --git a/filter/source/svg/svgfilter.cxx b/filter/source/svg/svgfilter.cxx
index f3bbe783f3ac..93a27ba634b6 100644
--- a/filter/source/svg/svgfilter.cxx
+++ b/filter/source/svg/svgfilter.cxx
@@ -88,7 +88,7 @@ SVGFilter::SVGFilter( const Reference< XComponentContext >& rxCtx ) :
     mbExportShapeSelection(false),
     maFilterData(),
     mxDefaultPage(),
-    mbWriterFilter(false),
+    mbWriterOrCalcFilter(false),
     mpDefaultSdrPage( nullptr ),
     mpSdrModel( nullptr ),
     mbPresentation( false ),
@@ -107,10 +107,10 @@ SVGFilter::~SVGFilter()
 
 sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescriptor )
 {
-    mbWriterFilter = false;
+    mbWriterOrCalcFilter = false;
 
     if(mxDstDoc.is()) // Import works for Impress / draw only
-        return filterImpressDraw(rDescriptor);
+        return filterImpressOrDraw(rDescriptor);
 
     if(mxSrcDoc.is())
     {
@@ -120,20 +120,20 @@ sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescripto
             {
                 OUString sFilterName;
                 rDescriptor[nInd].Value >>= sFilterName;
-                if(sFilterName == "writer_svg_Export")
+                if(sFilterName != "impress_svg_Export")
                 {
-                    mbWriterFilter = true;
-                    return filterWriter(rDescriptor);
+                    mbWriterOrCalcFilter = true;
+                    return filterWriterOrCalc(rDescriptor);
                 }
                 break;
             }
         }
-        return filterImpressDraw(rDescriptor);
+        return filterImpressOrDraw(rDescriptor);
     }
     return false;
 }
 
-sal_Bool SVGFilter::filterImpressDraw( const Sequence< PropertyValue >& rDescriptor )
+sal_Bool SVGFilter::filterImpressOrDraw( const Sequence< PropertyValue >& rDescriptor )
 {
     SolarMutexGuard aGuard;
     vcl::Window* pFocusWindow(Application::GetFocusWindow());
@@ -536,7 +536,7 @@ sal_Bool SVGFilter::filterImpressDraw( const Sequence< PropertyValue >& rDescrip
     return bRet;
 }
 
-sal_Bool SVGFilter::filterWriter( const Sequence< PropertyValue >& rDescriptor )
+sal_Bool SVGFilter::filterWriterOrCalc( const Sequence< PropertyValue >& rDescriptor )
 {
     bool bSelectionOnly = false;
 
diff --git a/filter/source/svg/svgfilter.hxx b/filter/source/svg/svgfilter.hxx
index 77e9b607c57f..435bd35073ff 100644
--- a/filter/source/svg/svgfilter.hxx
+++ b/filter/source/svg/svgfilter.hxx
@@ -211,7 +211,7 @@ private:
     Reference< css::drawing::XDrawPage >              mxDefaultPage;
     std::vector< Reference< css::drawing::XDrawPage > > mSelectedPages;
 
-    bool                                mbWriterFilter;
+    bool                                mbWriterOrCalcFilter;
 
 
     /// Impress / draw only members
@@ -233,8 +233,8 @@ private:
 
     /// @throws css::uno::RuntimeException
     bool                            implExport( const Sequence< PropertyValue >& rDescriptor );
-    bool                            implExportImpressDraw( const Reference< XOutputStream >& rxOStm );
-    bool                            implExportWriter( const Reference< XOutputStream >& rxOStm );
+    bool                            implExportImpressOrDraw( const Reference< XOutputStream >& rxOStm );
+    bool                            implExportWriterOrCalc( const Reference< XOutputStream >& rxOStm );
     static Reference< XWriter >     implCreateExportDocumentHandler( const Reference< XOutputStream >& rxOStm );
 
     void                            implGetPagePropSet( const Reference< css::drawing::XDrawPage > & rxPage );
@@ -246,10 +246,10 @@ private:
     void                            implGenerateScript();
 
     bool                            implExportDocument();
-    void                            implExportDocumentHeaderImpressDraw(sal_Int32 nDocX, sal_Int32 nDocY,
-                                                                        sal_Int32 nDocWidth, sal_Int32 nDocHeight);
-    void                            implExportDocumentHeaderWriter(sal_Int32 nDocX, sal_Int32 nDocY,
-                                                                   sal_Int32 nDocWidth, sal_Int32 nDocHeight);
+    void                            implExportDocumentHeaderImpressOrDraw(sal_Int32 nDocX, sal_Int32 nDocY,
+                                                                          sal_Int32 nDocWidth, sal_Int32 nDocHeight);
+    void                            implExportDocumentHeaderWriterOrCalc(sal_Int32 nDocX, sal_Int32 nDocY,
+                                                                         sal_Int32 nDocWidth, sal_Int32 nDocHeight);
     void                            implExportAnimations();
 
     bool                            implExportMasterPages( const std::vector< Reference< css::drawing::XDrawPage > >& rxPages,
@@ -281,8 +281,8 @@ private:
                                                                 const Reference< XPropertySetInfo > & rxPropSetInfo );
     DECL_LINK( CalcFieldHdl, EditFieldInfo*, void );
 
-    sal_Bool filterImpressDraw( const Sequence< PropertyValue >& rDescriptor );
-    sal_Bool filterWriter( const Sequence< PropertyValue >& rDescriptor );
+    sal_Bool filterImpressOrDraw( const Sequence< PropertyValue >& rDescriptor );
+    sal_Bool filterWriterOrCalc( const Sequence< PropertyValue >& rDescriptor );
 
 protected:
 
commit 02aa81895c77bf84f9d9ad2ccfee9355839ac0d1
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Thu Jun 20 16:43:28 2019 +0200
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Thu Jun 20 18:05:15 2019 +0200

    lok: Implement SVG export for Writer (SelectionOnly mode)
    
    Separate generic code from Impress / Draw specific code
    and implement shape selection handling in case of Writer.
    This is an internal filter, so it can be called only from
    the code.
    
    (cherry picked from commit e54700c45b22b10ec4f364800e0ad7c0627a6d3b)
    
    Change-Id: I807e04a0949530d6029037bb964c10c80197ff33

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index f6f933a8fd73..d335d804d9e2 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -2563,7 +2563,14 @@ static size_t doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char** pOu
         uno::Reference<io::XOutputStream> xOut = new utl::OOutputStreamWrapper(aOutStream);
 
         utl::MediaDescriptor aMediaDescriptor;
-        aMediaDescriptor["FilterName"] <<= OUString("impress_svg_Export");
+        if (doc_getDocumentType(pThis) == LOK_DOCTYPE_PRESENTATION)
+        {
+            aMediaDescriptor["FilterName"] <<= OUString("impress_svg_Export");
+        }
+        else if(doc_getDocumentType(pThis) == LOK_DOCTYPE_TEXT)
+        {
+            aMediaDescriptor["FilterName"] <<= OUString("writer_svg_Export");
+        }
         aMediaDescriptor["SelectionOnly"] <<= true;
         aMediaDescriptor["OutputStream"] <<= xOut;
 
diff --git a/filter/Configuration_filter.mk b/filter/Configuration_filter.mk
index d7a6322e5564..b56e0ae39bc8 100644
--- a/filter/Configuration_filter.mk
+++ b/filter/Configuration_filter.mk
@@ -790,11 +790,13 @@ $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_impressgraphic
 $(eval $(call filter_Configuration_add_types,fcfg_langpack,fcfg_writergraphics_types.xcu,filter/source/config/fragments/types,\
 	jpg_JPEG \
 	png_Portable_Network_Graphic \
+	svg_Scalable_Vector_Graphics \
 ))
 
 $(eval $(call filter_Configuration_add_filters,fcfg_langpack,fcfg_writergraphics_filters.xcu,filter/source/config/fragments/filters,\
 	writer_jpg_Export \
 	writer_png_Export \
+	writer_svg_Export \
 ))
 
 # fcfg_calcgraphics
diff --git a/filter/source/config/fragments/filters/writer_svg_Export.xcu b/filter/source/config/fragments/filters/writer_svg_Export.xcu
new file mode 100644
index 000000000000..c08576cdd69b
--- /dev/null
+++ b/filter/source/config/fragments/filters/writer_svg_Export.xcu
@@ -0,0 +1,30 @@
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+-->
+    <node oor:name="writer_svg_Export" oor:op="replace">
+        <prop oor:name="Flags"><value>EXPORT ALIEN 3RDPARTYFILTER INTERNAL NOTINFILEDIALOG</value></prop>
+        <prop oor:name="UIComponent"/>
+        <prop oor:name="FilterService"><value>com.sun.star.comp.Draw.SVGFilter</value></prop>
+        <prop oor:name="UserData"><value></value></prop>
+        <prop oor:name="UIName">
+            <value xml:lang="en-US">SVG - Scalable Vector Graphics</value>
+        </prop>
+        <prop oor:name="FileFormatVersion"><value>0</value></prop>
+        <prop oor:name="Type"><value>svg_Scalable_Vector_Graphics</value></prop>
+        <prop oor:name="TemplateName"/>
+        <prop oor:name="DocumentService"><value>com.sun.star.text.TextDocument</value></prop>
+    </node>
diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index 8ebeb51a2c2f..be397e7ac74e 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -505,12 +505,10 @@ bool EqualityBitmap::operator()( const ObjectRepresentation& rObjRep1,
 
 bool SVGFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
 {
-    Reference< XComponentContext >        xContext( ::comphelper::getProcessComponentContext() ) ;
     Reference< XOutputStream >            xOStm;
     std::unique_ptr<SvStream>             pOStm;
     sal_Int32                             nLength = rDescriptor.getLength();
     const PropertyValue*                  pValue = rDescriptor.getConstArray();
-    bool                                  bRet = false;
 
     maFilterData.realloc( 0 );
 
@@ -534,11 +532,22 @@ bool SVGFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
         }
     }
 
-    if( xOStm.is() )
+    if(mbWriterFilter)
+       return implExportWriter(xOStm);
+
+    return implExportImpressDraw(xOStm);
+}
+
+bool SVGFilter::implExportImpressDraw( const Reference< XOutputStream >& rxOStm)
+{
+    Reference< XComponentContext >        xContext( ::comphelper::getProcessComponentContext() ) ;
+    bool                                  bRet = false;
+
+    if( rxOStm.is() )
     {
         if( !mSelectedPages.empty() && !mMasterPageTargets.empty() )
         {
-            Reference< XDocumentHandler > xDocHandler( implCreateExportDocumentHandler( xOStm ), UNO_QUERY );
+            Reference< XDocumentHandler > xDocHandler( implCreateExportDocumentHandler( rxOStm ), UNO_QUERY );
 
             if( xDocHandler.is() )
             {
@@ -617,7 +626,51 @@ bool SVGFilter::implExport( const Sequence< PropertyValue >& rDescriptor )
             }
         }
     }
+    return bRet;
+}
+
+
+bool SVGFilter::implExportWriter( const Reference< XOutputStream >& rxOStm )
+{
+    Reference< XComponentContext >        xContext( ::comphelper::getProcessComponentContext() ) ;
+    bool                                  bRet = false;
+
+    if( rxOStm.is() )
+    {
+        Reference< XDocumentHandler > xDocHandler( implCreateExportDocumentHandler( rxOStm ), UNO_QUERY );
 
+        if( xDocHandler.is() )
+        {
+            mpObjects = new ObjectMap;
+
+            // mpSVGExport = new SVGExport( xDocHandler );
+            mpSVGExport = new SVGExport( xContext, xDocHandler, maFilterData );
+
+            // xSVGExport is set up only to manage the life-time of the object pointed by mpSVGExport,
+            // and in order to prevent that it is destroyed when passed to AnimationExporter.
+            Reference< XInterface > xSVGExport = static_cast< css::document::XFilter* >( mpSVGExport );
+
+            try
+            {
+                mxDefaultPage = mSelectedPages[0];
+                bRet = implExportDocument();
+            }
+            catch( ... )
+            {
+                delete mpSVGDoc;
+                mpSVGDoc = nullptr;
+                OSL_FAIL( "Exception caught" );
+            }
+
+            delete mpSVGWriter;
+            mpSVGWriter = nullptr;
+            mpSVGExport = nullptr; // pointed object is released by xSVGExport dtor at the end of this scope
+            delete mpSVGFontExport;
+            mpSVGFontExport = nullptr;
+            delete mpObjects;
+            mpObjects = nullptr;
+        }
+    }
     return bRet;
 }
 
@@ -640,6 +693,11 @@ bool SVGFilter::implLookForFirstVisiblePage()
 {
     sal_Int32 nCurPage = 0, nLastPage = mSelectedPages.size() - 1;
 
+    if(!mbPresentation || mbSinglePage)
+    {
+        mnVisiblePage = nCurPage;
+    }
+
     while( ( nCurPage <= nLastPage ) && ( -1 == mnVisiblePage ) )
     {
         const Reference< css::drawing::XDrawPage > & xDrawPage = mSelectedPages[nCurPage];
@@ -652,8 +710,7 @@ bool SVGFilter::implLookForFirstVisiblePage()
             {
                 bool bVisible = false;
 
-                if( !mbPresentation || mbSinglePage ||
-                    ( ( xPropSet->getPropertyValue( "Visible" ) >>= bVisible ) && bVisible ) )
+                if( ( xPropSet->getPropertyValue( "Visible" ) >>= bVisible ) && bVisible )
                 {
                     mnVisiblePage = nCurPage;
                 }
@@ -668,17 +725,15 @@ bool SVGFilter::implLookForFirstVisiblePage()
 
 bool SVGFilter::implExportDocument()
 {
-    OUString         aAttr;
     sal_Int32        nDocX = 0, nDocY = 0; // #i124608#
     sal_Int32        nDocWidth = 0, nDocHeight = 0;
-    bool         bRet = false;
+    bool             bRet = false;
     sal_Int32        nLastPage = mSelectedPages.size() - 1;
 
     mbSinglePage = (nLastPage == 0);
     mnVisiblePage = -1;
 
     const Reference< XPropertySet >             xDefaultPagePropertySet( mxDefaultPage, UNO_QUERY );
-    const Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
 
     // #i124608#
     mbExportShapeSelection = mbSinglePage && maShapeSelection.is() && maShapeSelection->getCount();
@@ -703,23 +758,19 @@ bool SVGFilter::implExportDocument()
         if(xPrimitiveFactory.is())
         {
             Reference< css::drawing::XShape > xShapeCandidate;
-            const Sequence< PropertyValue > aViewInformation;
-            const Sequence< PropertyValue > aParams;
 
             for(sal_Int32 a(0); a < maShapeSelection->getCount(); a++)
             {
                 if((maShapeSelection->getByIndex(a) >>= xShapeCandidate) && xShapeCandidate.is())
                 {
-                    const Sequence< Reference< XPrimitive2D > > aPrimitiveSequence(
-                        xPrimitiveFactory->createPrimitivesFromXShape( xShapeCandidate, aParams ));
-                    const sal_Int32 nCount(aPrimitiveSequence.getLength());
 
-                    for(sal_Int32 nIndex = 0; nIndex < nCount; nIndex++)
+                    Reference< XPropertySet > xShapePropSet( xShapeCandidate, UNO_QUERY );
+                    css::awt::Rectangle aBoundRect;
+                    if( xShapePropSet.is() && ( xShapePropSet->getPropertyValue( "BoundRect" ) >>= aBoundRect ))
                     {
-                        const RealRectangle2D aRect(aPrimitiveSequence[nIndex]->getRange(aViewInformation));
-
-                        aShapeRange.expand(basegfx::B2DTuple(aRect.X1, aRect.Y1));
-                        aShapeRange.expand(basegfx::B2DTuple(aRect.X2, aRect.Y2));
+                        aShapeRange.expand(basegfx::B2DTuple(aBoundRect.X, aBoundRect.Y));
+                        aShapeRange.expand(basegfx::B2DTuple(aBoundRect.X + aBoundRect.Width,
+                                                             aBoundRect.Y + aBoundRect.Height));
                     }
                 }
             }
@@ -734,6 +785,74 @@ bool SVGFilter::implExportDocument()
         }
     }
 
+    if(mbWriterFilter)
+        implExportDocumentHeaderWriter(nDocX, nDocY, nDocWidth, nDocHeight);
+    else
+        implExportDocumentHeaderImpressDraw(nDocX, nDocY, nDocWidth, nDocHeight);
+
+
+    if( implLookForFirstVisiblePage() )  // OK! We found at least one visible page.
+    {
+        if( mbPresentation && !mbExportShapeSelection )
+        {
+            implGenerateMetaData();
+            implExportAnimations();
+        }
+        else
+        {
+            implGetPagePropSet( mSelectedPages[0] );
+        }
+
+        // Create the (Shape, GDIMetaFile) map
+        if( implCreateObjects() )
+        {
+            ObjectMap::const_iterator                aIter( mpObjects->begin() );
+            ::std::vector< ObjectRepresentation >    aObjects( mpObjects->size() );
+            sal_uInt32                               nPos = 0;
+
+            while( aIter != mpObjects->end() )
+            {
+                aObjects[ nPos++ ] = (*aIter).second;
+                ++aIter;
+            }
+
+            mpSVGFontExport = new SVGFontExport( *mpSVGExport, aObjects );
+            mpSVGWriter = new SVGActionWriter( *mpSVGExport, *mpSVGFontExport );
+
+            if( mpSVGExport->IsEmbedFonts() )
+            {
+                mpSVGFontExport->EmbedFonts();
+            }
+            if( !mpSVGExport->IsUsePositionedCharacters() )
+            {
+                implExportTextShapeIndex();
+                implEmbedBulletGlyphs();
+                implExportTextEmbeddedBitmaps();
+            }
+
+            // #i124608# export a given object selection, so no MasterPage export at all
+            if (!mbExportShapeSelection)
+                implExportMasterPages( mMasterPageTargets, 0, mMasterPageTargets.size() - 1 );
+            implExportDrawPages( mSelectedPages, 0, nLastPage );
+
+            if( mbPresentation && !mbExportShapeSelection )
+            {
+                implGenerateScript();
+            }
+
+            delete mpSVGDoc;
+            mpSVGDoc = nullptr;
+            bRet = true;
+        }
+    }
+
+    return bRet;
+}
+
+void SVGFilter::implExportDocumentHeaderImpressDraw(sal_Int32 nDocX, sal_Int32 nDocY,
+                                                    sal_Int32 nDocWidth, sal_Int32 nDocHeight)
+{
+    const Reference< XExtendedDocumentHandler > xExtDocHandler( mpSVGExport->GetDocHandler(), UNO_QUERY );
     if( xExtDocHandler.is() && !mpSVGExport->IsUseTinyProfile() )
     {
         xExtDocHandler->unknown( SVG_DTD_STRING );
@@ -747,6 +866,7 @@ bool SVGFilter::implExportDocument()
     // The following if block means that the slide size is not adapted
     // to the size of the browser window, moreover the slide is top left aligned
     // instead of centered:
+    OUString aAttr;
     if( !mbPresentation )
     {
         aAttr = OUString::number( nDocWidth * 0.01 ) + "mm";
@@ -820,64 +940,40 @@ bool SVGFilter::implExportDocument()
             }
         }
     }
+}
 
-    if( implLookForFirstVisiblePage() )  // OK! We found at least one visible page.
-    {
-        if( mbPresentation && !mbExportShapeSelection )
-        {
-            implGenerateMetaData();
-            implExportAnimations();
-        }
-        else
-        {
-            implGetPagePropSet( mSelectedPages[0] );
-        }
+void SVGFilter::implExportDocumentHeaderWriter(sal_Int32 nDocX, sal_Int32 nDocY,
+                                               sal_Int32 nDocWidth, sal_Int32 nDocHeight)
+{
+    OUString aAttr;
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "version", "1.2" );
 
-        // Create the (Shape, GDIMetaFile) map
-        if( implCreateObjects() )
-        {
-            ::std::vector< ObjectRepresentation >    aObjects( mpObjects->size() );
-            sal_uInt32                               nPos = 0;
+    aAttr = OUString::number( nDocWidth * 0.01 ) + "mm";
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "width", aAttr );
 
-            for (auto const& elem : *mpObjects)
-            {
-                aObjects[ nPos++ ] = elem.second;
-            }
+    aAttr = OUString::number( nDocHeight * 0.01 ) + "mm";
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "height", aAttr );
 
-            mpSVGFontExport = new SVGFontExport( *mpSVGExport, aObjects );
-            mpSVGWriter = new SVGActionWriter( *mpSVGExport, *mpSVGFontExport );
-
-            if( mpSVGExport->IsEmbedFonts() )
-            {
-                mpSVGFontExport->EmbedFonts();
-            }
-            if( !mpSVGExport->IsUsePositionedCharacters() )
-            {
-                implExportTextShapeIndex();
-                implEmbedBulletGlyphs();
-                implExportTextEmbeddedBitmaps();
-            }
-
-            // #i124608# export a given object selection, so no MasterPage export at all
-            if (!mbExportShapeSelection)
-                implExportMasterPages( mMasterPageTargets, 0, mMasterPageTargets.size() - 1 );
-            implExportDrawPages( mSelectedPages, 0, nLastPage );
+    aAttr = OUString::number(nDocX) + " " + OUString::number(nDocY) + " ";
+    aAttr += OUString::number(nDocWidth) + " " + OUString::number(nDocHeight);
 
-            if( mbPresentation && !mbExportShapeSelection )
-            {
-                implGenerateScript();
-            }
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "viewBox", aAttr );
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "preserveAspectRatio", "xMidYMid" );
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "fill-rule", "evenodd" );
 
-            delete mpSVGDoc;
-            mpSVGDoc = nullptr;
-            bRet = true;
-        }
-    }
+    // standard line width is based on 1 pixel on a 90 DPI device (0.28222mmm)
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "stroke-width", OUString::number( 28.222 ) );
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "stroke-linejoin", "round" );
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns", constSvgNamespace );
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:ooo", "http://xml.openoffice.org/svg/export" );
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:xlink", "http://www.w3.org/1999/xlink" );
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0" );
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xmlns:smil", "urn:oasis:names:tc:opendocument:xmlns:smil-compatible:1.0" );
+    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "xml:space", "preserve" );
 
-    return bRet;
+    mpSVGDoc = new SvXMLElementExport( *mpSVGExport, XML_NAMESPACE_NONE, "svg", true, true );
 }
 
-
 /// Append aField to aFieldSet if it is not already present in the set and create the field id sFieldId
 template< typename TextFieldType >
 static OUString implGenerateFieldId( std::vector< TextField* > & aFieldSet,
diff --git a/filter/source/svg/svgfilter.cxx b/filter/source/svg/svgfilter.cxx
index ebcc522fbbca..f3bbe783f3ac 100644
--- a/filter/source/svg/svgfilter.cxx
+++ b/filter/source/svg/svgfilter.cxx
@@ -24,6 +24,7 @@
 #include <comphelper/lok.hxx>
 #include <comphelper/servicedecl.hxx>
 #include <uno/environment.h>
+#include <com/sun/star/text/XTextDocument.hpp>
 #include <com/sun/star/drawing/XDrawPage.hpp>
 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
 #include <com/sun/star/drawing/XDrawView.hpp>
@@ -78,17 +79,19 @@ SVGFilter::SVGFilter( const Reference< XComponentContext >& rxCtx ) :
     mpSVGExport( nullptr ),
     mpSVGFontExport( nullptr ),
     mpSVGWriter( nullptr ),
-    mpDefaultSdrPage( nullptr ),
-    mbPresentation( false ),
     mbSinglePage( false ),
     mnVisiblePage( -1 ),
     mpObjects( nullptr ),
     mxSrcDoc(),
     mxDstDoc(),
-    mxDefaultPage(),
-    maFilterData(),
     maShapeSelection(),
     mbExportShapeSelection(false),
+    maFilterData(),
+    mxDefaultPage(),
+    mbWriterFilter(false),
+    mpDefaultSdrPage( nullptr ),
+    mpSdrModel( nullptr ),
+    mbPresentation( false ),
     maOldFieldHdl()
 {
 }
@@ -104,6 +107,34 @@ SVGFilter::~SVGFilter()
 
 sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescriptor )
 {
+    mbWriterFilter = false;
+
+    if(mxDstDoc.is()) // Import works for Impress / draw only
+        return filterImpressDraw(rDescriptor);
+
+    if(mxSrcDoc.is())
+    {
+        for (sal_Int32 nInd = 0; nInd < rDescriptor.getLength(); nInd++)
+        {
+            if (rDescriptor[nInd].Name == "FilterName")
+            {
+                OUString sFilterName;
+                rDescriptor[nInd].Value >>= sFilterName;
+                if(sFilterName == "writer_svg_Export")
+                {
+                    mbWriterFilter = true;
+                    return filterWriter(rDescriptor);
+                }
+                break;
+            }
+        }
+        return filterImpressDraw(rDescriptor);
+    }
+    return false;
+}
+
+sal_Bool SVGFilter::filterImpressDraw( const Sequence< PropertyValue >& rDescriptor )
+{
     SolarMutexGuard aGuard;
     vcl::Window* pFocusWindow(Application::GetFocusWindow());
     bool bRet(false);
@@ -505,6 +536,49 @@ sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescripto
     return bRet;
 }
 
+sal_Bool SVGFilter::filterWriter( const Sequence< PropertyValue >& rDescriptor )
+{
+    bool bSelectionOnly = false;
+
+    for (sal_Int32 nInd = 0; nInd < rDescriptor.getLength(); nInd++)
+    {
+        if (rDescriptor[nInd].Name == "SelectionOnly")
+        {
+            rDescriptor[nInd].Value >>= bSelectionOnly;
+            break;
+        }
+    }
+
+    if(!bSelectionOnly) // For Writer onéy the selection-only mode is supported
+        return false;
+
+    uno::Reference<frame::XDesktop2> xDesktop(frame::Desktop::create(mxContext));
+    uno::Reference<frame::XController > xController;
+    if (xDesktop->getCurrentFrame().is())
+    {
+        uno::Reference<frame::XFrame> xFrame(xDesktop->getCurrentFrame(), uno::UNO_QUERY_THROW);
+        xController.set(xFrame->getController(), uno::UNO_QUERY_THROW);
+    }
+
+    Reference< view::XSelectionSupplier > xSelection (xController, UNO_QUERY);
+    if (!xSelection.is())
+        return false;
+
+    xSelection->getSelection() >>= maShapeSelection;
+
+    if (!maShapeSelection)
+        return false;
+
+    // Select only one draw page
+    uno::Reference< drawing::XDrawPagesSupplier > xDrawPagesSupplier( mxSrcDoc, uno::UNO_QUERY );
+    uno::Reference<drawing::XDrawPages> xDrawPages = xDrawPagesSupplier->getDrawPages();
+    uno::Reference< drawing::XDrawPage > xDrawPage( xDrawPages->getByIndex(0), uno::UNO_QUERY );
+    mSelectedPages.resize( 1 );
+    mSelectedPages[0] = xDrawPage;
+
+    return implExport( rDescriptor );
+}
+
 void SAL_CALL SVGFilter::cancel( )
 {
 }
diff --git a/filter/source/svg/svgfilter.hxx b/filter/source/svg/svgfilter.hxx
index 1b5254e25469..77e9b607c57f 100644
--- a/filter/source/svg/svgfilter.hxx
+++ b/filter/source/svg/svgfilter.hxx
@@ -192,31 +192,40 @@ public:
 
 private:
 
+    /// Generally use members
+
     Reference< XComponentContext >      mxContext;
     SvXMLElementExport*                 mpSVGDoc;
     SVGExport*                          mpSVGExport;
     SVGFontExport*                      mpSVGFontExport;
     SVGActionWriter*                    mpSVGWriter;
-    SdrPage*                            mpDefaultSdrPage;
-    bool                            mbPresentation;
-    bool                            mbSinglePage;
+    bool                                mbSinglePage;
     sal_Int32                           mnVisiblePage;
-    PagePropertySet                     mVisiblePagePropSet;
-    OUString                     msClipPathId;
-    UCharSetMapMap                      mTextFieldCharSets;
-    Reference< XInterface >             mCreateOjectsCurrentMasterPage;
-    UOStringMap                         mTextShapeIdListMap;
-    MetaBitmapActionSet                 mEmbeddedBitmapActionSet;
-    ObjectMap                           mEmbeddedBitmapActionMap;
     ObjectMap*                          mpObjects;
     Reference< XComponent >             mxSrcDoc;
     Reference< XComponent >             mxDstDoc;
-    Reference< css::drawing::XDrawPage > mxDefaultPage;
-    Sequence< PropertyValue >           maFilterData;
     // #i124608# explicit ShapeSelection for export when export of the selection is wanted
     Reference< css::drawing::XShapes >  maShapeSelection;
     bool                                mbExportShapeSelection;
+    Sequence< PropertyValue >           maFilterData;
+    Reference< css::drawing::XDrawPage >              mxDefaultPage;
     std::vector< Reference< css::drawing::XDrawPage > > mSelectedPages;
+
+    bool                                mbWriterFilter;
+
+
+    /// Impress / draw only members
+
+    SdrPage*                            mpDefaultSdrPage;
+    SdrModel*                           mpSdrModel;
+    bool                                mbPresentation;
+    PagePropertySet                     mVisiblePagePropSet;
+    OUString                            msClipPathId;
+    UCharSetMapMap                      mTextFieldCharSets;
+    Reference< XInterface >             mCreateOjectsCurrentMasterPage;
+    UOStringMap                         mTextShapeIdListMap;
+    MetaBitmapActionSet                 mEmbeddedBitmapActionSet;
+    ObjectMap                           mEmbeddedBitmapActionMap;
     std::vector< Reference< css::drawing::XDrawPage > > mMasterPageTargets;
 
     Link<EditFieldInfo*,void>           maOldFieldHdl;
@@ -224,6 +233,8 @@ private:
 
     /// @throws css::uno::RuntimeException
     bool                            implExport( const Sequence< PropertyValue >& rDescriptor );
+    bool                            implExportImpressDraw( const Reference< XOutputStream >& rxOStm );
+    bool                            implExportWriter( const Reference< XOutputStream >& rxOStm );
     static Reference< XWriter >     implCreateExportDocumentHandler( const Reference< XOutputStream >& rxOStm );
 
     void                            implGetPagePropSet( const Reference< css::drawing::XDrawPage > & rxPage );
@@ -235,6 +246,10 @@ private:
     void                            implGenerateScript();
 
     bool                            implExportDocument();
+    void                            implExportDocumentHeaderImpressDraw(sal_Int32 nDocX, sal_Int32 nDocY,
+                                                                        sal_Int32 nDocWidth, sal_Int32 nDocHeight);
+    void                            implExportDocumentHeaderWriter(sal_Int32 nDocX, sal_Int32 nDocY,
+                                                                   sal_Int32 nDocWidth, sal_Int32 nDocHeight);
     void                            implExportAnimations();
 
     bool                            implExportMasterPages( const std::vector< Reference< css::drawing::XDrawPage > >& rxPages,
@@ -266,6 +281,9 @@ private:
                                                                 const Reference< XPropertySetInfo > & rxPropSetInfo );
     DECL_LINK( CalcFieldHdl, EditFieldInfo*, void );
 
+    sal_Bool filterImpressDraw( const Sequence< PropertyValue >& rDescriptor );
+    sal_Bool filterWriter( const Sequence< PropertyValue >& rDescriptor );
+
 protected:
 
     // XFilter
commit 43777b9d951ae2925129c4056c44cb6c2d539fb6
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Fri Nov 23 12:14:49 2018 +0100
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Thu Jun 20 18:05:15 2019 +0200

    Avoid moving the shape by rotation
    
    The difference between Impress and Writer is the used
    unit. We can assume that SID_ATTR_TRANSFORM_ROT_X and
    SID_ATTR_TRANSFORM_ROT_Y contains the values in twips.
    
    Change-Id: I44ba9532348200742b2c7c369b89eb2545295684
    (cherry picked from commit 4a77c309bd44418cb86b30ab88b1e1506b66d4b9)

diff --git a/svx/source/svdraw/svdedtv1.cxx b/svx/source/svdraw/svdedtv1.cxx
index 43f72e63369f..21efbfcb74ea 100644
--- a/svx/source/svdraw/svdedtv1.cxx
+++ b/svx/source/svdraw/svdedtv1.cxx
@@ -62,7 +62,8 @@
 #include <svx/xlnedwit.hxx>
 #include <svx/xlnstwit.hxx>
 #include <svx/xlnwtit.hxx>
-
+#include <svx/svdview.hxx>
+#include <comphelper/lok.hxx>
 
 // EditView
 
@@ -1596,6 +1597,15 @@ void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr)
 
         if(GetSdrPageView())
         {
+            const bool bTiledRendering = comphelper::LibreOfficeKit::isActive();
+            if(bTiledRendering) {
+                // We gets the position in twips
+                if (OutputDevice* pOutputDevice = mpMarkedPV->GetView().GetFirstOutputDevice())
+                {
+                    if (pOutputDevice->GetMapMode().GetMapUnit() == MapUnit::Map100thMM)
+                        aRef = OutputDevice::LogicToLogic(aRef, MapMode(MapUnit::MapTwip), MapMode(MapUnit::Map100thMM));
+                }
+            }
             GetSdrPageView()->PagePosToLogic(aRef);
         }
 
commit b7840ea18541c73a577fbd61a7bce09cd8ac17e2
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Wed Nov 14 12:50:55 2018 +0100
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Thu Jun 20 18:05:15 2019 +0200

    Avoid writing out unneeded data to SVG file in SelectionOnly mode
    
    (cherry picked from commit 8ade6298814a7223eb1b11d72534dd4bb4257a4d)
    
    Change-Id: I6d0ce089be051667e965aff45a63f6b1a8342952

diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index 437ffd297ee1..8ebeb51a2c2f 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -786,6 +786,7 @@ bool SVGFilter::implExportDocument()
     mpSVGDoc = new SvXMLElementExport( *mpSVGExport, XML_NAMESPACE_NONE, "svg", true, true );
 
     // Create a ClipPath element that will be used for cutting bitmaps and other elements that could exceed the page margins.
+    if(!mbExportShapeSelection)
     {
         mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "ClipPathGroup" );
         SvXMLElementExport aDefsElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", true, true );
@@ -804,7 +805,6 @@ bool SVGFilter::implExportDocument()
         }
         // Create a ClipPath element applied to the leaving slide in order
         // to avoid that slide borders are visible during transition
-        if(!mbExportShapeSelection)
         {
             mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", "presentation_clip_path_shrink" );
             mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "clipPathUnits", "userSpaceOnUse" );
@@ -1190,6 +1190,9 @@ void SVGFilter::implExportAnimations()
 
 void SVGFilter::implExportTextShapeIndex()
 {
+    if(mbExportShapeSelection)
+        return;
+
     mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "TextShapeIndex" );
     SvXMLElementExport aDefsContainerElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", true, true );
 
@@ -1488,66 +1491,77 @@ void SVGFilter::implExportDrawPages( const std::vector< Reference< css::drawing:
         }
     }
 
-    // We wrap all slide in a group element with class name "SlideGroup".
-    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "SlideGroup" );
-    SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
-
-    for( sal_Int32 i = nFirstPage; i <= nLastPage; ++i )
+    if(!mbExportShapeSelection)
     {
-        Reference< css::drawing::XShapes > xShapes;
+        // We wrap all slide in a group element with class name "SlideGroup".
+        mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "SlideGroup" );
+        SvXMLElementExport aExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
 
-        if (mbExportShapeSelection)
-        {
-            // #i124608# export a given object selection
-            xShapes = maShapeSelection;
-        }
-        else
+        for( sal_Int32 i = nFirstPage; i <= nLastPage; ++i )
         {
-            xShapes.set( rxPages[i], UNO_QUERY );
-        }
+            Reference< css::drawing::XShapes > xShapes;
 
-        if( xShapes.is() )
-        {
-            // Insert the <g> open tag related to the svg element for
-            // handling a slide visibility.
-            // In case the exported slides are more than one the initial
-            // visibility of each slide is set to 'hidden'.
-            if( mbPresentation )
+            if (mbExportShapeSelection)
             {
-                mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", "hidden" );
+                // #i124608# export a given object selection
+                xShapes = maShapeSelection;
+            }
+            else
+            {
+                xShapes.set( rxPages[i], UNO_QUERY );
             }
-            SvXMLElementExport aGElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
-
 
+            if( xShapes.is() )
             {
-                // Insert a further inner the <g> open tag for handling elements
-                // inserted before or after a slide: that is used for some
-                // when switching from the last to the first slide.
-                const OUString & sPageId = implGetValidIDFromInterface( rxPages[i] );
-                OUString sContainerId = "container-";
-                sContainerId += sPageId;
-                mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sContainerId );
-                SvXMLElementExport aContainerExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
+                // Insert the <g> open tag related to the svg element for
+                // handling a slide visibility.
+                // In case the exported slides are more than one the initial
+                // visibility of each slide is set to 'hidden'.
+                if( mbPresentation )
+                {
+                    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", "hidden" );
+                }
+                SvXMLElementExport aGElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
+
 
                 {
-                    // add id attribute
-                    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sPageId );
+                    // Insert a further inner the <g> open tag for handling elements
+                    // inserted before or after a slide: that is used for some
+                    // when switching from the last to the first slide.
+                    const OUString & sPageId = implGetValidIDFromInterface( rxPages[i] );
+                    OUString sContainerId = "container-";
+                    sContainerId += sPageId;
+                    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sContainerId );
+                    SvXMLElementExport aContainerExp( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
 
-                    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "Slide" );
+                    {
+                        // add id attribute
+                        mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sPageId );
 
-                    // Adding a clip path to each exported slide , so in case
-                    // bitmaps or other elements exceed the slide margins, they are
-                    // trimmed, even when they are shown inside a thumbnail view.
-                    OUString sClipPathAttrValue = "url(#" + msClipPathId + ")";
-                    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "clip-path", sClipPathAttrValue );
+                        mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "Slide" );
 
-                    SvXMLElementExport aSlideElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
+                        // Adding a clip path to each exported slide , so in case
+                        // bitmaps or other elements exceed the slide margins, they are
+                        // trimmed, even when they are shown inside a thumbnail view.
+                        OUString sClipPathAttrValue = "url(#" + msClipPathId + ")";
+                        mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "clip-path", sClipPathAttrValue );
 
-                    implExportPage( sPageId, rxPages[i], xShapes, false /* is not a master page */ );
-                }
-            } // append the </g> closing tag related to inserted elements
-        } // append the </g> closing tag related to the svg element handling the slide visibility
+                        SvXMLElementExport aSlideElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
+
+                        implExportPage( sPageId, rxPages[i], xShapes, false /* is not a master page */ );
+                    }
+                } // append the </g> closing tag related to inserted elements
+            } // append the </g> closing tag related to the svg element handling the slide visibility
+        }
     }
+    else
+    {
+        assert(maShapeSelection.is());
+        assert(rxPages.size() == 1);
+
+        const OUString & sPageId = implGetValidIDFromInterface( rxPages[0] );
+        implExportPage( sPageId, rxPages[0], maShapeSelection, false /* is not a master page */ );
+     }
 }
 
 
commit 19e0d6662ff86913dc066095c26921d6f4a45c01
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Mon Nov 12 20:04:05 2018 +0100
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Thu Jun 20 18:05:15 2019 +0200

    Remove noise from the SVG file exported in SelectionOnly mode
    
    Change-Id: Ia09f6ab40c20c17230e8b544987a5d11b7359f2f
    (cherry picked from commit 13f8545b84ab62fe9c19b58c024f46f89518ce03)

diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index bfee60ca26e1..437ffd297ee1 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -804,6 +804,7 @@ bool SVGFilter::implExportDocument()
         }
         // Create a ClipPath element applied to the leaving slide in order
         // to avoid that slide borders are visible during transition
+        if(!mbExportShapeSelection)
         {
             mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", "presentation_clip_path_shrink" );
             mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "clipPathUnits", "userSpaceOnUse" );
@@ -822,7 +823,7 @@ bool SVGFilter::implExportDocument()
 
     if( implLookForFirstVisiblePage() )  // OK! We found at least one visible page.
     {
-        if( mbPresentation )
+        if( mbPresentation && !mbExportShapeSelection )
         {
             implGenerateMetaData();
             implExportAnimations();
@@ -1263,6 +1264,9 @@ void SVGFilter::implEmbedBulletGlyph( sal_Unicode cBullet, const OUString & sPat
  */
 void SVGFilter::implExportTextEmbeddedBitmaps()
 {
+    if (mEmbeddedBitmapActionSet.empty())
+        return;
+
     mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "TextEmbeddedBitmaps" );
     SvXMLElementExport aDefsContainerElem( *mpSVGExport, XML_NAMESPACE_NONE, "defs", true, true );
 
@@ -1463,7 +1467,7 @@ void SVGFilter::implExportDrawPages( const std::vector< Reference< css::drawing:
                 "SVGFilter::implExportDrawPages: nFirstPage > nLastPage" );
 
     // dummy slide - used as leaving slide for transition on the first slide
-    if( mbPresentation )
+    if( mbPresentation && !mbExportShapeSelection)
     {
         mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class", "DummySlide" );
         SvXMLElementExport aDummySlideElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
commit b15f1c7c234bf21bceafdb89f8b2791ae7fa0641
Author:     Ashod Nakashian <ashod.nakashian at collabora.co.uk>
AuthorDate: Tue Nov 13 01:24:40 2018 -0500
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Thu Jun 20 18:05:15 2019 +0200

    LOK: Fix API for renderShapeSelection
    
    Unlike C++, C doesn't allow reference-to-pointer types,
    and we do have C code that wouldn't compile with ref-to-ptr.
    Had to change to ptr-to-ptr, which is the proper way of
    having output arrays.
    
    For the same reason, we cannot use new/delete, rather we
    must use malloc/free.
    
    Another (lesser) issue was that we used the renderShapeSelection
    API to echo back an array we give it as prefix. This made
    the API unecessarily complex (in undocumented ways) and
    forced the implementation to both worry about user-data
    and managing the input memory. This logic is best moved
    to the client and the API simply returns the output data.
    
    Speaking of returning data, the API now returns the size
    of the array it allocated and wrote to, so the client
    can do a simple check on the return value directly.
    
    (cherry picked from commit ad5fb8798b295e9ad706a3836ffb53a0630f752f)
    
    Change-Id: Ida216c10d5b37efd1e0861e26b72cabb25c568e6

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 27072a93a603..f6f933a8fd73 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -714,7 +714,7 @@ static bool doc_addCertificate(LibreOfficeKitDocument* pThis,
 
 static int doc_getSignatureState(LibreOfficeKitDocument* pThis);
 
-static void doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char*& pOutput, size_t& nOutputSize);
+static size_t doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char** pOutput);
 
 LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XComponent> &xComponent)
     : mxComponent(xComponent)
@@ -2547,35 +2547,47 @@ static void doc_postWindowKeyEvent(LibreOfficeKitDocument* /*pThis*/, unsigned n
     }
 }
 
-static void doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char*& pOutput, size_t& nOutputSize)
+static size_t doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char** pOutput)
 {
     SolarMutexGuard aGuard;
     if (gImpl)
         gImpl->maLastExceptionMsg.clear();
 
-    LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
-
-    uno::Reference<frame::XStorable> xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW);
+    try
+    {
+        LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
 
-    SvMemoryStream aOutStream;
-    uno::Reference < io::XOutputStream > xOut = new utl::OOutputStreamWrapper( aOutStream );
+        uno::Reference<frame::XStorable> xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW);
 
-    utl::MediaDescriptor aMediaDescriptor;
-    aMediaDescriptor["FilterName"] <<= OUString("impress_svg_Export");
-    aMediaDescriptor["SelectionOnly"] <<= true;
-    aMediaDescriptor["OutputStream"] <<= xOut;
+        SvMemoryStream aOutStream;
+        uno::Reference<io::XOutputStream> xOut = new utl::OOutputStreamWrapper(aOutStream);
 
-    xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList());
+        utl::MediaDescriptor aMediaDescriptor;
+        aMediaDescriptor["FilterName"] <<= OUString("impress_svg_Export");
+        aMediaDescriptor["SelectionOnly"] <<= true;
+        aMediaDescriptor["OutputStream"] <<= xOut;
 
+        xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList());
 
-    size_t nStreamSize = aOutStream.GetEndOfData();
-    char* pTmp = pOutput;
-    pOutput = new char[nOutputSize + nStreamSize];
-    std::memcpy(pOutput, pTmp, nOutputSize);
-    std::memcpy(pOutput+nOutputSize, aOutStream.GetData(), nStreamSize);
+        if (pOutput)
+        {
+            const size_t nOutputSize = aOutStream.GetEndOfData();
+            *pOutput = static_cast<char*>(malloc(nOutputSize));
+            if (*pOutput)
+            {
+                std::memcpy(*pOutput, aOutStream.GetData(), nOutputSize);
+                return nOutputSize;
+            }
+        }
+    }
+    catch (const uno::Exception& exception)
+    {
+        if (gImpl)
+            gImpl->maLastExceptionMsg = exception.Message;
+        SAL_WARN("lok", "Failed to render shape selection: " << exception);
+    }
 
-    nOutputSize += nStreamSize;
-    delete [] pTmp;
+    return 0;
 }
 
 /** Class to react on finishing of a dispatched command.
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 0da392467b84..4dd23a2cbc7a 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -348,9 +348,7 @@ struct _LibreOfficeKitDocumentClass
     int (*getSignatureState) (LibreOfficeKitDocument* pThis);
 
     /// @see lok::Document::renderShapeSelection
-    void (*renderShapeSelection) (LibreOfficeKitDocument* pThis,
-                                  char*& pOutput,
-                                  size_t& nOutputSize);
+    size_t (*renderShapeSelection)(LibreOfficeKitDocument* pThis, char** pOutput);
 
 #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 865ad434417b..5d7771cf80b0 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -621,11 +621,12 @@ public:
 
     /**
      * Gets an image of the selected shapes.
-     *
+     * @param pOutput contains the result; use free to deallocate.
+     * @return the size ouf *pOutput in bytes.
      */
-    void renderShapeSelection(char*& pOutput, size_t& nOutputSize)
+    size_t renderShapeSelection(char** pOutput)
     {
-        mpDoc->pClass->renderShapeSelection(mpDoc, pOutput, nOutputSize);
+        return mpDoc->pClass->renderShapeSelection(mpDoc, pOutput);
     }
 
 #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
commit 3bbc8f9c1b05e80df1ff99e00d05ebb54372f0f9
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Mon Nov 12 18:11:21 2018 +0100
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Thu Jun 20 18:05:14 2019 +0200

    Remove cout line
    
    Change-Id: Ic1b30a89ae513b3b3ec71853830ef7600801dee0
    (cherry picked from commit c8df2b90d9acb8d719fc14bfd0d6ea81dc5aa760)

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index b794a42fbf31..27072a93a603 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -2553,8 +2553,6 @@ static void doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char*& pOutp
     if (gImpl)
         gImpl->maLastExceptionMsg.clear();
 
-    std::cout << "doc_renderShapeSelection" << std::endl;
-
     LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
 
     uno::Reference<frame::XStorable> xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW);
commit f179a1ee833598d3510e8b36835836d08767a8b7
Author:     Tamás Zolnai <tamas.zolnai at collabora.com>
AuthorDate: Sat Nov 10 18:57:26 2018 +0100
Commit:     Tamás Zolnai <tamas.zolnai at collabora.com>
CommitDate: Thu Jun 20 18:05:14 2019 +0200

    Introduce client-server message for requesting the selected shape as SVG
    
    It works for Impress only now.
    
    Change-Id: I95e3e37ae7df49b567108f6d6467038b715e886d
    (cherry picked from commit 1a5b2d2b6f28ec33c5e100fbc5b0c3438df6b006)

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 129eef6797bc..5e71f5771835 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -2453,9 +2453,10 @@ void DesktopLOKTest::testABI()
     CPPUNIT_ASSERT_EQUAL(documentClassOffset(43), offsetof(struct _LibreOfficeKitDocumentClass, insertCertificate));
     CPPUNIT_ASSERT_EQUAL(documentClassOffset(44), offsetof(struct _LibreOfficeKitDocumentClass, addCertificate));
     CPPUNIT_ASSERT_EQUAL(documentClassOffset(45), offsetof(struct _LibreOfficeKitDocumentClass, getSignatureState));
+    CPPUNIT_ASSERT_EQUAL(documentClassOffset(46), offsetof(struct _LibreOfficeKitDocumentClass, renderShapeSelection));
     // Extending is fine, update this, and add new assert for the offsetof the
     // new method
-    CPPUNIT_ASSERT_EQUAL(documentClassOffset(46), sizeof(struct _LibreOfficeKitDocumentClass));
+    CPPUNIT_ASSERT_EQUAL(documentClassOffset(47), sizeof(struct _LibreOfficeKitDocumentClass));
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(DesktopLOKTest);
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 5d2dd070ef30..b794a42fbf31 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -120,6 +120,7 @@
 #include <unotools/mediadescriptor.hxx>
 #include <unotools/pathoptions.hxx>
 #include <unotools/tempfile.hxx>
+#include <unotools/streamwrap.hxx>
 #include <osl/module.hxx>
 #include <comphelper/sequence.hxx>
 #include <sfx2/sfxbasemodel.hxx>
@@ -713,6 +714,8 @@ static bool doc_addCertificate(LibreOfficeKitDocument* pThis,
 
 static int doc_getSignatureState(LibreOfficeKitDocument* pThis);
 
+static void doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char*& pOutput, size_t& nOutputSize);
+
 LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XComponent> &xComponent)
     : mxComponent(xComponent)
 {
@@ -778,6 +781,8 @@ LibLODocument_Impl::LibLODocument_Impl(const uno::Reference <css::lang::XCompone
         m_pDocumentClass->addCertificate = doc_addCertificate;
         m_pDocumentClass->getSignatureState = doc_getSignatureState;
 
+        m_pDocumentClass->renderShapeSelection = doc_renderShapeSelection;
+
         gDocumentClass = m_pDocumentClass;
     }
     pClass = m_pDocumentClass.get();
@@ -2542,6 +2547,39 @@ static void doc_postWindowKeyEvent(LibreOfficeKitDocument* /*pThis*/, unsigned n
     }
 }
 
+static void doc_renderShapeSelection(LibreOfficeKitDocument* pThis, char*& pOutput, size_t& nOutputSize)
+{
+    SolarMutexGuard aGuard;
+    if (gImpl)
+        gImpl->maLastExceptionMsg.clear();
+
+    std::cout << "doc_renderShapeSelection" << std::endl;
+
+    LibLODocument_Impl* pDocument = static_cast<LibLODocument_Impl*>(pThis);
+
+    uno::Reference<frame::XStorable> xStorable(pDocument->mxComponent, uno::UNO_QUERY_THROW);
+
+    SvMemoryStream aOutStream;
+    uno::Reference < io::XOutputStream > xOut = new utl::OOutputStreamWrapper( aOutStream );
+
+    utl::MediaDescriptor aMediaDescriptor;
+    aMediaDescriptor["FilterName"] <<= OUString("impress_svg_Export");
+    aMediaDescriptor["SelectionOnly"] <<= true;
+    aMediaDescriptor["OutputStream"] <<= xOut;
+
+    xStorable->storeToURL("private:stream", aMediaDescriptor.getAsConstPropertyValueList());
+
+
+    size_t nStreamSize = aOutStream.GetEndOfData();
+    char* pTmp = pOutput;
+    pOutput = new char[nOutputSize + nStreamSize];
+    std::memcpy(pOutput, pTmp, nOutputSize);
+    std::memcpy(pOutput+nOutputSize, aOutStream.GetData(), nStreamSize);
+
+    nOutputSize += nStreamSize;
+    delete [] pTmp;
+}
+
 /** Class to react on finishing of a dispatched command.
 
     This will call a LOK_COMMAND_FINISHED callback when postUnoCommand was
diff --git a/filter/source/svg/svgfilter.cxx b/filter/source/svg/svgfilter.cxx
index 4f7b8982f1ae..ebcc522fbbca 100644
--- a/filter/source/svg/svgfilter.cxx
+++ b/filter/source/svg/svgfilter.cxx
@@ -341,6 +341,7 @@ sal_Bool SAL_CALL SVGFilter::filter( const Sequence< PropertyValue >& rDescripto
             {
                 // #i124608# extract single selection wanted from dialog return values
                 rDescriptor[nInd].Value >>= bSelectionOnly;
+                bPageProvided = false;
             }
             else if (rDescriptor[nInd].Name == "PagePos")
             {
diff --git a/include/LibreOfficeKit/LibreOfficeKit.h b/include/LibreOfficeKit/LibreOfficeKit.h
index 27d968c4a6b7..0da392467b84 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.h
+++ b/include/LibreOfficeKit/LibreOfficeKit.h
@@ -347,6 +347,11 @@ struct _LibreOfficeKitDocumentClass
     /// @see lok::Document::getSignatureState().
     int (*getSignatureState) (LibreOfficeKitDocument* pThis);
 
+    /// @see lok::Document::renderShapeSelection
+    void (*renderShapeSelection) (LibreOfficeKitDocument* pThis,
+                                  char*& pOutput,
+                                  size_t& nOutputSize);
+
 #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
 
diff --git a/include/LibreOfficeKit/LibreOfficeKit.hxx b/include/LibreOfficeKit/LibreOfficeKit.hxx
index 4a0ec6784b7b..865ad434417b 100644
--- a/include/LibreOfficeKit/LibreOfficeKit.hxx
+++ b/include/LibreOfficeKit/LibreOfficeKit.hxx
@@ -619,6 +619,15 @@ public:
         return mpDoc->pClass->getSignatureState(mpDoc);
     }
 
+    /**
+     * Gets an image of the selected shapes.
+     *
+     */
+    void renderShapeSelection(char*& pOutput, size_t& nOutputSize)
+    {
+        mpDoc->pClass->renderShapeSelection(mpDoc, pOutput, nOutputSize);
+    }
+
 #endif // defined LOK_USE_UNSTABLE_API || defined LIBO_INTERNAL_ONLY
 };
 


More information about the Libreoffice-commits mailing list