tdf#96083 slide transitions wrong with appearing shapes
When using appearing animations on shapes, some of the slide transitions incorrectly don't show these shapes. Same for disappearing shapes - both states are wrong during slide transition time. Fix slide bitmap generator to take final slide states into account. Change-Id: Iea0e576009a109c7f44a7a6498b0ee5b2c4791c5 Reviewed-on: https://gerrit.libreoffice.org/20199 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
This commit is contained in:
committed by
Thorsten Behrens
parent
93122eb06a
commit
57387eb30d
@@ -157,6 +157,11 @@ private:
|
|||||||
/// Set all Shapes to their initial attributes for slideshow
|
/// Set all Shapes to their initial attributes for slideshow
|
||||||
bool applyInitialShapeAttributes( const css::uno::Reference< css::animations::XAnimationNode >& xRootAnimationNode );
|
bool applyInitialShapeAttributes( const css::uno::Reference< css::animations::XAnimationNode >& xRootAnimationNode );
|
||||||
|
|
||||||
|
/// Set shapes to attributes corresponding to initial or final state of slide
|
||||||
|
void applyShapeAttributes(
|
||||||
|
const css::uno::Reference< css::animations::XAnimationNode >& xRootAnimationNode,
|
||||||
|
bool bInitial) const;
|
||||||
|
|
||||||
/// Renders current slide content to bitmap
|
/// Renders current slide content to bitmap
|
||||||
SlideBitmapSharedPtr createCurrentSlideBitmap(
|
SlideBitmapSharedPtr createCurrentSlideBitmap(
|
||||||
const UnoViewSharedPtr& rView,
|
const UnoViewSharedPtr& rView,
|
||||||
@@ -272,8 +277,11 @@ private:
|
|||||||
/// When true, show() was called. Slide hidden oherwise.
|
/// When true, show() was called. Slide hidden oherwise.
|
||||||
bool mbActive;
|
bool mbActive;
|
||||||
|
|
||||||
///When true, enablePaintOverlay was called and mbUserPaintOverlay = true
|
/// When true, enablePaintOverlay was called and mbUserPaintOverlay = true
|
||||||
bool mbPaintOverlayActive;
|
bool mbPaintOverlayActive;
|
||||||
|
|
||||||
|
/// When true, final state attributes are already applied to shapes
|
||||||
|
bool mbFinalStateApplied;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -369,7 +377,8 @@ SlideImpl::SlideImpl( const uno::Reference< drawing::XDrawPage >& xDra
|
|||||||
mbHaveAnimations( false ),
|
mbHaveAnimations( false ),
|
||||||
mbMainSequenceFound( false ),
|
mbMainSequenceFound( false ),
|
||||||
mbActive( false ),
|
mbActive( false ),
|
||||||
mbPaintOverlayActive( false )
|
mbPaintOverlayActive( false ),
|
||||||
|
mbFinalStateApplied( false )
|
||||||
{
|
{
|
||||||
// clone already existing views for slide bitmaps
|
// clone already existing views for slide bitmaps
|
||||||
for( const auto& rView : rViewContainer )
|
for( const auto& rView : rViewContainer )
|
||||||
@@ -523,8 +532,6 @@ void SlideImpl::hide()
|
|||||||
// vanish from view
|
// vanish from view
|
||||||
resetCursor();
|
resetCursor();
|
||||||
mbActive = false;
|
mbActive = false;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
basegfx::B2ISize SlideImpl::getSlideSize() const
|
basegfx::B2ISize SlideImpl::getSlideSize() const
|
||||||
@@ -680,6 +687,14 @@ SlideBitmapSharedPtr SlideImpl::createCurrentSlideBitmap( const UnoViewSharedPtr
|
|||||||
ENSURE_OR_THROW( mbShowLoaded,
|
ENSURE_OR_THROW( mbShowLoaded,
|
||||||
"SlideImpl::createCurrentSlideBitmap(): No show loaded" );
|
"SlideImpl::createCurrentSlideBitmap(): No show loaded" );
|
||||||
|
|
||||||
|
// tdf#96083 ensure end state settings are applied to shapes once when bitmap gets re-rendered
|
||||||
|
// in that state
|
||||||
|
if(!mbFinalStateApplied && FINAL_STATE == meAnimationState && mxRootNode.is())
|
||||||
|
{
|
||||||
|
const_cast< SlideImpl* >(this)->mbFinalStateApplied = true;
|
||||||
|
applyShapeAttributes(mxRootNode, false);
|
||||||
|
}
|
||||||
|
|
||||||
::cppcanvas::CanvasSharedPtr pCanvas( rView->getCanvas() );
|
::cppcanvas::CanvasSharedPtr pCanvas( rView->getCanvas() );
|
||||||
|
|
||||||
// create a bitmap of appropriate size
|
// create a bitmap of appropriate size
|
||||||
@@ -887,22 +902,12 @@ void SlideImpl::startIntrinsicAnimations()
|
|||||||
mpSubsettableShapeManager->notifyIntrinsicAnimationsEnabled();
|
mpSubsettableShapeManager->notifyIntrinsicAnimationsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SlideImpl::applyInitialShapeAttributes(
|
void SlideImpl::applyShapeAttributes(
|
||||||
const uno::Reference< animations::XAnimationNode >& xRootAnimationNode )
|
const css::uno::Reference< css::animations::XAnimationNode >& xRootAnimationNode,
|
||||||
|
bool bInitial) const
|
||||||
{
|
{
|
||||||
if( !implPrefetchShow() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if( !xRootAnimationNode.is() )
|
|
||||||
{
|
|
||||||
meAnimationState = INITIAL_STATE;
|
|
||||||
|
|
||||||
return true; // no animations - no attributes to apply -
|
|
||||||
// succeeded
|
|
||||||
}
|
|
||||||
|
|
||||||
uno::Sequence< animations::TargetProperties > aProps(
|
uno::Sequence< animations::TargetProperties > aProps(
|
||||||
TargetPropertiesCreator::createInitialTargetProperties( xRootAnimationNode ) );
|
TargetPropertiesCreator::createTargetProperties( xRootAnimationNode, bInitial ) );
|
||||||
|
|
||||||
// apply extracted values to our shapes
|
// apply extracted values to our shapes
|
||||||
const ::std::size_t nSize( aProps.getLength() );
|
const ::std::size_t nSize( aProps.getLength() );
|
||||||
@@ -994,6 +999,23 @@ bool SlideImpl::applyInitialShapeAttributes(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SlideImpl::applyInitialShapeAttributes(
|
||||||
|
const uno::Reference< animations::XAnimationNode >& xRootAnimationNode )
|
||||||
|
{
|
||||||
|
if( !implPrefetchShow() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( !xRootAnimationNode.is() )
|
||||||
|
{
|
||||||
|
meAnimationState = INITIAL_STATE;
|
||||||
|
|
||||||
|
return true; // no animations - no attributes to apply -
|
||||||
|
// succeeded
|
||||||
|
}
|
||||||
|
|
||||||
|
applyShapeAttributes(xRootAnimationNode, true);
|
||||||
|
|
||||||
meAnimationState = INITIAL_STATE;
|
meAnimationState = INITIAL_STATE;
|
||||||
|
|
||||||
|
@@ -95,19 +95,24 @@ namespace internal
|
|||||||
class NodeFunctor
|
class NodeFunctor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit NodeFunctor( XShapeHash& rShapeHash ) :
|
explicit NodeFunctor(
|
||||||
mrShapeHash( rShapeHash ),
|
XShapeHash& rShapeHash,
|
||||||
|
bool bInitial )
|
||||||
|
: mrShapeHash( rShapeHash ),
|
||||||
mxTargetShape(),
|
mxTargetShape(),
|
||||||
mnParagraphIndex( -1 )
|
mnParagraphIndex( -1 ),
|
||||||
|
mbInitial( bInitial)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeFunctor( XShapeHash& rShapeHash,
|
NodeFunctor( XShapeHash& rShapeHash,
|
||||||
const uno::Reference< drawing::XShape >& rTargetShape,
|
const uno::Reference< drawing::XShape >& rTargetShape,
|
||||||
sal_Int16 nParagraphIndex ) :
|
sal_Int16 nParagraphIndex,
|
||||||
|
bool bInitial) :
|
||||||
mrShapeHash( rShapeHash ),
|
mrShapeHash( rShapeHash ),
|
||||||
mxTargetShape( rTargetShape ),
|
mxTargetShape( rTargetShape ),
|
||||||
mnParagraphIndex( nParagraphIndex )
|
mnParagraphIndex( nParagraphIndex ),
|
||||||
|
mbInitial( bInitial )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,9 +174,11 @@ namespace internal
|
|||||||
// FALLTHROUGH intended
|
// FALLTHROUGH intended
|
||||||
case animations::AnimationNodeType::SEQ:
|
case animations::AnimationNodeType::SEQ:
|
||||||
{
|
{
|
||||||
|
/// forward bInitial
|
||||||
NodeFunctor aFunctor( mrShapeHash,
|
NodeFunctor aFunctor( mrShapeHash,
|
||||||
xTargetShape,
|
xTargetShape,
|
||||||
nParagraphIndex );
|
nParagraphIndex,
|
||||||
|
mbInitial );
|
||||||
if( !for_each_childNode( xNode, aFunctor ) )
|
if( !for_each_childNode( xNode, aFunctor ) )
|
||||||
{
|
{
|
||||||
OSL_FAIL( "AnimCore: NodeFunctor::operator(): child node iteration failed, "
|
OSL_FAIL( "AnimCore: NodeFunctor::operator(): child node iteration failed, "
|
||||||
@@ -250,8 +257,11 @@ namespace internal
|
|||||||
|
|
||||||
// check whether we already have an entry for
|
// check whether we already have an entry for
|
||||||
// this target (we only take the first set
|
// this target (we only take the first set
|
||||||
// effect for every shape)
|
// effect for every shape) - but keep going if
|
||||||
if( mrShapeHash.find( aTarget ) != mrShapeHash.end() )
|
// we're requested the final state (which
|
||||||
|
// eventually gets overwritten in the
|
||||||
|
// unordered list, see tdf#96083)
|
||||||
|
if( mbInitial && mrShapeHash.find( aTarget ) != mrShapeHash.end() )
|
||||||
break; // already an entry in existence for given XShape
|
break; // already an entry in existence for given XShape
|
||||||
|
|
||||||
// if this is an appear effect, hide shape
|
// if this is an appear effect, hide shape
|
||||||
@@ -286,6 +296,13 @@ namespace internal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if initial anim sets shape visible, set it
|
||||||
|
// to invisible. If we're asked for the final
|
||||||
|
// state, don't do anything obviously
|
||||||
|
if(mbInitial)
|
||||||
|
bVisible = !bVisible;
|
||||||
|
|
||||||
// target is set the 'visible' value,
|
// target is set the 'visible' value,
|
||||||
// so we should record the opposite value
|
// so we should record the opposite value
|
||||||
mrShapeHash.insert(
|
mrShapeHash.insert(
|
||||||
@@ -296,7 +313,7 @@ namespace internal
|
|||||||
beans::NamedValue(
|
beans::NamedValue(
|
||||||
//xAnimateNode->getAttributeName(),
|
//xAnimateNode->getAttributeName(),
|
||||||
OUString("visibility"),
|
OUString("visibility"),
|
||||||
uno::makeAny( !bVisible ) ) ) ) );
|
uno::makeAny( bVisible ) ) ) ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -306,19 +323,25 @@ namespace internal
|
|||||||
XShapeHash& mrShapeHash;
|
XShapeHash& mrShapeHash;
|
||||||
uno::Reference< drawing::XShape > mxTargetShape;
|
uno::Reference< drawing::XShape > mxTargetShape;
|
||||||
sal_Int16 mnParagraphIndex;
|
sal_Int16 mnParagraphIndex;
|
||||||
|
|
||||||
|
// get initial or filal state
|
||||||
|
bool mbInitial;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
uno::Sequence< animations::TargetProperties > SAL_CALL TargetPropertiesCreator::createInitialTargetProperties
|
uno::Sequence< animations::TargetProperties > SAL_CALL TargetPropertiesCreator::createTargetProperties
|
||||||
(
|
(
|
||||||
const uno::Reference< animations::XAnimationNode >& xRootNode
|
const uno::Reference< animations::XAnimationNode >& xRootNode,
|
||||||
|
bool bInitial
|
||||||
) //throw (uno::RuntimeException, std::exception)
|
) //throw (uno::RuntimeException, std::exception)
|
||||||
{
|
{
|
||||||
// scan all nodes for visibility changes, and record first
|
// scan all nodes for visibility changes, and record first
|
||||||
// 'visibility=true' for each shape
|
// 'visibility=true' for each shape
|
||||||
XShapeHash aShapeHash( 101 );
|
XShapeHash aShapeHash( 101 );
|
||||||
|
|
||||||
NodeFunctor aFunctor( aShapeHash );
|
NodeFunctor aFunctor(
|
||||||
|
aShapeHash,
|
||||||
|
bInitial );
|
||||||
|
|
||||||
// TODO(F1): Maybe limit functor application to main sequence
|
// TODO(F1): Maybe limit functor application to main sequence
|
||||||
// alone (CL said something that shape visibility is only
|
// alone (CL said something that shape visibility is only
|
||||||
|
@@ -34,7 +34,10 @@ namespace slideshow
|
|||||||
{
|
{
|
||||||
namespace TargetPropertiesCreator
|
namespace TargetPropertiesCreator
|
||||||
{
|
{
|
||||||
uno::Sequence< animations::TargetProperties > SAL_CALL createInitialTargetProperties( const uno::Reference< animations::XAnimationNode >& rootNode );
|
/// Generate shape property list - set bInitial to true for initial slide state
|
||||||
|
uno::Sequence< animations::TargetProperties > SAL_CALL createTargetProperties(
|
||||||
|
const uno::Reference< animations::XAnimationNode >& rootNode,
|
||||||
|
bool bInitial );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
Reference in New Issue
Block a user