summaryrefslogtreecommitdiff
path: root/vcl/win/source/gdi/salgdi_gdiplus.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/win/source/gdi/salgdi_gdiplus.cxx')
-rw-r--r--vcl/win/source/gdi/salgdi_gdiplus.cxx469
1 files changed, 7 insertions, 462 deletions
diff --git a/vcl/win/source/gdi/salgdi_gdiplus.cxx b/vcl/win/source/gdi/salgdi_gdiplus.cxx
index 1dc4f05a088a..65dbdd84acec 100644
--- a/vcl/win/source/gdi/salgdi_gdiplus.cxx
+++ b/vcl/win/source/gdi/salgdi_gdiplus.cxx
@@ -25,195 +25,11 @@
#include <win/salgdi.h>
#include <win/salbmp.h>
-#if defined _MSC_VER
-#ifndef min
-#define min(a,b) (((a) < (b)) ? (a) : (b))
-#endif
-#ifndef max
-#define max(a,b) (((a) > (b)) ? (a) : (b))
-#endif
-#endif
-
-#if defined _MSC_VER
-#pragma warning(push, 1)
-#endif
-
-#ifdef __MINGW32__
-#ifdef GetObject
-#undef GetObject
-#endif
-#define GetObject GetObjectA
-#endif
-
-#include <gdiplus.h>
-#include <gdiplusenums.h>
-#include <gdipluscolor.h>
-
-#ifdef __MINGW32__
-#ifdef GetObject
-#undef GetObject
-#endif
-#endif
-
-#if defined _MSC_VER
-#pragma warning(pop)
-#endif
-
-#include <basegfx/polygon/b2dpolygon.hxx>
-
-void impAddB2DPolygonToGDIPlusGraphicsPathReal(Gdiplus::GpPath *pPath, const basegfx::B2DPolygon& rPolygon, bool bNoLineJoin)
-{
- sal_uInt32 nCount(rPolygon.count());
-
- if(nCount)
- {
- const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1);
- const bool bControls(rPolygon.areControlPointsUsed());
- basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0));
-
- for(sal_uInt32 a(0); a < nEdgeCount; a++)
- {
- const sal_uInt32 nNextIndex((a + 1) % nCount);
- const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
-
- if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex)))
- {
- const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a));
- const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex));
-
- Gdiplus::DllExports::GdipAddPathBezier(pPath,
- aCurr.getX(), aCurr.getY(),
- aCa.getX(), aCa.getY(),
- aCb.getX(), aCb.getY(),
- aNext.getX(), aNext.getY());
- }
- else
- {
- Gdiplus::DllExports::GdipAddPathLine(pPath, aCurr.getX(), aCurr.getY(), aNext.getX(), aNext.getY());
- }
-
- if(a + 1 < nEdgeCount)
- {
- aCurr = aNext;
-
- if(bNoLineJoin)
- {
- Gdiplus::DllExports::GdipStartPathFigure(pPath);
- }
- }
- }
- }
-}
-
-void impAddB2DPolygonToGDIPlusGraphicsPathInteger(Gdiplus::GpPath *pPath, const basegfx::B2DPolygon& rPolygon, bool bNoLineJoin)
-{
- sal_uInt32 nCount(rPolygon.count());
-
- if(nCount)
- {
- const sal_uInt32 nEdgeCount(rPolygon.isClosed() ? nCount : nCount - 1);
- const bool bControls(rPolygon.areControlPointsUsed());
- basegfx::B2DPoint aCurr(rPolygon.getB2DPoint(0));
-
- for(sal_uInt32 a(0); a < nEdgeCount; a++)
- {
- const sal_uInt32 nNextIndex((a + 1) % nCount);
- const basegfx::B2DPoint aNext(rPolygon.getB2DPoint(nNextIndex));
-
- if(bControls && (rPolygon.isNextControlPointUsed(a) || rPolygon.isPrevControlPointUsed(nNextIndex)))
- {
- const basegfx::B2DPoint aCa(rPolygon.getNextControlPoint(a));
- const basegfx::B2DPoint aCb(rPolygon.getPrevControlPoint(nNextIndex));
-
- Gdiplus::DllExports::GdipAddPathBezier(
- pPath,
- aCurr.getX(), aCurr.getY(),
- aCa.getX(), aCa.getY(),
- aCb.getX(), aCb.getY(),
- aNext.getX(), aNext.getY());
- }
- else
- {
- Gdiplus::DllExports::GdipAddPathLine(pPath, aCurr.getX(), aCurr.getY(), aNext.getX(), aNext.getY());
- }
-
- if(a + 1 < nEdgeCount)
- {
- aCurr = aNext;
-
- if(bNoLineJoin)
- {
- Gdiplus::DllExports::GdipStartPathFigure(pPath);
- }
- }
- }
- }
-}
+#include "gdiimpl.hxx"
bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPolygon, double fTransparency)
{
- const sal_uInt32 nCount(rPolyPolygon.count());
-
- if(mbBrush && nCount && (fTransparency >= 0.0 && fTransparency < 1.0))
- {
- Gdiplus::GpGraphics *pGraphics = NULL;
- Gdiplus::DllExports::GdipCreateFromHDC(getHDC(), &pGraphics);
- const sal_uInt8 aTrans((sal_uInt8)255 - (sal_uInt8)basegfx::fround(fTransparency * 255.0));
- Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maFillColor), SALCOLOR_GREEN(maFillColor), SALCOLOR_BLUE(maFillColor));
- Gdiplus::GpSolidFill *pTestBrush;
- Gdiplus::DllExports::GdipCreateSolidFill(aTestColor.GetValue(), &pTestBrush);
- Gdiplus::GpPath *pPath = NULL;
- Gdiplus::DllExports::GdipCreatePath(Gdiplus::FillModeAlternate, &pPath);
-
- for(sal_uInt32 a(0); a < nCount; a++)
- {
- if(0 != a)
- {
- Gdiplus::DllExports::GdipStartPathFigure(pPath); // #i101491# not needed for first run
- }
-
- impAddB2DPolygonToGDIPlusGraphicsPathReal(pPath, rPolyPolygon.getB2DPolygon(a), false);
- Gdiplus::DllExports::GdipClosePathFigure(pPath);
- }
-
- if(getAntiAliasB2DDraw())
- {
- Gdiplus::DllExports::GdipSetSmoothingMode(pGraphics, Gdiplus::SmoothingModeAntiAlias);
- }
- else
- {
- Gdiplus::DllExports::GdipSetSmoothingMode(pGraphics, Gdiplus::SmoothingModeNone);
- }
-
- if(mbPrinter)
- {
- // #i121591#
- // Normally GdiPlus should not be used for printing at all since printers cannot
- // print transparent filled polygon geometry and normally this does not happen
- // since OutputDevice::RemoveTransparenciesFromMetaFile is used as preparation
- // and no transparent parts should remain for printing. But this can be overridden
- // by the user and thus happens. This call can only come (currently) from
- // OutputDevice::DrawTransparent, see comments there with the same TaskID.
- // If it is used, the mapping for the printer is wrong and needs to be corrected. I
- // checked that there is *no* transformation set and estimated that a stable factor
- // dependent of the printer's DPI is used. Create and set a transformation here to
- // correct this.
- Gdiplus::REAL aDpiX;
- Gdiplus::DllExports::GdipGetDpiX(pGraphics, &aDpiX);
- Gdiplus::REAL aDpiY;
- Gdiplus::DllExports::GdipGetDpiY(pGraphics, &aDpiY);
-
- Gdiplus::DllExports::GdipResetWorldTransform(pGraphics);
- Gdiplus::DllExports::GdipScaleWorldTransform(pGraphics, Gdiplus::REAL(100.0) / aDpiX, Gdiplus::REAL(100.0) / aDpiY, Gdiplus::MatrixOrderAppend);
- }
-
- Gdiplus::DllExports::GdipFillPath(pGraphics, pTestBrush, pPath);
-
- Gdiplus::DllExports::GdipDeletePath(pPath);
- Gdiplus::DllExports::GdipDeleteGraphics(pGraphics);
- }
-
- return true;
+ return mpImpl->drawPolyPolygon( rPolyPolygon, fTransparency );
}
bool WinSalGraphics::drawPolyLine(
@@ -223,199 +39,8 @@ bool WinSalGraphics::drawPolyLine(
basegfx::B2DLineJoin eLineJoin,
com::sun::star::drawing::LineCap eLineCap)
{
- const sal_uInt32 nCount(rPolygon.count());
-
- if(mbPen && nCount)
- {
- Gdiplus::GpGraphics *pGraphics = NULL;
- Gdiplus::DllExports::GdipCreateFromHDC(getHDC(), &pGraphics);
- const sal_uInt8 aTrans = (sal_uInt8)basegfx::fround( 255 * (1.0 - fTransparency) );
- Gdiplus::Color aTestColor(aTrans, SALCOLOR_RED(maLineColor), SALCOLOR_GREEN(maLineColor), SALCOLOR_BLUE(maLineColor));
- Gdiplus::GpPen *pTestPen = NULL;
- Gdiplus::DllExports::GdipCreatePen1(aTestColor.GetValue(), Gdiplus::REAL(rLineWidths.getX()), Gdiplus::UnitWorld, &pTestPen);
- Gdiplus::GpPath *pPath;
- Gdiplus::DllExports::GdipCreatePath(Gdiplus::FillModeAlternate, &pPath);
- bool bNoLineJoin(false);
-
- switch(eLineJoin)
- {
- default : // basegfx::B2DLINEJOIN_NONE :
- {
- if(basegfx::fTools::more(rLineWidths.getX(), 0.0))
- {
- bNoLineJoin = true;
- }
- break;
- }
- case basegfx::B2DLINEJOIN_BEVEL :
- {
- Gdiplus::DllExports::GdipSetPenLineJoin(pTestPen, Gdiplus::LineJoinBevel);
- break;
- }
- case basegfx::B2DLINEJOIN_MIDDLE :
- case basegfx::B2DLINEJOIN_MITER :
- {
- const Gdiplus::REAL aMiterLimit(15.0);
- Gdiplus::DllExports::GdipSetPenMiterLimit(pTestPen, aMiterLimit);
- Gdiplus::DllExports::GdipSetPenLineJoin(pTestPen, Gdiplus::LineJoinMiter);
- break;
- }
- case basegfx::B2DLINEJOIN_ROUND :
- {
- Gdiplus::DllExports::GdipSetPenLineJoin(pTestPen, Gdiplus::LineJoinRound);
- break;
- }
- }
-
- switch(eLineCap)
- {
- default: /*com::sun::star::drawing::LineCap_BUTT*/
- {
- // nothing to do
- break;
- }
- case com::sun::star::drawing::LineCap_ROUND:
- {
- Gdiplus::DllExports::GdipSetPenStartCap(pTestPen, Gdiplus::LineCapRound);
- Gdiplus::DllExports::GdipSetPenEndCap(pTestPen, Gdiplus::LineCapRound);
- break;
- }
- case com::sun::star::drawing::LineCap_SQUARE:
- {
- Gdiplus::DllExports::GdipSetPenStartCap(pTestPen, Gdiplus::LineCapSquare);
- Gdiplus::DllExports::GdipSetPenEndCap(pTestPen, Gdiplus::LineCapSquare);
- break;
- }
- }
-
- if(nCount > 250 && basegfx::fTools::more(rLineWidths.getX(), 1.5))
- {
- impAddB2DPolygonToGDIPlusGraphicsPathInteger(pPath, rPolygon, bNoLineJoin);
- }
- else
- {
- impAddB2DPolygonToGDIPlusGraphicsPathReal(pPath, rPolygon, bNoLineJoin);
- }
-
- if(rPolygon.isClosed() && !bNoLineJoin)
- {
- // #i101491# needed to create the correct line joins
- Gdiplus::DllExports::GdipClosePathFigure(pPath);
- }
-
- if(getAntiAliasB2DDraw())
- {
- Gdiplus::DllExports::GdipSetSmoothingMode(pGraphics, Gdiplus::SmoothingModeAntiAlias);
- }
- else
- {
- Gdiplus::DllExports::GdipSetSmoothingMode(pGraphics, Gdiplus::SmoothingModeNone);
- }
-
- Gdiplus::DllExports::GdipDrawPath(pGraphics, pTestPen, pPath);
-
- Gdiplus::DllExports::GdipDeletePath(pPath);
- Gdiplus::DllExports::GdipDeletePen(pTestPen);
- Gdiplus::DllExports::GdipDeleteGraphics(pGraphics);
- }
-
- return true;
-}
-
-void paintToGdiPlus(
- Gdiplus::Graphics& rGraphics,
- const SalTwoRect& rTR,
- Gdiplus::Bitmap& rBitmap)
-{
- // only parts of source are used
- Gdiplus::PointF aDestPoints[3];
- Gdiplus::ImageAttributes aAttributes;
-
- // define target region as paralellogram
- aDestPoints[0].X = Gdiplus::REAL(rTR.mnDestX);
- aDestPoints[0].Y = Gdiplus::REAL(rTR.mnDestY);
- aDestPoints[1].X = Gdiplus::REAL(rTR.mnDestX + rTR.mnDestWidth);
- aDestPoints[1].Y = Gdiplus::REAL(rTR.mnDestY);
- aDestPoints[2].X = Gdiplus::REAL(rTR.mnDestX);
- aDestPoints[2].Y = Gdiplus::REAL(rTR.mnDestY + rTR.mnDestHeight);
-
- aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY);
-
- rGraphics.DrawImage(
- &rBitmap,
- aDestPoints,
- 3,
- Gdiplus::REAL(rTR.mnSrcX),
- Gdiplus::REAL(rTR.mnSrcY),
- Gdiplus::REAL(rTR.mnSrcWidth),
- Gdiplus::REAL(rTR.mnSrcHeight),
- Gdiplus::UnitPixel,
- &aAttributes,
- 0,
- 0);
-}
-
-void setInterpolationMode(
- Gdiplus::Graphics& rGraphics,
- const long& rSrcWidth,
- const long& rDestWidth,
- const long& rSrcHeight,
- const long& rDestHeight)
-{
- const bool bSameWidth(rSrcWidth == rDestWidth);
- const bool bSameHeight(rSrcHeight == rDestHeight);
-
- if(bSameWidth && bSameHeight)
- {
-#ifdef __MINGW32__
- //Gdiplus::InterpolationModeInvalid is missing on mingw
- rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault);
-#else
- rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeInvalid);
-#endif
- }
- else if(rDestWidth > rSrcWidth && rDestHeight > rSrcHeight)
- {
- rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault);
- }
- else if(rDestWidth < rSrcWidth && rDestHeight < rSrcHeight)
- {
- rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeBicubic);
- }
- else
- {
- rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeDefault);
- }
-}
-
-bool WinSalGraphics::tryDrawBitmapGdiPlus(const SalTwoRect& rTR, const SalBitmap& rSrcBitmap)
-{
- if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight)
- {
- const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap);
- GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap());
-
- if(aARGB.get())
- {
- Gdiplus::Graphics aGraphics(getHDC());
-
- setInterpolationMode(
- aGraphics,
- rTR.mnSrcWidth,
- rTR.mnDestWidth,
- rTR.mnSrcHeight,
- rTR.mnDestHeight);
-
- paintToGdiPlus(
- aGraphics,
- rTR,
- *aARGB.get());
-
- return true;
- }
- }
-
- return false;
+ return mpImpl->drawPolyLine(rPolygon, fTransparency, rLineWidths,
+ eLineJoin, eLineCap);
}
bool WinSalGraphics::drawAlphaBitmap(
@@ -423,33 +48,7 @@ bool WinSalGraphics::drawAlphaBitmap(
const SalBitmap& rSrcBitmap,
const SalBitmap& rAlphaBmp)
{
- if(rTR.mnSrcWidth && rTR.mnSrcHeight && rTR.mnDestWidth && rTR.mnDestHeight)
- {
- const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSrcBitmap);
- const WinSalBitmap& rSalAlpha = static_cast< const WinSalBitmap& >(rAlphaBmp);
- GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap(&rSalAlpha));
-
- if(aARGB.get())
- {
- Gdiplus::Graphics aGraphics(getHDC());
-
- setInterpolationMode(
- aGraphics,
- rTR.mnSrcWidth,
- rTR.mnDestWidth,
- rTR.mnSrcHeight,
- rTR.mnDestHeight);
-
- paintToGdiPlus(
- aGraphics,
- rTR,
- *aARGB.get());
-
- return true;
- }
- }
-
- return false;
+ return mpImpl->drawAlphaBitmap(rTR, rSrcBitmap, rAlphaBmp);
}
bool WinSalGraphics::drawTransformedBitmap(
@@ -459,62 +58,8 @@ bool WinSalGraphics::drawTransformedBitmap(
const SalBitmap& rSourceBitmap,
const SalBitmap* pAlphaBitmap)
{
- const WinSalBitmap& rSalBitmap = static_cast< const WinSalBitmap& >(rSourceBitmap);
- const WinSalBitmap* pSalAlpha = static_cast< const WinSalBitmap* >(pAlphaBitmap);
- GdiPlusBmpPtr aARGB(rSalBitmap.ImplGetGdiPlusBitmap(pSalAlpha));
-
- if(aARGB.get())
- {
- const long nSrcWidth(aARGB->GetWidth());
- const long nSrcHeight(aARGB->GetHeight());
-
- if(nSrcWidth && nSrcHeight)
- {
- const long nDestWidth(basegfx::fround(basegfx::B2DVector(rX - rNull).getLength()));
- const long nDestHeight(basegfx::fround(basegfx::B2DVector(rY - rNull).getLength()));
-
- if(nDestWidth && nDestHeight)
- {
- Gdiplus::Graphics aGraphics(getHDC());
- Gdiplus::PointF aDestPoints[3];
- Gdiplus::ImageAttributes aAttributes;
-
- setInterpolationMode(
- aGraphics,
- nSrcWidth,
- nDestWidth,
- nSrcHeight,
- nDestHeight);
-
- // this mode is only capable of drawing the whole bitmap to a paralellogram
- aDestPoints[0].X = Gdiplus::REAL(rNull.getX());
- aDestPoints[0].Y = Gdiplus::REAL(rNull.getY());
- aDestPoints[1].X = Gdiplus::REAL(rX.getX());
- aDestPoints[1].Y = Gdiplus::REAL(rX.getY());
- aDestPoints[2].X = Gdiplus::REAL(rY.getX());
- aDestPoints[2].Y = Gdiplus::REAL(rY.getY());
-
- aAttributes.SetWrapMode(Gdiplus::WrapModeTileFlipXY);
-
- aGraphics.DrawImage(
- aARGB.get(),
- aDestPoints,
- 3,
- Gdiplus::REAL(0.0),
- Gdiplus::REAL(0.0),
- Gdiplus::REAL(nSrcWidth),
- Gdiplus::REAL(nSrcHeight),
- Gdiplus::UnitPixel,
- &aAttributes,
- 0,
- 0);
- }
- }
-
- return true;
- }
-
- return false;
+ return mpImpl->drawTransformedBitmap(rNull, rX, rY,
+ rSourceBitmap, pAlphaBitmap);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */