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