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

Marco Cecchetti marco.cecchetti at collabora.com
Sat Dec 19 07:27:51 PST 2015


 filter/source/svg/presentation_engine.js |   35 +++++++++++++++++++++++++------
 filter/source/svg/svgexport.cxx          |   33 +++++++++++++++++++----------
 sd/qa/unit/SVGExportTests.cxx            |   18 +++++++--------
 3 files changed, 60 insertions(+), 26 deletions(-)

New commits:
commit 7dd73ab0ce7d446b604936942937123adf3ea782
Author: Marco Cecchetti <marco.cecchetti at collabora.com>
Date:   Mon Dec 14 14:21:45 2015 +0100

    svg export: transition not displayed when switching from last to first slide
    
    Some transition, such as those involving clipping, is not displayed when
    switching from last to first slide. That is due to the fact that the
    leaving slide (the last one) is over the entering slide (the first one).
    
    The issue has been solved by hiding the last slide and placing a view to
    it (svg:use) behind the first slide.
    
    The text decoration unit test has been modified.
    
    Change-Id: Iac1d23a1b9834c301b8ae511ea3f81397e5a4229
    Reviewed-on: https://gerrit.libreoffice.org/20705
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Marco Cecchetti <mrcekets at gmail.com>

diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js
index c1e4645..83b979f 100644
--- a/filter/source/svg/presentation_engine.js
+++ b/filter/source/svg/presentation_engine.js
@@ -1218,7 +1218,7 @@ function MetaDocument()
     this.aMasterPageSet = new Object();
     this.aTextFieldHandlerSet = new Object();
     this.aTextFieldContentProviderSet = new Array();
-    this.aSlideNumberProvider =  new SlideNumberProvider( this.nStartSlideNumber + 1, this.sPageNumberingType );
+    this.aSlideNumberProvider = new SlideNumberProvider( this.nStartSlideNumber + 1, this.sPageNumberingType );
 
     // We create a map with key an id and value the svg element containing
     // the animations performed on the slide with such an id.
@@ -1336,7 +1336,8 @@ function MetaSlide( sMetaSlideId, aMetaDoc )
     else
         this.nSlideNumber= -1;
 
-    // Each slide element is wrapped by a <g> element that is responsible for
+    // Each slide element is double wrapped by <g> elements.
+    // The outer <g> element is responsible for
     // the slide element visibility. In fact the visibility attribute has
     // to be set on the parent of the slide element and not directly on
     // the slide element. The reason is that in index mode each slide
@@ -1351,7 +1352,14 @@ function MetaSlide( sMetaSlideId, aMetaDoc )
     // The workaround of setting up the visibility attribute on the slide
     // parent element let us to make visible a slide in a <use> element
     // even if the slide parent element visibility is set to 'hidden'.
-    this.aVisibilityStatusElement = this.slideElement.parentNode;
+    // The inner <g> element is used in order to append some element
+    // before or after the slide, operation that can be needed for some
+    // slide transition (e.g. fade through black). In this way we can
+    // create a view of both the slide and the appended elements that turns out
+    // to be useful for handling transition from the last to the first slide.
+    this.aContainerElement = this.slideElement.parentNode;
+    this.slideContainerId = this.aContainerElement.getAttribute( 'id' );
+    this.aVisibilityStatusElement = this.aContainerElement.parentNode;
 
     // We get a reference to the draw page element, where all shapes specific
     // of this slide live.
@@ -8503,7 +8511,7 @@ function AnimatedSlide( aMetaSlide )
 
     this.aMetaSlide = aMetaSlide;
     this.aSlideElement = this.aMetaSlide.slideElement;
-    this.sSlideId =  this.aMetaSlide.slideId;
+    this.sSlideId = this.aMetaSlide.slideId;
 
     this.aUsedAttributeSet = new Array();
 
@@ -8628,7 +8636,7 @@ AnimatedSlide.prototype.insertBefore = function( aElement )
 {
     if( aElement )
     {
-         this.aSlideElement.parentNode.insertBefore( aElement, this.aSlideElement );
+        this.aSlideElement.parentNode.insertBefore( aElement, this.aSlideElement );
     }
 };
 
@@ -8656,7 +8664,7 @@ AnimatedSlide.prototype.removeElement = function( aElement )
 {
     if( aElement )
     {
-         this.aSlideElement.parentNode.removeChild( aElement );
+        this.aSlideElement.parentNode.removeChild( aElement );
     }
 };
 
