Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / drawinglayer / source / texture / texture.cxx
blobc2d1a5468e78597108749293b186cfdaa1c00333
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <algorithm>
24 #include <drawinglayer/texture/texture.hxx>
25 #include <basegfx/numeric/ftools.hxx>
26 #include <basegfx/utils/gradienttools.hxx>
27 #include <basegfx/matrix/b2dhommatrixtools.hxx>
29 #include <converters.hxx>
31 namespace drawinglayer
33 namespace texture
35 GeoTexSvx::GeoTexSvx()
39 GeoTexSvx::~GeoTexSvx()
43 bool GeoTexSvx::operator==(const GeoTexSvx& /*rGeoTexSvx*/) const
45 // default implementation says yes (no data -> no difference)
46 return true;
49 void GeoTexSvx::modifyBColor(const basegfx::B2DPoint& /*rUV*/, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
51 // base implementation creates random color (for testing only, may also be pure virtual)
52 rBColor.setRed(getRandomColorRange());
53 rBColor.setGreen(getRandomColorRange());
54 rBColor.setBlue(getRandomColorRange());
57 void GeoTexSvx::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
59 // base implementation uses inverse of luminance of solved color (for testing only, may also be pure virtual)
60 basegfx::BColor aBaseColor;
61 modifyBColor(rUV, aBaseColor, rfOpacity);
62 rfOpacity = 1.0 - aBaseColor.luminance();
64 } // end of namespace texture
65 } // end of namespace drawinglayer
68 namespace drawinglayer
70 namespace texture
72 GeoTexSvxGradient::GeoTexSvxGradient(
73 const basegfx::B2DRange& rDefinitionRange,
74 const basegfx::BColor& rStart,
75 const basegfx::BColor& rEnd,
76 double fBorder)
77 : GeoTexSvx(),
78 maGradientInfo(),
79 maDefinitionRange(rDefinitionRange),
80 maStart(rStart),
81 maEnd(rEnd),
82 mfBorder(fBorder)
86 GeoTexSvxGradient::~GeoTexSvxGradient()
90 bool GeoTexSvxGradient::operator==(const GeoTexSvx& rGeoTexSvx) const
92 const GeoTexSvxGradient* pCompare = dynamic_cast< const GeoTexSvxGradient* >(&rGeoTexSvx);
94 return (pCompare
95 && maGradientInfo == pCompare->maGradientInfo
96 && maDefinitionRange == pCompare->maDefinitionRange
97 && mfBorder == pCompare->mfBorder);
99 } // end of namespace texture
100 } // end of namespace drawinglayer
103 namespace drawinglayer
105 namespace texture
107 GeoTexSvxGradientLinear::GeoTexSvxGradientLinear(
108 const basegfx::B2DRange& rDefinitionRange,
109 const basegfx::B2DRange& rOutputRange,
110 const basegfx::BColor& rStart,
111 const basegfx::BColor& rEnd,
112 sal_uInt32 nSteps,
113 double fBorder,
114 double fAngle)
115 : GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, fBorder),
116 mfUnitMinX(0.0),
117 mfUnitWidth(1.0),
118 mfUnitMaxY(1.0)
120 maGradientInfo = basegfx::utils::createLinearODFGradientInfo(
121 rDefinitionRange,
122 nSteps,
123 fBorder,
124 fAngle);
126 if(rDefinitionRange != rOutputRange)
128 basegfx::B2DRange aInvOutputRange(rOutputRange);
130 aInvOutputRange.transform(maGradientInfo.getBackTextureTransform());
131 mfUnitMinX = aInvOutputRange.getMinX();
132 mfUnitWidth = aInvOutputRange.getWidth();
133 mfUnitMaxY = aInvOutputRange.getMaxY();
137 GeoTexSvxGradientLinear::~GeoTexSvxGradientLinear()
141 void GeoTexSvxGradientLinear::appendTransformationsAndColors(
142 std::vector< B2DHomMatrixAndBColor >& rEntries,
143 basegfx::BColor& rOuterColor)
145 rOuterColor = maStart;
147 if(maGradientInfo.getSteps())
149 const double fStripeWidth(1.0 / maGradientInfo.getSteps());
150 B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
151 basegfx::B2DHomMatrix aPattern;
153 // bring from unit circle [-1, -1, 1, 1] to unit range [0, 0, 1, 1]
154 aPattern.scale(0.5, 0.5);
155 aPattern.translate(0.5, 0.5);
157 // scale and translate in X
158 aPattern.scale(mfUnitWidth, 1.0);
159 aPattern.translate(mfUnitMinX, 0.0);
161 for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
163 const double fPos(fStripeWidth * a);
164 basegfx::B2DHomMatrix aNew(aPattern);
166 // scale and translate in Y
167 double fHeight(1.0 - fPos);
169 if(a + 1 == maGradientInfo.getSteps() && mfUnitMaxY > 1.0)
171 fHeight += mfUnitMaxY - 1.0;
174 aNew.scale(1.0, fHeight);
175 aNew.translate(0.0, fPos);
177 // set at target
178 aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * aNew;
180 // interpolate and set color
181 aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
183 rEntries.push_back(aB2DHomMatrixAndBColor);
188 void GeoTexSvxGradientLinear::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
190 const double fScaler(basegfx::utils::getLinearGradientAlpha(rUV, maGradientInfo));
192 rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
194 } // end of namespace texture
195 } // end of namespace drawinglayer
198 namespace drawinglayer
200 namespace texture
202 GeoTexSvxGradientAxial::GeoTexSvxGradientAxial(
203 const basegfx::B2DRange& rDefinitionRange,
204 const basegfx::B2DRange& rOutputRange,
205 const basegfx::BColor& rStart,
206 const basegfx::BColor& rEnd,
207 sal_uInt32 nSteps,
208 double fBorder,
209 double fAngle)
210 : GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, fBorder),
211 mfUnitMinX(0.0),
212 mfUnitWidth(1.0)
214 maGradientInfo = basegfx::utils::createAxialODFGradientInfo(
215 rDefinitionRange,
216 nSteps,
217 fBorder,
218 fAngle);
220 if(rDefinitionRange != rOutputRange)
222 basegfx::B2DRange aInvOutputRange(rOutputRange);
224 aInvOutputRange.transform(maGradientInfo.getBackTextureTransform());
225 mfUnitMinX = aInvOutputRange.getMinX();
226 mfUnitWidth = aInvOutputRange.getWidth();
230 GeoTexSvxGradientAxial::~GeoTexSvxGradientAxial()
234 void GeoTexSvxGradientAxial::appendTransformationsAndColors(
235 std::vector< B2DHomMatrixAndBColor >& rEntries,
236 basegfx::BColor& rOuterColor)
238 rOuterColor = maEnd;
240 if(maGradientInfo.getSteps())
242 const double fStripeWidth(1.0 / maGradientInfo.getSteps());
243 B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
245 for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
247 const double fPos(fStripeWidth * a);
248 basegfx::B2DHomMatrix aNew;
250 // bring in X from unit circle [-1, -1, 1, 1] to unit range [0, 0, 1, 1]
251 aNew.scale(0.5, 1.0);
252 aNew.translate(0.5, 0.0);
254 // scale/translate in X
255 aNew.scale(mfUnitWidth, 1.0);
256 aNew.translate(mfUnitMinX, 0.0);
258 // already centered in Y on X-Axis, just scale in Y
259 aNew.scale(1.0, 1.0 - fPos);
261 // set at target
262 aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * aNew;
264 // interpolate and set color
265 aB2DHomMatrixAndBColor.maBColor = interpolate(maEnd, maStart, double(a) / double(maGradientInfo.getSteps() - 1));
267 rEntries.push_back(aB2DHomMatrixAndBColor);
272 void GeoTexSvxGradientAxial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
274 const double fScaler(basegfx::utils::getAxialGradientAlpha(rUV, maGradientInfo));
276 rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
278 } // end of namespace texture
279 } // end of namespace drawinglayer
282 namespace drawinglayer
284 namespace texture
286 GeoTexSvxGradientRadial::GeoTexSvxGradientRadial(
287 const basegfx::B2DRange& rDefinitionRange,
288 const basegfx::BColor& rStart,
289 const basegfx::BColor& rEnd,
290 sal_uInt32 nSteps,
291 double fBorder,
292 double fOffsetX,
293 double fOffsetY)
294 : GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, fBorder)
296 maGradientInfo = basegfx::utils::createRadialODFGradientInfo(
297 rDefinitionRange,
298 basegfx::B2DVector(fOffsetX,fOffsetY),
299 nSteps,
300 fBorder);
303 GeoTexSvxGradientRadial::~GeoTexSvxGradientRadial()
307 void GeoTexSvxGradientRadial::appendTransformationsAndColors(
308 std::vector< B2DHomMatrixAndBColor >& rEntries,
309 basegfx::BColor& rOuterColor)
311 rOuterColor = maStart;
313 if(maGradientInfo.getSteps())
315 const double fStepSize(1.0 / maGradientInfo.getSteps());
316 B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
318 for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
320 const double fSize(1.0 - (fStepSize * a));
321 aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::utils::createScaleB2DHomMatrix(fSize, fSize);
322 aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
323 rEntries.push_back(aB2DHomMatrixAndBColor);
328 void GeoTexSvxGradientRadial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
330 const double fScaler(basegfx::utils::getRadialGradientAlpha(rUV, maGradientInfo));
332 rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
334 } // end of namespace texture
335 } // end of namespace drawinglayer
338 namespace drawinglayer
340 namespace texture
342 GeoTexSvxGradientElliptical::GeoTexSvxGradientElliptical(
343 const basegfx::B2DRange& rDefinitionRange,
344 const basegfx::BColor& rStart,
345 const basegfx::BColor& rEnd,
346 sal_uInt32 nSteps,
347 double fBorder,
348 double fOffsetX,
349 double fOffsetY,
350 double fAngle)
351 : GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, fBorder)
353 maGradientInfo = basegfx::utils::createEllipticalODFGradientInfo(
354 rDefinitionRange,
355 basegfx::B2DVector(fOffsetX,fOffsetY),
356 nSteps,
357 fBorder,
358 fAngle);
361 GeoTexSvxGradientElliptical::~GeoTexSvxGradientElliptical()
365 void GeoTexSvxGradientElliptical::appendTransformationsAndColors(
366 std::vector< B2DHomMatrixAndBColor >& rEntries,
367 basegfx::BColor& rOuterColor)
369 rOuterColor = maStart;
371 if(maGradientInfo.getSteps())
373 double fWidth(1.0);
374 double fHeight(1.0);
375 double fIncrementX(0.0);
376 double fIncrementY(0.0);
378 if(maGradientInfo.getAspectRatio() > 1.0)
380 fIncrementY = fHeight / maGradientInfo.getSteps();
381 fIncrementX = fIncrementY / maGradientInfo.getAspectRatio();
383 else
385 fIncrementX = fWidth / maGradientInfo.getSteps();
386 fIncrementY = fIncrementX * maGradientInfo.getAspectRatio();
389 B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
391 for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
393 // next step
394 fWidth -= fIncrementX;
395 fHeight -= fIncrementY;
397 aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::utils::createScaleB2DHomMatrix(fWidth, fHeight);
398 aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
399 rEntries.push_back(aB2DHomMatrixAndBColor);
404 void GeoTexSvxGradientElliptical::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
406 const double fScaler(basegfx::utils::getEllipticalGradientAlpha(rUV, maGradientInfo));
408 rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
410 } // end of namespace texture
411 } // end of namespace drawinglayer
414 namespace drawinglayer
416 namespace texture
418 GeoTexSvxGradientSquare::GeoTexSvxGradientSquare(
419 const basegfx::B2DRange& rDefinitionRange,
420 const basegfx::BColor& rStart,
421 const basegfx::BColor& rEnd,
422 sal_uInt32 nSteps,
423 double fBorder,
424 double fOffsetX,
425 double fOffsetY,
426 double fAngle)
427 : GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, fBorder)
429 maGradientInfo = basegfx::utils::createSquareODFGradientInfo(
430 rDefinitionRange,
431 basegfx::B2DVector(fOffsetX,fOffsetY),
432 nSteps,
433 fBorder,
434 fAngle);
437 GeoTexSvxGradientSquare::~GeoTexSvxGradientSquare()
441 void GeoTexSvxGradientSquare::appendTransformationsAndColors(
442 std::vector< B2DHomMatrixAndBColor >& rEntries,
443 basegfx::BColor& rOuterColor)
445 rOuterColor = maStart;
447 if(maGradientInfo.getSteps())
449 const double fStepSize(1.0 / maGradientInfo.getSteps());
450 B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
452 for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
454 const double fSize(1.0 - (fStepSize * a));
455 aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::utils::createScaleB2DHomMatrix(fSize, fSize);
456 aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
457 rEntries.push_back(aB2DHomMatrixAndBColor);
462 void GeoTexSvxGradientSquare::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
464 const double fScaler(basegfx::utils::getSquareGradientAlpha(rUV, maGradientInfo));
466 rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
468 } // end of namespace texture
469 } // end of namespace drawinglayer
472 namespace drawinglayer
474 namespace texture
476 GeoTexSvxGradientRect::GeoTexSvxGradientRect(
477 const basegfx::B2DRange& rDefinitionRange,
478 const basegfx::BColor& rStart,
479 const basegfx::BColor& rEnd,
480 sal_uInt32 nSteps,
481 double fBorder,
482 double fOffsetX,
483 double fOffsetY,
484 double fAngle)
485 : GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, fBorder)
487 maGradientInfo = basegfx::utils::createRectangularODFGradientInfo(
488 rDefinitionRange,
489 basegfx::B2DVector(fOffsetX,fOffsetY),
490 nSteps,
491 fBorder,
492 fAngle);
495 GeoTexSvxGradientRect::~GeoTexSvxGradientRect()
499 void GeoTexSvxGradientRect::appendTransformationsAndColors(
500 std::vector< B2DHomMatrixAndBColor >& rEntries,
501 basegfx::BColor& rOuterColor)
503 rOuterColor = maStart;
505 if(maGradientInfo.getSteps())
507 double fWidth(1.0);
508 double fHeight(1.0);
509 double fIncrementX(0.0);
510 double fIncrementY(0.0);
512 if(maGradientInfo.getAspectRatio() > 1.0)
514 fIncrementY = fHeight / maGradientInfo.getSteps();
515 fIncrementX = fIncrementY / maGradientInfo.getAspectRatio();
517 else
519 fIncrementX = fWidth / maGradientInfo.getSteps();
520 fIncrementY = fIncrementX * maGradientInfo.getAspectRatio();
523 B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
525 for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
527 // next step
528 fWidth -= fIncrementX;
529 fHeight -= fIncrementY;
531 aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::utils::createScaleB2DHomMatrix(fWidth, fHeight);
532 aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
533 rEntries.push_back(aB2DHomMatrixAndBColor);
538 void GeoTexSvxGradientRect::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
540 const double fScaler(basegfx::utils::getRectangularGradientAlpha(rUV, maGradientInfo));
542 rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
544 } // end of namespace texture
545 } // end of namespace drawinglayer
548 namespace drawinglayer
550 namespace texture
552 GeoTexSvxHatch::GeoTexSvxHatch(
553 const basegfx::B2DRange& rDefinitionRange,
554 const basegfx::B2DRange& rOutputRange,
555 double fDistance,
556 double fAngle)
557 : maOutputRange(rOutputRange),
558 maTextureTransform(),
559 maBackTextureTransform(),
560 mfDistance(0.1),
561 mfAngle(fAngle),
562 mnSteps(10),
563 mbDefinitionRangeEqualsOutputRange(rDefinitionRange == rOutputRange)
565 double fTargetSizeX(rDefinitionRange.getWidth());
566 double fTargetSizeY(rDefinitionRange.getHeight());
567 double fTargetOffsetX(rDefinitionRange.getMinX());
568 double fTargetOffsetY(rDefinitionRange.getMinY());
570 fAngle = -fAngle;
572 // add object expansion
573 if(0.0 != fAngle)
575 const double fAbsCos(fabs(cos(fAngle)));
576 const double fAbsSin(fabs(sin(fAngle)));
577 const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
578 const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
579 fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
580 fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
581 fTargetSizeX = fNewX;
582 fTargetSizeY = fNewY;
585 // add object scale before rotate
586 maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
588 // add texture rotate after scale to keep perpendicular angles
589 if(0.0 != fAngle)
591 basegfx::B2DPoint aCenter(0.5, 0.5);
592 aCenter *= maTextureTransform;
594 maTextureTransform = basegfx::utils::createRotateAroundPoint(aCenter, fAngle)
595 * maTextureTransform;
598 // add object translate
599 maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
601 // prepare height for texture
602 const double fSteps((0.0 != fDistance) ? fTargetSizeY / fDistance : 10.0);
603 mnSteps = basegfx::fround(fSteps + 0.5);
604 mfDistance = 1.0 / fSteps;
607 GeoTexSvxHatch::~GeoTexSvxHatch()
611 bool GeoTexSvxHatch::operator==(const GeoTexSvx& rGeoTexSvx) const
613 const GeoTexSvxHatch* pCompare = dynamic_cast< const GeoTexSvxHatch* >(&rGeoTexSvx);
614 return (pCompare
615 && maOutputRange == pCompare->maOutputRange
616 && maTextureTransform == pCompare->maTextureTransform
617 && mfDistance == pCompare->mfDistance
618 && mfAngle == pCompare->mfAngle
619 && mnSteps == pCompare->mnSteps);
622 void GeoTexSvxHatch::appendTransformations(std::vector< basegfx::B2DHomMatrix >& rMatrices)
624 if(mbDefinitionRangeEqualsOutputRange)
626 // simple hatch where the definition area equals the output area
627 for(sal_uInt32 a(1); a < mnSteps; a++)
629 // create matrix
630 const double fOffset(mfDistance * static_cast<double>(a));
631 basegfx::B2DHomMatrix aNew;
632 aNew.set(1, 2, fOffset);
633 rMatrices.push_back(maTextureTransform * aNew);
636 else
638 // output area is different from definition area, back-transform to get
639 // the output area in unit coordinates and fill this with hatch lines
640 // using the settings derived from the definition area
641 basegfx::B2DRange aBackUnitRange(maOutputRange);
643 aBackUnitRange.transform(getBackTextureTransform());
645 // calculate vertical start value and a security maximum integer value to avoid death loops
646 double fStart(basegfx::snapToNearestMultiple(aBackUnitRange.getMinY(), mfDistance));
647 const sal_uInt32 nNeededIntegerSteps(basegfx::fround((aBackUnitRange.getHeight() / mfDistance) + 0.5));
648 sal_uInt32 nMaxIntegerSteps(std::min(nNeededIntegerSteps, sal_uInt32(10000)));
650 while(fStart < aBackUnitRange.getMaxY() && nMaxIntegerSteps)
652 // create new transform for
653 basegfx::B2DHomMatrix aNew;
655 // adapt x scale and position
656 //aNew.scale(aBackUnitRange.getWidth(), 1.0);
657 //aNew.translate(aBackUnitRange.getMinX(), 0.0);
658 aNew.set(0, 0, aBackUnitRange.getWidth());
659 aNew.set(0, 2, aBackUnitRange.getMinX());
661 // adapt y position to current step
662 aNew.set(1, 2, fStart);
663 //aNew.translate(0.0, fStart);
665 // add new transformation
666 rMatrices.push_back(maTextureTransform * aNew);
668 // next step
669 fStart += mfDistance;
670 nMaxIntegerSteps--;
675 double GeoTexSvxHatch::getDistanceToHatch(const basegfx::B2DPoint& rUV) const
677 const basegfx::B2DPoint aCoor(getBackTextureTransform() * rUV);
678 return fmod(aCoor.getY(), mfDistance);
681 const basegfx::B2DHomMatrix& GeoTexSvxHatch::getBackTextureTransform() const
683 if(maBackTextureTransform.isIdentity())
685 const_cast< GeoTexSvxHatch* >(this)->maBackTextureTransform = maTextureTransform;
686 const_cast< GeoTexSvxHatch* >(this)->maBackTextureTransform.invert();
689 return maBackTextureTransform;
691 } // end of namespace texture
692 } // end of namespace drawinglayer
695 namespace drawinglayer
697 namespace texture
699 GeoTexSvxTiled::GeoTexSvxTiled(
700 const basegfx::B2DRange& rRange,
701 double fOffsetX,
702 double fOffsetY)
703 : maRange(rRange),
704 mfOffsetX(std::clamp(fOffsetX, 0.0, 1.0)),
705 mfOffsetY(std::clamp(fOffsetY, 0.0, 1.0))
707 if(!basegfx::fTools::equalZero(mfOffsetX))
709 mfOffsetY = 0.0;
713 GeoTexSvxTiled::~GeoTexSvxTiled()
717 bool GeoTexSvxTiled::operator==(const GeoTexSvx& rGeoTexSvx) const
719 const GeoTexSvxTiled* pCompare = dynamic_cast< const GeoTexSvxTiled* >(&rGeoTexSvx);
721 return (pCompare
722 && maRange == pCompare->maRange
723 && mfOffsetX == pCompare->mfOffsetX
724 && mfOffsetY == pCompare->mfOffsetY);
727 sal_uInt32 GeoTexSvxTiled::getNumberOfTiles() const
729 return iterateTiles(nullptr);
732 void GeoTexSvxTiled::appendTransformations(std::vector< basegfx::B2DHomMatrix >& rMatrices) const
734 iterateTiles(&rMatrices);
737 sal_Int32 GeoTexSvxTiled::iterateTiles(std::vector< basegfx::B2DHomMatrix >* pMatrices) const
739 const double fWidth(maRange.getWidth());
740 sal_Int32 nTiles = 0;
742 if(!basegfx::fTools::equalZero(fWidth))
744 const double fHeight(maRange.getHeight());
746 if(!basegfx::fTools::equalZero(fHeight))
748 double fStartX(maRange.getMinX());
749 double fStartY(maRange.getMinY());
750 sal_Int32 nPosX(0);
751 sal_Int32 nPosY(0);
753 if(basegfx::fTools::more(fStartX, 0.0))
755 const sal_Int32 nDiff(static_cast<sal_Int32>(floor(fStartX / fWidth)) + 1);
757 nPosX -= nDiff;
758 fStartX -= nDiff * fWidth;
761 if(basegfx::fTools::less(fStartX + fWidth, 0.0))
763 const sal_Int32 nDiff(static_cast<sal_Int32>(floor(-fStartX / fWidth)));
765 nPosX += nDiff;
766 fStartX += nDiff * fWidth;
769 if(basegfx::fTools::more(fStartY, 0.0))
771 const sal_Int32 nDiff(static_cast<sal_Int32>(floor(fStartY / fHeight)) + 1);
773 nPosY -= nDiff;
774 fStartY -= nDiff * fHeight;
777 if(basegfx::fTools::less(fStartY + fHeight, 0.0))
779 const sal_Int32 nDiff(static_cast<sal_Int32>(floor(-fStartY / fHeight)));
781 nPosY += nDiff;
782 fStartY += nDiff * fHeight;
785 if(!basegfx::fTools::equalZero(mfOffsetY))
787 for(double fPosX(fStartX); basegfx::fTools::less(fPosX, 1.0); fPosX += fWidth, nPosX++)
789 for(double fPosY((nPosX % 2) ? fStartY - fHeight + (mfOffsetY * fHeight) : fStartY);
790 basegfx::fTools::less(fPosY, 1.0); fPosY += fHeight)
792 if(pMatrices)
794 pMatrices->push_back(
795 basegfx::utils::createScaleTranslateB2DHomMatrix(
796 fWidth,
797 fHeight,
798 fPosX,
799 fPosY));
801 else
803 nTiles++;
808 else
810 for(double fPosY(fStartY); basegfx::fTools::less(fPosY, 1.0); fPosY += fHeight, nPosY++)
812 for(double fPosX((nPosY % 2) ? fStartX - fWidth + (mfOffsetX * fWidth) : fStartX);
813 basegfx::fTools::less(fPosX, 1.0); fPosX += fWidth)
815 if(pMatrices)
817 pMatrices->push_back(
818 basegfx::utils::createScaleTranslateB2DHomMatrix(
819 fWidth,
820 fHeight,
821 fPosX,
822 fPosY));
824 else
826 nTiles++;
834 return nTiles;
836 } // end of namespace texture
837 } // end of namespace drawinglayer
839 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */