1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
33 #include <tools/svwin.h>
34 #include <wincomp.hxx>
35 #include <saldata.hxx>
37 #include <tools/debug.hxx>
40 #define min(a,b) (((a) < (b)) ? (a) : (b))
43 #define max(a,b) (((a) > (b)) ? (a) : (b))
47 #pragma warning(push, 1)
51 #include <GdiPlusEnums.h>
52 #include <GdiPlusColor.h>
58 #include <basegfx/polygon/b2dpolygon.hxx>
60 // -----------------------------------------------------------------------
62 void impAddB2DPolygonToGDIPlusGraphicsPathReal(Gdiplus::GraphicsPath
& rPath
, const basegfx::B2DPolygon
& rPolygon
, bool bNoLineJoin
)
64 sal_uInt32
nCount(rPolygon
.count());
68 const sal_uInt32
nEdgeCount(rPolygon
.isClosed() ? nCount
: nCount
- 1);
69 const bool bControls(rPolygon
.areControlPointsUsed());
70 basegfx::B2DPoint
aCurr(rPolygon
.getB2DPoint(0));
71 Gdiplus::PointF
aFCurr(Gdiplus::REAL(aCurr
.getX()), Gdiplus::REAL(aCurr
.getY()));
73 for(sal_uInt32
a(0); a
< nEdgeCount
; a
++)
75 const sal_uInt32
nNextIndex((a
+ 1) % nCount
);
76 const basegfx::B2DPoint
aNext(rPolygon
.getB2DPoint(nNextIndex
));
77 const Gdiplus::PointF
aFNext(Gdiplus::REAL(aNext
.getX()), Gdiplus::REAL(aNext
.getY()));
79 if(bControls
&& (rPolygon
.isNextControlPointUsed(a
) || rPolygon
.isPrevControlPointUsed(nNextIndex
)))
81 const basegfx::B2DPoint
aCa(rPolygon
.getNextControlPoint(a
));
82 const basegfx::B2DPoint
aCb(rPolygon
.getPrevControlPoint(nNextIndex
));
86 Gdiplus::PointF(Gdiplus::REAL(aCa
.getX()), Gdiplus::REAL(aCa
.getY())),
87 Gdiplus::PointF(Gdiplus::REAL(aCb
.getX()), Gdiplus::REAL(aCb
.getY())),
92 rPath
.AddLine(aFCurr
, aFNext
);
95 if(a
+ 1 < nEdgeCount
)
108 void impAddB2DPolygonToGDIPlusGraphicsPathInteger(Gdiplus::GraphicsPath
& rPath
, const basegfx::B2DPolygon
& rPolygon
, bool bNoLineJoin
)
110 sal_uInt32
nCount(rPolygon
.count());
114 const sal_uInt32
nEdgeCount(rPolygon
.isClosed() ? nCount
: nCount
- 1);
115 const bool bControls(rPolygon
.areControlPointsUsed());
116 basegfx::B2DPoint
aCurr(rPolygon
.getB2DPoint(0));
117 Gdiplus::Point
aICurr(INT(aCurr
.getX()), INT(aCurr
.getY()));
119 for(sal_uInt32
a(0); a
< nEdgeCount
; a
++)
121 const sal_uInt32
nNextIndex((a
+ 1) % nCount
);
122 const basegfx::B2DPoint
aNext(rPolygon
.getB2DPoint(nNextIndex
));
123 const Gdiplus::Point
aINext(INT(aNext
.getX()), INT(aNext
.getY()));
125 if(bControls
&& (rPolygon
.isNextControlPointUsed(a
) || rPolygon
.isPrevControlPointUsed(nNextIndex
)))
127 const basegfx::B2DPoint
aCa(rPolygon
.getNextControlPoint(a
));
128 const basegfx::B2DPoint
aCb(rPolygon
.getPrevControlPoint(nNextIndex
));
132 Gdiplus::Point(INT(aCa
.getX()), INT(aCa
.getY())),
133 Gdiplus::Point(INT(aCb
.getX()), INT(aCb
.getY())),
138 rPath
.AddLine(aICurr
, aINext
);
141 if(a
+ 1 < nEdgeCount
)
154 bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon
& rPolyPolygon
, double fTransparency
)
156 const sal_uInt32
nCount(rPolyPolygon
.count());
158 if(mbBrush
&& nCount
&& (fTransparency
>= 0.0 && fTransparency
< 1.0))
160 Gdiplus::Graphics
aGraphics(mhDC
);
161 const sal_uInt8
aTrans((sal_uInt8
)255 - (sal_uInt8
)basegfx::fround(fTransparency
* 255.0));
162 Gdiplus::Color
aTestColor(aTrans
, SALCOLOR_RED(maFillColor
), SALCOLOR_GREEN(maFillColor
), SALCOLOR_BLUE(maFillColor
));
163 Gdiplus::SolidBrush
aTestBrush(aTestColor
);
164 Gdiplus::GraphicsPath aPath
;
166 for(sal_uInt32
a(0); a
< nCount
; a
++)
170 aPath
.StartFigure(); // #i101491# not needed for first run
173 impAddB2DPolygonToGDIPlusGraphicsPathReal(aPath
, rPolyPolygon
.getB2DPolygon(a
), false);
177 if(getAntiAliasB2DDraw())
179 aGraphics
.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias
);
183 aGraphics
.SetSmoothingMode(Gdiplus::SmoothingModeNone
);
186 aGraphics
.FillPath(&aTestBrush
, &aPath
);
192 bool WinSalGraphics::drawPolyLine( const basegfx::B2DPolygon
& rPolygon
, double fTransparency
, const basegfx::B2DVector
& rLineWidths
, basegfx::B2DLineJoin eLineJoin
)
194 const sal_uInt32
nCount(rPolygon
.count());
198 Gdiplus::Graphics
aGraphics(mhDC
);
199 const sal_uInt8 aTrans
= (sal_uInt8
)basegfx::fround( 255 * (1.0 - fTransparency
) );
200 Gdiplus::Color
aTestColor(aTrans
, SALCOLOR_RED(maLineColor
), SALCOLOR_GREEN(maLineColor
), SALCOLOR_BLUE(maLineColor
));
201 Gdiplus::Pen
aTestPen(aTestColor
, Gdiplus::REAL(rLineWidths
.getX()));
202 Gdiplus::GraphicsPath aPath
;
203 bool bNoLineJoin(false);
207 default : // basegfx::B2DLINEJOIN_NONE :
209 if(basegfx::fTools::more(rLineWidths
.getX(), 0.0))
215 case basegfx::B2DLINEJOIN_BEVEL
:
217 aTestPen
.SetLineJoin(Gdiplus::LineJoinBevel
);
220 case basegfx::B2DLINEJOIN_MIDDLE
:
221 case basegfx::B2DLINEJOIN_MITER
:
223 const Gdiplus::REAL
aMiterLimit(15.0);
224 aTestPen
.SetMiterLimit(aMiterLimit
);
225 aTestPen
.SetLineJoin(Gdiplus::LineJoinMiter
);
228 case basegfx::B2DLINEJOIN_ROUND
:
230 aTestPen
.SetLineJoin(Gdiplus::LineJoinRound
);
235 if(nCount
> 250 && basegfx::fTools::more(rLineWidths
.getX(), 1.5))
237 impAddB2DPolygonToGDIPlusGraphicsPathInteger(aPath
, rPolygon
, bNoLineJoin
);
241 impAddB2DPolygonToGDIPlusGraphicsPathReal(aPath
, rPolygon
, bNoLineJoin
);
244 if(rPolygon
.isClosed() && !bNoLineJoin
)
246 // #i101491# needed to create the correct line joins
250 if(getAntiAliasB2DDraw())
252 aGraphics
.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias
);
256 aGraphics
.SetSmoothingMode(Gdiplus::SmoothingModeNone
);
259 aGraphics
.DrawPath(&aTestPen
, &aPath
);
265 // -----------------------------------------------------------------------