diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:51:28 +0000 |
commit | 940b4d1848e8c70ab7642901a68594e8016caffc (patch) | |
tree | eb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /slideshow/source/engine/transitions | |
parent | Initial commit. (diff) | |
download | libreoffice-upstream.tar.xz libreoffice-upstream.zip |
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'slideshow/source/engine/transitions')
53 files changed, 7736 insertions, 0 deletions
diff --git a/slideshow/source/engine/transitions/barndoorwipe.cxx b/slideshow/source/engine/transitions/barndoorwipe.cxx new file mode 100644 index 000000000..c2621f931 --- /dev/null +++ b/slideshow/source/engine/transitions/barndoorwipe.cxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/numeric/ftools.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include "barndoorwipe.hxx" + + +namespace slideshow::internal { + +::basegfx::B2DPolyPolygon BarnDoorWipe::operator () ( double t ) +{ + if (m_doubled) + t /= 2.0; + + basegfx::B2DHomMatrix aTransform(basegfx::utils::createTranslateB2DHomMatrix(-0.5, -0.5)); + aTransform.scale( ::basegfx::pruneScaleValue(t), 1.0 ); + aTransform.translate( 0.5, 0.5 ); + ::basegfx::B2DPolygon poly( m_unitRect ); + poly.transform( aTransform ); + ::basegfx::B2DPolyPolygon res(poly); + + if (m_doubled) { + aTransform = basegfx::utils::createTranslateB2DHomMatrix(-0.5, -0.5); + aTransform.rotate( M_PI_2 ); + aTransform.translate( 0.5, 0.5 ); + poly.transform( aTransform ); + res.append(poly); + } + + return res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/barndoorwipe.hxx b/slideshow/source/engine/transitions/barndoorwipe.hxx new file mode 100644 index 000000000..cb43fb92c --- /dev/null +++ b/slideshow/source/engine/transitions/barndoorwipe.hxx @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_BARNDOORWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_BARNDOORWIPE_HXX + +#include <basegfx/polygon/b2dpolygon.hxx> + +#include "parametricpolypolygon.hxx" +#include "transitiontools.hxx" + + +namespace slideshow { +namespace internal { + +/// Generate a barn door wipe or double barn door wipe: +class BarnDoorWipe : public ParametricPolyPolygon +{ +public: + explicit BarnDoorWipe( bool doubled = false ) + : m_unitRect( createUnitRect() ), m_doubled(doubled) {} + virtual ::basegfx::B2DPolyPolygon operator()( double x ) override; +private: + const ::basegfx::B2DPolygon m_unitRect; + const bool m_doubled; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_BARNDOORWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/barwipepolypolygon.cxx b/slideshow/source/engine/transitions/barwipepolypolygon.cxx new file mode 100644 index 000000000..d2f28df7d --- /dev/null +++ b/slideshow/source/engine/transitions/barwipepolypolygon.cxx @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include "barwipepolypolygon.hxx" + + +namespace slideshow::internal { + +::basegfx::B2DPolyPolygon BarWipePolyPolygon::operator () ( double t ) +{ + ::basegfx::B2DPolyPolygon res; + ::basegfx::B2DHomMatrix aTransform; + aTransform.scale( ::basegfx::pruneScaleValue( t / m_nBars ), 1.0 ); + for ( sal_Int32 i = m_nBars; i--; ) + { + ::basegfx::B2DHomMatrix transform( aTransform ); + transform.translate( static_cast<double>(i) / m_nBars, 0.0 ); + ::basegfx::B2DPolygon poly( m_unitRect ); + poly.transform( transform ); + res.append( poly ); + } + return res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/barwipepolypolygon.hxx b/slideshow/source/engine/transitions/barwipepolypolygon.hxx new file mode 100644 index 000000000..62ba19f44 --- /dev/null +++ b/slideshow/source/engine/transitions/barwipepolypolygon.hxx @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_BARWIPEPOLYPOLYGON_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_BARWIPEPOLYPOLYGON_HXX + +#include "parametricpolypolygon.hxx" +#include "transitiontools.hxx" + + +namespace slideshow { +namespace internal { + +/// Generates a horizontal, left-to-right bar wipe: +class BarWipePolyPolygon : public ParametricPolyPolygon +{ +public: + explicit BarWipePolyPolygon( sal_Int32 nBars = 1 /* nBars > 1: blinds effect */ ) + : m_nBars(nBars), + m_unitRect( createUnitRect() ) + {} + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; +private: + const sal_Int32 m_nBars; + const ::basegfx::B2DPolygon m_unitRect; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_BARWIPEPOLYPOLYGON_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/boxwipe.cxx b/slideshow/source/engine/transitions/boxwipe.cxx new file mode 100644 index 000000000..0844a905c --- /dev/null +++ b/slideshow/source/engine/transitions/boxwipe.cxx @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include "boxwipe.hxx" + + +namespace slideshow::internal { + +::basegfx::B2DPolyPolygon BoxWipe::operator () ( double t ) +{ + ::basegfx::B2DHomMatrix aTransform; + double d = ::basegfx::pruneScaleValue(t); + if (m_topCentered) { + aTransform.translate( -0.5, 0.0 ); + aTransform.scale( d, d ); + aTransform.translate( 0.5, 0.0 ); + } else { + aTransform.scale( d, d ); + } + + ::basegfx::B2DPolyPolygon res( m_unitRect ); + res.transform( aTransform ); + return res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/boxwipe.hxx b/slideshow/source/engine/transitions/boxwipe.hxx new file mode 100644 index 000000000..720720864 --- /dev/null +++ b/slideshow/source/engine/transitions/boxwipe.hxx @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_BOXWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_BOXWIPE_HXX + +#include "parametricpolypolygon.hxx" +#include "transitiontools.hxx" + + +namespace slideshow { +namespace internal { + +/// Generates a default topleft to right bottom box wipe +class BoxWipe : public ParametricPolyPolygon +{ +public: + explicit BoxWipe( bool topCentered ) : m_topCentered(topCentered), + m_unitRect( createUnitRect() ) + {} + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; +private: + const bool m_topCentered; + const ::basegfx::B2DPolyPolygon m_unitRect; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_BOXWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/checkerboardwipe.cxx b/slideshow/source/engine/transitions/checkerboardwipe.cxx new file mode 100644 index 000000000..a88224a33 --- /dev/null +++ b/slideshow/source/engine/transitions/checkerboardwipe.cxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include "checkerboardwipe.hxx" + + +namespace slideshow::internal { + +::basegfx::B2DPolyPolygon CheckerBoardWipe::operator () ( double t ) +{ + const double d = 1.0 / m_unitsPerEdge; + ::basegfx::B2DHomMatrix aTransform; + aTransform.scale( ::basegfx::pruneScaleValue( d * 2.0 * t ), + ::basegfx::pruneScaleValue( d ) ); + + ::basegfx::B2DPolyPolygon res; + for ( sal_Int32 i = m_unitsPerEdge; i--; ) + { + ::basegfx::B2DHomMatrix transform( aTransform ); + if ((i % 2) == 1) // odd line + transform.translate( -d, 0.0 ); + for ( sal_Int32 j = (m_unitsPerEdge / 2) + 1; j--; ) + { + ::basegfx::B2DPolyPolygon poly( m_unitRect ); + poly.transform( transform ); + res.append( poly ); + transform.translate( d * 2.0, 0.0 ); + } + aTransform.translate( 0.0, d ); // next line + } + return res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/checkerboardwipe.hxx b/slideshow/source/engine/transitions/checkerboardwipe.hxx new file mode 100644 index 000000000..ee206e5dd --- /dev/null +++ b/slideshow/source/engine/transitions/checkerboardwipe.hxx @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_CHECKERBOARDWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_CHECKERBOARDWIPE_HXX + +#include <osl/diagnose.h> + +#include "transitiontools.hxx" +#include "parametricpolypolygon.hxx" + + +namespace slideshow { +namespace internal { + +/// Generate a check board wipe (across) +class CheckerBoardWipe : public ParametricPolyPolygon +{ +public: + explicit CheckerBoardWipe( sal_Int32 unitsPerEdge = 10 ) + : m_unitsPerEdge(unitsPerEdge), + m_unitRect( createUnitRect() ) + { OSL_ASSERT( (unitsPerEdge % 2) == 0 ); } + virtual ::basegfx::B2DPolyPolygon operator () ( double x ) override; +private: + const sal_Int32 m_unitsPerEdge; + const ::basegfx::B2DPolyPolygon m_unitRect; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_CHECKERBOARDWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/clippingfunctor.cxx b/slideshow/source/engine/transitions/clippingfunctor.cxx new file mode 100644 index 000000000..be592ac49 --- /dev/null +++ b/slideshow/source/engine/transitions/clippingfunctor.cxx @@ -0,0 +1,209 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <tools/diagnose_ex.h> +#include "clippingfunctor.hxx" + +#include <basegfx/polygon/b2dpolypolygoncutter.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +namespace slideshow::internal +{ + ClippingFunctor::ClippingFunctor(const ParametricPolyPolygonSharedPtr& rPolygon, + const TransitionInfo& rTransitionInfo, + bool bDirectionForward, + bool bModeIn ) : + mpParametricPoly( rPolygon ), + maStaticTransformation(), + mbForwardParameterSweep( true ), + mbSubtractPolygon( false ), + mbScaleIsotrophically( rTransitionInfo.mbScaleIsotrophically ), + mbFlip(false) + { + ENSURE_OR_THROW( rPolygon, + "ClippingFunctor::ClippingFunctor(): Invalid parametric polygon" ); + + // maBackgroundRect serves as the minuent when + // subtracting a given clip polygon from the + // background. To speed up the clipper algo, avoid + // actual intersections of the generated + // poly-polygon with the minuent - i.e. choose the + // polygon to subtract from sufficiently large. + + // blow up unit rect to (-1,-1),(2,2) + // AW: Not needed, just use range + // ::basegfx::B2DHomMatrix aMatrix; + // aMatrix.scale(3.0,3.0); + // aMatrix.translate(-1.0,-1.0); + // maBackgroundRect.transform( aMatrix ); + + // extract modification info from maTransitionInfo + + + // perform general transformations _before_ the reverse + // mode changes. This allows the Transition table to be + // filled more consistently (otherwise, when e.g. rotating + // a clip 90 degrees, the ReverseMethod::FlipX becomes + // ReverseMethod::FlipY instead) + if (rTransitionInfo.mnRotationAngle != 0.0 || + rTransitionInfo.mnScaleX != 1.0 || + rTransitionInfo.mnScaleY != 1.0) + { + maStaticTransformation.translate( -0.5, -0.5 ); + // apply further transformations: + if (rTransitionInfo.mnRotationAngle != 0.0) + { + maStaticTransformation.rotate( + basegfx::deg2rad(rTransitionInfo.mnRotationAngle) ); + } + if (rTransitionInfo.mnScaleX != 1.0 || + rTransitionInfo.mnScaleY != 1.0) + { + maStaticTransformation.scale( + rTransitionInfo.mnScaleX, + rTransitionInfo.mnScaleY ); + } + maStaticTransformation.translate( 0.5, 0.5 ); + } + + if( !bDirectionForward ) + { + // Client has requested reversed + // direction. Apply TransitionInfo's choice + // for that + switch( rTransitionInfo.meReverseMethod ) + { + default: + ENSURE_OR_THROW( + false, + "TransitionFactory::TransitionFactory(): Unexpected reverse method" ); + break; + + case TransitionInfo::ReverseMethod::Ignore: + break; + + case TransitionInfo::ReverseMethod::SubtractAndInvert: + mbForwardParameterSweep = !mbForwardParameterSweep; + mbSubtractPolygon = !mbSubtractPolygon; + break; + + case TransitionInfo::ReverseMethod::Rotate180: + maStaticTransformation = basegfx::utils::createRotateAroundPoint(0.5, 0.5, M_PI) + * maStaticTransformation; + break; + + case TransitionInfo::ReverseMethod::FlipX: + maStaticTransformation = basegfx::utils::createScaleTranslateB2DHomMatrix(-1.0, 1.0, 1.0, 0.0) + * maStaticTransformation; + mbFlip = true; + break; + + case TransitionInfo::ReverseMethod::FlipY: + maStaticTransformation = basegfx::utils::createScaleTranslateB2DHomMatrix(1.0, -1.0, 0.0, 1.0) + * maStaticTransformation; + mbFlip = true; + break; + } + } + + if( !bModeIn ) + { + // client has requested 'out' mode. Apply + // TransitionInfo's method of choice + if( rTransitionInfo.mbOutInvertsSweep ) + mbForwardParameterSweep = !mbForwardParameterSweep; + else + mbSubtractPolygon = !mbSubtractPolygon; + } + } + + ::basegfx::B2DPolyPolygon ClippingFunctor::operator()( double nValue, + const ::basegfx::B2DSize& rTargetSize ) + { + // modify clip polygon according to static + // transformation plus current shape size + ::basegfx::B2DHomMatrix aMatrix( maStaticTransformation ); + + // retrieve current clip polygon + ::basegfx::B2DPolyPolygon aClipPoly = (*mpParametricPoly)( + mbForwardParameterSweep ? nValue : 1.0 - nValue ); + + // TODO(Q4): workaround here, better be fixed in cppcanvas + if (aClipPoly.count() == 0) + aClipPoly.append( basegfx::B2DPolygon() ); + + if (mbFlip) + aClipPoly.flip(); + + if( mbSubtractPolygon ) + { + // subtract given polygon from background + // rect. Do that before any transformations. + + // calc maBackgroundRect \ aClipPoly + // ================================= + + // AW: Simplified + // use a range with fixed size (-1,-1),(2,2) + const basegfx::B2DRange aBackgroundRange(-1, -1, 2, 2); + const basegfx::B2DRange aClipPolyRange(aClipPoly.getB2DRange()); + + if(aBackgroundRange.isInside(aClipPolyRange)) + { + // combine polygons; make the clip polygon the hole + aClipPoly = ::basegfx::utils::correctOrientations(aClipPoly); + aClipPoly.flip(); + aClipPoly.insert(0, basegfx::utils::createPolygonFromRect(aBackgroundRange)); + } + else + { + // when not completely inside aBackgroundRange clipping is needed + // subtract aClipPoly from aBackgroundRange + const basegfx::B2DPolyPolygon aBackgroundPolyPoly(basegfx::utils::createPolygonFromRect(aBackgroundRange)); + aClipPoly = basegfx::utils::solvePolygonOperationDiff(aBackgroundPolyPoly, aClipPoly); + } + } + + // scale polygon up to current shape size + if( mbScaleIsotrophically ) + { + const double nScale( ::std::max( rTargetSize.getX(), + rTargetSize.getY() ) ); + aMatrix.scale( nScale, nScale ); + aMatrix.translate( -(nScale-rTargetSize.getX())/2.0, + -(nScale-rTargetSize.getY())/2.0 ); + } + else + { + aMatrix.scale( rTargetSize.getX(), + rTargetSize.getY() ); + } + + // apply cumulative transformation to clip polygon + aClipPoly.transform( aMatrix ); + + return aClipPoly; + } + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/clippingfunctor.hxx b/slideshow/source/engine/transitions/clippingfunctor.hxx new file mode 100644 index 000000000..bc3e7b61a --- /dev/null +++ b/slideshow/source/engine/transitions/clippingfunctor.hxx @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_CLIPPINGFUNCTOR_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_CLIPPINGFUNCTOR_HXX + +#include <basegfx/vector/b2dsize.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <transitioninfo.hxx> +#include "parametricpolypolygon.hxx" + + +namespace slideshow +{ + namespace internal + { + /** Generates the final clipping polygon. + + This class serves as the functor, which generates the + final clipping polygon from a given ParametricPolyPolygon + and a TransitionInfo. + + The ParametricPolyPolygon can be obtained from the + ParametricPolyPolygonFactory, see there. + + The TransitionInfo further parametrizes the polygon + generated by the ParametricPolyPolygon, with common + modifications such as rotation, flipping, or change of + direction. This allows the ParametricPolyPolygonFactory to + provide only prototypical shapes, with the ClippingFunctor + further customizing the output. + */ + class ClippingFunctor + { + public: + ClippingFunctor( + const ParametricPolyPolygonSharedPtr& rPolygon, + const TransitionInfo& rTransitionInfo, + bool bDirectionForward, + bool bModeIn ); + + /** Generate clip polygon. + + @param nValue + Value to generate the polygon for. Must be in the + range [0,1]. + + @param rTargetSize + Size the clip polygon should cover. This is typically + the size of the object the effect is applied on. + */ + ::basegfx::B2DPolyPolygon operator()( double nValue, + const ::basegfx::B2DSize& rTargetSize ); + + private: + ParametricPolyPolygonSharedPtr mpParametricPoly; + ::basegfx::B2DHomMatrix maStaticTransformation; + // AW: Not needed + // ::basegfx::B2DPolyPolygon maBackgroundRect; + bool mbForwardParameterSweep; + bool mbSubtractPolygon; + const bool mbScaleIsotrophically; + bool mbFlip; + }; + + } +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_CLIPPINGFUNCTOR_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/clockwipe.cxx b/slideshow/source/engine/transitions/clockwipe.cxx new file mode 100644 index 000000000..bba29bfca --- /dev/null +++ b/slideshow/source/engine/transitions/clockwipe.cxx @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include "clockwipe.hxx" + + +namespace slideshow::internal { + +::basegfx::B2DPolygon ClockWipe::calcCenteredClock( double t, double e ) +{ + ::basegfx::B2DPolygon poly; + ::basegfx::B2DHomMatrix aTransform; + aTransform.rotate( t * 2.0 * M_PI ); + const double MAX_EDGE = 2.0; + ::basegfx::B2DPoint p( 0.0, -MAX_EDGE ); + p *= aTransform; + poly.append( p ); + if (t >= 0.875) + poly.append( ::basegfx::B2DPoint( -e, -e ) ); + if (t >= 0.625) + poly.append( ::basegfx::B2DPoint( -e, e ) ); + if (t >= 0.375) + poly.append( ::basegfx::B2DPoint( e, e ) ); + if (t >= 0.125) + poly.append( ::basegfx::B2DPoint( e, -e ) ); + poly.append( ::basegfx::B2DPoint( 0.0, -e ) ); + poly.append( ::basegfx::B2DPoint( 0.0, 0.0 ) ); + poly.setClosed(true); + return poly; +} + +::basegfx::B2DPolyPolygon ClockWipe::operator () ( double t ) +{ + const basegfx::B2DHomMatrix aTransform(basegfx::utils::createScaleTranslateB2DHomMatrix(0.5, 0.5, 0.5, 0.5)); + ::basegfx::B2DPolygon poly( calcCenteredClock(t) ); + poly.transform( aTransform ); + return ::basegfx::B2DPolyPolygon(poly); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/clockwipe.hxx b/slideshow/source/engine/transitions/clockwipe.hxx new file mode 100644 index 000000000..cd54086f6 --- /dev/null +++ b/slideshow/source/engine/transitions/clockwipe.hxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_CLOCKWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_CLOCKWIPE_HXX + +#include <basegfx/polygon/b2dpolygon.hxx> +#include "parametricpolypolygon.hxx" + + +namespace slideshow { +namespace internal { + +/// Generates a clockWiseTwelve clock wipe: +class ClockWipe : public ParametricPolyPolygon +{ +public: + /// 0,1 to 1,1 to 1,0 to 0,-1 to -1,0 to 0,1: + static ::basegfx::B2DPolygon calcCenteredClock( double t, double e = 1.0 ); + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_CLOCKWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/combtransition.cxx b/slideshow/source/engine/transitions/combtransition.cxx new file mode 100644 index 000000000..3fcdbb2e0 --- /dev/null +++ b/slideshow/source/engine/transitions/combtransition.cxx @@ -0,0 +1,178 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +#include "combtransition.hxx" + +namespace slideshow::internal { + +namespace { + +basegfx::B2DPolyPolygon createClipPolygon( + const ::basegfx::B2DVector& rDirection, + const ::basegfx::B2DSize& rSlideSize, + int nNumStrips, int nOffset ) +{ + // create clip polygon in standard orientation (will later + // be rotated to match direction vector) + ::basegfx::B2DPolyPolygon aClipPoly; + + // create nNumStrips/2 vertical strips + for( int i=nOffset; i<nNumStrips; i+=2 ) + { + aClipPoly.append( + ::basegfx::utils::createPolygonFromRect( + ::basegfx::B2DRectangle( double(i)/nNumStrips, 0.0, + double(i+1)/nNumStrips, 1.0) ) ); + + } + + // rotate polygons, such that the strips are parallel to + // the given direction vector + const ::basegfx::B2DVector aUpVec(0.0, 1.0); + basegfx::B2DHomMatrix aMatrix(basegfx::utils::createRotateAroundPoint(0.5, 0.5, aUpVec.angle( rDirection ))); + + // blow up clip polygon to slide size + aMatrix.scale( rSlideSize.getX(), + rSlideSize.getY() ); + + aClipPoly.transform( aMatrix ); + + return aClipPoly; +} + +} + +CombTransition::CombTransition( + std::optional<SlideSharedPtr> const & leavingSlide, + const SlideSharedPtr& pEnteringSlide, + const SoundPlayerSharedPtr& pSoundPlayer, + const UnoViewContainer& rViewContainer, + ScreenUpdater& rScreenUpdater, + EventMultiplexer& rEventMultiplexer, + const ::basegfx::B2DVector& rPushDirection, + sal_Int32 nNumStripes ) + : SlideChangeBase( leavingSlide, pEnteringSlide, pSoundPlayer, + rViewContainer, rScreenUpdater, rEventMultiplexer, + false /* no leaving sprite */, + false /* no entering sprite */ ), + maPushDirectionUnit( rPushDirection ), + mnNumStripes( nNumStripes ) +{ +} + +void CombTransition::renderComb( double t, + const ViewEntry& rViewEntry ) const +{ + const SlideBitmapSharedPtr& pEnteringBitmap = getEnteringBitmap(rViewEntry); + const cppcanvas::CanvasSharedPtr pCanvas_ = rViewEntry.mpView->getCanvas(); + + if( !pEnteringBitmap || !pCanvas_ ) + return; + + // calc bitmap offsets. The enter/leaving bitmaps are only + // as large as the actual slides. For scaled-down + // presentations, we have to move the left, top edge of + // those bitmaps to the actual position, governed by the + // given view transform. The aBitmapPosPixel local + // variable is already in device coordinate space + // (i.e. pixel). + + // TODO(F2): Properly respect clip here. Might have to be transformed, too. + const basegfx::B2DHomMatrix viewTransform( rViewEntry.mpView->getTransformation() ); + const basegfx::B2DPoint pageOrigin( viewTransform * basegfx::B2DPoint() ); + + // change transformation on cloned canvas to be in + // device pixel + cppcanvas::CanvasSharedPtr pCanvas( pCanvas_->clone() ); + basegfx::B2DPoint p; + + // TODO(Q2): Use basegfx bitmaps here + // TODO(F1): SlideBitmap is not fully portable between different canvases! + + const basegfx::B2DSize enteringSizePixel( + getEnteringSlideSizePixel( rViewEntry.mpView) ); + + const basegfx::B2DVector aPushDirection( + enteringSizePixel * maPushDirectionUnit ); + const basegfx::B2DPolyPolygon aClipPolygon1 = + createClipPolygon( maPushDirectionUnit, + enteringSizePixel, + mnNumStripes, 0 ); + const basegfx::B2DPolyPolygon aClipPolygon2 = + createClipPolygon( maPushDirectionUnit, + enteringSizePixel, + mnNumStripes, 1 ); + + SlideBitmapSharedPtr const & pLeavingBitmap = getLeavingBitmap(rViewEntry); + if( pLeavingBitmap ) + { + // render odd strips: + pLeavingBitmap->clip( aClipPolygon1 ); + // don't modify bitmap object (no move!): + p = basegfx::B2DPoint( pageOrigin + (t * aPushDirection) ); + pCanvas->setTransformation(basegfx::utils::createTranslateB2DHomMatrix(p.getX(), p.getY())); + pLeavingBitmap->draw( pCanvas ); + + // render even strips: + pLeavingBitmap->clip( aClipPolygon2 ); + // don't modify bitmap object (no move!): + p = basegfx::B2DPoint( pageOrigin - (t * aPushDirection) ); + pCanvas->setTransformation(basegfx::utils::createTranslateB2DHomMatrix(p.getX(), p.getY())); + pLeavingBitmap->draw( pCanvas ); + } + + // TODO(Q2): Use basegfx bitmaps here + // TODO(F1): SlideBitmap is not fully portable between different canvases! + + // render odd strips: + pEnteringBitmap->clip( aClipPolygon1 ); + // don't modify bitmap object (no move!): + p = basegfx::B2DPoint( pageOrigin + ((t - 1.0) * aPushDirection) ); + pCanvas->setTransformation(basegfx::utils::createTranslateB2DHomMatrix(p.getX(), p.getY())); + pEnteringBitmap->draw( pCanvas ); + + // render even strips: + pEnteringBitmap->clip( aClipPolygon2 ); + // don't modify bitmap object (no move!): + p = basegfx::B2DPoint( pageOrigin + ((1.0 - t) * aPushDirection) ); + pCanvas->setTransformation(basegfx::utils::createTranslateB2DHomMatrix(p.getX(), p.getY())); + pEnteringBitmap->draw( pCanvas ); +} + +bool CombTransition::operator()( double t ) +{ + std::for_each( beginViews(), + endViews(), + [this, &t]( const ViewEntry& rViewEntry ) + { return this->renderComb( t, rViewEntry ); } ); + + getScreenUpdater().notifyUpdate(); + + return true; +} + +} // namespace slideshow::internal + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/combtransition.hxx b/slideshow/source/engine/transitions/combtransition.hxx new file mode 100644 index 000000000..37b288ae6 --- /dev/null +++ b/slideshow/source/engine/transitions/combtransition.hxx @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_COMBTRANSITION_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_COMBTRANSITION_HXX + +#include "slidechangebase.hxx" + +namespace slideshow { +namespace internal { + +/** Comb transition class. + + This class provides a SlideChangeAnimation, showing a + comb-like effect (stripes of alternating push effects). +*/ +class CombTransition : public SlideChangeBase +{ +public: + /** Create the comb transition effect. + + @param nNumStripes + Number of comb-like stripes to show in this effect + */ + CombTransition( ::std::optional<SlideSharedPtr> const & leavingSlide, + const SlideSharedPtr& pEnteringSlide, + const SoundPlayerSharedPtr& pSoundPlayer, + const UnoViewContainer& rViewContainer, + ScreenUpdater& rScreenUpdater, + EventMultiplexer& rEventMultiplexer, + const ::basegfx::B2DVector& rPushDirection, + sal_Int32 nNumStripes ); + + // NumberAnimation + virtual bool operator()( double x ) override; + +private: + const ::basegfx::B2DVector maPushDirectionUnit; + sal_Int32 mnNumStripes; + + void renderComb( double t, const ViewEntry& rViewEntry ) const; +}; + +} // namespace internal +} // namespace presentation + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_COMBTRANSITION_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/doublediamondwipe.cxx b/slideshow/source/engine/transitions/doublediamondwipe.cxx new file mode 100644 index 000000000..9c482000d --- /dev/null +++ b/slideshow/source/engine/transitions/doublediamondwipe.cxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/point/b2dpoint.hxx> +#include "doublediamondwipe.hxx" + + +namespace slideshow::internal { + +::basegfx::B2DPolyPolygon DoubleDiamondWipe::operator () ( double t ) +{ + // outer: + const double a = ::basegfx::pruneScaleValue( 0.25 + (t * 0.75) ); + ::basegfx::B2DPolygon poly; + poly.append( ::basegfx::B2DPoint( 0.5 + a, 0.5 ) ); + poly.append( ::basegfx::B2DPoint( 0.5, 0.5 - a ) ); + poly.append( ::basegfx::B2DPoint( 0.5 - a, 0.5 ) ); + poly.append( ::basegfx::B2DPoint( 0.5, 0.5 + a ) ); + poly.setClosed(true); + ::basegfx::B2DPolyPolygon res(poly); + + // inner (reverse order to clip): + const double b = ::basegfx::pruneScaleValue( (1.0 - t) * 0.25 ); + poly.clear(); + poly.append( ::basegfx::B2DPoint( 0.5 + b, 0.5 ) ); + poly.append( ::basegfx::B2DPoint( 0.5, 0.5 + b ) ); + poly.append( ::basegfx::B2DPoint( 0.5 - b, 0.5 ) ); + poly.append( ::basegfx::B2DPoint( 0.5, 0.5 - b ) ); + poly.setClosed(true); + res.append(poly); + + return res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/doublediamondwipe.hxx b/slideshow/source/engine/transitions/doublediamondwipe.hxx new file mode 100644 index 000000000..eee6e32e5 --- /dev/null +++ b/slideshow/source/engine/transitions/doublediamondwipe.hxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_DOUBLEDIAMONDWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_DOUBLEDIAMONDWIPE_HXX + +#include <basegfx/polygon/b2dpolypolygon.hxx> + +#include "parametricpolypolygon.hxx" + + +namespace slideshow { +namespace internal { + +/// Generates a double diamond wipe: +class DoubleDiamondWipe : public ParametricPolyPolygon +{ +public: + DoubleDiamondWipe() {} + virtual ::basegfx::B2DPolyPolygon operator()( double x ) override; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_DOUBLEDIAMONDWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/ellipsewipe.cxx b/slideshow/source/engine/transitions/ellipsewipe.cxx new file mode 100644 index 000000000..7a5001efd --- /dev/null +++ b/slideshow/source/engine/transitions/ellipsewipe.cxx @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#include <com/sun/star/animations/TransitionSubType.hpp> +#include <basegfx/numeric/ftools.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include "ellipsewipe.hxx" + + +namespace slideshow::internal { + +::basegfx::B2DPolyPolygon EllipseWipe::operator () ( double t ) +{ + ::basegfx::B2DPoint rCenter(0.5,0.5); + double fRadius = ::basegfx::pruneScaleValue( t * M_SQRT2 / 2.0 ); + + if( mnSubType == com::sun::star::animations::TransitionSubType::VERTICAL ) + { + // oval: + ::basegfx::B2DPolygon poly ( + ::basegfx::utils::createPolygonFromEllipse( rCenter, fRadius*2, fRadius ) ); //Horizontal Ellipse is rotated by 90 degrees + return ::basegfx::B2DPolyPolygon( poly ); + } + else + { + // circle: + ::basegfx::B2DPolygon poly( + ::basegfx::utils::createPolygonFromCircle( rCenter, fRadius ) ); + return ::basegfx::B2DPolyPolygon( poly ); + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/ellipsewipe.hxx b/slideshow/source/engine/transitions/ellipsewipe.hxx new file mode 100644 index 000000000..9a86469a5 --- /dev/null +++ b/slideshow/source/engine/transitions/ellipsewipe.hxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_ELLIPSEWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_ELLIPSEWIPE_HXX + +#include "parametricpolypolygon.hxx" + + +namespace slideshow { +namespace internal { + +/// Generate an iris wipe +class EllipseWipe : public ParametricPolyPolygon +{ +public: + explicit EllipseWipe( sal_Int32 nSubType ): mnSubType( nSubType ) {} + virtual ::basegfx::B2DPolyPolygon operator () ( double x ) override; +private: + sal_Int32 mnSubType; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_ELLIPSEWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/fanwipe.cxx b/slideshow/source/engine/transitions/fanwipe.cxx new file mode 100644 index 000000000..b86b0def2 --- /dev/null +++ b/slideshow/source/engine/transitions/fanwipe.cxx @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <sal/log.hxx> +#include "transitiontools.hxx" +#include "clockwipe.hxx" +#include "fanwipe.hxx" + + +namespace slideshow::internal { + +::basegfx::B2DPolyPolygon FanWipe::operator () ( double t ) +{ + ::basegfx::B2DPolyPolygon res; + ::basegfx::B2DPolygon poly( + ClockWipe::calcCenteredClock( + t / ((m_center && m_single) ? 2.0 : 4.0) ) ); + + res.append( poly ); + // flip on y-axis: + poly.transform(basegfx::utils::createScaleB2DHomMatrix(-1.0, 1.0)); + poly.flip(); + res.append( poly ); + + if (m_center) + { + res.transform(basegfx::utils::createScaleTranslateB2DHomMatrix(0.5, 0.5, 0.5, 0.5)); + + if (! m_single) + res.append( flipOnXAxis(res) ); + } + else + { + SAL_WARN_IF( m_fanIn, "slideshow.opengl", "FanWipe: m_fanIn is true ?" ); + res.transform(basegfx::utils::createScaleTranslateB2DHomMatrix(0.5, 1.0, 0.5, 1.0)); + } + return res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/fanwipe.hxx b/slideshow/source/engine/transitions/fanwipe.hxx new file mode 100644 index 000000000..dc457c0d2 --- /dev/null +++ b/slideshow/source/engine/transitions/fanwipe.hxx @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_FANWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_FANWIPE_HXX + +#include "parametricpolypolygon.hxx" + + +namespace slideshow { +namespace internal { + +/// Generates a centerTop (center=true) or double fan wipe: +class FanWipe : public ParametricPolyPolygon +{ +public: + FanWipe( bool center, bool single = true, bool fanIn = false ) + : m_center(center), m_single(single), m_fanIn(fanIn) {} + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; +private: + bool m_center, m_single, m_fanIn; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_FANWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/figurewipe.cxx b/slideshow/source/engine/transitions/figurewipe.cxx new file mode 100644 index 000000000..f64145d55 --- /dev/null +++ b/slideshow/source/engine/transitions/figurewipe.cxx @@ -0,0 +1,117 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/numeric/ftools.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include "figurewipe.hxx" + + +namespace slideshow::internal { + +::basegfx::B2DPolyPolygon FigureWipe::operator () ( double t ) +{ + ::basegfx::B2DPolyPolygon res(m_figure); + res.transform(basegfx::utils::createScaleTranslateB2DHomMatrix(t, t, 0.5, 0.5)); + return res; +} + +std::shared_ptr<FigureWipe> FigureWipe::createTriangleWipe() +{ + const double s60 = sin( basegfx::deg2rad(60.0) ); + const double s30 = sin( basegfx::deg2rad(30.0) ); + ::basegfx::B2DPolygon figure; + figure.append( ::basegfx::B2DPoint( 0.5 + s30, 0.5 ) ); + figure.append( ::basegfx::B2DPoint( 0.0, -0.5 - s60 ) ); + figure.append( ::basegfx::B2DPoint( -0.5 - s30, 0.5 ) ); + figure.setClosed(true); + return std::make_shared<FigureWipe>(figure); +} + +std::shared_ptr<FigureWipe> FigureWipe::createArrowHeadWipe() +{ + const double s60 = sin( basegfx::deg2rad(60.0) ); + const double s30 = sin( basegfx::deg2rad(30.0) ); + const double off = s30; + ::basegfx::B2DPolygon figure; + figure.append( ::basegfx::B2DPoint( 0.5 + s30 + off, 0.5 + off ) ); + figure.append( ::basegfx::B2DPoint( 0.0, -0.5 - s60 ) ); + figure.append( ::basegfx::B2DPoint( -0.5 - s30 - off, 0.5 + off ) ); + figure.append( ::basegfx::B2DPoint( 0.0, 0.5 ) ); + figure.setClosed(true); + return std::make_shared<FigureWipe>(figure); +} + +std::shared_ptr<FigureWipe> FigureWipe::createPentagonWipe() +{ + const double s = sin( basegfx::deg2rad(18.0) ); + const double c = cos( basegfx::deg2rad(18.0) ); + ::basegfx::B2DPolygon figure; + figure.append( ::basegfx::B2DPoint( 0.5, 0.5 ) ); + figure.append( ::basegfx::B2DPoint( 0.5 + s, 0.5 - c ) ); + figure.append( ::basegfx::B2DPoint( 0.0, 0.5 - c - sin(basegfx::deg2rad(36.0)) ) ); + figure.append( ::basegfx::B2DPoint( -0.5 - s, 0.5 - c ) ); + figure.append( ::basegfx::B2DPoint( -0.5, 0.5 ) ); + figure.setClosed(true); + return std::make_shared<FigureWipe>(figure); +} + +std::shared_ptr<FigureWipe> FigureWipe::createHexagonWipe() +{ + const double s = sin( basegfx::deg2rad(30.0) ); + const double c = cos( basegfx::deg2rad(30.0) ); + ::basegfx::B2DPolygon figure; + figure.append( ::basegfx::B2DPoint( 0.5, c ) ); + figure.append( ::basegfx::B2DPoint( 0.5 + s, 0.0 ) ); + figure.append( ::basegfx::B2DPoint( 0.5, -c ) ); + figure.append( ::basegfx::B2DPoint( -0.5, -c ) ); + figure.append( ::basegfx::B2DPoint( -0.5 - s, 0.0 ) ); + figure.append( ::basegfx::B2DPoint( -0.5, c ) ); + figure.setClosed(true); + return std::make_shared<FigureWipe>(figure); +} + +std::shared_ptr<FigureWipe> FigureWipe::createStarWipe( sal_Int32 nPoints ) +{ + const double v = M_PI / nPoints; + const ::basegfx::B2DPoint p_( 0.0, -M_SQRT2 ); + ::basegfx::B2DPolygon figure; + for ( sal_Int32 pos = 0; pos < nPoints; ++pos ) { + const double w = pos * 2.0 * M_PI / nPoints; + ::basegfx::B2DHomMatrix aTransform; + ::basegfx::B2DPoint p(p_); + aTransform.rotate( -w ); + p *= aTransform; + figure.append(p); + p = p_; + aTransform.identity(); + aTransform.scale( 0.5, 0.5 ); + aTransform.rotate( -w - v ); + p *= aTransform; + figure.append(p); + } + figure.setClosed(true); + return std::make_shared<FigureWipe>(figure); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/figurewipe.hxx b/slideshow/source/engine/transitions/figurewipe.hxx new file mode 100644 index 000000000..f5dc91bde --- /dev/null +++ b/slideshow/source/engine/transitions/figurewipe.hxx @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_FIGUREWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_FIGUREWIPE_HXX + +#include "parametricpolypolygon.hxx" + + +namespace slideshow { +namespace internal { + +class FigureWipe : public ParametricPolyPolygon +{ +public: + static std::shared_ptr<FigureWipe> createTriangleWipe(); + static std::shared_ptr<FigureWipe> createArrowHeadWipe(); + static std::shared_ptr<FigureWipe> createStarWipe( sal_Int32 nPoints ); + static std::shared_ptr<FigureWipe> createPentagonWipe(); + static std::shared_ptr<FigureWipe> createHexagonWipe(); + + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; + explicit FigureWipe( ::basegfx::B2DPolygon const & figure ) : m_figure(figure) {} +private: + const ::basegfx::B2DPolygon m_figure; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_FIGUREWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/fourboxwipe.cxx b/slideshow/source/engine/transitions/fourboxwipe.cxx new file mode 100644 index 000000000..74833c2e0 --- /dev/null +++ b/slideshow/source/engine/transitions/fourboxwipe.cxx @@ -0,0 +1,74 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/numeric/ftools.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include "fourboxwipe.hxx" + + +namespace slideshow::internal { + +::basegfx::B2DPolyPolygon FourBoxWipe::operator () ( double t ) +{ + ::basegfx::B2DHomMatrix aTransform; + const double d = ::basegfx::pruneScaleValue( t / 2.0 ); + if (m_cornersOut) + { + aTransform = basegfx::utils::createTranslateB2DHomMatrix(-0.5, -0.5); + aTransform = basegfx::utils::createScaleTranslateB2DHomMatrix(d, d, -0.25, -0.25) + * aTransform; + } + else + { + aTransform = basegfx::utils::createScaleTranslateB2DHomMatrix(d, d, -0.5, -0.5); + } + + // top left: + ::basegfx::B2DPolygon square( m_unitRect ); + square.transform( aTransform ); + ::basegfx::B2DPolyPolygon res( square ); + // bottom left, flip on x-axis: + aTransform.scale( -1.0, 1.0 ); + ::basegfx::B2DPolygon square2( m_unitRect ); + square2.transform( aTransform ); + square2.flip(); // flip direction + res.append( square2 ); + // bottom right, flip on y-axis: + aTransform.scale( 1.0, -1.0 ); + ::basegfx::B2DPolygon square3( m_unitRect ); + square3.transform( aTransform ); + res.append( square3 ); + // top right, flip on x-axis: + aTransform.scale( -1.0, 1.0 ); + ::basegfx::B2DPolygon square4( m_unitRect ); + square4.transform( aTransform ); + square4.flip(); // flip direction + res.append( square4 ); + + aTransform = basegfx::utils::createTranslateB2DHomMatrix(0.5, 0.5); + res.transform( aTransform ); + return res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/fourboxwipe.hxx b/slideshow/source/engine/transitions/fourboxwipe.hxx new file mode 100644 index 000000000..3f2843bdb --- /dev/null +++ b/slideshow/source/engine/transitions/fourboxwipe.hxx @@ -0,0 +1,49 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_FOURBOXWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_FOURBOXWIPE_HXX + +#include "parametricpolypolygon.hxx" +#include "transitiontools.hxx" +#include <basegfx/polygon/b2dpolygon.hxx> + + +namespace slideshow { +namespace internal { + +/// Generate a 4-box wipe +class FourBoxWipe : public ParametricPolyPolygon +{ +public: + explicit FourBoxWipe( bool cornersOut ) : m_cornersOut(cornersOut), + m_unitRect( createUnitRect() ) + {} + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; +private: + const bool m_cornersOut; + const ::basegfx::B2DPolygon m_unitRect; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_FOURBOXWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/iriswipe.cxx b/slideshow/source/engine/transitions/iriswipe.cxx new file mode 100644 index 000000000..72d3e5a61 --- /dev/null +++ b/slideshow/source/engine/transitions/iriswipe.cxx @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include "iriswipe.hxx" + + +namespace slideshow::internal { + +::basegfx::B2DPolyPolygon IrisWipe::operator () ( double t ) +{ + const double d = ::basegfx::pruneScaleValue(t); + basegfx::B2DHomMatrix aTransform(basegfx::utils::createTranslateB2DHomMatrix(-0.5, -0.5)); + aTransform = basegfx::utils::createScaleTranslateB2DHomMatrix(d, d, 0.5, 0.5) * aTransform; + + ::basegfx::B2DPolyPolygon res( m_unitRect ); + res.transform( aTransform ); + return res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/iriswipe.hxx b/slideshow/source/engine/transitions/iriswipe.hxx new file mode 100644 index 000000000..966badee5 --- /dev/null +++ b/slideshow/source/engine/transitions/iriswipe.hxx @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_IRISWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_IRISWIPE_HXX + +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include "parametricpolypolygon.hxx" +#include "transitiontools.hxx" + + +namespace slideshow { +namespace internal { + +/// Generate an iris wipe +class IrisWipe : public ParametricPolyPolygon +{ +public: + IrisWipe() : m_unitRect( createUnitRect() ) {} + virtual ::basegfx::B2DPolyPolygon operator()( double x ) override; +private: + const ::basegfx::B2DPolyPolygon m_unitRect; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_IRISWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/parametricpolypolygon.hxx b/slideshow/source/engine/transitions/parametricpolypolygon.hxx new file mode 100644 index 000000000..f35b0cc76 --- /dev/null +++ b/slideshow/source/engine/transitions/parametricpolypolygon.hxx @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_PARAMETRICPOLYPOLYGON_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_PARAMETRICPOLYPOLYGON_HXX + +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <memory> + + +/* Definition of ParametricPolyPolygon interface */ + +namespace slideshow +{ + namespace internal + { + /** Interface defining a parametric poly-polygon. + + This interface defines a poly-polygon, whose actual shape + is parameterized by a floating point value. This is + e.g. used to generically access the various clip polygon + generators for transition effects. + + Since for every parametric poly-polygon, there is a set of + variations, which can easily be generated by simple + transformations or change in parameter range sweep + direction, objects implementing this interface only + generate <em>one</em> prototypical instance of the + parametric poly-polygon. Generally speaking, the main + effect direction should be horizontal, it should make + increasingly more area visible (transition 'in'), and when + there is a designated direction given, that should be + left-to-right. + */ + class ParametricPolyPolygon + { + public: + virtual ~ParametricPolyPolygon() {} + + /** Retrieve the poly-polygon for value t. + + @param t + Current parameter value to retrieve the corresponding + poly-polygon for. Permissible values for t must be in + the range [0,1]. + + @return a poly-polygon corresponding to the given + parameter value. The poly-polygon is interpreted as + living in the unit rectangle (i.e. [0,1]x[0,1]), but + is not necessarily constrained to completely lie in + this area (this very much depends on the actual effect + to be generated). Although, from a performance + perspective, it currently <em>is</em> advantageous to + try to keep the poly-polygon within these bounds (at + least if there are no hard reasons not to do so), + because then reversion or out transformations are + potentially faster to compute (see the + TransitionInfo::meReverseMethod member in + transitionfactory.cxx). Furthermore, if one of the + polygon modifications involve subtraction (also see + TransitionInfo::meReverseMethod), all generated + polygons should be oriented clock-wise + (i.e. traversing the polygon vertices with increasing + vertex index should generate a clock-wise movement). + */ + virtual ::basegfx::B2DPolyPolygon operator()( double t ) = 0; + }; + + typedef ::std::shared_ptr< ParametricPolyPolygon > ParametricPolyPolygonSharedPtr; + + } +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_PARAMETRICPOLYPOLYGON_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/parametricpolypolygonfactory.cxx b/slideshow/source/engine/transitions/parametricpolypolygonfactory.cxx new file mode 100644 index 000000000..773f76aea --- /dev/null +++ b/slideshow/source/engine/transitions/parametricpolypolygonfactory.cxx @@ -0,0 +1,269 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <tools/diagnose_ex.h> + +#include <com/sun/star/animations/TransitionType.hpp> +#include <com/sun/star/animations/TransitionSubType.hpp> + +#include "parametricpolypolygonfactory.hxx" +#include "barwipepolypolygon.hxx" +#include "boxwipe.hxx" +#include "fourboxwipe.hxx" +#include "barndoorwipe.hxx" +#include "doublediamondwipe.hxx" +#include "veewipe.hxx" +#include "iriswipe.hxx" +#include "ellipsewipe.hxx" +#include "checkerboardwipe.hxx" +#include "randomwipe.hxx" +#include "waterfallwipe.hxx" +#include "clockwipe.hxx" +#include "fanwipe.hxx" +#include "pinwheelwipe.hxx" +#include "snakewipe.hxx" +#include "spiralwipe.hxx" +#include "sweepwipe.hxx" +#include "figurewipe.hxx" +#include "zigzagwipe.hxx" + + +using namespace ::com::sun::star; + +namespace slideshow::internal +{ + ParametricPolyPolygonSharedPtr + ParametricPolyPolygonFactory::createClipPolyPolygon( + sal_Int16 nType, sal_Int16 nSubType ) + { + using namespace ::com::sun::star::animations::TransitionType; + using namespace ::com::sun::star::animations::TransitionSubType; + + switch (nType) + { + case BARWIPE: + return std::make_shared<BarWipePolyPolygon>(); + case BLINDSWIPE: + return std::make_shared<BarWipePolyPolygon>( 6 ); + case BOXWIPE: + return std::make_shared<BoxWipe>( nSubType == LEFTCENTER || + nSubType == TOPCENTER || + nSubType == RIGHTCENTER|| + nSubType == BOTTOMCENTER ); + case FOURBOXWIPE: + return std::make_shared<FourBoxWipe>( nSubType == CORNERSOUT ); + case BARNDOORWIPE: + return std::make_shared<BarnDoorWipe>(); + case DIAGONALWIPE: + return std::make_shared<BarWipePolyPolygon>(); + case VEEWIPE: + return std::make_shared<VeeWipe>(); + case IRISWIPE: + return std::make_shared<IrisWipe>(); + case ELLIPSEWIPE: + return std::make_shared<EllipseWipe>(nSubType); + case CHECKERBOARDWIPE: + return std::make_shared<CheckerBoardWipe>(); + case RANDOMBARWIPE: + return std::make_shared<RandomWipe>( 128, true /* bars */ ); + case DISSOLVE: + return std::make_shared<RandomWipe>( 16 * 16, // for now until dxcanvas is faster +// 64 * 64 /* elements */, + false /* dissolve */ ); + case WATERFALLWIPE: + return std::make_shared<WaterfallWipe>( + 128, + // flipOnYAxis: + nSubType == VERTICALRIGHT || + nSubType == HORIZONTALLEFT ); + case CLOCKWIPE: + return std::make_shared<ClockWipe>(); + case FANWIPE: + return std::make_shared<FanWipe>( // center: + nSubType == CENTERTOP || + nSubType == CENTERRIGHT ); + case PINWHEELWIPE: { + sal_Int32 blades; + switch (nSubType) { + case ONEBLADE: + blades = 1; + break; + case THREEBLADE: + blades = 3; + break; + case FOURBLADE: + blades = 4; + break; + case EIGHTBLADE: + blades = 8; + break; + default: + blades = 2; + break; + } + return std::make_shared<PinWheelWipe>( blades ); + } + case SNAKEWIPE: + return std::make_shared<SnakeWipe>( + // elements: + 8 * 8, + // diagonal: + nSubType == TOPLEFTDIAGONAL || + nSubType == TOPRIGHTDIAGONAL || + nSubType == BOTTOMRIGHTDIAGONAL || + nSubType == BOTTOMLEFTDIAGONAL, + // flipOnYAxis: + nSubType == TOPLEFTVERTICAL || + nSubType == TOPRIGHTDIAGONAL || + nSubType == BOTTOMLEFTDIAGONAL + ); + case PARALLELSNAKESWIPE: + return std::make_shared<ParallelSnakesWipe>( + // elements: + 8 * 8, + // diagonal: + nSubType == DIAGONALBOTTOMLEFTOPPOSITE || + nSubType == DIAGONALTOPLEFTOPPOSITE, + // flipOnYAxis: + nSubType == VERTICALBOTTOMLEFTOPPOSITE || + nSubType == HORIZONTALTOPLEFTOPPOSITE || + nSubType == DIAGONALTOPLEFTOPPOSITE, + // opposite: + nSubType == VERTICALTOPLEFTOPPOSITE || + nSubType == VERTICALBOTTOMLEFTOPPOSITE || + nSubType == HORIZONTALTOPLEFTOPPOSITE || + nSubType == HORIZONTALTOPRIGHTOPPOSITE || + nSubType == DIAGONALBOTTOMLEFTOPPOSITE || + nSubType == DIAGONALTOPLEFTOPPOSITE + ); + case SPIRALWIPE: + return std::make_shared<SpiralWipe>( + // elements: + 8 * 8, + // flipOnYAxis: + nSubType == TOPLEFTCOUNTERCLOCKWISE || + nSubType == TOPRIGHTCOUNTERCLOCKWISE || + nSubType == BOTTOMRIGHTCOUNTERCLOCKWISE || + nSubType == BOTTOMLEFTCOUNTERCLOCKWISE ); + case BOXSNAKESWIPE: + return std::make_shared<BoxSnakesWipe>( + // elements: + 8 * 8, + // fourBox: + nSubType == FOURBOXVERTICAL || + nSubType == FOURBOXHORIZONTAL ); + case SINGLESWEEPWIPE: + return std::make_shared<SweepWipe>( + // center: + nSubType == CLOCKWISETOP || + nSubType == CLOCKWISERIGHT || + nSubType == CLOCKWISEBOTTOM || + nSubType == CLOCKWISELEFT, + // single: + true, + // oppositeVertical: + false, + // flipOnYAxis: + nSubType == COUNTERCLOCKWISEBOTTOMLEFT || + nSubType == COUNTERCLOCKWISETOPRIGHT + ); + case DOUBLESWEEPWIPE: + return std::make_shared<SweepWipe>( + // center: + nSubType == PARALLELVERTICAL || + nSubType == PARALLELDIAGONAL || + nSubType == OPPOSITEVERTICAL || + nSubType == OPPOSITEHORIZONTAL, + // single: + false, + // oppositeVertical: + nSubType == OPPOSITEVERTICAL || + nSubType == OPPOSITEHORIZONTAL, + // flipOnYAxis: + false ); + case DOUBLEFANWIPE: + return std::make_shared<FanWipe>( + //center: + true, + // single: + false, + // fanIn: + nSubType == FANINVERTICAL || + nSubType == FANINHORIZONTAL ); + case TRIANGLEWIPE: + return FigureWipe::createTriangleWipe(); + case ARROWHEADWIPE: + return FigureWipe::createArrowHeadWipe(); + case PENTAGONWIPE: + return FigureWipe::createPentagonWipe(); + case HEXAGONWIPE: + return FigureWipe::createHexagonWipe(); + case STARWIPE: { + sal_Int32 points; + switch (nSubType) { + case FIVEPOINT: + points = 5; + break; + case SIXPOINT: + points = 6; + break; + default: + points = 4; + break; + } + return FigureWipe::createStarWipe(points); + } + case MISCDIAGONALWIPE: { + switch (nSubType) { + case DOUBLEBARNDOOR: + return std::make_shared<BarnDoorWipe>( true /* doubled */ ); + case DOUBLEDIAMOND: + return std::make_shared<DoubleDiamondWipe>(); + } + break; + } + case ZIGZAGWIPE: + return std::make_shared<ZigZagWipe>(5); + case BARNZIGZAGWIPE: + return std::make_shared<BarnZigZagWipe>(5); + + case BOWTIEWIPE: + case BARNVEEWIPE: + case EYEWIPE: + case ROUNDRECTWIPE: + case MISCSHAPEWIPE: + case SALOONDOORWIPE: + case WINDSHIELDWIPE: + // for now, map to barwipe transition + return std::make_shared<BarWipePolyPolygon>(); + + default: + case PUSHWIPE: + case SLIDEWIPE: + case FADE: + ENSURE_OR_THROW( false, + "createShapeClipPolyPolygonAnimation(): Transition type mismatch" ); + } + + return ParametricPolyPolygonSharedPtr(); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/parametricpolypolygonfactory.hxx b/slideshow/source/engine/transitions/parametricpolypolygonfactory.hxx new file mode 100644 index 000000000..2b188c4a1 --- /dev/null +++ b/slideshow/source/engine/transitions/parametricpolypolygonfactory.hxx @@ -0,0 +1,41 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_PARAMETRICPOLYPOLYGONFACTORY_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_PARAMETRICPOLYPOLYGONFACTORY_HXX + +#include "parametricpolypolygon.hxx" + +namespace slideshow +{ + namespace internal + { + /* Definition of Transitionfactory class */ + + namespace ParametricPolyPolygonFactory + { + ParametricPolyPolygonSharedPtr createClipPolyPolygon( sal_Int16 nTransitionType, + sal_Int16 nTransitionSubType ); + } + } +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_PARAMETRICPOLYPOLYGONFACTORY_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/pinwheelwipe.cxx b/slideshow/source/engine/transitions/pinwheelwipe.cxx new file mode 100644 index 000000000..74522a8e6 --- /dev/null +++ b/slideshow/source/engine/transitions/pinwheelwipe.cxx @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include "clockwipe.hxx" +#include "pinwheelwipe.hxx" + + +namespace slideshow::internal { + +::basegfx::B2DPolyPolygon PinWheelWipe::operator () ( double t ) +{ + ::basegfx::B2DPolygon poly( ClockWipe::calcCenteredClock( + t / m_blades, + 2.0 /* max edge when rotating */ ) ); + ::basegfx::B2DPolyPolygon res; + for ( sal_Int32 i = m_blades; i--; ) + { + ::basegfx::B2DPolygon p(poly); + p.transform(basegfx::utils::createRotateB2DHomMatrix((i * 2.0 * M_PI) / m_blades)); + res.append( p ); + } + res.transform(basegfx::utils::createScaleTranslateB2DHomMatrix(0.5, 0.5, 0.5, 0.5)); + return res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/pinwheelwipe.hxx b/slideshow/source/engine/transitions/pinwheelwipe.hxx new file mode 100644 index 000000000..1a353a64f --- /dev/null +++ b/slideshow/source/engine/transitions/pinwheelwipe.hxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_PINWHEELWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_PINWHEELWIPE_HXX + +#include "parametricpolypolygon.hxx" + + +namespace slideshow { +namespace internal { + +/// Generates a n-blade pinWheel wipe: +class PinWheelWipe : public ParametricPolyPolygon +{ +public: + explicit PinWheelWipe( sal_Int32 blades ) : m_blades(blades) {} + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; +private: + sal_Int32 m_blades; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_PINWHEELWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/randomwipe.cxx b/slideshow/source/engine/transitions/randomwipe.cxx new file mode 100644 index 000000000..58047a676 --- /dev/null +++ b/slideshow/source/engine/transitions/randomwipe.cxx @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/numeric/ftools.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include "randomwipe.hxx" +#include "transitiontools.hxx" +#include <tools.hxx> + + +namespace slideshow::internal { + +RandomWipe::RandomWipe( sal_Int32 nElements, bool randomBars ) + : m_positions( new ::basegfx::B2DPoint[ nElements ] ), + m_nElements( nElements ), + m_rect( createUnitRect() ) +{ + ::basegfx::B2DHomMatrix aTransform; + if (randomBars) + { + double edge = 1.0 / nElements; + for ( sal_Int32 pos = nElements; pos--; ) + m_positions[ pos ].setY( ::basegfx::pruneScaleValue( pos * edge ) ); + aTransform.scale( 1.0, ::basegfx::pruneScaleValue(edge) ); + } + else // dissolve effect + { + sal_Int32 sqrtElements = static_cast<sal_Int32>( + sqrt( static_cast<double>(nElements) ) ); + double edge = 1.0 / sqrtElements; + for ( sal_Int32 pos = nElements; pos--; ) { + m_positions[ pos ] = ::basegfx::B2DPoint( + ::basegfx::pruneScaleValue( (pos % sqrtElements) * edge ), + ::basegfx::pruneScaleValue( (pos / sqrtElements) * edge ) ); + } + const double pedge = ::basegfx::pruneScaleValue(edge); + aTransform.scale( pedge, pedge ); + } + m_rect.transform( aTransform ); + + // mix up: + for ( sal_Int32 pos1 = nElements ; pos1-- ; ) + { + const sal_Int32 pos2 = getRandomOrdinal(pos1+1); + ::std::swap(m_positions[ pos1], m_positions[ pos2 ]); + } +} + +::basegfx::B2DPolyPolygon RandomWipe::operator () ( double t ) +{ + ::basegfx::B2DPolyPolygon res; + for ( sal_Int32 pos = static_cast<sal_Int32>(t * m_nElements); pos--; ) + { + ::basegfx::B2DPoint const & point = m_positions[ pos ]; + ::basegfx::B2DPolygon poly( m_rect ); + poly.transform(basegfx::utils::createTranslateB2DHomMatrix(point.getX(), point.getY())); + res.append( poly ); + } + return res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/randomwipe.hxx b/slideshow/source/engine/transitions/randomwipe.hxx new file mode 100644 index 000000000..b6df2bb8f --- /dev/null +++ b/slideshow/source/engine/transitions/randomwipe.hxx @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_RANDOMWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_RANDOMWIPE_HXX + +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <memory> + +#include "parametricpolypolygon.hxx" + + +namespace slideshow { +namespace internal { + +class RandomWipe : public ParametricPolyPolygon +{ +public: + RandomWipe( sal_Int32 nElements, + bool randomBars /* true: generates a horizontal random bar wipe, + false: generates a dissolve wipe */ ); + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; +private: + ::std::unique_ptr< ::basegfx::B2DPoint []> m_positions; + sal_Int32 m_nElements; + ::basegfx::B2DPolygon m_rect; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_RANDOMWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/shapetransitionfactory.cxx b/slideshow/source/engine/transitions/shapetransitionfactory.cxx new file mode 100644 index 000000000..d0ff5325e --- /dev/null +++ b/slideshow/source/engine/transitions/shapetransitionfactory.cxx @@ -0,0 +1,369 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <tools/diagnose_ex.h> + +#include <sal/log.hxx> + +#include <com/sun/star/animations/TransitionType.hpp> +#include <com/sun/star/animations/TransitionSubType.hpp> + +#include <transitionfactory.hxx> +#include "transitionfactorytab.hxx" +#include "parametricpolypolygonfactory.hxx" +#include <animationfactory.hxx> +#include "clippingfunctor.hxx" + +using namespace ::com::sun::star; + +namespace slideshow::internal { + +/*************************************************** + *** *** + *** Shape Transition Effects *** + *** *** + ***************************************************/ + +namespace { + +class ClippingAnimation : public NumberAnimation +{ +public: + ClippingAnimation( + const ParametricPolyPolygonSharedPtr& rPolygon, + const ShapeManagerSharedPtr& rShapeManager, + const TransitionInfo& rTransitionInfo, + bool bDirectionForward, + bool bModeIn ); + + virtual ~ClippingAnimation() override; + + // Animation interface + + virtual void prefetch() override; + virtual void start( const AnimatableShapeSharedPtr& rShape, + const ShapeAttributeLayerSharedPtr& rAttrLayer ) override; + virtual void end() override; + + // NumberAnimation interface + + virtual bool operator()( double nValue ) override; + virtual double getUnderlyingValue() const override; + +private: + void end_(); + + AnimatableShapeSharedPtr mpShape; + ShapeAttributeLayerSharedPtr mpAttrLayer; + ShapeManagerSharedPtr mpShapeManager; + ClippingFunctor maClippingFunctor; + bool mbSpriteActive; +}; + +ClippingAnimation::ClippingAnimation( + const ParametricPolyPolygonSharedPtr& rPolygon, + const ShapeManagerSharedPtr& rShapeManager, + const TransitionInfo& rTransitionInfo, + bool bDirectionForward, + bool bModeIn ) : + mpShape(), + mpAttrLayer(), + mpShapeManager( rShapeManager ), + maClippingFunctor( rPolygon, + rTransitionInfo, + bDirectionForward, + bModeIn ), + mbSpriteActive(false) +{ + ENSURE_OR_THROW( + rShapeManager, + "ClippingAnimation::ClippingAnimation(): Invalid ShapeManager" ); +} + +ClippingAnimation::~ClippingAnimation() +{ + try + { + end_(); + } + catch (const uno::Exception&) + { + TOOLS_WARN_EXCEPTION("slideshow", ""); + } +} + +void ClippingAnimation::prefetch() +{ +} + +void ClippingAnimation::start( const AnimatableShapeSharedPtr& rShape, + const ShapeAttributeLayerSharedPtr& rAttrLayer ) +{ + OSL_ENSURE( !mpShape, + "ClippingAnimation::start(): Shape already set" ); + OSL_ENSURE( !mpAttrLayer, + "ClippingAnimation::start(): Attribute layer already set" ); + ENSURE_OR_THROW( rShape, + "ClippingAnimation::start(): Invalid shape" ); + ENSURE_OR_THROW( rAttrLayer, + "ClippingAnimation::start(): Invalid attribute layer" ); + + mpShape = rShape; + mpAttrLayer = rAttrLayer; + + if( !mbSpriteActive ) + { + mpShapeManager->enterAnimationMode( mpShape ); + mbSpriteActive = true; + } +} + +void ClippingAnimation::end() +{ + end_(); +} + +void ClippingAnimation::end_() +{ + if( mbSpriteActive ) + { + mbSpriteActive = false; + mpShapeManager->leaveAnimationMode( mpShape ); + + if( mpShape->isContentChanged() ) + mpShapeManager->notifyShapeUpdate( mpShape ); + } +} + +bool ClippingAnimation::operator()( double nValue ) +{ + ENSURE_OR_RETURN_FALSE( + mpAttrLayer && mpShape, + "ClippingAnimation::operator(): Invalid ShapeAttributeLayer" ); + + // set new clip + mpAttrLayer->setClip( maClippingFunctor( nValue, + mpShape->getDomBounds().getRange() ) ); + + if( mpShape->isContentChanged() ) + mpShapeManager->notifyShapeUpdate( mpShape ); + + return true; +} + +double ClippingAnimation::getUnderlyingValue() const +{ + ENSURE_OR_THROW( + mpAttrLayer, + "ClippingAnimation::getUnderlyingValue(): Invalid ShapeAttributeLayer" ); + + return 0.0; // though this should be used in concert with + // ActivitiesFactory::createSimpleActivity, better + // explicitly name our start value. + // Permissible range for operator() above is [0,1] +} + +AnimationActivitySharedPtr createShapeTransitionByType( + const ActivitiesFactory::CommonParameters& rParms, + const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + css::uno::Reference< css::animations::XTransitionFilter > const& xTransition, + sal_Int16 nType, + sal_Int16 nSubType ) +{ + ENSURE_OR_THROW( + xTransition.is(), + "createShapeTransitionByType(): Invalid XTransition" ); + + const TransitionInfo* pTransitionInfo( + getTransitionInfo( nType, nSubType ) ); + + AnimationActivitySharedPtr pGeneratedActivity; + if( pTransitionInfo != nullptr ) + { + switch( pTransitionInfo->meTransitionClass ) + { + default: + case TransitionInfo::TRANSITION_INVALID: + OSL_FAIL( "createShapeTransitionByType(): Invalid transition type. " + "Don't ask me for a 0 TransitionType, have no XTransitionFilter node instead!" ); + return AnimationActivitySharedPtr(); + + + case TransitionInfo::TRANSITION_CLIP_POLYPOLYGON: + { + // generate parametric poly-polygon + ParametricPolyPolygonSharedPtr pPoly( + ParametricPolyPolygonFactory::createClipPolyPolygon( + nType, nSubType ) ); + + // create a clip activity from that + pGeneratedActivity = ActivitiesFactory::createSimpleActivity( + rParms, + std::make_shared<ClippingAnimation>( + pPoly, + rShapeManager, + *pTransitionInfo, + xTransition->getDirection(), + xTransition->getMode() ), + true ); + } + break; + + case TransitionInfo::TRANSITION_SPECIAL: + { + switch( nType ) + { + case animations::TransitionType::RANDOM: + { + // select randomly one of the effects from the + // TransitionFactoryTable + + const TransitionInfo* pRandomTransitionInfo( getRandomTransitionInfo() ); + + ENSURE_OR_THROW( pRandomTransitionInfo != nullptr, + "createShapeTransitionByType(): Got invalid random transition info" ); + + ENSURE_OR_THROW( pRandomTransitionInfo->mnTransitionType != animations::TransitionType::RANDOM, + "createShapeTransitionByType(): Got random again for random input!" ); + + // and recurse + pGeneratedActivity = createShapeTransitionByType( rParms, + rShape, + rShapeManager, + rSlideSize, + xTransition, + pRandomTransitionInfo->mnTransitionType, + pRandomTransitionInfo->mnTransitionSubType ); + } + break; + + // TODO(F3): Implement slidewipe for shape + case animations::TransitionType::SLIDEWIPE: + { + sal_Int16 nBarWipeSubType(0); + bool bDirectionForward(true); + + // map slidewipe to BARWIPE, for now + switch( nSubType ) + { + case animations::TransitionSubType::FROMLEFT: + nBarWipeSubType = animations::TransitionSubType::LEFTTORIGHT; + bDirectionForward = true; + break; + + case animations::TransitionSubType::FROMRIGHT: + nBarWipeSubType = animations::TransitionSubType::LEFTTORIGHT; + bDirectionForward = false; + break; + + case animations::TransitionSubType::FROMTOP: + nBarWipeSubType = animations::TransitionSubType::TOPTOBOTTOM; + bDirectionForward = true; + break; + + case animations::TransitionSubType::FROMBOTTOM: + nBarWipeSubType = animations::TransitionSubType::TOPTOBOTTOM; + bDirectionForward = false; + break; + + default: + ENSURE_OR_THROW( false, + "createShapeTransitionByType(): Unexpected subtype for SLIDEWIPE" ); + break; + } + + // generate parametric poly-polygon + ParametricPolyPolygonSharedPtr pPoly( + ParametricPolyPolygonFactory::createClipPolyPolygon( + animations::TransitionType::BARWIPE, + nBarWipeSubType ) ); + + // create a clip activity from that + pGeneratedActivity = ActivitiesFactory::createSimpleActivity( + rParms, + std::make_shared<ClippingAnimation>( + pPoly, + rShapeManager, + *getTransitionInfo( animations::TransitionType::BARWIPE, + nBarWipeSubType ), + bDirectionForward, + xTransition->getMode() ), + true ); + } + break; + + default: + { + // TODO(F1): Check whether there's anything left, anyway, + // for _shape_ transitions. AFAIK, there are no special + // effects for shapes... + + // for now, map all to fade effect + pGeneratedActivity = ActivitiesFactory::createSimpleActivity( + rParms, + AnimationFactory::createNumberPropertyAnimation( + "Opacity", + rShape, + rShapeManager, + rSlideSize ), + xTransition->getMode() ); + } + break; + } + } + break; + } + } + + if( !pGeneratedActivity ) + { + // No animation generated, maybe no table entry for given + // transition? + SAL_WARN("slideshow", + "createShapeTransitionByType(): Unknown type/subtype combination encountered: " + << xTransition->getTransition() << " " << xTransition->getSubtype() ); + } + + return pGeneratedActivity; +} + +} // anon namespace + +AnimationActivitySharedPtr TransitionFactory::createShapeTransition( + const ActivitiesFactory::CommonParameters& rParms, + const AnimatableShapeSharedPtr& rShape, + const ShapeManagerSharedPtr& rShapeManager, + const ::basegfx::B2DVector& rSlideSize, + uno::Reference< animations::XTransitionFilter > const& xTransition ) +{ + return createShapeTransitionByType( rParms, + rShape, + rShapeManager, + rSlideSize, + xTransition, + xTransition->getTransition(), + xTransition->getSubtype() ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/slidechangebase.cxx b/slideshow/source/engine/transitions/slidechangebase.cxx new file mode 100644 index 000000000..bee40c948 --- /dev/null +++ b/slideshow/source/engine/transitions/slidechangebase.cxx @@ -0,0 +1,510 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <tools/diagnose_ex.h> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <cppcanvas/basegfxfactory.hxx> +#include <cppcanvas/customsprite.hxx> + +#include "slidechangebase.hxx" +#include <tools.hxx> + +#include <algorithm> + +using namespace com::sun::star; + +namespace slideshow::internal { + +SlideChangeBase::SlideChangeBase( std::optional<SlideSharedPtr> const & leavingSlide, + const SlideSharedPtr& pEnteringSlide, + const SoundPlayerSharedPtr& pSoundPlayer, + const UnoViewContainer& rViewContainer, + ScreenUpdater& rScreenUpdater, + EventMultiplexer& rEventMultiplexer, + bool bCreateLeavingSprites, + bool bCreateEnteringSprites ) : + mpSoundPlayer( pSoundPlayer ), + mrEventMultiplexer(rEventMultiplexer), + mrScreenUpdater(rScreenUpdater), + maLeavingSlide( leavingSlide ), + mpEnteringSlide( pEnteringSlide ), + maViewData(), + mrViewContainer(rViewContainer), + mbCreateLeavingSprites(bCreateLeavingSprites), + mbCreateEnteringSprites(bCreateEnteringSprites), + mbSpritesVisible(false), + mbFinished(false), + mbPrefetched(false) +{ + ENSURE_OR_THROW( + pEnteringSlide, + "SlideChangeBase::SlideChangeBase(): Invalid entering slide!" ); +} + +SlideBitmapSharedPtr SlideChangeBase::getLeavingBitmap( const ViewEntry& rViewEntry ) const +{ + if( !rViewEntry.mpLeavingBitmap ) + rViewEntry.mpLeavingBitmap = createBitmap(rViewEntry.mpView, + maLeavingSlide); + + return rViewEntry.mpLeavingBitmap; +} + +SlideBitmapSharedPtr SlideChangeBase::getEnteringBitmap( const ViewEntry& rViewEntry ) const +{ + if( !rViewEntry.mpEnteringBitmap ) + rViewEntry.mpEnteringBitmap = createBitmap( rViewEntry.mpView, + std::optional<SlideSharedPtr>(mpEnteringSlide) ); + + return rViewEntry.mpEnteringBitmap; +} + +SlideBitmapSharedPtr SlideChangeBase::createBitmap( const UnoViewSharedPtr& rView, + const std::optional<SlideSharedPtr>& rSlide ) const +{ + SlideBitmapSharedPtr pRet; + if( !rSlide ) + return pRet; + + SlideSharedPtr const & pSlide = *rSlide; + if( !pSlide ) + { + // TODO(P3): No need to generate a bitmap here. This only made + // the code more uniform. Faster would be to simply clear the + // sprite to black. + + // create empty, black-filled bitmap + const basegfx::B2ISize slideSizePixel( + getSlideSizePixel( basegfx::B2DSize( mpEnteringSlide->getSlideSize() ), + rView )); + + cppcanvas::CanvasSharedPtr pCanvas( rView->getCanvas() ); + + // create a bitmap of appropriate size + cppcanvas::BitmapSharedPtr pBitmap( + cppcanvas::BaseGfxFactory::createBitmap( + pCanvas, + slideSizePixel ) ); + + ENSURE_OR_THROW( + pBitmap, + "SlideChangeBase::createBitmap(): Cannot create page bitmap" ); + + cppcanvas::BitmapCanvasSharedPtr pBitmapCanvas( + pBitmap->getBitmapCanvas() ); + + ENSURE_OR_THROW( pBitmapCanvas, + "SlideChangeBase::createBitmap(): " + "Cannot create page bitmap canvas" ); + + // set transformation to identitiy (->device pixel) + pBitmapCanvas->setTransformation( ::basegfx::B2DHomMatrix() ); + + // clear bitmap to black + fillRect( pBitmapCanvas, + ::basegfx::B2DRectangle( 0.0, 0.0, + slideSizePixel.getX(), + slideSizePixel.getY() ), + 0x000000FFU ); + + pRet = std::make_shared<SlideBitmap>( pBitmap ); + } + else + { + pRet = pSlide->getCurrentSlideBitmap( rView ); + } + + return pRet; +} + +::basegfx::B2ISize SlideChangeBase::getEnteringSlideSizePixel( const UnoViewSharedPtr& pView ) const +{ + return getSlideSizePixel( basegfx::B2DSize( mpEnteringSlide->getSlideSize() ), + pView ); +} + +void SlideChangeBase::renderBitmap( + SlideBitmapSharedPtr const & pSlideBitmap, + cppcanvas::CanvasSharedPtr const & pCanvas ) +{ + if( !(pSlideBitmap && pCanvas) ) + return; + + // need to render without any transformation (we + // assume device units): + const basegfx::B2DHomMatrix viewTransform( + pCanvas->getTransformation() ); + const basegfx::B2DPoint pageOrigin( + viewTransform * basegfx::B2DPoint() ); + const cppcanvas::CanvasSharedPtr pDevicePixelCanvas( + pCanvas->clone() ); + + // render at output position, don't modify bitmap object (no move!): + const basegfx::B2DHomMatrix transform(basegfx::utils::createTranslateB2DHomMatrix( + pageOrigin.getX(), pageOrigin.getY())); + + pDevicePixelCanvas->setTransformation( transform ); + pSlideBitmap->draw( pDevicePixelCanvas ); +} + +void SlideChangeBase::prefetch() +{ + // we're a one-shot activity, and already finished + if( mbFinished || mbPrefetched ) + return; + + // register ourselves for view change events + mrEventMultiplexer.addViewHandler( std::dynamic_pointer_cast<ViewEventHandler>(shared_from_this()) ); + + // init views and create slide bitmaps + for( const auto& pView : mrViewContainer ) + viewAdded( pView ); + + mbPrefetched = true; +} + +void SlideChangeBase::start( const AnimatableShapeSharedPtr& /*rShape*/, + const ShapeAttributeLayerSharedPtr& /*rLayer*/ ) +{ + // we're a one-shot activity, and already finished + if( mbFinished ) + return; + + prefetch(); // no-op, if already done + + // get the subclasses a chance to do any specific initialization before run + for ( ViewsVecT::const_iterator aCurr( beginViews() ), aEnd( endViews() ); aCurr != aEnd; ++aCurr ) + prepareForRun( *aCurr, aCurr->mpView->getCanvas() ); + + // start accompanying sound effect, if any + if( mpSoundPlayer ) + { + mpSoundPlayer->startPlayback(); + // xxx todo: for now, presentation.cxx takes care about the slide + // #i50492# transition sound object, so just release it here + mpSoundPlayer.reset(); + } +} + +void SlideChangeBase::end() +{ + // we're a one-shot activity, and already finished + if( mbFinished ) + return; + + try + { + // draw fully entered bitmap: + ViewsVecT::const_iterator aCurr( beginViews() ); + const ViewsVecT::const_iterator aEnd( endViews() ); + while( aCurr != aEnd ) + { + // fully clear view content to background color + aCurr->mpView->clearAll(); + + const SlideBitmapSharedPtr pSlideBitmap( getEnteringBitmap( *aCurr )); + pSlideBitmap->clip( basegfx::B2DPolyPolygon() /* no clipping */ ); + aCurr->mpView->clearAll(); + renderBitmap( pSlideBitmap, + aCurr->mpView->getCanvas() ); + + ++aCurr; + } + } + catch( uno::Exception& ) + { + // make sure releasing below happens + } + + // swap changes to screen + mrScreenUpdater.notifyUpdate(); + + // make object dysfunctional + mbFinished = true; + ViewsVecT().swap(maViewData); + maLeavingSlide.reset(); + mpEnteringSlide.reset(); + + // sprites have been binned above + mbSpritesVisible = false; + + // remove also from event multiplexer, we're dead anyway + mrEventMultiplexer.removeViewHandler( std::dynamic_pointer_cast<ViewEventHandler>(shared_from_this()) ); +} + +bool SlideChangeBase::operator()( double nValue ) +{ + if( mbFinished ) + return false; + + const std::size_t nEntries( maViewData.size() ); + bool bSpritesVisible( mbSpritesVisible ); + + for( ::std::size_t i=0; i<nEntries; ++i ) + { + // calc sprite offsets. The enter/leaving bitmaps are only + // as large as the actual slides. For scaled-down + // presentations, we have to move the left, top edge of + // those bitmaps to the actual position, governed by the + // given view transform. The aSpritePosPixel local + // variable is already in device coordinate space + // (i.e. pixel). + + ViewEntry& rViewEntry( maViewData[i] ); + const ::cppcanvas::CanvasSharedPtr& rCanvas( rViewEntry.mpView->getCanvas() ); + ::cppcanvas::CustomSpriteSharedPtr& rInSprite( rViewEntry.mpInSprite ); + ::cppcanvas::CustomSpriteSharedPtr& rOutSprite( rViewEntry.mpOutSprite ); + + // TODO(F2): Properly respect clip here. + + // Might have to be transformed, too. + const ::basegfx::B2DHomMatrix aViewTransform( + rViewEntry.mpView->getTransformation() ); + const ::basegfx::B2DPoint aSpritePosPixel( + aViewTransform * ::basegfx::B2DPoint() ); + + // move sprite to final output position, in + // device coordinates + if( rOutSprite ) + rOutSprite->movePixel( aSpritePosPixel ); + if( rInSprite ) + rInSprite->movePixel( aSpritePosPixel ); + + if( !mbSpritesVisible ) + { + if( rOutSprite ) + { + // only render once: clipping is done + // exclusively with the sprite + const ::cppcanvas::CanvasSharedPtr pOutContentCanvas( + rOutSprite->getContentCanvas() ); + if( pOutContentCanvas) + { + // TODO(Q2): Use basegfx bitmaps here + + // TODO(F1): SlideBitmap is not fully portable + // between different canvases! + + // render the content + OSL_ASSERT( getLeavingBitmap( rViewEntry ) ); + if( getLeavingBitmap( rViewEntry ) ) + getLeavingBitmap( rViewEntry )->draw( pOutContentCanvas ); + } + } + + if( rInSprite ) + { + // only render once: clipping is done + // exclusively with the sprite + const ::cppcanvas::CanvasSharedPtr pInContentCanvas( + rInSprite->getContentCanvas() ); + if( pInContentCanvas ) + { + // TODO(Q2): Use basegfx bitmaps here + + // TODO(F1): SlideBitmap is not fully portable + // between different canvases! + + // render the content + getEnteringBitmap( rViewEntry )->draw( pInContentCanvas ); + } + } + } + + if( rOutSprite ) + performOut( rOutSprite, rViewEntry, rCanvas, nValue ); + if( rInSprite ) + performIn( rInSprite, rViewEntry, rCanvas, nValue ); + + // finishing deeds for first run. + if( !mbSpritesVisible) + { + // enable sprites: + if( rOutSprite ) + rOutSprite->show(); + if( rInSprite ) + rInSprite->show(); + bSpritesVisible = true; + } + } // for_each( sprite ) + + mbSpritesVisible = bSpritesVisible; + mrScreenUpdater.notifyUpdate(); + + return true; +} + +void SlideChangeBase::prepareForRun( + const ViewEntry& /* rViewEntry */, + const cppcanvas::CanvasSharedPtr& /* rDestinationCanvas */ ) +{ +} + +void SlideChangeBase::performIn( + const cppcanvas::CustomSpriteSharedPtr& /*rSprite*/, + const ViewEntry& /*rViewEntry*/, + const cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/, + double /*t*/ ) +{ +} + +void SlideChangeBase::performOut( + const cppcanvas::CustomSpriteSharedPtr& /*rSprite*/, + const ViewEntry& /*rViewEntry*/, + const cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/, + double /*t*/ ) +{ +} + +double SlideChangeBase::getUnderlyingValue() const +{ + return 0.0; // though this should be used in concert with + // ActivitiesFactory::createSimpleActivity, better + // explicitly name our start value. + // Permissible range for operator() above is [0,1] +} + +void SlideChangeBase::viewAdded( const UnoViewSharedPtr& rView ) +{ + // we're a one-shot activity, and already finished + if( mbFinished ) + return; + + maViewData.emplace_back(rView ); + + ViewEntry& rEntry( maViewData.back() ); + getEnteringBitmap( rEntry ); + getLeavingBitmap( rEntry ); + addSprites( rEntry ); +} + +void SlideChangeBase::viewRemoved( const UnoViewSharedPtr& rView ) +{ + // we're a one-shot activity, and already finished + if( mbFinished ) + return; + + // erase corresponding entry from maViewData + maViewData.erase( + std::remove_if( + maViewData.begin(), + maViewData.end(), + [rView]( const ViewEntry& rViewEntry ) + { return rView == rViewEntry.getView(); } ), + maViewData.end() ); +} + +void SlideChangeBase::viewChanged( const UnoViewSharedPtr& rView ) +{ + // we're a one-shot activity, and already finished + if( mbFinished ) + return; + + // find entry corresponding to modified view + ViewsVecT::iterator aModifiedEntry( + std::find_if( + maViewData.begin(), + maViewData.end(), + [rView]( const ViewEntry& rViewEntry ) + { return rView == rViewEntry.getView(); } ) ); + + OSL_ASSERT( aModifiedEntry != maViewData.end() ); + if( aModifiedEntry == maViewData.end() ) + return; + + // clear stale info (both bitmaps and sprites prolly need a + // resize) + clearViewEntry( *aModifiedEntry ); + addSprites( *aModifiedEntry ); +} + +void SlideChangeBase::viewsChanged() +{ + // we're a one-shot activity, and already finished + if( mbFinished ) + return; + + for( auto& rView : maViewData ) + { + // clear stale info (both bitmaps and sprites prolly need a + // resize) + clearViewEntry( rView ); + addSprites( rView ); + } +} + +cppcanvas::CustomSpriteSharedPtr SlideChangeBase::createSprite( + UnoViewSharedPtr const & pView, + basegfx::B2DSize const & rSpriteSize, + double nPrio ) const +{ + // TODO(P2): change to bitmapsprite once that's working + const cppcanvas::CustomSpriteSharedPtr pSprite( + pView->createSprite( rSpriteSize, + nPrio )); + + // alpha default is 0.0, which seems to be + // a bad idea when viewing content... + pSprite->setAlpha( 1.0 ); + if (mbSpritesVisible) + pSprite->show(); + + return pSprite; +} + +void SlideChangeBase::addSprites( ViewEntry& rEntry ) +{ + if( mbCreateLeavingSprites && maLeavingSlide ) + { + // create leaving sprite: + const basegfx::B2ISize leavingSlideSizePixel( + getLeavingBitmap( rEntry )->getSize() ); + + rEntry.mpOutSprite = createSprite( rEntry.mpView, + basegfx::B2DSize( leavingSlideSizePixel ), + 100 ); + } + + if( mbCreateEnteringSprites ) + { + // create entering sprite: + const basegfx::B2ISize enteringSlideSizePixel( + getSlideSizePixel( basegfx::B2DSize( mpEnteringSlide->getSlideSize() ), + rEntry.mpView )); + + rEntry.mpInSprite = createSprite( rEntry.mpView, + basegfx::B2DSize( enteringSlideSizePixel ), + 101 ); + } +} + +void SlideChangeBase::clearViewEntry( ViewEntry& rEntry ) +{ + // clear stale info (both bitmaps and sprites prolly need a + // resize) + rEntry.mpEnteringBitmap.reset(); + rEntry.mpLeavingBitmap.reset(); + rEntry.mpInSprite.reset(); + rEntry.mpOutSprite.reset(); +} + +} // namespace presentation + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/slidechangebase.hxx b/slideshow/source/engine/transitions/slidechangebase.hxx new file mode 100644 index 000000000..492bc5971 --- /dev/null +++ b/slideshow/source/engine/transitions/slidechangebase.hxx @@ -0,0 +1,205 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_SLIDECHANGEBASE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_SLIDECHANGEBASE_HXX + +#include <unoview.hxx> +#include <vieweventhandler.hxx> +#include <numberanimation.hxx> +#include <slide.hxx> +#include <screenupdater.hxx> +#include <soundplayer.hxx> + +#include <memory> +#include <optional> + +namespace cppcanvas +{ + class Canvas; + class CustomSprite; +} + +namespace slideshow { +namespace internal { + +/** Base class for all slide change effects. + + This class provides the basic sprite and view handling + functionality. Derived classes should normally only need to + implement the perform() method. +*/ +class SlideChangeBase : public ViewEventHandler, + public NumberAnimation +{ +public: + SlideChangeBase(const SlideChangeBase&) = delete; + SlideChangeBase& operator=(const SlideChangeBase&) = delete; + + // NumberAnimation + virtual bool operator()( double x ) override; + virtual double getUnderlyingValue() const override; + + // Animation + virtual void prefetch() override; + virtual void start( const AnimatableShapeSharedPtr&, + const ShapeAttributeLayerSharedPtr& ) override; + virtual void end() override; + + // ViewEventHandler + virtual void viewAdded( const UnoViewSharedPtr& rView ) override; + virtual void viewRemoved( const UnoViewSharedPtr& rView ) override; + virtual void viewChanged( const UnoViewSharedPtr& rView ) override; + virtual void viewsChanged() override; + +protected: + /** Create a new SlideChanger, for the given leaving and + entering slides. + */ + SlideChangeBase( + ::std::optional<SlideSharedPtr> const & leavingSlide, + const SlideSharedPtr& pEnteringSlide, + const SoundPlayerSharedPtr& pSoundPlayer, + const UnoViewContainer& rViewContainer, + ScreenUpdater& rScreenUpdater, + EventMultiplexer& rEventMultiplexer, + bool bCreateLeavingSprites = true, + bool bCreateEnteringSprites = true ); + + /// Info on a per-view basis + struct ViewEntry + { + explicit ViewEntry( const UnoViewSharedPtr& rView ) : + mpView( rView ) + { + } + + /// The view this entry is for + UnoViewSharedPtr mpView; + /// outgoing slide sprite + std::shared_ptr<cppcanvas::CustomSprite> mpOutSprite; + /// incoming slide sprite + std::shared_ptr<cppcanvas::CustomSprite> mpInSprite; + /// outgoing slide bitmap + mutable SlideBitmapSharedPtr mpLeavingBitmap; + /// incoming slide bitmap + mutable SlideBitmapSharedPtr mpEnteringBitmap; + + // for algo access + const UnoViewSharedPtr& getView() const { return mpView; } + }; + + typedef ::std::vector<ViewEntry> ViewsVecT; + + ViewsVecT::const_iterator beginViews() { return maViewData.begin(); } + ViewsVecT::const_iterator endViews() { return maViewData.end(); } + + SlideBitmapSharedPtr getLeavingBitmap( const ViewEntry& rViewEntry ) const; + SlideBitmapSharedPtr getEnteringBitmap( const ViewEntry& rViewEntry ) const; + + SlideBitmapSharedPtr createBitmap( const UnoViewSharedPtr& pView, + const std::optional<SlideSharedPtr>& rSlide_ ) const; + + ::basegfx::B2ISize getEnteringSlideSizePixel( const UnoViewSharedPtr& pView ) const; + + static void renderBitmap( SlideBitmapSharedPtr const& pSlideBitmap, + cppcanvas::CanvasSharedPtr const& pCanvas ); + + /** Called on derived classes to perform actions before first run. + + This typically involves rendering of the initial slide content. + + @param rViewEntry the view entry + + @param rDestinationCanvas the canvas to render on + */ + virtual void prepareForRun( + const ViewEntry& rViewEntry, + const cppcanvas::CanvasSharedPtr& rDestinationCanvas ); + + /** Called on derived classes to implement actual slide change. + + This method is called with the sprite of the slide coming 'in' + + @param rSprite + Current sprite to operate on. This is the sprite of the + 'entering' slide + + @param t + Current parameter value + */ + virtual void performIn( + const cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& rViewEntry, + const cppcanvas::CanvasSharedPtr& rDestinationCanvas, + double t ); + + /** Called on derived classes to implement actual slide change. + + This method is called with the sprite of the slide moving 'out' + + @param rSprite + Current sprite to operate on. This is the sprite of the + 'leaving' slide + + @param t + Current parameter value + */ + virtual void performOut( + const cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& rViewEntry, + const cppcanvas::CanvasSharedPtr& rDestinationCanvas, + double t ); + + ScreenUpdater& getScreenUpdater() const { return mrScreenUpdater; } + +private: + + cppcanvas::CustomSpriteSharedPtr createSprite( + UnoViewSharedPtr const & pView, + ::basegfx::B2DSize const & rSpriteSize, + double nPrio ) const; + + void addSprites( ViewEntry& rEntry ); + static void clearViewEntry( ViewEntry& rEntry ); + + SoundPlayerSharedPtr mpSoundPlayer; + + EventMultiplexer& mrEventMultiplexer; + ScreenUpdater& mrScreenUpdater; + + ::std::optional<SlideSharedPtr> maLeavingSlide; + SlideSharedPtr mpEnteringSlide; + + ViewsVecT maViewData; + const UnoViewContainer& mrViewContainer; + + const bool mbCreateLeavingSprites; + const bool mbCreateEnteringSprites; + bool mbSpritesVisible; + bool mbFinished; + bool mbPrefetched; +}; + +} // namespace internal +} // namespace presentation + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_SLIDECHANGEBASE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/slidetransitionfactory.cxx b/slideshow/source/engine/transitions/slidetransitionfactory.cxx new file mode 100644 index 000000000..3ec2c8089 --- /dev/null +++ b/slideshow/source/engine/transitions/slidetransitionfactory.cxx @@ -0,0 +1,1110 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#include <tools/diagnose_ex.h> +#include <sal/log.hxx> + +#include <basegfx/matrix/b2dhommatrix.hxx> + +#include <cppcanvas/customsprite.hxx> + +#include <com/sun/star/animations/TransitionType.hpp> +#include <com/sun/star/animations/TransitionSubType.hpp> + +#include "slidechangebase.hxx" +#include <transitionfactory.hxx> +#include "transitionfactorytab.hxx" +#include "parametricpolypolygonfactory.hxx" +#include "clippingfunctor.hxx" +#include "combtransition.hxx" +#include <tools.hxx> +#include <memory> + + +/*************************************************** + *** *** + *** Slide Transition Effects *** + *** *** + ***************************************************/ + +using namespace com::sun::star; + +namespace slideshow::internal { + +namespace { + +// helper methods +// ============================================= + +void fillPage( const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, + const ::basegfx::B2DSize& rPageSizePixel, + const RGBColor& rFillColor ) +{ + // need to render without any transformation (we + // assume rPageSizePixel to represent device units) + const ::cppcanvas::CanvasSharedPtr pDevicePixelCanvas( + rDestinationCanvas->clone() ); + pDevicePixelCanvas->setTransformation( ::basegfx::B2DHomMatrix() ); + + // TODO(F2): Properly respect clip here. + // Might have to be transformed, too. + const ::basegfx::B2DHomMatrix aViewTransform( + rDestinationCanvas->getTransformation() ); + const ::basegfx::B2DPoint aOutputPosPixel( + aViewTransform * ::basegfx::B2DPoint() ); + + fillRect( pDevicePixelCanvas, + ::basegfx::B2DRectangle( + aOutputPosPixel.getX(), + aOutputPosPixel.getY(), + aOutputPosPixel.getX() + rPageSizePixel.getX(), + aOutputPosPixel.getY() + rPageSizePixel.getY() ), + rFillColor.getIntegerColor() ); +} + +class PluginSlideChange: public SlideChangeBase +{ + struct TransitionViewPair { + uno::Reference<presentation::XTransition> mxTransition; + UnoViewSharedPtr mpView; + + TransitionViewPair( uno::Reference<presentation::XTransition> const & xTransition, const UnoViewSharedPtr& rView ) + : mxTransition(xTransition), mpView(rView) + { + } + + ~TransitionViewPair() + { + mxTransition.clear(); + mpView.reset(); + } + + void update( double t ) + { + mxTransition->update( t ); + } + }; + +public: + /** Create a new SlideChanger, for the given leaving and + entering slide bitmaps, which uses super secret OpenGL + stuff. + */ + PluginSlideChange( sal_Int16 nTransitionType, + sal_Int16 nTransitionSubType, + const RGBColor& rTransitionFadeColor, + std::optional<SlideSharedPtr> const& leavingSlide_, + const SlideSharedPtr& pEnteringSlide, + const UnoViewContainer& rViewContainer, + ScreenUpdater& rScreenUpdater, + const uno::Reference< + presentation::XTransitionFactory>& xFactory, + const SoundPlayerSharedPtr& pSoundPlayer, + EventMultiplexer& rEventMultiplexer) : + SlideChangeBase( leavingSlide_, + pEnteringSlide, + pSoundPlayer, + rViewContainer, + rScreenUpdater, + rEventMultiplexer ), + maTransitions(), + mbSuccess( false ), + mnTransitionType( nTransitionType ), + mnTransitionSubType( nTransitionSubType ), + mnTransitionFadeColor( rTransitionFadeColor ), + mxFactory( xFactory ) + { + // create one transition per view + for( const auto& rView : rViewContainer ) + { + if( !addTransition( rView ) ) + return; + + ENSURE_OR_THROW(maTransitions.back() && maTransitions.back()->mxTransition.is(), + "Failed to create plugin transition"); + } + mbSuccess = true; + } + + virtual ~PluginSlideChange() override + { + mxFactory.clear(); + } + + bool addTransition( const UnoViewSharedPtr& rView ) + { + uno::Reference<presentation::XTransition> rTransition = mxFactory->createTransition( + mnTransitionType, + mnTransitionSubType, + RGBAColor2UnoColor( mnTransitionFadeColor.getIntegerColor()), + rView->getUnoView(), + getLeavingBitmap(ViewEntry(rView))->getXBitmap(), + getEnteringBitmap(ViewEntry(rView))->getXBitmap() ); + + if( rTransition.is() ) + maTransitions.emplace_back( new TransitionViewPair( rTransition, rView ) ); + else + return false; + + return true; + } + + virtual bool operator()( double t ) override + { + for( const auto& pTransition : maTransitions ) + pTransition->update( t ); + return true; + } + + bool Success() + { + return mbSuccess; + } + + // ViewEventHandler + virtual void viewAdded( const UnoViewSharedPtr& rView ) override + { + SAL_INFO("slideshow", "PluginSlideChange viewAdded"); + SlideChangeBase::viewAdded( rView ); + + for( const auto& pCurrView : maTransitions ) + { + if( pCurrView->mpView == rView ) + return; + } + + SAL_INFO("slideshow", "need to be added" ); + addTransition( rView ); + } + + virtual void viewRemoved( const UnoViewSharedPtr& rView ) override + { + SAL_INFO("slideshow", "PluginSlideChange viewRemoved"); + SlideChangeBase::viewRemoved( rView ); + + auto aIter = std::find_if(maTransitions.begin(), maTransitions.end(), + [&rView](const std::unique_ptr<TransitionViewPair>& rxTransition) { return rxTransition->mpView == rView; }); + if (aIter != maTransitions.end()) + { + SAL_INFO("slideshow", "view removed" ); + maTransitions.erase( aIter ); + } + } + + virtual void viewChanged( const UnoViewSharedPtr& rView ) override + { + SAL_INFO("slideshow", "PluginSlideChange viewChanged"); + SlideChangeBase::viewChanged( rView ); + + for( const auto& pCurrView : maTransitions ) + { + if( pCurrView->mpView == rView ) + { + SAL_INFO("slideshow", "view changed" ); + pCurrView->mxTransition->viewChanged( rView->getUnoView(), + getLeavingBitmap(ViewEntry(rView))->getXBitmap(), + getEnteringBitmap(ViewEntry(rView))->getXBitmap() ); + } + else + SAL_INFO("slideshow", "view did not change" ); + } + } + + virtual void viewsChanged() override + { + SAL_INFO("slideshow", "PluginSlideChange viewsChanged"); + SlideChangeBase::viewsChanged(); + + for( const auto& pCurrView : maTransitions ) + { + SAL_INFO("slideshow", "view changed" ); + UnoViewSharedPtr pView = pCurrView->mpView; + pCurrView->mxTransition->viewChanged( pView->getUnoView(), + getLeavingBitmap(ViewEntry(pView))->getXBitmap(), + getEnteringBitmap(ViewEntry(pView))->getXBitmap() ); + } + } + +private: + // One transition object per view + std::vector< std::unique_ptr<TransitionViewPair> > maTransitions; + + // bool + bool mbSuccess; + + sal_Int16 mnTransitionType; + sal_Int16 mnTransitionSubType; + RGBColor mnTransitionFadeColor; + + uno::Reference<presentation::XTransitionFactory> mxFactory; +}; + +class ClippedSlideChange : public SlideChangeBase +{ +public: + /** Create a new SlideChanger, for the given leaving and + entering slide bitmaps, which applies the given clip + polygon. + */ + ClippedSlideChange( + const SlideSharedPtr& pEnteringSlide, + const ParametricPolyPolygonSharedPtr& rPolygon, + const TransitionInfo& rTransitionInfo, + const UnoViewContainer& rViewContainer, + ScreenUpdater& rScreenUpdater, + EventMultiplexer& rEventMultiplexer, + bool bDirectionForward, + const SoundPlayerSharedPtr& pSoundPlayer ) : + SlideChangeBase( + // leaving bitmap is empty, we're leveraging the fact that the + // old slide is still displayed in the background: + std::optional<SlideSharedPtr>(), + pEnteringSlide, + pSoundPlayer, + rViewContainer, + rScreenUpdater, + rEventMultiplexer ), + maClippingFunctor( rPolygon, + rTransitionInfo, + bDirectionForward, + true ) + {} + + virtual void performIn( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& rViewEntry, + const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, + double t ) override; + + virtual void performOut( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& rViewEntry, + const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, + double t ) override; + +private: + ClippingFunctor maClippingFunctor; +}; + +void ClippedSlideChange::performIn( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& rViewEntry, + const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/, + double t ) +{ + // #i46602# Better work in device coordinate space here, + // otherwise, we too easily suffer from roundoffs. Apart from + // that, getEnteringSizePixel() _guarantees_ to cover the whole + // slide bitmap. There's a catch, though: this removes any effect + // of the view transformation (e.g. rotation) from the transition. + rSprite->setClipPixel( + maClippingFunctor( t, + ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry.mpView) ) ) ); +} + +void ClippedSlideChange::performOut( + const ::cppcanvas::CustomSpriteSharedPtr& /*rSprite*/, + const ViewEntry& /*rViewEntry*/, + const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/, + double /*t*/ ) +{ + // not needed here +} + + +class FadingSlideChange : public SlideChangeBase +{ +public: + /** Create a new SlideChanger, for the given leaving and + entering slides, which applies a fade effect. + */ + FadingSlideChange( + std::optional<SlideSharedPtr> const & leavingSlide, + const SlideSharedPtr& pEnteringSlide, + std::optional<RGBColor> const& rFadeColor, + const SoundPlayerSharedPtr& pSoundPlayer, + const UnoViewContainer& rViewContainer, + ScreenUpdater& rScreenUpdater, + EventMultiplexer& rEventMultiplexer ) + : SlideChangeBase( leavingSlide, + pEnteringSlide, + pSoundPlayer, + rViewContainer, + rScreenUpdater, + rEventMultiplexer ), + maFadeColor( rFadeColor ) + {} + + virtual void prepareForRun( + const ViewEntry& rViewEntry, + const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) override; + + virtual void performIn( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& rViewEntry, + const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, + double t ) override; + + virtual void performOut( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& rViewEntry, + const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, + double t ) override; + +private: + const std::optional< RGBColor > maFadeColor; +}; + +void FadingSlideChange::prepareForRun( + const ViewEntry& rViewEntry, + const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) +{ + if ( maFadeColor ) + { + // clear page to given fade color. 'Leaving' slide is + // painted atop of that, but slowly fading out. + fillPage( rDestinationCanvas, + ::basegfx::B2DSize( getEnteringSlideSizePixel( rViewEntry.mpView ) ), + *maFadeColor ); + } +} + +void FadingSlideChange::performIn( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& /*rViewEntry*/, + const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/, + double t ) +{ + ENSURE_OR_THROW( + rSprite, + "FadingSlideChange::performIn(): Invalid sprite" ); + + if( maFadeColor ) + // After half of the active time, fade in new slide + rSprite->setAlpha( t > 0.5 ? 2.0*(t-0.5) : 0.0 ); + else + // Fade in new slide over full active time + rSprite->setAlpha( t ); +} + +void FadingSlideChange::performOut( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& /* rViewEntry */, + const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, + double t ) +{ + ENSURE_OR_THROW( + rSprite, + "FadingSlideChange::performOut(): Invalid sprite" ); + ENSURE_OR_THROW( + rDestinationCanvas, + "FadingSlideChange::performOut(): Invalid dest canvas" ); + + // only needed for color fades + if( maFadeColor ) + { + // Until half of the active time, fade out old + // slide. After half of the active time, old slide + // will be invisible. + rSprite->setAlpha( t > 0.5 ? 0.0 : 2.0*(0.5-t) ); + } +} + +class CutSlideChange : public SlideChangeBase +{ +public: + /** Create a new SlideChanger, for the given leaving and + entering slides, which applies a cut effect. + */ + CutSlideChange( + std::optional<SlideSharedPtr> const & leavingSlide, + const SlideSharedPtr& pEnteringSlide, + const RGBColor& rFadeColor, + const SoundPlayerSharedPtr& pSoundPlayer, + const UnoViewContainer& rViewContainer, + ScreenUpdater& rScreenUpdater, + EventMultiplexer& rEventMultiplexer ) + : SlideChangeBase( leavingSlide, + pEnteringSlide, + pSoundPlayer, + rViewContainer, + rScreenUpdater, + rEventMultiplexer ), + maFadeColor( rFadeColor ) + {} + + virtual void prepareForRun( + const ViewEntry& rViewEntry, + const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) override; + + virtual void performIn( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& rViewEntry, + const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, + double t ) override; + + virtual void performOut( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& rViewEntry, + const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, + double t ) override; + +private: + RGBColor maFadeColor; +}; + +void CutSlideChange::prepareForRun( + const ViewEntry& rViewEntry, + const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) +{ + // clear page to given fade color. 'Leaving' slide is + // painted atop of that + fillPage( rDestinationCanvas, + ::basegfx::B2DSize( getEnteringSlideSizePixel( rViewEntry.mpView ) ), + maFadeColor ); +} + +void CutSlideChange::performIn( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& /*rViewEntry*/, + const ::cppcanvas::CanvasSharedPtr& /*rDestinationCanvas*/, + double t ) +{ + ENSURE_OR_THROW( + rSprite, + "CutSlideChange::performIn(): Invalid sprite" ); + + // After 2/3rd of the active time, display new slide + rSprite->setAlpha( t > 2/3.0 ? 1.0 : 0.0 ); +} + +void CutSlideChange::performOut( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& /* rViewEntry */, + const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, + double t ) +{ + ENSURE_OR_THROW( + rSprite, + "CutSlideChange::performOut(): Invalid sprite" ); + ENSURE_OR_THROW( + rDestinationCanvas, + "CutSlideChange::performOut(): Invalid dest canvas" ); + + // Until 1/3rd of the active time, display old slide. + rSprite->setAlpha( t > 1/3.0 ? 0.0 : 1.0 ); +} + +class MovingSlideChange : public SlideChangeBase +{ + /// Direction vector for leaving slide, + const ::basegfx::B2DVector maLeavingDirection; + + /// Direction vector for entering slide, + const ::basegfx::B2DVector maEnteringDirection; + +public: + /** Create a new SlideChanger, for the given entering slide + bitmaps, which performs a moving slide change effect + + @param rLeavingDirection + Direction vector. The move is performed along this + direction vector, starting at a position where the leaving + slide is fully visible, and ending at a position where the + leaving slide is just not visible. The vector must have + unit length. + + @param rEnteringDirection + Direction vector. The move is performed along this + direction vector, starting at a position where the + entering slide is just not visible, and ending at the + final slide position. The vector must have unit length. + */ + MovingSlideChange( + const std::optional<SlideSharedPtr>& leavingSlide, + const SlideSharedPtr& pEnteringSlide, + const SoundPlayerSharedPtr& pSoundPlayer, + const UnoViewContainer& rViewContainer, + ScreenUpdater& rScreenUpdater, + EventMultiplexer& rEventMultiplexer, + const ::basegfx::B2DVector& rLeavingDirection, + const ::basegfx::B2DVector& rEnteringDirection ) + : SlideChangeBase( + leavingSlide, pEnteringSlide, pSoundPlayer, + rViewContainer, rScreenUpdater, rEventMultiplexer, + // Optimization: when leaving bitmap is given, + // but it does not move, don't create sprites for it, + // we simply paint it once at startup: + !rLeavingDirection.equalZero() /* bCreateLeavingSprites */, + !rEnteringDirection.equalZero() /* bCreateEnteringSprites */ ), + // TODO(F1): calc correct length of direction + // vector. Directions not strictly horizontal or vertical + // must travel a longer distance. + maLeavingDirection( rLeavingDirection ), + // TODO(F1): calc correct length of direction + // vector. Directions not strictly horizontal or vertical + // must travel a longer distance. + maEnteringDirection( rEnteringDirection ) + {} + + virtual void prepareForRun( + const ViewEntry& rViewEntry, + const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) override; + + virtual void performIn( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& rViewEntry, + const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, + double t ) override; + + virtual void performOut( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& rViewEntry, + const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, + double t ) override; +}; + +void MovingSlideChange::prepareForRun( + const ViewEntry& rViewEntry, + const cppcanvas::CanvasSharedPtr& rDestinationCanvas ) +{ + if ( maLeavingDirection.equalZero() ) + renderBitmap( getLeavingBitmap( rViewEntry ), rDestinationCanvas ); + else if ( maEnteringDirection.equalZero() ) + renderBitmap( getEnteringBitmap( rViewEntry ), rDestinationCanvas ); +} + +void MovingSlideChange::performIn( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& rViewEntry, + const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, + double t ) +{ + // intro sprite moves: + + ENSURE_OR_THROW( + rSprite, + "MovingSlideChange::performIn(): Invalid sprite" ); + ENSURE_OR_THROW( + rDestinationCanvas, + "MovingSlideChange::performIn(): Invalid dest canvas" ); + + // TODO(F1): This does not account for non-translational + // transformations! If the canvas is rotated, we still + // move the sprite unrotated (which might or might not + // produce the intended effect). + const basegfx::B2DHomMatrix aViewTransform( + rDestinationCanvas->getTransformation() ); + const basegfx::B2DPoint aPageOrigin( + aViewTransform * basegfx::B2DPoint() ); + + // move sprite + rSprite->movePixel( + aPageOrigin + + ((t - 1.0) * + ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry.mpView) ) * + maEnteringDirection) ); +} + +void MovingSlideChange::performOut( + const ::cppcanvas::CustomSpriteSharedPtr& rSprite, + const ViewEntry& rViewEntry, + const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas, + double t ) +{ + // outro sprite moves: + + ENSURE_OR_THROW( + rSprite, + "MovingSlideChange::performOut(): Invalid sprite" ); + ENSURE_OR_THROW( + rDestinationCanvas, + "MovingSlideChange::performOut(): Invalid dest canvas" ); + + // TODO(F1): This does not account for non-translational + // transformations! If the canvas is rotated, we still + // move the sprite unrotated (which might or might not + // produce the intended effect). + const basegfx::B2DHomMatrix aViewTransform( + rDestinationCanvas->getTransformation() ); + const basegfx::B2DPoint aPageOrigin( + aViewTransform * basegfx::B2DPoint() ); + + // move sprite + rSprite->movePixel( + aPageOrigin + (t * + ::basegfx::B2DSize( getEnteringSlideSizePixel(rViewEntry.mpView) ) * + maLeavingDirection) ); +} + + +NumberAnimationSharedPtr createPushWipeTransition( + std::optional<SlideSharedPtr> const & leavingSlide_, + const SlideSharedPtr& pEnteringSlide, + const UnoViewContainer& rViewContainer, + ScreenUpdater& rScreenUpdater, + EventMultiplexer& rEventMultiplexer, + sal_Int16 /*nTransitionType*/, + sal_Int16 nTransitionSubType, + bool /*bTransitionDirection*/, + const SoundPlayerSharedPtr& pSoundPlayer ) +{ + std::optional<SlideSharedPtr> leavingSlide; // no bitmap + if (leavingSlide_ && *leavingSlide_ != nullptr) + { + // opt: only page, if we've an + // actual slide to move out here. We + // _don't_ need a fake black background + // bitmap, neither for push nor for comb + // wipes. + leavingSlide = leavingSlide_; + } + + // setup direction vector + bool bComb( false ); + ::basegfx::B2DVector aDirection; + switch( nTransitionSubType ) + { + default: + OSL_FAIL( + "createPushWipeTransition(): Unexpected transition " + "subtype for animations::TransitionType::PUSHWIPE " + "transitions" ); + return NumberAnimationSharedPtr(); + + case animations::TransitionSubType::FROMTOP: + aDirection = ::basegfx::B2DVector( 0.0, 1.0 ); + break; + + case animations::TransitionSubType::FROMBOTTOM: + aDirection = ::basegfx::B2DVector( 0.0, -1.0 ); + break; + + case animations::TransitionSubType::FROMLEFT: + aDirection = ::basegfx::B2DVector( 1.0, 0.0 ); + break; + + case animations::TransitionSubType::FROMRIGHT: + aDirection = ::basegfx::B2DVector( -1.0, 0.0 ); + break; + + case animations::TransitionSubType::FROMBOTTOMRIGHT: + aDirection = ::basegfx::B2DVector( -1.0, -1.0 ); + break; + + case animations::TransitionSubType::FROMBOTTOMLEFT: + aDirection = ::basegfx::B2DVector( 1.0, -1.0 ); + break; + + case animations::TransitionSubType::FROMTOPRIGHT: + aDirection = ::basegfx::B2DVector( -1.0, 1.0 ); + break; + + case animations::TransitionSubType::FROMTOPLEFT: + aDirection = ::basegfx::B2DVector( 1.0, 1.0 ); + break; + + case animations::TransitionSubType::COMBHORIZONTAL: + aDirection = ::basegfx::B2DVector( 1.0, 0.0 ); + bComb = true; + break; + + case animations::TransitionSubType::COMBVERTICAL: + aDirection = ::basegfx::B2DVector( 0.0, 1.0 ); + bComb = true; + break; + } + + if( bComb ) + { + return std::make_shared<CombTransition>( leavingSlide, + pEnteringSlide, + pSoundPlayer, + rViewContainer, + rScreenUpdater, + rEventMultiplexer, + aDirection, + 24 /* comb with 12 stripes */ ); + } + else + { + return std::make_shared<MovingSlideChange>( leavingSlide, + pEnteringSlide, + pSoundPlayer, + rViewContainer, + rScreenUpdater, + rEventMultiplexer, + aDirection, + aDirection ); + } +} + +NumberAnimationSharedPtr createSlideWipeTransition( + std::optional<SlideSharedPtr> const & leavingSlide, + const SlideSharedPtr& pEnteringSlide, + const UnoViewContainer& rViewContainer, + ScreenUpdater& rScreenUpdater, + EventMultiplexer& rEventMultiplexer, + sal_Int16 /*nTransitionType*/, + sal_Int16 nTransitionSubType, + bool bTransitionDirection, + const SoundPlayerSharedPtr& pSoundPlayer ) +{ + // setup 'in' direction vector + ::basegfx::B2DVector aInDirection; + switch( nTransitionSubType ) + { + default: + OSL_FAIL( + "createSlideWipeTransition(): Unexpected transition " + "subtype for animations::TransitionType::SLIDEWIPE " + "transitions" ); + return NumberAnimationSharedPtr(); + + case animations::TransitionSubType::FROMTOP: + aInDirection = ::basegfx::B2DVector( 0.0, 1.0 ); + break; + + case animations::TransitionSubType::FROMRIGHT: + aInDirection = ::basegfx::B2DVector( -1.0, 0.0 ); + break; + + case animations::TransitionSubType::FROMLEFT: + aInDirection = ::basegfx::B2DVector( 1.0, 0.0 ); + break; + + case animations::TransitionSubType::FROMBOTTOM: + aInDirection = ::basegfx::B2DVector( 0.0, -1.0 ); + break; + + case animations::TransitionSubType::FROMBOTTOMRIGHT: + aInDirection = ::basegfx::B2DVector( -1.0, -1.0 ); + break; + + case animations::TransitionSubType::FROMBOTTOMLEFT: + aInDirection = ::basegfx::B2DVector( 1.0, -1.0 ); + break; + + case animations::TransitionSubType::FROMTOPRIGHT: + aInDirection = ::basegfx::B2DVector( -1.0, 1.0 ); + break; + + case animations::TransitionSubType::FROMTOPLEFT: + aInDirection = ::basegfx::B2DVector( 1.0, 1.0 ); + break; + } + + if( bTransitionDirection ) + { + // normal, 'forward' slide wipe effect. Since the old + // content is still on screen (and does not move), we omit + // the 'leaving' slide. + + + return std::make_shared<MovingSlideChange>( + std::optional<SlideSharedPtr>() /* no slide */, + pEnteringSlide, + pSoundPlayer, + rViewContainer, + rScreenUpdater, + rEventMultiplexer, + basegfx::B2DVector(), + aInDirection ); + } + else + { + // 'reversed' slide wipe effect. Reverse for slide wipes + // means, that the new slide is in the back, statically, + // and the old one is moving off in the foreground. + + + return std::make_shared<MovingSlideChange>( leavingSlide, + pEnteringSlide, + pSoundPlayer, + rViewContainer, + rScreenUpdater, + rEventMultiplexer, + aInDirection, + basegfx::B2DVector() ); + } +} + +NumberAnimationSharedPtr createPluginTransition( + sal_Int16 nTransitionType, + sal_Int16 nTransitionSubType, + const RGBColor& rTransitionFadeColor, + std::optional<SlideSharedPtr> const& pLeavingSlide, + const SlideSharedPtr& pEnteringSlide, + const UnoViewContainer& rViewContainer, + ScreenUpdater& rScreenUpdater, + const uno::Reference< + presentation::XTransitionFactory>& xFactory, + const SoundPlayerSharedPtr& pSoundPlayer, + EventMultiplexer& rEventMultiplexer) +{ + auto pTransition = + std::make_shared<PluginSlideChange>( + nTransitionType, + nTransitionSubType, + rTransitionFadeColor, + pLeavingSlide, + pEnteringSlide, + rViewContainer, + rScreenUpdater, + xFactory, + pSoundPlayer, + rEventMultiplexer ); + + if( !pTransition->Success() ) + return nullptr; + return pTransition; +} + +} // anon namespace + + +NumberAnimationSharedPtr TransitionFactory::createSlideTransition( + const SlideSharedPtr& pLeavingSlide, + const SlideSharedPtr& pEnteringSlide, + const UnoViewContainer& rViewContainer, + ScreenUpdater& rScreenUpdater, + EventMultiplexer& rEventMultiplexer, + const uno::Reference<presentation::XTransitionFactory>& xOptionalFactory, + sal_Int16 nTransitionType, + sal_Int16 nTransitionSubType, + bool bTransitionDirection, + const RGBColor& rTransitionFadeColor, + const SoundPlayerSharedPtr& pSoundPlayer ) +{ + // xxx todo: change to TransitionType::NONE, TransitionSubType::NONE: + if (nTransitionType == 0 && nTransitionSubType == 0) { + // just play sound, no slide transition: + if (pSoundPlayer) { + pSoundPlayer->startPlayback(); + // xxx todo: for now, presentation.cxx takes care about the slide + // #i50492# transition sound object, so just release it here + } + return NumberAnimationSharedPtr(); + } + + ENSURE_OR_THROW( + pEnteringSlide, + "TransitionFactory::createSlideTransition(): Invalid entering slide" ); + + if( xOptionalFactory.is() && + xOptionalFactory->hasTransition(nTransitionType, nTransitionSubType) ) + { + // #i82460# - optional plugin factory claims this transition. delegate. + NumberAnimationSharedPtr pTransition( + createPluginTransition( + nTransitionType, + nTransitionSubType, + rTransitionFadeColor, + std::make_optional(pLeavingSlide), + pEnteringSlide, + rViewContainer, + rScreenUpdater, + xOptionalFactory, + pSoundPlayer, + rEventMultiplexer )); + + if( pTransition ) + return pTransition; + } + + const TransitionInfo* pTransitionInfo( + getTransitionInfo( nTransitionType, nTransitionSubType ) ); + + if( pTransitionInfo != nullptr ) + { + switch( pTransitionInfo->meTransitionClass ) + { + default: + case TransitionInfo::TRANSITION_INVALID: + SAL_WARN("slideshow", + "TransitionFactory::createSlideTransition(): " + "Invalid type/subtype combination encountered." + << nTransitionType << " " << nTransitionSubType ); + return NumberAnimationSharedPtr(); + + + case TransitionInfo::TRANSITION_CLIP_POLYPOLYGON: + { + // generate parametric poly-polygon + ParametricPolyPolygonSharedPtr pPoly( + ParametricPolyPolygonFactory::createClipPolyPolygon( + nTransitionType, nTransitionSubType ) ); + + // create a clip transition from that + return std::make_shared<ClippedSlideChange>( pEnteringSlide, + pPoly, + *pTransitionInfo, + rViewContainer, + rScreenUpdater, + rEventMultiplexer, + bTransitionDirection, + pSoundPlayer ); + } + + case TransitionInfo::TRANSITION_SPECIAL: + { + switch( nTransitionType ) + { + default: + OSL_FAIL( + "TransitionFactory::createSlideTransition(): " + "Unexpected transition type for " + "TRANSITION_SPECIAL transitions" ); + return NumberAnimationSharedPtr(); + + case animations::TransitionType::RANDOM: + { + // select randomly one of the effects from the + // TransitionFactoryTable + + const TransitionInfo* pRandomTransitionInfo( + getRandomTransitionInfo() ); + + ENSURE_OR_THROW( + pRandomTransitionInfo != nullptr, + "TransitionFactory::createSlideTransition(): " + "Got invalid random transition info" ); + + ENSURE_OR_THROW( + pRandomTransitionInfo->mnTransitionType != + animations::TransitionType::RANDOM, + "TransitionFactory::createSlideTransition(): " + "Got random again for random input!" ); + + // and recurse + return createSlideTransition( + pLeavingSlide, + pEnteringSlide, + rViewContainer, + rScreenUpdater, + rEventMultiplexer, + xOptionalFactory, + pRandomTransitionInfo->mnTransitionType, + pRandomTransitionInfo->mnTransitionSubType, + bTransitionDirection, + rTransitionFadeColor, + pSoundPlayer ); + } + + case animations::TransitionType::PUSHWIPE: + { + return createPushWipeTransition( + std::make_optional(pLeavingSlide), + pEnteringSlide, + rViewContainer, + rScreenUpdater, + rEventMultiplexer, + nTransitionType, + nTransitionSubType, + bTransitionDirection, + pSoundPlayer ); + } + + case animations::TransitionType::SLIDEWIPE: + { + return createSlideWipeTransition( + std::make_optional(pLeavingSlide), + pEnteringSlide, + rViewContainer, + rScreenUpdater, + rEventMultiplexer, + nTransitionType, + nTransitionSubType, + bTransitionDirection, + pSoundPlayer ); + } + + case animations::TransitionType::BARWIPE: + case animations::TransitionType::FADE: + { + // black page: + std::optional<SlideSharedPtr> leavingSlide; + std::optional<RGBColor> aFadeColor; + + switch( nTransitionSubType ) + { + case animations::TransitionSubType::CROSSFADE: + // crossfade needs no further setup, + // just blend new slide over current + // slide. + break; + + // TODO(F1): Implement toColor/fromColor fades + case animations::TransitionSubType::FADETOCOLOR: + case animations::TransitionSubType::FADEFROMCOLOR: + case animations::TransitionSubType::FADEOVERCOLOR: + if (pLeavingSlide) { + // only generate, if fade + // effect really needs it. + leavingSlide = pLeavingSlide; + } + aFadeColor = rTransitionFadeColor; + break; + + default: + ENSURE_OR_THROW( false, + "SlideTransitionFactory::createSlideTransition(): Unknown FADE subtype" ); + } + + if( nTransitionType == animations::TransitionType::FADE ) + return std::make_shared<FadingSlideChange>( + leavingSlide, + pEnteringSlide, + aFadeColor, + pSoundPlayer, + rViewContainer, + rScreenUpdater, + rEventMultiplexer ); + else + return std::make_shared<CutSlideChange>( + leavingSlide, + pEnteringSlide, + rTransitionFadeColor, + pSoundPlayer, + rViewContainer, + rScreenUpdater, + rEventMultiplexer ); + } + } + } + break; + } + } + + // No animation generated, maybe no table entry for given + // transition? + SAL_WARN("slideshow", + "TransitionFactory::createSlideTransition(): " + "Unknown type/subtype combination encountered " + << nTransitionType << " " << nTransitionSubType ); + OSL_FAIL( + "TransitionFactory::createSlideTransition(): " + "Unknown type/subtype combination encountered" ); + + return NumberAnimationSharedPtr(); +} + +} // namespace presentation + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/snakewipe.cxx b/slideshow/source/engine/transitions/snakewipe.cxx new file mode 100644 index 000000000..ceaa1d001 --- /dev/null +++ b/slideshow/source/engine/transitions/snakewipe.cxx @@ -0,0 +1,238 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#include <sal/config.h> + +#include <cmath> + +#include <o3tl/temporary.hxx> +#include <osl/diagnose.h> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include "snakewipe.hxx" +#include "transitiontools.hxx" + + +namespace slideshow::internal { + +SnakeWipe::SnakeWipe( sal_Int32 nElements, bool diagonal, bool flipOnYAxis ) + : m_sqrtElements( static_cast<sal_Int32>( + sqrt( static_cast<double>(nElements) ) ) ), + m_elementEdge( 1.0 / m_sqrtElements ), + m_diagonal(diagonal), + m_flipOnYAxis(flipOnYAxis) +{ +} + +::basegfx::B2DPolyPolygon SnakeWipe::calcSnake( double t ) const +{ + ::basegfx::B2DPolyPolygon res; + const double area = t * m_sqrtElements * m_sqrtElements; + const sal_Int32 line_ = static_cast<sal_Int32>(area) / m_sqrtElements; + const double line = ::basegfx::pruneScaleValue( + static_cast<double>(line_) / m_sqrtElements ); + const double col = ::basegfx::pruneScaleValue( + (area - (line_ * m_sqrtElements)) / m_sqrtElements ); + + if (! ::basegfx::fTools::equalZero( line )) { + ::basegfx::B2DPolygon poly; + poly.append( ::basegfx::B2DPoint( 0.0, 0.0 ) ); + poly.append( ::basegfx::B2DPoint( 0.0, line ) ); + poly.append( ::basegfx::B2DPoint( 1.0, line ) ); + poly.append( ::basegfx::B2DPoint( 1.0, 0.0 ) ); + poly.setClosed(true); + res.append(poly); + } + if (! ::basegfx::fTools::equalZero( col )) + { + double offset = 0.0; + if ((line_ & 1) == 1) { + // odd line: => right to left + offset = (1.0 - col); + } + ::basegfx::B2DPolygon poly; + poly.append( ::basegfx::B2DPoint( offset, line ) ); + poly.append( ::basegfx::B2DPoint( offset, + line + m_elementEdge ) ); + poly.append( ::basegfx::B2DPoint( offset + col, + line + m_elementEdge ) ); + poly.append( ::basegfx::B2DPoint( offset + col, line ) ); + poly.setClosed(true); + res.append(poly); + } + + return res; +} + +::basegfx::B2DPolyPolygon SnakeWipe::calcHalfDiagonalSnake( + double t, bool in ) const +{ + ::basegfx::B2DPolyPolygon res; + + if (in) { + const double sqrtArea2 = sqrt( t * m_sqrtElements * m_sqrtElements ); + const double edge = ::basegfx::pruneScaleValue( + std::trunc(sqrtArea2) / + m_sqrtElements ); + + ::basegfx::B2DPolygon poly; + if (! ::basegfx::fTools::equalZero( edge )) { + poly.append( ::basegfx::B2DPoint( 0.0, 0.0 ) ); + poly.append( ::basegfx::B2DPoint( 0.0, edge ) ); + poly.append( ::basegfx::B2DPoint( edge, 0.0 ) ); + poly.setClosed(true); + res.append(poly); + } + const double a = M_SQRT1_2 / m_sqrtElements; + const double d = std::modf(sqrtArea2, &o3tl::temporary(double())); + const double len = t * M_SQRT2 * d; + const double height = ::basegfx::pruneScaleValue( M_SQRT1_2 / m_sqrtElements ); + poly.clear(); + poly.append( ::basegfx::B2DPoint( 0.0, 0.0 ) ); + poly.append( ::basegfx::B2DPoint( 0.0, height ) ); + poly.append( ::basegfx::B2DPoint( len + a, height ) ); + poly.append( ::basegfx::B2DPoint( len + a, 0.0 ) ); + poly.setClosed(true); + ::basegfx::B2DHomMatrix aTransform; + + if ((static_cast<sal_Int32>(sqrtArea2) & 1) == 1) + { + // odd line + aTransform = basegfx::utils::createRotateB2DHomMatrix(M_PI_2 + M_PI_4); + aTransform.translate(edge + m_elementEdge, 0.0); + } + else + { + aTransform = basegfx::utils::createTranslateB2DHomMatrix(-a, 0.0); + aTransform.rotate( -M_PI_4 ); + aTransform.translate( 0.0, edge ); + } + + poly.transform( aTransform ); + res.append(poly); + } + else // out + { + const double sqrtArea2 = sqrt( t * m_sqrtElements * m_sqrtElements ); + const double edge = ::basegfx::pruneScaleValue( + std::trunc(sqrtArea2) / + m_sqrtElements ); + + ::basegfx::B2DPolygon poly; + if (! ::basegfx::fTools::equalZero( edge )) { + poly.append( ::basegfx::B2DPoint( 0.0, 1.0 ) ); + poly.append( ::basegfx::B2DPoint( edge, 1.0 ) ); + poly.append( ::basegfx::B2DPoint( 1.0, edge ) ); + poly.append( ::basegfx::B2DPoint( 1.0, 0.0 ) ); + poly.setClosed(true); + res.append(poly); + } + const double a = M_SQRT1_2 / m_sqrtElements; + const double d = std::modf(sqrtArea2, &o3tl::temporary(double())); + const double len = (1.0 - t) * M_SQRT2 * d; + const double height = ::basegfx::pruneScaleValue( M_SQRT1_2 / m_sqrtElements ); + poly.clear(); + poly.append( ::basegfx::B2DPoint( 0.0, 0.0 ) ); + poly.append( ::basegfx::B2DPoint( 0.0, height ) ); + poly.append( ::basegfx::B2DPoint( len + a, height ) ); + poly.append( ::basegfx::B2DPoint( len + a, 0.0 ) ); + poly.setClosed(true); + ::basegfx::B2DHomMatrix aTransform; + + if ((static_cast<sal_Int32>(sqrtArea2) & 1) == 1) + { + // odd line + aTransform = basegfx::utils::createTranslateB2DHomMatrix(0.0, -height); + aTransform.rotate( M_PI_2 + M_PI_4 ); + aTransform.translate( 1.0, edge ); + } + else + { + aTransform = basegfx::utils::createRotateB2DHomMatrix(-M_PI_4); + aTransform.translate( edge, 1.0 ); + } + poly.transform( aTransform ); + res.append(poly); + } + + return res; +} + +::basegfx::B2DPolyPolygon SnakeWipe::operator () ( double t ) +{ + ::basegfx::B2DPolyPolygon res; + if (m_diagonal) + { + if (t >= 0.5) { + res.append( calcHalfDiagonalSnake( 1.0, true ) ); + res.append( calcHalfDiagonalSnake( 2.0 * (t - 0.5), false ) ); + } + else + res.append( calcHalfDiagonalSnake( 2.0 * t, true ) ); + } + else + res = calcSnake(t); + + return m_flipOnYAxis ? flipOnYAxis(res) : res; +} + +::basegfx::B2DPolyPolygon ParallelSnakesWipe::operator () ( double t ) +{ + ::basegfx::B2DPolyPolygon res; + if (m_diagonal) + { + OSL_ASSERT( m_opposite ); + ::basegfx::B2DPolyPolygon half( + calcHalfDiagonalSnake( t, false /* out */ ) ); + // flip on x axis and rotate 90 degrees: + basegfx::B2DHomMatrix aTransform(basegfx::utils::createScaleB2DHomMatrix(1.0, -1.0)); + aTransform.translate( -0.5, 0.5 ); + aTransform.rotate( M_PI_2 ); + aTransform.translate( 0.5, 0.5 ); + half.transform( aTransform ); + half.flip(); + res.append( half ); + + // rotate 180 degrees: + aTransform = basegfx::utils::createTranslateB2DHomMatrix(-0.5, -0.5); + aTransform.rotate( M_PI ); + aTransform.translate( 0.5, 0.5 ); + half.transform( aTransform ); + res.append( half ); + } + else + { + ::basegfx::B2DPolyPolygon half( calcSnake( t / 2.0 ) ); + // rotate 90 degrees: + basegfx::B2DHomMatrix aTransform(basegfx::utils::createTranslateB2DHomMatrix(-0.5, -0.5)); + aTransform.rotate( M_PI_2 ); + aTransform.translate( 0.5, 0.5 ); + half.transform( aTransform ); + res.append( flipOnYAxis(half) ); + res.append( m_opposite ? flipOnXAxis(half) : half ); + } + + return m_flipOnYAxis ? flipOnYAxis(res) : res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/snakewipe.hxx b/slideshow/source/engine/transitions/snakewipe.hxx new file mode 100644 index 000000000..ec71f4f83 --- /dev/null +++ b/slideshow/source/engine/transitions/snakewipe.hxx @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_SNAKEWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_SNAKEWIPE_HXX + +#include "parametricpolypolygon.hxx" + + +namespace slideshow { +namespace internal { + +/// Generates a snake wipe: +class SnakeWipe : public ParametricPolyPolygon +{ +public: + SnakeWipe( sal_Int32 nElements, bool diagonal, bool flipOnYAxis ); + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; + +protected: + // topLeftHorizontal: + ::basegfx::B2DPolyPolygon calcSnake( double t ) const; + // topLeftDiagonal: + ::basegfx::B2DPolyPolygon calcHalfDiagonalSnake( double t, bool in ) const; + + const sal_Int32 m_sqrtElements; + const double m_elementEdge; + const bool m_diagonal; + const bool m_flipOnYAxis; +}; + +/// Generates a parallel snakes wipe: +class ParallelSnakesWipe : public SnakeWipe +{ +public: + ParallelSnakesWipe( sal_Int32 nElements, + bool diagonal, bool flipOnYAxis, bool opposite ) + : SnakeWipe( nElements, diagonal, flipOnYAxis ), + m_opposite( opposite ) + {} + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; +private: + const bool m_opposite; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_SNAKEWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/spiralwipe.cxx b/slideshow/source/engine/transitions/spiralwipe.cxx new file mode 100644 index 000000000..3d1dc0282 --- /dev/null +++ b/slideshow/source/engine/transitions/spiralwipe.cxx @@ -0,0 +1,120 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include "spiralwipe.hxx" +#include "transitiontools.hxx" + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/numeric/ftools.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + + +namespace slideshow::internal { + +SpiralWipe::SpiralWipe( sal_Int32 nElements, bool flipOnYAxis ) + : m_elements(nElements), + m_sqrtElements( static_cast<sal_Int32>( + sqrt( static_cast<double>(nElements) ) ) ), + m_flipOnYAxis(flipOnYAxis) +{ +} + +::basegfx::B2DPolyPolygon SpiralWipe::calcNegSpiral( double t ) const +{ + const double area = t * m_elements; + const double e = sqrt(area) / 2.0; + const sal_Int32 edge = static_cast<sal_Int32>(e) * 2; + + basegfx::B2DHomMatrix aTransform(basegfx::utils::createTranslateB2DHomMatrix(-0.5, -0.5)); + const double edge_ = ::basegfx::pruneScaleValue( + static_cast<double>(edge) / m_sqrtElements ); + aTransform.scale( edge_, edge_ ); + aTransform.translate( 0.5, 0.5 ); + ::basegfx::B2DPolygon poly( createUnitRect() ); + poly.transform( aTransform ); + ::basegfx::B2DPolyPolygon res(poly); + + if (! ::basegfx::fTools::equalZero( 1.0 - t )) { + const sal_Int32 edge1 = edge + 1; + sal_Int32 len = static_cast<sal_Int32>( (e - (edge /2)) * edge1 * 4 ); + double w = M_PI_2; + while (len > 0) { + const sal_Int32 alen = std::min(len, edge1); + len -= alen; + poly = createUnitRect(); + aTransform = basegfx::utils::createScaleB2DHomMatrix( + ::basegfx::pruneScaleValue( static_cast<double>(alen) / m_sqrtElements ), + ::basegfx::pruneScaleValue( 1.0 / m_sqrtElements ) ); + aTransform.translate( + - ::basegfx::pruneScaleValue( + static_cast<double>(edge / 2) / m_sqrtElements ), + ::basegfx::pruneScaleValue( + static_cast<double>(edge / 2) / m_sqrtElements ) ); + aTransform.rotate( w ); + w -= M_PI_2; + aTransform.translate( 0.5, 0.5 ); + poly.transform( aTransform ); + res.append(poly); + } + } + + return res; +} + +::basegfx::B2DPolyPolygon SpiralWipe::operator () ( double t ) +{ + ::basegfx::B2DPolyPolygon res( createUnitRect() ); + ::basegfx::B2DPolyPolygon innerSpiral( calcNegSpiral( 1.0 - t ) ); + innerSpiral.flip(); + res.append(innerSpiral); + return m_flipOnYAxis ? flipOnYAxis(res) : res; +} + +::basegfx::B2DPolyPolygon BoxSnakesWipe::operator () ( double t ) +{ + ::basegfx::B2DPolyPolygon res( createUnitRect() ); + ::basegfx::B2DPolyPolygon innerSpiral( calcNegSpiral( 1.0 - t ) ); + innerSpiral.flip(); + + if (m_fourBox) { + ::basegfx::B2DHomMatrix aTransform; + aTransform.scale( 0.5, 0.5 ); + innerSpiral.transform( aTransform ); + res.append(innerSpiral); + res.append( flipOnXAxis(innerSpiral) ); + innerSpiral = flipOnYAxis(innerSpiral); + res.append(innerSpiral); + res.append( flipOnXAxis(innerSpiral) ); + } + else { + ::basegfx::B2DHomMatrix aTransform; + aTransform.scale( 1.0, 0.5 ); + innerSpiral.transform( aTransform ); + res.append(innerSpiral); + res.append( flipOnXAxis(innerSpiral) ); + } + + return m_flipOnYAxis ? flipOnYAxis(res) : res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/spiralwipe.hxx b/slideshow/source/engine/transitions/spiralwipe.hxx new file mode 100644 index 000000000..fe89c0c8e --- /dev/null +++ b/slideshow/source/engine/transitions/spiralwipe.hxx @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_SPIRALWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_SPIRALWIPE_HXX + +#include "parametricpolypolygon.hxx" + + +namespace slideshow { +namespace internal { + +/// Generates a topLeftClockWise or +/// bottomLeftCounterClockWise (flipOnYAxis=true) spiral wipe: +class SpiralWipe : public ParametricPolyPolygon +{ +public: + SpiralWipe( sal_Int32 nElements, bool flipOnYAxis = false ); + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; +protected: + ::basegfx::B2DPolyPolygon calcNegSpiral( double t ) const; + + const sal_Int32 m_elements; + const sal_Int32 m_sqrtElements; + const bool m_flipOnYAxis; +}; + +/// Generates a twoBoxLeft or fourBoxHorizontal wipe: +class BoxSnakesWipe : public SpiralWipe +{ +public: + BoxSnakesWipe( sal_Int32 nElements, bool fourBox ) + : SpiralWipe(nElements), m_fourBox(fourBox) {} + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; +private: + const bool m_fourBox; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_SPIRALWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/sweepwipe.cxx b/slideshow/source/engine/transitions/sweepwipe.cxx new file mode 100644 index 000000000..e6fcb8c2d --- /dev/null +++ b/slideshow/source/engine/transitions/sweepwipe.cxx @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include "clockwipe.hxx" +#include "sweepwipe.hxx" +#include "transitiontools.hxx" + + +namespace slideshow::internal { + +::basegfx::B2DPolyPolygon SweepWipe::operator () ( double t ) +{ + t /= 2.0; + if (! m_center) + t /= 2.0; + if (!m_single && !m_oppositeVertical) + t /= 2.0; + + ::basegfx::B2DPolygon poly( ClockWipe::calcCenteredClock( 0.25 + t ) ); + ::basegfx::B2DHomMatrix aTransform; + + if (m_center) + { + aTransform = basegfx::utils::createTranslateB2DHomMatrix(0.5, 0.0); + poly.transform( aTransform ); + } + ::basegfx::B2DPolyPolygon res(poly); + + if (! m_single) + { + if (m_oppositeVertical) + { + aTransform = basegfx::utils::createScaleB2DHomMatrix(1.0, -1.0); + aTransform.translate( 0.0, 1.0 ); + poly.transform( aTransform ); + poly.flip(); + } + else + { + aTransform = basegfx::utils::createTranslateB2DHomMatrix(-0.5, -0.5); + aTransform.rotate( M_PI ); + aTransform.translate( 0.5, 0.5 ); + poly.transform( aTransform ); + } + res.append(poly); + } + + return m_flipOnYAxis ? flipOnYAxis(res) : res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/sweepwipe.hxx b/slideshow/source/engine/transitions/sweepwipe.hxx new file mode 100644 index 000000000..acc10e67e --- /dev/null +++ b/slideshow/source/engine/transitions/sweepwipe.hxx @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_SWEEPWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_SWEEPWIPE_HXX + +#include "parametricpolypolygon.hxx" + + +namespace slideshow { +namespace internal { + +class SweepWipe : public ParametricPolyPolygon +{ +public: + SweepWipe( bool center, bool single, + bool oppositeVertical, bool flipOnYAxis ) + : m_center(center), m_single(single), + m_oppositeVertical(oppositeVertical), m_flipOnYAxis(flipOnYAxis) + {} + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; +private: + const bool m_center, m_single, m_oppositeVertical, m_flipOnYAxis; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_SWEEPWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/transitionfactorytab.cxx b/slideshow/source/engine/transitions/transitionfactorytab.cxx new file mode 100644 index 000000000..6ec5a57f5 --- /dev/null +++ b/slideshow/source/engine/transitions/transitionfactorytab.cxx @@ -0,0 +1,2134 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <com/sun/star/animations/TransitionType.hpp> +#include <com/sun/star/animations/TransitionSubType.hpp> + +#include "transitionfactorytab.hxx" +#include <transitioninfo.hxx> +#include <tools.hxx> + +#include <algorithm> + +using namespace ::com::sun::star; + +namespace slideshow::internal { + +namespace { + +static const TransitionInfo lcl_transitionInfo[] = +{ + { + 0, + 0, + TransitionInfo::TRANSITION_INVALID, + 0.0, + 0.0, + 0.0, + TransitionInfo::ReverseMethod::Ignore, + false, + false + }, + { + // mapped to BarWipePolyPolygon: + animations::TransitionType::BARWIPE, + animations::TransitionSubType::LEFTTORIGHT, // (1) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + false, // 'out' by subtraction + false // scale isotropically to target size + }, + { + // mapped to BarWipePolyPolygon: + animations::TransitionType::BARWIPE, + animations::TransitionSubType::TOPTOBOTTOM, // (2) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + false, // 'out' by subtraction + false // scale isotropically to target size + }, + + { + // mapped to BarWipePolyPolygon(nBars=5): + animations::TransitionType::BLINDSWIPE, + animations::TransitionSubType::VERTICAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BarWipePolyPolygon(nBars=5): + animations::TransitionType::BLINDSWIPE, + animations::TransitionSubType::HORIZONTAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to BoxWipe: + animations::TransitionType::BOXWIPE, + animations::TransitionSubType::TOPLEFT, // (3) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, // possible via bottomRight + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BoxWipe: + animations::TransitionType::BOXWIPE, + animations::TransitionSubType::TOPRIGHT, // (4) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, // possible via bottomLeft + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BoxWipe: + animations::TransitionType::BOXWIPE, + animations::TransitionSubType::BOTTOMRIGHT, // (5) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, // possible via topLeft + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BoxWipe: + animations::TransitionType::BOXWIPE, + animations::TransitionSubType::BOTTOMLEFT, // (6) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, // possible via topRight + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BoxWipe: + animations::TransitionType::BOXWIPE, + animations::TransitionSubType::TOPCENTER, // (23) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BoxWipe: + animations::TransitionType::BOXWIPE, + animations::TransitionSubType::RIGHTCENTER, // (24) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BoxWipe: + animations::TransitionType::BOXWIPE, + animations::TransitionSubType::BOTTOMCENTER, // (25) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BoxWipe: + animations::TransitionType::BOXWIPE, + animations::TransitionSubType::LEFTCENTER, // (26) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to FourBoxWipe: + animations::TransitionType::FOURBOXWIPE, + animations::TransitionSubType::CORNERSIN, // (7) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FourBoxWipe: + animations::TransitionType::FOURBOXWIPE, + animations::TransitionSubType::CORNERSOUT, // (8) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to BarnDoorWipe: + animations::TransitionType::BARNDOORWIPE, + animations::TransitionSubType::VERTICAL, // (21) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BarnDoorWipe: + animations::TransitionType::BARNDOORWIPE, + animations::TransitionSubType::HORIZONTAL, // (22) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BarnDoorWipe: + animations::TransitionType::BARNDOORWIPE, + animations::TransitionSubType::DIAGONALBOTTOMLEFT, // (45) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 45.0, // rotation + M_SQRT2, // scaling + M_SQRT2, // scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BarnDoorWipe: + animations::TransitionType::BARNDOORWIPE, + animations::TransitionSubType::DIAGONALTOPLEFT, // (46) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -45.0, // rotation + M_SQRT2, // scaling + M_SQRT2, // scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to BarWipePolyPolygon: + animations::TransitionType::DIAGONALWIPE, + animations::TransitionSubType::TOPLEFT, // (41) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 45.0, // rotation + M_SQRT2, // scaling + M_SQRT2, // scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BarWipePolyPolygon: + animations::TransitionType::DIAGONALWIPE, + animations::TransitionSubType::TOPRIGHT, // (42) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 135.0, // rotation + M_SQRT2, // scaling + M_SQRT2, // scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + + { + animations::TransitionType::BOWTIEWIPE, + animations::TransitionSubType::VERTICAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::BOWTIEWIPE, + animations::TransitionSubType::HORIZONTAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to BarnDoorWipe (doubled=true): + animations::TransitionType::MISCDIAGONALWIPE, + animations::TransitionSubType::DOUBLEBARNDOOR, // (47) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 45.0, // rotation + M_SQRT2, // scaling + M_SQRT2, // scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to DoubleDiamondWipe: + animations::TransitionType::MISCDIAGONALWIPE, + animations::TransitionSubType::DOUBLEDIAMOND, // (48) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to VeeWipe: + animations::TransitionType::VEEWIPE, + animations::TransitionSubType::DOWN, // (61) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to VeeWipe: + animations::TransitionType::VEEWIPE, + animations::TransitionSubType::LEFT, // (62) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::VEEWIPE, + animations::TransitionSubType::UP, // (63) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::VEEWIPE, + animations::TransitionSubType::RIGHT, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + + { + animations::TransitionType::BARNVEEWIPE, + animations::TransitionSubType::TOP, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::BARNVEEWIPE, + animations::TransitionSubType::LEFT, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::BARNVEEWIPE, + animations::TransitionSubType::UP, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::BARNVEEWIPE, + animations::TransitionSubType::RIGHT, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to ZigZagWipe: + animations::TransitionType::ZIGZAGWIPE, + animations::TransitionSubType::LEFTTORIGHT, // (71) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to ZigZagWipe: + animations::TransitionType::ZIGZAGWIPE, + animations::TransitionSubType::TOPTOBOTTOM, // (72) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BarnZigZagWipe: + animations::TransitionType::BARNZIGZAGWIPE, + animations::TransitionSubType::VERTICAL, // (73) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BarnZigZagWipe: + animations::TransitionType::BARNZIGZAGWIPE, + animations::TransitionSubType::HORIZONTAL, // (74) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to IrisWipe: + animations::TransitionType::IRISWIPE, + animations::TransitionSubType::RECTANGLE, // (101) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to IrisWipe: + animations::TransitionType::IRISWIPE, + animations::TransitionSubType::DIAMOND, // (102) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 45.0, // rotation + M_SQRT2, // scaling + M_SQRT2, // scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + + { + // mapped to FigureWipe(triangle): + animations::TransitionType::TRIANGLEWIPE, + animations::TransitionSubType::UP, // (103) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FigureWipe(triangle): + animations::TransitionType::TRIANGLEWIPE, + animations::TransitionSubType::RIGHT, // (104) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FigureWipe(triangle): + animations::TransitionType::TRIANGLEWIPE, + animations::TransitionSubType::DOWN, // (105) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FigureWipe(triangle): + animations::TransitionType::TRIANGLEWIPE, + animations::TransitionSubType::LEFT, // (106) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 270.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to FigureWipe(arrowHead): + animations::TransitionType::ARROWHEADWIPE, + animations::TransitionSubType::UP, // (107) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FigureWipe(arrowHead): + animations::TransitionType::ARROWHEADWIPE, + animations::TransitionSubType::RIGHT, // (108) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FigureWipe(arrowHead): + animations::TransitionType::ARROWHEADWIPE, + animations::TransitionSubType::DOWN, // (109) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FigureWipe(arrowHead): + animations::TransitionType::ARROWHEADWIPE, + animations::TransitionSubType::LEFT, // (110) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 270.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to FigureWipe(pentagon): + animations::TransitionType::PENTAGONWIPE, + animations::TransitionSubType::UP, // (111) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FigureWipe(pentagon): + animations::TransitionType::PENTAGONWIPE, + animations::TransitionSubType::DOWN, // (112) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to FigureWipe(hexagon): + animations::TransitionType::HEXAGONWIPE, + animations::TransitionSubType::HORIZONTAL, // (113) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FigureWipe(hexagon): + animations::TransitionType::HEXAGONWIPE, + animations::TransitionSubType::VERTICAL, // (114) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to EllipseWipe: + animations::TransitionType::ELLIPSEWIPE, + animations::TransitionSubType::CIRCLE, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + true // scale isotropically to target size + }, + { + // mapped to EllipseWipe: + animations::TransitionType::ELLIPSEWIPE, + animations::TransitionSubType::HORIZONTAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to EllipseWipe: + animations::TransitionType::ELLIPSEWIPE, + animations::TransitionSubType::VERTICAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + true // scale isotropically to target size + }, + + + { + animations::TransitionType::EYEWIPE, + animations::TransitionSubType::HORIZONTAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::EYEWIPE, + animations::TransitionSubType::VERTICAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::ROUNDRECTWIPE, + animations::TransitionSubType::HORIZONTAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::ROUNDRECTWIPE, + animations::TransitionSubType::VERTICAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to FigureWipe(star, points=4): + animations::TransitionType::STARWIPE, + animations::TransitionSubType::FOURPOINT, // (127) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FigureWipe(star, points=5): + animations::TransitionType::STARWIPE, + animations::TransitionSubType::FIVEPOINT, // (128) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FigureWipe(star, points=6): + animations::TransitionType::STARWIPE, + animations::TransitionSubType::SIXPOINT, // (129) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + animations::TransitionType::MISCSHAPEWIPE, + animations::TransitionSubType::HEART, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::MISCSHAPEWIPE, + animations::TransitionSubType::KEYHOLE, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to ClockWipe: + animations::TransitionType::CLOCKWIPE, + animations::TransitionSubType::CLOCKWISETWELVE, // (201) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to ClockWipe: + animations::TransitionType::CLOCKWIPE, + animations::TransitionSubType::CLOCKWISETHREE, // (202) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Rotate180, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to ClockWipe: + animations::TransitionType::CLOCKWIPE, + animations::TransitionSubType::CLOCKWISESIX, // (203) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Rotate180, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to ClockWipe: + animations::TransitionType::CLOCKWIPE, + animations::TransitionSubType::CLOCKWISENINE, // (204) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 270.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Rotate180, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to PinWheelWipe: + animations::TransitionType::PINWHEELWIPE, + animations::TransitionSubType::ONEBLADE, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + true // scale isotropically to target size, like ppt + }, + { + // mapped to PinWheelWipe: + animations::TransitionType::PINWHEELWIPE, + animations::TransitionSubType::TWOBLADEVERTICAL, // (205) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + true // scale isotropically to target size, like ppt + }, + { + // mapped to PinWheelWipe: + animations::TransitionType::PINWHEELWIPE, + animations::TransitionSubType::TWOBLADEHORIZONTAL, // (206) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + true, // 'out' by parameter sweep inversion + true // scale isotropically to target size, like ppt + }, + { + // mapped to PinWheelWipe: + animations::TransitionType::PINWHEELWIPE, + animations::TransitionSubType::THREEBLADE, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + true // scale isotropically to target size, like ppt + }, + { + // mapped to PinWheelWipe: + animations::TransitionType::PINWHEELWIPE, + animations::TransitionSubType::FOURBLADE, // (207) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + true // scale isotropically to target size, like ppt + }, + { + // mapped to PinWheelWipe: + animations::TransitionType::PINWHEELWIPE, + animations::TransitionSubType::EIGHTBLADE, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + true // scale isotropically to target size, like ppt + }, + + { + // mapped to SweepWipe (center=true, single=true): + animations::TransitionType::SINGLESWEEPWIPE, + animations::TransitionSubType::CLOCKWISETOP, // (221) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SweepWipe (center=true, single=true): + animations::TransitionType::SINGLESWEEPWIPE, + animations::TransitionSubType::CLOCKWISERIGHT, // (222) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SweepWipe (center=true, single=true): + animations::TransitionType::SINGLESWEEPWIPE, + animations::TransitionSubType::CLOCKWISEBOTTOM, // (223) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SweepWipe (center=true, single=true): + animations::TransitionType::SINGLESWEEPWIPE, + animations::TransitionSubType::CLOCKWISELEFT, // (224) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 270.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SweepWipe (center=false, single=true): + animations::TransitionType::SINGLESWEEPWIPE, + animations::TransitionSubType::CLOCKWISETOPLEFT, // (241) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SweepWipe (center=false, single=true, flipOnYAxis=true): + animations::TransitionType::SINGLESWEEPWIPE, + animations::TransitionSubType::COUNTERCLOCKWISEBOTTOMLEFT, // (242) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SweepWipe (center=false, single=true): + animations::TransitionType::SINGLESWEEPWIPE, + animations::TransitionSubType::CLOCKWISEBOTTOMRIGHT, // (243) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SweepWipe (center=false, single=true, flipOnYAxis=true): + animations::TransitionType::SINGLESWEEPWIPE, + animations::TransitionSubType::COUNTERCLOCKWISETOPRIGHT, // (244) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to FanWipe(center=true): + animations::TransitionType::FANWIPE, + animations::TransitionSubType::CENTERTOP, // (211) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FanWipe(center=true): + animations::TransitionType::FANWIPE, + animations::TransitionSubType::CENTERRIGHT, // (212) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FanWipe: + animations::TransitionType::FANWIPE, + animations::TransitionSubType::TOP, // (231) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FanWipe: + animations::TransitionType::FANWIPE, + animations::TransitionSubType::RIGHT, // (232) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FanWipe: + animations::TransitionType::FANWIPE, + animations::TransitionSubType::BOTTOM, // (233) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FanWipe: + animations::TransitionType::FANWIPE, + animations::TransitionSubType::LEFT, // (234) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to FanWipe(center=true, single=false, fanIn=false): + animations::TransitionType::DOUBLEFANWIPE, + animations::TransitionSubType::FANOUTVERTICAL, // (213) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FanWipe(center=true, single=false, fanIn=false): + animations::TransitionType::DOUBLEFANWIPE, + animations::TransitionSubType::FANOUTHORIZONTAL, // (214) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FanWipe(center=true, single=false, fanIn=true): + animations::TransitionType::DOUBLEFANWIPE, + animations::TransitionSubType::FANINVERTICAL, // (235) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to FanWipe(center=true, single=false, fanIn=true): + animations::TransitionType::DOUBLEFANWIPE, + animations::TransitionSubType::FANINHORIZONTAL, // (236) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to SweepWipe (center=true, single=false): + animations::TransitionType::DOUBLESWEEPWIPE, + animations::TransitionSubType::PARALLELVERTICAL, // (225) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SweepWipe (center=true, single=false): + animations::TransitionType::DOUBLESWEEPWIPE, + animations::TransitionSubType::PARALLELDIAGONAL, // (226) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SweepWipe (center=true, single=false, + // oppositeVertical=true): + animations::TransitionType::DOUBLESWEEPWIPE, + animations::TransitionSubType::OPPOSITEVERTICAL, // (227) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SweepWipe (center=true, single=false, + // oppositeVertical=true): + animations::TransitionType::DOUBLESWEEPWIPE, + animations::TransitionSubType::OPPOSITEHORIZONTAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SweepWipe (center=false, single=false): + animations::TransitionType::DOUBLESWEEPWIPE, + animations::TransitionSubType::PARALLELDIAGONALTOPLEFT, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SweepWipe (center=false, single=false): + animations::TransitionType::DOUBLESWEEPWIPE, + animations::TransitionSubType::PARALLELDIAGONALBOTTOMLEFT, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + animations::TransitionType::SALOONDOORWIPE, + animations::TransitionSubType::TOP, // (251) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::SALOONDOORWIPE, + animations::TransitionSubType::LEFT, // (252) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::SALOONDOORWIPE, + animations::TransitionSubType::BOTTOM, // (253) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::SALOONDOORWIPE, + animations::TransitionSubType::RIGHT, // (254) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::WINDSHIELDWIPE, + animations::TransitionSubType::RIGHT, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::WINDSHIELDWIPE, + animations::TransitionSubType::UP, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::WINDSHIELDWIPE, + animations::TransitionSubType::VERTICAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::WINDSHIELDWIPE, + animations::TransitionSubType::HORIZONTAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to SnakeWipe: + animations::TransitionType::SNAKEWIPE, + animations::TransitionSubType::TOPLEFTHORIZONTAL, // (301) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Rotate180, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SnakeWipe(flipOnYAxis=true): + animations::TransitionType::SNAKEWIPE, + animations::TransitionSubType::TOPLEFTVERTICAL, // (302) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Rotate180, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SnakeWipe(diagonal=true): + animations::TransitionType::SNAKEWIPE, + animations::TransitionSubType::TOPLEFTDIAGONAL, // (303) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Rotate180, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SnakeWipe(diagonal=true, flipOnYAxis=true): + animations::TransitionType::SNAKEWIPE, + animations::TransitionSubType::TOPRIGHTDIAGONAL, // (304) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Rotate180, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SnakeWipe(diagonal=true): + animations::TransitionType::SNAKEWIPE, + animations::TransitionSubType::BOTTOMRIGHTDIAGONAL, // (305) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Rotate180, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SnakeWipe(diagonal=true, flipOnYAxis=true): + animations::TransitionType::SNAKEWIPE, + animations::TransitionSubType::BOTTOMLEFTDIAGONAL, // (306) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Rotate180, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to SpiralWipe: + animations::TransitionType::SPIRALWIPE, + animations::TransitionSubType::TOPLEFTCLOCKWISE, // (310) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SpiralWipe: + animations::TransitionType::SPIRALWIPE, + animations::TransitionSubType::TOPRIGHTCLOCKWISE, // (311) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SpiralWipe: + animations::TransitionType::SPIRALWIPE, + animations::TransitionSubType::BOTTOMRIGHTCLOCKWISE, // (312) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SpiralWipe: + animations::TransitionType::SPIRALWIPE, + animations::TransitionSubType::BOTTOMLEFTCLOCKWISE, // (313) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 270.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SpiralWipe(flipOnYAxis=true): + animations::TransitionType::SPIRALWIPE, + animations::TransitionSubType::TOPLEFTCOUNTERCLOCKWISE, // (314) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SpiralWipe(flipOnYAxis=true): + animations::TransitionType::SPIRALWIPE, + animations::TransitionSubType::TOPRIGHTCOUNTERCLOCKWISE, // (315) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SpiralWipe(flipOnYAxis=true): + animations::TransitionType::SPIRALWIPE, + animations::TransitionSubType::BOTTOMRIGHTCOUNTERCLOCKWISE, // (316) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 270.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to SpiralWipe(flipOnYAxis=true): + animations::TransitionType::SPIRALWIPE, + animations::TransitionSubType::BOTTOMLEFTCOUNTERCLOCKWISE, // (317) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::SubtractAndInvert, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to ParallelSnakesWipe: + animations::TransitionType::PARALLELSNAKESWIPE, + animations::TransitionSubType::VERTICALTOPSAME, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to ParallelSnakesWipe: + animations::TransitionType::PARALLELSNAKESWIPE, + animations::TransitionSubType::VERTICALBOTTOMSAME, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to ParallelSnakesWipe (opposite=true): + animations::TransitionType::PARALLELSNAKESWIPE, + animations::TransitionSubType::VERTICALTOPLEFTOPPOSITE, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to ParallelSnakesWipe (flipOnYAxis=true, opposite=true): + animations::TransitionType::PARALLELSNAKESWIPE, + animations::TransitionSubType::VERTICALBOTTOMLEFTOPPOSITE, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to ParallelSnakesWipe: + animations::TransitionType::PARALLELSNAKESWIPE, + animations::TransitionSubType::HORIZONTALLEFTSAME, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to ParallelSnakesWipe: + animations::TransitionType::PARALLELSNAKESWIPE, + animations::TransitionSubType::HORIZONTALRIGHTSAME, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to ParallelSnakesWipe (flipOnYAxis=true, opposite=true): + animations::TransitionType::PARALLELSNAKESWIPE, + animations::TransitionSubType::HORIZONTALTOPLEFTOPPOSITE, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to ParallelSnakesWipe (opposite=true): + animations::TransitionType::PARALLELSNAKESWIPE, + animations::TransitionSubType::HORIZONTALTOPRIGHTOPPOSITE, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to ParallelSnakesWipe (diagonal=true, opposite=true): + animations::TransitionType::PARALLELSNAKESWIPE, + animations::TransitionSubType::DIAGONALBOTTOMLEFTOPPOSITE, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to ParallelSnakesWipe (diagonal=true, opposite=true, + // flipOnYAxis=true): + animations::TransitionType::PARALLELSNAKESWIPE, + animations::TransitionSubType::DIAGONALTOPLEFTOPPOSITE, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to BoxSnakesWipe: + animations::TransitionType::BOXSNAKESWIPE, + animations::TransitionSubType::TWOBOXTOP, // (340) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BoxSnakesWipe: + animations::TransitionType::BOXSNAKESWIPE, + animations::TransitionSubType::TWOBOXBOTTOM, // (341) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BoxSnakesWipe: + animations::TransitionType::BOXSNAKESWIPE, + animations::TransitionSubType::TWOBOXLEFT, // (342) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BoxSnakesWipe: + animations::TransitionType::BOXSNAKESWIPE, + animations::TransitionSubType::TWOBOXRIGHT, // (343) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 180.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BoxSnakesWipe(fourBox=true): + animations::TransitionType::BOXSNAKESWIPE, + animations::TransitionSubType::FOURBOXVERTICAL, // (344) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to BoxSnakesWipe(fourBox=true): + animations::TransitionType::BOXSNAKESWIPE, + animations::TransitionSubType::FOURBOXHORIZONTAL, // (345) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to WaterfallWipe: + animations::TransitionType::WATERFALLWIPE, + animations::TransitionSubType::VERTICALLEFT, // (350) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Rotate180, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to WaterfallWipe (flipOnYAxis=true): + animations::TransitionType::WATERFALLWIPE, + animations::TransitionSubType::VERTICALRIGHT, // (351) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Rotate180, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to WaterfallWipe (flipOnYAxis=true): + animations::TransitionType::WATERFALLWIPE, + animations::TransitionSubType::HORIZONTALLEFT, // (352) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + -90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Rotate180, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to WaterfallWipe, flipOnYAxis=false: + animations::TransitionType::WATERFALLWIPE, + animations::TransitionSubType::HORIZONTALRIGHT, // (353) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Rotate180, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + animations::TransitionType::PUSHWIPE, + animations::TransitionSubType::FROMLEFT, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::PUSHWIPE, + animations::TransitionSubType::FROMTOP, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::PUSHWIPE, + animations::TransitionSubType::FROMRIGHT, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::PUSHWIPE, + animations::TransitionSubType::FROMBOTTOM, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::PUSHWIPE, + animations::TransitionSubType::FROMBOTTOMRIGHT, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::PUSHWIPE, + animations::TransitionSubType::FROMBOTTOMLEFT, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::PUSHWIPE, + animations::TransitionSubType::FROMTOPRIGHT, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::PUSHWIPE, + animations::TransitionSubType::FROMTOPLEFT, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::PUSHWIPE, + animations::TransitionSubType::COMBHORIZONTAL, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::PUSHWIPE, + animations::TransitionSubType::COMBVERTICAL, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::SLIDEWIPE, + animations::TransitionSubType::FROMLEFT, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, // special code for this transition + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::SLIDEWIPE, + animations::TransitionSubType::FROMTOP, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, // special code for this transition + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::SLIDEWIPE, + animations::TransitionSubType::FROMRIGHT, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, // special code for this transition + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::SLIDEWIPE, + animations::TransitionSubType::FROMBOTTOM, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, // special code for this transition + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::SLIDEWIPE, + animations::TransitionSubType::FROMBOTTOMRIGHT, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, // special code for this transition + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::SLIDEWIPE, + animations::TransitionSubType::FROMTOPRIGHT, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, // special code for this transition + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::SLIDEWIPE, + animations::TransitionSubType::FROMTOPLEFT, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, // special code for this transition + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::SLIDEWIPE, + animations::TransitionSubType::FROMBOTTOMLEFT, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, // special code for this transition + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::FADE, + animations::TransitionSubType::CROSSFADE, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::FADE, + animations::TransitionSubType::FADETOCOLOR, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::FADE, + animations::TransitionSubType::FADEFROMCOLOR, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + animations::TransitionType::FADE, + animations::TransitionSubType::FADEOVERCOLOR, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + // this is the cut through black fade (does not fade, but does a + // hard cut) + { + animations::TransitionType::BARWIPE, + animations::TransitionSubType::FADEOVERCOLOR, + TransitionInfo::TRANSITION_SPECIAL, + // TODO(F2): Setup parameters + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to RandomWipe: + animations::TransitionType::RANDOMBARWIPE, + animations::TransitionSubType::VERTICAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to RandomWipe: + animations::TransitionType::RANDOMBARWIPE, + animations::TransitionSubType::HORIZONTAL, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to CheckerBoard: + animations::TransitionType::CHECKERBOARDWIPE, + animations::TransitionSubType::DOWN, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 90.0, // rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipY, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + { + // mapped to CheckerBoard: + animations::TransitionType::CHECKERBOARDWIPE, + animations::TransitionSubType::ACROSS, // (default) + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::FlipX, + true, // 'out' by parameter sweep inversion + false // scale isotropically to target size + }, + + { + // mapped to RandomWipe: + animations::TransitionType::DISSOLVE, + animations::TransitionSubType::DEFAULT, + TransitionInfo::TRANSITION_CLIP_POLYPOLYGON, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + true // scale isotropically to target size + }, + + + // NOTE: This entry MUST be the last, to keep + // createSlideTransition() from infinite recursion. Because + // getRandomTransitionInfo() below will exclude the last entry of + // the table from the random number generation. + + { + // specially handled + animations::TransitionType::RANDOM, + animations::TransitionSubType::DEFAULT, + TransitionInfo::TRANSITION_SPECIAL, + 0.0, // no rotation + 1.0, // no scaling + 1.0, // no scaling + TransitionInfo::ReverseMethod::Ignore, + true, // 'out' by parameter sweep inversion + true // scale isotropically to target size + } + + // NOTE: DON'T add after this entry! See comment above! + +}; + +} // anon namespace + +const TransitionInfo* getTransitionInfo( + sal_Int16 nTransitionType, sal_Int16 nTransitionSubType ) +{ + static const TransitionInfo* pTableEnd = lcl_transitionInfo+ + SAL_N_ELEMENTS(lcl_transitionInfo); + + const TransitionInfo* pRes = ::std::find_if( + lcl_transitionInfo, pTableEnd, + TransitionInfo::Comparator( nTransitionType, + nTransitionSubType ) ); + if (pRes != pTableEnd) + return pRes; + else + return nullptr; +} + +const TransitionInfo* getRandomTransitionInfo() +{ + return lcl_transitionInfo + getRandomOrdinal( + SAL_N_ELEMENTS(lcl_transitionInfo) + - 1 /* exclude random transition at end of table */ ); +} + +} // namespace presentation + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/transitionfactorytab.hxx b/slideshow/source/engine/transitions/transitionfactorytab.hxx new file mode 100644 index 000000000..157dfec47 --- /dev/null +++ b/slideshow/source/engine/transitions/transitionfactorytab.hxx @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_TRANSITIONFACTORYTAB_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_TRANSITIONFACTORYTAB_HXX + +#include <sal/config.h> + +#include <sal/types.h> + +namespace slideshow::internal { + +struct TransitionInfo; + +TransitionInfo const * getTransitionInfo( + sal_Int16 nTransitionType, sal_Int16 nTransitionSubType); + +TransitionInfo const * getRandomTransitionInfo(); + +} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/transitiontools.cxx b/slideshow/source/engine/transitions/transitiontools.cxx new file mode 100644 index 000000000..e930028f6 --- /dev/null +++ b/slideshow/source/engine/transitions/transitiontools.cxx @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include "transitiontools.hxx" +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + + +namespace slideshow::internal { + +// TODO(Q2): Move this to basegfx +::basegfx::B2DPolygon createUnitRect() +{ + return ::basegfx::utils::createPolygonFromRect( + ::basegfx::B2DRectangle(0.0,0.0, + 1.0,1.0 ) ); +} + +::basegfx::B2DPolyPolygon flipOnYAxis( + ::basegfx::B2DPolyPolygon const & polypoly ) +{ + ::basegfx::B2DPolyPolygon res(polypoly); + res.transform(basegfx::utils::createScaleTranslateB2DHomMatrix(-1.0, 1.0, 1.0, 0.0)); + res.flip(); + return res; +} + +::basegfx::B2DPolyPolygon flipOnXAxis( + ::basegfx::B2DPolyPolygon const & polypoly ) +{ + ::basegfx::B2DPolyPolygon res(polypoly); + res.transform(basegfx::utils::createScaleTranslateB2DHomMatrix(1.0, -1.0, 0.0, 1.0)); + res.flip(); + return res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/transitiontools.hxx b/slideshow/source/engine/transitions/transitiontools.hxx new file mode 100644 index 000000000..53b3b4f46 --- /dev/null +++ b/slideshow/source/engine/transitions/transitiontools.hxx @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_TRANSITIONTOOLS_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_TRANSITIONTOOLS_HXX + +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> + + +namespace slideshow { +namespace internal { + +/// Create a unit rect. +::basegfx::B2DPolygon createUnitRect(); + +/// Flips on X-axis: +::basegfx::B2DPolyPolygon flipOnXAxis( + ::basegfx::B2DPolyPolygon const & polypoly ); + +/// Flips on Y-axis: +::basegfx::B2DPolyPolygon flipOnYAxis( + ::basegfx::B2DPolyPolygon const & polypoly ); + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_TRANSITIONTOOLS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/veewipe.cxx b/slideshow/source/engine/transitions/veewipe.cxx new file mode 100644 index 000000000..48fc4304b --- /dev/null +++ b/slideshow/source/engine/transitions/veewipe.cxx @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/point/b2dpoint.hxx> +#include "veewipe.hxx" + + +namespace slideshow::internal { + +::basegfx::B2DPolyPolygon VeeWipe::operator () ( double t ) +{ + ::basegfx::B2DPolygon poly; + poly.append( ::basegfx::B2DPoint( 0.0, -1.0 ) ); + const double d = ::basegfx::pruneScaleValue( 2.0 * t ); + poly.append( ::basegfx::B2DPoint( 0.0, d - 1.0 ) ); + poly.append( ::basegfx::B2DPoint( 0.5, d ) ); + poly.append( ::basegfx::B2DPoint( 1.0, d - 1.0 ) ); + poly.append( ::basegfx::B2DPoint( 1.0, -1.0 ) ); + poly.setClosed(true); + return ::basegfx::B2DPolyPolygon( poly ); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/veewipe.hxx b/slideshow/source/engine/transitions/veewipe.hxx new file mode 100644 index 000000000..537fd79e0 --- /dev/null +++ b/slideshow/source/engine/transitions/veewipe.hxx @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_VEEWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_VEEWIPE_HXX + +#include <basegfx/polygon/b2dpolypolygon.hxx> + +#include "parametricpolypolygon.hxx" + + +namespace slideshow { +namespace internal { + +/// Generate a vee wipe +class VeeWipe : public ParametricPolyPolygon +{ +public: + VeeWipe() {} + virtual ::basegfx::B2DPolyPolygon operator()( double x ) override; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_VEEWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/waterfallwipe.cxx b/slideshow/source/engine/transitions/waterfallwipe.cxx new file mode 100644 index 000000000..c3ef81ca5 --- /dev/null +++ b/slideshow/source/engine/transitions/waterfallwipe.cxx @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/numeric/ftools.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include "waterfallwipe.hxx" +#include "transitiontools.hxx" + + +namespace slideshow::internal { + +WaterfallWipe::WaterfallWipe( sal_Int32 nElements, bool flipOnYAxis ) + : m_flipOnYAxis( flipOnYAxis ) +{ + const sal_Int32 sqrtElements = static_cast<sal_Int32>( + sqrt( static_cast<double>(nElements) ) ); + const double elementEdge = 1.0 / sqrtElements; + m_waterfall.append( ::basegfx::B2DPoint( 0.0, -1.0 ) ); + for ( sal_Int32 pos = sqrtElements; pos--; ) + { + const sal_Int32 xPos = sqrtElements - pos - 1; + const double yPos = ::basegfx::pruneScaleValue( ((pos + 1) * elementEdge) - 1.0 ); + m_waterfall.append( ::basegfx::B2DPoint( + ::basegfx::pruneScaleValue( xPos * elementEdge ), + yPos ) ); + m_waterfall.append( ::basegfx::B2DPoint( + ::basegfx::pruneScaleValue( (xPos + 1) * elementEdge ), + yPos ) ); + } + m_waterfall.append( ::basegfx::B2DPoint( 1.0, -1.0 ) ); + m_waterfall.setClosed(true); +} + +::basegfx::B2DPolyPolygon WaterfallWipe::operator () ( double t ) +{ + ::basegfx::B2DPolygon poly( m_waterfall ); + poly.transform(basegfx::utils::createTranslateB2DHomMatrix(0.0, ::basegfx::pruneScaleValue(2.0 * t))); + poly.setB2DPoint( 0, ::basegfx::B2DPoint( 0.0, -1.0 ) ); + poly.setB2DPoint( poly.count()-1, ::basegfx::B2DPoint( 1.0, -1.0 ) ); + + return m_flipOnYAxis ? flipOnYAxis( ::basegfx::B2DPolyPolygon(poly) ) + : ::basegfx::B2DPolyPolygon(poly); +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/waterfallwipe.hxx b/slideshow/source/engine/transitions/waterfallwipe.hxx new file mode 100644 index 000000000..6f397058c --- /dev/null +++ b/slideshow/source/engine/transitions/waterfallwipe.hxx @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_WATERFALLWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_WATERFALLWIPE_HXX + +#include "parametricpolypolygon.hxx" +#include <basegfx/polygon/b2dpolygon.hxx> + + +namespace slideshow { +namespace internal { + +/// Generate a vertical left waterfall wipe +class WaterfallWipe : public ParametricPolyPolygon +{ +public: + WaterfallWipe( sal_Int32 nElements, bool flipOnYAxis ); + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; +private: + bool m_flipOnYAxis; + ::basegfx::B2DPolygon m_waterfall; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_WATERFALLWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/zigzagwipe.cxx b/slideshow/source/engine/transitions/zigzagwipe.cxx new file mode 100644 index 000000000..9b1f14221 --- /dev/null +++ b/slideshow/source/engine/transitions/zigzagwipe.cxx @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + + +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include "transitiontools.hxx" +#include "zigzagwipe.hxx" + + +namespace slideshow::internal { + +ZigZagWipe::ZigZagWipe( sal_Int32 nZigs ) : m_zigEdge( 1.0 / nZigs ) +{ + const double d = m_zigEdge; + const double d2 = d / 2.0; + m_stdZigZag.append( ::basegfx::B2DPoint( -1.0 - d, -d ) ); + m_stdZigZag.append( ::basegfx::B2DPoint( -1.0 - d, 1.0 + d ) ); + m_stdZigZag.append( ::basegfx::B2DPoint( -d, 1.0 + d ) ); + for ( sal_Int32 pos = nZigs + 2; pos--; ) { + m_stdZigZag.append( ::basegfx::B2DPoint( 0.0, ((pos - 1) * d) + d2 ) ); + m_stdZigZag.append( ::basegfx::B2DPoint( -d, (pos - 1) * d ) ); + } + m_stdZigZag.setClosed(true); +} + +::basegfx::B2DPolyPolygon ZigZagWipe::operator () ( double t ) +{ + ::basegfx::B2DPolyPolygon res(m_stdZigZag); + res.transform(basegfx::utils::createTranslateB2DHomMatrix((1.0 + m_zigEdge) * t, 0.0)); + return res; +} + +::basegfx::B2DPolyPolygon BarnZigZagWipe::operator () ( double t ) +{ + ::basegfx::B2DPolyPolygon res( createUnitRect() ); + ::basegfx::B2DPolygon poly( m_stdZigZag ); + poly.flip(); + basegfx::B2DHomMatrix aTransform(basegfx::utils::createTranslateB2DHomMatrix( + (1.0 + m_zigEdge) * (1.0 - t) / 2.0, 0.0)); + poly.transform( aTransform ); + res.append( poly ); + aTransform.scale( -1.0, 1.0 ); + aTransform.translate( 1.0, m_zigEdge / 2.0 ); + poly = m_stdZigZag; + poly.transform( aTransform ); + res.append( poly ); + return res; +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/transitions/zigzagwipe.hxx b/slideshow/source/engine/transitions/zigzagwipe.hxx new file mode 100644 index 000000000..ca927ba44 --- /dev/null +++ b/slideshow/source/engine/transitions/zigzagwipe.hxx @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * 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 . + */ + +#ifndef INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_ZIGZAGWIPE_HXX +#define INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_ZIGZAGWIPE_HXX + +#include "parametricpolypolygon.hxx" +#include <basegfx/polygon/b2dpolygon.hxx> + + +namespace slideshow { +namespace internal { + +/// Generates a left to right zigZag wipe: +class ZigZagWipe : public ParametricPolyPolygon +{ +public: + explicit ZigZagWipe( sal_Int32 nZigs ); + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; +protected: + const double m_zigEdge; + ::basegfx::B2DPolygon m_stdZigZag; +}; + +/// Generates a vertical barnZigZag wipe: +class BarnZigZagWipe : public ZigZagWipe +{ +public: + explicit BarnZigZagWipe( sal_Int32 nZigs ) : ZigZagWipe(nZigs) {} + virtual ::basegfx::B2DPolyPolygon operator () ( double t ) override; +}; + +} +} + +#endif // INCLUDED_SLIDESHOW_SOURCE_ENGINE_TRANSITIONS_ZIGZAGWIPE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |