1464702f4SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3464702f4SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4464702f4SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5464702f4SAndrew Rist  * distributed with this work for additional information
6464702f4SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7464702f4SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8464702f4SAndrew Rist  * "License"); you may not use this file except in compliance
9464702f4SAndrew Rist  * with the License.  You may obtain a copy of the License at
10464702f4SAndrew Rist  *
11464702f4SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12464702f4SAndrew Rist  *
13464702f4SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14464702f4SAndrew Rist  * software distributed under the License is distributed on an
15464702f4SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16464702f4SAndrew Rist  * KIND, either express or implied.  See the License for the
17464702f4SAndrew Rist  * specific language governing permissions and limitations
18464702f4SAndrew Rist  * under the License.
19464702f4SAndrew Rist  *
20464702f4SAndrew Rist  *************************************************************/
21464702f4SAndrew Rist 
22464702f4SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <drawinglayer/texture/texture.hxx>
28cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx>
29cdf0e10cSrcweir #include <basegfx/tools/gradienttools.hxx>
30cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
33cdf0e10cSrcweir 
34cdf0e10cSrcweir namespace drawinglayer
35cdf0e10cSrcweir {
36*64b14621SArmin Le Grand     namespace texture
37*64b14621SArmin Le Grand     {
GeoTexSvx()38*64b14621SArmin Le Grand         GeoTexSvx::GeoTexSvx()
39*64b14621SArmin Le Grand         {
40*64b14621SArmin Le Grand         }
41*64b14621SArmin Le Grand 
~GeoTexSvx()42*64b14621SArmin Le Grand         GeoTexSvx::~GeoTexSvx()
43*64b14621SArmin Le Grand         {
44*64b14621SArmin Le Grand         }
45*64b14621SArmin Le Grand 
operator ==(const GeoTexSvx &) const46*64b14621SArmin Le Grand         bool GeoTexSvx::operator==(const GeoTexSvx& /*rGeoTexSvx*/) const
47*64b14621SArmin Le Grand         {
48*64b14621SArmin Le Grand             // default implementation says yes (no data -> no difference)
49*64b14621SArmin Le Grand             return true;
50*64b14621SArmin Le Grand         }
51*64b14621SArmin Le Grand 
modifyBColor(const basegfx::B2DPoint &,basegfx::BColor & rBColor,double &) const52*64b14621SArmin Le Grand         void GeoTexSvx::modifyBColor(const basegfx::B2DPoint& /*rUV*/, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
53*64b14621SArmin Le Grand         {
54*64b14621SArmin Le Grand             // base implementation creates random color (for testing only, may also be pure virtual)
55*64b14621SArmin Le Grand             rBColor.setRed((rand() & 0x7fff) / 32767.0);
56*64b14621SArmin Le Grand             rBColor.setGreen((rand() & 0x7fff) / 32767.0);
57*64b14621SArmin Le Grand             rBColor.setBlue((rand() & 0x7fff) / 32767.0);
58*64b14621SArmin Le Grand         }
59*64b14621SArmin Le Grand 
modifyOpacity(const basegfx::B2DPoint & rUV,double & rfOpacity) const60*64b14621SArmin Le Grand         void GeoTexSvx::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
61*64b14621SArmin Le Grand         {
62*64b14621SArmin Le Grand             // base implementation uses inverse of luminance of solved color (for testing only, may also be pure virtual)
63*64b14621SArmin Le Grand             basegfx::BColor aBaseColor;
64*64b14621SArmin Le Grand             modifyBColor(rUV, aBaseColor, rfOpacity);
65*64b14621SArmin Le Grand             rfOpacity = 1.0 - aBaseColor.luminance();
66*64b14621SArmin Le Grand         }
67*64b14621SArmin Le Grand     } // end of namespace texture
68cdf0e10cSrcweir } // end of namespace drawinglayer
69cdf0e10cSrcweir 
70cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
71cdf0e10cSrcweir 
72cdf0e10cSrcweir namespace drawinglayer
73cdf0e10cSrcweir {
7496fc4b33SArmin Le Grand     namespace texture
7596fc4b33SArmin Le Grand     {
GeoTexSvxGradient(const basegfx::B2DRange & rDefinitionRange,const basegfx::BColor & rStart,const basegfx::BColor & rEnd,sal_uInt32,double fBorder)76*64b14621SArmin Le Grand         GeoTexSvxGradient::GeoTexSvxGradient(
77*64b14621SArmin Le Grand             const basegfx::B2DRange& rDefinitionRange,
7896fc4b33SArmin Le Grand             const basegfx::BColor& rStart,
7996fc4b33SArmin Le Grand             const basegfx::BColor& rEnd,
80d931502cSPavel Janík             sal_uInt32 /* nSteps */,
8196fc4b33SArmin Le Grand             double fBorder)
82*64b14621SArmin Le Grand         :   GeoTexSvx(),
8396fc4b33SArmin Le Grand             maGradientInfo(),
84*64b14621SArmin Le Grand             maDefinitionRange(rDefinitionRange),
85*64b14621SArmin Le Grand             maStart(rStart),
86*64b14621SArmin Le Grand             maEnd(rEnd),
87*64b14621SArmin Le Grand             mfBorder(fBorder)
88*64b14621SArmin Le Grand         {
89*64b14621SArmin Le Grand         }
90cdf0e10cSrcweir 
~GeoTexSvxGradient()91*64b14621SArmin Le Grand         GeoTexSvxGradient::~GeoTexSvxGradient()
92*64b14621SArmin Le Grand         {
93*64b14621SArmin Le Grand         }
94cdf0e10cSrcweir 
operator ==(const GeoTexSvx & rGeoTexSvx) const95*64b14621SArmin Le Grand         bool GeoTexSvxGradient::operator==(const GeoTexSvx& rGeoTexSvx) const
96*64b14621SArmin Le Grand         {
97*64b14621SArmin Le Grand             const GeoTexSvxGradient* pCompare = dynamic_cast< const GeoTexSvxGradient* >(&rGeoTexSvx);
9896fc4b33SArmin Le Grand 
9996fc4b33SArmin Le Grand             return (pCompare
100*64b14621SArmin Le Grand                 && maGradientInfo == pCompare->maGradientInfo
101*64b14621SArmin Le Grand                 && maDefinitionRange == pCompare->maDefinitionRange
102*64b14621SArmin Le Grand                 && mfBorder == pCompare->mfBorder);
103*64b14621SArmin Le Grand         }
104*64b14621SArmin Le Grand     } // end of namespace texture
105cdf0e10cSrcweir } // end of namespace drawinglayer
106cdf0e10cSrcweir 
107cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
108cdf0e10cSrcweir 
109cdf0e10cSrcweir namespace drawinglayer
110cdf0e10cSrcweir {
111*64b14621SArmin Le Grand     namespace texture
112*64b14621SArmin Le Grand     {
GeoTexSvxGradientLinear(const basegfx::B2DRange & rDefinitionRange,const basegfx::B2DRange & rOutputRange,const basegfx::BColor & rStart,const basegfx::BColor & rEnd,sal_uInt32 nSteps,double fBorder,double fAngle)113*64b14621SArmin Le Grand         GeoTexSvxGradientLinear::GeoTexSvxGradientLinear(
114*64b14621SArmin Le Grand             const basegfx::B2DRange& rDefinitionRange,
115*64b14621SArmin Le Grand             const basegfx::B2DRange& rOutputRange,
11696fc4b33SArmin Le Grand             const basegfx::BColor& rStart,
11796fc4b33SArmin Le Grand             const basegfx::BColor& rEnd,
11896fc4b33SArmin Le Grand             sal_uInt32 nSteps,
11996fc4b33SArmin Le Grand             double fBorder,
12096fc4b33SArmin Le Grand             double fAngle)
121*64b14621SArmin Le Grand         :   GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder),
122*64b14621SArmin Le Grand             mfUnitMinX(0.0),
123*64b14621SArmin Le Grand             mfUnitWidth(1.0),
124*64b14621SArmin Le Grand             mfUnitMaxY(1.0)
125*64b14621SArmin Le Grand         {
12696fc4b33SArmin Le Grand             maGradientInfo = basegfx::tools::createLinearODFGradientInfo(
127*64b14621SArmin Le Grand                 rDefinitionRange,
12896fc4b33SArmin Le Grand                 nSteps,
12996fc4b33SArmin Le Grand                 fBorder,
13096fc4b33SArmin Le Grand                 fAngle);
131cdf0e10cSrcweir 
132*64b14621SArmin Le Grand             if(rDefinitionRange != rOutputRange)
133*64b14621SArmin Le Grand             {
134*64b14621SArmin Le Grand                 basegfx::B2DRange aInvOutputRange(rOutputRange);
135*64b14621SArmin Le Grand 
136*64b14621SArmin Le Grand                 aInvOutputRange.transform(maGradientInfo.getBackTextureTransform());
137*64b14621SArmin Le Grand                 mfUnitMinX = aInvOutputRange.getMinX();
138*64b14621SArmin Le Grand                 mfUnitWidth = aInvOutputRange.getWidth();
139*64b14621SArmin Le Grand                 mfUnitMaxY = aInvOutputRange.getMaxY();
140*64b14621SArmin Le Grand             }
141*64b14621SArmin Le Grand         }
142*64b14621SArmin Le Grand 
~GeoTexSvxGradientLinear()143*64b14621SArmin Le Grand         GeoTexSvxGradientLinear::~GeoTexSvxGradientLinear()
144*64b14621SArmin Le Grand         {
145*64b14621SArmin Le Grand         }
146cdf0e10cSrcweir 
appendTransformationsAndColors(std::vector<B2DHomMatrixAndBColor> & rEntries,basegfx::BColor & rOuterColor)14796fc4b33SArmin Le Grand         void GeoTexSvxGradientLinear::appendTransformationsAndColors(
14896fc4b33SArmin Le Grand             std::vector< B2DHomMatrixAndBColor >& rEntries,
149*64b14621SArmin Le Grand             basegfx::BColor& rOuterColor)
15096fc4b33SArmin Le Grand         {
151*64b14621SArmin Le Grand             rOuterColor = maStart;
15296fc4b33SArmin Le Grand 
15396fc4b33SArmin Le Grand             if(maGradientInfo.getSteps())
15496fc4b33SArmin Le Grand             {
15596fc4b33SArmin Le Grand                 const double fStripeWidth(1.0 / maGradientInfo.getSteps());
15696fc4b33SArmin Le Grand                 B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
157*64b14621SArmin Le Grand                 basegfx::B2DHomMatrix aPattern;
158*64b14621SArmin Le Grand 
159*64b14621SArmin Le Grand                 // bring from unit circle [-1, -1, 1, 1] to unit range [0, 0, 1, 1]
160*64b14621SArmin Le Grand                 aPattern.scale(0.5, 0.5);
161*64b14621SArmin Le Grand                 aPattern.translate(0.5, 0.5);
162*64b14621SArmin Le Grand 
163*64b14621SArmin Le Grand                 // scale and translate in X
164*64b14621SArmin Le Grand                 aPattern.scale(mfUnitWidth, 1.0);
165*64b14621SArmin Le Grand                 aPattern.translate(mfUnitMinX, 0.0);
16696fc4b33SArmin Le Grand 
16796fc4b33SArmin Le Grand                 for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
16896fc4b33SArmin Le Grand                 {
16996fc4b33SArmin Le Grand                     const double fPos(fStripeWidth * a);
170*64b14621SArmin Le Grand                     basegfx::B2DHomMatrix aNew(aPattern);
171*64b14621SArmin Le Grand 
172*64b14621SArmin Le Grand                     // scale and translate in Y
173*64b14621SArmin Le Grand                     double fHeight(1.0 - fPos);
174*64b14621SArmin Le Grand 
175*64b14621SArmin Le Grand                     if(a + 1 == maGradientInfo.getSteps() && mfUnitMaxY > 1.0)
176*64b14621SArmin Le Grand                     {
177*64b14621SArmin Le Grand                         fHeight += mfUnitMaxY - 1.0;
178*64b14621SArmin Le Grand                     }
179*64b14621SArmin Le Grand 
180*64b14621SArmin Le Grand                     aNew.scale(1.0, fHeight);
181*64b14621SArmin Le Grand                     aNew.translate(0.0, fPos);
182*64b14621SArmin Le Grand 
183*64b14621SArmin Le Grand                     // set at target
184*64b14621SArmin Le Grand                     aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * aNew;
185*64b14621SArmin Le Grand 
186*64b14621SArmin Le Grand                     // interpolate and set color
18796fc4b33SArmin Le Grand                     aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
188*64b14621SArmin Le Grand 
18996fc4b33SArmin Le Grand                     rEntries.push_back(aB2DHomMatrixAndBColor);
19096fc4b33SArmin Le Grand                 }
19196fc4b33SArmin Le Grand             }
19296fc4b33SArmin Le Grand         }
193cdf0e10cSrcweir 
modifyBColor(const basegfx::B2DPoint & rUV,basegfx::BColor & rBColor,double &) const194*64b14621SArmin Le Grand         void GeoTexSvxGradientLinear::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
195*64b14621SArmin Le Grand         {
196cdf0e10cSrcweir             const double fScaler(basegfx::tools::getLinearGradientAlpha(rUV, maGradientInfo));
197cdf0e10cSrcweir 
1987024eca9SArmin Le Grand             rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
199*64b14621SArmin Le Grand         }
200*64b14621SArmin Le Grand     } // end of namespace texture
201cdf0e10cSrcweir } // end of namespace drawinglayer
202cdf0e10cSrcweir 
203cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
204cdf0e10cSrcweir 
205cdf0e10cSrcweir namespace drawinglayer
206cdf0e10cSrcweir {
207*64b14621SArmin Le Grand     namespace texture
208*64b14621SArmin Le Grand     {
GeoTexSvxGradientAxial(const basegfx::B2DRange & rDefinitionRange,const basegfx::B2DRange & rOutputRange,const basegfx::BColor & rStart,const basegfx::BColor & rEnd,sal_uInt32 nSteps,double fBorder,double fAngle)209*64b14621SArmin Le Grand         GeoTexSvxGradientAxial::GeoTexSvxGradientAxial(
210*64b14621SArmin Le Grand             const basegfx::B2DRange& rDefinitionRange,
211*64b14621SArmin Le Grand             const basegfx::B2DRange& rOutputRange,
21296fc4b33SArmin Le Grand             const basegfx::BColor& rStart,
21396fc4b33SArmin Le Grand             const basegfx::BColor& rEnd,
21496fc4b33SArmin Le Grand             sal_uInt32 nSteps,
21596fc4b33SArmin Le Grand             double fBorder,
21696fc4b33SArmin Le Grand             double fAngle)
217*64b14621SArmin Le Grand         :   GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder),
218*64b14621SArmin Le Grand             mfUnitMinX(0.0),
219*64b14621SArmin Le Grand             mfUnitWidth(1.0)
220*64b14621SArmin Le Grand         {
22196fc4b33SArmin Le Grand             maGradientInfo = basegfx::tools::createAxialODFGradientInfo(
222*64b14621SArmin Le Grand                 rDefinitionRange,
22396fc4b33SArmin Le Grand                 nSteps,
22496fc4b33SArmin Le Grand                 fBorder,
22596fc4b33SArmin Le Grand                 fAngle);
226cdf0e10cSrcweir 
227*64b14621SArmin Le Grand             if(rDefinitionRange != rOutputRange)
228*64b14621SArmin Le Grand             {
229*64b14621SArmin Le Grand                 basegfx::B2DRange aInvOutputRange(rOutputRange);
230*64b14621SArmin Le Grand 
231*64b14621SArmin Le Grand                 aInvOutputRange.transform(maGradientInfo.getBackTextureTransform());
232*64b14621SArmin Le Grand                 mfUnitMinX = aInvOutputRange.getMinX();
233*64b14621SArmin Le Grand                 mfUnitWidth = aInvOutputRange.getWidth();
234*64b14621SArmin Le Grand             }
235*64b14621SArmin Le Grand         }
236*64b14621SArmin Le Grand 
~GeoTexSvxGradientAxial()237*64b14621SArmin Le Grand         GeoTexSvxGradientAxial::~GeoTexSvxGradientAxial()
238*64b14621SArmin Le Grand         {
239*64b14621SArmin Le Grand         }
240cdf0e10cSrcweir 
appendTransformationsAndColors(std::vector<B2DHomMatrixAndBColor> & rEntries,basegfx::BColor & rOuterColor)24196fc4b33SArmin Le Grand         void GeoTexSvxGradientAxial::appendTransformationsAndColors(
24296fc4b33SArmin Le Grand             std::vector< B2DHomMatrixAndBColor >& rEntries,
243*64b14621SArmin Le Grand             basegfx::BColor& rOuterColor)
24496fc4b33SArmin Le Grand         {
245*64b14621SArmin Le Grand             rOuterColor = maEnd;
246cdf0e10cSrcweir 
24796fc4b33SArmin Le Grand             if(maGradientInfo.getSteps())
24896fc4b33SArmin Le Grand             {
24996fc4b33SArmin Le Grand                 const double fStripeWidth(1.0 / maGradientInfo.getSteps());
25096fc4b33SArmin Le Grand                 B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
251cdf0e10cSrcweir 
25296fc4b33SArmin Le Grand                 for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
25396fc4b33SArmin Le Grand                 {
254*64b14621SArmin Le Grand                     const double fPos(fStripeWidth * a);
255*64b14621SArmin Le Grand                     basegfx::B2DHomMatrix aNew;
256*64b14621SArmin Le Grand 
257*64b14621SArmin Le Grand                     // bring in X from unit circle [-1, -1, 1, 1] to unit range [0, 0, 1, 1]
258*64b14621SArmin Le Grand                     aNew.scale(0.5, 1.0);
259*64b14621SArmin Le Grand                     aNew.translate(0.5, 0.0);
260*64b14621SArmin Le Grand 
261*64b14621SArmin Le Grand                     // scale/translate in X
262*64b14621SArmin Le Grand                     aNew.scale(mfUnitWidth, 1.0);
263*64b14621SArmin Le Grand                     aNew.translate(mfUnitMinX, 0.0);
264*64b14621SArmin Le Grand 
265*64b14621SArmin Le Grand                     // already centerd in Y on X-Axis, just scale in Y
266*64b14621SArmin Le Grand                     aNew.scale(1.0, 1.0 - fPos);
267*64b14621SArmin Le Grand 
268*64b14621SArmin Le Grand                     // set at target
269*64b14621SArmin Le Grand                     aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * aNew;
270*64b14621SArmin Le Grand 
271*64b14621SArmin Le Grand                     // interpolate and set color
27296fc4b33SArmin Le Grand                     aB2DHomMatrixAndBColor.maBColor = interpolate(maEnd, maStart, double(a) / double(maGradientInfo.getSteps() - 1));
273*64b14621SArmin Le Grand 
27496fc4b33SArmin Le Grand                     rEntries.push_back(aB2DHomMatrixAndBColor);
27596fc4b33SArmin Le Grand                 }
27696fc4b33SArmin Le Grand             }
277*64b14621SArmin Le Grand         }
278cdf0e10cSrcweir 
modifyBColor(const basegfx::B2DPoint & rUV,basegfx::BColor & rBColor,double &) const279*64b14621SArmin Le Grand         void GeoTexSvxGradientAxial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
280*64b14621SArmin Le Grand         {
281cdf0e10cSrcweir             const double fScaler(basegfx::tools::getAxialGradientAlpha(rUV, maGradientInfo));
282cdf0e10cSrcweir 
2837024eca9SArmin Le Grand             rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
284*64b14621SArmin Le Grand         }
285*64b14621SArmin Le Grand     } // end of namespace texture
286cdf0e10cSrcweir } // end of namespace drawinglayer
287cdf0e10cSrcweir 
288cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
289cdf0e10cSrcweir 
290cdf0e10cSrcweir namespace drawinglayer
291cdf0e10cSrcweir {
292*64b14621SArmin Le Grand     namespace texture
293*64b14621SArmin Le Grand     {
GeoTexSvxGradientRadial(const basegfx::B2DRange & rDefinitionRange,const basegfx::BColor & rStart,const basegfx::BColor & rEnd,sal_uInt32 nSteps,double fBorder,double fOffsetX,double fOffsetY)294*64b14621SArmin Le Grand         GeoTexSvxGradientRadial::GeoTexSvxGradientRadial(
295*64b14621SArmin Le Grand             const basegfx::B2DRange& rDefinitionRange,
29696fc4b33SArmin Le Grand             const basegfx::BColor& rStart,
29796fc4b33SArmin Le Grand             const basegfx::BColor& rEnd,
29896fc4b33SArmin Le Grand             sal_uInt32 nSteps,
29996fc4b33SArmin Le Grand             double fBorder,
30096fc4b33SArmin Le Grand             double fOffsetX,
30196fc4b33SArmin Le Grand             double fOffsetY)
302*64b14621SArmin Le Grand         :   GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder)
303*64b14621SArmin Le Grand         {
30496fc4b33SArmin Le Grand             maGradientInfo = basegfx::tools::createRadialODFGradientInfo(
305*64b14621SArmin Le Grand                 rDefinitionRange,
30696fc4b33SArmin Le Grand                 basegfx::B2DVector(fOffsetX,fOffsetY),
30796fc4b33SArmin Le Grand                 nSteps,
30896fc4b33SArmin Le Grand                 fBorder);
309*64b14621SArmin Le Grand         }
310cdf0e10cSrcweir 
~GeoTexSvxGradientRadial()311*64b14621SArmin Le Grand         GeoTexSvxGradientRadial::~GeoTexSvxGradientRadial()
312*64b14621SArmin Le Grand         {
313*64b14621SArmin Le Grand         }
314cdf0e10cSrcweir 
appendTransformationsAndColors(std::vector<B2DHomMatrixAndBColor> & rEntries,basegfx::BColor & rOuterColor)315*64b14621SArmin Le Grand         void GeoTexSvxGradientRadial::appendTransformationsAndColors(
31696fc4b33SArmin Le Grand             std::vector< B2DHomMatrixAndBColor >& rEntries,
317*64b14621SArmin Le Grand             basegfx::BColor& rOuterColor)
318*64b14621SArmin Le Grand         {
319*64b14621SArmin Le Grand             rOuterColor = maStart;
320cdf0e10cSrcweir 
32196fc4b33SArmin Le Grand             if(maGradientInfo.getSteps())
32296fc4b33SArmin Le Grand             {
32396fc4b33SArmin Le Grand                 const double fStepSize(1.0 / maGradientInfo.getSteps());
32496fc4b33SArmin Le Grand                 B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
32596fc4b33SArmin Le Grand 
32696fc4b33SArmin Le Grand                 for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
32796fc4b33SArmin Le Grand                 {
32896fc4b33SArmin Le Grand                     const double fSize(1.0 - (fStepSize * a));
32996fc4b33SArmin Le Grand                     aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::tools::createScaleB2DHomMatrix(fSize, fSize);
33096fc4b33SArmin Le Grand                     aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
33196fc4b33SArmin Le Grand                     rEntries.push_back(aB2DHomMatrixAndBColor);
33296fc4b33SArmin Le Grand                 }
33396fc4b33SArmin Le Grand             }
33496fc4b33SArmin Le Grand         }
335cdf0e10cSrcweir 
modifyBColor(const basegfx::B2DPoint & rUV,basegfx::BColor & rBColor,double &) const336*64b14621SArmin Le Grand         void GeoTexSvxGradientRadial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
337*64b14621SArmin Le Grand         {
338cdf0e10cSrcweir             const double fScaler(basegfx::tools::getRadialGradientAlpha(rUV, maGradientInfo));
339cdf0e10cSrcweir 
3407024eca9SArmin Le Grand             rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
341*64b14621SArmin Le Grand         }
342*64b14621SArmin Le Grand     } // end of namespace texture
343cdf0e10cSrcweir } // end of namespace drawinglayer
344cdf0e10cSrcweir 
345cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
346cdf0e10cSrcweir 
347cdf0e10cSrcweir namespace drawinglayer
348cdf0e10cSrcweir {
349*64b14621SArmin Le Grand     namespace texture
350*64b14621SArmin Le Grand     {
GeoTexSvxGradientElliptical(const basegfx::B2DRange & rDefinitionRange,const basegfx::BColor & rStart,const basegfx::BColor & rEnd,sal_uInt32 nSteps,double fBorder,double fOffsetX,double fOffsetY,double fAngle)351*64b14621SArmin Le Grand         GeoTexSvxGradientElliptical::GeoTexSvxGradientElliptical(
352*64b14621SArmin Le Grand             const basegfx::B2DRange& rDefinitionRange,
35396fc4b33SArmin Le Grand             const basegfx::BColor& rStart,
35496fc4b33SArmin Le Grand             const basegfx::BColor& rEnd,
35596fc4b33SArmin Le Grand             sal_uInt32 nSteps,
35696fc4b33SArmin Le Grand             double fBorder,
35796fc4b33SArmin Le Grand             double fOffsetX,
35896fc4b33SArmin Le Grand             double fOffsetY,
35996fc4b33SArmin Le Grand             double fAngle)
360*64b14621SArmin Le Grand         :   GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder)
361*64b14621SArmin Le Grand         {
36296fc4b33SArmin Le Grand             maGradientInfo = basegfx::tools::createEllipticalODFGradientInfo(
363*64b14621SArmin Le Grand                 rDefinitionRange,
36496fc4b33SArmin Le Grand                 basegfx::B2DVector(fOffsetX,fOffsetY),
36596fc4b33SArmin Le Grand                 nSteps,
36696fc4b33SArmin Le Grand                 fBorder,
36796fc4b33SArmin Le Grand                 fAngle);
368*64b14621SArmin Le Grand         }
369cdf0e10cSrcweir 
~GeoTexSvxGradientElliptical()370*64b14621SArmin Le Grand         GeoTexSvxGradientElliptical::~GeoTexSvxGradientElliptical()
371*64b14621SArmin Le Grand         {
372*64b14621SArmin Le Grand         }
373cdf0e10cSrcweir 
appendTransformationsAndColors(std::vector<B2DHomMatrixAndBColor> & rEntries,basegfx::BColor & rOuterColor)374*64b14621SArmin Le Grand         void GeoTexSvxGradientElliptical::appendTransformationsAndColors(
37596fc4b33SArmin Le Grand             std::vector< B2DHomMatrixAndBColor >& rEntries,
376*64b14621SArmin Le Grand             basegfx::BColor& rOuterColor)
377*64b14621SArmin Le Grand         {
378*64b14621SArmin Le Grand             rOuterColor = maStart;
379cdf0e10cSrcweir 
38096fc4b33SArmin Le Grand             if(maGradientInfo.getSteps())
38196fc4b33SArmin Le Grand             {
38296fc4b33SArmin Le Grand                 double fWidth(1.0);
38396fc4b33SArmin Le Grand                 double fHeight(1.0);
38496fc4b33SArmin Le Grand                 double fIncrementX(0.0);
38596fc4b33SArmin Le Grand                 double fIncrementY(0.0);
38696fc4b33SArmin Le Grand 
38796fc4b33SArmin Le Grand                 if(maGradientInfo.getAspectRatio() > 1.0)
38896fc4b33SArmin Le Grand                 {
38996fc4b33SArmin Le Grand                     fIncrementY = fHeight / maGradientInfo.getSteps();
39096fc4b33SArmin Le Grand                     fIncrementX = fIncrementY / maGradientInfo.getAspectRatio();
39196fc4b33SArmin Le Grand                 }
39296fc4b33SArmin Le Grand                 else
39396fc4b33SArmin Le Grand                 {
39496fc4b33SArmin Le Grand                     fIncrementX = fWidth / maGradientInfo.getSteps();
39596fc4b33SArmin Le Grand                     fIncrementY = fIncrementX * maGradientInfo.getAspectRatio();
39696fc4b33SArmin Le Grand                 }
39796fc4b33SArmin Le Grand 
39896fc4b33SArmin Le Grand                 B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
39996fc4b33SArmin Le Grand 
40096fc4b33SArmin Le Grand                 for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
40196fc4b33SArmin Le Grand                 {
40296fc4b33SArmin Le Grand                     // next step
40396fc4b33SArmin Le Grand                     fWidth -= fIncrementX;
40496fc4b33SArmin Le Grand                     fHeight -= fIncrementY;
40596fc4b33SArmin Le Grand 
40696fc4b33SArmin Le Grand                     aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::tools::createScaleB2DHomMatrix(fWidth, fHeight);
40796fc4b33SArmin Le Grand                     aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
40896fc4b33SArmin Le Grand                     rEntries.push_back(aB2DHomMatrixAndBColor);
40996fc4b33SArmin Le Grand                 }
41096fc4b33SArmin Le Grand             }
411*64b14621SArmin Le Grand         }
412cdf0e10cSrcweir 
modifyBColor(const basegfx::B2DPoint & rUV,basegfx::BColor & rBColor,double &) const413*64b14621SArmin Le Grand         void GeoTexSvxGradientElliptical::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
414*64b14621SArmin Le Grand         {
415cdf0e10cSrcweir             const double fScaler(basegfx::tools::getEllipticalGradientAlpha(rUV, maGradientInfo));
416cdf0e10cSrcweir 
4177024eca9SArmin Le Grand             rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
418*64b14621SArmin Le Grand         }
419*64b14621SArmin Le Grand     } // end of namespace texture
420cdf0e10cSrcweir } // end of namespace drawinglayer
421cdf0e10cSrcweir 
422cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
423cdf0e10cSrcweir 
424cdf0e10cSrcweir namespace drawinglayer
425cdf0e10cSrcweir {
426*64b14621SArmin Le Grand     namespace texture
427*64b14621SArmin Le Grand     {
GeoTexSvxGradientSquare(const basegfx::B2DRange & rDefinitionRange,const basegfx::BColor & rStart,const basegfx::BColor & rEnd,sal_uInt32 nSteps,double fBorder,double fOffsetX,double fOffsetY,double fAngle)428*64b14621SArmin Le Grand         GeoTexSvxGradientSquare::GeoTexSvxGradientSquare(
429*64b14621SArmin Le Grand             const basegfx::B2DRange& rDefinitionRange,
43096fc4b33SArmin Le Grand             const basegfx::BColor& rStart,
43196fc4b33SArmin Le Grand             const basegfx::BColor& rEnd,
43296fc4b33SArmin Le Grand             sal_uInt32 nSteps,
43396fc4b33SArmin Le Grand             double fBorder,
43496fc4b33SArmin Le Grand             double fOffsetX,
43596fc4b33SArmin Le Grand             double fOffsetY,
43696fc4b33SArmin Le Grand             double fAngle)
437*64b14621SArmin Le Grand         :   GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder)
438*64b14621SArmin Le Grand         {
43996fc4b33SArmin Le Grand             maGradientInfo = basegfx::tools::createSquareODFGradientInfo(
440*64b14621SArmin Le Grand                 rDefinitionRange,
44196fc4b33SArmin Le Grand                 basegfx::B2DVector(fOffsetX,fOffsetY),
44296fc4b33SArmin Le Grand                 nSteps,
44396fc4b33SArmin Le Grand                 fBorder,
44496fc4b33SArmin Le Grand                 fAngle);
445*64b14621SArmin Le Grand         }
446cdf0e10cSrcweir 
~GeoTexSvxGradientSquare()447*64b14621SArmin Le Grand         GeoTexSvxGradientSquare::~GeoTexSvxGradientSquare()
448*64b14621SArmin Le Grand         {
449*64b14621SArmin Le Grand         }
450cdf0e10cSrcweir 
appendTransformationsAndColors(std::vector<B2DHomMatrixAndBColor> & rEntries,basegfx::BColor & rOuterColor)451*64b14621SArmin Le Grand         void GeoTexSvxGradientSquare::appendTransformationsAndColors(
45296fc4b33SArmin Le Grand             std::vector< B2DHomMatrixAndBColor >& rEntries,
453*64b14621SArmin Le Grand             basegfx::BColor& rOuterColor)
454*64b14621SArmin Le Grand         {
455*64b14621SArmin Le Grand             rOuterColor = maStart;
456cdf0e10cSrcweir 
45796fc4b33SArmin Le Grand             if(maGradientInfo.getSteps())
45896fc4b33SArmin Le Grand             {
45996fc4b33SArmin Le Grand                 const double fStepSize(1.0 / maGradientInfo.getSteps());
46096fc4b33SArmin Le Grand                 B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
46196fc4b33SArmin Le Grand 
46296fc4b33SArmin Le Grand                 for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
46396fc4b33SArmin Le Grand                 {
46496fc4b33SArmin Le Grand                     const double fSize(1.0 - (fStepSize * a));
46596fc4b33SArmin Le Grand                     aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::tools::createScaleB2DHomMatrix(fSize, fSize);
46696fc4b33SArmin Le Grand                     aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
46796fc4b33SArmin Le Grand                     rEntries.push_back(aB2DHomMatrixAndBColor);
46896fc4b33SArmin Le Grand                 }
46996fc4b33SArmin Le Grand             }
470*64b14621SArmin Le Grand         }
471cdf0e10cSrcweir 
modifyBColor(const basegfx::B2DPoint & rUV,basegfx::BColor & rBColor,double &) const472*64b14621SArmin Le Grand         void GeoTexSvxGradientSquare::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
473*64b14621SArmin Le Grand         {
474cdf0e10cSrcweir             const double fScaler(basegfx::tools::getSquareGradientAlpha(rUV, maGradientInfo));
475cdf0e10cSrcweir 
4767024eca9SArmin Le Grand             rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
477*64b14621SArmin Le Grand         }
478*64b14621SArmin Le Grand     } // end of namespace texture
479cdf0e10cSrcweir } // end of namespace drawinglayer
480cdf0e10cSrcweir 
481cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
482cdf0e10cSrcweir 
483cdf0e10cSrcweir namespace drawinglayer
484cdf0e10cSrcweir {
485*64b14621SArmin Le Grand     namespace texture
486*64b14621SArmin Le Grand     {
GeoTexSvxGradientRect(const basegfx::B2DRange & rDefinitionRange,const basegfx::BColor & rStart,const basegfx::BColor & rEnd,sal_uInt32 nSteps,double fBorder,double fOffsetX,double fOffsetY,double fAngle)487*64b14621SArmin Le Grand         GeoTexSvxGradientRect::GeoTexSvxGradientRect(
488*64b14621SArmin Le Grand             const basegfx::B2DRange& rDefinitionRange,
48996fc4b33SArmin Le Grand             const basegfx::BColor& rStart,
49096fc4b33SArmin Le Grand             const basegfx::BColor& rEnd,
49196fc4b33SArmin Le Grand             sal_uInt32 nSteps,
49296fc4b33SArmin Le Grand             double fBorder,
49396fc4b33SArmin Le Grand             double fOffsetX,
49496fc4b33SArmin Le Grand             double fOffsetY,
49596fc4b33SArmin Le Grand             double fAngle)
496*64b14621SArmin Le Grand         :   GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder)
497*64b14621SArmin Le Grand         {
49896fc4b33SArmin Le Grand             maGradientInfo = basegfx::tools::createRectangularODFGradientInfo(
499*64b14621SArmin Le Grand                 rDefinitionRange,
50096fc4b33SArmin Le Grand                 basegfx::B2DVector(fOffsetX,fOffsetY),
50196fc4b33SArmin Le Grand                 nSteps,
50296fc4b33SArmin Le Grand                 fBorder,
50396fc4b33SArmin Le Grand                 fAngle);
504*64b14621SArmin Le Grand         }
505cdf0e10cSrcweir 
~GeoTexSvxGradientRect()506*64b14621SArmin Le Grand         GeoTexSvxGradientRect::~GeoTexSvxGradientRect()
507*64b14621SArmin Le Grand         {
508*64b14621SArmin Le Grand         }
509cdf0e10cSrcweir 
appendTransformationsAndColors(std::vector<B2DHomMatrixAndBColor> & rEntries,basegfx::BColor & rOuterColor)510*64b14621SArmin Le Grand         void GeoTexSvxGradientRect::appendTransformationsAndColors(
51196fc4b33SArmin Le Grand             std::vector< B2DHomMatrixAndBColor >& rEntries,
512*64b14621SArmin Le Grand             basegfx::BColor& rOuterColor)
513*64b14621SArmin Le Grand         {
514*64b14621SArmin Le Grand             rOuterColor = maStart;
515cdf0e10cSrcweir 
51696fc4b33SArmin Le Grand             if(maGradientInfo.getSteps())
51796fc4b33SArmin Le Grand             {
51896fc4b33SArmin Le Grand                 double fWidth(1.0);
51996fc4b33SArmin Le Grand                 double fHeight(1.0);
52096fc4b33SArmin Le Grand                 double fIncrementX(0.0);
52196fc4b33SArmin Le Grand                 double fIncrementY(0.0);
52296fc4b33SArmin Le Grand 
52396fc4b33SArmin Le Grand                 if(maGradientInfo.getAspectRatio() > 1.0)
52496fc4b33SArmin Le Grand                 {
52596fc4b33SArmin Le Grand                     fIncrementY = fHeight / maGradientInfo.getSteps();
52696fc4b33SArmin Le Grand                     fIncrementX = fIncrementY / maGradientInfo.getAspectRatio();
52796fc4b33SArmin Le Grand                 }
52896fc4b33SArmin Le Grand                 else
52996fc4b33SArmin Le Grand                 {
53096fc4b33SArmin Le Grand                     fIncrementX = fWidth / maGradientInfo.getSteps();
53196fc4b33SArmin Le Grand                     fIncrementY = fIncrementX * maGradientInfo.getAspectRatio();
53296fc4b33SArmin Le Grand                 }
53396fc4b33SArmin Le Grand 
53496fc4b33SArmin Le Grand                 B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
53596fc4b33SArmin Le Grand 
53696fc4b33SArmin Le Grand                 for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
53796fc4b33SArmin Le Grand                 {
53896fc4b33SArmin Le Grand                     // next step
53996fc4b33SArmin Le Grand                     fWidth -= fIncrementX;
54096fc4b33SArmin Le Grand                     fHeight -= fIncrementY;
54196fc4b33SArmin Le Grand 
54296fc4b33SArmin Le Grand                     aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::tools::createScaleB2DHomMatrix(fWidth, fHeight);
54396fc4b33SArmin Le Grand                     aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
54496fc4b33SArmin Le Grand                     rEntries.push_back(aB2DHomMatrixAndBColor);
54596fc4b33SArmin Le Grand                 }
54696fc4b33SArmin Le Grand             }
547*64b14621SArmin Le Grand         }
548cdf0e10cSrcweir 
modifyBColor(const basegfx::B2DPoint & rUV,basegfx::BColor & rBColor,double &) const549*64b14621SArmin Le Grand         void GeoTexSvxGradientRect::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
550*64b14621SArmin Le Grand         {
551cdf0e10cSrcweir             const double fScaler(basegfx::tools::getRectangularGradientAlpha(rUV, maGradientInfo));
552cdf0e10cSrcweir 
5537024eca9SArmin Le Grand             rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
554*64b14621SArmin Le Grand         }
555*64b14621SArmin Le Grand     } // end of namespace texture
556cdf0e10cSrcweir } // end of namespace drawinglayer
557cdf0e10cSrcweir 
558cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
559cdf0e10cSrcweir 
560cdf0e10cSrcweir namespace drawinglayer
561cdf0e10cSrcweir {
562*64b14621SArmin Le Grand     namespace texture
563*64b14621SArmin Le Grand     {
GeoTexSvxHatch(const basegfx::B2DRange & rDefinitionRange,const basegfx::B2DRange & rOutputRange,double fDistance,double fAngle)564*64b14621SArmin Le Grand         GeoTexSvxHatch::GeoTexSvxHatch(
565*64b14621SArmin Le Grand             const basegfx::B2DRange& rDefinitionRange,
566*64b14621SArmin Le Grand             const basegfx::B2DRange& rOutputRange,
56796fc4b33SArmin Le Grand             double fDistance,
56896fc4b33SArmin Le Grand             double fAngle)
569*64b14621SArmin Le Grand         :   maOutputRange(rOutputRange),
570*64b14621SArmin Le Grand             maTextureTransform(),
571*64b14621SArmin Le Grand             maBackTextureTransform(),
572*64b14621SArmin Le Grand             mfDistance(0.1),
573*64b14621SArmin Le Grand             mfAngle(fAngle),
574*64b14621SArmin Le Grand             mnSteps(10),
575*64b14621SArmin Le Grand             mbDefinitionRangeEqualsOutputRange(rDefinitionRange == rOutputRange)
576*64b14621SArmin Le Grand         {
577*64b14621SArmin Le Grand             double fTargetSizeX(rDefinitionRange.getWidth());
578*64b14621SArmin Le Grand             double fTargetSizeY(rDefinitionRange.getHeight());
579*64b14621SArmin Le Grand             double fTargetOffsetX(rDefinitionRange.getMinX());
580*64b14621SArmin Le Grand             double fTargetOffsetY(rDefinitionRange.getMinY());
581cdf0e10cSrcweir 
582cdf0e10cSrcweir             fAngle = -fAngle;
583cdf0e10cSrcweir 
584*64b14621SArmin Le Grand             // add object expansion
585*64b14621SArmin Le Grand             if(0.0 != fAngle)
586*64b14621SArmin Le Grand             {
587*64b14621SArmin Le Grand                 const double fAbsCos(fabs(cos(fAngle)));
588*64b14621SArmin Le Grand                 const double fAbsSin(fabs(sin(fAngle)));
589*64b14621SArmin Le Grand                 const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
590*64b14621SArmin Le Grand                 const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
591*64b14621SArmin Le Grand                 fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
592*64b14621SArmin Le Grand                 fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
593*64b14621SArmin Le Grand                 fTargetSizeX = fNewX;
594*64b14621SArmin Le Grand                 fTargetSizeY = fNewY;
595*64b14621SArmin Le Grand             }
596*64b14621SArmin Le Grand 
597*64b14621SArmin Le Grand             // add object scale before rotate
598*64b14621SArmin Le Grand             maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
599*64b14621SArmin Le Grand 
600*64b14621SArmin Le Grand             // add texture rotate after scale to keep perpendicular angles
601*64b14621SArmin Le Grand             if(0.0 != fAngle)
602*64b14621SArmin Le Grand             {
603*64b14621SArmin Le Grand                 basegfx::B2DPoint aCenter(0.5, 0.5);
604*64b14621SArmin Le Grand                 aCenter *= maTextureTransform;
605cdf0e10cSrcweir 
606cdf0e10cSrcweir                 maTextureTransform = basegfx::tools::createRotateAroundPoint(aCenter, fAngle)
607cdf0e10cSrcweir                     * maTextureTransform;
608*64b14621SArmin Le Grand             }
609*64b14621SArmin Le Grand 
610*64b14621SArmin Le Grand             // add object translate
611*64b14621SArmin Le Grand             maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
612*64b14621SArmin Le Grand 
613*64b14621SArmin Le Grand             // prepare height for texture
614*64b14621SArmin Le Grand             const double fSteps((0.0 != fDistance) ? fTargetSizeY / fDistance : 10.0);
615*64b14621SArmin Le Grand             mnSteps = basegfx::fround(fSteps + 0.5);
616*64b14621SArmin Le Grand             mfDistance = 1.0 / fSteps;
617*64b14621SArmin Le Grand         }
618*64b14621SArmin Le Grand 
~GeoTexSvxHatch()619*64b14621SArmin Le Grand         GeoTexSvxHatch::~GeoTexSvxHatch()
620*64b14621SArmin Le Grand         {
621*64b14621SArmin Le Grand         }
622*64b14621SArmin Le Grand 
operator ==(const GeoTexSvx & rGeoTexSvx) const623*64b14621SArmin Le Grand         bool GeoTexSvxHatch::operator==(const GeoTexSvx& rGeoTexSvx) const
624*64b14621SArmin Le Grand         {
625*64b14621SArmin Le Grand             const GeoTexSvxHatch* pCompare = dynamic_cast< const GeoTexSvxHatch* >(&rGeoTexSvx);
626*64b14621SArmin Le Grand             return (pCompare
627*64b14621SArmin Le Grand                 && maOutputRange == pCompare->maOutputRange
628*64b14621SArmin Le Grand                 && maTextureTransform == pCompare->maTextureTransform
629*64b14621SArmin Le Grand                 && mfDistance == pCompare->mfDistance
630*64b14621SArmin Le Grand                 && mfAngle == pCompare->mfAngle
631*64b14621SArmin Le Grand                 && mnSteps == pCompare->mnSteps);
632*64b14621SArmin Le Grand         }
633*64b14621SArmin Le Grand 
appendTransformations(::std::vector<basegfx::B2DHomMatrix> & rMatrices)634*64b14621SArmin Le Grand         void GeoTexSvxHatch::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
635*64b14621SArmin Le Grand         {
636*64b14621SArmin Le Grand             if(mbDefinitionRangeEqualsOutputRange)
637*64b14621SArmin Le Grand             {
638*64b14621SArmin Le Grand                 // simple hatch where the definition area equals the output area
639*64b14621SArmin Le Grand                 for(sal_uInt32 a(1); a < mnSteps; a++)
640*64b14621SArmin Le Grand                 {
641*64b14621SArmin Le Grand                     // create matrix
642*64b14621SArmin Le Grand                     const double fOffset(mfDistance * (double)a);
643*64b14621SArmin Le Grand                     basegfx::B2DHomMatrix aNew;
644*64b14621SArmin Le Grand                     aNew.set(1, 2, fOffset);
645*64b14621SArmin Le Grand                     rMatrices.push_back(maTextureTransform * aNew);
646*64b14621SArmin Le Grand                 }
647*64b14621SArmin Le Grand             }
648*64b14621SArmin Le Grand             else
649*64b14621SArmin Le Grand             {
650*64b14621SArmin Le Grand                 // output area is different from definition area, back-transform to get
651*64b14621SArmin Le Grand                 // the output area in unit coordinates and fill this with hatch lines
652*64b14621SArmin Le Grand                 // using the settings derived from the definition area
653*64b14621SArmin Le Grand                 basegfx::B2DRange aBackUnitRange(maOutputRange);
654*64b14621SArmin Le Grand 
655*64b14621SArmin Le Grand                 aBackUnitRange.transform(getBackTextureTransform());
656*64b14621SArmin Le Grand 
657*64b14621SArmin Le Grand                 // calculate vertical start value and a security maximum integer value to avoid death loops
658*64b14621SArmin Le Grand                 double fStart(basegfx::snapToNearestMultiple(aBackUnitRange.getMinY(), mfDistance));
659*64b14621SArmin Le Grand                 const sal_uInt32 nNeededIntegerSteps(basegfx::fround((aBackUnitRange.getHeight() / mfDistance) + 0.5));
660*64b14621SArmin Le Grand                 sal_uInt32 nMaxIntegerSteps(::std::min(nNeededIntegerSteps, sal_uInt32(10000)));
661*64b14621SArmin Le Grand 
662*64b14621SArmin Le Grand                 while(fStart < aBackUnitRange.getMaxY() && nMaxIntegerSteps)
663*64b14621SArmin Le Grand                 {
664*64b14621SArmin Le Grand                     // create new transform for
665*64b14621SArmin Le Grand                     basegfx::B2DHomMatrix aNew;
666*64b14621SArmin Le Grand 
667*64b14621SArmin Le Grand                     // adapt x scale and position
668*64b14621SArmin Le Grand                     //aNew.scale(aBackUnitRange.getWidth(), 1.0);
669*64b14621SArmin Le Grand                     //aNew.translate(aBackUnitRange.getMinX(), 0.0);
670*64b14621SArmin Le Grand                     aNew.set(0, 0, aBackUnitRange.getWidth());
671*64b14621SArmin Le Grand                     aNew.set(0, 2, aBackUnitRange.getMinX());
672*64b14621SArmin Le Grand 
673*64b14621SArmin Le Grand                     // adapt y position to current step
674*64b14621SArmin Le Grand                     aNew.set(1, 2, fStart);
675*64b14621SArmin Le Grand                     //aNew.translate(0.0, fStart);
676*64b14621SArmin Le Grand 
677*64b14621SArmin Le Grand                     // add new transformation
678*64b14621SArmin Le Grand                     rMatrices.push_back(maTextureTransform * aNew);
679*64b14621SArmin Le Grand 
680*64b14621SArmin Le Grand                     // next step
681*64b14621SArmin Le Grand                     fStart += mfDistance;
682*64b14621SArmin Le Grand                     nMaxIntegerSteps--;
683*64b14621SArmin Le Grand                 }
684*64b14621SArmin Le Grand             }
685*64b14621SArmin Le Grand         }
686*64b14621SArmin Le Grand 
getDistanceToHatch(const basegfx::B2DPoint & rUV) const687*64b14621SArmin Le Grand         double GeoTexSvxHatch::getDistanceToHatch(const basegfx::B2DPoint& rUV) const
688*64b14621SArmin Le Grand         {
689*64b14621SArmin Le Grand             const basegfx::B2DPoint aCoor(getBackTextureTransform() * rUV);
690*64b14621SArmin Le Grand             return fmod(aCoor.getY(), mfDistance);
691*64b14621SArmin Le Grand         }
69296fc4b33SArmin Le Grand 
getBackTextureTransform() const69396fc4b33SArmin Le Grand         const basegfx::B2DHomMatrix& GeoTexSvxHatch::getBackTextureTransform() const
69496fc4b33SArmin Le Grand         {
69596fc4b33SArmin Le Grand             if(maBackTextureTransform.isIdentity())
69696fc4b33SArmin Le Grand             {
69796fc4b33SArmin Le Grand                 const_cast< GeoTexSvxHatch* >(this)->maBackTextureTransform = maTextureTransform;
69896fc4b33SArmin Le Grand                 const_cast< GeoTexSvxHatch* >(this)->maBackTextureTransform.invert();
69996fc4b33SArmin Le Grand             }
70096fc4b33SArmin Le Grand 
70196fc4b33SArmin Le Grand             return maBackTextureTransform;
70296fc4b33SArmin Le Grand         }
703*64b14621SArmin Le Grand     } // end of namespace texture
704cdf0e10cSrcweir } // end of namespace drawinglayer
705cdf0e10cSrcweir 
706cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
707cdf0e10cSrcweir 
708cdf0e10cSrcweir namespace drawinglayer
709cdf0e10cSrcweir {
710*64b14621SArmin Le Grand     namespace texture
711*64b14621SArmin Le Grand     {
GeoTexSvxTiled(const basegfx::B2DRange & rRange,double fOffsetX,double fOffsetY)712*64b14621SArmin Le Grand         GeoTexSvxTiled::GeoTexSvxTiled(
713035a2f44SArmin Le Grand             const basegfx::B2DRange& rRange,
714035a2f44SArmin Le Grand             double fOffsetX,
715035a2f44SArmin Le Grand             double fOffsetY)
716*64b14621SArmin Le Grand         :   maRange(rRange),
717035a2f44SArmin Le Grand             mfOffsetX(basegfx::clamp(fOffsetX, 0.0, 1.0)),
718035a2f44SArmin Le Grand             mfOffsetY(basegfx::clamp(fOffsetY, 0.0, 1.0))
719*64b14621SArmin Le Grand         {
720035a2f44SArmin Le Grand             if(!basegfx::fTools::equalZero(mfOffsetX))
721035a2f44SArmin Le Grand             {
722035a2f44SArmin Le Grand                 mfOffsetY = 0.0;
723035a2f44SArmin Le Grand             }
724*64b14621SArmin Le Grand         }
725cdf0e10cSrcweir 
~GeoTexSvxTiled()726*64b14621SArmin Le Grand         GeoTexSvxTiled::~GeoTexSvxTiled()
727*64b14621SArmin Le Grand         {
728*64b14621SArmin Le Grand         }
729cdf0e10cSrcweir 
operator ==(const GeoTexSvx & rGeoTexSvx) const730*64b14621SArmin Le Grand         bool GeoTexSvxTiled::operator==(const GeoTexSvx& rGeoTexSvx) const
731*64b14621SArmin Le Grand         {
732*64b14621SArmin Le Grand             const GeoTexSvxTiled* pCompare = dynamic_cast< const GeoTexSvxTiled* >(&rGeoTexSvx);
733*64b14621SArmin Le Grand 
734035a2f44SArmin Le Grand             return (pCompare
735*64b14621SArmin Le Grand                 && maRange == pCompare->maRange
736*64b14621SArmin Le Grand                 && mfOffsetX == pCompare->mfOffsetX
737035a2f44SArmin Le Grand                 && mfOffsetY == pCompare->mfOffsetY);
738*64b14621SArmin Le Grand         }
739cdf0e10cSrcweir 
appendTransformations(::std::vector<basegfx::B2DHomMatrix> & rMatrices)740*64b14621SArmin Le Grand         void GeoTexSvxTiled::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
741*64b14621SArmin Le Grand         {
742035a2f44SArmin Le Grand             const double fWidth(maRange.getWidth());
743cdf0e10cSrcweir 
744035a2f44SArmin Le Grand             if(!basegfx::fTools::equalZero(fWidth))
745035a2f44SArmin Le Grand             {
746035a2f44SArmin Le Grand                 const double fHeight(maRange.getHeight());
747cdf0e10cSrcweir 
748035a2f44SArmin Le Grand                 if(!basegfx::fTools::equalZero(fHeight))
749035a2f44SArmin Le Grand                 {
750*64b14621SArmin Le Grand                     double fStartX(maRange.getMinX());
751*64b14621SArmin Le Grand                     double fStartY(maRange.getMinY());
752035a2f44SArmin Le Grand                     sal_Int32 nPosX(0);
753035a2f44SArmin Le Grand                     sal_Int32 nPosY(0);
754035a2f44SArmin Le Grand 
755*64b14621SArmin Le Grand                     if(basegfx::fTools::more(fStartX, 0.0))
756*64b14621SArmin Le Grand                     {
757035a2f44SArmin Le Grand                         const sal_Int32 nDiff(static_cast<sal_Int32>(floor(fStartX / fWidth)) + 1);
758035a2f44SArmin Le Grand 
759035a2f44SArmin Le Grand                         nPosX -= nDiff;
760*64b14621SArmin Le Grand                         fStartX -= nDiff * fWidth;
761*64b14621SArmin Le Grand                     }
762035a2f44SArmin Le Grand 
763*64b14621SArmin Le Grand                     if(basegfx::fTools::less(fStartX + fWidth, 0.0))
764*64b14621SArmin Le Grand                     {
765035a2f44SArmin Le Grand                         const sal_Int32 nDiff(static_cast<sal_Int32>(floor(-fStartX / fWidth)));
766035a2f44SArmin Le Grand 
767035a2f44SArmin Le Grand                         nPosX += nDiff;
768*64b14621SArmin Le Grand                         fStartX += nDiff * fWidth;
769*64b14621SArmin Le Grand                     }
770035a2f44SArmin Le Grand 
771*64b14621SArmin Le Grand                     if(basegfx::fTools::more(fStartY, 0.0))
772*64b14621SArmin Le Grand                     {
773035a2f44SArmin Le Grand                         const sal_Int32 nDiff(static_cast<sal_Int32>(floor(fStartY / fHeight)) + 1);
774035a2f44SArmin Le Grand 
775035a2f44SArmin Le Grand                         nPosY -= nDiff;
776*64b14621SArmin Le Grand                         fStartY -= nDiff * fHeight;
777*64b14621SArmin Le Grand                     }
778035a2f44SArmin Le Grand 
779*64b14621SArmin Le Grand                     if(basegfx::fTools::less(fStartY + fHeight, 0.0))
780*64b14621SArmin Le Grand                     {
781035a2f44SArmin Le Grand                         const sal_Int32 nDiff(static_cast<sal_Int32>(floor(-fStartY / fHeight)));
782035a2f44SArmin Le Grand 
783035a2f44SArmin Le Grand                         nPosY += nDiff;
784*64b14621SArmin Le Grand                         fStartY += nDiff * fHeight;
785*64b14621SArmin Le Grand                     }
786035a2f44SArmin Le Grand 
787035a2f44SArmin Le Grand                     if(!basegfx::fTools::equalZero(mfOffsetY))
788035a2f44SArmin Le Grand                     {
789035a2f44SArmin Le Grand                         for(double fPosX(fStartX); basegfx::fTools::less(fPosX, 1.0); fPosX += fWidth, nPosX++)
790035a2f44SArmin Le Grand                         {
791035a2f44SArmin Le Grand                             for(double fPosY(nPosX % 2 ? fStartY - fHeight + (mfOffsetY * fHeight) : fStartY);
792035a2f44SArmin Le Grand                                 basegfx::fTools::less(fPosY, 1.0); fPosY += fHeight)
793035a2f44SArmin Le Grand                             {
794035a2f44SArmin Le Grand                                 rMatrices.push_back(
795035a2f44SArmin Le Grand                                     basegfx::tools::createScaleTranslateB2DHomMatrix(
796035a2f44SArmin Le Grand                                         fWidth,
797035a2f44SArmin Le Grand                                         fHeight,
798035a2f44SArmin Le Grand                                         fPosX,
799035a2f44SArmin Le Grand                                         fPosY));
800035a2f44SArmin Le Grand                             }
801035a2f44SArmin Le Grand                         }
802035a2f44SArmin Le Grand                     }
803035a2f44SArmin Le Grand                     else
804035a2f44SArmin Le Grand                     {
805035a2f44SArmin Le Grand                         for(double fPosY(fStartY); basegfx::fTools::less(fPosY, 1.0); fPosY += fHeight, nPosY++)
806035a2f44SArmin Le Grand                         {
807035a2f44SArmin Le Grand                             for(double fPosX(nPosY % 2 ? fStartX - fWidth + (mfOffsetX * fWidth) : fStartX);
808035a2f44SArmin Le Grand                                 basegfx::fTools::less(fPosX, 1.0); fPosX += fWidth)
809035a2f44SArmin Le Grand                             {
810035a2f44SArmin Le Grand                                 rMatrices.push_back(
811035a2f44SArmin Le Grand                                     basegfx::tools::createScaleTranslateB2DHomMatrix(
812035a2f44SArmin Le Grand                                         fWidth,
813035a2f44SArmin Le Grand                                         fHeight,
814035a2f44SArmin Le Grand                                         fPosX,
815035a2f44SArmin Le Grand                                         fPosY));
816035a2f44SArmin Le Grand                             }
817035a2f44SArmin Le Grand                         }
818035a2f44SArmin Le Grand                     }
819035a2f44SArmin Le Grand                 }
820035a2f44SArmin Le Grand             }
821*64b14621SArmin Le Grand         }
822*64b14621SArmin Le Grand     } // end of namespace texture
823cdf0e10cSrcweir } // end of namespace drawinglayer
824cdf0e10cSrcweir 
825cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
826cdf0e10cSrcweir // eof
827