Update ooo320-m1
[ooovba.git] / slideshow / source / engine / transitions / clippingfunctor.cxx
blob89ed7f22d362d7053ed5843f805db4ca8cb6da04
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: clippingfunctor.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
34 #include <canvas/debug.hxx>
35 #include <tools/diagnose_ex.h>
36 #include "clippingfunctor.hxx"
37 #include "transitiontools.hxx"
39 #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
40 #include <basegfx/polygon/b2dpolygonclipper.hxx>
41 #include <basegfx/polygon/b2dpolygontools.hxx>
42 #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
44 namespace slideshow
46 namespace internal
48 ClippingFunctor::ClippingFunctor(const ParametricPolyPolygonSharedPtr& rPolygon,
49 const TransitionInfo& rTransitionInfo,
50 bool bDirectionForward,
51 bool bModeIn ) :
52 mpParametricPoly( rPolygon ),
53 maStaticTransformation(),
54 // AW: Not needed
55 // maBackgroundRect( createUnitRect() ),
56 mbForwardParameterSweep( true ),
57 mbSubtractPolygon( false ),
58 mbScaleIsotrophically( rTransitionInfo.mbScaleIsotrophically ),
59 mbFlip(false)
61 ENSURE_OR_THROW( rPolygon,
62 "ClippingFunctor::ClippingFunctor(): Invalid parametric polygon" );
64 // maBackgroundRect serves as the minuent when
65 // subtracting a given clip polygon from the
66 // background. To speed up the clipper algo, avoid
67 // actual intersections of the generated
68 // poly-polygon with the minuent - i.e. choose the
69 // polygon to subtract from sufficiently large.
71 // blow up unit rect to (-1,-1),(2,2)
72 // AW: Not needed, just use range
73 // ::basegfx::B2DHomMatrix aMatrix;
74 // aMatrix.scale(3.0,3.0);
75 // aMatrix.translate(-1.0,-1.0);
76 // maBackgroundRect.transform( aMatrix );
78 // extract modification info from maTransitionInfo
79 // -----------------------------------------------
81 // perform general transformations _before_ the reverse
82 // mode changes. This allows the Transition table to be
83 // filled more constitently (otherwise, when e.g. rotating
84 // a clip 90 degrees, the REVERSEMETHOD_FLIP_X becomes
85 // REVERSEMETHOD_FLIP_Y instead)
86 if (rTransitionInfo.mnRotationAngle != 0.0 ||
87 rTransitionInfo.mnScaleX != 1.0 ||
88 rTransitionInfo.mnScaleY != 1.0)
90 maStaticTransformation.translate( -0.5, -0.5 );
91 // apply further transformations:
92 if (rTransitionInfo.mnRotationAngle != 0.0)
94 maStaticTransformation.rotate(
95 basegfx::deg2rad(rTransitionInfo.mnRotationAngle) );
97 if (rTransitionInfo.mnScaleX != 1.0 ||
98 rTransitionInfo.mnScaleY != 1.0)
100 maStaticTransformation.scale(
101 rTransitionInfo.mnScaleX,
102 rTransitionInfo.mnScaleY );
104 maStaticTransformation.translate( 0.5, 0.5 );
107 if( !bDirectionForward )
109 // Client has requested reversed
110 // direction. Apply TransitionInfo's choice
111 // for that
112 switch( rTransitionInfo.meReverseMethod )
114 default:
115 ENSURE_OR_THROW(
116 false,
117 "TransitionFactory::TransitionFactory(): Unexpected reverse method" );
118 break;
120 case TransitionInfo::REVERSEMETHOD_IGNORE:
121 break;
123 case TransitionInfo::REVERSEMETHOD_INVERT_SWEEP:
124 mbForwardParameterSweep = !mbForwardParameterSweep;
125 break;
127 case TransitionInfo::REVERSEMETHOD_SUBTRACT_POLYGON:
128 mbSubtractPolygon = !mbSubtractPolygon;
129 break;
131 case TransitionInfo::REVERSEMETHOD_SUBTRACT_AND_INVERT:
132 mbForwardParameterSweep = !mbForwardParameterSweep;
133 mbSubtractPolygon = !mbSubtractPolygon;
134 break;
136 case TransitionInfo::REVERSEMETHOD_ROTATE_180:
137 maStaticTransformation.translate( -0.5, -0.5 );
138 maStaticTransformation.rotate( M_PI );
139 maStaticTransformation.translate( 0.5, 0.5 );
140 break;
142 case TransitionInfo::REVERSEMETHOD_FLIP_X:
143 maStaticTransformation.scale( -1.0, 1.0 );
144 maStaticTransformation.translate( 1.0, 0.0 );
145 mbFlip = true;
146 break;
148 case TransitionInfo::REVERSEMETHOD_FLIP_Y:
149 maStaticTransformation.scale( 1.0, -1.0 );
150 maStaticTransformation.translate( 0.0, 1.0 );
151 mbFlip = true;
152 break;
156 if( !bModeIn )
158 // client has requested 'out' mode. Apply
159 // TransitionInfo's method of choice
160 if( rTransitionInfo.mbOutInvertsSweep )
161 mbForwardParameterSweep = !mbForwardParameterSweep;
162 else
163 mbSubtractPolygon = !mbSubtractPolygon;
167 ::basegfx::B2DPolyPolygon ClippingFunctor::operator()( double nValue,
168 const ::basegfx::B2DSize& rTargetSize )
170 // modify clip polygon according to static
171 // transformation plus current shape size
172 ::basegfx::B2DHomMatrix aMatrix( maStaticTransformation );
174 // retrieve current clip polygon
175 ::basegfx::B2DPolyPolygon aClipPoly = (*mpParametricPoly)(
176 mbForwardParameterSweep ? nValue : 1.0 - nValue );
178 // TODO(Q4): workaround here, better be fixed in cppcanvas
179 if (aClipPoly.count() == 0)
180 aClipPoly.append( basegfx::B2DPolygon() );
182 if (mbFlip)
183 aClipPoly.flip();
185 // currently, clipper cannot cope with curves. Subdivide first
186 // AW: Should be no longer necessary; clipping tools are now bezier-safe
187 // if( aClipPoly.areControlPointsUsed() )
188 // aClipPoly = ::basegfx::tools::adaptiveSubdivideByAngle(aClipPoly);
190 if( mbSubtractPolygon )
192 // subtract given polygon from background
193 // rect. Do that before any transformations.
195 // calc maBackgroundRect \ aClipPoly
196 // =================================
198 // AW: Simplified
199 // use a range with fixed size (-1,-1),(2,2)
200 const basegfx::B2DRange aBackgroundRange(-1, -1, 2, 2);
201 const basegfx::B2DRange aClipPolyRange(aClipPoly.getB2DRange());
203 if(aBackgroundRange.isInside(aClipPolyRange))
205 // combine polygons; make the clip polygon the hole
206 aClipPoly = ::basegfx::tools::correctOrientations(aClipPoly);
207 aClipPoly.flip();
208 aClipPoly.insert(0, basegfx::tools::createPolygonFromRect(aBackgroundRange));
210 else
212 // when not completely inside aBackgroundRange clipping is needed
213 // substract aClipPoly from aBackgroundRange
214 const basegfx::B2DPolyPolygon aBackgroundPolyPoly(basegfx::tools::createPolygonFromRect(aBackgroundRange));
215 aClipPoly = basegfx::tools::solvePolygonOperationDiff(aBackgroundPolyPoly, aClipPoly);
219 // scale polygon up to current shape size
220 if( mbScaleIsotrophically )
222 const double nScale( ::std::max( rTargetSize.getX(),
223 rTargetSize.getY() ) );
224 aMatrix.scale( nScale, nScale );
225 aMatrix.translate( -(nScale-rTargetSize.getX())/2.0,
226 -(nScale-rTargetSize.getY())/2.0 );
228 else
230 aMatrix.scale( rTargetSize.getX(),
231 rTargetSize.getY() );
234 // apply cumulative transformation to clip polygon
235 aClipPoly.transform( aMatrix );
237 return aClipPoly;