Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <drawinglayer/texture/texture.hxx>
21 : #include <drawinglayer/tools/converters.hxx>
22 : #include <basegfx/numeric/ftools.hxx>
23 : #include <basegfx/tools/gradienttools.hxx>
24 : #include <basegfx/matrix/b2dhommatrixtools.hxx>
25 :
26 : namespace drawinglayer
27 : {
28 : namespace texture
29 : {
30 1895 : GeoTexSvx::GeoTexSvx()
31 : {
32 1895 : }
33 :
34 1895 : GeoTexSvx::~GeoTexSvx()
35 : {
36 1895 : }
37 :
38 0 : bool GeoTexSvx::operator==(const GeoTexSvx& /*rGeoTexSvx*/) const
39 : {
40 : // default implementation says yes (no data -> no difference)
41 0 : return true;
42 : }
43 :
44 0 : void GeoTexSvx::modifyBColor(const basegfx::B2DPoint& /*rUV*/, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
45 : {
46 : // base implementation creates random color (for testing only, may also be pure virtual)
47 0 : rBColor.setRed(tools::getRandomColorRange());
48 0 : rBColor.setGreen(tools::getRandomColorRange());
49 0 : rBColor.setBlue(tools::getRandomColorRange());
50 0 : }
51 :
52 367456 : void GeoTexSvx::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const
53 : {
54 : // base implementation uses inverse of luminance of solved color (for testing only, may also be pure virtual)
55 367456 : basegfx::BColor aBaseColor;
56 367456 : modifyBColor(rUV, aBaseColor, rfOpacity);
57 367456 : rfOpacity = 1.0 - aBaseColor.luminance();
58 367456 : }
59 : } // end of namespace texture
60 : } // end of namespace drawinglayer
61 :
62 :
63 :
64 : namespace drawinglayer
65 : {
66 : namespace texture
67 : {
68 1805 : GeoTexSvxGradient::GeoTexSvxGradient(
69 : const basegfx::B2DRange& rDefinitionRange,
70 : const basegfx::BColor& rStart,
71 : const basegfx::BColor& rEnd,
72 : sal_uInt32 /* nSteps */,
73 : double fBorder)
74 : : GeoTexSvx(),
75 : maGradientInfo(),
76 : maDefinitionRange(rDefinitionRange),
77 : maStart(rStart),
78 : maEnd(rEnd),
79 1805 : mfBorder(fBorder)
80 : {
81 1805 : }
82 :
83 1805 : GeoTexSvxGradient::~GeoTexSvxGradient()
84 : {
85 1805 : }
86 :
87 0 : bool GeoTexSvxGradient::operator==(const GeoTexSvx& rGeoTexSvx) const
88 : {
89 0 : const GeoTexSvxGradient* pCompare = dynamic_cast< const GeoTexSvxGradient* >(&rGeoTexSvx);
90 :
91 : return (pCompare
92 0 : && maGradientInfo == pCompare->maGradientInfo
93 0 : && maDefinitionRange == pCompare->maDefinitionRange
94 0 : && mfBorder == pCompare->mfBorder);
95 : }
96 : } // end of namespace texture
97 : } // end of namespace drawinglayer
98 :
99 :
100 :
101 : namespace drawinglayer
102 : {
103 : namespace texture
104 : {
105 1424 : GeoTexSvxGradientLinear::GeoTexSvxGradientLinear(
106 : const basegfx::B2DRange& rDefinitionRange,
107 : const basegfx::B2DRange& rOutputRange,
108 : const basegfx::BColor& rStart,
109 : const basegfx::BColor& rEnd,
110 : sal_uInt32 nSteps,
111 : double fBorder,
112 : double fAngle)
113 : : GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder),
114 : mfUnitMinX(0.0),
115 : mfUnitWidth(1.0),
116 1424 : mfUnitMaxY(1.0)
117 : {
118 2848 : maGradientInfo = basegfx::tools::createLinearODFGradientInfo(
119 : rDefinitionRange,
120 : nSteps,
121 : fBorder,
122 1424 : fAngle);
123 :
124 1424 : if(rDefinitionRange != rOutputRange)
125 : {
126 4 : basegfx::B2DRange aInvOutputRange(rOutputRange);
127 :
128 4 : aInvOutputRange.transform(maGradientInfo.getBackTextureTransform());
129 4 : mfUnitMinX = aInvOutputRange.getMinX();
130 4 : mfUnitWidth = aInvOutputRange.getWidth();
131 4 : mfUnitMaxY = aInvOutputRange.getMaxY();
132 : }
133 1424 : }
134 :
135 1444 : GeoTexSvxGradientLinear::~GeoTexSvxGradientLinear()
136 : {
137 1444 : }
138 :
139 1404 : void GeoTexSvxGradientLinear::appendTransformationsAndColors(
140 : std::vector< B2DHomMatrixAndBColor >& rEntries,
141 : basegfx::BColor& rOuterColor)
142 : {
143 1404 : rOuterColor = maStart;
144 :
145 1404 : if(maGradientInfo.getSteps())
146 : {
147 1404 : const double fStripeWidth(1.0 / maGradientInfo.getSteps());
148 1404 : B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
149 2808 : basegfx::B2DHomMatrix aPattern;
150 :
151 : // bring from unit circle [-1, -1, 1, 1] to unit range [0, 0, 1, 1]
152 1404 : aPattern.scale(0.5, 0.5);
153 1404 : aPattern.translate(0.5, 0.5);
154 :
155 : // scale and translate in X
156 1404 : aPattern.scale(mfUnitWidth, 1.0);
157 1404 : aPattern.translate(mfUnitMinX, 0.0);
158 :
159 174865 : for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
160 : {
161 173461 : const double fPos(fStripeWidth * a);
162 173461 : basegfx::B2DHomMatrix aNew(aPattern);
163 :
164 : // scale and translate in Y
165 173461 : double fHeight(1.0 - fPos);
166 :
167 173461 : if(a + 1 == maGradientInfo.getSteps() && mfUnitMaxY > 1.0)
168 : {
169 4 : fHeight += mfUnitMaxY - 1.0;
170 : }
171 :
172 173461 : aNew.scale(1.0, fHeight);
173 173461 : aNew.translate(0.0, fPos);
174 :
175 : // set at target
176 173461 : aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * aNew;
177 :
178 : // interpolate and set color
179 173461 : aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
180 :
181 173461 : rEntries.push_back(aB2DHomMatrixAndBColor);
182 174865 : }
183 : }
184 1404 : }
185 :
186 183639 : void GeoTexSvxGradientLinear::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
187 : {
188 183639 : const double fScaler(basegfx::tools::getLinearGradientAlpha(rUV, maGradientInfo));
189 :
190 183639 : rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
191 183639 : }
192 : } // end of namespace texture
193 : } // end of namespace drawinglayer
194 :
195 :
196 :
197 : namespace drawinglayer
198 : {
199 : namespace texture
200 : {
201 381 : GeoTexSvxGradientAxial::GeoTexSvxGradientAxial(
202 : const basegfx::B2DRange& rDefinitionRange,
203 : const basegfx::B2DRange& rOutputRange,
204 : const basegfx::BColor& rStart,
205 : const basegfx::BColor& rEnd,
206 : sal_uInt32 nSteps,
207 : double fBorder,
208 : double fAngle)
209 : : GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder),
210 : mfUnitMinX(0.0),
211 381 : mfUnitWidth(1.0)
212 : {
213 762 : maGradientInfo = basegfx::tools::createAxialODFGradientInfo(
214 : rDefinitionRange,
215 : nSteps,
216 : fBorder,
217 381 : fAngle);
218 :
219 381 : if(rDefinitionRange != rOutputRange)
220 : {
221 2 : basegfx::B2DRange aInvOutputRange(rOutputRange);
222 :
223 2 : aInvOutputRange.transform(maGradientInfo.getBackTextureTransform());
224 2 : mfUnitMinX = aInvOutputRange.getMinX();
225 2 : mfUnitWidth = aInvOutputRange.getWidth();
226 : }
227 381 : }
228 :
229 401 : GeoTexSvxGradientAxial::~GeoTexSvxGradientAxial()
230 : {
231 401 : }
232 :
233 361 : void GeoTexSvxGradientAxial::appendTransformationsAndColors(
234 : std::vector< B2DHomMatrixAndBColor >& rEntries,
235 : basegfx::BColor& rOuterColor)
236 : {
237 361 : rOuterColor = maEnd;
238 :
239 361 : if(maGradientInfo.getSteps())
240 : {
241 361 : const double fStripeWidth(1.0 / maGradientInfo.getSteps());
242 361 : B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
243 :
244 45847 : for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
245 : {
246 45486 : const double fPos(fStripeWidth * a);
247 45486 : basegfx::B2DHomMatrix aNew;
248 :
249 : // bring in X from unit circle [-1, -1, 1, 1] to unit range [0, 0, 1, 1]
250 45486 : aNew.scale(0.5, 1.0);
251 45486 : aNew.translate(0.5, 0.0);
252 :
253 : // scale/translate in X
254 45486 : aNew.scale(mfUnitWidth, 1.0);
255 45486 : aNew.translate(mfUnitMinX, 0.0);
256 :
257 : // already centerd in Y on X-Axis, just scale in Y
258 45486 : aNew.scale(1.0, 1.0 - fPos);
259 :
260 : // set at target
261 45486 : aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * aNew;
262 :
263 : // interpolate and set color
264 45486 : aB2DHomMatrixAndBColor.maBColor = interpolate(maEnd, maStart, double(a) / double(maGradientInfo.getSteps() - 1));
265 :
266 45486 : rEntries.push_back(aB2DHomMatrixAndBColor);
267 45847 : }
268 : }
269 361 : }
270 :
271 183817 : void GeoTexSvxGradientAxial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
272 : {
273 183817 : const double fScaler(basegfx::tools::getAxialGradientAlpha(rUV, maGradientInfo));
274 :
275 183817 : rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
276 183817 : }
277 : } // end of namespace texture
278 : } // end of namespace drawinglayer
279 :
280 :
281 :
282 : namespace drawinglayer
283 : {
284 : namespace texture
285 : {
286 0 : 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 0 : : GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder)
295 : {
296 0 : maGradientInfo = basegfx::tools::createRadialODFGradientInfo(
297 : rDefinitionRange,
298 : basegfx::B2DVector(fOffsetX,fOffsetY),
299 : nSteps,
300 0 : fBorder);
301 0 : }
302 :
303 0 : GeoTexSvxGradientRadial::~GeoTexSvxGradientRadial()
304 : {
305 0 : }
306 :
307 0 : void GeoTexSvxGradientRadial::appendTransformationsAndColors(
308 : std::vector< B2DHomMatrixAndBColor >& rEntries,
309 : basegfx::BColor& rOuterColor)
310 : {
311 0 : rOuterColor = maStart;
312 :
313 0 : if(maGradientInfo.getSteps())
314 : {
315 0 : const double fStepSize(1.0 / maGradientInfo.getSteps());
316 0 : B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
317 :
318 0 : for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
319 : {
320 0 : const double fSize(1.0 - (fStepSize * a));
321 0 : aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::tools::createScaleB2DHomMatrix(fSize, fSize);
322 0 : aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
323 0 : rEntries.push_back(aB2DHomMatrixAndBColor);
324 0 : }
325 : }
326 0 : }
327 :
328 0 : void GeoTexSvxGradientRadial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
329 : {
330 0 : const double fScaler(basegfx::tools::getRadialGradientAlpha(rUV, maGradientInfo));
331 :
332 0 : rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
333 0 : }
334 : } // end of namespace texture
335 : } // end of namespace drawinglayer
336 :
337 :
338 :
339 : namespace drawinglayer
340 : {
341 : namespace texture
342 : {
343 0 : GeoTexSvxGradientElliptical::GeoTexSvxGradientElliptical(
344 : const basegfx::B2DRange& rDefinitionRange,
345 : const basegfx::BColor& rStart,
346 : const basegfx::BColor& rEnd,
347 : sal_uInt32 nSteps,
348 : double fBorder,
349 : double fOffsetX,
350 : double fOffsetY,
351 : double fAngle)
352 0 : : GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder)
353 : {
354 0 : maGradientInfo = basegfx::tools::createEllipticalODFGradientInfo(
355 : rDefinitionRange,
356 : basegfx::B2DVector(fOffsetX,fOffsetY),
357 : nSteps,
358 : fBorder,
359 0 : fAngle);
360 0 : }
361 :
362 0 : GeoTexSvxGradientElliptical::~GeoTexSvxGradientElliptical()
363 : {
364 0 : }
365 :
366 0 : void GeoTexSvxGradientElliptical::appendTransformationsAndColors(
367 : std::vector< B2DHomMatrixAndBColor >& rEntries,
368 : basegfx::BColor& rOuterColor)
369 : {
370 0 : rOuterColor = maStart;
371 :
372 0 : if(maGradientInfo.getSteps())
373 : {
374 0 : double fWidth(1.0);
375 0 : double fHeight(1.0);
376 0 : double fIncrementX(0.0);
377 0 : double fIncrementY(0.0);
378 :
379 0 : if(maGradientInfo.getAspectRatio() > 1.0)
380 : {
381 0 : fIncrementY = fHeight / maGradientInfo.getSteps();
382 0 : fIncrementX = fIncrementY / maGradientInfo.getAspectRatio();
383 : }
384 : else
385 : {
386 0 : fIncrementX = fWidth / maGradientInfo.getSteps();
387 0 : fIncrementY = fIncrementX * maGradientInfo.getAspectRatio();
388 : }
389 :
390 0 : B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
391 :
392 0 : for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
393 : {
394 : // next step
395 0 : fWidth -= fIncrementX;
396 0 : fHeight -= fIncrementY;
397 :
398 0 : aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::tools::createScaleB2DHomMatrix(fWidth, fHeight);
399 0 : aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
400 0 : rEntries.push_back(aB2DHomMatrixAndBColor);
401 0 : }
402 : }
403 0 : }
404 :
405 0 : void GeoTexSvxGradientElliptical::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
406 : {
407 0 : const double fScaler(basegfx::tools::getEllipticalGradientAlpha(rUV, maGradientInfo));
408 :
409 0 : rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
410 0 : }
411 : } // end of namespace texture
412 : } // end of namespace drawinglayer
413 :
414 :
415 :
416 : namespace drawinglayer
417 : {
418 : namespace texture
419 : {
420 0 : GeoTexSvxGradientSquare::GeoTexSvxGradientSquare(
421 : const basegfx::B2DRange& rDefinitionRange,
422 : const basegfx::BColor& rStart,
423 : const basegfx::BColor& rEnd,
424 : sal_uInt32 nSteps,
425 : double fBorder,
426 : double fOffsetX,
427 : double fOffsetY,
428 : double fAngle)
429 0 : : GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder)
430 : {
431 0 : maGradientInfo = basegfx::tools::createSquareODFGradientInfo(
432 : rDefinitionRange,
433 : basegfx::B2DVector(fOffsetX,fOffsetY),
434 : nSteps,
435 : fBorder,
436 0 : fAngle);
437 0 : }
438 :
439 0 : GeoTexSvxGradientSquare::~GeoTexSvxGradientSquare()
440 : {
441 0 : }
442 :
443 0 : void GeoTexSvxGradientSquare::appendTransformationsAndColors(
444 : std::vector< B2DHomMatrixAndBColor >& rEntries,
445 : basegfx::BColor& rOuterColor)
446 : {
447 0 : rOuterColor = maStart;
448 :
449 0 : if(maGradientInfo.getSteps())
450 : {
451 0 : const double fStepSize(1.0 / maGradientInfo.getSteps());
452 0 : B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
453 :
454 0 : for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
455 : {
456 0 : const double fSize(1.0 - (fStepSize * a));
457 0 : aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::tools::createScaleB2DHomMatrix(fSize, fSize);
458 0 : aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
459 0 : rEntries.push_back(aB2DHomMatrixAndBColor);
460 0 : }
461 : }
462 0 : }
463 :
464 0 : void GeoTexSvxGradientSquare::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
465 : {
466 0 : const double fScaler(basegfx::tools::getSquareGradientAlpha(rUV, maGradientInfo));
467 :
468 0 : rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
469 0 : }
470 : } // end of namespace texture
471 : } // end of namespace drawinglayer
472 :
473 :
474 :
475 : namespace drawinglayer
476 : {
477 : namespace texture
478 : {
479 0 : GeoTexSvxGradientRect::GeoTexSvxGradientRect(
480 : const basegfx::B2DRange& rDefinitionRange,
481 : const basegfx::BColor& rStart,
482 : const basegfx::BColor& rEnd,
483 : sal_uInt32 nSteps,
484 : double fBorder,
485 : double fOffsetX,
486 : double fOffsetY,
487 : double fAngle)
488 0 : : GeoTexSvxGradient(rDefinitionRange, rStart, rEnd, nSteps, fBorder)
489 : {
490 0 : maGradientInfo = basegfx::tools::createRectangularODFGradientInfo(
491 : rDefinitionRange,
492 : basegfx::B2DVector(fOffsetX,fOffsetY),
493 : nSteps,
494 : fBorder,
495 0 : fAngle);
496 0 : }
497 :
498 0 : GeoTexSvxGradientRect::~GeoTexSvxGradientRect()
499 : {
500 0 : }
501 :
502 0 : void GeoTexSvxGradientRect::appendTransformationsAndColors(
503 : std::vector< B2DHomMatrixAndBColor >& rEntries,
504 : basegfx::BColor& rOuterColor)
505 : {
506 0 : rOuterColor = maStart;
507 :
508 0 : if(maGradientInfo.getSteps())
509 : {
510 0 : double fWidth(1.0);
511 0 : double fHeight(1.0);
512 0 : double fIncrementX(0.0);
513 0 : double fIncrementY(0.0);
514 :
515 0 : if(maGradientInfo.getAspectRatio() > 1.0)
516 : {
517 0 : fIncrementY = fHeight / maGradientInfo.getSteps();
518 0 : fIncrementX = fIncrementY / maGradientInfo.getAspectRatio();
519 : }
520 : else
521 : {
522 0 : fIncrementX = fWidth / maGradientInfo.getSteps();
523 0 : fIncrementY = fIncrementX * maGradientInfo.getAspectRatio();
524 : }
525 :
526 0 : B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
527 :
528 0 : for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
529 : {
530 : // next step
531 0 : fWidth -= fIncrementX;
532 0 : fHeight -= fIncrementY;
533 :
534 0 : aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::tools::createScaleB2DHomMatrix(fWidth, fHeight);
535 0 : aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
536 0 : rEntries.push_back(aB2DHomMatrixAndBColor);
537 0 : }
538 : }
539 0 : }
540 :
541 0 : void GeoTexSvxGradientRect::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
542 : {
543 0 : const double fScaler(basegfx::tools::getRectangularGradientAlpha(rUV, maGradientInfo));
544 :
545 0 : rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
546 0 : }
547 : } // end of namespace texture
548 : } // end of namespace drawinglayer
549 :
550 :
551 :
552 : namespace drawinglayer
553 : {
554 : namespace texture
555 : {
556 66 : GeoTexSvxHatch::GeoTexSvxHatch(
557 : const basegfx::B2DRange& rDefinitionRange,
558 : const basegfx::B2DRange& rOutputRange,
559 : double fDistance,
560 : double fAngle)
561 : : maOutputRange(rOutputRange),
562 : maTextureTransform(),
563 : maBackTextureTransform(),
564 : mfDistance(0.1),
565 : mfAngle(fAngle),
566 : mnSteps(10),
567 66 : mbDefinitionRangeEqualsOutputRange(rDefinitionRange == rOutputRange)
568 : {
569 66 : double fTargetSizeX(rDefinitionRange.getWidth());
570 66 : double fTargetSizeY(rDefinitionRange.getHeight());
571 66 : double fTargetOffsetX(rDefinitionRange.getMinX());
572 66 : double fTargetOffsetY(rDefinitionRange.getMinY());
573 :
574 66 : fAngle = -fAngle;
575 :
576 : // add object expansion
577 66 : if(0.0 != fAngle)
578 : {
579 0 : const double fAbsCos(fabs(cos(fAngle)));
580 0 : const double fAbsSin(fabs(sin(fAngle)));
581 0 : const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
582 0 : const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
583 0 : fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
584 0 : fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
585 0 : fTargetSizeX = fNewX;
586 0 : fTargetSizeY = fNewY;
587 : }
588 :
589 : // add object scale before rotate
590 66 : maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
591 :
592 : // add texture rotate after scale to keep perpendicular angles
593 66 : if(0.0 != fAngle)
594 : {
595 0 : basegfx::B2DPoint aCenter(0.5, 0.5);
596 0 : aCenter *= maTextureTransform;
597 :
598 0 : maTextureTransform = basegfx::tools::createRotateAroundPoint(aCenter, fAngle)
599 0 : * maTextureTransform;
600 : }
601 :
602 : // add object translate
603 66 : maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
604 :
605 : // prepare height for texture
606 66 : const double fSteps((0.0 != fDistance) ? fTargetSizeY / fDistance : 10.0);
607 66 : mnSteps = basegfx::fround(fSteps + 0.5);
608 66 : mfDistance = 1.0 / fSteps;
609 66 : }
610 :
611 86 : GeoTexSvxHatch::~GeoTexSvxHatch()
612 : {
613 86 : }
614 :
615 0 : bool GeoTexSvxHatch::operator==(const GeoTexSvx& rGeoTexSvx) const
616 : {
617 0 : const GeoTexSvxHatch* pCompare = dynamic_cast< const GeoTexSvxHatch* >(&rGeoTexSvx);
618 : return (pCompare
619 0 : && maOutputRange == pCompare->maOutputRange
620 0 : && maTextureTransform == pCompare->maTextureTransform
621 0 : && mfDistance == pCompare->mfDistance
622 0 : && mfAngle == pCompare->mfAngle
623 0 : && mnSteps == pCompare->mnSteps);
624 : }
625 :
626 46 : void GeoTexSvxHatch::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
627 : {
628 46 : if(mbDefinitionRangeEqualsOutputRange)
629 : {
630 : // simple hatch where the definition area equals the output area
631 1880 : for(sal_uInt32 a(1); a < mnSteps; a++)
632 : {
633 : // create matrix
634 1840 : const double fOffset(mfDistance * (double)a);
635 1840 : basegfx::B2DHomMatrix aNew;
636 1840 : aNew.set(1, 2, fOffset);
637 1840 : rMatrices.push_back(maTextureTransform * aNew);
638 1840 : }
639 : }
640 : else
641 : {
642 : // output area is different from definition area, back-transform to get
643 : // the output area in unit coordinates and fill this with hatch lines
644 : // using the settings derived from the definition area
645 6 : basegfx::B2DRange aBackUnitRange(maOutputRange);
646 :
647 6 : aBackUnitRange.transform(getBackTextureTransform());
648 :
649 : // calculate vertical start value and a security maximum integer value to avoid death loops
650 6 : double fStart(basegfx::snapToNearestMultiple(aBackUnitRange.getMinY(), mfDistance));
651 6 : const sal_uInt32 nNeededIntegerSteps(basegfx::fround((aBackUnitRange.getHeight() / mfDistance) + 0.5));
652 6 : sal_uInt32 nMaxIntegerSteps(::std::min(nNeededIntegerSteps, sal_uInt32(10000)));
653 :
654 90 : while(fStart < aBackUnitRange.getMaxY() && nMaxIntegerSteps)
655 : {
656 : // create new transform for
657 78 : basegfx::B2DHomMatrix aNew;
658 :
659 : // adapt x scale and position
660 : //aNew.scale(aBackUnitRange.getWidth(), 1.0);
661 : //aNew.translate(aBackUnitRange.getMinX(), 0.0);
662 78 : aNew.set(0, 0, aBackUnitRange.getWidth());
663 78 : aNew.set(0, 2, aBackUnitRange.getMinX());
664 :
665 : // adapt y position to current step
666 78 : aNew.set(1, 2, fStart);
667 : //aNew.translate(0.0, fStart);
668 :
669 : // add new transformation
670 78 : rMatrices.push_back(maTextureTransform * aNew);
671 :
672 : // next step
673 78 : fStart += mfDistance;
674 78 : nMaxIntegerSteps--;
675 78 : }
676 : }
677 46 : }
678 :
679 123447 : double GeoTexSvxHatch::getDistanceToHatch(const basegfx::B2DPoint& rUV) const
680 : {
681 123447 : const basegfx::B2DPoint aCoor(getBackTextureTransform() * rUV);
682 123447 : return fmod(aCoor.getY(), mfDistance);
683 : }
684 :
685 123453 : const basegfx::B2DHomMatrix& GeoTexSvxHatch::getBackTextureTransform() const
686 : {
687 123453 : if(maBackTextureTransform.isIdentity())
688 : {
689 26 : const_cast< GeoTexSvxHatch* >(this)->maBackTextureTransform = maTextureTransform;
690 26 : const_cast< GeoTexSvxHatch* >(this)->maBackTextureTransform.invert();
691 : }
692 :
693 123453 : return maBackTextureTransform;
694 : }
695 : } // end of namespace texture
696 : } // end of namespace drawinglayer
697 :
698 :
699 :
700 : namespace drawinglayer
701 : {
702 : namespace texture
703 : {
704 4 : GeoTexSvxTiled::GeoTexSvxTiled(
705 : const basegfx::B2DRange& rRange,
706 : double fOffsetX,
707 : double fOffsetY)
708 : : maRange(rRange),
709 8 : mfOffsetX(basegfx::clamp(fOffsetX, 0.0, 1.0)),
710 12 : mfOffsetY(basegfx::clamp(fOffsetY, 0.0, 1.0))
711 : {
712 4 : if(!basegfx::fTools::equalZero(mfOffsetX))
713 : {
714 0 : mfOffsetY = 0.0;
715 : }
716 4 : }
717 :
718 4 : GeoTexSvxTiled::~GeoTexSvxTiled()
719 : {
720 4 : }
721 :
722 0 : bool GeoTexSvxTiled::operator==(const GeoTexSvx& rGeoTexSvx) const
723 : {
724 0 : const GeoTexSvxTiled* pCompare = dynamic_cast< const GeoTexSvxTiled* >(&rGeoTexSvx);
725 :
726 : return (pCompare
727 0 : && maRange == pCompare->maRange
728 0 : && mfOffsetX == pCompare->mfOffsetX
729 0 : && mfOffsetY == pCompare->mfOffsetY);
730 : }
731 :
732 4 : void GeoTexSvxTiled::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
733 : {
734 4 : const double fWidth(maRange.getWidth());
735 :
736 4 : if(!basegfx::fTools::equalZero(fWidth))
737 : {
738 4 : const double fHeight(maRange.getHeight());
739 :
740 4 : if(!basegfx::fTools::equalZero(fHeight))
741 : {
742 4 : double fStartX(maRange.getMinX());
743 4 : double fStartY(maRange.getMinY());
744 4 : sal_Int32 nPosX(0);
745 4 : sal_Int32 nPosY(0);
746 :
747 4 : if(basegfx::fTools::more(fStartX, 0.0))
748 : {
749 1 : const sal_Int32 nDiff(static_cast<sal_Int32>(floor(fStartX / fWidth)) + 1);
750 :
751 1 : nPosX -= nDiff;
752 1 : fStartX -= nDiff * fWidth;
753 : }
754 :
755 4 : if(basegfx::fTools::less(fStartX + fWidth, 0.0))
756 : {
757 0 : const sal_Int32 nDiff(static_cast<sal_Int32>(floor(-fStartX / fWidth)));
758 :
759 0 : nPosX += nDiff;
760 0 : fStartX += nDiff * fWidth;
761 : }
762 :
763 4 : if(basegfx::fTools::more(fStartY, 0.0))
764 : {
765 1 : const sal_Int32 nDiff(static_cast<sal_Int32>(floor(fStartY / fHeight)) + 1);
766 :
767 1 : nPosY -= nDiff;
768 1 : fStartY -= nDiff * fHeight;
769 : }
770 :
771 4 : if(basegfx::fTools::less(fStartY + fHeight, 0.0))
772 : {
773 0 : const sal_Int32 nDiff(static_cast<sal_Int32>(floor(-fStartY / fHeight)));
774 :
775 0 : nPosY += nDiff;
776 0 : fStartY += nDiff * fHeight;
777 : }
778 :
779 4 : if(!basegfx::fTools::equalZero(mfOffsetY))
780 : {
781 0 : for(double fPosX(fStartX); basegfx::fTools::less(fPosX, 1.0); fPosX += fWidth, nPosX++)
782 : {
783 0 : for(double fPosY(nPosX % 2 ? fStartY - fHeight + (mfOffsetY * fHeight) : fStartY);
784 0 : basegfx::fTools::less(fPosY, 1.0); fPosY += fHeight)
785 : {
786 : rMatrices.push_back(
787 : basegfx::tools::createScaleTranslateB2DHomMatrix(
788 : fWidth,
789 : fHeight,
790 : fPosX,
791 0 : fPosY));
792 : }
793 : }
794 : }
795 : else
796 : {
797 20 : for(double fPosY(fStartY); basegfx::fTools::less(fPosY, 1.0); fPosY += fHeight, nPosY++)
798 : {
799 1050 : for(double fPosX(nPosY % 2 ? fStartX - fWidth + (mfOffsetX * fWidth) : fStartX);
800 700 : basegfx::fTools::less(fPosX, 1.0); fPosX += fWidth)
801 : {
802 : rMatrices.push_back(
803 : basegfx::tools::createScaleTranslateB2DHomMatrix(
804 : fWidth,
805 : fHeight,
806 : fPosX,
807 334 : fPosY));
808 : }
809 : }
810 : }
811 : }
812 : }
813 4 : }
814 : } // end of namespace texture
815 : } // end of namespace drawinglayer
816 :
817 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|