@@ -12406,6 +12414,11 @@ SlideShow.prototype.notifySlideStart = function( nNewSlideIndex, nOldSlideIndex
 SlideShow.prototype.notifyTransitionEnd = function( nSlideIndex )
 {
     theMetaDoc.setCurrentSlide( nSlideIndex );
+    if( this.aSlideViewElement )
+    {
+        theMetaDoc.getCurrentSlide().aVisibilityStatusElement.parentNode.removeChild( this.aSlideViewElement );
+        this.aSlideViewElement = null;
+    }
     if( this.isEnabled() )
     {
         // clear all queues
@@ -12777,6 +12790,16 @@ SlideShow.prototype.displaySlide = function( nNewSlide, bSkipSlideTransition )
             var aSlideTransitionHandler = aNewMetaSlide.aTransitionHandler;
             if( aSlideTransitionHandler && aSlideTransitionHandler.isValid() )
             {
+                // when we switch from the last to the first slide we need to hide the last slide
+                // or nobody will see the transition, hence we create a view of the last slide and
+                // we place it before the first slide
+                if( nOldSlide > nNewSlide )
+                {
+                    this.aSlideViewElement = document.createElementNS( NSS['svg'], 'use' );
+                    setNSAttribute( 'xlink', this.aSlideViewElement, 'href', '#' + aOldMetaSlide.slideContainerId );
+                    aNewMetaSlide.aVisibilityStatusElement.parentNode.insertBefore( this.aSlideViewElement, aNewMetaSlide.aVisibilityStatusElement );
+                    aOldMetaSlide.hide();
+                }
                 var aLeavingSlide = aOldMetaSlide;
                 var aEnteringSlide = aNewMetaSlide;
                 var aTransitionEndEvent = makeEvent( bind2( this.notifyTransitionEnd, this, nNewSlide ) );
diff --git a/filter/source/svg/svgexport.cxx b/filter/source/svg/svgexport.cxx
index 21a9b83..d55e3c4 100644
--- a/filter/source/svg/svgexport.cxx
+++ b/filter/source/svg/svgexport.cxx
@@ -1601,23 +1601,34 @@ bool SVGFilter::implExportDrawPages( const SVGFilter::XDrawPageSequence & rxPage
             }
             SvXMLElementExport aGElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
 
+
             {
-                // add id attribute
+                // Insert a further inner the <g> open tag for handling elements
+                // inserted before or after a slide: that is used for some
+                // when swithing from the last to the first slide.
                 const OUString & sPageId = implGetValidIDFromInterface( rxPages[i] );
-                mpSVGExport->AddAttribute( XML_NAMESPACE_NONE, "id", sPageId );
+                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 );
 
-                bRet = implExportPage( sPageId, rxPages[i], xShapes, false /* is not a master page */ ) || bRet;
-            }
+                    SvXMLElementExport aSlideElement( *mpSVGExport, XML_NAMESPACE_NONE, "g", true, true );
+
+                    bRet = implExportPage( sPageId, rxPages[i], xShapes, false /* is not a master page */ ) || bRet;
+                }
+            } // append the </g> closing tag related to inserted elements
         } // append the </g> closing tag related to the svg element handling the slide visibility
     }
 
diff --git a/sd/qa/unit/SVGExportTests.cxx b/sd/qa/unit/SVGExportTests.cxx
index cd4259c..7dec2c6 100644
--- a/sd/qa/unit/SVGExportTests.cxx
+++ b/sd/qa/unit/SVGExportTests.cxx
@@ -100,15 +100,15 @@ public:
 
         assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG ), 1);
         assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2] ), "class", "SlideGroup");
-        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G ), "class", "Slide");
-        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G/SVG_G[1] ), "class", "TitleText");
-        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G/SVG_G[1]/SVG_G/SVG_TEXT ), "class", "TextShape");
-        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G/SVG_G[1]/SVG_G/SVG_TEXT/SVG_TSPAN ), "class", "TextParagraph");
-        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G/SVG_G[1]/SVG_G/SVG_TEXT/SVG_TSPAN ), "text-decoration", "underline");
-
-        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G/SVG_G[2]/SVG_G/SVG_TEXT ), "class", "TextShape");
-        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G/SVG_G[2]/SVG_G/SVG_TEXT/SVG_TSPAN ), "class", "TextParagraph");
-        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G/SVG_G[2]/SVG_G/SVG_TEXT/SVG_TSPAN ), "text-decoration", "line-through");
+        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G ), "class", "Slide");
+        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G/SVG_G/SVG_G[1] ), "class", "TitleText");
+        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G/SVG_G/SVG_G[1]/SVG_G/SVG_TEXT ), "class", "TextShape");
+        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G/SVG_G/SVG_G[1]/SVG_G/SVG_TEXT/SVG_TSPAN ), "class", "TextParagraph");
+        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G/SVG_G/SVG_G[1]/SVG_G/SVG_TEXT/SVG_TSPAN ), "text-decoration", "underline");
+
+        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G/SVG_G/SVG_G[2]/SVG_G/SVG_TEXT ), "class", "TextShape");
+        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G/SVG_G/SVG_G[2]/SVG_G/SVG_TEXT/SVG_TSPAN ), "class", "TextParagraph");
+        assertXPath(svgDoc, MAKE_PATH_STRING( /SVG_SVG/SVG_G[2]/SVG_G/SVG_G/SVG_G/SVG_G/SVG_G[2]/SVG_G/SVG_TEXT/SVG_TSPAN ), "text-decoration", "line-through");
     }
 
     CPPUNIT_TEST_SUITE(SdSVGFilterTest);


More information about the Libreoffice-commits mailing list