xref: /trunk/main/svx/source/svdraw/gradtrns.cxx (revision 4d196ef4ae78ff6471489db4943d00e5f0bbde43)
1f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5f6e50924SAndrew Rist  * distributed with this work for additional information
6f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17f6e50924SAndrew Rist  * specific language governing permissions and limitations
18f6e50924SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20f6e50924SAndrew Rist  *************************************************************/
21f6e50924SAndrew Rist 
22f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include "gradtrns.hxx"
28cdf0e10cSrcweir #include <svx/svdobj.hxx>
29cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx>
30cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
31cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx>
32cdf0e10cSrcweir #include <vcl/salbtype.hxx> // FRound
33cdf0e10cSrcweir 
34cdf0e10cSrcweir 
GradToVec(GradTransGradient & rG,GradTransVector & rV,const SdrObject * pObj)35cdf0e10cSrcweir void GradTransformer::GradToVec(GradTransGradient& rG, GradTransVector& rV, const SdrObject* pObj)
36cdf0e10cSrcweir {
37cdf0e10cSrcweir     // handle start color
38cdf0e10cSrcweir     rV.aCol1 = rG.aGradient.GetStartColor();
39cdf0e10cSrcweir     if(100 != rG.aGradient.GetStartIntens())
40cdf0e10cSrcweir     {
41cdf0e10cSrcweir         const double fFact((double)rG.aGradient.GetStartIntens() / 100.0);
42cdf0e10cSrcweir         rV.aCol1 = Color(rV.aCol1.getBColor() * fFact);
43cdf0e10cSrcweir     }
44cdf0e10cSrcweir 
45cdf0e10cSrcweir     // handle end color
46cdf0e10cSrcweir     rV.aCol2 = rG.aGradient.GetEndColor();
47cdf0e10cSrcweir     if(100 != rG.aGradient.GetEndIntens())
48cdf0e10cSrcweir     {
49cdf0e10cSrcweir         const double fFact((double)rG.aGradient.GetEndIntens() / 100.0);
50cdf0e10cSrcweir         rV.aCol2 = Color(rV.aCol2.getBColor() * fFact);
51cdf0e10cSrcweir     }
52cdf0e10cSrcweir 
53cdf0e10cSrcweir     // calc the basic positions
54cdf0e10cSrcweir     const Rectangle aObjectSnapRectangle(pObj->GetSnapRect());
55cdf0e10cSrcweir     const basegfx::B2DRange aRange(aObjectSnapRectangle.Left(), aObjectSnapRectangle.Top(), aObjectSnapRectangle.Right(), aObjectSnapRectangle.Bottom());
56cdf0e10cSrcweir     const basegfx::B2DPoint aCenter(aRange.getCenter());
57cdf0e10cSrcweir     basegfx::B2DPoint aStartPos, aEndPos;
58cdf0e10cSrcweir 
59cdf0e10cSrcweir     switch(rG.aGradient.GetGradientStyle())
60cdf0e10cSrcweir     {
61cdf0e10cSrcweir         case XGRAD_LINEAR :
62cdf0e10cSrcweir         {
63cdf0e10cSrcweir             aStartPos = basegfx::B2DPoint(aCenter.getX(), aRange.getMinY());
64cdf0e10cSrcweir             aEndPos = basegfx::B2DPoint(aCenter.getX(), aRange.getMaximum().getY());
65cdf0e10cSrcweir 
66cdf0e10cSrcweir             if(rG.aGradient.GetBorder())
67cdf0e10cSrcweir             {
68cdf0e10cSrcweir                 basegfx::B2DVector aFullVec(aStartPos - aEndPos);
69cdf0e10cSrcweir                 const double fLen = (aFullVec.getLength() * (100.0 - (double)rG.aGradient.GetBorder())) / 100.0;
70cdf0e10cSrcweir                 aFullVec.normalize();
71cdf0e10cSrcweir                 aStartPos = aEndPos + (aFullVec * fLen);
72cdf0e10cSrcweir             }
73cdf0e10cSrcweir 
74cdf0e10cSrcweir             if(rG.aGradient.GetAngle())
75cdf0e10cSrcweir             {
76cdf0e10cSrcweir                 const double fAngle = (double)rG.aGradient.GetAngle() * (F_PI180 / 10.0);
77cdf0e10cSrcweir                 const basegfx::B2DHomMatrix aTransformation(basegfx::tools::createRotateAroundPoint(aCenter, -fAngle));
78cdf0e10cSrcweir 
79cdf0e10cSrcweir                 aStartPos *= aTransformation;
80cdf0e10cSrcweir                 aEndPos *= aTransformation;
81cdf0e10cSrcweir             }
82cdf0e10cSrcweir             break;
83cdf0e10cSrcweir         }
84cdf0e10cSrcweir         case XGRAD_AXIAL :
85cdf0e10cSrcweir         {
86cdf0e10cSrcweir             aStartPos = aCenter;
87cdf0e10cSrcweir             aEndPos = basegfx::B2DPoint(aCenter.getX(), aRange.getMaximum().getY());
88cdf0e10cSrcweir 
89cdf0e10cSrcweir             if(rG.aGradient.GetBorder())
90cdf0e10cSrcweir             {
91cdf0e10cSrcweir                 basegfx::B2DVector aFullVec(aEndPos - aStartPos);
92cdf0e10cSrcweir                 const double fLen = (aFullVec.getLength() * (100.0 - (double)rG.aGradient.GetBorder())) / 100.0;
93cdf0e10cSrcweir                 aFullVec.normalize();
94cdf0e10cSrcweir                 aEndPos = aStartPos + (aFullVec * fLen);
95cdf0e10cSrcweir             }
96cdf0e10cSrcweir 
97cdf0e10cSrcweir             if(rG.aGradient.GetAngle())
98cdf0e10cSrcweir             {
99cdf0e10cSrcweir                 const double fAngle = (double)rG.aGradient.GetAngle() * (F_PI180 / 10.0);
100cdf0e10cSrcweir                 const basegfx::B2DHomMatrix aTransformation(basegfx::tools::createRotateAroundPoint(aCenter, -fAngle));
101cdf0e10cSrcweir 
102cdf0e10cSrcweir                 aStartPos *= aTransformation;
103cdf0e10cSrcweir                 aEndPos *= aTransformation;
104cdf0e10cSrcweir             }
105cdf0e10cSrcweir             break;
106cdf0e10cSrcweir         }
107cdf0e10cSrcweir         case XGRAD_RADIAL :
108cdf0e10cSrcweir         case XGRAD_SQUARE :
109cdf0e10cSrcweir         {
110cdf0e10cSrcweir             aStartPos = basegfx::B2DPoint(aRange.getMinX(), aRange.getMaximum().getY());
111cdf0e10cSrcweir             aEndPos = basegfx::B2DPoint(aRange.getMinX(), aRange.getMinY());
112cdf0e10cSrcweir 
113cdf0e10cSrcweir             if(rG.aGradient.GetBorder())
114cdf0e10cSrcweir             {
115cdf0e10cSrcweir                 basegfx::B2DVector aFullVec(aStartPos - aEndPos);
116cdf0e10cSrcweir                 const double fLen = (aFullVec.getLength() * (100.0 - (double)rG.aGradient.GetBorder())) / 100.0;
117cdf0e10cSrcweir                 aFullVec.normalize();
118cdf0e10cSrcweir                 aStartPos = aEndPos + (aFullVec * fLen);
119cdf0e10cSrcweir             }
120cdf0e10cSrcweir 
121cdf0e10cSrcweir             if(rG.aGradient.GetAngle())
122cdf0e10cSrcweir             {
123cdf0e10cSrcweir                 const double fAngle = (double)rG.aGradient.GetAngle() * (F_PI180 / 10.0);
124cdf0e10cSrcweir                 const basegfx::B2DHomMatrix aTransformation(basegfx::tools::createRotateAroundPoint(aEndPos, -fAngle));
125cdf0e10cSrcweir 
126cdf0e10cSrcweir                 aStartPos *= aTransformation;
127cdf0e10cSrcweir                 aEndPos *= aTransformation;
128cdf0e10cSrcweir             }
129cdf0e10cSrcweir 
130cdf0e10cSrcweir             if(rG.aGradient.GetXOffset() || rG.aGradient.GetYOffset())
131cdf0e10cSrcweir             {
132cdf0e10cSrcweir                 basegfx::B2DPoint aOffset(
133cdf0e10cSrcweir                     (aRange.getWidth() * rG.aGradient.GetXOffset()) / 100.0,
134cdf0e10cSrcweir                     (aRange.getHeight() * rG.aGradient.GetYOffset()) / 100.0);
135cdf0e10cSrcweir 
136cdf0e10cSrcweir                 aStartPos += aOffset;
137cdf0e10cSrcweir                 aEndPos += aOffset;
138cdf0e10cSrcweir             }
139cdf0e10cSrcweir 
140cdf0e10cSrcweir             break;
141cdf0e10cSrcweir         }
142cdf0e10cSrcweir         case XGRAD_ELLIPTICAL :
143cdf0e10cSrcweir         case XGRAD_RECT :
144cdf0e10cSrcweir         {
145cdf0e10cSrcweir             aStartPos = basegfx::B2DPoint(aRange.getMinX(), aCenter.getY());
146cdf0e10cSrcweir             aEndPos = basegfx::B2DPoint(aRange.getMinX(), aRange.getMinY());
147cdf0e10cSrcweir 
148cdf0e10cSrcweir             if(rG.aGradient.GetBorder())
149cdf0e10cSrcweir             {
150cdf0e10cSrcweir                 basegfx::B2DVector aFullVec(aStartPos - aEndPos);
151cdf0e10cSrcweir                 const double fLen = (aFullVec.getLength() * (100.0 - (double)rG.aGradient.GetBorder())) / 100.0;
152cdf0e10cSrcweir                 aFullVec.normalize();
153cdf0e10cSrcweir                 aStartPos = aEndPos + (aFullVec * fLen);
154cdf0e10cSrcweir             }
155cdf0e10cSrcweir 
156cdf0e10cSrcweir             if(rG.aGradient.GetAngle())
157cdf0e10cSrcweir             {
158cdf0e10cSrcweir                 const double fAngle = (double)rG.aGradient.GetAngle() * (F_PI180 / 10.0);
159cdf0e10cSrcweir                 const basegfx::B2DHomMatrix aTransformation(basegfx::tools::createRotateAroundPoint(aEndPos, -fAngle));
160cdf0e10cSrcweir 
161cdf0e10cSrcweir                 aStartPos *= aTransformation;
162cdf0e10cSrcweir                 aEndPos *= aTransformation;
163cdf0e10cSrcweir             }
164cdf0e10cSrcweir 
165cdf0e10cSrcweir             if(rG.aGradient.GetXOffset() || rG.aGradient.GetYOffset())
166cdf0e10cSrcweir             {
167cdf0e10cSrcweir                 basegfx::B2DPoint aOffset(
168cdf0e10cSrcweir                     (aRange.getWidth() * rG.aGradient.GetXOffset()) / 100.0,
169cdf0e10cSrcweir                     (aRange.getHeight() * rG.aGradient.GetYOffset()) / 100.0);
170cdf0e10cSrcweir 
171cdf0e10cSrcweir                 aStartPos += aOffset;
172cdf0e10cSrcweir                 aEndPos += aOffset;
173cdf0e10cSrcweir             }
174cdf0e10cSrcweir 
175cdf0e10cSrcweir             break;
176cdf0e10cSrcweir         }
177cdf0e10cSrcweir     }
178cdf0e10cSrcweir 
179cdf0e10cSrcweir     // set values for vector positions now
180cdf0e10cSrcweir     rV.maPositionA = aStartPos;
181cdf0e10cSrcweir     rV.maPositionB = aEndPos;
182cdf0e10cSrcweir }
183cdf0e10cSrcweir 
184cdf0e10cSrcweir 
VecToGrad(GradTransVector & rV,GradTransGradient & rG,GradTransGradient & rGOld,const SdrObject * pObj,sal_Bool bMoveSingle,sal_Bool bMoveFirst)185cdf0e10cSrcweir void GradTransformer::VecToGrad(GradTransVector& rV, GradTransGradient& rG, GradTransGradient& rGOld, const SdrObject* pObj,
186cdf0e10cSrcweir     sal_Bool bMoveSingle, sal_Bool bMoveFirst)
187cdf0e10cSrcweir {
188cdf0e10cSrcweir     // fill old gradient to new gradient to have a base
189cdf0e10cSrcweir     rG = rGOld;
190cdf0e10cSrcweir 
191cdf0e10cSrcweir     // handle color changes
192cdf0e10cSrcweir     if(rV.aCol1 != rGOld.aGradient.GetStartColor())
193cdf0e10cSrcweir     {
194cdf0e10cSrcweir         rG.aGradient.SetStartColor(rV.aCol1);
195cdf0e10cSrcweir         rG.aGradient.SetStartIntens(100);
196cdf0e10cSrcweir     }
197cdf0e10cSrcweir     if(rV.aCol2 != rGOld.aGradient.GetEndColor())
198cdf0e10cSrcweir     {
199cdf0e10cSrcweir         rG.aGradient.SetEndColor(rV.aCol2);
200cdf0e10cSrcweir         rG.aGradient.SetEndIntens(100);
201cdf0e10cSrcweir     }
202cdf0e10cSrcweir 
203cdf0e10cSrcweir     // calc the basic positions
204cdf0e10cSrcweir     const Rectangle aObjectSnapRectangle(pObj->GetSnapRect());
205cdf0e10cSrcweir     const basegfx::B2DRange aRange(aObjectSnapRectangle.Left(), aObjectSnapRectangle.Top(), aObjectSnapRectangle.Right(), aObjectSnapRectangle.Bottom());
206cdf0e10cSrcweir     const basegfx::B2DPoint aCenter(aRange.getCenter());
207cdf0e10cSrcweir     basegfx::B2DPoint aStartPos(rV.maPositionA);
208cdf0e10cSrcweir     basegfx::B2DPoint aEndPos(rV.maPositionB);
209cdf0e10cSrcweir 
210cdf0e10cSrcweir     switch(rG.aGradient.GetGradientStyle())
211cdf0e10cSrcweir     {
212cdf0e10cSrcweir         case XGRAD_LINEAR :
213cdf0e10cSrcweir         {
214cdf0e10cSrcweir             if(!bMoveSingle || (bMoveSingle && !bMoveFirst))
215cdf0e10cSrcweir             {
216cdf0e10cSrcweir                 basegfx::B2DVector aFullVec(aEndPos - aStartPos);
217cdf0e10cSrcweir 
218cdf0e10cSrcweir                 if(bMoveSingle)
219cdf0e10cSrcweir                 {
220cdf0e10cSrcweir                     aFullVec = aEndPos - aCenter;
221cdf0e10cSrcweir                 }
222cdf0e10cSrcweir 
223cdf0e10cSrcweir                 aFullVec.normalize();
224cdf0e10cSrcweir 
225cdf0e10cSrcweir                 double fNewFullAngle(atan2(aFullVec.getY(), aFullVec.getX()));
226cdf0e10cSrcweir                 fNewFullAngle /= F_PI180;
227cdf0e10cSrcweir                 fNewFullAngle *= -10.0;
228cdf0e10cSrcweir                 fNewFullAngle += 900.0;
229cdf0e10cSrcweir 
230cdf0e10cSrcweir                 // clip
231cdf0e10cSrcweir                 while(fNewFullAngle < 0.0)
232cdf0e10cSrcweir                 {
233cdf0e10cSrcweir                     fNewFullAngle += 3600.0;
234cdf0e10cSrcweir                 }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir                 while(fNewFullAngle >= 3600.0)
237cdf0e10cSrcweir                 {
238cdf0e10cSrcweir                     fNewFullAngle -= 3600.0;
239cdf0e10cSrcweir                 }
240cdf0e10cSrcweir 
241cdf0e10cSrcweir                 // to int and set
242cdf0e10cSrcweir                 sal_Int32 nNewAngle = FRound(fNewFullAngle);
243cdf0e10cSrcweir 
244cdf0e10cSrcweir                 if(nNewAngle != rGOld.aGradient.GetAngle())
245cdf0e10cSrcweir                 {
246cdf0e10cSrcweir                     rG.aGradient.SetAngle(nNewAngle);
247cdf0e10cSrcweir                 }
248cdf0e10cSrcweir             }
249cdf0e10cSrcweir 
250cdf0e10cSrcweir             if(!bMoveSingle || (bMoveSingle && bMoveFirst))
251cdf0e10cSrcweir             {
252cdf0e10cSrcweir                 const basegfx::B2DVector aFullVec(aEndPos - aStartPos);
253cdf0e10cSrcweir                 const basegfx::B2DPoint aBottomLeft(aRange.getMinX(), aRange.getMaximum().getY());
254cdf0e10cSrcweir                 const basegfx::B2DPoint aTopLeft(aRange.getMinX(), aRange.getMinY());
255cdf0e10cSrcweir                 const basegfx::B2DVector aOldVec(aBottomLeft - aTopLeft);
256cdf0e10cSrcweir                 const double fFullLen(aFullVec.getLength());
257cdf0e10cSrcweir                 const double fOldLen(aOldVec.getLength());
258cdf0e10cSrcweir                 const double fNewBorder((fFullLen * 100.0) / fOldLen);
259cdf0e10cSrcweir                 sal_Int32 nNewBorder(100L - FRound(fNewBorder));
260cdf0e10cSrcweir 
261cdf0e10cSrcweir                 // clip
262cdf0e10cSrcweir                 if(nNewBorder < 0L)
263cdf0e10cSrcweir                 {
264cdf0e10cSrcweir                     nNewBorder = 0L;
265cdf0e10cSrcweir                 }
266cdf0e10cSrcweir 
267cdf0e10cSrcweir                 if(nNewBorder > 100L)
268cdf0e10cSrcweir                 {
269cdf0e10cSrcweir                     nNewBorder = 100L;
270cdf0e10cSrcweir                 }
271cdf0e10cSrcweir 
272cdf0e10cSrcweir                 // set
273cdf0e10cSrcweir                 if(nNewBorder != rG.aGradient.GetBorder())
274cdf0e10cSrcweir                 {
275cdf0e10cSrcweir                     rG.aGradient.SetBorder((sal_uInt16)nNewBorder);
276cdf0e10cSrcweir                 }
277cdf0e10cSrcweir             }
278cdf0e10cSrcweir 
279cdf0e10cSrcweir             break;
280cdf0e10cSrcweir         }
281cdf0e10cSrcweir         case XGRAD_AXIAL :
282cdf0e10cSrcweir         {
283cdf0e10cSrcweir             if(!bMoveSingle || (bMoveSingle && !bMoveFirst))
284cdf0e10cSrcweir             {
285cdf0e10cSrcweir                 basegfx::B2DVector aFullVec(aEndPos - aCenter);
286cdf0e10cSrcweir                 const basegfx::B2DVector aOldVec(basegfx::B2DPoint(aCenter.getX(), aRange.getMaximum().getY()) - aCenter);
287cdf0e10cSrcweir                 const double fFullLen(aFullVec.getLength());
288cdf0e10cSrcweir                 const double fOldLen(aOldVec.getLength());
289cdf0e10cSrcweir                 const double fNewBorder((fFullLen * 100.0) / fOldLen);
290cdf0e10cSrcweir                 sal_Int32 nNewBorder = 100 - FRound(fNewBorder);
291cdf0e10cSrcweir 
292cdf0e10cSrcweir                 // clip
293cdf0e10cSrcweir                 if(nNewBorder < 0L)
294cdf0e10cSrcweir                 {
295cdf0e10cSrcweir                     nNewBorder = 0L;
296cdf0e10cSrcweir                 }
297cdf0e10cSrcweir 
298cdf0e10cSrcweir                 if(nNewBorder > 100L)
299cdf0e10cSrcweir                 {
300cdf0e10cSrcweir                     nNewBorder = 100L;
301cdf0e10cSrcweir                 }
302cdf0e10cSrcweir 
303cdf0e10cSrcweir                 // set
304cdf0e10cSrcweir                 if(nNewBorder != rG.aGradient.GetBorder())
305cdf0e10cSrcweir                 {
306cdf0e10cSrcweir                     rG.aGradient.SetBorder((sal_uInt16)nNewBorder);
307cdf0e10cSrcweir                 }
308cdf0e10cSrcweir 
309cdf0e10cSrcweir                 aFullVec.normalize();
310cdf0e10cSrcweir                 double fNewFullAngle(atan2(aFullVec.getY(), aFullVec.getX()));
311cdf0e10cSrcweir                 fNewFullAngle /= F_PI180;
312cdf0e10cSrcweir                 fNewFullAngle *= -10.0;
313cdf0e10cSrcweir                 fNewFullAngle += 900.0;
314cdf0e10cSrcweir 
315cdf0e10cSrcweir                 // clip
316cdf0e10cSrcweir                 while(fNewFullAngle < 0.0)
317cdf0e10cSrcweir                 {
318cdf0e10cSrcweir                     fNewFullAngle += 3600.0;
319cdf0e10cSrcweir                 }
320cdf0e10cSrcweir 
321cdf0e10cSrcweir                 while(fNewFullAngle >= 3600.0)
322cdf0e10cSrcweir                 {
323cdf0e10cSrcweir                     fNewFullAngle -= 3600.0;
324cdf0e10cSrcweir                 }
325cdf0e10cSrcweir 
326cdf0e10cSrcweir                 // to int and set
327cdf0e10cSrcweir                 const sal_Int32 nNewAngle(FRound(fNewFullAngle));
328cdf0e10cSrcweir 
329cdf0e10cSrcweir                 if(nNewAngle != rGOld.aGradient.GetAngle())
330cdf0e10cSrcweir                 {
331cdf0e10cSrcweir                     rG.aGradient.SetAngle(nNewAngle);
332cdf0e10cSrcweir                 }
333cdf0e10cSrcweir             }
334cdf0e10cSrcweir 
335cdf0e10cSrcweir             break;
336cdf0e10cSrcweir         }
337cdf0e10cSrcweir         case XGRAD_RADIAL :
338cdf0e10cSrcweir         case XGRAD_SQUARE :
339cdf0e10cSrcweir         {
340cdf0e10cSrcweir             if(!bMoveSingle || (bMoveSingle && !bMoveFirst))
341cdf0e10cSrcweir             {
342cdf0e10cSrcweir                 const basegfx::B2DPoint aTopLeft(aRange.getMinX(), aRange.getMinY());
343cdf0e10cSrcweir                 const basegfx::B2DPoint aOffset(aEndPos - aTopLeft);
344cdf0e10cSrcweir                 sal_Int32 nNewXOffset(FRound((aOffset.getX() * 100.0) / aRange.getWidth()));
345cdf0e10cSrcweir                 sal_Int32 nNewYOffset(FRound((aOffset.getY() * 100.0) / aRange.getHeight()));
346cdf0e10cSrcweir 
347cdf0e10cSrcweir                 // clip
348cdf0e10cSrcweir                 if(nNewXOffset < 0L)
349cdf0e10cSrcweir                 {
350cdf0e10cSrcweir                     nNewXOffset = 0L;
351cdf0e10cSrcweir                 }
352cdf0e10cSrcweir 
353cdf0e10cSrcweir                 if(nNewXOffset > 100L)
354cdf0e10cSrcweir                 {
355cdf0e10cSrcweir                     nNewXOffset = 100L;
356cdf0e10cSrcweir                 }
357cdf0e10cSrcweir 
358cdf0e10cSrcweir                 if(nNewYOffset < 0L)
359cdf0e10cSrcweir                 {
360cdf0e10cSrcweir                     nNewYOffset = 0L;
361cdf0e10cSrcweir                 }
362cdf0e10cSrcweir 
363cdf0e10cSrcweir                 if(nNewYOffset > 100L)
364cdf0e10cSrcweir                 {
365cdf0e10cSrcweir                     nNewYOffset = 100L;
366cdf0e10cSrcweir                 }
367cdf0e10cSrcweir 
368cdf0e10cSrcweir                 rG.aGradient.SetXOffset((sal_uInt16)nNewXOffset);
369cdf0e10cSrcweir                 rG.aGradient.SetYOffset((sal_uInt16)nNewYOffset);
370cdf0e10cSrcweir 
371cdf0e10cSrcweir                 aStartPos -= aOffset;
372cdf0e10cSrcweir                 aEndPos -= aOffset;
373cdf0e10cSrcweir             }
374cdf0e10cSrcweir 
375cdf0e10cSrcweir             if(!bMoveSingle || (bMoveSingle && bMoveFirst))
376cdf0e10cSrcweir             {
377cdf0e10cSrcweir                 basegfx::B2DVector aFullVec(aStartPos - aEndPos);
378cdf0e10cSrcweir                 const basegfx::B2DPoint aBottomLeft(aRange.getMinX(), aRange.getMaximum().getY());
379cdf0e10cSrcweir                 const basegfx::B2DPoint aTopLeft(aRange.getMinX(), aRange.getMinY());
380cdf0e10cSrcweir                 const basegfx::B2DVector aOldVec(aBottomLeft - aTopLeft);
381cdf0e10cSrcweir                 const double fFullLen(aFullVec.getLength());
382cdf0e10cSrcweir                 const double fOldLen(aOldVec.getLength());
383cdf0e10cSrcweir                 const double fNewBorder((fFullLen * 100.0) / fOldLen);
384cdf0e10cSrcweir                 sal_Int32 nNewBorder(100L - FRound(fNewBorder));
385cdf0e10cSrcweir 
386cdf0e10cSrcweir                 // clip
387cdf0e10cSrcweir                 if(nNewBorder < 0L)
388cdf0e10cSrcweir                 {
389cdf0e10cSrcweir                     nNewBorder = 0L;
390cdf0e10cSrcweir                 }
391cdf0e10cSrcweir 
392cdf0e10cSrcweir                 if(nNewBorder > 100L)
393cdf0e10cSrcweir                 {
394cdf0e10cSrcweir                     nNewBorder = 100L;
395cdf0e10cSrcweir                 }
396cdf0e10cSrcweir 
397cdf0e10cSrcweir                 // set
398cdf0e10cSrcweir                 if(nNewBorder != rG.aGradient.GetBorder())
399cdf0e10cSrcweir                 {
400cdf0e10cSrcweir                     rG.aGradient.SetBorder((sal_uInt16)nNewBorder);
401cdf0e10cSrcweir                 }
402cdf0e10cSrcweir 
403cdf0e10cSrcweir                 // angle is not definitely necessary for these modes, but it makes
404cdf0e10cSrcweir                 // controlling more fun for the user
405cdf0e10cSrcweir                 aFullVec.normalize();
406cdf0e10cSrcweir                 double fNewFullAngle(atan2(aFullVec.getY(), aFullVec.getX()));
407cdf0e10cSrcweir                 fNewFullAngle /= F_PI180;
408cdf0e10cSrcweir                 fNewFullAngle *= -10.0;
409cdf0e10cSrcweir                 fNewFullAngle += 900.0;
410cdf0e10cSrcweir 
411cdf0e10cSrcweir                 // clip
412cdf0e10cSrcweir                 while(fNewFullAngle < 0.0)
413cdf0e10cSrcweir                 {
414cdf0e10cSrcweir                     fNewFullAngle += 3600.0;
415cdf0e10cSrcweir                 }
416cdf0e10cSrcweir 
417cdf0e10cSrcweir                 while(fNewFullAngle >= 3600.0)
418cdf0e10cSrcweir                 {
419cdf0e10cSrcweir                     fNewFullAngle -= 3600.0;
420cdf0e10cSrcweir                 }
421cdf0e10cSrcweir 
422cdf0e10cSrcweir                 // to int and set
423cdf0e10cSrcweir                 const sal_Int32 nNewAngle(FRound(fNewFullAngle));
424cdf0e10cSrcweir 
425cdf0e10cSrcweir                 if(nNewAngle != rGOld.aGradient.GetAngle())
426cdf0e10cSrcweir                 {
427cdf0e10cSrcweir                     rG.aGradient.SetAngle(nNewAngle);
428cdf0e10cSrcweir                 }
429cdf0e10cSrcweir             }
430cdf0e10cSrcweir 
431cdf0e10cSrcweir             break;
432cdf0e10cSrcweir         }
433cdf0e10cSrcweir         case XGRAD_ELLIPTICAL :
434cdf0e10cSrcweir         case XGRAD_RECT :
435cdf0e10cSrcweir         {
436cdf0e10cSrcweir             if(!bMoveSingle || (bMoveSingle && !bMoveFirst))
437cdf0e10cSrcweir             {
438cdf0e10cSrcweir                 const basegfx::B2DPoint aTopLeft(aRange.getMinX(), aRange.getMinY());
439cdf0e10cSrcweir                 const basegfx::B2DPoint aOffset(aEndPos - aTopLeft);
440cdf0e10cSrcweir                 sal_Int32 nNewXOffset(FRound((aOffset.getX() * 100.0) / aRange.getWidth()));
441cdf0e10cSrcweir                 sal_Int32 nNewYOffset(FRound((aOffset.getY() * 100.0) / aRange.getHeight()));
442cdf0e10cSrcweir 
443cdf0e10cSrcweir                 // clip
444cdf0e10cSrcweir                 if(nNewXOffset < 0L)
445cdf0e10cSrcweir                 {
446cdf0e10cSrcweir                     nNewXOffset = 0L;
447cdf0e10cSrcweir                 }
448cdf0e10cSrcweir 
449cdf0e10cSrcweir                 if(nNewXOffset > 100L)
450cdf0e10cSrcweir                 {
451cdf0e10cSrcweir                     nNewXOffset = 100L;
452cdf0e10cSrcweir                 }
453cdf0e10cSrcweir 
454cdf0e10cSrcweir                 if(nNewYOffset < 0L)
455cdf0e10cSrcweir                 {
456cdf0e10cSrcweir                     nNewYOffset = 0L;
457cdf0e10cSrcweir                 }
458cdf0e10cSrcweir 
459cdf0e10cSrcweir                 if(nNewYOffset > 100L)
460cdf0e10cSrcweir                 {
461cdf0e10cSrcweir                     nNewYOffset = 100L;
462cdf0e10cSrcweir                 }
463cdf0e10cSrcweir 
464cdf0e10cSrcweir                 rG.aGradient.SetXOffset((sal_uInt16)nNewXOffset);
465cdf0e10cSrcweir                 rG.aGradient.SetYOffset((sal_uInt16)nNewYOffset);
466cdf0e10cSrcweir 
467cdf0e10cSrcweir                 aStartPos -= aOffset;
468cdf0e10cSrcweir                 aEndPos -= aOffset;
469cdf0e10cSrcweir             }
470cdf0e10cSrcweir 
471cdf0e10cSrcweir             if(!bMoveSingle || (bMoveSingle && bMoveFirst))
472cdf0e10cSrcweir             {
473cdf0e10cSrcweir                 basegfx::B2DVector aFullVec(aStartPos - aEndPos);
474cdf0e10cSrcweir                 const basegfx::B2DPoint aTopLeft(aRange.getMinX(), aRange.getMinY());
475cdf0e10cSrcweir                 const basegfx::B2DPoint aCenterLeft(aRange.getMinX(), aRange.getHeight());
476cdf0e10cSrcweir                 const basegfx::B2DVector aOldVec(aCenterLeft - aTopLeft);
477cdf0e10cSrcweir                 const double fFullLen(aFullVec.getLength());
478cdf0e10cSrcweir                 const double fOldLen(aOldVec.getLength());
479cdf0e10cSrcweir                 const double fNewBorder((fFullLen * 100.0) / fOldLen);
480cdf0e10cSrcweir                 sal_Int32 nNewBorder(100L - FRound(fNewBorder));
481cdf0e10cSrcweir 
482cdf0e10cSrcweir                 // clip
483cdf0e10cSrcweir                 if(nNewBorder < 0L)
484cdf0e10cSrcweir                 {
485cdf0e10cSrcweir                     nNewBorder = 0L;
486cdf0e10cSrcweir                 }
487cdf0e10cSrcweir 
488cdf0e10cSrcweir                 if(nNewBorder > 100L)
489cdf0e10cSrcweir                 {
490cdf0e10cSrcweir                     nNewBorder = 100L;
491cdf0e10cSrcweir                 }
492cdf0e10cSrcweir 
493cdf0e10cSrcweir                 // set
494cdf0e10cSrcweir                 if(nNewBorder != rG.aGradient.GetBorder())
495cdf0e10cSrcweir                 {
496cdf0e10cSrcweir                     rG.aGradient.SetBorder((sal_uInt16)nNewBorder);
497cdf0e10cSrcweir                 }
498cdf0e10cSrcweir 
499cdf0e10cSrcweir                 // angle is not definitely necessary for these modes, but it makes
500cdf0e10cSrcweir                 // controlling more fun for the user
501cdf0e10cSrcweir                 aFullVec.normalize();
502cdf0e10cSrcweir                 double fNewFullAngle(atan2(aFullVec.getY(), aFullVec.getX()));
503cdf0e10cSrcweir                 fNewFullAngle /= F_PI180;
504cdf0e10cSrcweir                 fNewFullAngle *= -10.0;
505cdf0e10cSrcweir                 fNewFullAngle += 900.0;
506cdf0e10cSrcweir 
507cdf0e10cSrcweir                 // clip
508cdf0e10cSrcweir                 while(fNewFullAngle < 0.0)
509cdf0e10cSrcweir                 {
510cdf0e10cSrcweir                     fNewFullAngle += 3600.0;
511cdf0e10cSrcweir                 }
512cdf0e10cSrcweir 
513cdf0e10cSrcweir                 while(fNewFullAngle >= 3600.0)
514cdf0e10cSrcweir                 {
515cdf0e10cSrcweir                     fNewFullAngle -= 3600.0;
516cdf0e10cSrcweir                 }
517cdf0e10cSrcweir 
518cdf0e10cSrcweir                 // to int and set
519cdf0e10cSrcweir                 const sal_Int32 nNewAngle(FRound(fNewFullAngle));
520cdf0e10cSrcweir 
521cdf0e10cSrcweir                 if(nNewAngle != rGOld.aGradient.GetAngle())
522cdf0e10cSrcweir                 {
523cdf0e10cSrcweir                     rG.aGradient.SetAngle(nNewAngle);
524cdf0e10cSrcweir                 }
525cdf0e10cSrcweir             }
526cdf0e10cSrcweir 
527cdf0e10cSrcweir             break;
528cdf0e10cSrcweir         }
529cdf0e10cSrcweir     }
530cdf0e10cSrcweir }
531cdf0e10cSrcweir 
532*4d196ef4Smseidel /* vim: set noet sw=4 ts=4: */
533