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/texture3d.hxx> 28 #include <vcl/bmpacc.hxx> 29 #include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx> 30 31 ////////////////////////////////////////////////////////////////////////////// 32 33 namespace drawinglayer 34 { 35 namespace texture 36 { GeoTexSvxMono(const basegfx::BColor & rSingleColor,double fOpacity)37 GeoTexSvxMono::GeoTexSvxMono( 38 const basegfx::BColor& rSingleColor, 39 double fOpacity) 40 : maSingleColor(rSingleColor), 41 mfOpacity(fOpacity) 42 { 43 } 44 operator ==(const GeoTexSvx & rGeoTexSvx) const45 bool GeoTexSvxMono::operator==(const GeoTexSvx& rGeoTexSvx) const 46 { 47 const GeoTexSvxMono* pCompare = dynamic_cast< const GeoTexSvxMono* >(&rGeoTexSvx); 48 49 return (pCompare 50 && maSingleColor == pCompare->maSingleColor 51 && mfOpacity == pCompare->mfOpacity); 52 } 53 modifyBColor(const basegfx::B2DPoint &,basegfx::BColor & rBColor,double &) const54 void GeoTexSvxMono::modifyBColor(const basegfx::B2DPoint& /*rUV*/, basegfx::BColor& rBColor, double& /*rfOpacity*/) const 55 { 56 rBColor = maSingleColor; 57 } 58 modifyOpacity(const basegfx::B2DPoint &,double & rfOpacity) const59 void GeoTexSvxMono::modifyOpacity(const basegfx::B2DPoint& /*rUV*/, double& rfOpacity) const 60 { 61 rfOpacity = mfOpacity; 62 } 63 } // end of namespace texture 64 } // end of namespace drawinglayer 65 66 ////////////////////////////////////////////////////////////////////////////// 67 68 namespace drawinglayer 69 { 70 namespace texture 71 { GeoTexSvxBitmapEx(const BitmapEx & rBitmapEx,const basegfx::B2DRange & rRange)72 GeoTexSvxBitmapEx::GeoTexSvxBitmapEx( 73 const BitmapEx& rBitmapEx, 74 const basegfx::B2DRange& rRange) 75 : maBitmapEx(rBitmapEx), 76 mpReadBitmap(0), 77 maTransparence(), 78 mpReadTransparence(0), 79 maTopLeft(rRange.getMinimum()), 80 maSize(rRange.getRange()), 81 mfMulX(0.0), 82 mfMulY(0.0), 83 mbIsAlpha(false), 84 mbIsTransparent(maBitmapEx.IsTransparent()) 85 { 86 // #121194# Todo: use alpha channel, too (for 3d) 87 mpReadBitmap = maBitmapEx.GetBitmap().AcquireReadAccess(); 88 OSL_ENSURE(mpReadBitmap, "GeoTexSvxBitmapEx: Got no read access to Bitmap (!)"); 89 90 if(mbIsTransparent) 91 { 92 if(maBitmapEx.IsAlpha()) 93 { 94 mbIsAlpha = true; 95 maTransparence = rBitmapEx.GetAlpha().GetBitmap(); 96 } 97 else 98 { 99 maTransparence = rBitmapEx.GetMask(); 100 } 101 102 mpReadTransparence = maTransparence.AcquireReadAccess(); 103 } 104 105 mfMulX = (double)mpReadBitmap->Width() / maSize.getX(); 106 mfMulY = (double)mpReadBitmap->Height() / maSize.getY(); 107 108 if(maSize.getX() <= 1.0) 109 { 110 maSize.setX(1.0); 111 } 112 113 if(maSize.getY() <= 1.0) 114 { 115 maSize.setY(1.0); 116 } 117 } 118 ~GeoTexSvxBitmapEx()119 GeoTexSvxBitmapEx::~GeoTexSvxBitmapEx() 120 { 121 delete mpReadTransparence; 122 delete mpReadBitmap; 123 } 124 impGetTransparence(sal_Int32 & rX,sal_Int32 & rY) const125 sal_uInt8 GeoTexSvxBitmapEx::impGetTransparence(sal_Int32& rX, sal_Int32& rY) const 126 { 127 switch(maBitmapEx.GetTransparentType()) 128 { 129 case TRANSPARENT_NONE: 130 { 131 break; 132 } 133 case TRANSPARENT_COLOR: 134 { 135 const BitmapColor aBitmapColor(mpReadBitmap->GetColor(rY, rX)); 136 137 if(maBitmapEx.GetTransparentColor() == aBitmapColor.operator Color()) 138 { 139 return 255; 140 } 141 142 break; 143 } 144 case TRANSPARENT_BITMAP: 145 { 146 OSL_ENSURE(mpReadTransparence, "OOps, transparence type Bitmap, but no read access created in the constructor (?)"); 147 const BitmapColor aBitmapColor(mpReadTransparence->GetPixel(rY, rX)); 148 149 if(mbIsAlpha) 150 { 151 return aBitmapColor.GetIndex(); 152 } 153 else 154 { 155 if(0x00 != aBitmapColor.GetIndex()) 156 { 157 return 255; 158 } 159 } 160 break; 161 } 162 } 163 164 return 0; 165 } 166 impIsValid(const basegfx::B2DPoint & rUV,sal_Int32 & rX,sal_Int32 & rY) const167 bool GeoTexSvxBitmapEx::impIsValid(const basegfx::B2DPoint& rUV, sal_Int32& rX, sal_Int32& rY) const 168 { 169 if(mpReadBitmap) 170 { 171 rX = (sal_Int32)((rUV.getX() - maTopLeft.getX()) * mfMulX); 172 173 if(rX >= 0L && rX < mpReadBitmap->Width()) 174 { 175 rY = (sal_Int32)((rUV.getY() - maTopLeft.getY()) * mfMulY); 176 177 return (rY >= 0L && rY < mpReadBitmap->Height()); 178 } 179 } 180 181 return false; 182 } 183 modifyBColor(const basegfx::B2DPoint & rUV,basegfx::BColor & rBColor,double & rfOpacity) const184 void GeoTexSvxBitmapEx::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const 185 { 186 sal_Int32 nX, nY; 187 188 if(impIsValid(rUV, nX, nY)) 189 { 190 const double fConvertColor(1.0 / 255.0); 191 const BitmapColor aBMCol(mpReadBitmap->GetColor(nY, nX)); 192 const basegfx::BColor aBSource( 193 (double)aBMCol.GetRed() * fConvertColor, 194 (double)aBMCol.GetGreen() * fConvertColor, 195 (double)aBMCol.GetBlue() * fConvertColor); 196 197 rBColor = aBSource; 198 199 if(mbIsTransparent) 200 { 201 // when we have a transparence, make use of it 202 const sal_uInt8 aLuminance(impGetTransparence(nX, nY)); 203 204 rfOpacity = ((double)(0xff - aLuminance) * (1.0 / 255.0)); 205 } 206 else 207 { 208 rfOpacity = 1.0; 209 } 210 } 211 else 212 { 213 rfOpacity = 0.0; 214 } 215 } 216 modifyOpacity(const basegfx::B2DPoint & rUV,double & rfOpacity) const217 void GeoTexSvxBitmapEx::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const 218 { 219 sal_Int32 nX, nY; 220 221 if(impIsValid(rUV, nX, nY)) 222 { 223 if(mbIsTransparent) 224 { 225 // this texture has an alpha part, use it 226 const sal_uInt8 aLuminance(impGetTransparence(nX, nY)); 227 const double fNewOpacity((double)(0xff - aLuminance) * (1.0 / 255.0)); 228 229 rfOpacity = 1.0 - ((1.0 - fNewOpacity) * (1.0 - rfOpacity)); 230 } 231 else 232 { 233 // this texture is a color bitmap used as transparence map 234 const BitmapColor aBMCol(mpReadBitmap->GetColor(nY, nX)); 235 const Color aColor(aBMCol.GetRed(), aBMCol.GetGreen(), aBMCol.GetBlue()); 236 237 rfOpacity = ((double)(0xff - aColor.GetLuminance()) * (1.0 / 255.0)); 238 } 239 } 240 else 241 { 242 rfOpacity = 0.0; 243 } 244 } 245 } // end of namespace texture 246 } // end of namespace drawinglayer 247 248 ////////////////////////////////////////////////////////////////////////////// 249 250 namespace drawinglayer 251 { 252 namespace texture 253 { impGetCorrected(const basegfx::B2DPoint & rUV) const254 basegfx::B2DPoint GeoTexSvxBitmapExTiled::impGetCorrected(const basegfx::B2DPoint& rUV) const 255 { 256 double fX(rUV.getX() - maTopLeft.getX()); 257 double fY(rUV.getY() - maTopLeft.getY()); 258 259 if(mbUseOffsetX) 260 { 261 const sal_Int32 nCol(static_cast< sal_Int32 >((fY < 0.0 ? maSize.getY() -fY : fY) / maSize.getY())); 262 263 if(nCol % 2) 264 { 265 fX += mfOffsetX * maSize.getX(); 266 } 267 } 268 else if(mbUseOffsetY) 269 { 270 const sal_Int32 nRow(static_cast< sal_Int32 >((fX < 0.0 ? maSize.getX() -fX : fX) / maSize.getX())); 271 272 if(nRow % 2) 273 { 274 fY += mfOffsetY * maSize.getY(); 275 } 276 } 277 278 fX = fmod(fX, maSize.getX()); 279 fY = fmod(fY, maSize.getY()); 280 281 if(fX < 0.0) 282 { 283 fX += maSize.getX(); 284 } 285 286 if(fY < 0.0) 287 { 288 fY += maSize.getY(); 289 } 290 291 return basegfx::B2DPoint(fX + maTopLeft.getX(), fY + maTopLeft.getY()); 292 } 293 GeoTexSvxBitmapExTiled(const BitmapEx & rBitmapEx,const basegfx::B2DRange & rRange,double fOffsetX,double fOffsetY)294 GeoTexSvxBitmapExTiled::GeoTexSvxBitmapExTiled( 295 const BitmapEx& rBitmapEx, 296 const basegfx::B2DRange& rRange, 297 double fOffsetX, 298 double fOffsetY) 299 : GeoTexSvxBitmapEx(rBitmapEx, rRange), 300 mfOffsetX(basegfx::clamp(fOffsetX, 0.0, 1.0)), 301 mfOffsetY(basegfx::clamp(fOffsetY, 0.0, 1.0)), 302 mbUseOffsetX(!basegfx::fTools::equalZero(mfOffsetX)), 303 mbUseOffsetY(!mbUseOffsetX && !basegfx::fTools::equalZero(mfOffsetY)) 304 { 305 } 306 modifyBColor(const basegfx::B2DPoint & rUV,basegfx::BColor & rBColor,double & rfOpacity) const307 void GeoTexSvxBitmapExTiled::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const 308 { 309 if(mpReadBitmap) 310 { 311 GeoTexSvxBitmapEx::modifyBColor(impGetCorrected(rUV), rBColor, rfOpacity); 312 } 313 } 314 modifyOpacity(const basegfx::B2DPoint & rUV,double & rfOpacity) const315 void GeoTexSvxBitmapExTiled::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const 316 { 317 if(mpReadBitmap) 318 { 319 GeoTexSvxBitmapEx::modifyOpacity(impGetCorrected(rUV), rfOpacity); 320 } 321 } 322 } // end of namespace texture 323 } // end of namespace drawinglayer 324 325 ////////////////////////////////////////////////////////////////////////////// 326 327 namespace drawinglayer 328 { 329 namespace texture 330 { GeoTexSvxMultiHatch(const primitive3d::HatchTexturePrimitive3D & rPrimitive,double fLogicPixelSize)331 GeoTexSvxMultiHatch::GeoTexSvxMultiHatch( 332 const primitive3d::HatchTexturePrimitive3D& rPrimitive, 333 double fLogicPixelSize) 334 : mfLogicPixelSize(fLogicPixelSize), 335 mp0(0L), 336 mp1(0L), 337 mp2(0L) 338 { 339 const attribute::FillHatchAttribute& rHatch(rPrimitive.getHatch()); 340 const basegfx::B2DRange aOutlineRange(0.0, 0.0, rPrimitive.getTextureSize().getX(), rPrimitive.getTextureSize().getY()); 341 const double fAngleA(rHatch.getAngle()); 342 maColor = rHatch.getColor(); 343 mbFillBackground = rHatch.isFillBackground(); 344 mp0 = new GeoTexSvxHatch( 345 aOutlineRange, 346 aOutlineRange, 347 rHatch.getDistance(), 348 fAngleA); 349 350 if(attribute::HATCHSTYLE_DOUBLE == rHatch.getStyle() || attribute::HATCHSTYLE_TRIPLE == rHatch.getStyle()) 351 { 352 mp1 = new GeoTexSvxHatch( 353 aOutlineRange, 354 aOutlineRange, 355 rHatch.getDistance(), 356 fAngleA + F_PI2); 357 } 358 359 if(attribute::HATCHSTYLE_TRIPLE == rHatch.getStyle()) 360 { 361 mp2 = new GeoTexSvxHatch( 362 aOutlineRange, 363 aOutlineRange, 364 rHatch.getDistance(), 365 fAngleA + F_PI4); 366 } 367 } 368 ~GeoTexSvxMultiHatch()369 GeoTexSvxMultiHatch::~GeoTexSvxMultiHatch() 370 { 371 delete mp0; 372 delete mp1; 373 delete mp2; 374 } 375 impIsOnHatch(const basegfx::B2DPoint & rUV) const376 bool GeoTexSvxMultiHatch::impIsOnHatch(const basegfx::B2DPoint& rUV) const 377 { 378 if(mp0->getDistanceToHatch(rUV) < mfLogicPixelSize) 379 { 380 return true; 381 } 382 383 if(mp1 && mp1->getDistanceToHatch(rUV) < mfLogicPixelSize) 384 { 385 return true; 386 } 387 388 if(mp2 && mp2->getDistanceToHatch(rUV) < mfLogicPixelSize) 389 { 390 return true; 391 } 392 393 return false; 394 } 395 modifyBColor(const basegfx::B2DPoint & rUV,basegfx::BColor & rBColor,double & rfOpacity) const396 void GeoTexSvxMultiHatch::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const 397 { 398 if(impIsOnHatch(rUV)) 399 { 400 rBColor = maColor; 401 } 402 else if(!mbFillBackground) 403 { 404 rfOpacity = 0.0; 405 } 406 } 407 modifyOpacity(const basegfx::B2DPoint & rUV,double & rfOpacity) const408 void GeoTexSvxMultiHatch::modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const 409 { 410 if(mbFillBackground || impIsOnHatch(rUV)) 411 { 412 rfOpacity = 1.0; 413 } 414 else 415 { 416 rfOpacity = 0.0; 417 } 418 } 419 } // end of namespace texture 420 } // end of namespace drawinglayer 421 422 ////////////////////////////////////////////////////////////////////////////// 423 // eof 424