xref: /AOO41X/main/vcl/win/source/gdi/salgdi_gdiplus.cxx (revision 5f27b83cee6e25e8a00edc4ae51b88fe9d2801da)
19f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
39f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
49f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
59f62ea84SAndrew Rist  * distributed with this work for additional information
69f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
79f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
89f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
99f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
119f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
139f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
149f62ea84SAndrew Rist  * software distributed under the License is distributed on an
159f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
179f62ea84SAndrew Rist  * specific language governing permissions and limitations
189f62ea84SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
209f62ea84SAndrew Rist  *************************************************************/
219f62ea84SAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_vcl.hxx"
24cdf0e10cSrcweir 
25cdf0e10cSrcweir #include <stdio.h>
26cdf0e10cSrcweir #include <string.h>
27cdf0e10cSrcweir #include <tools/svwin.h>
28cdf0e10cSrcweir #include <tools/debug.hxx>
29cdf0e10cSrcweir #include <win/wincomp.hxx>
30cdf0e10cSrcweir #include <win/saldata.hxx>
31cdf0e10cSrcweir #include <win/salgdi.h>
32*5f27b83cSArmin Le Grand #include <win/salbmp.h>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #ifndef min
35cdf0e10cSrcweir #define min(a,b)	(((a) < (b)) ? (a) : (b))
36cdf0e10cSrcweir #endif
37cdf0e10cSrcweir #ifndef max
38cdf0e10cSrcweir #define max(a,b)	(((a) > (b)) ? (a) : (b))
39cdf0e10cSrcweir #endif
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #if defined _MSC_VER
42cdf0e10cSrcweir #pragma warning(push, 1)
43cdf0e10cSrcweir #endif
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #include <GdiPlus.h>
46cdf0e10cSrcweir #include <GdiPlusEnums.h>
47cdf0e10cSrcweir #include <GdiPlusColor.h>
48cdf0e10cSrcweir 
49cdf0e10cSrcweir #if defined _MSC_VER
50cdf0e10cSrcweir #pragma warning(pop)
51cdf0e10cSrcweir #endif
52cdf0e10cSrcweir 
53cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
54cdf0e10cSrcweir 
55cdf0e10cSrcweir // -----------------------------------------------------------------------
56cdf0e10cSrcweir 
57cdf0e10cSrcweir void impAddB2DPolygonToGDIPlusGraphicsPathReal(Gdiplus::GraphicsPath& rPath, const basegfx::B2DPolygon& rPolygon, bool bNoLineJoin)
58cdf0e10cSrcweir {
59cdf0e10cSrcweir     sal_uInt32 nCount(rPolygon.count());
60cdf0e10cSrcweir 
61cdf0e10cSrcweir     if(nCount)
62cdf0e10cSrcweir     {
63cdf0e10cSrcweir         const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1);
64cdf0e10cSrcweir         const bool bControls(rPolygon.areControlPointsUsed());
65cdf0e10cSrcweir         basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0));
66cdf0e10cSrcweir         Gdiplus::PointF aFCurr(Gdiplus::REAL(aCurr.getX()), Gdiplus::REAL(aCurr.getY()));
67cdf0e10cSrcweir 
68cdf0e10cSrcweir         for(sal_uInt32 a(0); a < nEdgeCount; a++)
69cdf0e10cSrcweir         {
70cdf0e10cSrcweir 	        const sal_uInt32 nNextIndex((a + 1) % nCount);
71cdf0e10cSrcweir 	        const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
72cdf0e10cSrcweir 	        const Gdiplus::PointF aFNext(Gdiplus::REAL(aNext.getX()), Gdiplus::REAL(aNext.getY()));
73cdf0e10cSrcweir 
74cdf0e10cSrcweir 	        if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex)))
75cdf0e10cSrcweir 	        {
76cdf0e10cSrcweir 		        const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a));
77cdf0e10cSrcweir 		        const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex));
78cdf0e10cSrcweir 
79cdf0e10cSrcweir 		        rPath.AddBezier(
80cdf0e10cSrcweir 			        aFCurr,
81cdf0e10cSrcweir 			        Gdiplus::PointF(Gdiplus::REAL(aCa.getX()), Gdiplus::REAL(aCa.getY())),
82cdf0e10cSrcweir 			        Gdiplus::PointF(Gdiplus::REAL(aCb.getX()), Gdiplus::REAL(aCb.getY())),
83cdf0e10cSrcweir 			        aFNext);
84cdf0e10cSrcweir 	        }
85cdf0e10cSrcweir 	        else
86cdf0e10cSrcweir 	        {
87cdf0e10cSrcweir 		        rPath.AddLine(aFCurr, aFNext);
88cdf0e10cSrcweir 	        }
89cdf0e10cSrcweir 
90cdf0e10cSrcweir 	        if(a + 1 < nEdgeCount)
91cdf0e10cSrcweir 	        {
92cdf0e10cSrcweir 		        aFCurr = aFNext;
93cdf0e10cSrcweir 
94cdf0e10cSrcweir 			    if(bNoLineJoin)
95cdf0e10cSrcweir 			    {
96cdf0e10cSrcweir 				    rPath.StartFigure();
97cdf0e10cSrcweir 			    }
98cdf0e10cSrcweir 	        }
99cdf0e10cSrcweir         }
100cdf0e10cSrcweir     }
101cdf0e10cSrcweir }
102cdf0e10cSrcweir 
103cdf0e10cSrcweir void impAddB2DPolygonToGDIPlusGraphicsPathInteger(Gdiplus::GraphicsPath& rPath, const basegfx::B2DPolygon& rPolygon, bool bNoLineJoin)
104cdf0e10cSrcweir {
105cdf0e10cSrcweir     sal_uInt32 nCount(rPolygon.count());
106cdf0e10cSrcweir 
107cdf0e10cSrcweir     if(nCount)
108cdf0e10cSrcweir     {
109cdf0e10cSrcweir         const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1);
110cdf0e10cSrcweir         const bool bControls(rPolygon.areControlPointsUsed());
111cdf0e10cSrcweir         basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0));
112cdf0e10cSrcweir         Gdiplus::Point aICurr(INT(aCurr.getX()), INT(aCurr.getY()));
113cdf0e10cSrcweir 
114cdf0e10cSrcweir         for(sal_uInt32 a(0); a < nEdgeCount; a++)
115cdf0e10cSrcweir         {
116cdf0e10cSrcweir 	        const sal_uInt32 nNextIndex((a + 1) % nCount);
117cdf0e10cSrcweir 	        const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
118cdf0e10cSrcweir 	        const Gdiplus::Point aINext(INT(aNext.getX()), INT(aNext.getY()));
119cdf0e10cSrcweir 
120cdf0e10cSrcweir 	        if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex)))
121cdf0e10cSrcweir 	        {
122cdf0e10cSrcweir 		        const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a));
123cdf0e10cSrcweir 		        const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex));
124cdf0e10cSrcweir 
125cdf0e10cSrcweir 		        rPath.AddBezier(
126cdf0e10cSrcweir 			        aICurr,
127cdf0e10cSrcweir 			        Gdiplus::Point(INT(aCa.getX()), INT(aCa.getY())),
128cdf0e10cSrcweir 			        Gdiplus::Point(INT(aCb.getX()), INT(aCb.getY())),
129cdf0e10cSrcweir 			        aINext);
130cdf0e10cSrcweir 	        }
131cdf0e10cSrcweir 	        else
132cdf0e10cSrcweir 	        {
133cdf0e10cSrcweir 		        rPath.AddLine(aICurr, aINext);
134cdf0e10cSrcweir 	        }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 	        if(a + 1 < nEdgeCount)
137cdf0e10cSrcweir 	        {
138cdf0e10cSrcweir 		        aICurr = aINext;
139cdf0e10cSrcweir 
140cdf0e10cSrcweir 			    if(bNoLineJoin)
141cdf0e10cSrcweir 			    {
142cdf0e10cSrcweir 				    rPath.StartFigure();
143cdf0e10cSrcweir 			    }
144cdf0e10cSrcweir 	        }
145cdf0e10cSrcweir         }
146cdf0e10cSrcweir     }
147cdf0e10cSrcweir }
148cdf0e10cSrcweir 
149cdf0e10cSrcweir bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency)
150cdf0e10cSrcweir {
151cdf0e10cSrcweir 	const sal_uInt32 nCount(rPolyPolygon.count());
152cdf0e10cSrcweir 
153cdf0e10cSrcweir 	if(mbBrush && nCount && (fTransparency >= 0.0 && fTransparency < 1.0))
154cdf0e10cSrcweir 	{
155*5f27b83cSArmin Le Grand 		Gdiplus::Graphics aGraphics(getHDC());
156cdf0e10cSrcweir 		const sal_uInt8 aTrans((sal_uInt8)255 - (sal_uInt8)basegfx::fround(fTransparency * 255.0));
157cdf0e10cSrcweir 		Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maFillColor), SALCOLOR_GREEN(maFillColor), SALCOLOR_BLUE(maFillColor));
158cdf0e10cSrcweir 		Gdiplus::SolidBrush aTestBrush(aTestColor);
159cdf0e10cSrcweir 		Gdiplus::GraphicsPath aPath;
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 		for(sal_uInt32 a(0); a < nCount; a++)
162cdf0e10cSrcweir 		{
163cdf0e10cSrcweir             if(0 != a)
164cdf0e10cSrcweir             {
165cdf0e10cSrcweir                 aPath.StartFigure(); // #i101491# not needed for first run
166cdf0e10cSrcweir             }
167cdf0e10cSrcweir 
168cdf0e10cSrcweir 			impAddB2DPolygonToGDIPlusGraphicsPathReal(aPath, rPolyPolygon.getB2DPolygon(a), false);
169cdf0e10cSrcweir             aPath.CloseFigure();
170cdf0e10cSrcweir 		}
171cdf0e10cSrcweir 
172cdf0e10cSrcweir         if(getAntiAliasB2DDraw())
173cdf0e10cSrcweir         {
174cdf0e10cSrcweir             aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
175cdf0e10cSrcweir         }
176cdf0e10cSrcweir         else
177cdf0e10cSrcweir         {
178cdf0e10cSrcweir     		aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone);
179cdf0e10cSrcweir         }
180cdf0e10cSrcweir 
181cdf0e10cSrcweir 		aGraphics.FillPath(&aTestBrush, &aPath);
182cdf0e10cSrcweir 	}
183cdf0e10cSrcweir 
184cdf0e10cSrcweir  	return true;
185cdf0e10cSrcweir }
186cdf0e10cSrcweir 
1875aaf853bSArmin Le Grand bool WinSalGraphics::drawPolyLine(
1885aaf853bSArmin Le Grand     const basegfx::B2DPolygon& rPolygon,
1895aaf853bSArmin Le Grand     double fTransparency,
1905aaf853bSArmin Le Grand     const basegfx::B2DVector& rLineWidths,
1915aaf853bSArmin Le Grand     basegfx::B2DLineJoin eLineJoin,
1925aaf853bSArmin Le Grand     com::sun::star::drawing::LineCap eLineCap)
193cdf0e10cSrcweir {
194cdf0e10cSrcweir     const sal_uInt32 nCount(rPolygon.count());
195cdf0e10cSrcweir 
196cdf0e10cSrcweir 	if(mbPen && nCount)
197cdf0e10cSrcweir 	{
198*5f27b83cSArmin Le Grand 		Gdiplus::Graphics aGraphics(getHDC());
199cdf0e10cSrcweir 		const sal_uInt8 aTrans = (sal_uInt8)basegfx::fround( 255 * (1.0 - fTransparency) );
200cdf0e10cSrcweir 		Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor));
201cdf0e10cSrcweir 		Gdiplus::Pen aTestPen(aTestColor, Gdiplus::REAL(rLineWidths.getX()));
202cdf0e10cSrcweir 		Gdiplus::GraphicsPath aPath;
203cdf0e10cSrcweir 		bool bNoLineJoin(false);
204cdf0e10cSrcweir 
205cdf0e10cSrcweir 		switch(eLineJoin)
206cdf0e10cSrcweir 		{
207cdf0e10cSrcweir 			default : // basegfx::B2DLINEJOIN_NONE :
208cdf0e10cSrcweir 			{
209cdf0e10cSrcweir 				if(basegfx::fTools::more(rLineWidths.getX(), 0.0))
210cdf0e10cSrcweir 				{
211cdf0e10cSrcweir 					bNoLineJoin = true;
212cdf0e10cSrcweir 				}
213cdf0e10cSrcweir 				break;
214cdf0e10cSrcweir 			}
215cdf0e10cSrcweir 			case basegfx::B2DLINEJOIN_BEVEL :
216cdf0e10cSrcweir 			{
217cdf0e10cSrcweir 				aTestPen.SetLineJoin(Gdiplus::LineJoinBevel);
218cdf0e10cSrcweir 				break;
219cdf0e10cSrcweir 			}
220cdf0e10cSrcweir 			case basegfx::B2DLINEJOIN_MIDDLE :
221cdf0e10cSrcweir 			case basegfx::B2DLINEJOIN_MITER :
222cdf0e10cSrcweir 			{
223cdf0e10cSrcweir 				const Gdiplus::REAL aMiterLimit(15.0);
224cdf0e10cSrcweir 				aTestPen.SetMiterLimit(aMiterLimit);
225cdf0e10cSrcweir 				aTestPen.SetLineJoin(Gdiplus::LineJoinMiter);
226cdf0e10cSrcweir 				break;
227cdf0e10cSrcweir 			}
228cdf0e10cSrcweir 			case basegfx::B2DLINEJOIN_ROUND :
229cdf0e10cSrcweir 			{
230cdf0e10cSrcweir 				aTestPen.SetLineJoin(Gdiplus::LineJoinRound);
231cdf0e10cSrcweir 				break;
232cdf0e10cSrcweir 			}
233cdf0e10cSrcweir 		}
234cdf0e10cSrcweir 
2355aaf853bSArmin Le Grand         switch(eLineCap)
2365aaf853bSArmin Le Grand         {
2375aaf853bSArmin Le Grand             default: /*com::sun::star::drawing::LineCap_BUTT*/
2385aaf853bSArmin Le Grand             {
2395aaf853bSArmin Le Grand                 // nothing to do
2405aaf853bSArmin Le Grand                 break;
2415aaf853bSArmin Le Grand             }
2425aaf853bSArmin Le Grand             case com::sun::star::drawing::LineCap_ROUND:
2435aaf853bSArmin Le Grand             {
2445aaf853bSArmin Le Grand                 aTestPen.SetStartCap(Gdiplus::LineCapRound);
2455aaf853bSArmin Le Grand                 aTestPen.SetEndCap(Gdiplus::LineCapRound);
2465aaf853bSArmin Le Grand                 break;
2475aaf853bSArmin Le Grand             }
2485aaf853bSArmin Le Grand             case com::sun::star::drawing::LineCap_SQUARE:
2495aaf853bSArmin Le Grand             {
2505aaf853bSArmin Le Grand                 aTestPen.SetStartCap(Gdiplus::LineCapSquare);
2515aaf853bSArmin Le Grand                 aTestPen.SetEndCap(Gdiplus::LineCapSquare);
2525aaf853bSArmin Le Grand                 break;
2535aaf853bSArmin Le Grand             }
2545aaf853bSArmin Le Grand         }
2555aaf853bSArmin Le Grand 
256cdf0e10cSrcweir 		if(nCount > 250 && basegfx::fTools::more(rLineWidths.getX(), 1.5))
257cdf0e10cSrcweir         {
258cdf0e10cSrcweir     		impAddB2DPolygonToGDIPlusGraphicsPathInteger(aPath, rPolygon, bNoLineJoin);
259cdf0e10cSrcweir         }
260cdf0e10cSrcweir         else
261cdf0e10cSrcweir         {
262cdf0e10cSrcweir     		impAddB2DPolygonToGDIPlusGraphicsPathReal(aPath, rPolygon, bNoLineJoin);
263cdf0e10cSrcweir         }
264cdf0e10cSrcweir 
265cdf0e10cSrcweir         if(rPolygon.isClosed() && !bNoLineJoin)
266cdf0e10cSrcweir         {
267cdf0e10cSrcweir             // #i101491# needed to create the correct line joins
268cdf0e10cSrcweir             aPath.CloseFigure();
269cdf0e10cSrcweir         }
270cdf0e10cSrcweir 
271cdf0e10cSrcweir         if(getAntiAliasB2DDraw())
272cdf0e10cSrcweir         {
273cdf0e10cSrcweir     		aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
274cdf0e10cSrcweir         }
275cdf0e10cSrcweir         else
276cdf0e10cSrcweir         {
277cdf0e10cSrcweir     		aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone);
278cdf0e10cSrcweir         }
279cdf0e10cSrcweir 
280cdf0e10cSrcweir 		aGraphics.DrawPath(&aTestPen, &aPath);
281cdf0e10cSrcweir 	}
282cdf0e10cSrcweir 
283cdf0e10cSrcweir 	return true;
284cdf0e10cSrcweir }
285cdf0e10cSrcweir 
286cdf0e10cSrcweir // -----------------------------------------------------------------------
287*5f27b83cSArmin Le Grand 
288*5f27b83cSArmin Le Grand void paintToGdiPlus(
289*5f27b83cSArmin Le Grand     Gdiplus::Graphics& rGraphics,
290*5f27b83cSArmin Le Grand     const SalTwoRect& rTR,
291*5f27b83cSArmin Le Grand     Gdiplus::Bitmap& rBitmap)
292*5f27b83cSArmin Le Grand {
293*5f27b83cSArmin Le Grand     // only parts of source are used
294*5f27b83cSArmin Le Grand     Gdiplus::PointF aDestPoints[3];
295*5f27b83cSArmin Le Grand     Gdiplus::ImageAttributes aAttributes;
296*5f27b83cSArmin Le Grand 
297*5f27b83cSArmin Le Grand     // define target region as paralellogram
298*5f27b83cSArmin Le Grand     aDestPoints[0].X = Gdiplus::REAL(rTR.mnDestX);
299*5f27b83cSArmin Le Grand     aDestPoints[0].Y = Gdiplus::REAL(rTR.mnDestY);
300*5f27b83cSArmin Le Grand     aDestPoints[1].X = Gdiplus::REAL(rTR.mnDestX + rTR.mnDestWidth);
301*5f27b83cSArmin Le Grand     aDestPoints[1].Y = Gdiplus::REAL(rTR.mnDestY);
302*5f27b83cSArmin Le Grand     aDestPoints[2].X = Gdiplus::REAL(rTR.mnDestX);
303*5f27b83cSArmin Le Grand     aDestPoints[2].Y = Gdiplus::REAL(rTR.mnDestY + rTR.mnDestHeight);
304*5f27b83cSArmin Le Grand 
305*5f27b83cSArmin Le Grand     aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY);
306*5f27b83cSArmin Le Grand 
307*5f27b83cSArmin Le Grand     rGraphics.DrawImage(
308*5f27b83cSArmin Le Grand         &rBitmap,
309*5f27b83cSArmin Le Grand         aDestPoints,
310*5f27b83cSArmin Le Grand         3,
311*5f27b83cSArmin Le Grand         Gdiplus::REAL(rTR.mnSrcX),
312*5f27b83cSArmin Le Grand         Gdiplus::REAL(rTR.mnSrcY),
313*5f27b83cSArmin Le Grand         Gdiplus::REAL(rTR.mnSrcWidth),
314*5f27b83cSArmin Le Grand         Gdiplus::REAL(rTR.mnSrcHeight),
315*5f27b83cSArmin Le Grand         Gdiplus::UnitPixel,
316*5f27b83cSArmin Le Grand         &aAttributes,
317*5f27b83cSArmin Le Grand         0,
318*5f27b83cSArmin Le Grand         0);
319*5f27b83cSArmin Le Grand }
320*5f27b83cSArmin Le Grand 
321*5f27b83cSArmin Le Grand // -----------------------------------------------------------------------
322*5f27b83cSArmin Le Grand 
323*5f27b83cSArmin Le Grand void setInterpolationMode(
324*5f27b83cSArmin Le Grand     Gdiplus::Graphics& rGraphics,
325*5f27b83cSArmin Le Grand     const long& rSrcWidth,
326*5f27b83cSArmin Le Grand     const long& rDestWidth,
327*5f27b83cSArmin Le Grand     const long& rSrcHeight,
328*5f27b83cSArmin Le Grand     const long& rDestHeight)
329*5f27b83cSArmin Le Grand {
330*5f27b83cSArmin Le Grand     const bool bSameWidth(rSrcWidth == rDestWidth);
331*5f27b83cSArmin Le Grand     const bool bSameHeight(rSrcHeight == rDestHeight);
332*5f27b83cSArmin Le Grand 
333*5f27b83cSArmin Le Grand     if(bSameWidth && bSameHeight)
334*5f27b83cSArmin Le Grand     {
335*5f27b83cSArmin Le Grand         rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeInvalid);
336*5f27b83cSArmin Le Grand     }
337*5f27b83cSArmin Le Grand     else if(rDestWidth > rSrcWidth && rDestHeight > rSrcHeight)
338*5f27b83cSArmin Le Grand     {
339*5f27b83cSArmin Le Grand         rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault);
340*5f27b83cSArmin Le Grand     }
341*5f27b83cSArmin Le Grand     else if(rDestWidth < rSrcWidth && rDestHeight < rSrcHeight)
342*5f27b83cSArmin Le Grand     {
343*5f27b83cSArmin Le Grand         rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeBicubic);
344*5f27b83cSArmin Le Grand     }
345*5f27b83cSArmin Le Grand     else
346*5f27b83cSArmin Le Grand     {
347*5f27b83cSArmin Le Grand         rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault);
348*5f27b83cSArmin Le Grand     }
349*5f27b83cSArmin Le Grand }
350*5f27b83cSArmin Le Grand 
351*5f27b83cSArmin Le Grand 
352*5f27b83cSArmin Le Grand bool WinSalGraphics::tryDrawBitmapGdiPlus(const SalTwoRect& rTR, const SalBitmap& rSrcBitmap)
353*5f27b83cSArmin Le Grand {
354*5f27b83cSArmin Le Grand     if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight)
355*5f27b83cSArmin Le Grand     {
356*5f27b83cSArmin Le Grand         const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap);
357*5f27b83cSArmin Le Grand         GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap());
358*5f27b83cSArmin Le Grand 
359*5f27b83cSArmin Le Grand         if(aARGB.get())
360*5f27b83cSArmin Le Grand         {
361*5f27b83cSArmin Le Grand             Gdiplus::Graphics aGraphics(getHDC());
362*5f27b83cSArmin Le Grand 
363*5f27b83cSArmin Le Grand             setInterpolationMode(
364*5f27b83cSArmin Le Grand                 aGraphics,
365*5f27b83cSArmin Le Grand                 rTR.mnSrcWidth,
366*5f27b83cSArmin Le Grand                 rTR.mnDestWidth,
367*5f27b83cSArmin Le Grand                 rTR.mnSrcHeight,
368*5f27b83cSArmin Le Grand                 rTR.mnDestHeight);
369*5f27b83cSArmin Le Grand 
370*5f27b83cSArmin Le Grand             paintToGdiPlus(
371*5f27b83cSArmin Le Grand                 aGraphics,
372*5f27b83cSArmin Le Grand                 rTR,
373*5f27b83cSArmin Le Grand                 *aARGB.get());
374*5f27b83cSArmin Le Grand 
375*5f27b83cSArmin Le Grand             return true;
376*5f27b83cSArmin Le Grand         }
377*5f27b83cSArmin Le Grand     }
378*5f27b83cSArmin Le Grand 
379*5f27b83cSArmin Le Grand     return false;
380*5f27b83cSArmin Le Grand }
381*5f27b83cSArmin Le Grand 
382*5f27b83cSArmin Le Grand bool WinSalGraphics::drawAlphaBitmap(
383*5f27b83cSArmin Le Grand     const SalTwoRect& rTR,
384*5f27b83cSArmin Le Grand     const SalBitmap& rSrcBitmap,
385*5f27b83cSArmin Le Grand     const SalBitmap& rAlphaBmp)
386*5f27b83cSArmin Le Grand {
387*5f27b83cSArmin Le Grand     if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight)
388*5f27b83cSArmin Le Grand     {
389*5f27b83cSArmin Le Grand         const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap);
390*5f27b83cSArmin Le Grand         const WinSalBitmap& rSalAlpha = static_cast< const WinSalBitmap& >(rAlphaBmp);
391*5f27b83cSArmin Le Grand         GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap(&rSalAlpha));
392*5f27b83cSArmin Le Grand 
393*5f27b83cSArmin Le Grand         if(aARGB.get())
394*5f27b83cSArmin Le Grand         {
395*5f27b83cSArmin Le Grand             Gdiplus::Graphics aGraphics(getHDC());
396*5f27b83cSArmin Le Grand 
397*5f27b83cSArmin Le Grand             setInterpolationMode(
398*5f27b83cSArmin Le Grand                 aGraphics,
399*5f27b83cSArmin Le Grand                 rTR.mnSrcWidth,
400*5f27b83cSArmin Le Grand                 rTR.mnDestWidth,
401*5f27b83cSArmin Le Grand                 rTR.mnSrcHeight,
402*5f27b83cSArmin Le Grand                 rTR.mnDestHeight);
403*5f27b83cSArmin Le Grand 
404*5f27b83cSArmin Le Grand             paintToGdiPlus(
405*5f27b83cSArmin Le Grand                 aGraphics,
406*5f27b83cSArmin Le Grand                 rTR,
407*5f27b83cSArmin Le Grand                 *aARGB.get());
408*5f27b83cSArmin Le Grand 
409*5f27b83cSArmin Le Grand             return true;
410*5f27b83cSArmin Le Grand         }
411*5f27b83cSArmin Le Grand     }
412*5f27b83cSArmin Le Grand 
413*5f27b83cSArmin Le Grand     return false;
414*5f27b83cSArmin Le Grand }
415*5f27b83cSArmin Le Grand 
416*5f27b83cSArmin Le Grand // -----------------------------------------------------------------------
417*5f27b83cSArmin Le Grand 
418*5f27b83cSArmin Le Grand bool WinSalGraphics::drawTransformedBitmap(
419*5f27b83cSArmin Le Grand     const basegfx::B2DPoint& rNull,
420*5f27b83cSArmin Le Grand     const basegfx::B2DPoint& rX,
421*5f27b83cSArmin Le Grand     const basegfx::B2DPoint& rY,
422*5f27b83cSArmin Le Grand     const SalBitmap& rSourceBitmap,
423*5f27b83cSArmin Le Grand     const SalBitmap* pAlphaBitmap)
424*5f27b83cSArmin Le Grand {
425*5f27b83cSArmin Le Grand     const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSourceBitmap);
426*5f27b83cSArmin Le Grand     const WinSalBitmap* pSalAlpha = static_cast< const WinSalBitmap* >(pAlphaBitmap);
427*5f27b83cSArmin Le Grand     GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap(pSalAlpha));
428*5f27b83cSArmin Le Grand 
429*5f27b83cSArmin Le Grand     if(aARGB.get())
430*5f27b83cSArmin Le Grand     {
431*5f27b83cSArmin Le Grand         const long nSrcWidth(aARGB->GetWidth());
432*5f27b83cSArmin Le Grand         const long nSrcHeight(aARGB->GetHeight());
433*5f27b83cSArmin Le Grand 
434*5f27b83cSArmin Le Grand         if(nSrcWidth && nSrcHeight)
435*5f27b83cSArmin Le Grand         {
436*5f27b83cSArmin Le Grand             const long nDestWidth(basegfx::fround(basegfx::B2DVector(rX - rNull).getLength()));
437*5f27b83cSArmin Le Grand             const long nDestHeight(basegfx::fround(basegfx::B2DVector(rY - rNull).getLength()));
438*5f27b83cSArmin Le Grand 
439*5f27b83cSArmin Le Grand             if(nDestWidth && nDestHeight)
440*5f27b83cSArmin Le Grand             {
441*5f27b83cSArmin Le Grand                 Gdiplus::Graphics aGraphics(getHDC());
442*5f27b83cSArmin Le Grand                 Gdiplus::PointF aDestPoints[3];
443*5f27b83cSArmin Le Grand                 Gdiplus::ImageAttributes aAttributes;
444*5f27b83cSArmin Le Grand 
445*5f27b83cSArmin Le Grand                 setInterpolationMode(
446*5f27b83cSArmin Le Grand                     aGraphics,
447*5f27b83cSArmin Le Grand                     nSrcWidth,
448*5f27b83cSArmin Le Grand                     nDestWidth,
449*5f27b83cSArmin Le Grand                     nSrcHeight,
450*5f27b83cSArmin Le Grand                     nDestHeight);
451*5f27b83cSArmin Le Grand 
452*5f27b83cSArmin Le Grand                 // this mode is only capable of drawing the whole bitmap to a paralellogram
453*5f27b83cSArmin Le Grand                 aDestPoints[0].X = Gdiplus::REAL(rNull.getX());
454*5f27b83cSArmin Le Grand                 aDestPoints[0].Y = Gdiplus::REAL(rNull.getY());
455*5f27b83cSArmin Le Grand                 aDestPoints[1].X = Gdiplus::REAL(rX.getX());
456*5f27b83cSArmin Le Grand                 aDestPoints[1].Y = Gdiplus::REAL(rX.getY());
457*5f27b83cSArmin Le Grand                 aDestPoints[2].X = Gdiplus::REAL(rY.getX());
458*5f27b83cSArmin Le Grand                 aDestPoints[2].Y = Gdiplus::REAL(rY.getY());
459*5f27b83cSArmin Le Grand 
460*5f27b83cSArmin Le Grand                 aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY);
461*5f27b83cSArmin Le Grand 
462*5f27b83cSArmin Le Grand                 aGraphics.DrawImage(
463*5f27b83cSArmin Le Grand                     aARGB.get(),
464*5f27b83cSArmin Le Grand                     aDestPoints,
465*5f27b83cSArmin Le Grand                     3,
466*5f27b83cSArmin Le Grand                     Gdiplus::REAL(0.0),
467*5f27b83cSArmin Le Grand                     Gdiplus::REAL(0.0),
468*5f27b83cSArmin Le Grand                     Gdiplus::REAL(nSrcWidth),
469*5f27b83cSArmin Le Grand                     Gdiplus::REAL(nSrcHeight),
470*5f27b83cSArmin Le Grand                     Gdiplus::UnitPixel,
471*5f27b83cSArmin Le Grand                     &aAttributes,
472*5f27b83cSArmin Le Grand                     0,
473*5f27b83cSArmin Le Grand                     0);
474*5f27b83cSArmin Le Grand             }
475*5f27b83cSArmin Le Grand         }
476*5f27b83cSArmin Le Grand 
477*5f27b83cSArmin Le Grand         return true;
478*5f27b83cSArmin Le Grand     }
479*5f27b83cSArmin Le Grand 
480*5f27b83cSArmin Le Grand     return false;
481*5f27b83cSArmin Le Grand }
482*5f27b83cSArmin Le Grand 
483*5f27b83cSArmin Le Grand // -----------------------------------------------------------------------
484*5f27b83cSArmin Le Grand // eof
485