From ce13dd5cd19aa289a85bdee3712a1f9f3facca37 Mon Sep 17 00:00:00 2001 From: Marco Cecchetti Date: Mon, 14 Dec 2015 14:21:45 +0100 Subject: 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 Reviewed-by: Marco Cecchetti --- filter/source/svg/presentation_engine.js | 35 ++++++++++++++++++++++++++------ filter/source/svg/svgexport.cxx | 33 ++++++++++++++++++++---------- 2 files changed, 51 insertions(+), 17 deletions(-) (limited to 'filter') diff --git a/filter/source/svg/presentation_engine.js b/filter/source/svg/presentation_engine.js index c1cc82b41458..dcc5cc607e3c 100644 --- a/filter/source/svg/presentation_engine.js +++ b/filter/source/svg/presentation_engine.js @@ -1207,7 +1207,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. @@ -1325,7 +1325,8 @@ function MetaSlide( sMetaSlideId, aMetaDoc ) else this.nSlideNumber= -1; - // Each slide element is wrapped by a element that is responsible for + // Each slide element is double wrapped by elements. + // The outer 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 @@ -1340,7 +1341,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 element // even if the slide parent element visibility is set to 'hidden'. - this.aVisibilityStatusElement = this.slideElement.parentNode; + // The inner 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. @@ -8344,7 +8352,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(); @@ -8469,7 +8477,7 @@ AnimatedSlide.prototype.insertBefore = function( aElement ) { if( aElement ) { - this.aSlideElement.parentNode.insertBefore( aElement, this.aSlideElement ); + this.aSlideElement.parentNode.insertBefore( aElement, this.aSlideElement ); } }; @@ -8497,7 +8505,7 @@ AnimatedSlide.prototype.removeElement = function( aElement ) { if( aElement ) { - this.aSlideElement.parentNode.removeChild( aElement ); + this.aSlideElement.parentNode.removeChild( aElement ); } }; @@ -12245,6 +12253,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 @@ -12616,6 +12629,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 21a9b839fe3c..d55e3c4c6e45 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 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 closing tag related to inserted elements } // append the closing tag related to the svg element handling the slide visibility } -- cgit v1.2.3