1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <drawinglayer/primitive3d/sdrdecompositiontools3d.hxx>
21 #include <basegfx/polygon/b3dpolygon.hxx>
22 #include <drawinglayer/attribute/strokeattribute.hxx>
23 #include <drawinglayer/primitive3d/baseprimitive3d.hxx>
24 #include <drawinglayer/primitive3d/polygonprimitive3d.hxx>
25 #include <basegfx/polygon/b3dpolypolygon.hxx>
26 #include <drawinglayer/primitive3d/polypolygonprimitive3d.hxx>
27 #include <vcl/vclenum.hxx>
28 #include <drawinglayer/attribute/fillgraphicattribute.hxx>
29 #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
30 #include <vcl/bitmapaccess.hxx>
31 #include <basegfx/polygon/b3dpolypolygontools.hxx>
32 #include <drawinglayer/primitive3d/textureprimitive3d.hxx>
33 #include <drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx>
34 #include <drawinglayer/primitive3d/hatchtextureprimitive3d.hxx>
35 #include <drawinglayer/primitive3d/shadowprimitive3d.hxx>
36 #include <basegfx/range/b2drange.hxx>
37 #include <drawinglayer/attribute/sdrlineattribute.hxx>
38 #include <drawinglayer/attribute/sdrobjectattribute3d.hxx>
39 #include <drawinglayer/attribute/sdrfillattribute.hxx>
40 #include <drawinglayer/attribute/sdrshadowattribute.hxx>
41 #include <drawinglayer/primitive3d/hiddengeometryprimitive3d.hxx>
44 namespace drawinglayer
48 basegfx::B3DRange
getRangeFrom3DGeometry(std::vector
< basegfx::B3DPolyPolygon
>& rFill
)
50 basegfx::B3DRange aRetval
;
52 for(const basegfx::B3DPolyPolygon
& a
: rFill
)
54 aRetval
.expand(basegfx::utils::getRange(a
));
60 void applyNormalsKindSphereTo3DGeometry(std::vector
< basegfx::B3DPolyPolygon
>& rFill
, const basegfx::B3DRange
& rRange
)
62 // create sphere normals
63 const basegfx::B3DPoint
aCenter(rRange
.getCenter());
65 for(basegfx::B3DPolyPolygon
& a
: rFill
)
67 a
= basegfx::utils::applyDefaultNormalsSphere(a
, aCenter
);
71 void applyNormalsKindFlatTo3DGeometry(std::vector
< basegfx::B3DPolyPolygon
>& rFill
)
73 for(basegfx::B3DPolyPolygon
& a
: rFill
)
79 void applyNormalsInvertTo3DGeometry(std::vector
< basegfx::B3DPolyPolygon
>& rFill
)
82 for(basegfx::B3DPolyPolygon
& a
: rFill
)
84 a
= basegfx::utils::invertNormals(a
);
88 void applyTextureTo3DGeometry(
89 css::drawing::TextureProjectionMode eModeX
,
90 css::drawing::TextureProjectionMode eModeY
,
91 std::vector
< basegfx::B3DPolyPolygon
>& rFill
,
92 const basegfx::B3DRange
& rRange
,
93 const basegfx::B2DVector
& rTextureSize
)
95 // handle texture coordinates X
96 const bool bParallelX(css::drawing::TextureProjectionMode_PARALLEL
== eModeX
);
97 const bool bSphereX(!bParallelX
&& (css::drawing::TextureProjectionMode_SPHERE
== eModeX
));
99 // handle texture coordinates Y
100 const bool bParallelY(css::drawing::TextureProjectionMode_PARALLEL
== eModeY
);
101 const bool bSphereY(!bParallelY
&& (css::drawing::TextureProjectionMode_SPHERE
== eModeY
));
103 if(bParallelX
|| bParallelY
)
105 // apply parallel texture coordinates in X and/or Y
108 a
= basegfx::utils::applyDefaultTextureCoordinatesParallel(a
, rRange
, bParallelX
, bParallelY
);
112 if(bSphereX
|| bSphereY
)
114 // apply spherical texture coordinates in X and/or Y
115 const basegfx::B3DPoint
aCenter(rRange
.getCenter());
119 a
= basegfx::utils::applyDefaultTextureCoordinatesSphere(a
, aCenter
, bSphereX
, bSphereY
);
123 // transform texture coordinates to texture size
124 basegfx::B2DHomMatrix aTexMatrix
;
125 aTexMatrix
.scale(rTextureSize
.getX(), rTextureSize
.getY());
129 a
.transformTextureCoordinates(aTexMatrix
);
133 Primitive3DContainer
create3DPolyPolygonLinePrimitives(
134 const basegfx::B3DPolyPolygon
& rUnitPolyPolygon
,
135 const basegfx::B3DHomMatrix
& rObjectTransform
,
136 const attribute::SdrLineAttribute
& rLine
)
138 // prepare fully scaled polyPolygon
139 basegfx::B3DPolyPolygon
aScaledPolyPolygon(rUnitPolyPolygon
);
140 aScaledPolyPolygon
.transform(rObjectTransform
);
142 // create line and stroke attribute
143 const attribute::LineAttribute
aLineAttribute(rLine
.getColor(), rLine
.getWidth(), rLine
.getJoin(), rLine
.getCap());
144 const attribute::StrokeAttribute
aStrokeAttribute(rLine
.getDotDashArray(), rLine
.getFullDotDashLen());
147 Primitive3DContainer
aRetval(aScaledPolyPolygon
.count());
149 for(sal_uInt32
a(0); a
< aScaledPolyPolygon
.count(); a
++)
151 const Primitive3DReference
xRef(new PolygonStrokePrimitive3D(aScaledPolyPolygon
.getB3DPolygon(a
), aLineAttribute
, aStrokeAttribute
));
155 if(0.0 != rLine
.getTransparence())
157 // create UnifiedTransparenceTexturePrimitive3D, add created primitives and exchange
158 const Primitive3DReference
xRef(new UnifiedTransparenceTexturePrimitive3D(rLine
.getTransparence(), aRetval
));
165 Primitive3DContainer
create3DPolyPolygonFillPrimitives(
166 const std::vector
< basegfx::B3DPolyPolygon
>& r3DPolyPolygonVector
,
167 const basegfx::B3DHomMatrix
& rObjectTransform
,
168 const basegfx::B2DVector
& rTextureSize
,
169 const attribute::Sdr3DObjectAttribute
& aSdr3DObjectAttribute
,
170 const attribute::SdrFillAttribute
& rFill
,
171 const attribute::FillGradientAttribute
& rFillGradient
)
173 Primitive3DContainer aRetval
;
175 if(!r3DPolyPolygonVector
.empty())
177 // create list of simple fill primitives
178 aRetval
.resize(r3DPolyPolygonVector
.size());
180 for(size_t a(0); a
< r3DPolyPolygonVector
.size(); a
++)
182 // get scaled PolyPolygon
183 basegfx::B3DPolyPolygon
aScaledPolyPolygon(r3DPolyPolygonVector
[a
]);
184 aScaledPolyPolygon
.transform(rObjectTransform
);
186 if(aScaledPolyPolygon
.areNormalsUsed())
188 aScaledPolyPolygon
.transformNormals(rObjectTransform
);
191 const Primitive3DReference
xRef(new PolyPolygonMaterialPrimitive3D(
193 aSdr3DObjectAttribute
.getMaterial(),
194 aSdr3DObjectAttribute
.getDoubleSided()));
198 // look for and evtl. build texture sub-group primitive
199 if(!rFill
.getGradient().isDefault()
200 || !rFill
.getHatch().isDefault()
201 || !rFill
.getFillGraphic().isDefault())
203 bool bModulate(css::drawing::TextureMode_MODULATE
== aSdr3DObjectAttribute
.getTextureMode());
204 bool bFilter(aSdr3DObjectAttribute
.getTextureFilter());
205 BasePrimitive3D
* pNewTexturePrimitive3D
= nullptr;
207 if(!rFill
.getGradient().isDefault())
209 // create gradientTexture3D with sublist, add to local aRetval
210 pNewTexturePrimitive3D
= new GradientTexturePrimitive3D(
217 else if(!rFill
.getHatch().isDefault())
219 // create hatchTexture3D with sublist, add to local aRetval
220 pNewTexturePrimitive3D
= new HatchTexturePrimitive3D(
227 else // if(!rFill.getFillGraphic().isDefault())
229 // create bitmapTexture3D with sublist, add to local aRetval
230 const basegfx::B2DRange
aTexRange(0.0, 0.0, rTextureSize
.getX(), rTextureSize
.getY());
232 pNewTexturePrimitive3D
= new BitmapTexturePrimitive3D(
233 rFill
.getFillGraphic().createFillGraphicAttribute(aTexRange
),
240 // exchange aRetval content with texture group
241 const Primitive3DReference
xRef(pNewTexturePrimitive3D
);
244 if(css::drawing::TextureKind2_LUMINANCE
== aSdr3DObjectAttribute
.getTextureKind())
246 // use modified color primitive to force textures to gray
247 const basegfx::BColorModifierSharedPtr
aBColorModifier(
248 new basegfx::BColorModifier_gray());
249 const Primitive3DReference
xRef2(
250 new ModifiedColorPrimitive3D(
258 if(0.0 != rFill
.getTransparence())
260 // create UnifiedTransparenceTexturePrimitive3D with sublist and exchange
261 const Primitive3DReference
xRef(new UnifiedTransparenceTexturePrimitive3D(rFill
.getTransparence(), aRetval
));
264 else if(!rFillGradient
.isDefault())
266 // create TransparenceTexturePrimitive3D with sublist and exchange
267 const Primitive3DReference
xRef(new TransparenceTexturePrimitive3D(rFillGradient
, aRetval
, rTextureSize
));
275 Primitive3DContainer
createShadowPrimitive3D(
276 const Primitive3DContainer
& rSource
,
277 const attribute::SdrShadowAttribute
& rShadow
,
280 // create Shadow primitives. Uses already created primitives
281 if(!rSource
.empty() && !basegfx::fTools::moreOrEqual(rShadow
.getTransparence(), 1.0))
283 // prepare new list for shadow geometry
284 basegfx::B2DHomMatrix aShadowOffset
;
285 aShadowOffset
.set(0, 2, rShadow
.getOffset().getX());
286 aShadowOffset
.set(1, 2, rShadow
.getOffset().getY());
288 // create shadow primitive and add primitives
289 const Primitive3DReference
xRef(new ShadowPrimitive3D(aShadowOffset
, rShadow
.getColor(), rShadow
.getTransparence(), bShadow3D
, rSource
));
294 return Primitive3DContainer();
298 Primitive3DContainer
createHiddenGeometryPrimitives3D(
299 const std::vector
< basegfx::B3DPolyPolygon
>& r3DPolyPolygonVector
,
300 const basegfx::B3DHomMatrix
& rObjectTransform
,
301 const basegfx::B2DVector
& rTextureSize
,
302 const attribute::Sdr3DObjectAttribute
& aSdr3DObjectAttribute
)
304 // create hidden sub-geometry which can be used for HitTest
305 // and BoundRect calculations, but will not be visualized
306 const attribute::SdrFillAttribute
aSimplifiedFillAttribute(
309 attribute::FillGradientAttribute(),
310 attribute::FillHatchAttribute(),
311 attribute::SdrFillGraphicAttribute());
313 const Primitive3DReference
aHidden(
314 new HiddenGeometryPrimitive3D(
315 create3DPolyPolygonFillPrimitives(
316 r3DPolyPolygonVector
,
319 aSdr3DObjectAttribute
,
320 aSimplifiedFillAttribute
,
321 attribute::FillGradientAttribute())));
326 } // end of namespace primitive3d
327 } // end of namespace drawinglayer
329 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */