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