Update ooo320-m1
[ooovba.git] / drawinglayer / source / processor2d / vclhelpergradient.cxx
blobc02845e9c6faee58e11e2326436c44cb3e0793b5
1 /*************************************************************************
3 * OpenOffice.org - a multi-platform office productivity suite
5 * $RCSfile: vclhelpergradient.cxx,v $
7 * $Revision: 1.5 $
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,
32 * MA 02111-1307 USA
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
52 namespace
54 sal_uInt32 impCalcGradientSteps(OutputDevice& rOutDev, sal_uInt32 nSteps, const basegfx::B2DRange& rRange, sal_uInt32 nMaxDist)
56 if(nSteps == 0L)
58 const Size aSize(rOutDev.LogicToPixel(Size(basegfx::fround(rRange.getWidth()), basegfx::fround(rRange.getHeight()))));
59 nSteps = (aSize.getWidth() + aSize.getHeight()) >> 3L;
62 if(nSteps < 2L)
64 nSteps = 2L;
67 if(nSteps > nMaxDist)
69 nSteps = nMaxDist;
72 return nSteps;
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++)
86 // set correct color
87 const basegfx::BColor aFillColor(rColors[a]);
88 rOutDev.SetFillColor(Color(aFillColor));
90 if(a)
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);
99 else
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;
115 sal_uInt32 a;
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));
130 // set correct color
131 if(rColors.size() > a)
133 const basegfx::BColor aFillColor(rColors[a]);
134 rOutDev.SetFillColor(Color(aFillColor));
137 // create vcl PolyPolygon and draw it
138 if(a)
140 PolyPolygon aVclPolyPoly(aVclPolygons[a - 1L]);
141 aVclPolyPoly.Insert(aVclPolygons[a]);
142 rOutDev.DrawPolyPolygon(aVclPolyPoly);
144 else
146 PolyPolygon aVclPolyPoly(aVclTargetForm);
147 aVclPolyPoly.Insert(aVclPolygons[0L]);
148 rOutDev.DrawPolyPolygon(aVclPolyPoly);
152 // draw last poly in last color
153 if(rColors.size())
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++)
169 // set correct color
170 if(rColors.size() > a)
172 const basegfx::BColor aFillColor(rColors[a]);
173 rOutDev.SetFillColor(Color(aFillColor));
176 // create vcl PolyPolygon and draw it
177 if(a)
179 PolyPolygon aVclPolyPoly(aVclPolygons[a - 1L]);
180 aVclPolyPoly.Insert(aVclPolygons[a]);
181 rOutDev.DrawPolyPolygon(aVclPolyPoly);
183 else
185 PolyPolygon aVclPolyPoly(aVclTargetForm);
186 aVclPolyPoly.Insert(aVclPolygons[0L]);
187 rOutDev.DrawPolyPolygon(aVclPolyPoly);
191 // draw last poly in last color
192 if(rColors.size())
194 const basegfx::BColor aFillColor(rColors[rColors.size() - 1L]);
195 rOutDev.SetFillColor(Color(aFillColor));
196 rOutDev.DrawPolygon(aVclPolygons[aVclPolygons.size() - 1L]);
199 // reset drawmode
200 rOutDev.Pop();
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,
211 sal_uInt32 nSteps,
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);
226 else
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));
234 // create geometries
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);
242 break;
244 case attribute::GRADIENTSTYLE_AXIAL:
246 texture::GeoTexSvxGradientAxial aGradient(aOutlineRange, rStart, rEnd, nSteps, fBorder, fAngle);
247 aGradient.appendTransformations(aMatrices);
248 aGradient.appendColors(aColors);
249 break;
251 case attribute::GRADIENTSTYLE_RADIAL:
253 texture::GeoTexSvxGradientRadial aGradient(aOutlineRange, rStart, rEnd, nSteps, fBorder, fOffsetX, fOffsetY);
254 aGradient.appendTransformations(aMatrices);
255 aGradient.appendColors(aColors);
256 break;
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);
263 break;
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);
270 break;
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);
277 break;
281 // paint them with mask using the XOR method
282 if(aMatrices.size())
284 if(bSimple)
286 impDrawGradientToOutDevSimple(rOutDev, rTargetForm, aMatrices, aColors, aUnitPolygon);
288 else
290 impDrawGradientToOutDevComplex(rOutDev, rTargetForm, aMatrices, aColors, aUnitPolygon);
294 } // end of namespace drawinglayer
296 //////////////////////////////////////////////////////////////////////////////
297 // eof