1 /*************************************************************************
3 * OpenOffice.org - a multi-platform office productivity suite
5 * $RCSfile: vclhelpergradient.cxx,v $
9 * last change: $Author: aw $ $Date: 2008-05-27 14:11:22 $
11 * The Contents of this file are made available subject to
12 * the terms of GNU Lesser General Public License Version 2.1.
15 * GNU Lesser General Public License Version 2.1
16 * =============================================
17 * Copyright 2005 by Sun Microsystems, Inc.
18 * 901 San Antonio Road, Palo Alto, CA 94303, USA
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License version 2.1, as published by the Free Software Foundation.
24 * This library is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * Lesser General Public License for more details.
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this library; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
34 ************************************************************************/
36 // MARKER(update_precomp.py): autogen include statement, do not remove
37 #include "precompiled_drawinglayer.hxx"
39 #include <vclhelpergradient.hxx>
40 #include <basegfx/range/b2drange.hxx>
41 #include <vcl/outdev.hxx>
42 #include <basegfx/polygon/b2dpolygon.hxx>
43 #include <basegfx/polygon/b2dpolypolygontools.hxx>
44 #include <basegfx/polygon/b2dpolygontools.hxx>
45 #include <drawinglayer/texture/texture.hxx>
47 //////////////////////////////////////////////////////////////////////////////
48 // support methods for vcl direct gradient renderering
50 namespace drawinglayer
54 sal_uInt32
impCalcGradientSteps(OutputDevice
& rOutDev
, sal_uInt32 nSteps
, const basegfx::B2DRange
& rRange
, sal_uInt32 nMaxDist
)
58 const Size
aSize(rOutDev
.LogicToPixel(Size(basegfx::fround(rRange
.getWidth()), basegfx::fround(rRange
.getHeight()))));
59 nSteps
= (aSize
.getWidth() + aSize
.getHeight()) >> 3L;
75 void impDrawGradientToOutDevSimple(
76 OutputDevice
& rOutDev
,
77 const basegfx::B2DPolyPolygon
& rTargetForm
,
78 const ::std::vector
< basegfx::B2DHomMatrix
>& rMatrices
,
79 const ::std::vector
< basegfx::BColor
>& rColors
,
80 const basegfx::B2DPolygon
& rUnitPolygon
)
82 rOutDev
.SetLineColor();
84 for(sal_uInt32
a(0L); a
< rColors
.size(); a
++)
87 const basegfx::BColor
aFillColor(rColors
[a
]);
88 rOutDev
.SetFillColor(Color(aFillColor
));
92 if(a
- 1L < static_cast< sal_uInt32
>(rMatrices
.size()))
94 basegfx::B2DPolygon
aNewPoly(rUnitPolygon
);
95 aNewPoly
.transform(rMatrices
[a
- 1L]);
96 rOutDev
.DrawPolygon(aNewPoly
);
101 rOutDev
.DrawPolyPolygon(rTargetForm
);
106 void impDrawGradientToOutDevComplex(
107 OutputDevice
& rOutDev
,
108 const basegfx::B2DPolyPolygon
& rTargetForm
,
109 const ::std::vector
< basegfx::B2DHomMatrix
>& rMatrices
,
110 const ::std::vector
< basegfx::BColor
>& rColors
,
111 const basegfx::B2DPolygon
& rUnitPolygon
)
113 PolyPolygon
aVclTargetForm(rTargetForm
);
114 ::std::vector
< Polygon
> aVclPolygons
;
117 // remember and set to XOR
118 rOutDev
.SetLineColor();
119 rOutDev
.Push(PUSH_RASTEROP
);
120 rOutDev
.SetRasterOp(ROP_XOR
);
122 // draw gradient PolyPolygons
123 for(a
= 0L; a
< rMatrices
.size(); a
++)
125 // create polygon and remember
126 basegfx::B2DPolygon
aNewPoly(rUnitPolygon
);
127 aNewPoly
.transform(rMatrices
[a
]);
128 aVclPolygons
.push_back(Polygon(aNewPoly
));
131 if(rColors
.size() > a
)
133 const basegfx::BColor
aFillColor(rColors
[a
]);
134 rOutDev
.SetFillColor(Color(aFillColor
));
137 // create vcl PolyPolygon and draw it
140 PolyPolygon
aVclPolyPoly(aVclPolygons
[a
- 1L]);
141 aVclPolyPoly
.Insert(aVclPolygons
[a
]);
142 rOutDev
.DrawPolyPolygon(aVclPolyPoly
);
146 PolyPolygon
aVclPolyPoly(aVclTargetForm
);
147 aVclPolyPoly
.Insert(aVclPolygons
[0L]);
148 rOutDev
.DrawPolyPolygon(aVclPolyPoly
);
152 // draw last poly in last color
155 const basegfx::BColor
aFillColor(rColors
[rColors
.size() - 1L]);
156 rOutDev
.SetFillColor(Color(aFillColor
));
157 rOutDev
.DrawPolygon(aVclPolygons
[aVclPolygons
.size() - 1L]);
160 // draw object form in black and go back to XOR
161 rOutDev
.SetFillColor(COL_BLACK
);
162 rOutDev
.SetRasterOp(ROP_0
);
163 rOutDev
.DrawPolyPolygon(aVclTargetForm
);
164 rOutDev
.SetRasterOp(ROP_XOR
);
166 // draw gradient PolyPolygons again
167 for(a
= 0L; a
< rMatrices
.size(); a
++)
170 if(rColors
.size() > a
)
172 const basegfx::BColor
aFillColor(rColors
[a
]);
173 rOutDev
.SetFillColor(Color(aFillColor
));
176 // create vcl PolyPolygon and draw it
179 PolyPolygon
aVclPolyPoly(aVclPolygons
[a
- 1L]);
180 aVclPolyPoly
.Insert(aVclPolygons
[a
]);
181 rOutDev
.DrawPolyPolygon(aVclPolyPoly
);
185 PolyPolygon
aVclPolyPoly(aVclTargetForm
);
186 aVclPolyPoly
.Insert(aVclPolygons
[0L]);
187 rOutDev
.DrawPolyPolygon(aVclPolyPoly
);
191 // draw last poly in last color
194 const basegfx::BColor
aFillColor(rColors
[rColors
.size() - 1L]);
195 rOutDev
.SetFillColor(Color(aFillColor
));
196 rOutDev
.DrawPolygon(aVclPolygons
[aVclPolygons
.size() - 1L]);
202 } // end of anonymous namespace
203 } // end of namespace drawinglayer
205 namespace drawinglayer
207 void impDrawGradientToOutDev(
208 OutputDevice
& rOutDev
,
209 const basegfx::B2DPolyPolygon
& rTargetForm
,
210 attribute::GradientStyle eGradientStyle
,
212 const basegfx::BColor
& rStart
,
213 const basegfx::BColor
& rEnd
,
214 double fBorder
, double fAngle
, double fOffsetX
, double fOffsetY
, bool bSimple
)
216 const basegfx::B2DRange
aOutlineRange(basegfx::tools::getRange(rTargetForm
));
217 ::std::vector
< basegfx::B2DHomMatrix
> aMatrices
;
218 ::std::vector
< basegfx::BColor
> aColors
;
219 basegfx::B2DPolygon aUnitPolygon
;
221 if(attribute::GRADIENTSTYLE_RADIAL
== eGradientStyle
|| attribute::GRADIENTSTYLE_ELLIPTICAL
== eGradientStyle
)
223 const basegfx::B2DPoint
aCircleCenter(0.5, 0.5);
224 aUnitPolygon
= basegfx::tools::createPolygonFromEllipse(aCircleCenter
, 0.5, 0.5);
228 aUnitPolygon
= basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0.0, 0.0, 1.0, 1.0));
231 // make sure steps is not too high/low
232 nSteps
= impCalcGradientSteps(rOutDev
, nSteps
, aOutlineRange
, sal_uInt32((rStart
.getMaximumDistance(rEnd
) * 127.5) + 0.5));
235 switch(eGradientStyle
)
237 case attribute::GRADIENTSTYLE_LINEAR
:
239 texture::GeoTexSvxGradientLinear
aGradient(aOutlineRange
, rStart
, rEnd
, nSteps
, fBorder
, fAngle
);
240 aGradient
.appendTransformations(aMatrices
);
241 aGradient
.appendColors(aColors
);
244 case attribute::GRADIENTSTYLE_AXIAL
:
246 texture::GeoTexSvxGradientAxial
aGradient(aOutlineRange
, rStart
, rEnd
, nSteps
, fBorder
, fAngle
);
247 aGradient
.appendTransformations(aMatrices
);
248 aGradient
.appendColors(aColors
);
251 case attribute::GRADIENTSTYLE_RADIAL
:
253 texture::GeoTexSvxGradientRadial
aGradient(aOutlineRange
, rStart
, rEnd
, nSteps
, fBorder
, fOffsetX
, fOffsetY
);
254 aGradient
.appendTransformations(aMatrices
);
255 aGradient
.appendColors(aColors
);
258 case attribute::GRADIENTSTYLE_ELLIPTICAL
:
260 texture::GeoTexSvxGradientElliptical
aGradient(aOutlineRange
, rStart
, rEnd
, nSteps
, fBorder
, fOffsetX
, fOffsetX
, fAngle
);
261 aGradient
.appendTransformations(aMatrices
);
262 aGradient
.appendColors(aColors
);
265 case attribute::GRADIENTSTYLE_SQUARE
:
267 texture::GeoTexSvxGradientSquare
aGradient(aOutlineRange
, rStart
, rEnd
, nSteps
, fBorder
, fOffsetX
, fOffsetX
, fAngle
);
268 aGradient
.appendTransformations(aMatrices
);
269 aGradient
.appendColors(aColors
);
272 case attribute::GRADIENTSTYLE_RECT
:
274 texture::GeoTexSvxGradientRect
aGradient(aOutlineRange
, rStart
, rEnd
, nSteps
, fBorder
, fOffsetX
, fOffsetX
, fAngle
);
275 aGradient
.appendTransformations(aMatrices
);
276 aGradient
.appendColors(aColors
);
281 // paint them with mask using the XOR method
286 impDrawGradientToOutDevSimple(rOutDev
, rTargetForm
, aMatrices
, aColors
, aUnitPolygon
);
290 impDrawGradientToOutDevComplex(rOutDev
, rTargetForm
, aMatrices
, aColors
, aUnitPolygon
);
294 } // end of namespace drawinglayer
296 //////////////////////////////////////////////////////////////////////////////