1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_drawinglayer.hxx" 30 31 #include <drawinglayer/primitive3d/sdrdecompositiontools3d.hxx> 32 #include <basegfx/polygon/b3dpolygon.hxx> 33 #include <drawinglayer/attribute/strokeattribute.hxx> 34 #include <drawinglayer/primitive3d/baseprimitive3d.hxx> 35 #include <drawinglayer/primitive3d/polygonprimitive3d.hxx> 36 #include <basegfx/polygon/b3dpolypolygon.hxx> 37 #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx> 38 #include <vcl/vclenum.hxx> 39 #include <drawinglayer/attribute/fillbitmapattribute.hxx> 40 #include <drawinglayer/attribute/sdrfillbitmapattribute.hxx> 41 #include <vcl/bmpacc.hxx> 42 #include <basegfx/polygon/b3dpolypolygontools.hxx> 43 #include <drawinglayer/primitive3d/textureprimitive3d.hxx> 44 #include <drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx> 45 #include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx> 46 #include <drawinglayer/primitive3d/shadowprimitive3d.hxx> 47 #include <basegfx/range/b2drange.hxx> 48 #include <drawinglayer/attribute/sdrlineattribute.hxx> 49 #include <drawinglayer/attribute/sdrobjectattribute3d.hxx> 50 #include <drawinglayer/attribute/sdrfillattribute.hxx> 51 #include <drawinglayer/attribute/sdrshadowattribute.hxx> 52 #include <drawinglayer/primitive3d/hiddengeometryprimitive3d.hxx> 53 54 ////////////////////////////////////////////////////////////////////////////// 55 56 namespace drawinglayer 57 { 58 namespace primitive3d 59 { 60 basegfx::B3DRange getRangeFrom3DGeometry(::std::vector< basegfx::B3DPolyPolygon >& rFill) 61 { 62 basegfx::B3DRange aRetval; 63 64 for(sal_uInt32 a(0); a < rFill.size(); a++) 65 { 66 aRetval.expand(basegfx::tools::getRange(rFill[a])); 67 } 68 69 return aRetval; 70 } 71 72 void applyNormalsKindSphereTo3DGeometry(::std::vector< basegfx::B3DPolyPolygon >& rFill, const basegfx::B3DRange& rRange) 73 { 74 // create sphere normals 75 const basegfx::B3DPoint aCenter(rRange.getCenter()); 76 77 for(sal_uInt32 a(0); a < rFill.size(); a++) 78 { 79 rFill[a] = basegfx::tools::applyDefaultNormalsSphere(rFill[a], aCenter); 80 } 81 } 82 83 void applyNormalsKindFlatTo3DGeometry(::std::vector< basegfx::B3DPolyPolygon >& rFill) 84 { 85 for(sal_uInt32 a(0); a < rFill.size(); a++) 86 { 87 rFill[a].clearNormals(); 88 } 89 } 90 91 void applyNormalsInvertTo3DGeometry(::std::vector< basegfx::B3DPolyPolygon >& rFill) 92 { 93 // invert normals 94 for(sal_uInt32 a(0); a < rFill.size(); a++) 95 { 96 rFill[a] = basegfx::tools::invertNormals(rFill[a]); 97 } 98 } 99 100 void applyTextureTo3DGeometry( 101 ::com::sun::star::drawing::TextureProjectionMode eModeX, 102 ::com::sun::star::drawing::TextureProjectionMode eModeY, 103 ::std::vector< basegfx::B3DPolyPolygon >& rFill, 104 const basegfx::B3DRange& rRange, 105 const basegfx::B2DVector& rTextureSize) 106 { 107 sal_uInt32 a; 108 109 // handle texture coordinates X 110 const bool bParallelX(::com::sun::star::drawing::TextureProjectionMode_PARALLEL == eModeX); 111 const bool bSphereX(!bParallelX && (::com::sun::star::drawing::TextureProjectionMode_SPHERE == eModeX)); 112 113 // handle texture coordinates Y 114 const bool bParallelY(::com::sun::star::drawing::TextureProjectionMode_PARALLEL == eModeY); 115 const bool bSphereY(!bParallelY && (::com::sun::star::drawing::TextureProjectionMode_SPHERE == eModeY)); 116 117 if(bParallelX || bParallelY) 118 { 119 // apply parallel texture coordinates in X and/or Y 120 for(a = 0; a < rFill.size(); a++) 121 { 122 rFill[a] = basegfx::tools::applyDefaultTextureCoordinatesParallel(rFill[a], rRange, bParallelX, bParallelY); 123 } 124 } 125 126 if(bSphereX || bSphereY) 127 { 128 // apply spherical texture coordinates in X and/or Y 129 const basegfx::B3DPoint aCenter(rRange.getCenter()); 130 131 for(a = 0; a < rFill.size(); a++) 132 { 133 rFill[a] = basegfx::tools::applyDefaultTextureCoordinatesSphere(rFill[a], aCenter, bSphereX, bSphereY); 134 } 135 } 136 137 // transform texture coordinates to texture size 138 basegfx::B2DHomMatrix aTexMatrix; 139 aTexMatrix.scale(rTextureSize.getX(), rTextureSize.getY()); 140 141 for(a = 0; a < rFill.size(); a++) 142 { 143 rFill[a].transformTextureCoordiantes(aTexMatrix); 144 } 145 } 146 147 Primitive3DSequence create3DPolyPolygonLinePrimitives( 148 const basegfx::B3DPolyPolygon& rUnitPolyPolygon, 149 const basegfx::B3DHomMatrix& rObjectTransform, 150 const attribute::SdrLineAttribute& rLine) 151 { 152 // prepare fully scaled polyPolygon 153 basegfx::B3DPolyPolygon aScaledPolyPolygon(rUnitPolyPolygon); 154 aScaledPolyPolygon.transform(rObjectTransform); 155 156 // create line and stroke attribute 157 const attribute::LineAttribute aLineAttribute(rLine.getColor(), rLine.getWidth(), rLine.getJoin()); 158 const attribute::StrokeAttribute aStrokeAttribute(rLine.getDotDashArray(), rLine.getFullDotDashLen()); 159 160 // create primitives 161 Primitive3DSequence aRetval(aScaledPolyPolygon.count()); 162 163 for(sal_uInt32 a(0L); a < aScaledPolyPolygon.count(); a++) 164 { 165 const Primitive3DReference xRef(new PolygonStrokePrimitive3D(aScaledPolyPolygon.getB3DPolygon(a), aLineAttribute, aStrokeAttribute)); 166 aRetval[a] = xRef; 167 } 168 169 if(0.0 != rLine.getTransparence()) 170 { 171 // create UnifiedTransparenceTexturePrimitive3D, add created primitives and exchange 172 const Primitive3DReference xRef(new UnifiedTransparenceTexturePrimitive3D(rLine.getTransparence(), aRetval)); 173 aRetval = Primitive3DSequence(&xRef, 1L); 174 } 175 176 return aRetval; 177 } 178 179 Primitive3DSequence create3DPolyPolygonFillPrimitives( 180 const ::std::vector< basegfx::B3DPolyPolygon >& r3DPolyPolygonVector, 181 const basegfx::B3DHomMatrix& rObjectTransform, 182 const basegfx::B2DVector& rTextureSize, 183 const attribute::Sdr3DObjectAttribute& aSdr3DObjectAttribute, 184 const attribute::SdrFillAttribute& rFill, 185 const attribute::FillGradientAttribute& rFillGradient) 186 { 187 Primitive3DSequence aRetval; 188 189 if(r3DPolyPolygonVector.size()) 190 { 191 // create list of simple fill primitives 192 aRetval.realloc(r3DPolyPolygonVector.size()); 193 194 for(sal_uInt32 a(0L); a < r3DPolyPolygonVector.size(); a++) 195 { 196 // get scaled PolyPolygon 197 basegfx::B3DPolyPolygon aScaledPolyPolygon(r3DPolyPolygonVector[a]); 198 aScaledPolyPolygon.transform(rObjectTransform); 199 200 if(aScaledPolyPolygon.areNormalsUsed()) 201 { 202 aScaledPolyPolygon.transformNormals(rObjectTransform); 203 } 204 205 const Primitive3DReference xRef(new PolyPolygonMaterialPrimitive3D( 206 aScaledPolyPolygon, 207 aSdr3DObjectAttribute.getMaterial(), 208 aSdr3DObjectAttribute.getDoubleSided())); 209 aRetval[a] = xRef; 210 } 211 212 // look for and evtl. build texture sub-group primitive 213 if(!rFill.getGradient().isDefault() 214 || !rFill.getHatch().isDefault() 215 || !rFill.getBitmap().isDefault()) 216 { 217 bool bModulate(::com::sun::star::drawing::TextureMode_MODULATE == aSdr3DObjectAttribute.getTextureMode()); 218 bool bFilter(aSdr3DObjectAttribute.getTextureFilter()); 219 BasePrimitive3D* pNewTexturePrimitive3D = 0; 220 221 if(!rFill.getGradient().isDefault()) 222 { 223 // create gradientTexture3D with sublist, add to local aRetval 224 pNewTexturePrimitive3D = new GradientTexturePrimitive3D( 225 rFill.getGradient(), 226 aRetval, 227 rTextureSize, 228 bModulate, 229 bFilter); 230 } 231 else if(!rFill.getHatch().isDefault()) 232 { 233 // create hatchTexture3D with sublist, add to local aRetval 234 pNewTexturePrimitive3D = new HatchTexturePrimitive3D( 235 rFill.getHatch(), 236 aRetval, 237 rTextureSize, 238 bModulate, 239 bFilter); 240 } 241 else // if(!rFill.getBitmap().isDefault()) 242 { 243 // create bitmapTexture3D with sublist, add to local aRetval 244 basegfx::B2DRange aTexRange(0.0, 0.0, rTextureSize.getX(), rTextureSize.getY()); 245 246 pNewTexturePrimitive3D = new BitmapTexturePrimitive3D( 247 rFill.getBitmap().getFillBitmapAttribute(aTexRange), 248 aRetval, 249 rTextureSize, 250 bModulate, 251 bFilter); 252 } 253 254 // exchange aRetval content with texture group 255 const Primitive3DReference xRef(pNewTexturePrimitive3D); 256 aRetval = Primitive3DSequence(&xRef, 1L); 257 258 if(::com::sun::star::drawing::TextureKind2_LUMINANCE == aSdr3DObjectAttribute.getTextureKind()) 259 { 260 // use modified color primitive to force textures to gray 261 const basegfx::BColorModifier aBColorModifier(basegfx::BColor(), 0.0, basegfx::BCOLORMODIFYMODE_GRAY); 262 const Primitive3DReference xRef2(new ModifiedColorPrimitive3D(aRetval, aBColorModifier)); 263 aRetval = Primitive3DSequence(&xRef2, 1L); 264 } 265 } 266 267 if(0.0 != rFill.getTransparence()) 268 { 269 // create UnifiedTransparenceTexturePrimitive3D with sublist and exchange 270 const Primitive3DReference xRef(new UnifiedTransparenceTexturePrimitive3D(rFill.getTransparence(), aRetval)); 271 aRetval = Primitive3DSequence(&xRef, 1L); 272 } 273 else if(!rFillGradient.isDefault()) 274 { 275 // create TransparenceTexturePrimitive3D with sublist and exchange 276 const Primitive3DReference xRef(new TransparenceTexturePrimitive3D(rFillGradient, aRetval, rTextureSize)); 277 aRetval = Primitive3DSequence(&xRef, 1L); 278 } 279 } 280 281 return aRetval; 282 } 283 284 Primitive3DSequence createShadowPrimitive3D( 285 const Primitive3DSequence& rSource, 286 const attribute::SdrShadowAttribute& rShadow, 287 bool bShadow3D) 288 { 289 // create Shadow primitives. Uses already created primitives 290 if(rSource.hasElements() && !basegfx::fTools::moreOrEqual(rShadow.getTransparence(), 1.0)) 291 { 292 // prepare new list for shadow geometry 293 basegfx::B2DHomMatrix aShadowOffset; 294 aShadowOffset.set(0, 2, rShadow.getOffset().getX()); 295 aShadowOffset.set(1, 2, rShadow.getOffset().getY()); 296 297 // create shadow primitive and add primitives 298 const Primitive3DReference xRef(new ShadowPrimitive3D(aShadowOffset, rShadow.getColor(), rShadow.getTransparence(), bShadow3D, rSource)); 299 return Primitive3DSequence(&xRef, 1L); 300 } 301 else 302 { 303 return Primitive3DSequence(); 304 } 305 } 306 307 Primitive3DSequence createHiddenGeometryPrimitives3D( 308 const ::std::vector< basegfx::B3DPolyPolygon >& r3DPolyPolygonVector, 309 const basegfx::B3DHomMatrix& rObjectTransform, 310 const basegfx::B2DVector& rTextureSize, 311 const attribute::Sdr3DObjectAttribute& aSdr3DObjectAttribute) 312 { 313 // create hidden sub-geometry which can be used for HitTest 314 // and BoundRect calculations, but will not be visualized 315 const attribute::SdrFillAttribute aSimplifiedFillAttribute( 316 0.0, 317 basegfx::BColor(), 318 attribute::FillGradientAttribute(), 319 attribute::FillHatchAttribute(), 320 attribute::SdrFillBitmapAttribute()); 321 322 const Primitive3DReference aHidden( 323 new HiddenGeometryPrimitive3D( 324 create3DPolyPolygonFillPrimitives( 325 r3DPolyPolygonVector, 326 rObjectTransform, 327 rTextureSize, 328 aSdr3DObjectAttribute, 329 aSimplifiedFillAttribute, 330 attribute::FillGradientAttribute()))); 331 332 return Primitive3DSequence(&aHidden, 1); 333 } 334 335 } // end of namespace primitive3d 336 } // end of namespace drawinglayer 337 338 ////////////////////////////////////////////////////////////////////////////// 339 // eof 340