[Libreoffice-commits] core.git: filter/source sd/qa

Marco Cecchetti (via logerrit) logerrit at kemper.freedesktop.org
Tue Jan 26 16:57:38 UTC 2021


 filter/source/svg/presentation_engine.js |   22 ++++++++-
 filter/source/svg/svgexport.cxx          |   72 +++++++++++++++++++++----------
 sd/qa/unit/SVGExportTests.cxx            |    2 
 3 files changed, 71 insertions(+), 25 deletions(-)

New commits:
commit fd84bce804279b881099a7c0d44136d75d015ca1
Author:     Marco Cecchetti <marco.cecchetti at collabora.com>
AuthorDate: Mon Jan 11 10:28:57 2021 +0100
Commit:     Marco Cecchetti <marco.cecchetti at collabora.com>
CommitDate: Tue Jan 26 17:56:49 2021 +0100

    filter: svg: slide with a custom background are not exported correctly
    
    When a slide has a custom background, the background overlaps any
    master page object: text fields, shapes, ...
    
    Change-Id: Icc410617760502fa4092cfe248155b3e20906abb
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/109089
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Marco Cecchetti <marco.cecchetti at collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/109867
    Tested-by: Jenkins

diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index 9bd2936a019d..48c342c88a01 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -359,7 +359,7 @@ function uniqueArray(src, key, sort) {
  * @returns {String|Undefined} prefixed
  */
 function prefixed(obj, property) {
-    // tml: Have to check for obj being undefined 
+    // tml: Have to check for obj being undefined
     if (obj === undefined) {
         return undefined;
     }
@@ -4436,6 +4436,7 @@ var aOOOAttrSlide = 'slide';
 var aOOOAttrMaster = 'master';
 var aOOOAttrSlideDuration = 'slide-duration';
 var aOOOAttrHasTransition = 'has-transition';
+var aOOOAttrHasCustomBackground = 'has-custom-background';
 var aOOOAttrBackgroundVisibility = 'background-visibility';
 var aOOOAttrMasterObjectsVisibility = 'master-objects-visibility';
 var aOOOAttrPageNumberVisibility = 'page-number-visibility';
@@ -5056,10 +5057,20 @@ function MetaSlide( sMetaSlideId, aMetaDoc )
     assert( this.pageElement,
             'MetaSlide: page element <' + this.slideId + '> not found.' );
 
+    // The slide custom background element and its id attribute.
+    this.backgroundElement = getElementByClassName( this.pageElement, 'Background' );
+    if( this.backgroundElement )
+    {
+        this.backgroundId = this.backgroundElement.getAttribute( 'id' );
+    }
+
     // We initialize the MasterPage object that provides direct access to
     // the target master page element.
     this.masterPage = this.initMasterPage();
 
+    // We check if the slide has a custom background which overrides the one of the targeted master page
+    this.bHasCustomBackground = this.initHasCustomBackground();
+
     // We initialize visibility properties of the target master page elements.
     this.nAreMasterObjectsVisible     = this.initVisibilityProperty( aOOOAttrMasterObjectsVisibility,  VISIBLE );
     this.nIsBackgroundVisible         = this.initVisibilityProperty( aOOOAttrBackgroundVisibility,     VISIBLE );
@@ -5181,6 +5192,12 @@ initHasTransition : function()
     return ( sHasTransition === 'true' );
 },
 
+initHasCustomBackground : function()
+{
+    var sHasCustomBackground = this.element.getAttributeNS( NSS['ooo'], aOOOAttrHasCustomBackground );
+    return ( sHasCustomBackground === 'true' );
+},
+
 initVisibilityProperty : function( aVisibilityAttribute, nDefaultValue )
 {
     var nVisibility = nDefaultValue;
@@ -5660,10 +5677,11 @@ MasterPageView.prototype.createElement = function()
     // init the Background element
     if( this.aMetaSlide.nIsBackgroundVisible )
     {
+        var nBackgroundId = this.aMetaSlide.bHasCustomBackground ? this.aMetaSlide.backgroundId : this.aMasterPage.backgroundId;
         this.aBackgroundElement = theDocument.createElementNS( NSS['svg'], 'use' );
         this.aBackgroundElement.setAttribute( 'class', 'Background' );
         setNSAttribute( 'xlink', this.aBackgroundElement,
-                        'href', '#' + this.aMasterPage.backgroundId );
+                        'href', '#' + nBackgroundId );
 
         // node linking
         aMasterPageViewElement.appendChild( this.aBackgroundElement );
diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index eb5da674e6c3..edac14eb186b 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -35,6 +35,8 @@
 #include <com/sun/star/xml/sax/Writer.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <com/sun/star/drawing/ShapeCollection.hpp>
+#include <com/sun/star/drawing/BitmapMode.hpp>
+#include <com/sun/star/drawing/RectanglePoint.hpp>
 
 #include <rtl/bootstrap.hxx>
 #include <svx/unopage.hxx>
@@ -90,6 +92,7 @@ constexpr OUStringLiteral aOOOElemTextField = u"" NSPREFIX "text_field";
 // ooo xml attributes for meta_slide
 const char    aOOOAttrSlide[] = NSPREFIX "slide";
 const char    aOOOAttrMaster[] = NSPREFIX "master";
+const char    aOOOAttrHasCustomBackground[] = NSPREFIX "has-custom-background";
 const char    aOOOAttrBackgroundVisibility[] = NSPREFIX "background-visibility";
 const char    aOOOAttrMasterObjectsVisibility[] = NSPREFIX "master-objects-visibility";
 const char    aOOOAttrSlideDuration[] = NSPREFIX "slide-duration";
@@ -1152,6 +1155,18 @@ void SVGFilter::implGenerateMetaData()
                     VariableDateTimeField         aVariableDateTimeField;
                     FooterField                   aFooterField;
 
+                    // check if the slide has a custom background wich overlaps the matser page background
+                    Reference< XPropertySet > xBackground;
+                    xPropSet->getPropertyValue( "Background" ) >>= xBackground;
+                    if( xBackground.is() )
+                    {
+                        drawing::FillStyle aFillStyle;
+                        bool assigned = ( xBackground->getPropertyValue( "FillStyle" ) >>= aFillStyle );
+                        // has a custom background ?
+                        if( assigned && aFillStyle != drawing::FillStyle_NONE )
+                            mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, aOOOAttrHasCustomBackground, "true" );
+                    }
+
                     xPropSet->getPropertyValue( "IsBackgroundVisible" )  >>= bBackgroundVisibility;
                     // in case the attribute is set to its default value it is not appended to the meta-slide element
                     if( !bBackgroundVisibility ) // visibility default value: 'visible'
@@ -1746,34 +1761,47 @@ bool SVGFilter::implExportPage( std::u16string_view sPageId,
             const GDIMetaFile& rMtf = (*mpObjects)[ rxPage ].GetRepresentation();
             if( rMtf.GetActionSize() )
             {
-                // background id = "bg-" + page id
-                OUString sBackgroundId = OUString::Concat("bg-") + sPageId;
-                mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sBackgroundId );
-
-                // At present (LibreOffice 3.4.0) the 'IsBackgroundVisible' property is not handled
-                // by Impress; anyway we handle this property as referring only to the visibility
-                // of the master page background. So if a slide has its own background object,
-                // the visibility of such a background object is always inherited from the visibility
-                // of the parent slide regardless of the value of the 'IsBackgroundVisible' property.
-                // This means that we need to set up the visibility attribute only for the background
-                // element of a master page.
-                if( !mbPresentation && bMaster )
+                // If this is not a master page wrap the slide custom background
+                // by a <defs> element.
+                // Slide custom background, if any, is referenced at a different position
+                // in order to not overlap background objects.
+                std::unique_ptr<SvXMLElementExport> xDefsExp;
+                if (!bMaster) // insert the <defs> open tag related to the slide background
                 {
-                    if( !mVisiblePagePropSet.bIsBackgroundVisible )
+                    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class",  "SlideBackground" );
+                    xDefsExp.reset( new SvXMLElementExport( *mpSVGExport, XML_NAMESPACE_NONE, "defs", true, true ) );
+                }
+                {
+                    // background id = "bg-" + page id
+                    OUString sBackgroundId = OUString::Concat("bg-") + sPageId;
+                    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sBackgroundId );
+
+                    // At present (LibreOffice 3.4.0) the 'IsBackgroundVisible' property is not handled
+                    // by Impress; anyway we handle this property as referring only to the visibility
+                    // of the master page background. So if a slide has its own background object,
+                    // the visibility of such a background object is always inherited from the visibility
+                    // of the parent slide regardless of the value of the 'IsBackgroundVisible' property.
+                    // This means that we need to set up the visibility attribute only for the background
+                    // element of a master page.
+                    if( !mbPresentation && bMaster )
                     {
-                        mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", "hidden" );
+                        if( !mVisiblePagePropSet.bIsBackgroundVisible )
+                        {
+                            mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "visibility", "hidden" );
+                        }
                     }
-                }
 
