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 491 : GeoTexSvx::GeoTexSvx()
31 : {
32 491 : }
33 :
34 491 : GeoTexSvx::~GeoTexSvx()
35 : {
36 491 : }
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 69448 : 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 69448 : basegfx::BColor aBaseColor;
56 69448 : modifyBColor(rUV, aBaseColor, rfOpacity);
57 69448 : rfOpacity = 1.0 - aBaseColor.luminance();
58 69448 : }
59 : } // end of namespace texture
60 : } // end of namespace drawinglayer
61 :
62 :
63 :
64 : namespace drawinglayer
65 : {
66 : namespace texture
67 : {
68 473 : 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 473 : mfBorder(fBorder)
80 : {
81 473 : }
82 :
83 473 : GeoTexSvxGradient::~GeoTexSvxGradient()
84 : {
85 473 : }
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 360 : 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 360 : mfUnitMaxY(1.0)
117 : {
118 720 : maGradientInfo = basegfx::tools::createLinearODFGradientInfo(
119 : rDefinitionRange,
120 : nSteps,
121 : fBorder,
122 360 : fAngle);
123 :
124 360 : if(rDefinitionRange != rOutputRange)
125 : {
126 2 : basegfx::B2DRange aInvOutputRange(rOutputRange);
127 :
128 2 : aInvOutputRange.transform(maGradientInfo.getBackTextureTransform());
129 2 : mfUnitMinX = aInvOutputRange.getMinX();
130 2 : mfUnitWidth = aInvOutputRange.getWidth();
131 2 : mfUnitMaxY = aInvOutputRange.getMaxY();
132 : }
133 360 : }
134 :
135 364 : GeoTexSvxGradientLinear::~GeoTexSvxGradientLinear()
136 : {
137 364 : }
138 :
139 356 : void GeoTexSvxGradientLinear::appendTransformationsAndColors(
140 : std::vector< B2DHomMatrixAndBColor >& rEntries,
141 : basegfx::BColor& rOuterColor)
142 : {
143 356 : rOuterColor = maStart;
144 :
145 356 : if(maGradientInfo.getSteps())
146 : {
147 356 : const double fStripeWidth(1.0 / maGradientInfo.getSteps());
148 356 : B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
149 712 : basegfx::B2DHomMatrix aPattern;
150 :
151 : // bring from unit circle [-1, -1, 1, 1] to unit range [0, 0, 1, 1]
152 356 : aPattern.scale(0.5, 0.5);
153 356 : aPattern.translate(0.5, 0.5);
154 :
155 : // scale and translate in X
156 356 : aPattern.scale(mfUnitWidth, 1.0);
157 356 : aPattern.translate(mfUnitMinX, 0.0);
158 :
159 44910 : for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
160 : {
161 44554 : const double fPos(fStripeWidth * a);
162 44554 : basegfx::B2DHomMatrix aNew(aPattern);
163 :
164 : // scale and translate in Y
165 44554 : double fHeight(1.0 - fPos);
166 :
167 44554 : if(a + 1 == maGradientInfo.getSteps() && mfUnitMaxY > 1.0)
168 : {
169 0 : fHeight += mfUnitMaxY - 1.0;
170 : }
171 :
172 44554 : aNew.scale(1.0, fHeight);
173 44554 : aNew.translate(0.0, fPos);
174 :
175 : // set at target
176 44554 : aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * aNew;
177 :
178 : // interpolate and set color
179 44554 : aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(maGradientInfo.getSteps() - 1));
180 :
181 44554 : rEntries.push_back(aB2DHomMatrixAndBColor);
182 44910 : }
183 : }
184 356 : }
185 :
186 34713 : void GeoTexSvxGradientLinear::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
187 : {
188 34713 : const double fScaler(basegfx::tools::getLinearGradientAlpha(rUV, maGradientInfo));
189 :
190 34713 : rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
191 34713 : }
192 : } // end of namespace texture
193 : } // end of namespace drawinglayer
194 :
195 :
196 :
197 : namespace drawinglayer
198 : {
199 : namespace texture
200 : {
201 113 : 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 113 : mfUnitWidth(1.0)
212 : {
213 226 : maGradientInfo = basegfx::tools::createAxialODFGradientInfo(
214 : rDefinitionRange,
215 : nSteps,
216 : fBorder,
217 113 : fAngle);
218 :
219 113 : if(rDefinitionRange != rOutputRange)
220 : {
221 4 : basegfx::B2DRange aInvOutputRange(rOutputRange);
222 :
223 4 : aInvOutputRange.transform(maGradientInfo.getBackTextureTransform());
224 4 : mfUnitMinX = aInvOutputRange.getMinX();
225 4 : mfUnitWidth = aInvOutputRange.getWidth();
226 : }
227 113 : }
228 :
229 117 : GeoTexSvxGradientAxial::~GeoTexSvxGradientAxial()
230 : {
231 117 : }
232 :
233 109 : void GeoTexSvxGradientAxial::appendTransformationsAndColors(
234 : std::vector< B2DHomMatrixAndBColor >& rEntries,
235 : basegfx::BColor& rOuterColor)
236 : {
237 109 : rOuterColor = maEnd;
238 :
239 109 : if(maGradientInfo.getSteps())
240 : {
241 109 : const double fStripeWidth(1.0 / maGradientInfo.getSteps());
242 109 : B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
243 :
244 13550 : for(sal_uInt32 a(1); a < maGradientInfo.getSteps(); a++)
245 : {
246 13441 : const double fPos(fStripeWidth * a);
247 13441 : basegfx::B2DHomMatrix aNew;
248 :
249 : // bring in X from unit circle [-1, -1, 1, 1] to unit range [0, 0, 1, 1]
250 13441 : aNew.scale(0.5, 1.0);
251 13441 : aNew.translate(0.5, 0.0);
252 :
253 : // scale/translate in X
254 13441 : aNew.scale(mfUnitWidth, 1.0);
255 13441 : aNew.translate(mfUnitMinX, 0.0);
256 :
257 : // already centerd in Y on X-Axis, just scale in Y
258 13441 : aNew.scale(1.0, 1.0 - fPos);
259 :
260 : // set at target
261 13441 : aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * aNew;
262 :
263 : // interpolate and set color
264 13441 : aB2DHomMatrixAndBColor.maBColor = interpolate(maEnd, maStart, double(a) / double(maGradientInfo.getSteps() - 1));
265 :
266 13441 : rEntries.push_back(aB2DHomMatrixAndBColor);
267 13550 : }
268 : }
269 109 : }
270 :
271 34735 : void GeoTexSvxGradientAxial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
272 : {
273 34735 : const double fScaler(basegfx::tools::getAxialGradientAlpha(rUV, maGradientInfo));
274 :
275 34735 : rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
276 34735 : }
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 12 : 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 12 : mbDefinitionRangeEqualsOutputRange(rDefinitionRange == rOutputRange)
568 : {
569 12 : double fTargetSizeX(rDefinitionRange.getWidth());
570 12 : double fTargetSizeY(rDefinitionRange.getHeight());
571 12 : double fTargetOffsetX(rDefinitionRange.getMinX());
572 12 : double fTargetOffsetY(rDefinitionRange.getMinY());
573 :
574 12 : fAngle = -fAngle;
575 :
576 : // add object expansion
577 12 : 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 12 : maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
591 :
592 : // add texture rotate after scale to keep perpendicular angles
593 12 : 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 12 : maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
604 :
605 : // prepare height for texture
606 12 : const double fSteps((0.0 != fDistance) ? fTargetSizeY / fDistance : 10.0);
607 12 : mnSteps = basegfx::fround(fSteps + 0.5);
608 12 : mfDistance = 1.0 / fSteps;
609 12 : }
610 :
611 16 : GeoTexSvxHatch::~GeoTexSvxHatch()
612 : {
613 16 : }
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 8 : void GeoTexSvxHatch::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
627 : {
628 8 : if(mbDefinitionRangeEqualsOutputRange)
629 : {
630 : // simple hatch where the definition area equals the output area
631 376 : for(sal_uInt32 a(1); a < mnSteps; a++)
632 : {
633 : // create matrix
634 368 : const double fOffset(mfDistance * (double)a);
635 368 : basegfx::B2DHomMatrix aNew;
636 368 : aNew.set(1, 2, fOffset);
637 368 : rMatrices.push_back(maTextureTransform * aNew);
638 368 : }
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 0 : basegfx::B2DRange aBackUnitRange(maOutputRange);
646 :
647 0 : aBackUnitRange.transform(getBackTextureTransform());
648 :
649 : // calculate vertical start value and a security maximum integer value to avoid death loops
650 0 : double fStart(basegfx::snapToNearestMultiple(aBackUnitRange.getMinY(), mfDistance));
651 0 : const sal_uInt32 nNeededIntegerSteps(basegfx::fround((aBackUnitRange.getHeight() / mfDistance) + 0.5));
652 0 : sal_uInt32 nMaxIntegerSteps(::std::min(nNeededIntegerSteps, sal_uInt32(10000)));
653 :
654 0 : while(fStart < aBackUnitRange.getMaxY() && nMaxIntegerSteps)
655 : {
656 : // create new transform for
657 0 : 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 0 : aNew.set(0, 0, aBackUnitRange.getWidth());
663 0 : aNew.set(0, 2, aBackUnitRange.getMinX());
664 :
665 : // adapt y position to current step
666 0 : aNew.set(1, 2, fStart);
667 : //aNew.translate(0.0, fStart);
668 :
669 : // add new transformation
670 0 : rMatrices.push_back(maTextureTransform * aNew);
671 :
672 : // next step
673 0 : fStart += mfDistance;
674 0 : nMaxIntegerSteps--;
675 0 : }
676 : }
677 8 : }
678 :
679 23562 : double GeoTexSvxHatch::getDistanceToHatch(const basegfx::B2DPoint& rUV) const
680 : {
681 23562 : const basegfx::B2DPoint aCoor(getBackTextureTransform() * rUV);
682 23562 : return fmod(aCoor.getY(), mfDistance);
683 : }
684 :
685 23562 : const basegfx::B2DHomMatrix& GeoTexSvxHatch::getBackTextureTransform() const
686 : {
687 23562 : if(maBackTextureTransform.isIdentity())
688 : {
689 4 : const_cast< GeoTexSvxHatch* >(this)->maBackTextureTransform = maTextureTransform;
690 4 : const_cast< GeoTexSvxHatch* >(this)->maBackTextureTransform.invert();
691 : }
692 :
693 23562 : 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 2 : GeoTexSvxTiled::GeoTexSvxTiled(
705 : const basegfx::B2DRange& rRange,
706 : double fOffsetX,
707 : double fOffsetY)
708 : : maRange(rRange),
709 4 : mfOffsetX(basegfx::clamp(fOffsetX, 0.0, 1.0)),
710 6 : mfOffsetY(basegfx::clamp(fOffsetY, 0.0, 1.0))
711 : {
712 2 : if(!basegfx::fTools::equalZero(mfOffsetX))
713 : {
714 0 : mfOffsetY = 0.0;
715 : }
716 2 : }
717 :
718 2 : GeoTexSvxTiled::~GeoTexSvxTiled()
719 : {
720 2 : }
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 2 : void GeoTexSvxTiled::appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices)
733 : {
734 2 : const double fWidth(maRange.getWidth());
735 :
736 2 : if(!basegfx::fTools::equalZero(fWidth))
737 : {
738 2 : const double fHeight(maRange.getHeight());
739 :
740 2 : if(!basegfx::fTools::equalZero(fHeight))
741 : {
742 2 : double fStartX(maRange.getMinX());
743 2 : double fStartY(maRange.getMinY());
744 2 : sal_Int32 nPosX(0);
745 2 : sal_Int32 nPosY(0);
746 :
747 2 : if(basegfx::fTools::more(fStartX, 0.0))
748 : {
749 2 : const sal_Int32 nDiff(static_cast<sal_Int32>(floor(fStartX / fWidth)) + 1);
750 :
751 2 : nPosX -= nDiff;
752 2 : fStartX -= nDiff * fWidth;
753 : }
754 :
755 2 : 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 2 : if(basegfx::fTools::more(fStartY, 0.0))
764 : {
765 2 : const sal_Int32 nDiff(static_cast<sal_Int32>(floor(fStartY / fHeight)) + 1);
766 :
767 2 : nPosY -= nDiff;
768 2 : fStartY -= nDiff * fHeight;
769 : }
770 :
771 2 : 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 2 : 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 28 : for(double fPosY(fStartY); basegfx::fTools::less(fPosY, 1.0); fPosY += fHeight, nPosY++)
798 : {
799 2064 : for(double fPosX(nPosY % 2 ? fStartX - fWidth + (mfOffsetX * fWidth) : fStartX);
800 1376 : basegfx::fTools::less(fPosX, 1.0); fPosX += fWidth)
801 : {
802 : rMatrices.push_back(
803 : basegfx::tools::createScaleTranslateB2DHomMatrix(
804 : fWidth,
805 : fHeight,
806 : fPosX,
807 662 : fPosY));
808 : }
809 : }
810 : }
811 : }
812 : }
813 2 : }
814 : } // end of namespace texture
815 1143 : } // end of namespace drawinglayer
816 :
817 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|