xref: /trunk/main/drawinglayer/source/texture/texture.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_drawinglayer.hxx"
30 
31 #include <drawinglayer/texture/texture.hxx>
32 #include <basegfx/numeric/ftools.hxx>
33 #include <basegfx/tools/gradienttools.hxx>
34 #include <basegfx/matrix/b2dhommatrixtools.hxx>
35 
36 //////////////////////////////////////////////////////////////////////////////
37 
38 namespace drawinglayer
39 {
40     namespace texture
41     {
42         GeoTexSvx::GeoTexSvx()
43         {
44         }
45 
46         GeoTexSvx::~GeoTexSvx()
47         {
48         }
49 
50         bool GeoTexSvx::operator==(const GeoTexSvx& /*rGeoTexSvx*/) const
51         {
52             // default implementation says yes (no data -> no difference)
53             return true;
54         }
55 
56         void GeoTexSvx::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& /*rMatrices*/)
57         {
58             // default implementation does nothing
59         }
60 
61         void GeoTexSvx::modifyBColor(const basegfx::B2DPoint& /*rUV*/, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
62         {
63             // base implementation creates random color (for testing only, may also be pure virtual)
64             rBColor.setRed((rand() & 0x7fff) / 32767.0);
65             rBColor.setGreen((rand() & 0x7fff) / 32767.0);
66             rBColor.setBlue((rand() & 0x7fff) / 32767.0);
67         }
68 
69         void GeoTexSvx::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
70         {
71             // base implementation uses inverse of luminance of solved color (for testing only, may also be pure virtual)
72             basegfx::BColor aBaseColor;
73             modifyBColor(rUV, aBaseColor, rfOpacity);
74             rfOpacity = 1.0 - aBaseColor.luminance();
75         }
76     } // end of namespace texture
77 } // end of namespace drawinglayer
78 
79 //////////////////////////////////////////////////////////////////////////////
80 
81 namespace drawinglayer
82 {
83     namespace texture
84     {
85         void GeoTexSvxGradient::impAppendMatrix(::std::vector< basegfx::B2DHomMatrix >& rMatrices, const basegfx::B2DRange& rRange)
86         {
87             basegfx::B2DHomMatrix aNew;
88             aNew.set(0, 0, rRange.getWidth());
89             aNew.set(1, 1, rRange.getHeight());
90             aNew.set(0, 2, rRange.getMinX());
91             aNew.set(1, 2, rRange.getMinY());
92             rMatrices.push_back(maGradientInfo.maTextureTransform * aNew);
93         }
94 
95         void GeoTexSvxGradient::impAppendColorsRadial(::std::vector< basegfx::BColor >& rColors)
96         {
97             if(maGradientInfo.mnSteps)
98             {
99                 rColors.push_back(maStart);
100 
101                 for(sal_uInt32 a(1L); a < maGradientInfo.mnSteps - 1L; a++)
102                 {
103                     rColors.push_back(interpolate(maStart, maEnd, (double)a / (double)maGradientInfo.mnSteps));
104                 }
105 
106                 rColors.push_back(maEnd);
107             }
108         }
109 
110         GeoTexSvxGradient::GeoTexSvxGradient(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder)
111         :   maTargetRange(rTargetRange),
112             maStart(rStart),
113             maEnd(rEnd),
114             mfBorder(fBorder)
115         {
116             maGradientInfo.mnSteps = nSteps;
117             maGradientInfo.mfAspectRatio = 1.0;
118         }
119 
120         GeoTexSvxGradient::~GeoTexSvxGradient()
121         {
122         }
123 
124         bool GeoTexSvxGradient::operator==(const GeoTexSvx& rGeoTexSvx) const
125         {
126             const GeoTexSvxGradient* pCompare = dynamic_cast< const GeoTexSvxGradient* >(&rGeoTexSvx);
127             return (pCompare
128                 && maGradientInfo.maTextureTransform == pCompare->maGradientInfo.maTextureTransform
129                 && maTargetRange == pCompare->maTargetRange
130                 && maGradientInfo.mnSteps == pCompare->maGradientInfo.mnSteps
131                 && maGradientInfo.mfAspectRatio == pCompare->maGradientInfo.mfAspectRatio
132                 && mfBorder == pCompare->mfBorder);
133         }
134     } // end of namespace texture
135 } // end of namespace drawinglayer
136 
137 //////////////////////////////////////////////////////////////////////////////
138 
139 namespace drawinglayer
140 {
141     namespace texture
142     {
143         GeoTexSvxGradientLinear::GeoTexSvxGradientLinear(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fAngle)
144         :   GeoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
145         {
146             basegfx::tools::createLinearODFGradientInfo(maGradientInfo,
147                                                         rTargetRange,
148                                                         nSteps,
149                                                         fBorder,
150                                                         fAngle);
151         }
152 
153         GeoTexSvxGradientLinear::~GeoTexSvxGradientLinear()
154         {
155         }
156 
157         void GeoTexSvxGradientLinear::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
158         {
159             if(maGradientInfo.mnSteps)
160             {
161                 const double fStripeWidth(1.0 / maGradientInfo.mnSteps);
162                 for(sal_uInt32 a(1L); a < maGradientInfo.mnSteps; a++)
163                 {
164                     const basegfx::B2DRange aRect(0.0, fStripeWidth * a, 1.0, 1.0);
165                     impAppendMatrix(rMatrices, aRect);
166                 }
167             }
168         }
169 
170         void GeoTexSvxGradientLinear::appendColors(::std::vector< basegfx::BColor >& rColors)
171         {
172             if(maGradientInfo.mnSteps)
173             {
174                 rColors.push_back(maStart);
175 
176                 for(sal_uInt32 a(1L); a < maGradientInfo.mnSteps; a++)
177                 {
178                     rColors.push_back(interpolate(maStart, maEnd, (double)a / (double)(maGradientInfo.mnSteps + 1L)));
179                 }
180             }
181         }
182 
183         void GeoTexSvxGradientLinear::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
184         {
185             const double fScaler(basegfx::tools::getLinearGradientAlpha(rUV, maGradientInfo));
186 
187             rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
188         }
189     } // end of namespace texture
190 } // end of namespace drawinglayer
191 
192 //////////////////////////////////////////////////////////////////////////////
193 
194 namespace drawinglayer
195 {
196     namespace texture
197     {
198         GeoTexSvxGradientAxial::GeoTexSvxGradientAxial(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fAngle)
199         :   GeoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
200         {
201             basegfx::tools::createAxialODFGradientInfo(maGradientInfo,
202                                                        rTargetRange,
203                                                        nSteps,
204                                                        fBorder,
205                                                        fAngle);
206         }
207 
208         GeoTexSvxGradientAxial::~GeoTexSvxGradientAxial()
209         {
210         }
211 
212         void GeoTexSvxGradientAxial::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
213         {
214             if(maGradientInfo.mnSteps)
215             {
216                 const double fStripeWidth=1.0 / (maGradientInfo.mnSteps - 1L);
217                 for(sal_uInt32 a(maGradientInfo.mnSteps-1L); a != 0; a--)
218                 {
219                     const basegfx::B2DRange aRect(0, 0, 1.0, fStripeWidth * a);
220                     impAppendMatrix(rMatrices, aRect);
221                 }
222             }
223         }
224 
225         void GeoTexSvxGradientAxial::appendColors(::std::vector< basegfx::BColor >& rColors)
226         {
227             if(maGradientInfo.mnSteps)
228             {
229                 rColors.push_back(maEnd);
230 
231                 for(sal_uInt32 a(1L); a < maGradientInfo.mnSteps; a++)
232                 {
233                     rColors.push_back(interpolate(maEnd, maStart, (double)a / (double)maGradientInfo.mnSteps));
234                 }
235             }
236         }
237 
238         void GeoTexSvxGradientAxial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
239         {
240             const double fScaler(basegfx::tools::getAxialGradientAlpha(rUV, maGradientInfo));
241 
242             rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
243         }
244     } // end of namespace texture
245 } // end of namespace drawinglayer
246 
247 //////////////////////////////////////////////////////////////////////////////
248 
249 namespace drawinglayer
250 {
251     namespace texture
252     {
253         GeoTexSvxGradientRadial::GeoTexSvxGradientRadial(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY)
254         :   GeoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
255         {
256             basegfx::tools::createRadialODFGradientInfo(maGradientInfo,
257                                                         rTargetRange,
258                                                         basegfx::B2DVector(fOffsetX,fOffsetY),
259                                                         nSteps,
260                                                         fBorder);
261         }
262 
263         GeoTexSvxGradientRadial::~GeoTexSvxGradientRadial()
264         {
265         }
266 
267         void GeoTexSvxGradientRadial::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
268         {
269             if(maGradientInfo.mnSteps)
270             {
271                 const double fStepSize=1.0 / maGradientInfo.mnSteps;
272                 for(sal_uInt32 a(maGradientInfo.mnSteps-1L); a > 0; a--)
273                 {
274                     const basegfx::B2DRange aRect(0, 0, fStepSize*a, fStepSize*a);
275                     impAppendMatrix(rMatrices, aRect);
276                 }
277             }
278         }
279 
280         void GeoTexSvxGradientRadial::appendColors(::std::vector< basegfx::BColor >& rColors)
281         {
282             impAppendColorsRadial(rColors);
283         }
284 
285         void GeoTexSvxGradientRadial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
286         {
287             const double fScaler(basegfx::tools::getRadialGradientAlpha(rUV, maGradientInfo));
288 
289             rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
290         }
291     } // end of namespace texture
292 } // end of namespace drawinglayer
293 
294 //////////////////////////////////////////////////////////////////////////////
295 
296 namespace drawinglayer
297 {
298     namespace texture
299     {
300         GeoTexSvxGradientElliptical::GeoTexSvxGradientElliptical(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY, double fAngle)
301         :   GeoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
302         {
303             basegfx::tools::createEllipticalODFGradientInfo(maGradientInfo,
304                                                             rTargetRange,
305                                                             basegfx::B2DVector(fOffsetX,fOffsetY),
306                                                             nSteps,
307                                                             fBorder,
308                                                             fAngle);
309         }
310 
311         GeoTexSvxGradientElliptical::~GeoTexSvxGradientElliptical()
312         {
313         }
314 
315         void GeoTexSvxGradientElliptical::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
316         {
317             if(maGradientInfo.mnSteps)
318             {
319                 double fWidth(1);
320                 double fHeight(1);
321                 double fIncrementX, fIncrementY;
322 
323                 if(maGradientInfo.mfAspectRatio > 1.0)
324                 {
325                     fIncrementY = fHeight / maGradientInfo.mnSteps;
326                     fIncrementX = fIncrementY / maGradientInfo.mfAspectRatio;
327                 }
328                 else
329                 {
330                     fIncrementX = fWidth / maGradientInfo.mnSteps;
331                     fIncrementY = fIncrementX * maGradientInfo.mfAspectRatio;
332                 }
333 
334                 for(sal_uInt32 a(1L); a < maGradientInfo.mnSteps; a++)
335                 {
336                     // next step
337                     fWidth  -= fIncrementX;
338                     fHeight -= fIncrementY;
339 
340                     // create matrix
341                     const basegfx::B2DRange aRect(0, 0, fWidth, fHeight);
342                     impAppendMatrix(rMatrices, aRect);
343                 }
344             }
345         }
346 
347         void GeoTexSvxGradientElliptical::appendColors(::std::vector< basegfx::BColor >& rColors)
348         {
349             impAppendColorsRadial(rColors);
350         }
351 
352         void GeoTexSvxGradientElliptical::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
353         {
354             const double fScaler(basegfx::tools::getEllipticalGradientAlpha(rUV, maGradientInfo));
355 
356             rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
357         }
358     } // end of namespace texture
359 } // end of namespace drawinglayer
360 
361 //////////////////////////////////////////////////////////////////////////////
362 
363 namespace drawinglayer
364 {
365     namespace texture
366     {
367         GeoTexSvxGradientSquare::GeoTexSvxGradientSquare(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY, double fAngle)
368         :   GeoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
369         {
370             basegfx::tools::createSquareODFGradientInfo(maGradientInfo,
371                                                         rTargetRange,
372                                                         basegfx::B2DVector(fOffsetX,fOffsetY),
373                                                         nSteps,
374                                                         fBorder,
375                                                         fAngle);
376         }
377 
378         GeoTexSvxGradientSquare::~GeoTexSvxGradientSquare()
379         {
380         }
381 
382         void GeoTexSvxGradientSquare::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
383         {
384             if(maGradientInfo.mnSteps)
385             {
386                 const double fStepSize=1.0 / maGradientInfo.mnSteps;
387                 for(sal_uInt32 a(maGradientInfo.mnSteps-1L); a > 0; a--)
388                 {
389                     const basegfx::B2DRange aRect(0, 0, fStepSize*a, fStepSize*a);
390                     impAppendMatrix(rMatrices, aRect);
391                 }
392             }
393         }
394 
395         void GeoTexSvxGradientSquare::appendColors(::std::vector< basegfx::BColor >& rColors)
396         {
397             impAppendColorsRadial(rColors);
398         }
399 
400         void GeoTexSvxGradientSquare::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
401         {
402             const double fScaler(basegfx::tools::getSquareGradientAlpha(rUV, maGradientInfo));
403 
404             rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
405         }
406     } // end of namespace texture
407 } // end of namespace drawinglayer
408 
409 //////////////////////////////////////////////////////////////////////////////
410 
411 namespace drawinglayer
412 {
413     namespace texture
414     {
415         GeoTexSvxGradientRect::GeoTexSvxGradientRect(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY, double fAngle)
416         :   GeoTexSvxGradient(rTargetRange, rStart, rEnd, nSteps, fBorder)
417         {
418             basegfx::tools::createRectangularODFGradientInfo(maGradientInfo,
419                                                              rTargetRange,
420                                                              basegfx::B2DVector(fOffsetX,fOffsetY),
421                                                              nSteps,
422                                                              fBorder,
423                                                              fAngle);
424         }
425 
426         GeoTexSvxGradientRect::~GeoTexSvxGradientRect()
427         {
428         }
429 
430         void GeoTexSvxGradientRect::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
431         {
432             if(maGradientInfo.mnSteps)
433             {
434                 double fWidth(1);
435                 double fHeight(1);
436                 double fIncrementX, fIncrementY;
437 
438                 if(maGradientInfo.mfAspectRatio > 1.0)
439                 {
440                     fIncrementY = fHeight / maGradientInfo.mnSteps;
441                     fIncrementX = fIncrementY / maGradientInfo.mfAspectRatio;
442                 }
443                 else
444                 {
445                     fIncrementX = fWidth / maGradientInfo.mnSteps;
446                     fIncrementY = fIncrementX * maGradientInfo.mfAspectRatio;
447                 }
448 
449                 for(sal_uInt32 a(1L); a < maGradientInfo.mnSteps; a++)
450                 {
451                     // next step
452                     fWidth  -= fIncrementX;
453                     fHeight -= fIncrementY;
454 
455                     // create matrix
456                     const basegfx::B2DRange aRect(0, 0, fWidth, fHeight);
457                     impAppendMatrix(rMatrices, aRect);
458                 }
459             }
460         }
461 
462         void GeoTexSvxGradientRect::appendColors(::std::vector< basegfx::BColor >& rColors)
463         {
464             impAppendColorsRadial(rColors);
465         }
466 
467         void GeoTexSvxGradientRect::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
468         {
469             const double fScaler(basegfx::tools::getRectangularGradientAlpha(rUV, maGradientInfo));
470 
471             rBColor = (maStart * (1.0 - fScaler)) + (maEnd * fScaler);
472         }
473     } // end of namespace texture
474 } // end of namespace drawinglayer
475 
476 //////////////////////////////////////////////////////////////////////////////
477 
478 namespace drawinglayer
479 {
480     namespace texture
481     {
482         GeoTexSvxHatch::GeoTexSvxHatch(const basegfx::B2DRange& rTargetRange, double fDistance, double fAngle)
483         :   mfDistance(0.1),
484             mfAngle(fAngle),
485             mnSteps(10L)
486         {
487             double fTargetSizeX(rTargetRange.getWidth());
488             double fTargetSizeY(rTargetRange.getHeight());
489             double fTargetOffsetX(rTargetRange.getMinX());
490             double fTargetOffsetY(rTargetRange.getMinY());
491 
492             fAngle = -fAngle;
493 
494             // add object expansion
495             if(0.0 != fAngle)
496             {
497                 const double fAbsCos(fabs(cos(fAngle)));
498                 const double fAbsSin(fabs(sin(fAngle)));
499                 const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
500                 const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
501                 fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
502                 fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
503                 fTargetSizeX = fNewX;
504                 fTargetSizeY = fNewY;
505             }
506 
507             // add object scale before rotate
508             maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
509 
510             // add texture rotate after scale to keep perpendicular angles
511             if(0.0 != fAngle)
512             {
513                 basegfx::B2DPoint aCenter(0.5, 0.5);
514                 aCenter *= maTextureTransform;
515 
516                 maTextureTransform = basegfx::tools::createRotateAroundPoint(aCenter, fAngle)
517                     * maTextureTransform;
518             }
519 
520             // add object translate
521             maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
522 
523             // prepare height for texture
524             const double fSteps((0.0 != fDistance) ? fTargetSizeY / fDistance : 10.0);
525             mnSteps = basegfx::fround(fSteps + 0.5);
526             mfDistance = 1.0 / fSteps;
527 
528             // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
529             maBackTextureTransform = maTextureTransform;
530             maBackTextureTransform.invert();
531         }
532 
533         GeoTexSvxHatch::~GeoTexSvxHatch()
534         {
535         }
536 
537         bool GeoTexSvxHatch::operator==(const GeoTexSvx& rGeoTexSvx) const
538         {
539             const GeoTexSvxHatch* pCompare = dynamic_cast< const GeoTexSvxHatch* >(&rGeoTexSvx);
540             return (pCompare
541                 && maTextureTransform == pCompare->maTextureTransform
542                 && mfDistance == pCompare->mfDistance
543                 && mfAngle == pCompare->mfAngle
544                 && mnSteps == pCompare->mnSteps);
545         }
546 
547         void GeoTexSvxHatch::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
548         {
549             for(sal_uInt32 a(1L); a < mnSteps; a++)
550             {
551                 // create matrix
552                 const double fOffset(mfDistance * (double)a);
553                 basegfx::B2DHomMatrix aNew;
554                 aNew.set(1, 2, fOffset);
555                 rMatrices.push_back(maTextureTransform * aNew);
556             }
557         }
558 
559         double GeoTexSvxHatch::getDistanceToHatch(const basegfx::B2DPoint& rUV) const
560         {
561             const basegfx::B2DPoint aCoor(maBackTextureTransform * rUV);
562             return fmod(aCoor.getY(), mfDistance);
563         }
564     } // end of namespace texture
565 } // end of namespace drawinglayer
566 
567 //////////////////////////////////////////////////////////////////////////////
568 
569 namespace drawinglayer
570 {
571     namespace texture
572     {
573         GeoTexSvxTiled::GeoTexSvxTiled(const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize)
574         :   maTopLeft(rTopLeft),
575             maSize(rSize)
576         {
577             if(basegfx::fTools::lessOrEqual(maSize.getX(), 0.0))
578             {
579                 maSize.setX(1.0);
580             }
581 
582             if(basegfx::fTools::lessOrEqual(maSize.getY(), 0.0))
583             {
584                 maSize.setY(1.0);
585             }
586         }
587 
588         GeoTexSvxTiled::~GeoTexSvxTiled()
589         {
590         }
591 
592         bool GeoTexSvxTiled::operator==(const GeoTexSvx& rGeoTexSvx) const
593         {
594             const GeoTexSvxTiled* pCompare = dynamic_cast< const GeoTexSvxTiled* >(&rGeoTexSvx);
595             return (pCompare
596                 && maTopLeft == pCompare->maTopLeft
597                 && maSize == pCompare->maSize);
598         }
599 
600         void GeoTexSvxTiled::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
601         {
602             double fStartX(maTopLeft.getX());
603             double fStartY(maTopLeft.getY());
604 
605             if(basegfx::fTools::more(fStartX, 0.0))
606             {
607                 fStartX -= (floor(fStartX / maSize.getX()) + 1.0) * maSize.getX();
608             }
609 
610             if(basegfx::fTools::less(fStartX + maSize.getX(), 0.0))
611             {
612                 fStartX += floor(-fStartX / maSize.getX()) * maSize.getX();
613             }
614 
615             if(basegfx::fTools::more(fStartY, 0.0))
616             {
617                 fStartY -= (floor(fStartY / maSize.getY()) + 1.0) * maSize.getY();
618             }
619 
620             if(basegfx::fTools::less(fStartY + maSize.getY(), 0.0))
621             {
622                 fStartY += floor(-fStartY / maSize.getY()) * maSize.getY();
623             }
624 
625             for(double fPosY(fStartY); basegfx::fTools::less(fPosY, 1.0); fPosY += maSize.getY())
626             {
627                 for(double fPosX(fStartX); basegfx::fTools::less(fPosX, 1.0); fPosX += maSize.getX())
628                 {
629                     basegfx::B2DHomMatrix aNew;
630 
631                     aNew.set(0, 0, maSize.getX());
632                     aNew.set(1, 1, maSize.getY());
633                     aNew.set(0, 2, fPosX);
634                     aNew.set(1, 2, fPosY);
635 
636                     rMatrices.push_back(aNew);
637                 }
638             }
639         }
640     } // end of namespace texture
641 } // end of namespace drawinglayer
642 
643 //////////////////////////////////////////////////////////////////////////////
644 // eof
645