-                mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class",  "Background" );
+                    mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "class",  "Background" );
 
-                // insert the <g> open tag related to the Background
-                SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
+                    // insert the <g> open tag related to the Background
+                    SvXMLElementExport aExp2( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
+
+                    // append all elements that make up the Background
+                    const Point aNullPt;
+                    mpSVGWriter->WriteMetaFile( aNullPt, rMtf.GetPrefSize(), rMtf, SVGWRITER_WRITE_FILL );
+                } // insert the </g> closing tag related to the Background
 
-                // append all elements that make up the Background
-                const Point aNullPt;
-                mpSVGWriter->WriteMetaFile( aNullPt, rMtf.GetPrefSize(), rMtf, SVGWRITER_WRITE_FILL );
-            }   // insert the </g> closing tag related to the Background
+            } // insert the </defs> closing tag related to the slide background
         }
 
         // In case we are dealing with a master page we need to group all its shapes
diff --git a/sd/qa/unit/SVGExportTests.cxx b/sd/qa/unit/SVGExportTests.cxx
index 5e0d7757ae4c..d8b828c9bd76 100644
--- a/sd/qa/unit/SVGExportTests.cxx
+++ b/sd/qa/unit/SVGExportTests.cxx
@@ -122,7 +122,7 @@ public:
         // There should be only one child (no link to javascript url)
         assertXPathChildren(svgDoc,
                             SAL_STRINGIFY(/ SVG_SVG / SVG_G[2] / SVG_G / SVG_G / SVG_G / SVG_G
-                                             / SVG_G[4] / SVG_G),
+                                             / SVG_G[3] / SVG_G),
                             1);
     }
 


More information about the Libreoffice-commits mailing list