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> 325f27b83cSArmin 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 { 1555f27b83cSArmin 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 181*4aeb9d34SArmin Le Grand if(mbPrinter) 182*4aeb9d34SArmin Le Grand { 183*4aeb9d34SArmin Le Grand // #121591# 184*4aeb9d34SArmin Le Grand // Normally GdiPlus should not be used for printing at all since printers cannot 185*4aeb9d34SArmin Le Grand // print transparent filled polygon geometry and normally this does not happen 186*4aeb9d34SArmin Le Grand // since OutputDevice::RemoveTransparenciesFromMetaFile is used as preparation 187*4aeb9d34SArmin Le Grand // and no transparent parts should remain for printing. But this can be overriden 188*4aeb9d34SArmin Le Grand // by the user and thus happens. This call can only come (currently) from 189*4aeb9d34SArmin Le Grand // OutputDevice::DrawTransparent, see comments sthere with the same TaskID. 190*4aeb9d34SArmin Le Grand // If it is used, the mapping for the printer is wrong and needs to be corrected. I 191*4aeb9d34SArmin Le Grand // checked that there is *no* transformation set (testcode commented out below) and 192*4aeb9d34SArmin Le Grand // estimated that a stable factor dependent of the printer's DPI is used. Create 193*4aeb9d34SArmin Le Grand // and set a transformation here to correct this 194*4aeb9d34SArmin Le Grand const Gdiplus::REAL aDpiX(aGraphics.GetDpiX()); 195*4aeb9d34SArmin Le Grand const Gdiplus::REAL aDpiY(aGraphics.GetDpiY()); 196*4aeb9d34SArmin Le Grand 197*4aeb9d34SArmin Le Grand // test code to check the current transformation at the graphics device 198*4aeb9d34SArmin Le Grand //Gdiplus::Matrix matrix; 199*4aeb9d34SArmin Le Grand //aGraphics.GetTransform(&matrix); 200*4aeb9d34SArmin Le Grand //Gdiplus::REAL elements[6]; 201*4aeb9d34SArmin Le Grand //matrix.GetElements(elements); 202*4aeb9d34SArmin Le Grand 203*4aeb9d34SArmin Le Grand Gdiplus::Matrix aPrinterTransform; 204*4aeb9d34SArmin Le Grand aPrinterTransform.Scale(Gdiplus::REAL(100.0) / aDpiX, Gdiplus::REAL(100.0) / aDpiY); 205*4aeb9d34SArmin Le Grand aGraphics.SetTransform(&aPrinterTransform); 206*4aeb9d34SArmin Le Grand } 207*4aeb9d34SArmin Le Grand 208cdf0e10cSrcweir aGraphics.FillPath(&aTestBrush, &aPath); 209cdf0e10cSrcweir } 210cdf0e10cSrcweir 211cdf0e10cSrcweir return true; 212cdf0e10cSrcweir } 213cdf0e10cSrcweir 2145aaf853bSArmin Le Grand bool WinSalGraphics::drawPolyLine( 2155aaf853bSArmin Le Grand const basegfx::B2DPolygon& rPolygon, 2165aaf853bSArmin Le Grand double fTransparency, 2175aaf853bSArmin Le Grand const basegfx::B2DVector& rLineWidths, 2185aaf853bSArmin Le Grand basegfx::B2DLineJoin eLineJoin, 2195aaf853bSArmin Le Grand com::sun::star::drawing::LineCap eLineCap) 220cdf0e10cSrcweir { 221cdf0e10cSrcweir const sal_uInt32 nCount(rPolygon.count()); 222cdf0e10cSrcweir 223cdf0e10cSrcweir if(mbPen && nCount) 224cdf0e10cSrcweir { 2255f27b83cSArmin Le Grand Gdiplus::Graphics aGraphics(getHDC()); 226cdf0e10cSrcweir const sal_uInt8 aTrans = (sal_uInt8)basegfx::fround( 255 * (1.0 - fTransparency) ); 227cdf0e10cSrcweir Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor)); 228cdf0e10cSrcweir Gdiplus::Pen aTestPen(aTestColor, Gdiplus::REAL(rLineWidths.getX())); 229cdf0e10cSrcweir Gdiplus::GraphicsPath aPath; 230cdf0e10cSrcweir bool bNoLineJoin(false); 231cdf0e10cSrcweir 232cdf0e10cSrcweir switch(eLineJoin) 233cdf0e10cSrcweir { 234cdf0e10cSrcweir default : // basegfx::B2DLINEJOIN_NONE : 235cdf0e10cSrcweir { 236cdf0e10cSrcweir if(basegfx::fTools::more(rLineWidths.getX(), 0.0)) 237cdf0e10cSrcweir { 238cdf0e10cSrcweir bNoLineJoin = true; 239cdf0e10cSrcweir } 240cdf0e10cSrcweir break; 241cdf0e10cSrcweir } 242cdf0e10cSrcweir case basegfx::B2DLINEJOIN_BEVEL : 243cdf0e10cSrcweir { 244cdf0e10cSrcweir aTestPen.SetLineJoin(Gdiplus::LineJoinBevel); 245cdf0e10cSrcweir break; 246cdf0e10cSrcweir } 247cdf0e10cSrcweir case basegfx::B2DLINEJOIN_MIDDLE : 248cdf0e10cSrcweir case basegfx::B2DLINEJOIN_MITER : 249cdf0e10cSrcweir { 250cdf0e10cSrcweir const Gdiplus::REAL aMiterLimit(15.0); 251cdf0e10cSrcweir aTestPen.SetMiterLimit(aMiterLimit); 252cdf0e10cSrcweir aTestPen.SetLineJoin(Gdiplus::LineJoinMiter); 253cdf0e10cSrcweir break; 254cdf0e10cSrcweir } 255cdf0e10cSrcweir case basegfx::B2DLINEJOIN_ROUND : 256cdf0e10cSrcweir { 257cdf0e10cSrcweir aTestPen.SetLineJoin(Gdiplus::LineJoinRound); 258cdf0e10cSrcweir break; 259cdf0e10cSrcweir } 260cdf0e10cSrcweir } 261cdf0e10cSrcweir 2625aaf853bSArmin Le Grand switch(eLineCap) 2635aaf853bSArmin Le Grand { 2645aaf853bSArmin Le Grand default: /*com::sun::star::drawing::LineCap_BUTT*/ 2655aaf853bSArmin Le Grand { 2665aaf853bSArmin Le Grand // nothing to do 2675aaf853bSArmin Le Grand break; 2685aaf853bSArmin Le Grand } 2695aaf853bSArmin Le Grand case com::sun::star::drawing::LineCap_ROUND: 2705aaf853bSArmin Le Grand { 2715aaf853bSArmin Le Grand aTestPen.SetStartCap(Gdiplus::LineCapRound); 2725aaf853bSArmin Le Grand aTestPen.SetEndCap(Gdiplus::LineCapRound); 2735aaf853bSArmin Le Grand break; 2745aaf853bSArmin Le Grand } 2755aaf853bSArmin Le Grand case com::sun::star::drawing::LineCap_SQUARE: 2765aaf853bSArmin Le Grand { 2775aaf853bSArmin Le Grand aTestPen.SetStartCap(Gdiplus::LineCapSquare); 2785aaf853bSArmin Le Grand aTestPen.SetEndCap(Gdiplus::LineCapSquare); 2795aaf853bSArmin Le Grand break; 2805aaf853bSArmin Le Grand } 2815aaf853bSArmin Le Grand } 2825aaf853bSArmin Le Grand 283cdf0e10cSrcweir if(nCount > 250 && basegfx::fTools::more(rLineWidths.getX(), 1.5)) 284cdf0e10cSrcweir { 285cdf0e10cSrcweir impAddB2DPolygonToGDIPlusGraphicsPathInteger(aPath, rPolygon, bNoLineJoin); 286cdf0e10cSrcweir } 287cdf0e10cSrcweir else 288cdf0e10cSrcweir { 289cdf0e10cSrcweir impAddB2DPolygonToGDIPlusGraphicsPathReal(aPath, rPolygon, bNoLineJoin); 290cdf0e10cSrcweir } 291cdf0e10cSrcweir 292cdf0e10cSrcweir if(rPolygon.isClosed() && !bNoLineJoin) 293cdf0e10cSrcweir { 294cdf0e10cSrcweir // #i101491# needed to create the correct line joins 295cdf0e10cSrcweir aPath.CloseFigure(); 296cdf0e10cSrcweir } 297cdf0e10cSrcweir 298cdf0e10cSrcweir if(getAntiAliasB2DDraw()) 299cdf0e10cSrcweir { 300cdf0e10cSrcweir aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias); 301cdf0e10cSrcweir } 302cdf0e10cSrcweir else 303cdf0e10cSrcweir { 304cdf0e10cSrcweir aGraphics.SetSmoothingMode(Gdiplus::SmoothingModeNone); 305cdf0e10cSrcweir } 306cdf0e10cSrcweir 307cdf0e10cSrcweir aGraphics.DrawPath(&aTestPen, &aPath); 308cdf0e10cSrcweir } 309cdf0e10cSrcweir 310cdf0e10cSrcweir return true; 311cdf0e10cSrcweir } 312cdf0e10cSrcweir 313cdf0e10cSrcweir // ----------------------------------------------------------------------- 3145f27b83cSArmin Le Grand 3155f27b83cSArmin Le Grand void paintToGdiPlus( 3165f27b83cSArmin Le Grand Gdiplus::Graphics& rGraphics, 3175f27b83cSArmin Le Grand const SalTwoRect& rTR, 3185f27b83cSArmin Le Grand Gdiplus::Bitmap& rBitmap) 3195f27b83cSArmin Le Grand { 3205f27b83cSArmin Le Grand // only parts of source are used 3215f27b83cSArmin Le Grand Gdiplus::PointF aDestPoints[3]; 3225f27b83cSArmin Le Grand Gdiplus::ImageAttributes aAttributes; 3235f27b83cSArmin Le Grand 3245f27b83cSArmin Le Grand // define target region as paralellogram 3255f27b83cSArmin Le Grand aDestPoints[0].X = Gdiplus::REAL(rTR.mnDestX); 3265f27b83cSArmin Le Grand aDestPoints[0].Y = Gdiplus::REAL(rTR.mnDestY); 3275f27b83cSArmin Le Grand aDestPoints[1].X = Gdiplus::REAL(rTR.mnDestX + rTR.mnDestWidth); 3285f27b83cSArmin Le Grand aDestPoints[1].Y = Gdiplus::REAL(rTR.mnDestY); 3295f27b83cSArmin Le Grand aDestPoints[2].X = Gdiplus::REAL(rTR.mnDestX); 3305f27b83cSArmin Le Grand aDestPoints[2].Y = Gdiplus::REAL(rTR.mnDestY + rTR.mnDestHeight); 3315f27b83cSArmin Le Grand 3325f27b83cSArmin Le Grand aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY); 3335f27b83cSArmin Le Grand 3345f27b83cSArmin Le Grand rGraphics.DrawImage( 3355f27b83cSArmin Le Grand &rBitmap, 3365f27b83cSArmin Le Grand aDestPoints, 3375f27b83cSArmin Le Grand 3, 3385f27b83cSArmin Le Grand Gdiplus::REAL(rTR.mnSrcX), 3395f27b83cSArmin Le Grand Gdiplus::REAL(rTR.mnSrcY), 3405f27b83cSArmin Le Grand Gdiplus::REAL(rTR.mnSrcWidth), 3415f27b83cSArmin Le Grand Gdiplus::REAL(rTR.mnSrcHeight), 3425f27b83cSArmin Le Grand Gdiplus::UnitPixel, 3435f27b83cSArmin Le Grand &aAttributes, 3445f27b83cSArmin Le Grand 0, 3455f27b83cSArmin Le Grand 0); 3465f27b83cSArmin Le Grand } 3475f27b83cSArmin Le Grand 3485f27b83cSArmin Le Grand // ----------------------------------------------------------------------- 3495f27b83cSArmin Le Grand 3505f27b83cSArmin Le Grand void setInterpolationMode( 3515f27b83cSArmin Le Grand Gdiplus::Graphics& rGraphics, 3525f27b83cSArmin Le Grand const long& rSrcWidth, 3535f27b83cSArmin Le Grand const long& rDestWidth, 3545f27b83cSArmin Le Grand const long& rSrcHeight, 3555f27b83cSArmin Le Grand const long& rDestHeight) 3565f27b83cSArmin Le Grand { 3575f27b83cSArmin Le Grand const bool bSameWidth(rSrcWidth == rDestWidth); 3585f27b83cSArmin Le Grand const bool bSameHeight(rSrcHeight == rDestHeight); 3595f27b83cSArmin Le Grand 3605f27b83cSArmin Le Grand if(bSameWidth && bSameHeight) 3615f27b83cSArmin Le Grand { 3625f27b83cSArmin Le Grand rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeInvalid); 3635f27b83cSArmin Le Grand } 3645f27b83cSArmin Le Grand else if(rDestWidth > rSrcWidth && rDestHeight > rSrcHeight) 3655f27b83cSArmin Le Grand { 3665f27b83cSArmin Le Grand rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault); 3675f27b83cSArmin Le Grand } 3685f27b83cSArmin Le Grand else if(rDestWidth < rSrcWidth && rDestHeight < rSrcHeight) 3695f27b83cSArmin Le Grand { 3705f27b83cSArmin Le Grand rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeBicubic); 3715f27b83cSArmin Le Grand } 3725f27b83cSArmin Le Grand else 3735f27b83cSArmin Le Grand { 3745f27b83cSArmin Le Grand rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault); 3755f27b83cSArmin Le Grand } 3765f27b83cSArmin Le Grand } 3775f27b83cSArmin Le Grand 3785f27b83cSArmin Le Grand 3795f27b83cSArmin Le Grand bool WinSalGraphics::tryDrawBitmapGdiPlus(const SalTwoRect& rTR, const SalBitmap& rSrcBitmap) 3805f27b83cSArmin Le Grand { 3815f27b83cSArmin Le Grand if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight) 3825f27b83cSArmin Le Grand { 3835f27b83cSArmin Le Grand const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap); 3845f27b83cSArmin Le Grand GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap()); 3855f27b83cSArmin Le Grand 3865f27b83cSArmin Le Grand if(aARGB.get()) 3875f27b83cSArmin Le Grand { 3885f27b83cSArmin Le Grand Gdiplus::Graphics aGraphics(getHDC()); 3895f27b83cSArmin Le Grand 3905f27b83cSArmin Le Grand setInterpolationMode( 3915f27b83cSArmin Le Grand aGraphics, 3925f27b83cSArmin Le Grand rTR.mnSrcWidth, 3935f27b83cSArmin Le Grand rTR.mnDestWidth, 3945f27b83cSArmin Le Grand rTR.mnSrcHeight, 3955f27b83cSArmin Le Grand rTR.mnDestHeight); 3965f27b83cSArmin Le Grand 3975f27b83cSArmin Le Grand paintToGdiPlus( 3985f27b83cSArmin Le Grand aGraphics, 3995f27b83cSArmin Le Grand rTR, 4005f27b83cSArmin Le Grand *aARGB.get()); 4015f27b83cSArmin Le Grand 4025f27b83cSArmin Le Grand return true; 4035f27b83cSArmin Le Grand } 4045f27b83cSArmin Le Grand } 4055f27b83cSArmin Le Grand 4065f27b83cSArmin Le Grand return false; 4075f27b83cSArmin Le Grand } 4085f27b83cSArmin Le Grand 4095f27b83cSArmin Le Grand bool WinSalGraphics::drawAlphaBitmap( 4105f27b83cSArmin Le Grand const SalTwoRect& rTR, 4115f27b83cSArmin Le Grand const SalBitmap& rSrcBitmap, 4125f27b83cSArmin Le Grand const SalBitmap& rAlphaBmp) 4135f27b83cSArmin Le Grand { 4145f27b83cSArmin Le Grand if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight) 4155f27b83cSArmin Le Grand { 4165f27b83cSArmin Le Grand const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap); 4175f27b83cSArmin Le Grand const WinSalBitmap& rSalAlpha = static_cast< const WinSalBitmap& >(rAlphaBmp); 4185f27b83cSArmin Le Grand GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap(&rSalAlpha)); 4195f27b83cSArmin Le Grand 4205f27b83cSArmin Le Grand if(aARGB.get()) 4215f27b83cSArmin Le Grand { 4225f27b83cSArmin Le Grand Gdiplus::Graphics aGraphics(getHDC()); 4235f27b83cSArmin Le Grand 4245f27b83cSArmin Le Grand setInterpolationMode( 4255f27b83cSArmin Le Grand aGraphics, 4265f27b83cSArmin Le Grand rTR.mnSrcWidth, 4275f27b83cSArmin Le Grand rTR.mnDestWidth, 4285f27b83cSArmin Le Grand rTR.mnSrcHeight, 4295f27b83cSArmin Le Grand rTR.mnDestHeight); 4305f27b83cSArmin Le Grand 4315f27b83cSArmin Le Grand paintToGdiPlus( 4325f27b83cSArmin Le Grand aGraphics, 4335f27b83cSArmin Le Grand rTR, 4345f27b83cSArmin Le Grand *aARGB.get()); 4355f27b83cSArmin Le Grand 4365f27b83cSArmin Le Grand return true; 4375f27b83cSArmin Le Grand } 4385f27b83cSArmin Le Grand } 4395f27b83cSArmin Le Grand 4405f27b83cSArmin Le Grand return false; 4415f27b83cSArmin Le Grand } 4425f27b83cSArmin Le Grand 4435f27b83cSArmin Le Grand // ----------------------------------------------------------------------- 4445f27b83cSArmin Le Grand 4455f27b83cSArmin Le Grand bool WinSalGraphics::drawTransformedBitmap( 4465f27b83cSArmin Le Grand const basegfx::B2DPoint& rNull, 4475f27b83cSArmin Le Grand const basegfx::B2DPoint& rX, 4485f27b83cSArmin Le Grand const basegfx::B2DPoint& rY, 4495f27b83cSArmin Le Grand const SalBitmap& rSourceBitmap, 4505f27b83cSArmin Le Grand const SalBitmap* pAlphaBitmap) 4515f27b83cSArmin Le Grand { 4525f27b83cSArmin Le Grand const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSourceBitmap); 4535f27b83cSArmin Le Grand const WinSalBitmap* pSalAlpha = static_cast< const WinSalBitmap* >(pAlphaBitmap); 4545f27b83cSArmin Le Grand GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap(pSalAlpha)); 4555f27b83cSArmin Le Grand 4565f27b83cSArmin Le Grand if(aARGB.get()) 4575f27b83cSArmin Le Grand { 4585f27b83cSArmin Le Grand const long nSrcWidth(aARGB->GetWidth()); 4595f27b83cSArmin Le Grand const long nSrcHeight(aARGB->GetHeight()); 4605f27b83cSArmin Le Grand 4615f27b83cSArmin Le Grand if(nSrcWidth && nSrcHeight) 4625f27b83cSArmin Le Grand { 4635f27b83cSArmin Le Grand const long nDestWidth(basegfx::fround(basegfx::B2DVector(rX - rNull).getLength())); 4645f27b83cSArmin Le Grand const long nDestHeight(basegfx::fround(basegfx::B2DVector(rY - rNull).getLength())); 4655f27b83cSArmin Le Grand 4665f27b83cSArmin Le Grand if(nDestWidth && nDestHeight) 4675f27b83cSArmin Le Grand { 4685f27b83cSArmin Le Grand Gdiplus::Graphics aGraphics(getHDC()); 4695f27b83cSArmin Le Grand Gdiplus::PointF aDestPoints[3]; 4705f27b83cSArmin Le Grand Gdiplus::ImageAttributes aAttributes; 4715f27b83cSArmin Le Grand 4725f27b83cSArmin Le Grand setInterpolationMode( 4735f27b83cSArmin Le Grand aGraphics, 4745f27b83cSArmin Le Grand nSrcWidth, 4755f27b83cSArmin Le Grand nDestWidth, 4765f27b83cSArmin Le Grand nSrcHeight, 4775f27b83cSArmin Le Grand nDestHeight); 4785f27b83cSArmin Le Grand 4795f27b83cSArmin Le Grand // this mode is only capable of drawing the whole bitmap to a paralellogram 4805f27b83cSArmin Le Grand aDestPoints[0].X = Gdiplus::REAL(rNull.getX()); 4815f27b83cSArmin Le Grand aDestPoints[0].Y = Gdiplus::REAL(rNull.getY()); 4825f27b83cSArmin Le Grand aDestPoints[1].X = Gdiplus::REAL(rX.getX()); 4835f27b83cSArmin Le Grand aDestPoints[1].Y = Gdiplus::REAL(rX.getY()); 4845f27b83cSArmin Le Grand aDestPoints[2].X = Gdiplus::REAL(rY.getX()); 4855f27b83cSArmin Le Grand aDestPoints[2].Y = Gdiplus::REAL(rY.getY()); 4865f27b83cSArmin Le Grand 4875f27b83cSArmin Le Grand aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY); 4885f27b83cSArmin Le Grand 4895f27b83cSArmin Le Grand aGraphics.DrawImage( 4905f27b83cSArmin Le Grand aARGB.get(), 4915f27b83cSArmin Le Grand aDestPoints, 4925f27b83cSArmin Le Grand 3, 4935f27b83cSArmin Le Grand Gdiplus::REAL(0.0), 4945f27b83cSArmin Le Grand Gdiplus::REAL(0.0), 4955f27b83cSArmin Le Grand Gdiplus::REAL(nSrcWidth), 4965f27b83cSArmin Le Grand Gdiplus::REAL(nSrcHeight), 4975f27b83cSArmin Le Grand Gdiplus::UnitPixel, 4985f27b83cSArmin Le Grand &aAttributes, 4995f27b83cSArmin Le Grand 0, 5005f27b83cSArmin Le Grand 0); 5015f27b83cSArmin Le Grand } 5025f27b83cSArmin Le Grand } 5035f27b83cSArmin Le Grand 5045f27b83cSArmin Le Grand return true; 5055f27b83cSArmin Le Grand } 5065f27b83cSArmin Le Grand 5075f27b83cSArmin Le Grand return false; 5085f27b83cSArmin Le Grand } 5095f27b83cSArmin Le Grand 5105f27b83cSArmin Le Grand // ----------------------------------------------------------------------- 5115f27b83cSArmin Le Grand // eof 512