diff options
author | Armin Le Grand <alg@apache.org> | 2013-01-23 13:27:50 +0000 |
---|---|---|
committer | Armin Le Grand <alg@apache.org> | 2013-01-23 13:27:50 +0000 |
commit | b2cc0de3fc9adee90787ca760e86869f9255b380 (patch) | |
tree | 18b91dc019fdc7cfe2c612d9c02d95c9d037e367 | |
parent | aa85e31b3162cd4b18c818bf0af1a854cb05c57d (diff) |
#121534# Reintegrating changes for rotated bitmap support
Notes
Notes:
merged as: 9bb96049addebd8907854730713d8a3f5f033e34
52 files changed, 2145 insertions, 1397 deletions
diff --git a/canvas/source/vcl/bitmapbackbuffer.cxx b/canvas/source/vcl/bitmapbackbuffer.cxx index 0208550563dc..a8055db4587b 100644 --- a/canvas/source/vcl/bitmapbackbuffer.cxx +++ b/canvas/source/vcl/bitmapbackbuffer.cxx @@ -85,6 +85,7 @@ namespace vclcanvas { // VDev content is more current than bitmap - copy contents before! mpVDev->EnableMapMode( sal_False ); + mpVDev->SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); const Point aEmptyPoint; *maBitmap = mpVDev->GetBitmapEx( aEmptyPoint, mpVDev->GetOutputSizePixel() ); @@ -105,6 +106,7 @@ namespace vclcanvas if( mbVDevContentIsCurrent && mpVDev ) { mpVDev->EnableMapMode( sal_False ); + mpVDev->SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); aSize = mpVDev->GetOutputSizePixel(); } @@ -148,6 +150,7 @@ namespace vclcanvas { // fill with bitmap content mpVDev->EnableMapMode( sal_False ); + mpVDev->SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); const Point aEmptyPoint; mpVDev->DrawBitmapEx( aEmptyPoint, *maBitmap ); } diff --git a/canvas/source/vcl/canvashelper.cxx b/canvas/source/vcl/canvashelper.cxx index 461d981d22f7..11bd95df80a7 100644 --- a/canvas/source/vcl/canvashelper.cxx +++ b/canvas/source/vcl/canvashelper.cxx @@ -162,6 +162,7 @@ namespace vclcanvas { mp2ndOutDev = rOutDev; mp2ndOutDev->getOutDev().EnableMapMode( sal_False ); + mp2ndOutDev->getOutDev().SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); } void CanvasHelper::clear() @@ -173,6 +174,7 @@ namespace vclcanvas tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); rOutDev.EnableMapMode( sal_False ); + rOutDev.SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); rOutDev.SetLineColor( COL_WHITE ); rOutDev.SetFillColor( COL_WHITE ); rOutDev.DrawRect( Rectangle( Point(), @@ -184,6 +186,7 @@ namespace vclcanvas rOutDev2.SetDrawMode( DRAWMODE_DEFAULT ); rOutDev2.EnableMapMode( sal_False ); + rOutDev2.SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); rOutDev2.SetLineColor( COL_WHITE ); rOutDev2.SetFillColor( COL_WHITE ); rOutDev2.DrawRect( Rectangle( Point(), @@ -934,6 +937,7 @@ namespace vclcanvas tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); rOutDev.EnableMapMode( sal_False ); + rOutDev.SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); // TODO(F2): Support alpha vdev canvas here const Point aEmptyPoint(0,0); @@ -963,6 +967,7 @@ namespace vclcanvas tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); rOutDev.EnableMapMode( sal_False ); + rOutDev.SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); Bitmap aBitmap( rOutDev.GetBitmap(aRect.TopLeft(), aRect.GetSize()) ); @@ -1016,6 +1021,7 @@ namespace vclcanvas tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); rOutDev.EnableMapMode( sal_False ); + rOutDev.SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); const Rectangle aRect( ::vcl::unotools::rectangleFromIntegerRectangle2D(rect) ); const sal_uInt16 nBitCount( ::std::min( (sal_uInt16)24U, @@ -1142,6 +1148,7 @@ namespace vclcanvas tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); rOutDev.EnableMapMode( sal_False ); + rOutDev.SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); const Size aBmpSize( rOutDev.GetOutputSizePixel() ); @@ -1179,6 +1186,7 @@ namespace vclcanvas tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); rOutDev.EnableMapMode( sal_False ); + rOutDev.SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); const Size aBmpSize( rOutDev.GetOutputSizePixel() ); @@ -1218,6 +1226,7 @@ namespace vclcanvas OutputDevice* p2ndOutDev = NULL; rOutDev.EnableMapMode( sal_False ); + rOutDev.SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); if( mp2ndOutDev ) p2ndOutDev = &mp2ndOutDev->getOutDev(); diff --git a/canvas/source/vcl/impltools.hxx b/canvas/source/vcl/impltools.hxx index b5addece52f9..6863f9e99cbe 100644 --- a/canvas/source/vcl/impltools.hxx +++ b/canvas/source/vcl/impltools.hxx @@ -137,14 +137,16 @@ namespace vclcanvas public: explicit OutDevStateKeeper( OutputDevice& rOutDev ) : mpOutDev( &rOutDev ), - mbMappingWasEnabled( mpOutDev->IsMapModeEnabled() ) + mbMappingWasEnabled( mpOutDev->IsMapModeEnabled() ), + mnAntiAliasing( mpOutDev->GetAntialiasing() ) { init(); } explicit OutDevStateKeeper( const OutDevProviderSharedPtr& rOutDev ) : mpOutDev( rOutDev.get() ? &(rOutDev->getOutDev()) : NULL ), - mbMappingWasEnabled( mpOutDev ? mpOutDev->IsMapModeEnabled() : false ) + mbMappingWasEnabled( mpOutDev ? mpOutDev->IsMapModeEnabled() : false ), + mnAntiAliasing( mpOutDev ? mpOutDev->GetAntialiasing() : 0 ) { init(); } @@ -154,6 +156,8 @@ namespace vclcanvas if( mpOutDev ) { mpOutDev->EnableMapMode( mbMappingWasEnabled ); + mpOutDev->SetAntialiasing( mnAntiAliasing ); + mpOutDev->Pop(); } } @@ -165,11 +169,13 @@ namespace vclcanvas { mpOutDev->Push(); mpOutDev->EnableMapMode(sal_False); + mpOutDev->SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); } } - OutputDevice* mpOutDev; - const bool mbMappingWasEnabled; + OutputDevice* mpOutDev; + const bool mbMappingWasEnabled; + const sal_uInt16 mnAntiAliasing; }; ::Point mapRealPoint2D( const ::com::sun::star::geometry::RealPoint2D& rPoint, diff --git a/canvas/source/vcl/spritecanvashelper.cxx b/canvas/source/vcl/spritecanvashelper.cxx index 11341c616a2d..6832e9043459 100644 --- a/canvas/source/vcl/spritecanvashelper.cxx +++ b/canvas/source/vcl/spritecanvashelper.cxx @@ -95,6 +95,7 @@ namespace vclcanvas // wouldn't save much render time, and b) will clutter // scrolled sprite content outside this area) rOutDev.EnableMapMode( sal_False ); + rOutDev.SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); rOutDev.SetClipRegion( rRequestedArea ); // repaint affected sprite directly to output device (at @@ -329,6 +330,7 @@ namespace vclcanvas // flush to screen rOutDev.EnableMapMode( sal_False ); + rOutDev.SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); rOutDev.SetClipRegion(); rOutDev.DrawOutDev( aEmptyPoint, aOutDevSize, aEmptyPoint, aOutDevSize, @@ -574,6 +576,7 @@ namespace vclcanvas // paint background maVDev->EnableMapMode( sal_False ); + maVDev->SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); maVDev->SetClipRegion(); maVDev->DrawOutDev( aEmptyPoint, aOutputSize, aOutputPosition, aOutputSize, @@ -591,6 +594,7 @@ namespace vclcanvas // flush to screen rOutDev.EnableMapMode( sal_False ); + rOutDev.SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); rOutDev.DrawOutDev( aOutputPosition, aOutputSize, aEmptyPoint, aOutputSize, *maVDev ); diff --git a/canvas/source/vcl/spritedevicehelper.cxx b/canvas/source/vcl/spritedevicehelper.cxx index 1281db30c280..c1dac715bd15 100644 --- a/canvas/source/vcl/spritedevicehelper.cxx +++ b/canvas/source/vcl/spritedevicehelper.cxx @@ -141,6 +141,7 @@ namespace vclcanvas const ::Point aEmptyPoint; mpBackBuffer->getOutDev().EnableMapMode( sal_False ); + mpBackBuffer->getOutDev().SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW ); WriteDIB(mpBackBuffer->getOutDev().GetBitmap(aEmptyPoint, mpBackBuffer->getOutDev().GetOutputSizePixel()), aStream, false, true); } diff --git a/drawinglayer/Library_drawinglayer.mk b/drawinglayer/Library_drawinglayer.mk index 5e93468d5d26..699fd8dd09f4 100644 --- a/drawinglayer/Library_drawinglayer.mk +++ b/drawinglayer/Library_drawinglayer.mk @@ -156,8 +156,6 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\ drawinglayer/source/primitive3d/textureprimitive3d \ drawinglayer/source/primitive3d/transformprimitive3d \ drawinglayer/source/processor2d/baseprocessor2d \ - drawinglayer/source/processor2d/vclhelperbitmaptransform \ - drawinglayer/source/processor2d/vclhelperbitmaprender \ drawinglayer/source/processor2d/vclhelperbufferdevice \ drawinglayer/source/processor2d/vclprocessor2d \ drawinglayer/source/processor2d/helperwrongspellrenderer \ diff --git a/drawinglayer/source/processor2d/vclhelperbitmaprender.cxx b/drawinglayer/source/processor2d/vclhelperbitmaprender.cxx deleted file mode 100644 index c978f414fb29..000000000000 --- a/drawinglayer/source/processor2d/vclhelperbitmaprender.cxx +++ /dev/null @@ -1,229 +0,0 @@ -/************************************************************** - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - *************************************************************/ - - - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_drawinglayer.hxx" - -#include <vclhelperbitmaprender.hxx> -#include <basegfx/vector/b2dvector.hxx> -#include <basegfx/matrix/b2dhommatrix.hxx> -#include <basegfx/range/b2drange.hxx> -#include <vcl/outdev.hxx> -#include <vclhelperbitmaptransform.hxx> -#include <basegfx/matrix/b2dhommatrixtools.hxx> -#include <vcl/gdimtf.hxx> - -////////////////////////////////////////////////////////////////////////////// -// support for different kinds of bitmap rendering using vcl - -namespace drawinglayer -{ - void RenderBitmapPrimitive2D_BitmapEx( - OutputDevice& rOutDev, - const BitmapEx& rBitmapEx, - const basegfx::B2DHomMatrix& rTransform) - { - // only translate and scale, use vcl's DrawBitmapEx(). - BitmapEx aContent(rBitmapEx); - - // prepare dest coor. Necessary to expand since vcl's DrawBitmapEx draws one pix less - basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0); - aOutlineRange.transform(rTransform); - // prepare dest coordinates - const Point aPoint( - basegfx::fround(aOutlineRange.getMinX()), - basegfx::fround(aOutlineRange.getMinY())); - const Size aSize( - basegfx::fround(aOutlineRange.getWidth()), - basegfx::fround(aOutlineRange.getHeight())); - - // decompose matrix to check for shear, rotate and mirroring - basegfx::B2DVector aScale, aTranslate; - double fRotate, fShearX; - rTransform.decompose(aScale, aTranslate, fRotate, fShearX); - - // Check mirroring. - sal_uInt32 nMirrorFlags(BMP_MIRROR_NONE); - - if(basegfx::fTools::less(aScale.getX(), 0.0)) - { - nMirrorFlags |= BMP_MIRROR_HORZ; - } - - if(basegfx::fTools::less(aScale.getY(), 0.0)) - { - nMirrorFlags |= BMP_MIRROR_VERT; - } - - if(BMP_MIRROR_NONE != nMirrorFlags) - { - aContent.Mirror(nMirrorFlags); - } - - // draw bitmap - if(aSize == aContent.GetSizePixel()) - { - rOutDev.DrawBitmapEx(aPoint, aContent); - } - else - { - rOutDev.DrawBitmapEx(aPoint, aSize, aContent); - } - } - - void RenderBitmapPrimitive2D_self( - OutputDevice& rOutDev, - const BitmapEx& rBitmapEx, - const basegfx::B2DHomMatrix& rTransform) - { - // process self with free transformation (containing shear and rotate). Get dest rect in pixels. - basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0); - aOutlineRange.transform(rTransform); - const Rectangle aDestRectLogic( - basegfx::fround(aOutlineRange.getMinX()), - basegfx::fround(aOutlineRange.getMinY()), - basegfx::fround(aOutlineRange.getMaxX()), - basegfx::fround(aOutlineRange.getMaxY())); - const Rectangle aDestRectPixel(rOutDev.LogicToPixel(aDestRectLogic)); - - // #i96708# check if Metafile is recorded - const GDIMetaFile* pMetaFile = rOutDev.GetConnectMetaFile(); - const bool bRecordToMetaFile(pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause()); - - // intersect with output pixel size, but only - // when not recording to metafile - const Rectangle aOutputRectPixel(Point(), rOutDev.GetOutputSizePixel()); - Rectangle aCroppedRectPixel(bRecordToMetaFile ? aDestRectPixel : aDestRectPixel.GetIntersection(aOutputRectPixel)); - - if(!aCroppedRectPixel.IsEmpty()) - { - // as maximum for destination, orientate at aOutputRectPixel, but - // take a rotation of 45 degrees (sqrt(2)) as maximum expansion into account - const Size aSourceSizePixel(rBitmapEx.GetSizePixel()); - const double fMaximumArea( - - // #121153# With Metafile, aOutputRectPixel may be empty and a virtual - // maximum quadratic size has to be used - bRecordToMetaFile ? 500000.0 : - - (double)aOutputRectPixel.getWidth() * - (double)aOutputRectPixel.getHeight() * - 1.4142136); // 1.4142136 taken as sqrt(2.0) - - // test if discrete view size (pixel) maybe too big and limit it - const double fArea(aCroppedRectPixel.getWidth() * aCroppedRectPixel.getHeight()); - const bool bNeedToReduce(fArea > fMaximumArea); - double fReduceFactor(1.0); - const Size aDestSizePixel(aCroppedRectPixel.GetSize()); - - if(bNeedToReduce) - { - fReduceFactor = sqrt(fMaximumArea / fArea); - aCroppedRectPixel.setWidth(basegfx::fround(aCroppedRectPixel.getWidth() * fReduceFactor)); - aCroppedRectPixel.setHeight(basegfx::fround(aCroppedRectPixel.getHeight() * fReduceFactor)); - } - - // build transform from pixel in aDestination to pixel in rBitmapEx - // from relative in aCroppedRectPixel to relative in aDestRectPixel - // No need to take bNeedToReduce into account, TopLeft is unchanged - basegfx::B2DHomMatrix aTransform(basegfx::tools::createTranslateB2DHomMatrix( - aCroppedRectPixel.Left() - aDestRectPixel.Left(), - aCroppedRectPixel.Top() - aDestRectPixel.Top())); - - // from relative in aDestRectPixel to absolute Logic. Here it - // is essential to adapt to reduce factor (if used) - double fAdaptedDRPWidth((double)aDestRectPixel.getWidth()); - double fAdaptedDRPHeight((double)aDestRectPixel.getHeight()); - - if(bNeedToReduce) - { - fAdaptedDRPWidth *= fReduceFactor; - fAdaptedDRPHeight *= fReduceFactor; - } - - aTransform = basegfx::tools::createScaleTranslateB2DHomMatrix( - aDestRectLogic.getWidth() / fAdaptedDRPWidth, aDestRectLogic.getHeight() / fAdaptedDRPHeight, - aDestRectLogic.Left(), aDestRectLogic.Top()) - * aTransform; - - // from absolute in Logic to unified object coordinates (0.0 .. 1.0 in x and y) - basegfx::B2DHomMatrix aInvBitmapTransform(rTransform); - aInvBitmapTransform.invert(); - aTransform = aInvBitmapTransform * aTransform; - - // from unit object coordinates to rBitmapEx pixel coordintes - aTransform.scale(aSourceSizePixel.getWidth() - 1L, aSourceSizePixel.getHeight() - 1L); - - // create bitmap using source, destination and linear back-transformation - BitmapEx aDestination = impTransformBitmapEx(rBitmapEx, aCroppedRectPixel, aTransform); - - // paint - if(bNeedToReduce) - { - // paint in target size - if(bRecordToMetaFile) - { - rOutDev.DrawBitmapEx( - rOutDev.PixelToLogic(aCroppedRectPixel.TopLeft()), - rOutDev.PixelToLogic(aDestSizePixel), - aDestination); - } - else - { - const bool bWasEnabled(rOutDev.IsMapModeEnabled()); - rOutDev.EnableMapMode(false); - - rOutDev.DrawBitmapEx( - aCroppedRectPixel.TopLeft(), - aDestSizePixel, - aDestination); - - rOutDev.EnableMapMode(bWasEnabled); - } - } - else - { - if(bRecordToMetaFile) - { - rOutDev.DrawBitmapEx( - rOutDev.PixelToLogic(aCroppedRectPixel.TopLeft()), - aDestination); - } - else - { - const bool bWasEnabled(rOutDev.IsMapModeEnabled()); - rOutDev.EnableMapMode(false); - - rOutDev.DrawBitmapEx( - aCroppedRectPixel.TopLeft(), - aDestination); - - rOutDev.EnableMapMode(bWasEnabled); - } - } - } - } -} // end of namespace drawinglayer - -////////////////////////////////////////////////////////////////////////////// -// eof diff --git a/drawinglayer/source/processor2d/vclhelperbitmaprender.hxx b/drawinglayer/source/processor2d/vclhelperbitmaprender.hxx deleted file mode 100644 index 85b248ae7608..000000000000 --- a/drawinglayer/source/processor2d/vclhelperbitmaprender.hxx +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************** - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - *************************************************************/ - - - -#ifndef INCLUDED_DRAWINGLAYER_PROCESSOR2D_VCLHELPERBITMAPRENDER_HXX -#define INCLUDED_DRAWINGLAYER_PROCESSOR2D_VCLHELPERBITMAPRENDER_HXX - -#include <sal/types.h> - -////////////////////////////////////////////////////////////////////////////// -// predefines - -class OutputDevice; -class BitmapEx; -namespace basegfx { class B2DHomMatrix; } - -////////////////////////////////////////////////////////////////////////////// -// support methods for vcl direct gradient renderering - -namespace drawinglayer -{ - void RenderBitmapPrimitive2D_BitmapEx( - OutputDevice& rOutDev, - const BitmapEx& rBitmapEx, - const basegfx::B2DHomMatrix& rTransform); - - void RenderBitmapPrimitive2D_self( - OutputDevice& rOutDev, - const BitmapEx& rBitmapEx, - const basegfx::B2DHomMatrix& rTransform); - -} // end of namespace drawinglayer - -////////////////////////////////////////////////////////////////////////////// - -#endif // INCLUDED_DRAWINGLAYER_PROCESSOR2D_VCLHELPERBITMAPRENDER_HXX - -// eof diff --git a/drawinglayer/source/processor2d/vclhelperbitmaptransform.cxx b/drawinglayer/source/processor2d/vclhelperbitmaptransform.cxx deleted file mode 100644 index fb8407ee578e..000000000000 --- a/drawinglayer/source/processor2d/vclhelperbitmaptransform.cxx +++ /dev/null @@ -1,336 +0,0 @@ -/************************************************************** - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - *************************************************************/ - - - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_drawinglayer.hxx" - -#include <vclhelperbitmaptransform.hxx> -#include <vcl/bmpacc.hxx> -#include <basegfx/point/b2dpoint.hxx> -#include <basegfx/color/bcolormodifier.hxx> - -////////////////////////////////////////////////////////////////////////////// -// support for rendering Bitmap and BitmapEx contents - -namespace drawinglayer -{ - namespace - { - void impSmoothPoint(BitmapColor& rValue, const basegfx::B2DPoint& rSource, sal_Int32 nIntX, sal_Int32 nIntY, BitmapReadAccess& rRead) - { - double fDeltaX(rSource.getX() - nIntX); - double fDeltaY(rSource.getY() - nIntY); - sal_Int32 nIndX(0L); - sal_Int32 nIndY(0L); - - if(fDeltaX > 0.0 && nIntX + 1L < rRead.Width()) - { - nIndX++; - } - else if(fDeltaX < 0.0 && nIntX >= 1L) - { - fDeltaX = -fDeltaX; - nIndX--; - } - - if(fDeltaY > 0.0 && nIntY + 1L < rRead.Height()) - { - nIndY++; - } - else if(fDeltaY < 0.0 && nIntY >= 1L) - { - fDeltaY = -fDeltaY; - nIndY--; - } - - if(nIndX || nIndY) - { - const double fColorToReal(1.0 / 255.0); - double fR(rValue.GetRed() * fColorToReal); - double fG(rValue.GetGreen() * fColorToReal); - double fB(rValue.GetBlue() * fColorToReal); - double fRBottom(0.0), fGBottom(0.0), fBBottom(0.0); - - if(nIndX) - { - const double fMulA(fDeltaX * fColorToReal); - double fMulB(1.0 - fDeltaX); - const BitmapColor aTopPartner(rRead.GetColor(nIntY, nIntX + nIndX)); - - fR = (fR * fMulB) + (aTopPartner.GetRed() * fMulA); - fG = (fG * fMulB) + (aTopPartner.GetGreen() * fMulA); - fB = (fB * fMulB) + (aTopPartner.GetBlue() * fMulA); - - if(nIndY) - { - fMulB *= fColorToReal; - const BitmapColor aBottom(rRead.GetColor(nIntY + nIndY, nIntX)); - const BitmapColor aBottomPartner(rRead.GetColor(nIntY + nIndY, nIntX + nIndX)); - - fRBottom = (aBottom.GetRed() * fMulB) + (aBottomPartner.GetRed() * fMulA); - fGBottom = (aBottom.GetGreen() * fMulB) + (aBottomPartner.GetGreen() * fMulA); - fBBottom = (aBottom.GetBlue() * fMulB) + (aBottomPartner.GetBlue() * fMulA); - } - } - - if(nIndY) - { - if(!nIndX) - { - const BitmapColor aBottom(rRead.GetColor(nIntY + nIndY, nIntX)); - - fRBottom = aBottom.GetRed() * fColorToReal; - fGBottom = aBottom.GetGreen() * fColorToReal; - fBBottom = aBottom.GetBlue() * fColorToReal; - } - - const double fMulB(1.0 - fDeltaY); - - fR = (fR * fMulB) + (fRBottom * fDeltaY); - fG = (fG * fMulB) + (fGBottom * fDeltaY); - fB = (fB * fMulB) + (fBBottom * fDeltaY); - } - - rValue.SetRed((sal_uInt8)(fR * 255.0)); - rValue.SetGreen((sal_uInt8)(fG * 255.0)); - rValue.SetBlue((sal_uInt8)(fB * 255.0)); - } - } - - Bitmap impTransformBitmap( - const Bitmap& rSource, - const Size aDestinationSize, - const basegfx::B2DHomMatrix& rTransform, - bool bSmooth) - { - Bitmap aDestination(aDestinationSize, 24); - BitmapWriteAccess* pWrite = aDestination.AcquireWriteAccess(); - - if(pWrite) - { - const Size aContentSizePixel(rSource.GetSizePixel()); - BitmapReadAccess* pRead = (const_cast< Bitmap& >(rSource)).AcquireReadAccess(); - - if(pRead) - { - const Size aDestinationSizePixel(aDestination.GetSizePixel()); - bool bWorkWithIndex(rSource.GetBitCount() <= 8); - BitmapColor aOutside(BitmapColor(0xff, 0xff, 0xff)); - - for(sal_Int32 y(0L); y < aDestinationSizePixel.getHeight(); y++) - { - for(sal_Int32 x(0L); x < aDestinationSizePixel.getWidth(); x++) - { - const basegfx::B2DPoint aSourceCoor(rTransform * basegfx::B2DPoint(x, y)); - const sal_Int32 nIntX(basegfx::fround(aSourceCoor.getX())); - - if(nIntX >= 0L && nIntX < aContentSizePixel.getWidth()) - { - const sal_Int32 nIntY(basegfx::fround(aSourceCoor.getY())); - - if(nIntY >= 0L && nIntY < aContentSizePixel.getHeight()) - { - // inside pixel - BitmapColor aValue; - - if(bWorkWithIndex) - { - aValue = pRead->GetPaletteColor(pRead->GetPixelIndex(nIntY, nIntX)); - } - else - { - aValue = pRead->GetPixel(nIntY, nIntX); - } - - if(bSmooth) - { - impSmoothPoint(aValue, aSourceCoor, nIntX, nIntY, *pRead); - } - - pWrite->SetPixel(y, x, aValue); - continue; - } - } - - // here are outside pixels. Complete mask - if(bWorkWithIndex) - { - pWrite->SetPixel(y, x, aOutside); - } - } - } - - delete pRead; - } - - delete pWrite; - } - - rSource.AdaptBitCount(aDestination); - - return aDestination; - } - } // end of anonymous namespace -} // end of namespace drawinglayer - -namespace drawinglayer -{ - BitmapEx impTransformBitmapEx( - const BitmapEx& rSource, - const Rectangle& rCroppedRectPixel, - const basegfx::B2DHomMatrix& rTransform) - { - // force destination to 24 bit, we want to smooth output - const Size aDestinationSize(rCroppedRectPixel.GetSize()); - static bool bDoSmoothAtAll(true); - const Bitmap aDestination(impTransformBitmap(rSource.GetBitmap(), aDestinationSize, rTransform, bDoSmoothAtAll)); - - // create mask - if(rSource.IsTransparent()) - { - if(rSource.IsAlpha()) - { - const Bitmap aAlpha(impTransformBitmap(rSource.GetAlpha().GetBitmap(), aDestinationSize, rTransform, bDoSmoothAtAll)); - return BitmapEx(aDestination, AlphaMask(aAlpha)); - } - else - { - const Bitmap aMask(impTransformBitmap(rSource.GetMask(), aDestinationSize, rTransform, false)); - return BitmapEx(aDestination, aMask); - } - } - - return BitmapEx(aDestination); - } - - BitmapEx impModifyBitmapEx( - const basegfx::BColorModifierStack& rBColorModifierStack, - const BitmapEx& rSource) - { - Bitmap aChangedBitmap(rSource.GetBitmap()); - bool bDone(false); - - for(sal_uInt32 a(rBColorModifierStack.count()); a && !bDone; ) - { - const basegfx::BColorModifier& rModifier = rBColorModifierStack.getBColorModifier(--a); - - switch(rModifier.getMode()) - { - case basegfx::BCOLORMODIFYMODE_REPLACE : - { - // complete replace - if(rSource.IsTransparent()) - { - // clear bitmap with dest color - if(aChangedBitmap.GetBitCount() <= 8) - { - // do NOT use erase; for e.g. 8bit Bitmaps, the nearest color to the given - // erase color is determined and used -> this may be different from what is - // wanted here. Better create a new bitmap with the needed color explicitely - BitmapReadAccess* pReadAccess = aChangedBitmap.AcquireReadAccess(); - OSL_ENSURE(pReadAccess, "Got no Bitmap ReadAccess ?!?"); - - if(pReadAccess) - { - BitmapPalette aNewPalette(pReadAccess->GetPalette()); - aNewPalette[0] = BitmapColor(Color(rModifier.getBColor())); - aChangedBitmap = Bitmap( - aChangedBitmap.GetSizePixel(), - aChangedBitmap.GetBitCount(), - &aNewPalette); - delete pReadAccess; - } - } - else - { - aChangedBitmap.Erase(Color(rModifier.getBColor())); - } - } - else - { - // erase bitmap, caller will know to paint direct - aChangedBitmap.SetEmpty(); - } - - bDone = true; - break; - } - - default : // BCOLORMODIFYMODE_INTERPOLATE, BCOLORMODIFYMODE_GRAY, BCOLORMODIFYMODE_BLACKANDWHITE - { - BitmapWriteAccess* pContent = aChangedBitmap.AcquireWriteAccess(); - - if(pContent) - { - const double fConvertColor(1.0 / 255.0); - - for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++) - { - for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++) - { - const BitmapColor aBMCol(pContent->GetColor(y, x)); - const basegfx::BColor aBSource( - (double)aBMCol.GetRed() * fConvertColor, - (double)aBMCol.GetGreen() * fConvertColor, - (double)aBMCol.GetBlue() * fConvertColor); - const basegfx::BColor aBDest(rModifier.getModifiedColor(aBSource)); - - pContent->SetPixel(y, x, BitmapColor(Color(aBDest))); - } - } - - delete pContent; - } - - break; - } - } - } - - if(aChangedBitmap.IsEmpty()) - { - return BitmapEx(); - } - else - { - if(rSource.IsTransparent()) - { - if(rSource.IsAlpha()) - { - return BitmapEx(aChangedBitmap, rSource.GetAlpha()); - } - else - { - return BitmapEx(aChangedBitmap, rSource.GetMask()); - } - } - else - { - return BitmapEx(aChangedBitmap); - } - } - } -} // end of namespace drawinglayer - -////////////////////////////////////////////////////////////////////////////// -// eof diff --git a/drawinglayer/source/processor2d/vclhelperbitmaptransform.hxx b/drawinglayer/source/processor2d/vclhelperbitmaptransform.hxx deleted file mode 100644 index 4717c2ddcc7f..000000000000 --- a/drawinglayer/source/processor2d/vclhelperbitmaptransform.hxx +++ /dev/null @@ -1,56 +0,0 @@ -/************************************************************** - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - *************************************************************/ - - - -#ifndef INCLUDED_DRAWINGLAYER_PROCESSOR2D_VCLHELPERBITMAPTRANSFORM_HXX -#define INCLUDED_DRAWINGLAYER_PROCESSOR2D_VCLHELPERBITMAPTRANSFORM_HXX - -#include <vcl/bitmapex.hxx> - -////////////////////////////////////////////////////////////////////////////// -// predefines - -namespace basegfx { - class B2DHomMatrix; - class BColorModifierStack; -} - -////////////////////////////////////////////////////////////////////////////// -// support methods for vcl direct gradient renderering - -namespace drawinglayer -{ - BitmapEx impTransformBitmapEx( - const BitmapEx& rSource, - const Rectangle& rCroppedRectPixel, - const basegfx::B2DHomMatrix& rTransform); - - BitmapEx impModifyBitmapEx( - const basegfx::BColorModifierStack& rBColorModifierStack, - const BitmapEx& rSource); -} // end of namespace drawinglayer - -////////////////////////////////////////////////////////////////////////////// - -#endif // INCLUDED_DRAWINGLAYER_PROCESSOR2D_VCLHELPERBITMAPTRANSFORM_HXX - -// eof diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx index 40cb8ee76377..dffb112e9fbd 100644 --- a/drawinglayer/source/processor2d/vclprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx @@ -31,9 +31,7 @@ #include <vcl/outdev.hxx> #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> -#include <vclhelperbitmaptransform.hxx> #include <basegfx/polygon/b2dpolygontools.hxx> -#include <vclhelperbitmaprender.hxx> #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx> #include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx> #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> @@ -410,7 +408,7 @@ namespace drawinglayer if(maBColorModifierStack.count()) { - aBitmapEx = impModifyBitmapEx(maBColorModifierStack, aBitmapEx); + aBitmapEx = aBitmapEx.ModifyBitmapEx(maBColorModifierStack); if(aBitmapEx.IsEmpty()) { @@ -427,36 +425,24 @@ namespace drawinglayer } } - { - static bool bForceUseOfOwnTransformer(false); - - // decompose matrix to check for shear, rotate and mirroring - basegfx::B2DVector aScale, aTranslate; - double fRotate, fShearX; - aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX); + // decompose matrix to check for shear, rotate and mirroring + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; - // #121387# when mirrored and rotated, avoid the GraphicManager output which has low quality - const bool bRotated(!basegfx::fTools::equalZero(fRotate)); - const bool bSheared(!basegfx::fTools::equalZero(fShearX)); - //const bool bMirrored(aScale.getX() < 0.0 || aScale.getY() < 0.0); - // const bool bMirroredAndRotated(bRotated && bMirrored); + aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX); - if(!bForceUseOfOwnTransformer && !bRotated && !bSheared) // && !bMirrored) - { - RenderBitmapPrimitive2D_BitmapEx(*mpOutputDevice, aBitmapEx, aLocalTransform); - } - else - { - if(!aBitmapEx.IsTransparent() && (bSheared || bRotated)) - { - // parts will be uncovered, extend aBitmapEx with a mask bitmap - const Bitmap aContent(aBitmapEx.GetBitmap()); - aBitmapEx = BitmapEx(aContent, Bitmap(aContent.GetSizePixel(), 1)); - } + const bool bRotated(!basegfx::fTools::equalZero(fRotate)); + const bool bSheared(!basegfx::fTools::equalZero(fShearX)); - RenderBitmapPrimitive2D_self(*mpOutputDevice, aBitmapEx, aLocalTransform); - } + if(!aBitmapEx.IsTransparent() && (bSheared || bRotated)) + { + // parts will be uncovered, extend aBitmapEx with a mask bitmap + const Bitmap aContent(aBitmapEx.GetBitmap()); + aBitmapEx = BitmapEx(aContent, Bitmap(aContent.GetSizePixel(), 1)); } + + // draw using OutputDevice'sDrawTransformedBitmapEx + mpOutputDevice->DrawTransformedBitmapEx(aLocalTransform, aBitmapEx); } void VclProcessor2D::RenderFillGraphicPrimitive2D(const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate) @@ -537,7 +523,7 @@ namespace drawinglayer if(maBColorModifierStack.count()) { // when color modifier, apply to bitmap - aBitmapEx = impModifyBitmapEx(maBColorModifierStack, aBitmapEx); + aBitmapEx = aBitmapEx.ModifyBitmapEx(maBColorModifierStack); // impModifyBitmapEx uses empty bitmap as sign to return that // the content will be completely replaced to mono color, use shortcut diff --git a/officecfg/registry/schema/org/openoffice/Office/Draw.xcs b/officecfg/registry/schema/org/openoffice/Office/Draw.xcs index 48490dc70128..319c298118f5 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Draw.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Draw.xcs @@ -322,7 +322,7 @@ <desc>Indicates whether a double-click on an object activates the rotation mode.</desc> <label>Rotation Mode after clicking object</label> </info> - <value>false</value> + <value>true</value> </prop> <prop oor:name="Preview" oor:type="xs:double"> <!-- OldPath: Draw/Other --> diff --git a/svx/source/sdr/contact/objectcontactofpageview.cxx b/svx/source/sdr/contact/objectcontactofpageview.cxx index 30c160a74419..a1b137f8e83e 100644 --- a/svx/source/sdr/contact/objectcontactofpageview.cxx +++ b/svx/source/sdr/contact/objectcontactofpageview.cxx @@ -179,6 +179,7 @@ namespace sdr const double fCurrentTime(getPrimitiveAnimator().GetTime()); OutputDevice& rTargetOutDev = GetPageWindow().GetPaintWindow().GetTargetOutputDevice(); basegfx::B2DRange aViewRange; + basegfx::B2DHomMatrix aViewTransformation; // create ViewRange if(isOutputToRecordingMetaFile()) @@ -228,12 +229,16 @@ namespace sdr // transform to world coordinates aViewRange.transform(rTargetOutDev.GetInverseViewTransformation()); + + // for metafile, leave ViewTransformation empty, but for pixel renderer + // get it from OutputDevice + aViewTransformation = rTargetOutDev.GetViewTransformation(); } // update local ViewInformation2D const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D( basegfx::B2DHomMatrix(), - rTargetOutDev.GetViewTransformation(), + aViewTransformation, aViewRange, GetXDrawPageForSdrPage(GetSdrPage()), fCurrentTime, diff --git a/svx/source/svdraw/svdhdl.cxx b/svx/source/svdraw/svdhdl.cxx index b94b418d6942..b37ccf332f73 100644 --- a/svx/source/svdraw/svdhdl.cxx +++ b/svx/source/svdraw/svdhdl.cxx @@ -545,7 +545,7 @@ void SdrHdl::CreateB2dIAObject() // for SJ and the CustomShapeHandles: case HDL_CUSTOMSHAPE1: { - eKindOfMarker = (b1PixMore) ? Customshape_7x7 : Customshape_9x9; + eKindOfMarker = (b1PixMore) ? Customshape_9x9 : Customshape_7x7; eColIndex = Yellow; break; } diff --git a/svx/source/svdraw/svdograf.cxx b/svx/source/svdraw/svdograf.cxx index ddecc010385f..2328272834f6 100644 --- a/svx/source/svdraw/svdograf.cxx +++ b/svx/source/svdraw/svdograf.cxx @@ -737,7 +737,6 @@ void SdrGrafObj::ReleaseGraphicLink() void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const { - FASTBOOL bAnim = pGraphic->IsAnimated(); FASTBOOL bNoPresGrf = ( pGraphic->GetType() != GRAPHIC_NONE ) && !bEmptyPresObj; rInfo.bResizeFreeAllowed = aGeo.nDrehWink % 9000 == 0 || @@ -745,10 +744,10 @@ void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const aGeo.nDrehWink % 27000 == 0; rInfo.bResizePropAllowed = sal_True; - rInfo.bRotateFreeAllowed = bNoPresGrf && !bAnim; - rInfo.bRotate90Allowed = bNoPresGrf && !bAnim; - rInfo.bMirrorFreeAllowed = bNoPresGrf && !bAnim; - rInfo.bMirror45Allowed = bNoPresGrf && !bAnim; + rInfo.bRotateFreeAllowed = bNoPresGrf; + rInfo.bRotate90Allowed = bNoPresGrf; + rInfo.bMirrorFreeAllowed = bNoPresGrf; + rInfo.bMirror45Allowed = bNoPresGrf; rInfo.bMirror90Allowed = !bEmptyPresObj; rInfo.bTransparenceAllowed = sal_False; rInfo.bGradientAllowed = sal_False; diff --git a/vcl/aqua/source/gdi/salgdi.cxx b/vcl/aqua/source/gdi/salgdi.cxx index b448538cdf09..e63ea9d3f664 100644 --- a/vcl/aqua/source/gdi/salgdi.cxx +++ b/vcl/aqua/source/gdi/salgdi.cxx @@ -1096,17 +1096,17 @@ sal_Bool AquaSalGraphics::drawPolyPolygonBezier( sal_uLong, const sal_uLong*, // ----------------------------------------------------------------------- -void AquaSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGraphics ) +void AquaSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics *pSrcGraphics ) { if( !pSrcGraphics ) pSrcGraphics = this; //from unix salgdi2.cxx //[FIXME] find a better way to prevent calc from crashing when width and height are negative - if( pPosAry->mnSrcWidth <= 0 - || pPosAry->mnSrcHeight <= 0 - || pPosAry->mnDestWidth <= 0 - || pPosAry->mnDestHeight <= 0 ) + if( rPosAry.mnSrcWidth <= 0 + || rPosAry.mnSrcHeight <= 0 + || rPosAry.mnDestWidth <= 0 + || rPosAry.mnDestHeight <= 0 ) { return; } @@ -1115,16 +1115,16 @@ void AquaSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGrap /*const*/ AquaSalGraphics* pSrc = static_cast<AquaSalGraphics*>(pSrcGraphics); const bool bSameGraphics = (this == pSrc) || (mbWindow && mpFrame && pSrc->mbWindow && (mpFrame == pSrc->mpFrame)); if( bSameGraphics - && (pPosAry->mnSrcWidth == pPosAry->mnDestWidth) - && (pPosAry->mnSrcHeight == pPosAry->mnDestHeight)) + && (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) + && (rPosAry.mnSrcHeight == rPosAry.mnDestHeight)) { // short circuit if there is nothing to do - if( (pPosAry->mnSrcX == pPosAry->mnDestX) - && (pPosAry->mnSrcY == pPosAry->mnDestY)) + if( (rPosAry.mnSrcX == rPosAry.mnDestX) + && (rPosAry.mnSrcY == rPosAry.mnDestY)) return; // use copyArea() if source and destination context are identical - copyArea( pPosAry->mnDestX, pPosAry->mnDestY, pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcWidth, pPosAry->mnSrcHeight, 0 ); + copyArea( rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, 0 ); return; } @@ -1133,8 +1133,8 @@ void AquaSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGrap DBG_ASSERT( pSrc->mxLayer!=NULL, "AquaSalGraphics::copyBits() from non-layered graphics" ); - const CGPoint aDstPoint = { +pPosAry->mnDestX - pPosAry->mnSrcX, pPosAry->mnDestY - pPosAry->mnSrcY }; - if( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth && pPosAry->mnSrcHeight == pPosAry->mnDestHeight) && + const CGPoint aDstPoint = { +rPosAry.mnDestX - rPosAry.mnSrcX, rPosAry.mnDestY - rPosAry.mnSrcY }; + if( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth && rPosAry.mnSrcHeight == rPosAry.mnDestHeight) && (!mnBitmapDepth || (aDstPoint.x + pSrc->mnWidth) <= mnWidth) ) // workaround a Quartz crasher { // in XOR mode the drawing context is redirected to the XOR mask @@ -1145,7 +1145,7 @@ void AquaSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGrap xCopyContext = mpXorEmulation->GetTargetContext(); CGContextSaveGState( xCopyContext ); - const CGRect aDstRect = { {pPosAry->mnDestX, pPosAry->mnDestY}, {pPosAry->mnDestWidth, pPosAry->mnDestHeight} }; + const CGRect aDstRect = { {rPosAry.mnDestX, rPosAry.mnDestY}, {rPosAry.mnDestWidth, rPosAry.mnDestHeight} }; CGContextClipToRect( xCopyContext, aDstRect ); // draw at new destination @@ -1160,14 +1160,14 @@ void AquaSalGraphics::copyBits( const SalTwoRect *pPosAry, SalGraphics *pSrcGrap } else { - SalBitmap* pBitmap = pSrc->getBitmap( pPosAry->mnSrcX, pPosAry->mnSrcY, pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ); + SalBitmap* pBitmap = pSrc->getBitmap( rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ); if( pBitmap ) { - SalTwoRect aPosAry( *pPosAry ); + SalTwoRect aPosAry( rPosAry ); aPosAry.mnSrcX = 0; aPosAry.mnSrcY = 0; - drawBitmap( &aPosAry, *pBitmap ); + drawBitmap( aPosAry, *pBitmap ); delete pBitmap; } } @@ -1192,7 +1192,7 @@ void AquaSalGraphics::copyArea( long nDstX, long nDstY,long nSrcX, long nSrcY, l aPosAry.mnDestY = nDstY; aPosAry.mnDestWidth = nSrcWidth; aPosAry.mnDestHeight = nSrcHeight; - drawBitmap( &aPosAry, *pBitmap ); + drawBitmap( aPosAry, *pBitmap ); delete pBitmap; } #else @@ -1239,17 +1239,17 @@ void AquaSalGraphics::copyArea( long nDstX, long nDstY,long nSrcX, long nSrcY, l // ----------------------------------------------------------------------- -void AquaSalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ) +void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) { if( !CheckContext() ) return; const AquaSalBitmap& rBitmap = static_cast<const AquaSalBitmap&>(rSalBitmap); - CGImageRef xImage = rBitmap.CreateCroppedImage( (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight ); + CGImageRef xImage = rBitmap.CreateCroppedImage( (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight ); if( !xImage ) return; - const CGRect aDstRect = {{pPosAry->mnDestX, pPosAry->mnDestY}, {pPosAry->mnDestWidth, pPosAry->mnDestHeight}}; + const CGRect aDstRect = {{rPosAry.mnDestX, rPosAry.mnDestY}, {rPosAry.mnDestWidth, rPosAry.mnDestHeight}}; CGContextDrawImage( mrContext, aDstRect, xImage ); CGImageRelease( xImage ); RefreshRect( aDstRect ); @@ -1257,26 +1257,26 @@ void AquaSalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rS // ----------------------------------------------------------------------- -void AquaSalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap,SalColor ) +void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap,SalColor ) { DBG_ERROR("not implemented for color masking!"); - drawBitmap( pPosAry, rSalBitmap ); + drawBitmap( rPosAry, rSalBitmap ); } // ----------------------------------------------------------------------- -void AquaSalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ) +void AquaSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ) { if( !CheckContext() ) return; const AquaSalBitmap& rBitmap = static_cast<const AquaSalBitmap&>(rSalBitmap); const AquaSalBitmap& rMask = static_cast<const AquaSalBitmap&>(rTransparentBitmap); - CGImageRef xMaskedImage( rBitmap.CreateWithMask( rMask, pPosAry->mnSrcX, pPosAry->mnSrcY, pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ) ); + CGImageRef xMaskedImage( rBitmap.CreateWithMask( rMask, rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ) ); if( !xMaskedImage ) return; - const CGRect aDstRect = {{pPosAry->mnDestX, pPosAry->mnDestY}, {pPosAry->mnDestWidth, pPosAry->mnDestHeight}}; + const CGRect aDstRect = {{rPosAry.mnDestX, rPosAry.mnDestY}, {rPosAry.mnDestWidth, rPosAry.mnDestHeight}}; CGContextDrawImage( mrContext, aDstRect, xMaskedImage ); CGImageRelease( xMaskedImage ); RefreshRect( aDstRect ); @@ -1284,17 +1284,17 @@ void AquaSalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rS // ----------------------------------------------------------------------- -void AquaSalGraphics::drawMask( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ) +void AquaSalGraphics::drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ) { if( !CheckContext() ) return; const AquaSalBitmap& rBitmap = static_cast<const AquaSalBitmap&>(rSalBitmap); - CGImageRef xImage = rBitmap.CreateColorMask( pPosAry->mnSrcX, pPosAry->mnSrcY, pPosAry->mnSrcWidth, pPosAry->mnSrcHeight, nMaskColor ); + CGImageRef xImage = rBitmap.CreateColorMask( rPosAry.mnSrcX, rPosAry.mnSrcY, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, nMaskColor ); if( !xImage ) return; - const CGRect aDstRect = {{pPosAry->mnDestX, pPosAry->mnDestY}, {pPosAry->mnDestWidth, pPosAry->mnDestHeight}}; + const CGRect aDstRect = {{rPosAry.mnDestX, rPosAry.mnDestY}, {rPosAry.mnDestWidth, rPosAry.mnDestHeight}}; CGContextDrawImage( mrContext, aDstRect, xImage ); CGImageRelease( xImage ); RefreshRect( aDstRect ); @@ -1531,6 +1531,19 @@ bool AquaSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, } // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +bool AquaSalGraphics::drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) +{ + // here direct support for transformed bitmaps can be impemented + (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap; + return false; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= bool AquaSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ) { diff --git a/vcl/inc/aqua/salgdi.h b/vcl/inc/aqua/salgdi.h index 8cc6dd7ba6fd..909ca1175c3d 100644 --- a/vcl/inc/aqua/salgdi.h +++ b/vcl/inc/aqua/salgdi.h @@ -199,15 +199,15 @@ public: // CopyBits and DrawBitmap --> RasterOp and ClipRegion // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics - virtual void copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics ); - virtual void drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ); + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ); - virtual void drawMask( const SalTwoRect* pPosAry, + virtual void drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ); @@ -223,6 +223,12 @@ public: virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + virtual bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap); virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); diff --git a/vcl/inc/os2/salgdi.h b/vcl/inc/os2/salgdi.h index 702b28aeaa7f..bc051f716281 100644 --- a/vcl/inc/os2/salgdi.h +++ b/vcl/inc/os2/salgdi.h @@ -182,15 +182,15 @@ protected: // CopyBits and DrawBitmap --> RasterOp and ClipRegion // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics - virtual void copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics ); - virtual void drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ); + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ); - virtual void drawMask( const SalTwoRect* pPosAry, + virtual void drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ); @@ -221,6 +221,12 @@ protected: virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + virtual bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap); virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); public: diff --git a/vcl/inc/salgdi.hxx b/vcl/inc/salgdi.hxx index 72720845a307..1480794dbe83 100644 --- a/vcl/inc/salgdi.hxx +++ b/vcl/inc/salgdi.hxx @@ -97,8 +97,9 @@ class VCL_PLUGIN_PUBLIC SalGraphics int m_nLayout; // 0: mirroring off, 1: mirror x-axis protected: + /// bitfield // flags which hold the SetAntialiasing() value from OutputDevice - bool m_bAntiAliasB2DDraw; + bool m_bAntiAliasB2DDraw : 1; public: // get/set AA @@ -135,15 +136,15 @@ protected: // CopyBits and DrawBitmap --> RasterOp and ClipRegion // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics - virtual void copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics ) = 0; - virtual void drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ) = 0; - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) = 0; + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) = 0; + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ) = 0; - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rMaskBitmap ) = 0; - virtual void drawMask( const SalTwoRect* pPosAry, + virtual void drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ) = 0; @@ -184,6 +185,15 @@ protected: virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ) = 0; + + /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */ + virtual bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) = 0; + /** Render solid rectangle with given transparency @param nTransparency @@ -401,23 +411,23 @@ public: // CopyBits and DrawBitmap --> RasterOp and ClipRegion // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics - void CopyBits( const SalTwoRect* pPosAry, + void CopyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics, const OutputDevice *pOutDev, const OutputDevice *pSrcOutDev ); - void DrawBitmap( const SalTwoRect* pPosAry, + void DrawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const OutputDevice *pOutDev ); - void DrawBitmap( const SalTwoRect* pPosAry, + void DrawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor, const OutputDevice *pOutDev ); - void DrawBitmap( const SalTwoRect* pPosAry, + void DrawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap, const OutputDevice *pOutDev ); - void DrawMask( const SalTwoRect* pPosAry, + void DrawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor, const OutputDevice *pOutDev ); @@ -485,6 +495,14 @@ public: const SalBitmap& rAlphaBitmap, const OutputDevice *pOutDev ); + bool DrawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap, + const OutputDevice* pOutDev ); + bool DrawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency, const OutputDevice *pOutDev ); diff --git a/vcl/inc/unx/gtk/gtkgdi.hxx b/vcl/inc/unx/gtk/gtkgdi.hxx index 0f7ec041b5ed..b5199aa78e27 100644 --- a/vcl/inc/unx/gtk/gtkgdi.hxx +++ b/vcl/inc/unx/gtk/gtkgdi.hxx @@ -81,7 +81,7 @@ public: // a control is painted; but presentation effects need // the background set to None; workaround: set the background // before copyBits - virtual void copyBits( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); protected: diff --git a/vcl/inc/unx/pspgraphics.h b/vcl/inc/unx/pspgraphics.h index 3323a6e85d0a..8464ad7d1789 100644 --- a/vcl/inc/unx/pspgraphics.h +++ b/vcl/inc/unx/pspgraphics.h @@ -159,17 +159,17 @@ public: long nSrcWidth, long nSrcHeight, sal_uInt16 nFlags ); - virtual void copyBits( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ); - virtual void drawMask( const SalTwoRect* pPosAry, + virtual void drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ); virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ); @@ -183,6 +183,12 @@ public: virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + virtual bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap); virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); virtual SystemGraphicsData GetGraphicsData() const; diff --git a/vcl/inc/unx/salgdi.h b/vcl/inc/unx/salgdi.h index 60a734be51b2..b74b8c4894a8 100644 --- a/vcl/inc/unx/salgdi.h +++ b/vcl/inc/unx/salgdi.h @@ -175,7 +175,7 @@ protected: int &nSrcY, Pixmap hClipMask ); using SalGraphics::DrawBitmap; - void DrawBitmap( const SalTwoRect *pPosAry, + void DrawBitmap( const SalTwoRect& rPosAry, SalGraphics *pThis, const SalBitmap &rSalBitmap, const SalBitmap &rTransparentBitmap, @@ -184,7 +184,7 @@ protected: GC GetFontGC(); bool setFont( const ImplFontSelectData* pEntry, int nFallbackLevel ); - void drawMaskedBitmap( const SalTwoRect* pPosAry, + void drawMaskedBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ); @@ -312,17 +312,17 @@ public: long nSrcWidth, long nSrcHeight, sal_uInt16 nFlags ); - virtual void copyBits( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rMaskBitmap ); - virtual void drawMask( const SalTwoRect* pPosAry, + virtual void drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ); virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ); @@ -335,6 +335,12 @@ public: virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + virtual bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap); virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); diff --git a/vcl/inc/vcl/bitmapex.hxx b/vcl/inc/vcl/bitmapex.hxx index 0e288cdd3c5b..0ba8ebb4ed5a 100644 --- a/vcl/inc/vcl/bitmapex.hxx +++ b/vcl/inc/vcl/bitmapex.hxx @@ -28,6 +28,7 @@ #include <vcl/bitmap.hxx> #include <vcl/alpha.hxx> #include <tools/color.hxx> +#include <basegfx/color/bcolormodifier.hxx> // ------------------- // - TransparentType - @@ -380,6 +381,44 @@ public: 0 is not transparent, 255 is fully transparent */ sal_uInt8 GetTransparency(sal_Int32 nX, sal_Int32 nY) const; + + /** Create transformed Bitmap + + @param fWidth + The target width in pixels + + @param fHeight + The target height in pixels + + @param rTransformation + The back transformation for each pixel in (0 .. fWidth),(0 .. fHeight) to + local pixel coordiantes + */ + BitmapEx TransformBitmapEx( + double fWidth, + double fHeight, + const basegfx::B2DHomMatrix& rTransformation) const; + + /** Create transformed Bitmap + + @param rTransformation + The transformation from unit coordinates to target + + @param fMaximumArea + A limitation for the maximum size of pixels to use for the result + + @return The transformed bitmap + */ + BitmapEx getTransformed( + const basegfx::B2DHomMatrix& rTransformation, + double fMaximumArea = 500000.0) const; + + /** Create ColorStack-modified version of this BitmapEx + + @param rBColorModifierStack + A ColrModifierStack which defines how each pixel has to be modified + */ + BitmapEx ModifyBitmapEx(const basegfx::BColorModifierStack& rBColorModifierStack) const; }; #endif // _SV_BITMAPEX_HXX diff --git a/vcl/inc/vcl/outdev.hxx b/vcl/inc/vcl/outdev.hxx index 9f704592390a..5779aeeda7ed 100644 --- a/vcl/inc/vcl/outdev.hxx +++ b/vcl/inc/vcl/outdev.hxx @@ -77,6 +77,7 @@ class SalLayout; class ImplLayoutArgs; class ImplFontAttributes; class VirtualDevice; +struct SalTwoRect; namespace com { namespace sun { @@ -355,27 +356,29 @@ private: Point maRefPoint; sal_uInt16 mnAntialiasing; LanguageType meTextLanguage; - mutable sal_Bool mbMap:1, - mbMapIsDefault:1, - mbClipRegion:1, - mbBackground:1, - mbOutput:1, - mbDevOutput:1, - mbOutputClipped:1, - mbLineColor:1, - mbFillColor:1, - mbInitLineColor:1, - mbInitFillColor:1, - mbInitFont:1, - mbInitTextColor:1, - mbInitClipRegion:1, - mbClipRegionSet:1, - mbKerning:1, - mbNewFont:1, - mbTextLines:1, - mbTextSpecial:1, - mbRefPoint:1, - mbEnableRTL:1; + + /// bitfield + mutable bool mbMap : 1; + mutable bool mbMapIsDefault : 1; + mutable bool mbClipRegion : 1; + mutable bool mbBackground : 1; + mutable bool mbOutput : 1; + mutable bool mbDevOutput : 1; + mutable bool mbOutputClipped : 1; + mutable bool mbLineColor : 1; + mutable bool mbFillColor : 1; + mutable bool mbInitLineColor : 1; + mutable bool mbInitFillColor : 1; + mutable bool mbInitFont : 1; + mutable bool mbInitTextColor : 1; + mutable bool mbInitClipRegion : 1; + mutable bool mbClipRegionSet : 1; + mutable bool mbKerning : 1; + mutable bool mbNewFont : 1; + mutable bool mbTextLines : 1; + mutable bool mbTextSpecial : 1; + mutable bool mbRefPoint : 1; + mutable bool mbEnableRTL : 1; public: SAL_DLLPRIVATE sal_Int32 ImplGetDPIX() const { return mnDPIX; } @@ -482,7 +485,7 @@ public: SAL_DLLPRIVATE void ImplDrawGradientWallpaper( long nX, long nY, long nWidth, long nHeight, const Wallpaper& rWallpaper ); SAL_DLLPRIVATE void ImplDraw2ColorFrame( const Rectangle& rRect, const Color& rLeftTopColor, const Color& rRightBottomColor ); - SAL_DLLPRIVATE void ImplDrawOutDevDirect( const OutputDevice* pSrcDev, void* pPosAry ); + SAL_DLLPRIVATE void ImplDrawOutDevDirect( const OutputDevice* pSrcDev, SalTwoRect& rPosAry ); SAL_DLLPRIVATE void ImplDrawBitmap( const Point& rDestPt, const Size& rDestSize, const Point& rSrcPtPixel, const Size& rSrcSizePixel, const Bitmap& rBitmap, const sal_uLong nAction ); @@ -772,6 +775,20 @@ public: const Point& rSrcPtPixel, const Size& rSrcSizePixel, const BitmapEx& rBitmapEx ); + /** Draw BitampEx transformed + + @param rTransformation + The transformation describing the target positioning of the given bitmap. Transforming + the unit object coordinates (0, 0, 1, 1) with this matrix is the transformation to + discrete coordinates + + @param rBitmapEx + The BitmapEx to be painted + */ + void DrawTransformedBitmapEx( + const basegfx::B2DHomMatrix& rTransformation, + const BitmapEx& rBitmapEx); + void DrawMask( const Point& rDestPt, const Bitmap& rBitmap, const Color& rMaskColor ); void DrawMask( const Point& rDestPt, const Size& rDestSize, diff --git a/vcl/inc/vcl/salbtype.hxx b/vcl/inc/vcl/salbtype.hxx index 9d632b2d76ad..6863aed58ffa 100644 --- a/vcl/inc/vcl/salbtype.hxx +++ b/vcl/inc/vcl/salbtype.hxx @@ -282,8 +282,9 @@ struct VCL_DLLPUBLIC BitmapBuffer // - StretchAndConvert - // --------------------- -VCL_DLLPUBLIC BitmapBuffer* StretchAndConvert( const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect, - sal_uLong nDstBitmapFormat, BitmapPalette* pDstPal = NULL, ColorMask* pDstMask = NULL ); +VCL_DLLPUBLIC BitmapBuffer* StretchAndConvert( + const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect, + sal_uLong nDstBitmapFormat, const BitmapPalette* pDstPal = NULL, const ColorMask* pDstMask = NULL ); // ------------------------------------------------------------------ diff --git a/vcl/inc/win/salbmp.h b/vcl/inc/win/salbmp.h index 83df2cd6c843..4604c9ae9bf2 100644 --- a/vcl/inc/win/salbmp.h +++ b/vcl/inc/win/salbmp.h @@ -27,6 +27,7 @@ #include <tools/gen.hxx> #include <win/wincomp.hxx> #include <salbmp.hxx> +#include <boost/shared_ptr.hpp> // -------------- // - SalBitmap - @@ -36,24 +37,38 @@ struct BitmapBuffer; class BitmapColor; class BitmapPalette; class SalGraphics; +namespace Gdiplus { class Bitmap; } +typedef boost::shared_ptr< Gdiplus::Bitmap > GdiPlusBmpPtr; class WinSalBitmap : public SalBitmap { private: + friend class GdiPlusBuffer; // allow buffer to remove maGdiPlusBitmap eventually Size maSize; HGLOBAL mhDIB; HBITMAP mhDDB; - sal_uInt16 mnBitCount; + + // the buffered evtl. used Gdiplus::Bitmap instance. It is managed by + // GdiPlusBuffer. To make this safe, it is only handed out as shared + // pointer; the GdiPlusBuffer may delete the local instance + GdiPlusBmpPtr maGdiPlusBitmap; + + sal_uInt16 mnBitCount; + + Gdiplus::Bitmap* ImplCreateGdiPlusBitmap(const WinSalBitmap& rAlphaSource); + Gdiplus::Bitmap* ImplCreateGdiPlusBitmap(); public: HGLOBAL ImplGethDIB() const { return mhDIB; } HBITMAP ImplGethDDB() const { return mhDDB; } + GdiPlusBmpPtr ImplGetGdiPlusBitmap(const WinSalBitmap* pAlphaSource = 0) const; + static HGLOBAL ImplCreateDIB( const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal ); static HANDLE ImplCopyDIBOrDDB( HANDLE hHdl, bool bDIB ); - static sal_uInt16 ImplGetDIBColorCount( HGLOBAL hDIB ); + static sal_uInt16 ImplGetDIBColorCount( HGLOBAL hDIB ); static void ImplDecodeRLEBuffer( const BYTE* pSrcBuf, BYTE* pDstBuf, const Size& rSizePixel, bool bRLE4 ); diff --git a/vcl/inc/win/salgdi.h b/vcl/inc/win/salgdi.h index 1ba1c51f36fb..dd909d2db980 100644 --- a/vcl/inc/win/salgdi.h +++ b/vcl/inc/win/salgdi.h @@ -128,8 +128,14 @@ public: class WinSalGraphics : public SalGraphics { +private: + HDC mhLocalDC; // HDC + +public: + HDC getHDC() { return mhLocalDC; } + void setHDC(HDC aNew) { mhLocalDC = aNew; } + public: - HDC mhDC; // HDC HWND mhWnd; // Window-Handle, when Window-Graphics HFONT mhFonts[ MAX_FALLBACK ]; // Font + Fallbacks const ImplWinFontData* mpWinFontData[ MAX_FALLBACK ]; // pointer to the most recent font face @@ -155,15 +161,17 @@ public: KERNINGPAIR* mpFontKernPairs; // Kerning Pairs of the current Font sal_uIntPtr mnFontKernPairCount;// Number of Kerning Pairs of the current Font int mnPenWidth; // Linienbreite - sal_Bool mbStockPen; // is Pen a stockpen - sal_Bool mbStockBrush; // is Brush a stcokbrush - sal_Bool mbPen; // is Pen (FALSE == NULL_PEN) - sal_Bool mbBrush; // is Brush (FALSE == NULL_BRUSH) - sal_Bool mbPrinter; // is Printer - sal_Bool mbVirDev; // is VirDev - sal_Bool mbWindow; // is Window - sal_Bool mbScreen; // is Screen compatible - bool mbXORMode; // _every_ output with RasterOp XOR + + /// bitfield + bool mbStockPen : 1; // is Pen a stockpen + bool mbStockBrush : 1; // is Brush a stcokbrush + bool mbPen : 1; // is Pen (FALSE == NULL_PEN) + bool mbBrush : 1; // is Brush (FALSE == NULL_BRUSH) + bool mbPrinter : 1; // is Printer + bool mbVirDev : 1; // is VirDev + bool mbWindow : 1; // is Window + bool mbScreen : 1; // is Screen compatible + bool mbXORMode : 1; // _every_ output with RasterOp XOR // remember RGB values for SetLineColor/SetFillColor SalColor maLineColor; @@ -202,15 +210,15 @@ protected: // CopyBits and DrawBitmap --> RasterOp and ClipRegion // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics - virtual void copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics ); - virtual void drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ); + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ); - virtual void drawMask( const SalTwoRect* pPosAry, + virtual void drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ); @@ -239,8 +247,18 @@ protected: virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + virtual bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap); virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); +private: + // local helpers + bool tryDrawBitmapGdiPlus(const SalTwoRect& rTR, const SalBitmap& rSrcBitmap); + public: // public SalGraphics methods, the interface to teh independent vcl part diff --git a/vcl/inc/win/salvd.h b/vcl/inc/win/salvd.h index 8ffef2edec5f..f7db62823802 100644 --- a/vcl/inc/win/salvd.h +++ b/vcl/inc/win/salvd.h @@ -34,8 +34,14 @@ class WinSalGraphics; class WinSalVirtualDevice : public SalVirtualDevice { +private: + HDC mhLocalDC; // HDC or 0 for Cache Device + +public: + HDC getHDC() { return mhLocalDC; } + void setHDC(HDC aNew) { mhLocalDC = aNew; } + public: - HDC mhDC; // HDC or 0 for Cache Device HBITMAP mhBmp; // Memory Bitmap HBITMAP mhDefBmp; // Default Bitmap WinSalGraphics* mpGraphics; // current VirDev graphics diff --git a/vcl/os2/source/gdi/salgdi2.cxx b/vcl/os2/source/gdi/salgdi2.cxx index aba94c85fe50..cc798a80a985 100644 --- a/vcl/os2/source/gdi/salgdi2.cxx +++ b/vcl/os2/source/gdi/salgdi2.cxx @@ -51,7 +51,7 @@ bool Os2SalGraphics::supportsOperation( OutDevSupportType ) const } -void Os2SalGraphics::copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics ) +void Os2SalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) { HPS hSrcPS; POINTL thePoints[4]; @@ -71,22 +71,22 @@ void Os2SalGraphics::copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraph } // lower-left corner of target - thePoints[0].x = pPosAry->mnDestX; - thePoints[0].y = TY( pPosAry->mnDestY + pPosAry->mnDestHeight - 1 ); + thePoints[0].x = rPosAry.mnDestX; + thePoints[0].y = TY( rPosAry.mnDestY + rPosAry.mnDestHeight - 1 ); // upper-right corner of target - thePoints[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth; - thePoints[1].y = TY( pPosAry->mnDestY - 1 ); + thePoints[1].x = rPosAry.mnDestX + rPosAry.mnDestWidth; + thePoints[1].y = TY( rPosAry.mnDestY - 1 ); // lower-left corner of source - thePoints[2].x = pPosAry->mnSrcX; - thePoints[2].y = nSrcHeight - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight ); + thePoints[2].x = rPosAry.mnSrcX; + thePoints[2].y = nSrcHeight - ( rPosAry.mnSrcY + rPosAry.mnSrcHeight ); - if ( ( pPosAry->mnDestWidth != pPosAry->mnSrcWidth ) || ( pPosAry->mnDestHeight != pPosAry->mnSrcHeight ) ) + if ( ( rPosAry.mnDestWidth != rPosAry.mnSrcWidth ) || ( rPosAry.mnDestHeight != rPosAry.mnSrcHeight ) ) { // upper-right corner of Source - thePoints[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth; - thePoints[3].y = nSrcHeight - pPosAry->mnSrcY + pPosAry->mnSrcHeight; + thePoints[3].x = rPosAry.mnSrcX + rPosAry.mnSrcWidth; + thePoints[3].y = nSrcHeight - rPosAry.mnSrcY + rPosAry.mnSrcHeight; GpiBitBlt( mhPS, hSrcPS, 4, thePoints, mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY, BBO_IGNORE ); @@ -275,7 +275,7 @@ void Os2SalGraphics::copyArea( long nDestX, long nDestY, // ----------------------------------------------------------------------- void ImplDrawBitmap( HPS hPS, long nScreenHeight, - const SalTwoRect* pPosAry, const Os2SalBitmap& rSalBitmap, + const SalTwoRect& rPosAry, const Os2SalBitmap& rSalBitmap, PM_BOOL bPrinter, int nDrawMode ) { if( hPS ) @@ -305,15 +305,15 @@ void ImplDrawBitmap( HPS hPS, long nScreenHeight, long nInfoSize = *(ULONG*) pBI + rSalBitmap.ImplGetDIBColorCount( hDrawDIB ) * sizeof( RGB2 ); PM_BYTE* pBits = (PM_BYTE*) pBI + nInfoSize; - pts[0].x = pPosAry->mnDestX; - pts[0].y = nScreenHeight - pPosAry->mnDestY - pPosAry->mnDestHeight; - pts[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth - 1; - pts[1].y = nScreenHeight - pPosAry->mnDestY - 1; + pts[0].x = rPosAry.mnDestX; + pts[0].y = nScreenHeight - rPosAry.mnDestY - rPosAry.mnDestHeight; + pts[1].x = rPosAry.mnDestX + rPosAry.mnDestWidth - 1; + pts[1].y = nScreenHeight - rPosAry.mnDestY - 1; - pts[2].x = pPosAry->mnSrcX; - pts[2].y = nHeight - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight ); - pts[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth; - pts[3].y = nHeight - pPosAry->mnSrcY; + pts[2].x = rPosAry.mnSrcX; + pts[2].y = nHeight - ( rPosAry.mnSrcY + rPosAry.mnSrcHeight ); + pts[3].x = rPosAry.mnSrcX + rPosAry.mnSrcWidth; + pts[3].y = nHeight - rPosAry.mnSrcY; // if we've got a 1Bit DIB, we create a 4Bit substitute if( ( pBIH->cBitCount == 1 ) && !hSubst ) @@ -400,15 +400,15 @@ void ImplDrawBitmap( HPS hPS, long nScreenHeight, { POINTL pts[ 4 ]; - pts[0].x = pPosAry->mnDestX; - pts[0].y = nScreenHeight - pPosAry->mnDestY - pPosAry->mnDestHeight; - pts[1].x = pPosAry->mnDestX + pPosAry->mnDestWidth - 1; - pts[1].y = nScreenHeight - pPosAry->mnDestY - 1; + pts[0].x = rPosAry.mnDestX; + pts[0].y = nScreenHeight - rPosAry.mnDestY - rPosAry.mnDestHeight; + pts[1].x = rPosAry.mnDestX + rPosAry.mnDestWidth - 1; + pts[1].y = nScreenHeight - rPosAry.mnDestY - 1; - pts[2].x = pPosAry->mnSrcX; - pts[2].y = rSalBitmap.GetSize().Height() - ( pPosAry->mnSrcY + pPosAry->mnSrcHeight ); - pts[3].x = pPosAry->mnSrcX + pPosAry->mnSrcWidth; - pts[3].y = rSalBitmap.GetSize().Height() - pPosAry->mnSrcY; + pts[2].x = rPosAry.mnSrcX; + pts[2].y = rSalBitmap.GetSize().Height() - ( rPosAry.mnSrcY + rPosAry.mnSrcHeight ); + pts[3].x = rPosAry.mnSrcX + rPosAry.mnSrcWidth; + pts[3].y = rSalBitmap.GetSize().Height() - rPosAry.mnSrcY; GpiWCBitBlt( hPS, hDrawDDB, 4L, pts, nDrawMode, BBO_IGNORE ); /* @@ -425,30 +425,29 @@ void ImplDrawBitmap( HPS hPS, long nScreenHeight, // ----------------------------------------------------------------------- -void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry, - const SalBitmap& rSalBitmap ) +void Os2SalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) { ImplDrawBitmap( mhPS, mnHeight, - pPosAry, static_cast<const Os2SalBitmap&>(rSalBitmap), + rPosAry, static_cast<const Os2SalBitmap&>(rSalBitmap), mbPrinter, mbXORMode ? ROP_SRCINVERT : ROP_SRCCOPY ); } // ----------------------------------------------------------------------- -void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry, +void Os2SalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ) { DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); //const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap); // an FM: kann erst einmal unberuecksichtigt bleiben - drawBitmap( pPosAry, rSalBitmap ); + drawBitmap( rPosAry, rSalBitmap ); } // ----------------------------------------------------------------------- -void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry, +void Os2SalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSSalBitmap, const SalBitmap& rSTransparentBitmap ) { @@ -459,12 +458,12 @@ void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry, if( bFastTransparent ) { - ImplDrawBitmap( mhPS, mnHeight, pPosAry, rTransparentBitmap, FALSE, ROP_SRCAND ); - ImplDrawBitmap( mhPS, mnHeight, pPosAry, rSalBitmap, FALSE, ROP_SRCPAINT ); + ImplDrawBitmap( mhPS, mnHeight, rPosAry, rTransparentBitmap, FALSE, ROP_SRCAND ); + ImplDrawBitmap( mhPS, mnHeight, rPosAry, rSalBitmap, FALSE, ROP_SRCPAINT ); } else { - SalTwoRect aPosAry = *pPosAry; + SalTwoRect aPosAry = rPosAry; int nDstX = (int) aPosAry.mnDestX; int nDstY = (int) aPosAry.mnDestY; int nDstWidth = (int) aPosAry.mnDestWidth; @@ -497,13 +496,13 @@ void Os2SalGraphics::drawBitmap( const SalTwoRect* pPosAry, aPtL[ 2 ].y = TY( nDstY + nDstHeight - 1 ); GpiBitBlt( hMemPS, hPS, 3, aPtL, ROP_SRCCOPY, BBO_IGNORE ); - ImplDrawBitmap( hMaskPS, nDstHeight, &aPosAry, rTransparentBitmap, FALSE, ROP_SRCCOPY ); + ImplDrawBitmap( hMaskPS, nDstHeight, aPosAry, rTransparentBitmap, FALSE, ROP_SRCCOPY ); aPtL[ 2 ].x = 0; aPtL[ 2 ].y = 0; GpiBitBlt( hMemPS, hMaskPS, 3, aPtL, ROP_SRCAND, BBO_IGNORE ); - ImplDrawBitmap( hMaskPS, nDstHeight, &aPosAry, rSalBitmap, FALSE, ROP_SRCERASE ); + ImplDrawBitmap( hMaskPS, nDstHeight, aPosAry, rSalBitmap, FALSE, ROP_SRCERASE ); GpiBitBlt( hMemPS, hMaskPS, 3, aPtL, ROP_SRCPAINT, BBO_IGNORE ); aPtL[ 0 ].x = nDstX; @@ -542,6 +541,20 @@ bool Os2SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, // ----------------------------------------------------------------------- +bool Os2SalGraphics::drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) +{ + // here direct support for transformed bitmaps can be impemented + (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap; + return false; +} + +// ----------------------------------------------------------------------- + bool Os2SalGraphics::drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ) { @@ -551,7 +564,7 @@ bool Os2SalGraphics::drawAlphaRect( long nX, long nY, long nWidth, // ----------------------------------------------------------------------- -void Os2SalGraphics::drawMask( const SalTwoRect* pPosAry, +void Os2SalGraphics::drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSSalBitmap, SalColor nMaskColor ) { @@ -559,7 +572,7 @@ void Os2SalGraphics::drawMask( const SalTwoRect* pPosAry, const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap); - SalTwoRect aPosAry = *pPosAry; + SalTwoRect aPosAry = rPosAry; HPS hPS = mhPS; IMAGEBUNDLE aBundle, aOldBundle; AREABUNDLE aAreaBundle, aOldAreaBundle; @@ -582,7 +595,7 @@ void Os2SalGraphics::drawMask( const SalTwoRect* pPosAry, Ft2SetAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL | ABB_MIX_MODE | ABB_BACK_MIX_MODE, 0, &aAreaBundle ); - ImplDrawBitmap( hPS, mnHeight, &aPosAry, rSalBitmap, FALSE, 0x00B8L ); + ImplDrawBitmap( hPS, mnHeight, aPosAry, rSalBitmap, FALSE, 0x00B8L ); Ft2SetAttrs( hPS, PRIM_IMAGE, IBB_COLOR | IBB_BACK_COLOR, 0, &aOldBundle ); Ft2SetAttrs( hPS, PRIM_AREA, ABB_COLOR | ABB_BACK_COLOR | ABB_SYMBOL | diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx index 383e5245b434..e8ce7b97549c 100644 --- a/vcl/source/gdi/bitmapex.cxx +++ b/vcl/source/gdi/bitmapex.cxx @@ -37,6 +37,7 @@ #include <vcl/dibtools.hxx> #include <image.h> #include <impimagetree.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> // ------------ // - BitmapEx - @@ -833,4 +834,371 @@ sal_uInt8 BitmapEx::GetTransparency(sal_Int32 nX, sal_Int32 nY) const } // ------------------------------------------------------------------ + +namespace +{ + void impSmoothPoint(BitmapColor& rValue, const basegfx::B2DPoint& rSource, sal_Int32 nIntX, sal_Int32 nIntY, BitmapReadAccess& rRead) + { + double fDeltaX(rSource.getX() - nIntX); + double fDeltaY(rSource.getY() - nIntY); + sal_Int32 nIndX(0L); + sal_Int32 nIndY(0L); + + if(fDeltaX > 0.0 && nIntX + 1L < rRead.Width()) + { + nIndX++; + } + else if(fDeltaX < 0.0 && nIntX >= 1L) + { + fDeltaX = -fDeltaX; + nIndX--; + } + + if(fDeltaY > 0.0 && nIntY + 1L < rRead.Height()) + { + nIndY++; + } + else if(fDeltaY < 0.0 && nIntY >= 1L) + { + fDeltaY = -fDeltaY; + nIndY--; + } + + if(nIndX || nIndY) + { + const double fColorToReal(1.0 / 255.0); + double fR(rValue.GetRed() * fColorToReal); + double fG(rValue.GetGreen() * fColorToReal); + double fB(rValue.GetBlue() * fColorToReal); + double fRBottom(0.0), fGBottom(0.0), fBBottom(0.0); + + if(nIndX) + { + const double fMulA(fDeltaX * fColorToReal); + double fMulB(1.0 - fDeltaX); + const BitmapColor aTopPartner(rRead.GetColor(nIntY, nIntX + nIndX)); + + fR = (fR * fMulB) + (aTopPartner.GetRed() * fMulA); + fG = (fG * fMulB) + (aTopPartner.GetGreen() * fMulA); + fB = (fB * fMulB) + (aTopPartner.GetBlue() * fMulA); + + if(nIndY) + { + fMulB *= fColorToReal; + const BitmapColor aBottom(rRead.GetColor(nIntY + nIndY, nIntX)); + const BitmapColor aBottomPartner(rRead.GetColor(nIntY + nIndY, nIntX + nIndX)); + + fRBottom = (aBottom.GetRed() * fMulB) + (aBottomPartner.GetRed() * fMulA); + fGBottom = (aBottom.GetGreen() * fMulB) + (aBottomPartner.GetGreen() * fMulA); + fBBottom = (aBottom.GetBlue() * fMulB) + (aBottomPartner.GetBlue() * fMulA); + } + } + + if(nIndY) + { + if(!nIndX) + { + const BitmapColor aBottom(rRead.GetColor(nIntY + nIndY, nIntX)); + + fRBottom = aBottom.GetRed() * fColorToReal; + fGBottom = aBottom.GetGreen() * fColorToReal; + fBBottom = aBottom.GetBlue() * fColorToReal; + } + + const double fMulB(1.0 - fDeltaY); + + fR = (fR * fMulB) + (fRBottom * fDeltaY); + fG = (fG * fMulB) + (fGBottom * fDeltaY); + fB = (fB * fMulB) + (fBBottom * fDeltaY); + } + + rValue.SetRed((sal_uInt8)(fR * 255.0)); + rValue.SetGreen((sal_uInt8)(fG * 255.0)); + rValue.SetBlue((sal_uInt8)(fB * 255.0)); + } + } + + Bitmap impTransformBitmap( + const Bitmap& rSource, + const Size aDestinationSize, + const basegfx::B2DHomMatrix& rTransform, + bool bSmooth) + { + Bitmap aDestination(aDestinationSize, 24); + BitmapWriteAccess* pWrite = aDestination.AcquireWriteAccess(); + + if(pWrite) + { + const Size aContentSizePixel(rSource.GetSizePixel()); + BitmapReadAccess* pRead = (const_cast< Bitmap& >(rSource)).AcquireReadAccess(); + + if(pRead) + { + const Size aDestinationSizePixel(aDestination.GetSizePixel()); + bool bWorkWithIndex(rSource.GetBitCount() <= 8); + BitmapColor aOutside(BitmapColor(0xff, 0xff, 0xff)); + + for(sal_Int32 y(0L); y < aDestinationSizePixel.getHeight(); y++) + { + for(sal_Int32 x(0L); x < aDestinationSizePixel.getWidth(); x++) + { + const basegfx::B2DPoint aSourceCoor(rTransform * basegfx::B2DPoint(x, y)); + const sal_Int32 nIntX(basegfx::fround(aSourceCoor.getX())); + + if(nIntX >= 0L && nIntX < aContentSizePixel.getWidth()) + { + const sal_Int32 nIntY(basegfx::fround(aSourceCoor.getY())); + + if(nIntY >= 0L && nIntY < aContentSizePixel.getHeight()) + { + // inside pixel + BitmapColor aValue; + + if(bWorkWithIndex) + { + aValue = pRead->GetPaletteColor(pRead->GetPixelIndex(nIntY, nIntX)); + } + else + { + aValue = pRead->GetPixel(nIntY, nIntX); + } + + if(bSmooth) + { + impSmoothPoint(aValue, aSourceCoor, nIntX, nIntY, *pRead); + } + + pWrite->SetPixel(y, x, aValue); + continue; + } + } + + // here are outside pixels. Complete mask + if(bWorkWithIndex) + { + pWrite->SetPixel(y, x, aOutside); + } + } + } + + delete pRead; + } + + delete pWrite; + } + + rSource.AdaptBitCount(aDestination); + + return aDestination; + } +} // end of anonymous namespace +BitmapEx BitmapEx::TransformBitmapEx( + double fWidth, + double fHeight, + const basegfx::B2DHomMatrix& rTransformation) const +{ + if(fWidth <= 1 || fHeight <= 1) + return BitmapEx(); + + // force destination to 24 bit, we want to smooth output + const Size aDestinationSize(basegfx::fround(fWidth), basegfx::fround(fHeight)); + static bool bDoSmoothAtAll(true); + const Bitmap aDestination(impTransformBitmap(GetBitmap(), aDestinationSize, rTransformation, bDoSmoothAtAll)); + + // create mask + if(IsTransparent()) + { + if(IsAlpha()) + { + const Bitmap aAlpha(impTransformBitmap(GetAlpha().GetBitmap(), aDestinationSize, rTransformation, bDoSmoothAtAll)); + return BitmapEx(aDestination, AlphaMask(aAlpha)); + } + else + { + const Bitmap aMask(impTransformBitmap(GetMask(), aDestinationSize, rTransformation, false)); + return BitmapEx(aDestination, aMask); + } + } + + return BitmapEx(aDestination); +} + +// ------------------------------------------------------------------ + +BitmapEx BitmapEx::getTransformed( + const basegfx::B2DHomMatrix& rTransformation, + double fMaximumArea) const +{ + BitmapEx aRetval; + + if(IsEmpty()) + return aRetval; + + const sal_uInt32 nSourceWidth(GetSizePixel().Width()); + const sal_uInt32 nSourceHeight(GetSizePixel().Height()); + + if(!nSourceWidth || !nSourceHeight) + return aRetval; + + // Get dest range + basegfx::B2DRange aOutlineRange(0.0, 0.0, 1.0, 1.0); + aOutlineRange.transform(rTransformation); + + // get target size + double fWidth(aOutlineRange.getWidth()); + double fHeight(aOutlineRange.getHeight()); + + if(fWidth < 1.0 || fHeight < 1.0) + return aRetval; + + // test if discrete size (pixel) maybe too big and limit it + const double fArea(fWidth * fHeight); + const bool bNeedToReduce(fArea > fMaximumArea); + double fReduceFactor(1.0); + + if(bNeedToReduce) + { + fReduceFactor = sqrt(fMaximumArea / fArea); + fWidth *= fReduceFactor; + fHeight *= fReduceFactor; + } + + // Build complete transform from source pixels to target pixels. + // Start by scaling from source pixel size to unit coordinates + basegfx::B2DHomMatrix aTransform( + basegfx::tools::createScaleB2DHomMatrix( + 1.0 / nSourceWidth, + 1.0 / nSourceHeight)); + + // multiply with given transform which leads from unit coordinates inside + // aOutlineRange + aTransform = rTransformation * aTransform; + + // substract top-left of aOutlineRange + aTransform.translate(-aOutlineRange.getMinX(), -aOutlineRange.getMinY()); + + // scale to target pixels (if needed) + if(bNeedToReduce) + { + aTransform.scale(fReduceFactor, fReduceFactor); + } + + // invert to get transformation from target pixel coordiates to source pixels + aTransform.invert(); + + // create bitmap using source, destination and linear back-transformation + aRetval = TransformBitmapEx(fWidth, fHeight, aTransform); + + return aRetval; +} + +// ------------------------------------------------------------------ + +BitmapEx BitmapEx::ModifyBitmapEx(const basegfx::BColorModifierStack& rBColorModifierStack) const +{ + Bitmap aChangedBitmap(GetBitmap()); + bool bDone(false); + + for(sal_uInt32 a(rBColorModifierStack.count()); a && !bDone; ) + { + const basegfx::BColorModifier& rModifier = rBColorModifierStack.getBColorModifier(--a); + + switch(rModifier.getMode()) + { + case basegfx::BCOLORMODIFYMODE_REPLACE : + { + // complete replace + if(IsTransparent()) + { + // clear bitmap with dest color + if(aChangedBitmap.GetBitCount() <= 8) + { + // do NOT use erase; for e.g. 8bit Bitmaps, the nearest color to the given + // erase color is determined and used -> this may be different from what is + // wanted here. Better create a new bitmap with the needed color explicitely + BitmapReadAccess* pReadAccess = aChangedBitmap.AcquireReadAccess(); + OSL_ENSURE(pReadAccess, "Got no Bitmap ReadAccess ?!?"); + + if(pReadAccess) + { + BitmapPalette aNewPalette(pReadAccess->GetPalette()); + aNewPalette[0] = BitmapColor(Color(rModifier.getBColor())); + aChangedBitmap = Bitmap( + aChangedBitmap.GetSizePixel(), + aChangedBitmap.GetBitCount(), + &aNewPalette); + delete pReadAccess; + } + } + else + { + aChangedBitmap.Erase(Color(rModifier.getBColor())); + } + } + else + { + // erase bitmap, caller will know to paint direct + aChangedBitmap.SetEmpty(); + } + + bDone = true; + break; + } + + default : // BCOLORMODIFYMODE_INTERPOLATE, BCOLORMODIFYMODE_GRAY, BCOLORMODIFYMODE_BLACKANDWHITE + { + BitmapWriteAccess* pContent = aChangedBitmap.AcquireWriteAccess(); + + if(pContent) + { + const double fConvertColor(1.0 / 255.0); + + for(sal_uInt32 y(0L); y < (sal_uInt32)pContent->Height(); y++) + { + for(sal_uInt32 x(0L); x < (sal_uInt32)pContent->Width(); x++) + { + const BitmapColor aBMCol(pContent->GetColor(y, x)); + const basegfx::BColor aBSource( + (double)aBMCol.GetRed() * fConvertColor, + (double)aBMCol.GetGreen() * fConvertColor, + (double)aBMCol.GetBlue() * fConvertColor); + const basegfx::BColor aBDest(rModifier.getModifiedColor(aBSource)); + + pContent->SetPixel(y, x, BitmapColor(Color(aBDest))); + } + } + + delete pContent; + } + + break; + } + } + } + + if(aChangedBitmap.IsEmpty()) + { + return BitmapEx(); + } + else + { + if(IsTransparent()) + { + if(IsAlpha()) + { + return BitmapEx(aChangedBitmap, GetAlpha()); + } + else + { + return BitmapEx(aChangedBitmap, GetMask()); + } + } + else + { + return BitmapEx(aChangedBitmap); + } + } +} + +// ------------------------------------------------------------------ // eof diff --git a/vcl/source/gdi/outdev2.cxx b/vcl/source/gdi/outdev2.cxx index a57da0cde9ca..1ca43f10c913 100644 --- a/vcl/source/gdi/outdev2.cxx +++ b/vcl/source/gdi/outdev2.cxx @@ -19,13 +19,10 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" #include <tools/debug.hxx> - #include <vcl/bitmap.hxx> #include <vcl/bitmapex.hxx> #include <vcl/window.hxx> @@ -36,7 +33,6 @@ #include <vcl/outdev.hxx> #include <vcl/window.hxx> #include <vcl/image.hxx> - #include <bmpfast.hxx> #include <salbmp.hxx> #include <salgdi.hxx> @@ -46,6 +42,7 @@ #include <outdev.h> #include <window.h> #include <outdata.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> #define BAND_MAX_SIZE 512000 @@ -75,8 +72,6 @@ DBG_NAMEEX( OutputDevice ) return; \ } -#define TwoRect SalTwoRect - // ------------- // - externals - // ------------- @@ -89,7 +84,7 @@ extern sal_uLong nVCLLut[ 256 ]; // ======================================================================= -sal_uLong ImplAdjustTwoRect( TwoRect& rTwoRect, const Size& rSizePix ) +sal_uLong ImplAdjustTwoRect( SalTwoRect& rTwoRect, const Size& rSizePix ) { sal_uLong nMirrFlags = 0; @@ -148,12 +143,11 @@ sal_uLong ImplAdjustTwoRect( TwoRect& rTwoRect, const Size& rSizePix ) // ======================================================================= -void OutputDevice::ImplDrawOutDevDirect( const OutputDevice* pSrcDev, void* pVoidPosAry ) +void OutputDevice::ImplDrawOutDevDirect( const OutputDevice* pSrcDev, SalTwoRect& rPosAry ) { - TwoRect* pPosAry = (TwoRect*)pVoidPosAry; SalGraphics* pGraphics2; - if ( pPosAry->mnSrcWidth && pPosAry->mnSrcHeight && pPosAry->mnDestWidth && pPosAry->mnDestHeight ) + if ( rPosAry.mnSrcWidth && rPosAry.mnSrcHeight && rPosAry.mnDestWidth && rPosAry.mnDestHeight ) { if ( this == pSrcDev ) pGraphics2 = NULL; @@ -196,25 +190,25 @@ void OutputDevice::ImplDrawOutDevDirect( const OutputDevice* pSrcDev, void* pVoi // #102532# Offset only has to be pseudo window offset Rectangle aSrcOutRect( Point( pSrcDev->mnOutOffX, pSrcDev->mnOutOffY ), Size( pSrcDev->mnOutWidth, pSrcDev->mnOutHeight ) ); - Rectangle aSrcRect( Point( pPosAry->mnSrcX, pPosAry->mnSrcY ), - Size( pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ) ); + Rectangle aSrcRect( Point( rPosAry.mnSrcX, rPosAry.mnSrcY ), + Size( rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ) ); const long nOldRight = aSrcRect.Right(); const long nOldBottom = aSrcRect.Bottom(); if ( !aSrcRect.Intersection( aSrcOutRect ).IsEmpty() ) { - if ( (pPosAry->mnSrcX+pPosAry->mnSrcWidth-1) > aSrcOutRect.Right() ) + if ( (rPosAry.mnSrcX+rPosAry.mnSrcWidth-1) > aSrcOutRect.Right() ) { - const long nOldWidth = pPosAry->mnSrcWidth; - pPosAry->mnSrcWidth -= (nOldRight - aSrcRect.Right()); - pPosAry->mnDestWidth = pPosAry->mnDestWidth * pPosAry->mnSrcWidth / nOldWidth; + const long nOldWidth = rPosAry.mnSrcWidth; + rPosAry.mnSrcWidth -= (nOldRight - aSrcRect.Right()); + rPosAry.mnDestWidth = rPosAry.mnDestWidth * rPosAry.mnSrcWidth / nOldWidth; } - if ( (pPosAry->mnSrcY+pPosAry->mnSrcHeight-1) > aSrcOutRect.Bottom() ) + if ( (rPosAry.mnSrcY+rPosAry.mnSrcHeight-1) > aSrcOutRect.Bottom() ) { - const long nOldHeight = pPosAry->mnSrcHeight; - pPosAry->mnSrcHeight -= (nOldBottom - aSrcRect.Bottom()); - pPosAry->mnDestHeight = pPosAry->mnDestHeight * pPosAry->mnSrcHeight / nOldHeight; + const long nOldHeight = rPosAry.mnSrcHeight; + rPosAry.mnSrcHeight -= (nOldBottom - aSrcRect.Bottom()); + rPosAry.mnDestHeight = rPosAry.mnDestHeight * rPosAry.mnSrcHeight / nOldHeight; } // --- RTL --- if this is no window, but pSrcDev is a window @@ -223,12 +217,12 @@ void OutputDevice::ImplDrawOutDevDirect( const OutputDevice* pSrcDev, void* pVoi // mirroring is performed here if( (GetOutDevType() != OUTDEV_WINDOW) && pGraphics2 && (pGraphics2->GetLayout() & SAL_LAYOUT_BIDI_RTL) ) { - SalTwoRect pPosAry2 = *pPosAry; - pGraphics2->mirror( pPosAry2.mnSrcX, pPosAry2.mnSrcWidth, pSrcDev ); - mpGraphics->CopyBits( &pPosAry2, pGraphics2, this, pSrcDev ); + SalTwoRect aPosAry2 = rPosAry; + pGraphics2->mirror( aPosAry2.mnSrcX, aPosAry2.mnSrcWidth, pSrcDev ); + mpGraphics->CopyBits( aPosAry2, pGraphics2, this, pSrcDev ); } else - mpGraphics->CopyBits( pPosAry, pGraphics2, this, pSrcDev ); + mpGraphics->CopyBits( rPosAry, pGraphics2, this, pSrcDev ); } } } @@ -262,7 +256,7 @@ void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize, OUTDEV_INIT(); - TwoRect aPosAry; + SalTwoRect aPosAry; aPosAry.mnSrcWidth = ImplLogicWidthToDevicePixel( rSrcSize.Width() ); aPosAry.mnSrcHeight = ImplLogicHeightToDevicePixel( rSrcSize.Height() ); aPosAry.mnDestWidth = ImplLogicWidthToDevicePixel( rDestSize.Width() ); @@ -298,7 +292,7 @@ void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize, aPosAry.mnDestHeight = aPosAry.mnDestHeight*aPosAry.mnSrcHeight/nOldHeight; } - mpGraphics->CopyBits( &aPosAry, NULL, this, NULL ); + mpGraphics->CopyBits( aPosAry, NULL, this, NULL ); } } @@ -335,7 +329,7 @@ void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize, OUTDEV_INIT(); - TwoRect aPosAry; + SalTwoRect aPosAry; aPosAry.mnSrcX = rOutDev.ImplLogicXToDevicePixel( rSrcPt.X() ); aPosAry.mnSrcY = rOutDev.ImplLogicYToDevicePixel( rSrcPt.Y() ); aPosAry.mnSrcWidth = rOutDev.ImplLogicWidthToDevicePixel( rSrcSize.Width() ); @@ -358,7 +352,7 @@ void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize, } else { - ImplDrawOutDevDirect( &rOutDev, &aPosAry ); + ImplDrawOutDevDirect( &rOutDev, aPosAry ); // #i32109#: make destination rectangle opaque - source has no alpha mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, rDestSize) ); @@ -374,7 +368,7 @@ void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize, else { // no alpha at all, neither in source nor destination device - ImplDrawOutDevDirect( &rOutDev, &aPosAry ); + ImplDrawOutDevDirect( &rOutDev, aPosAry ); } } } @@ -397,7 +391,7 @@ void OutputDevice::CopyArea( const Point& rDestPt, OUTDEV_INIT(); - TwoRect aPosAry; + SalTwoRect aPosAry; aPosAry.mnSrcWidth = ImplLogicWidthToDevicePixel( rSrcSize.Width() ); aPosAry.mnSrcHeight = ImplLogicHeightToDevicePixel( rSrcSize.Height() ); @@ -439,7 +433,7 @@ void OutputDevice::CopyArea( const Point& rDestPt, { aPosAry.mnDestWidth = aPosAry.mnSrcWidth; aPosAry.mnDestHeight = aPosAry.mnSrcHeight; - mpGraphics->CopyBits( &aPosAry, NULL, this, NULL ); + mpGraphics->CopyBits( aPosAry, NULL, this, NULL ); } } } @@ -479,7 +473,7 @@ void OutputDevice::ImplDrawFrameDev( const Point& rPt, const Point& rDevPt, cons else ImplSelectClipRegion( rRegion ); - TwoRect aPosAry; + SalTwoRect aPosAry; aPosAry.mnSrcX = rDevPt.X(); aPosAry.mnSrcY = rDevPt.Y(); aPosAry.mnSrcWidth = rDevSize.Width(); @@ -488,7 +482,7 @@ void OutputDevice::ImplDrawFrameDev( const Point& rPt, const Point& rDevPt, cons aPosAry.mnDestY = rPt.Y(); aPosAry.mnDestWidth = rDevSize.Width(); aPosAry.mnDestHeight = rDevSize.Height(); - ImplDrawOutDevDirect( &rOutDev, &aPosAry ); + ImplDrawOutDevDirect( &rOutDev, aPosAry ); // Dafuer sorgen, das ClipRegion neu berechnet und gesetzt wird mbInitClipRegion = sal_True; @@ -576,16 +570,18 @@ void OutputDevice::ImplDrawBitmap( const Point& rDestPt, const Size& rDestSize, { DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); - Bitmap aBmp( rBitmap ); - if ( ( mnDrawMode & DRAWMODE_NOBITMAP ) ) return; - else if ( ROP_INVERT == meRasterOp ) + + if ( ROP_INVERT == meRasterOp ) { DrawRect( Rectangle( rDestPt, rDestSize ) ); return; } - else if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | + + Bitmap aBmp( rBitmap ); + + if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP ) ) { if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP ) ) @@ -638,7 +634,7 @@ void OutputDevice::ImplDrawBitmap( const Point& rDestPt, const Size& rDestSize, if( !aBmp.IsEmpty() ) { - TwoRect aPosAry; + SalTwoRect aPosAry; aPosAry.mnSrcX = rSrcPtPixel.X(); aPosAry.mnSrcY = rSrcPtPixel.Y(); @@ -667,6 +663,11 @@ void OutputDevice::ImplDrawBitmap( const Point& rDestPt, const Size& rDestSize, * that the destination rectangle will overlap the device but only * be reasonably (say factor 2) larger than the device itself. */ + + // not needed for win32, it uses GdiPlus and is able to do everything without + // internally scaling the bitmap +#ifndef WIN32 + if( aPosAry.mnDestWidth > 2048 || aPosAry.mnDestHeight > 2048 ) { if( meOutDevType == OUTDEV_WINDOW || @@ -720,9 +721,12 @@ void OutputDevice::ImplDrawBitmap( const Point& rDestPt, const Size& rDestSize, } } } +#endif if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight ) - mpGraphics->DrawBitmap( &aPosAry, *aBmp.ImplGetImpBitmap()->ImplGetSalBitmap(), this ); + { + mpGraphics->DrawBitmap( aPosAry, *aBmp.ImplGetImpBitmap()->ImplGetSalBitmap(), this ); + } } } } @@ -738,7 +742,9 @@ void OutputDevice::DrawBitmapEx( const Point& rDestPt, return; if( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() ) + { DrawBitmap( rDestPt, rBitmapEx.GetBitmap() ); + } else { const Size aSizePix( rBitmapEx.GetSizePixel() ); @@ -757,9 +763,13 @@ void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize, return; if ( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() ) + { DrawBitmap( rDestPt, rDestSize, rBitmapEx.GetBitmap() ); + } else + { ImplDrawBitmapEx( rDestPt, rDestSize, Point(), rBitmapEx.GetSizePixel(), rBitmapEx, META_BMPEXSCALE_ACTION ); + } } // ------------------------------------------------------------------ @@ -774,9 +784,117 @@ void OutputDevice::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize, return; if( TRANSPARENT_NONE == rBitmapEx.GetTransparentType() ) + { DrawBitmap( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmapEx.GetBitmap() ); + } else + { ImplDrawBitmapEx( rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel, rBitmapEx, META_BMPEXSCALEPART_ACTION ); + } +} + +// ------------------------------------------------------------------ + +void OutputDevice::DrawTransformedBitmapEx( + const basegfx::B2DHomMatrix& rTransformation, + const BitmapEx& rBitmapEx) +{ + DBG_TRACE( "OutputDevice::DrawBitmapEx( Point, Size )" ); + + if( ImplIsRecordLayout() ) + return; + + if(rBitmapEx.IsEmpty()) + return; + + if ( mnDrawMode & DRAWMODE_NOBITMAP ) + return; + + // decompose matrix to check rotation and shear + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + rTransformation.decompose(aScale, aTranslate, fRotate, fShearX); + const bool bRotated(!basegfx::fTools::equalZero(fRotate)); + const bool bSheared(!basegfx::fTools::equalZero(fShearX)); + const bool bMirroredX(basegfx::fTools::less(aScale.getX(), 0.0)); + const bool bMirroredY(basegfx::fTools::less(aScale.getY(), 0.0)); + + if(!bRotated && !bSheared && !bMirroredX && !bMirroredY) + { + // with no rotation, shear or mirroring it can be mapped to DrawBitmapEx + // do *not* execute the mirroring here, it's done in the fallback + const Point aDestPt(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY())); + const Size aDestSize(basegfx::fround(aScale.getX()), basegfx::fround(aScale.getY())); + + DrawBitmapEx(aDestPt, aDestSize, rBitmapEx); + return; + } + + // we have rotation,shear or mirror, check if some crazy mode needs the + // created transformed bitmap + const bool bInvert(ROP_INVERT == meRasterOp); + const bool bBitmapChangedColor(mnDrawMode & (DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP)); + const bool bMetafile(mpMetaFile); + const bool bPrinter(OUTDEV_PRINTER == meOutDevType); + bool bDone(false); + const basegfx::B2DHomMatrix aFullTransform(GetViewTransformation() * rTransformation); + const bool bTryDirectPaint(!bInvert && !bBitmapChangedColor && !bMetafile && !bPrinter); + + if(bTryDirectPaint) + { + // try to paint directly + const basegfx::B2DPoint aNull(aFullTransform * basegfx::B2DPoint(0.0, 0.0)); + const basegfx::B2DPoint aTopX(aFullTransform * basegfx::B2DPoint(1.0, 0.0)); + const basegfx::B2DPoint aTopY(aFullTransform * basegfx::B2DPoint(0.0, 1.0)); + SalBitmap* pSalSrcBmp = rBitmapEx.GetBitmap().ImplGetImpBitmap()->ImplGetSalBitmap(); + SalBitmap* pSalAlphaBmp = 0; + + if(rBitmapEx.IsTransparent()) + { + if(rBitmapEx.IsAlpha()) + { + pSalAlphaBmp = rBitmapEx.GetAlpha().ImplGetImpBitmap()->ImplGetSalBitmap(); + } + else + { + pSalAlphaBmp = rBitmapEx.GetMask().ImplGetImpBitmap()->ImplGetSalBitmap(); + } + } + + bDone = mpGraphics->DrawTransformedBitmap( + aNull, + aTopX, + aTopY, + *pSalSrcBmp, + pSalAlphaBmp, + this); + } + + if(!bDone) + { + // take the fallback when no rotate and shear, but mirror (else we would have done this above) + if(!bRotated && !bSheared) + { + // with no rotation or shear it can be mapped to DrawBitmapEx + // do *not* execute the mirroring here, it's done in the fallback + const Point aDestPt(basegfx::fround(aTranslate.getX()), basegfx::fround(aTranslate.getY())); + const Size aDestSize(basegfx::fround(aScale.getX()), basegfx::fround(aScale.getY())); + + DrawBitmapEx(aDestPt, aDestSize, rBitmapEx); + return; + } + + // fallback; create transformed bitmap the hard way (back-transform + // the pixels) and paint + basegfx::B2DRange aTargetRange(0.0, 0.0, 1.0, 1.0); + const double fMaximumArea(bMetafile ? 800000.0 : 200000.0); + const BitmapEx aTransformed(rBitmapEx.getTransformed(aFullTransform, fMaximumArea)); + aTargetRange.transform(rTransformation); + const Point aDestPt(basegfx::fround(aTargetRange.getMinX()), basegfx::fround(aTargetRange.getMinY())); + const Size aDestSize(basegfx::fround(aTargetRange.getWidth()), basegfx::fround(aTargetRange.getHeight())); + + DrawBitmapEx(aDestPt, aDestSize, aTransformed); + } } // ------------------------------------------------------------------ @@ -786,17 +904,20 @@ void OutputDevice::ImplDrawBitmapEx( const Point& rDestPt, const Size& rDestSize const BitmapEx& rBitmapEx, const sal_uLong nAction ) { DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice ); - - BitmapEx aBmpEx( rBitmapEx ); + OSL_ENSURE(TRANSPARENT_NONE != rBitmapEx.GetTransparentType(), "ImplDrawBitmapEx not needed, no transparency in BitmapEx (!)"); if ( mnDrawMode & DRAWMODE_NOBITMAP ) return; - else if ( ROP_INVERT == meRasterOp ) + + if ( ROP_INVERT == meRasterOp ) { DrawRect( Rectangle( rDestPt, rDestSize ) ); return; } - else if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | + + BitmapEx aBmpEx( rBitmapEx ); + + if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP | DRAWMODE_GRAYBITMAP | DRAWMODE_GHOSTEDBITMAP ) ) { if ( mnDrawMode & ( DRAWMODE_BLACKBITMAP | DRAWMODE_WHITEBITMAP ) ) @@ -875,9 +996,11 @@ void OutputDevice::ImplDrawBitmapEx( const Point& rDestPt, const Size& rDestSize aBmp.Replace( aMask, Color( COL_WHITE ) ); ImplPrintTransparent( aBmp, aMask, rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel ); } + return; } - else if( aBmpEx.IsAlpha() ) + + if(aBmpEx.IsAlpha()) { ImplDrawAlpha( aBmpEx.GetBitmap(), aBmpEx.GetAlpha(), rDestPt, rDestSize, rSrcPtPixel, rSrcSizePixel ); return; @@ -885,7 +1008,7 @@ void OutputDevice::ImplDrawBitmapEx( const Point& rDestPt, const Size& rDestSize if( !( !aBmpEx ) ) { - TwoRect aPosAry; + SalTwoRect aPosAry; aPosAry.mnSrcX = rSrcPtPixel.X(); aPosAry.mnSrcY = rSrcPtPixel.Y(); @@ -904,70 +1027,92 @@ void OutputDevice::ImplDrawBitmapEx( const Point& rDestPt, const Size& rDestSize if( nMirrFlags ) aBmpEx.Mirror( nMirrFlags ); - const ImpBitmap* pImpBmp = aBmpEx.ImplGetBitmapImpBitmap(); + const SalBitmap* pSalSrcBmp = aBmpEx.ImplGetBitmapImpBitmap()->ImplGetSalBitmap(); const ImpBitmap* pMaskBmp = aBmpEx.ImplGetMaskImpBitmap(); if ( pMaskBmp ) { - // #4919452# reduce operation area to bounds of - // cliprect. since masked transparency involves - // creation of a large vdev and copying the screen - // content into that (slooow read from framebuffer), - // that should considerably increase performance for - // large bitmaps and small clippings. - - // Note that this optimisation is a workaround for a - // Writer peculiarity, namely, to decompose background - // graphics into myriads of disjunct, tiny - // rectangles. That otherwise kills us here, since for - // transparent output, SAL always prepares the whole - // bitmap, if aPosAry contains the whole bitmap (and - // it's _not_ to blame for that). - - // Note the call to ImplPixelToDevicePixel(), since - // aPosAry already contains the mnOutOff-offsets, they - // also have to be applied to the region - Rectangle aClipRegionBounds( ImplPixelToDevicePixel(maRegion).GetBoundRect() ); - - // TODO: Also respect scaling (that's a bit tricky, - // since the source points have to move fractional - // amounts (which is not possible, thus has to be - // emulated by increases copy area) - // const double nScaleX( aPosAry.mnDestWidth / aPosAry.mnSrcWidth ); - // const double nScaleY( aPosAry.mnDestHeight / aPosAry.mnSrcHeight ); - - // for now, only identity scales allowed - if( !aClipRegionBounds.IsEmpty() && - aPosAry.mnDestWidth == aPosAry.mnSrcWidth && - aPosAry.mnDestHeight == aPosAry.mnSrcHeight ) + SalBitmap* pSalAlphaBmp = pMaskBmp->ImplGetSalBitmap(); + bool bTryDirectPaint(pSalSrcBmp && pSalAlphaBmp); + + if(bTryDirectPaint) { - // now intersect dest rect with clip region - aClipRegionBounds.Intersection( Rectangle( aPosAry.mnDestX, - aPosAry.mnDestY, - aPosAry.mnDestX + aPosAry.mnDestWidth - 1, - aPosAry.mnDestY + aPosAry.mnDestHeight - 1 ) ); - - // Note: I could theoretically optimize away the - // DrawBitmap below, if the region is empty - // here. Unfortunately, cannot rule out that - // somebody relies on the side effects. - if( !aClipRegionBounds.IsEmpty() ) + // only paint direct when no scaling and no MapMode, else the + // more expensive conversions may be done for short-time Bitmap/BitmapEx + // used for buffering only + if(!IsMapMode() && aPosAry.mnSrcWidth == aPosAry.mnDestWidth && aPosAry.mnSrcHeight == aPosAry.mnDestHeight) { - aPosAry.mnSrcX += aClipRegionBounds.Left() - aPosAry.mnDestX; - aPosAry.mnSrcY += aClipRegionBounds.Top() - aPosAry.mnDestY; - aPosAry.mnSrcWidth = aClipRegionBounds.GetWidth(); - aPosAry.mnSrcHeight = aClipRegionBounds.GetHeight(); - - aPosAry.mnDestX = aClipRegionBounds.Left(); - aPosAry.mnDestY = aClipRegionBounds.Top(); - aPosAry.mnDestWidth = aClipRegionBounds.GetWidth(); - aPosAry.mnDestHeight = aClipRegionBounds.GetHeight(); + bTryDirectPaint = false; } } - mpGraphics->DrawBitmap( &aPosAry, *pImpBmp->ImplGetSalBitmap(), - *pMaskBmp->ImplGetSalBitmap(), - this ); + if(bTryDirectPaint && mpGraphics->DrawAlphaBitmap(aPosAry, *pSalSrcBmp, *pSalAlphaBmp, this)) + { + // tried to paint as alpha directly. If tis worked, we are done (except + // alpha, see below) + } + else + { + // #4919452# reduce operation area to bounds of + // cliprect. since masked transparency involves + // creation of a large vdev and copying the screen + // content into that (slooow read from framebuffer), + // that should considerably increase performance for + // large bitmaps and small clippings. + + // Note that this optimisation is a workaround for a + // Writer peculiarity, namely, to decompose background + // graphics into myriads of disjunct, tiny + // rectangles. That otherwise kills us here, since for + // transparent output, SAL always prepares the whole + // bitmap, if aPosAry contains the whole bitmap (and + // it's _not_ to blame for that). + + // Note the call to ImplPixelToDevicePixel(), since + // aPosAry already contains the mnOutOff-offsets, they + // also have to be applied to the region + Rectangle aClipRegionBounds( ImplPixelToDevicePixel(maRegion).GetBoundRect() ); + + // TODO: Also respect scaling (that's a bit tricky, + // since the source points have to move fractional + // amounts (which is not possible, thus has to be + // emulated by increases copy area) + // const double nScaleX( aPosAry.mnDestWidth / aPosAry.mnSrcWidth ); + // const double nScaleY( aPosAry.mnDestHeight / aPosAry.mnSrcHeight ); + + // for now, only identity scales allowed + if( !aClipRegionBounds.IsEmpty() && + aPosAry.mnDestWidth == aPosAry.mnSrcWidth && + aPosAry.mnDestHeight == aPosAry.mnSrcHeight ) + { + // now intersect dest rect with clip region + aClipRegionBounds.Intersection( Rectangle( aPosAry.mnDestX, + aPosAry.mnDestY, + aPosAry.mnDestX + aPosAry.mnDestWidth - 1, + aPosAry.mnDestY + aPosAry.mnDestHeight - 1 ) ); + + // Note: I could theoretically optimize away the + // DrawBitmap below, if the region is empty + // here. Unfortunately, cannot rule out that + // somebody relies on the side effects. + if( !aClipRegionBounds.IsEmpty() ) + { + aPosAry.mnSrcX += aClipRegionBounds.Left() - aPosAry.mnDestX; + aPosAry.mnSrcY += aClipRegionBounds.Top() - aPosAry.mnDestY; + aPosAry.mnSrcWidth = aClipRegionBounds.GetWidth(); + aPosAry.mnSrcHeight = aClipRegionBounds.GetHeight(); + + aPosAry.mnDestX = aClipRegionBounds.Left(); + aPosAry.mnDestY = aClipRegionBounds.Top(); + aPosAry.mnDestWidth = aClipRegionBounds.GetWidth(); + aPosAry.mnDestHeight = aClipRegionBounds.GetHeight(); + } + } + + mpGraphics->DrawBitmap( aPosAry, *pSalSrcBmp, + *pMaskBmp->ImplGetSalBitmap(), + this ); + } // #110958# Paint mask to alpha channel. Luckily, the // black and white representation of the mask maps to @@ -986,7 +1131,7 @@ void OutputDevice::ImplDrawBitmapEx( const Point& rDestPt, const Size& rDestSize } else { - mpGraphics->DrawBitmap( &aPosAry, *pImpBmp->ImplGetSalBitmap(), this ); + mpGraphics->DrawBitmap( aPosAry, *pSalSrcBmp, this ); if( mpAlphaVDev ) { @@ -1132,7 +1277,7 @@ void OutputDevice::ImplDrawMask( const Point& rDestPt, const Size& rDestSize, const ImpBitmap* pImpBmp = rBitmap.ImplGetImpBitmap(); if ( pImpBmp ) { - TwoRect aPosAry; + SalTwoRect aPosAry; aPosAry.mnSrcX = rSrcPtPixel.X(); aPosAry.mnSrcY = rSrcPtPixel.Y(); @@ -1154,11 +1299,11 @@ void OutputDevice::ImplDrawMask( const Point& rDestPt, const Size& rDestSize, { Bitmap aTmp( rBitmap ); aTmp.Mirror( nMirrFlags ); - mpGraphics->DrawMask( &aPosAry, *aTmp.ImplGetImpBitmap()->ImplGetSalBitmap(), + mpGraphics->DrawMask( aPosAry, *aTmp.ImplGetImpBitmap()->ImplGetSalBitmap(), ImplColorToSal( rMaskColor ) , this); } else - mpGraphics->DrawMask( &aPosAry, *pImpBmp->ImplGetSalBitmap(), + mpGraphics->DrawMask( aPosAry, *pImpBmp->ImplGetSalBitmap(), ImplColorToSal( rMaskColor ), this ); } @@ -1299,7 +1444,7 @@ Bitmap OutputDevice::GetBitmap( const Point& rSrcPt, const Size& rSize ) const { if ( ((OutputDevice*)&aVDev)->mpGraphics || ((OutputDevice*)&aVDev)->ImplGetGraphics() ) { - TwoRect aPosAry; + SalTwoRect aPosAry; aPosAry.mnSrcX = nX; aPosAry.mnSrcY = nY; @@ -1311,7 +1456,7 @@ Bitmap OutputDevice::GetBitmap( const Point& rSrcPt, const Size& rSize ) const aPosAry.mnDestHeight = nHeight; if ( (nWidth > 0) && (nHeight > 0) ) - (((OutputDevice*)&aVDev)->mpGraphics)->CopyBits( &aPosAry, mpGraphics, this, this ); + (((OutputDevice*)&aVDev)->mpGraphics)->CopyBits( aPosAry, mpGraphics, this, this ); aBmp = aVDev.GetBitmap( Point(), aVDev.GetOutputSizePixel() ); } @@ -1945,7 +2090,22 @@ void OutputDevice::ImplDrawAlpha( const Bitmap& rBmp, const AlphaMask& rAlpha, static const char* pDisableNative = getenv( "SAL_DISABLE_NATIVE_ALPHA"); // #i83087# Naturally, system alpha blending cannot work with // separate alpha VDev - if( !mpAlphaVDev && !pDisableNative && !bHMirr && !bVMirr ) + bool bTryDirectPaint(!mpAlphaVDev && !pDisableNative && !bHMirr && !bVMirr); + +#ifdef WNT + if(bTryDirectPaint) + { + // only paint direct when no scaling and no MapMode, else the + // more expensive conversions may be done for short-time Bitmap/BitmapEx + // used for buffering only + if(!IsMapMode() && rSrcSizePixel.Width() == aOutSz.Width() && rSrcSizePixel.Height() == aOutSz.Height()) + { + bTryDirectPaint = false; + } + } +#endif + + if(bTryDirectPaint) { Point aRelPt = aOutPt + Point( mnOutOffX, mnOutOffY ); SalTwoRect aTR = { diff --git a/vcl/source/gdi/outmap.cxx b/vcl/source/gdi/outmap.cxx index f8b329549aad..fb8e9de61337 100644 --- a/vcl/source/gdi/outmap.cxx +++ b/vcl/source/gdi/outmap.cxx @@ -875,7 +875,7 @@ void OutputDevice::SetMapMode( const MapMode& rNewMapMode ) mpAlphaVDev->SetMapMode( rNewMapMode ); // Ist Default-MapMode, dann bereche nichts - sal_Bool bOldMap = mbMap; + bool bOldMap = mbMap; mbMap = !rNewMapMode.IsDefault(); if ( mbMap ) { diff --git a/vcl/source/gdi/salgdilayout.cxx b/vcl/source/gdi/salgdilayout.cxx index 12ead6c91029..8ef7ad7338d5 100644 --- a/vcl/source/gdi/salgdilayout.cxx +++ b/vcl/source/gdi/salgdilayout.cxx @@ -95,6 +95,19 @@ bool SalGraphics::drawAlphaBitmap( const SalTwoRect&, // ---------------------------------------------------------------------------- +bool SalGraphics::drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) +{ + // here direct support for transformed bitmaps can be impemented + return false; +} + +// ---------------------------------------------------------------------------- + void SalGraphics::mirror( long& x, const OutputDevice *pOutDev, bool bBack ) const { long w; @@ -583,72 +596,72 @@ void SalGraphics::CopyArea( long nDestX, long nDestY, } copyArea( nDestX, nDestY, nSrcX, nSrcY, nSrcWidth, nSrcHeight, nFlags ); } -void SalGraphics::CopyBits( const SalTwoRect* pPosAry, +void SalGraphics::CopyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics, const OutputDevice *pOutDev, const OutputDevice *pSrcOutDev ) { if( ( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) || (pSrcGraphics && ( (pSrcGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) || (pSrcOutDev && pSrcOutDev->IsRTLEnabled()) ) ) ) { - SalTwoRect pPosAry2 = *pPosAry; + SalTwoRect aPosAry2 = rPosAry; if( (pSrcGraphics && (pSrcGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL)) || (pSrcOutDev && pSrcOutDev->IsRTLEnabled()) ) - mirror( pPosAry2.mnSrcX, pPosAry2.mnSrcWidth, pSrcOutDev ); + mirror( aPosAry2.mnSrcX, aPosAry2.mnSrcWidth, pSrcOutDev ); if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) - mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); - copyBits( &pPosAry2, pSrcGraphics ); + mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); + copyBits( aPosAry2, pSrcGraphics ); } else - copyBits( pPosAry, pSrcGraphics ); + copyBits( rPosAry, pSrcGraphics ); } -void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry, +void SalGraphics::DrawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - SalTwoRect pPosAry2 = *pPosAry; - mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); - drawBitmap( &pPosAry2, rSalBitmap ); + SalTwoRect aPosAry2 = rPosAry; + mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); + drawBitmap( aPosAry2, rSalBitmap ); } else - drawBitmap( pPosAry, rSalBitmap ); + drawBitmap( rPosAry, rSalBitmap ); } -void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry, +void SalGraphics::DrawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - SalTwoRect pPosAry2 = *pPosAry; - mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); - drawBitmap( &pPosAry2, rSalBitmap, nTransparentColor ); + SalTwoRect aPosAry2 = rPosAry; + mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); + drawBitmap( aPosAry2, rSalBitmap, nTransparentColor ); } else - drawBitmap( pPosAry, rSalBitmap, nTransparentColor ); + drawBitmap( rPosAry, rSalBitmap, nTransparentColor ); } -void SalGraphics::DrawBitmap( const SalTwoRect* pPosAry, +void SalGraphics::DrawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - SalTwoRect pPosAry2 = *pPosAry; - mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); - drawBitmap( &pPosAry2, rSalBitmap, rTransparentBitmap ); + SalTwoRect aPosAry2 = rPosAry; + mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); + drawBitmap( aPosAry2, rSalBitmap, rTransparentBitmap ); } else - drawBitmap( pPosAry, rSalBitmap, rTransparentBitmap ); + drawBitmap( rPosAry, rSalBitmap, rTransparentBitmap ); } -void SalGraphics::DrawMask( const SalTwoRect* pPosAry, +void SalGraphics::DrawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor, const OutputDevice *pOutDev ) { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - SalTwoRect pPosAry2 = *pPosAry; - mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); - drawMask( &pPosAry2, rSalBitmap, nMaskColor ); + SalTwoRect aPosAry2 = rPosAry; + mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); + drawMask( aPosAry2, rSalBitmap, nMaskColor ); } else - drawMask( pPosAry, rSalBitmap, nMaskColor ); + drawMask( rPosAry, rSalBitmap, nMaskColor ); } SalBitmap* SalGraphics::GetBitmap( long nX, long nY, long nWidth, long nHeight, const OutputDevice *pOutDev ) { @@ -807,14 +820,40 @@ bool SalGraphics::DrawAlphaBitmap( const SalTwoRect& rPosAry, { if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) { - SalTwoRect pPosAry2 = rPosAry; - mirror( pPosAry2.mnDestX, pPosAry2.mnDestWidth, pOutDev ); - return drawAlphaBitmap( pPosAry2, rSourceBitmap, rAlphaBitmap ); + SalTwoRect aPosAry2 = rPosAry; + mirror( aPosAry2.mnDestX, aPosAry2.mnDestWidth, pOutDev ); + return drawAlphaBitmap( aPosAry2, rSourceBitmap, rAlphaBitmap ); } else return drawAlphaBitmap( rPosAry, rSourceBitmap, rAlphaBitmap ); } +bool SalGraphics::DrawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap, + const OutputDevice* pOutDev) +{ + if( (m_nLayout & SAL_LAYOUT_BIDI_RTL) || (pOutDev && pOutDev->IsRTLEnabled()) ) + { + basegfx::B2DPoint aNull(rNull); + basegfx::B2DPoint aX(rX); + basegfx::B2DPoint aY(rY); + + mirror(aNull, pOutDev); + mirror(aX, pOutDev); + mirror(aY, pOutDev); + + return drawTransformedBitmap(aNull, aX, aY, rSourceBitmap, pAlphaBitmap); + } + else + { + return drawTransformedBitmap(rNull, rX, rY, rSourceBitmap, pAlphaBitmap); + } +} + bool SalGraphics::DrawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency, const OutputDevice *pOutDev ) { diff --git a/vcl/source/gdi/salmisc.cxx b/vcl/source/gdi/salmisc.cxx index 7d9623fbdfb6..817aa90e13da 100644 --- a/vcl/source/gdi/salmisc.cxx +++ b/vcl/source/gdi/salmisc.cxx @@ -288,8 +288,9 @@ static void ImplTCToPAL( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffe // - StretchAndConvert - // --------------------- -BitmapBuffer* StretchAndConvert( const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect, - sal_uLong nDstBitmapFormat, BitmapPalette* pDstPal, ColorMask* pDstMask ) +BitmapBuffer* StretchAndConvert( + const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect, + sal_uLong nDstBitmapFormat, const BitmapPalette* pDstPal, const ColorMask* pDstMask ) { FncGetPixel pFncGetPixel; FncSetPixel pFncSetPixel; diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx index 8a28dd15fb93..7ba8cd1dfdc1 100644 --- a/vcl/source/gdi/virdev.cxx +++ b/vcl/source/gdi/virdev.cxx @@ -274,7 +274,7 @@ sal_Bool VirtualDevice::ImplSetOutputSizePixel( const Size& rNewSize, sal_Bool b aPosAry.mnDestWidth = nWidth; aPosAry.mnDestHeight = nHeight; - pGraphics->CopyBits( &aPosAry, mpGraphics, this, this ); + pGraphics->CopyBits( aPosAry, mpGraphics, this, this ); pNewVirDev->ReleaseGraphics( pGraphics ); ImplReleaseGraphics(); pSVData->mpDefInst->DestroyVirtualDevice( mpVirDev ); diff --git a/vcl/unx/generic/gdi/pspgraphics.cxx b/vcl/unx/generic/gdi/pspgraphics.cxx index f0a010d815c5..0d77cf40456d 100644 --- a/vcl/unx/generic/gdi/pspgraphics.cxx +++ b/vcl/unx/generic/gdi/pspgraphics.cxx @@ -469,7 +469,7 @@ sal_Bool PspGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, void return m_pPrinterGfx->DrawEPS( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ), pPtr, nSize ); } -void PspGraphics::copyBits( const SalTwoRect*, +void PspGraphics::copyBits( const SalTwoRect&, SalGraphics* ) { DBG_ERROR( "Error: PrinterGfx::CopyBits() not implemented" ); @@ -480,12 +480,12 @@ void PspGraphics::copyArea ( long,long,long,long,long,long,sal_uInt16 ) DBG_ERROR( "Error: PrinterGfx::CopyArea() not implemented" ); } -void PspGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ) +void PspGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) { - Rectangle aSrc (Point(pPosAry->mnSrcX, pPosAry->mnSrcY), - Size(pPosAry->mnSrcWidth, pPosAry->mnSrcHeight)); - Rectangle aDst (Point(pPosAry->mnDestX, pPosAry->mnDestY), - Size(pPosAry->mnDestWidth, pPosAry->mnDestHeight)); + Rectangle aSrc (Point(rPosAry.mnSrcX, rPosAry.mnSrcY), + Size(rPosAry.mnSrcWidth, rPosAry.mnSrcHeight)); + Rectangle aDst (Point(rPosAry.mnDestX, rPosAry.mnDestY), + Size(rPosAry.mnDestWidth, rPosAry.mnDestHeight)); BitmapBuffer* pBuffer= const_cast<SalBitmap&>(rSalBitmap).AcquireBuffer(sal_True); @@ -495,21 +495,21 @@ void PspGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBi const_cast<SalBitmap&>(rSalBitmap).ReleaseBuffer (pBuffer, sal_True); } -void PspGraphics::drawBitmap( const SalTwoRect*, +void PspGraphics::drawBitmap( const SalTwoRect&, const SalBitmap&, const SalBitmap& ) { DBG_ERROR("Error: no PrinterGfx::DrawBitmap() for transparent bitmap"); } -void PspGraphics::drawBitmap( const SalTwoRect*, +void PspGraphics::drawBitmap( const SalTwoRect&, const SalBitmap&, SalColor ) { DBG_ERROR("Error: no PrinterGfx::DrawBitmap() for transparent color"); } -void PspGraphics::drawMask( const SalTwoRect*, +void PspGraphics::drawMask( const SalTwoRect&, const SalBitmap &, SalColor ) { @@ -1493,6 +1493,18 @@ bool PspGraphics::drawAlphaBitmap( const SalTwoRect&, return false; } +bool PspGraphics::drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) +{ + // here direct support for transformed bitmaps can be impemented + (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap; + return false; +} + bool PspGraphics::drawAlphaRect( long, long, long, long, sal_uInt8 ) { return false; diff --git a/vcl/unx/generic/gdi/salgdi2.cxx b/vcl/unx/generic/gdi/salgdi2.cxx index 2f283569a71e..8f384387e389 100644 --- a/vcl/unx/generic/gdi/salgdi2.cxx +++ b/vcl/unx/generic/gdi/salgdi2.cxx @@ -457,17 +457,17 @@ void X11SalGraphics::YieldGraphicsExpose() } while( aEvent.xgraphicsexpose.count != 0 ); } -void X11SalGraphics::copyBits( const SalTwoRect *pPosAry, +void X11SalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics *pSSrcGraphics ) { X11SalGraphics* pSrcGraphics = pSSrcGraphics ? static_cast<X11SalGraphics*>(pSSrcGraphics) : this; - if( pPosAry->mnSrcWidth <= 0 - || pPosAry->mnSrcHeight <= 0 - || pPosAry->mnDestWidth <= 0 - || pPosAry->mnDestHeight <= 0 ) + if( rPosAry.mnSrcWidth <= 0 + || rPosAry.mnSrcHeight <= 0 + || rPosAry.mnDestWidth <= 0 + || rPosAry.mnDestHeight <= 0 ) { return; } @@ -500,8 +500,8 @@ void X11SalGraphics::copyBits( const SalTwoRect *pPosAry, n = 0; if( n == 2 - && pPosAry->mnSrcWidth == pPosAry->mnDestWidth - && pPosAry->mnSrcHeight == pPosAry->mnDestHeight + && rPosAry.mnSrcWidth == rPosAry.mnDestWidth + && rPosAry.mnSrcHeight == rPosAry.mnDestHeight ) { // #i60699# Need to generate graphics exposures (to repaint @@ -519,7 +519,7 @@ void X11SalGraphics::copyBits( const SalTwoRect *pPosAry, { Pixmap hPixmap = XCreatePixmap( GetXDisplay(), pSrcGraphics->GetDrawable(), // source - pPosAry->mnSrcWidth, pPosAry->mnSrcHeight, + rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, pSrcGraphics->GetBitCount() ); pCopyGC = GetDisplay()->GetCopyGC( m_nScreen ); @@ -533,16 +533,16 @@ void X11SalGraphics::copyBits( const SalTwoRect *pPosAry, pSrcGraphics->GetDrawable(), // source hPixmap, // destination pCopyGC, // no clipping - pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcWidth, pPosAry->mnSrcHeight, + rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, 0, 0 ); // destination XCopyArea( GetXDisplay(), hPixmap, // source GetDrawable(), // destination GetInvertGC(), // destination clipping 0, 0, // source - pPosAry->mnSrcWidth, pPosAry->mnSrcHeight, - pPosAry->mnDestX, pPosAry->mnDestY ); + rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, + rPosAry.mnDestX, rPosAry.mnDestY ); XFreePixmap( GetXDisplay(), hPixmap ); } else @@ -558,9 +558,9 @@ void X11SalGraphics::copyBits( const SalTwoRect *pPosAry, pSrcGraphics->GetDrawable(), // source GetDrawable(), // destination pCopyGC, // destination clipping - pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcWidth, pPosAry->mnSrcHeight, - pPosAry->mnDestX, pPosAry->mnDestY ); + rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcWidth, rPosAry.mnSrcHeight, + rPosAry.mnDestX, rPosAry.mnDestY ); } if( bNeedGraphicsExposures ) @@ -578,10 +578,10 @@ void X11SalGraphics::copyBits( const SalTwoRect *pPosAry, // #i60699# No chance to handle graphics exposures - we copy // to a temp bitmap first, into which no repaints are // technically possible. - SalBitmap *pDDB = pSrcGraphics->getBitmap( pPosAry->mnSrcX, - pPosAry->mnSrcY, - pPosAry->mnSrcWidth, - pPosAry->mnSrcHeight ); + SalBitmap *pDDB = pSrcGraphics->getBitmap( rPosAry.mnSrcX, + rPosAry.mnSrcY, + rPosAry.mnSrcWidth, + rPosAry.mnSrcHeight ); if( !pDDB ) { @@ -589,10 +589,10 @@ void X11SalGraphics::copyBits( const SalTwoRect *pPosAry, return; } - SalTwoRect aPosAry( *pPosAry ); + SalTwoRect aPosAry( rPosAry ); aPosAry.mnSrcX = 0, aPosAry.mnSrcY = 0; - drawBitmap( &aPosAry, *pDDB ); + drawBitmap( aPosAry, *pDDB ); delete pDDB; } @@ -620,11 +620,11 @@ void X11SalGraphics::copyArea ( long nDestX, long nDestY, aPosAry.mnSrcWidth = nSrcWidth; aPosAry.mnSrcHeight = nSrcHeight; - copyBits ( &aPosAry, 0 ); + copyBits ( aPosAry, 0 ); } // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ) +void X11SalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) { const SalDisplay* pSalDisp = GetDisplay(); Display* pXDisp = pSalDisp->GetDisplay(); @@ -643,7 +643,7 @@ void X11SalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSa XChangeGC( pXDisp, aGC, nValues, &aNewVal ); } - static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aDrawable, m_nScreen, nDepth, *pPosAry, aGC ); + static_cast<const X11SalBitmap&>(rSalBitmap).ImplDraw( aDrawable, m_nScreen, nDepth, rPosAry, aGC ); if( rSalBitmap.GetBitCount() == 1 ) XChangeGC( pXDisp, aGC, nValues, &aOldVal ); @@ -652,7 +652,7 @@ void X11SalGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSa // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::drawBitmap( const SalTwoRect* pPosAry, +void X11SalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSrcBitmap, const SalBitmap& rMaskBitmap ) { @@ -665,15 +665,15 @@ void X11SalGraphics::drawBitmap( const SalTwoRect* pPosAry, int nMaskFormat = pAlphaBuffer->mnFormat; const_cast<SalBitmap&>(rMaskBitmap).ReleaseBuffer( pAlphaBuffer, sal_True ); if( nMaskFormat == BMP_FORMAT_8BIT_PAL ) - drawAlphaBitmap( *pPosAry, rSrcBitmap, rMaskBitmap ); + drawAlphaBitmap( rPosAry, rSrcBitmap, rMaskBitmap ); } - drawMaskedBitmap( pPosAry, rSrcBitmap, rMaskBitmap ); + drawMaskedBitmap( rPosAry, rSrcBitmap, rMaskBitmap ); } // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry, +void X11SalGraphics::drawMaskedBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransBitmap ) { @@ -687,10 +687,10 @@ void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry, const sal_uInt16 nDepth( m_pVDev ? m_pVDev->GetDepth() : pSalDisp->GetVisual( m_nScreen ).GetDepth() ); - Pixmap aFG( XCreatePixmap( pXDisp, aDrawable, pPosAry->mnDestWidth, - pPosAry->mnDestHeight, nDepth ) ); - Pixmap aBG( XCreatePixmap( pXDisp, aDrawable, pPosAry->mnDestWidth, - pPosAry->mnDestHeight, nDepth ) ); + Pixmap aFG( XCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth, + rPosAry.mnDestHeight, nDepth ) ); + Pixmap aBG( XCreatePixmap( pXDisp, aDrawable, rPosAry.mnDestWidth, + rPosAry.mnDestHeight, nDepth ) ); if( aFG && aBG ) { @@ -699,7 +699,7 @@ void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry, const SalColormap& rColMap = pSalDisp->GetColormap( m_nScreen ); const int nBlack = rColMap.GetBlackPixel(), nWhite = rColMap.GetWhitePixel(); const int nValues = GCFunction | GCForeground | GCBackground; - SalTwoRect aTmpRect( *pPosAry ); aTmpRect.mnDestX = aTmpRect.mnDestY = 0; + SalTwoRect aTmpRect( rPosAry ); aTmpRect.mnDestX = aTmpRect.mnDestY = 0; // draw paint bitmap in pixmap #1 aValues.function = GXcopy, aValues.foreground = nWhite, aValues.background = nBlack; @@ -709,8 +709,8 @@ void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry, // draw background in pixmap #2 XCopyArea( pXDisp, aDrawable, aBG, aTmpGC, - pPosAry->mnDestX, pPosAry->mnDestY, - pPosAry->mnDestWidth, pPosAry->mnDestHeight, + rPosAry.mnDestX, rPosAry.mnDestY, + rPosAry.mnDestWidth, rPosAry.mnDestHeight, 0, 0 ); DBG_TESTTRANS( aBG ); @@ -738,7 +738,7 @@ void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry, XChangeGC( pXDisp, aTmpGC, nValues, &aValues ); XCopyArea( pXDisp, aFG, aBG, aTmpGC, 0, 0, - pPosAry->mnDestWidth, pPosAry->mnDestHeight, + rPosAry.mnDestWidth, rPosAry.mnDestHeight, 0, 0 ); DBG_TESTTRANS( aBG ); @@ -749,8 +749,8 @@ void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry, // copy pixmap #2 (result) to background XCopyArea( pXDisp, aBG, aDrawable, GetCopyGC(), 0, 0, - pPosAry->mnDestWidth, pPosAry->mnDestHeight, - pPosAry->mnDestX, pPosAry->mnDestY ); + rPosAry.mnDestWidth, rPosAry.mnDestHeight, + rPosAry.mnDestX, rPosAry.mnDestY ); DBG_TESTTRANS( aBG ); @@ -760,7 +760,7 @@ void X11SalGraphics::drawMaskedBitmap( const SalTwoRect* pPosAry, XFlush( pXDisp ); } else - drawBitmap( pPosAry, rSalBitmap ); + drawBitmap( rPosAry, rSalBitmap ); if( aFG ) XFreePixmap( pXDisp, aFG ); @@ -902,6 +902,19 @@ bool X11SalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, } // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= +bool X11SalGraphics::drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) +{ + // here direct support for transformed bitmaps can be impemented + (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap; + return false; +} + +// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= bool X11SalGraphics::drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ) { @@ -935,7 +948,7 @@ bool X11SalGraphics::drawAlphaRect( long nX, long nY, long nWidth, } // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::drawBitmap( const SalTwoRect*, +void X11SalGraphics::drawBitmap( const SalTwoRect&, const SalBitmap&, SalColor ) { @@ -943,7 +956,7 @@ void X11SalGraphics::drawBitmap( const SalTwoRect*, } // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -void X11SalGraphics::drawMask( const SalTwoRect* pPosAry, +void X11SalGraphics::drawMask( const SalTwoRect& rPosAry, const SalBitmap &rSalBitmap, SalColor nMaskColor ) { @@ -951,12 +964,12 @@ void X11SalGraphics::drawMask( const SalTwoRect* pPosAry, Display* pXDisp = pSalDisp->GetDisplay(); Drawable aDrawable( GetDrawable() ); Pixmap aStipple( XCreatePixmap( pXDisp, aDrawable, - pPosAry->mnDestWidth, - pPosAry->mnDestHeight, 1 ) ); + rPosAry.mnDestWidth, + rPosAry.mnDestHeight, 1 ) ); if( aStipple ) { - SalTwoRect aTwoRect( *pPosAry ); aTwoRect.mnDestX = aTwoRect.mnDestY = 0; + SalTwoRect aTwoRect( rPosAry ); aTwoRect.mnDestX = aTwoRect.mnDestY = 0; GC aTmpGC; XGCValues aValues; @@ -970,19 +983,19 @@ void X11SalGraphics::drawMask( const SalTwoRect* pPosAry, // Set stipple and draw rectangle GC aStippleGC( GetStippleGC() ); - int nX = pPosAry->mnDestX, nY = pPosAry->mnDestY; + int nX = rPosAry.mnDestX, nY = rPosAry.mnDestY; XSetStipple( pXDisp, aStippleGC, aStipple ); XSetTSOrigin( pXDisp, aStippleGC, nX, nY ); XSetForeground( pXDisp, aStippleGC, GetPixel( nMaskColor ) ); XFillRectangle( pXDisp, aDrawable, aStippleGC, nX, nY, - pPosAry->mnDestWidth, pPosAry->mnDestHeight ); + rPosAry.mnDestWidth, rPosAry.mnDestHeight ); XFreePixmap( pXDisp, aStipple ); XFlush( pXDisp ); } else - drawBitmap( pPosAry, rSalBitmap ); + drawBitmap( rPosAry, rSalBitmap ); } // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= diff --git a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx index eac3312a3a7f..3e265d59063e 100644 --- a/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx +++ b/vcl/unx/gtk/gdi/salnativewidgets-gtk.cxx @@ -484,7 +484,7 @@ bool GtkSalGraphics::setClipRegion( const Region& i_rClip ) return bRet; } -void GtkSalGraphics::copyBits( const SalTwoRect* pPosAry, +void GtkSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) { GtkSalFrame* pFrame = GetGtkFrame(); @@ -502,7 +502,7 @@ void GtkSalGraphics::copyBits( const SalTwoRect* pPosAry, None ); } } - X11SalGraphics::copyBits( pPosAry, pSrcGraphics ); + X11SalGraphics::copyBits( rPosAry, pSrcGraphics ); if( pFrame && pFrame->getBackgroundPixmap() != None ) XSetWindowBackgroundPixmap( pFrame->getDisplay()->GetDisplay(), aWin, diff --git a/vcl/unx/headless/svpgdi.cxx b/vcl/unx/headless/svpgdi.cxx index 5360e71a41ea..75755181a6b8 100644 --- a/vcl/unx/headless/svpgdi.cxx +++ b/vcl/unx/headless/svpgdi.cxx @@ -75,6 +75,18 @@ bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect&, const SalBitmap& /*rSou return false; } +bool SvpSalGraphics::drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) +{ + // here direct support for transformed bitmaps can be impemented + (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap; + return false; +} + bool SvpSalGraphics::drawAlphaRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/, sal_uInt8 /*nTransparency*/ ) { // TODO(P3) implement alpha blending @@ -455,73 +467,72 @@ void SvpSalGraphics::copyArea( long nDestX, dbgOut( m_aDevice ); } -void SvpSalGraphics::copyBits( const SalTwoRect* pPosAry, +void SvpSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) { SvpSalGraphics* pSrc = pSrcGraphics ? static_cast<SvpSalGraphics*>(pSrcGraphics) : this; - B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcX+pPosAry->mnSrcWidth, - pPosAry->mnSrcY+pPosAry->mnSrcHeight ); - B2IRange aDestRect( pPosAry->mnDestX, pPosAry->mnDestY, - pPosAry->mnDestX+pPosAry->mnDestWidth, - pPosAry->mnDestY+pPosAry->mnDestHeight ); + B2IRange aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcX+rPosAry.mnSrcWidth, + rPosAry.mnSrcY+rPosAry.mnSrcHeight ); + B2IRange aDestRect( rPosAry.mnDestX, rPosAry.mnDestY, + rPosAry.mnDestX+rPosAry.mnDestWidth, + rPosAry.mnDestY+rPosAry.mnDestHeight ); m_aDevice->drawBitmap( pSrc->m_aOrigDevice, aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap ); dbgOut( m_aDevice ); } -void SvpSalGraphics::drawBitmap( const SalTwoRect* pPosAry, - const SalBitmap& rSalBitmap ) +void SvpSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) { const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap); - B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcX+pPosAry->mnSrcWidth, - pPosAry->mnSrcY+pPosAry->mnSrcHeight ); - B2IRange aDestRect( pPosAry->mnDestX, pPosAry->mnDestY, - pPosAry->mnDestX+pPosAry->mnDestWidth, - pPosAry->mnDestY+pPosAry->mnDestHeight ); + B2IRange aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcX+rPosAry.mnSrcWidth, + rPosAry.mnSrcY+rPosAry.mnSrcHeight ); + B2IRange aDestRect( rPosAry.mnDestX, rPosAry.mnDestY, + rPosAry.mnDestX+rPosAry.mnDestWidth, + rPosAry.mnDestY+rPosAry.mnDestHeight ); m_aDevice->drawBitmap( rSrc.getBitmap(), aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap ); dbgOut( m_aDevice ); } -void SvpSalGraphics::drawBitmap( const SalTwoRect*, +void SvpSalGraphics::drawBitmap( const SalTwoRect&, const SalBitmap&, SalColor ) { // SNI, as in X11 plugin } -void SvpSalGraphics::drawBitmap( const SalTwoRect* pPosAry, +void SvpSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ) { const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap); const SvpSalBitmap& rSrcTrans = static_cast<const SvpSalBitmap&>(rTransparentBitmap); - B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcX+pPosAry->mnSrcWidth, - pPosAry->mnSrcY+pPosAry->mnSrcHeight ); - B2IRange aDestRect( pPosAry->mnDestX, pPosAry->mnDestY, - pPosAry->mnDestX+pPosAry->mnDestWidth, - pPosAry->mnDestY+pPosAry->mnDestHeight ); + B2IRange aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcX+rPosAry.mnSrcWidth, + rPosAry.mnSrcY+rPosAry.mnSrcHeight ); + B2IRange aDestRect( rPosAry.mnDestX, rPosAry.mnDestY, + rPosAry.mnDestX+rPosAry.mnDestWidth, + rPosAry.mnDestY+rPosAry.mnDestHeight ); m_aDevice->drawMaskedBitmap( rSrc.getBitmap(), rSrcTrans.getBitmap(), aSrcRect, aDestRect, DrawMode_PAINT, m_aClipMap ); dbgOut( m_aDevice ); } -void SvpSalGraphics::drawMask( const SalTwoRect* pPosAry, +void SvpSalGraphics::drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ) { const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap); - B2IRange aSrcRect( pPosAry->mnSrcX, pPosAry->mnSrcY, - pPosAry->mnSrcX+pPosAry->mnSrcWidth, - pPosAry->mnSrcY+pPosAry->mnSrcHeight ); - B2IPoint aDestPoint( pPosAry->mnDestX, pPosAry->mnDestY ); + B2IRange aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY, + rPosAry.mnSrcX+rPosAry.mnSrcWidth, + rPosAry.mnSrcY+rPosAry.mnSrcHeight ); + B2IPoint aDestPoint( rPosAry.mnDestX, rPosAry.mnDestY ); // BitmapDevice::drawMaskedColor works with 0==transparent, // 255==opaque. drawMask() semantic is the other way // around. Therefore, invert mask. BitmapDeviceSharedPtr aCopy = - cloneBitmapDevice( B2IVector( pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ), + cloneBitmapDevice( B2IVector( rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ), rSrc.getBitmap() ); basebmp::Color aBgColor( COL_WHITE ); aCopy->clear(aBgColor); @@ -529,7 +540,7 @@ void SvpSalGraphics::drawMask( const SalTwoRect* pPosAry, aCopy->drawMaskedColor( aFgColor, rSrc.getBitmap(), aSrcRect, B2IPoint() ); basebmp::Color aColor( nMaskColor ); - B2IRange aSrcRect2( 0, 0, pPosAry->mnSrcWidth, pPosAry->mnSrcHeight ); + B2IRange aSrcRect2( 0, 0, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ); m_aDevice->drawMaskedColor( aColor, aCopy, aSrcRect, aDestPoint, m_aClipMap ); dbgOut( m_aDevice ); } diff --git a/vcl/unx/headless/svpgdi.hxx b/vcl/unx/headless/svpgdi.hxx index f36e72aa4c19..ffa3feb8f084 100644 --- a/vcl/unx/headless/svpgdi.hxx +++ b/vcl/unx/headless/svpgdi.hxx @@ -50,6 +50,12 @@ class SvpSalGraphics : public SalGraphics protected: virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + virtual bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap); virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); public: @@ -144,17 +150,17 @@ public: long nSrcWidth, long nSrcHeight, sal_uInt16 nFlags ); - virtual void copyBits( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ); - virtual void drawMask( const SalTwoRect* pPosAry, + virtual void drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ); virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ); diff --git a/vcl/unx/headless/svppspgraphics.cxx b/vcl/unx/headless/svppspgraphics.cxx index bcf938909538..abd5e68097be 100644 --- a/vcl/unx/headless/svppspgraphics.cxx +++ b/vcl/unx/headless/svppspgraphics.cxx @@ -175,6 +175,18 @@ bool PspGraphics::drawAlphaBitmap( const SalTwoRect&, const SalBitmap& /*rSource return false; } +bool PspGraphics::drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap) +{ + // here direct support for transformed bitmaps can be impemented + (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap; + return false; +} + bool PspGraphics::drawAlphaRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/, sal_uInt8 /*nTransparency*/ ) { return false; @@ -391,7 +403,7 @@ sal_Bool PspGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, void return m_pPrinterGfx->DrawEPS( Rectangle( Point( nX, nY ), Size( nWidth, nHeight ) ), pPtr, nSize ); } -void PspGraphics::copyBits( const SalTwoRect* /*pPosAry*/, +void PspGraphics::copyBits( const SalTwoRect& /*rPosAry*/, SalGraphics* /*pSSrcGraphics*/ ) { DBG_ERROR( "Error: PrinterGfx::CopyBits() not implemented" ); @@ -405,12 +417,12 @@ void PspGraphics::copyArea ( long /*nDestX*/, long /*nDestY*/, DBG_ERROR( "Error: PrinterGfx::CopyArea() not implemented" ); } -void PspGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBitmap ) +void PspGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) { - Rectangle aSrc (Point(pPosAry->mnSrcX, pPosAry->mnSrcY), - Size(pPosAry->mnSrcWidth, pPosAry->mnSrcHeight)); - Rectangle aDst (Point(pPosAry->mnDestX, pPosAry->mnDestY), - Size(pPosAry->mnDestWidth, pPosAry->mnDestHeight)); + Rectangle aSrc (Point(rPosAry.mnSrcX, rPosAry.mnSrcY), + Size(rPosAry.mnSrcWidth, rPosAry.mnSrcHeight)); + Rectangle aDst (Point(rPosAry.mnDestX, rPosAry.mnDestY), + Size(rPosAry.mnDestWidth, rPosAry.mnDestHeight)); const SvpSalBitmap* pBmp = dynamic_cast<const SvpSalBitmap*>(&rSalBitmap); if( pBmp ) @@ -420,21 +432,21 @@ void PspGraphics::drawBitmap( const SalTwoRect* pPosAry, const SalBitmap& rSalBi } } -void PspGraphics::drawBitmap( const SalTwoRect* /*pPosAry*/, +void PspGraphics::drawBitmap( const SalTwoRect& /*pPosAry*/, const SalBitmap& /*rSalBitmap*/, const SalBitmap& /*rTransBitmap*/ ) { DBG_ERROR("Error: no PrinterGfx::DrawBitmap() for transparent bitmap"); } -void PspGraphics::drawBitmap( const SalTwoRect* /*pPosAry*/, +void PspGraphics::drawBitmap( const SalTwoRect& /*pPosAry*/, const SalBitmap& /*rSalBitmap*/, SalColor /*nTransparentColor*/ ) { DBG_ERROR("Error: no PrinterGfx::DrawBitmap() for transparent color"); } -void PspGraphics::drawMask( const SalTwoRect* /*pPosAry*/, +void PspGraphics::drawMask( const SalTwoRect& /*rPosAry*/, const SalBitmap& /*rSalBitmap*/, SalColor /*nMaskColor*/ ) { diff --git a/vcl/unx/headless/svppspgraphics.hxx b/vcl/unx/headless/svppspgraphics.hxx index f8a4d182f369..74ea978511ac 100644 --- a/vcl/unx/headless/svppspgraphics.hxx +++ b/vcl/unx/headless/svppspgraphics.hxx @@ -51,6 +51,12 @@ class PspGraphics : public SalGraphics protected: virtual bool drawAlphaBitmap( const SalTwoRect&, const SalBitmap& rSourceBitmap, const SalBitmap& rAlphaBitmap ); + virtual bool drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + const SalBitmap& rSourceBitmap, + const SalBitmap* pAlphaBitmap); virtual bool drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ); public: @@ -163,17 +169,17 @@ public: long nSrcWidth, long nSrcHeight, sal_uInt16 nFlags ); - virtual void copyBits( const SalTwoRect* pPosAry, + virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nTransparentColor ); - virtual void drawBitmap( const SalTwoRect* pPosAry, + virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, const SalBitmap& rTransparentBitmap ); - virtual void drawMask( const SalTwoRect* pPosAry, + virtual void drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap, SalColor nMaskColor ); virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ); diff --git a/vcl/win/source/gdi/salbmp.cxx b/vcl/win/source/gdi/salbmp.cxx index 00ccab05be18..20e60e8c276b 100644 --- a/vcl/win/source/gdi/salbmp.cxx +++ b/vcl/win/source/gdi/salbmp.cxx @@ -19,26 +19,32 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" #include <tools/svwin.h> - #include <vcl/bitmap.hxx> // for BitmapSystemData #include <vcl/salbtype.hxx> - #include <win/wincomp.hxx> #include <win/salgdi.h> #include <win/saldata.hxx> #include <win/salbmp.h> - #include <string.h> +#include <vcl/timer.hxx> +#include <comphelper/broadcasthelper.hxx> +#include <map> + +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +#include <GdiPlus.h> -// ----------- +// ------------------------------------------------------------------ // - Inlines - -// ----------- inline void ImplSetPixel4( const HPBYTE pScanline, long nX, const BYTE cIndex ) { @@ -48,14 +54,139 @@ inline void ImplSetPixel4( const HPBYTE pScanline, long nX, const BYTE cIndex ) ( rByte &= 0x0f, rByte |= ( cIndex << 4 ) ); } -// ---------------- +// ------------------------------------------------------------------ +// Helper class to manage Gdiplus::Bitmap instances inside of +// WinSalBitmap + +struct Comparator +{ + bool operator()(WinSalBitmap* pA, WinSalBitmap* pB) const + { + return pA < pB; + } +}; + +typedef ::std::map< WinSalBitmap*, sal_uInt32, Comparator > EntryMap; +static const sal_uInt32 nDefaultCycles(60); + +class GdiPlusBuffer : protected comphelper::OBaseMutex, public Timer +{ +private: + EntryMap maEntries; + +public: + GdiPlusBuffer() + : Timer(), + maEntries() + { + SetTimeout(1000); + Stop(); + } + + ~GdiPlusBuffer() + { + Stop(); + } + + void addEntry(WinSalBitmap& rEntry) + { + ::osl::MutexGuard aGuard(m_aMutex); + EntryMap::iterator aFound = maEntries.find(&rEntry); + + if(aFound == maEntries.end()) + { + if(maEntries.empty()) + { + Start(); + } + + maEntries[&rEntry] = nDefaultCycles; + } + } + + void remEntry(WinSalBitmap& rEntry) + { + ::osl::MutexGuard aGuard(m_aMutex); + EntryMap::iterator aFound = maEntries.find(&rEntry); + + if(aFound != maEntries.end()) + { + maEntries.erase(aFound); + + if(maEntries.empty()) + { + Stop(); + } + } + } + + void touchEntry(WinSalBitmap& rEntry) + { + ::osl::MutexGuard aGuard(m_aMutex); + EntryMap::iterator aFound = maEntries.find(&rEntry); + + if(aFound != maEntries.end()) + { + aFound->second = nDefaultCycles; + } + } + + // from parent Timer + virtual void Timeout() + { + ::osl::MutexGuard aGuard(m_aMutex); + EntryMap::iterator aIter(maEntries.begin()); + + while(aIter != maEntries.end()) + { + if(aIter->second) + { + aIter->second--; + aIter++; + } + else + { + EntryMap::iterator aDelete(aIter); + WinSalBitmap* pSource = aDelete->first; + aIter++; + maEntries.erase(aDelete); + + if(maEntries.empty()) + { + Stop(); + } + + // delete at WinSalBitmap after entry is removed; this + // way it would not hurt to call remEntry from there, too + if(pSource->maGdiPlusBitmap.get()) + { + pSource->maGdiPlusBitmap.reset(); + } + } + } + + if(!maEntries.empty()) + { + Start(); + } + } +}; + +// ------------------------------------------------------------------ +// Global instance of GdiPlusBuffer which manages Gdiplus::Bitmap +// instances + +static GdiPlusBuffer aGdiPlusBuffer; + +// ------------------------------------------------------------------ // - WinSalBitmap - -// ---------------- -WinSalBitmap::WinSalBitmap() : - mhDIB ( 0 ), - mhDDB ( 0 ), - mnBitCount ( 0 ) +WinSalBitmap::WinSalBitmap() +: maSize(), + mhDIB(0), + mhDDB(0), + maGdiPlusBitmap(), + mnBitCount(0) { } @@ -68,6 +199,292 @@ WinSalBitmap::~WinSalBitmap() // ------------------------------------------------------------------ +void WinSalBitmap::Destroy() +{ + if(maGdiPlusBitmap.get()) + { + aGdiPlusBuffer.remEntry(*this); + } + + if( mhDIB ) + GlobalFree( mhDIB ); + else if( mhDDB ) + DeleteObject( mhDDB ); + + maSize = Size(); + mnBitCount = 0; +} + +// ------------------------------------------------------------------ + +GdiPlusBmpPtr WinSalBitmap::ImplGetGdiPlusBitmap(const WinSalBitmap* pAlphaSource) const +{ + if(maGdiPlusBitmap.get()) + { + aGdiPlusBuffer.touchEntry(const_cast< WinSalBitmap& >(*this)); + } + else + { + if(maSize.Width() > 0 && maSize.Height() > 0) + { + WinSalBitmap* pThat = const_cast< WinSalBitmap* >(this); + + if(pAlphaSource) + { + pThat->maGdiPlusBitmap.reset(pThat->ImplCreateGdiPlusBitmap(*pAlphaSource)); + } + else + { + pThat->maGdiPlusBitmap.reset(pThat->ImplCreateGdiPlusBitmap()); + } + + if(maGdiPlusBitmap.get()) + { + aGdiPlusBuffer.addEntry(*pThat); + } + } + } + + return maGdiPlusBitmap; +} + +// ------------------------------------------------------------------ + +Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap() +{ + Gdiplus::Bitmap* pRetval(0); + WinSalBitmap* pSalRGB = const_cast< WinSalBitmap* >(this); + WinSalBitmap* pExtraWinSalRGB = 0; + + if(!pSalRGB->ImplGethDIB()) + { + // we need DIB for success with AcquireBuffer, create a replacement WinSalBitmap + pExtraWinSalRGB = new WinSalBitmap(); + pExtraWinSalRGB->Create(*pSalRGB, pSalRGB->GetBitCount()); + pSalRGB = pExtraWinSalRGB; + } + + BitmapBuffer* pRGB = pSalRGB->AcquireBuffer(true); + BitmapBuffer* pExtraRGB = 0; + + if(pRGB && BMP_FORMAT_24BIT_TC_BGR != (pRGB->mnFormat & ~BMP_FORMAT_TOP_DOWN)) + { + // convert source bitmap to BMP_FORMAT_24BIT_TC_BGR format if not yet in that format + SalTwoRect aSalTwoRect; + + aSalTwoRect.mnSrcX = aSalTwoRect.mnSrcY = aSalTwoRect.mnDestX = aSalTwoRect.mnDestY = 0; + aSalTwoRect.mnSrcWidth = aSalTwoRect.mnDestWidth = pRGB->mnWidth; + aSalTwoRect.mnSrcHeight = aSalTwoRect.mnDestHeight = pRGB->mnHeight; + + pExtraRGB = StretchAndConvert( + *pRGB, + aSalTwoRect, + BMP_FORMAT_24BIT_TC_BGR, + 0); + + pSalRGB->ReleaseBuffer(pRGB, true); + pRGB = pExtraRGB; + } + + if(pRGB + && pRGB->mnWidth > 0 + && pRGB->mnHeight > 0 + && BMP_FORMAT_24BIT_TC_BGR == (pRGB->mnFormat & ~BMP_FORMAT_TOP_DOWN)) + { + const sal_uInt32 nW(pRGB->mnWidth); + const sal_uInt32 nH(pRGB->mnHeight); + + pRetval = new Gdiplus::Bitmap(nW, nH, PixelFormat24bppRGB); + + if(pRetval) + { + sal_uInt8* pSrcRGB(pRGB->mpBits); + const sal_uInt32 nExtraRGB(pRGB->mnScanlineSize - (nW * 3)); + const bool bTopDown(pRGB->mnFormat & BMP_FORMAT_TOP_DOWN); + + for(sal_uInt32 y(0); y < nH; y++) + { + const sal_uInt32 nYInsert(bTopDown ? y : nH - y - 1); + + for(sal_uInt32 x(0); x < nW; x++) + { + const sal_uInt8 nB(*pSrcRGB++); + const sal_uInt8 nG(*pSrcRGB++); + const sal_uInt8 nR(*pSrcRGB++); + + pRetval->SetPixel(x, nYInsert, Gdiplus::Color(nR, nG, nB)); + } + + pSrcRGB += nExtraRGB; + } + } + } + + if(pExtraRGB) + { + delete pExtraRGB; + } + else + { + pSalRGB->ReleaseBuffer(pRGB, true); + } + + if(pExtraWinSalRGB) + { + delete pExtraWinSalRGB; + } + + return pRetval; +} + +// ------------------------------------------------------------------ + +Gdiplus::Bitmap* WinSalBitmap::ImplCreateGdiPlusBitmap(const WinSalBitmap& rAlphaSource) +{ + Gdiplus::Bitmap* pRetval(0); + WinSalBitmap* pSalRGB = const_cast< WinSalBitmap* >(this); + WinSalBitmap* pExtraWinSalRGB = 0; + + if(!pSalRGB->ImplGethDIB()) + { + // we need DIB for success with AcquireBuffer, create a replacement WinSalBitmap + pExtraWinSalRGB = new WinSalBitmap(); + pExtraWinSalRGB->Create(*pSalRGB, pSalRGB->GetBitCount()); + pSalRGB = pExtraWinSalRGB; + } + + BitmapBuffer* pRGB = pSalRGB->AcquireBuffer(true); + BitmapBuffer* pExtraRGB = 0; + + if(pRGB && BMP_FORMAT_24BIT_TC_BGR != (pRGB->mnFormat & ~BMP_FORMAT_TOP_DOWN)) + { + // convert source bitmap to BMP_FORMAT_24BIT_TC_BGR format if not yet in that format + SalTwoRect aSalTwoRect; + + aSalTwoRect.mnSrcX = aSalTwoRect.mnSrcY = aSalTwoRect.mnDestX = aSalTwoRect.mnDestY = 0; + aSalTwoRect.mnSrcWidth = aSalTwoRect.mnDestWidth = pRGB->mnWidth; + aSalTwoRect.mnSrcHeight = aSalTwoRect.mnDestHeight = pRGB->mnHeight; + + pExtraRGB = StretchAndConvert( + *pRGB, + aSalTwoRect, + BMP_FORMAT_24BIT_TC_BGR, + 0); + + pSalRGB->ReleaseBuffer(pRGB, true); + pRGB = pExtraRGB; + } + + WinSalBitmap* pSalA = const_cast< WinSalBitmap* >(&rAlphaSource); + WinSalBitmap* pExtraWinSalA = 0; + + if(!pSalA->ImplGethDIB()) + { + // we need DIB for success with AcquireBuffer, create a replacement WinSalBitmap + pExtraWinSalA = new WinSalBitmap(); + pExtraWinSalA->Create(*pSalA, pSalA->GetBitCount()); + pSalA = pExtraWinSalA; + } + + BitmapBuffer* pA = pSalA->AcquireBuffer(true); + BitmapBuffer* pExtraA = 0; + + if(pA && BMP_FORMAT_8BIT_PAL != (pA->mnFormat & ~BMP_FORMAT_TOP_DOWN)) + { + // convert alpha bitmap to BMP_FORMAT_8BIT_PAL format if not yet in that format + SalTwoRect aSalTwoRect; + + aSalTwoRect.mnSrcX = aSalTwoRect.mnSrcY = aSalTwoRect.mnDestX = aSalTwoRect.mnDestY = 0; + aSalTwoRect.mnSrcWidth = aSalTwoRect.mnDestWidth = pA->mnWidth; + aSalTwoRect.mnSrcHeight = aSalTwoRect.mnDestHeight = pA->mnHeight; + const BitmapPalette& rTargetPalette = Bitmap::GetGreyPalette(256); + + pExtraA = StretchAndConvert( + *pA, + aSalTwoRect, + BMP_FORMAT_8BIT_PAL, + &rTargetPalette); + + pSalA->ReleaseBuffer(pA, true); + pA = pExtraA; + } + + if(pRGB + && pA + && pRGB->mnWidth > 0 + && pRGB->mnHeight > 0 + && pRGB->mnWidth == pA->mnWidth + && pRGB->mnHeight == pA->mnHeight + && BMP_FORMAT_24BIT_TC_BGR == (pRGB->mnFormat & ~BMP_FORMAT_TOP_DOWN) + && BMP_FORMAT_8BIT_PAL == (pA->mnFormat & ~BMP_FORMAT_TOP_DOWN)) + { + // we have alpha and bitmap in known formats, create GdiPlus Bitmap as 32bit ARGB + const sal_uInt32 nW(pRGB->mnWidth); + const sal_uInt32 nH(pRGB->mnHeight); + + pRetval = new Gdiplus::Bitmap(nW, nH, PixelFormat32bppARGB); + + if(pRetval) + { + sal_uInt8* pSrcRGB(pRGB->mpBits); + sal_uInt8* pSrcA(pA->mpBits); + const sal_uInt32 nExtraRGB(pRGB->mnScanlineSize - (nW * 3)); + const sal_uInt32 nExtraA(pA->mnScanlineSize - nW); + const bool bTopDown(pRGB->mnFormat & BMP_FORMAT_TOP_DOWN); + + for(sal_uInt32 y(0); y < nH; y++) + { + const sal_uInt32 nYInsert(bTopDown ? y : nH - y - 1); + + for(sal_uInt32 x(0); x < nW; x++) + { + const sal_uInt8 nB(*pSrcRGB++); + const sal_uInt8 nG(*pSrcRGB++); + const sal_uInt8 nR(*pSrcRGB++); + const sal_uInt8 nA(0xff - *pSrcA++); + + pRetval->SetPixel(x, nYInsert, Gdiplus::Color(nA, nR, nG, nB)); + } + + pSrcRGB += nExtraRGB; + pSrcA += nExtraA; + } + } + } + + if(pExtraA) + { + delete pExtraA; + } + else + { + pSalA->ReleaseBuffer(pA, true); + } + + if(pExtraWinSalA) + { + delete pExtraWinSalA; + } + + if(pExtraRGB) + { + delete pExtraRGB; + } + else + { + pSalRGB->ReleaseBuffer(pRGB, true); + } + + if(pExtraWinSalRGB) + { + delete pExtraWinSalRGB; + } + + return pRetval; +} + +// ------------------------------------------------------------------ + bool WinSalBitmap::Create( HANDLE hBitmap, bool bDIB, bool bCopyHandle ) { bool bRet = TRUE; @@ -177,7 +594,7 @@ bool WinSalBitmap::Create( const SalBitmap& rSSalBmp, SalGraphics* pSGraphics ) { PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( rSalBmp.mhDIB ); PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) pBI; - HDC hDC = pGraphics->mhDC; + HDC hDC = pGraphics->getHDC(); HBITMAP hNewDDB; BITMAP aDDBInfo; PBYTE pBits = (PBYTE) pBI + *(DWORD*) pBI + @@ -264,19 +681,6 @@ bool WinSalBitmap::Create( const SalBitmap& rSSalBmp, sal_uInt16 nNewBitCount ) // ------------------------------------------------------------------ -void WinSalBitmap::Destroy() -{ - if( mhDIB ) - GlobalFree( mhDIB ); - else if( mhDDB ) - DeleteObject( mhDDB ); - - maSize = Size(); - mnBitCount = 0; -} - -// ------------------------------------------------------------------ - sal_uInt16 WinSalBitmap::ImplGetDIBColorCount( HGLOBAL hDIB ) { sal_uInt16 nColors = 0; diff --git a/vcl/win/source/gdi/salgdi.cxx b/vcl/win/source/gdi/salgdi.cxx index e25a417a9179..9a05ce7ad91c 100644 --- a/vcl/win/source/gdi/salgdi.cxx +++ b/vcl/win/source/gdi/salgdi.cxx @@ -524,16 +524,16 @@ void ImplSalInitGraphics( WinSalGraphics* pData ) // Beim Printer berechnen wir die minimale Linienstaerke if ( pData->mbPrinter ) { - int nDPIX = GetDeviceCaps( pData->mhDC, LOGPIXELSX ); + int nDPIX = GetDeviceCaps( pData->getHDC(), LOGPIXELSX ); if ( nDPIX <= 300 ) pData->mnPenWidth = 0; else pData->mnPenWidth = nDPIX/300; } - ::SetTextAlign( pData->mhDC, TA_BASELINE | TA_LEFT | TA_NOUPDATECP ); - ::SetBkMode( pData->mhDC, TRANSPARENT ); - ::SetROP2( pData->mhDC, R2_COPYPEN ); + ::SetTextAlign( pData->getHDC(), TA_BASELINE | TA_LEFT | TA_NOUPDATECP ); + ::SetBkMode( pData->getHDC(), TRANSPARENT ); + ::SetROP2( pData->getHDC(), R2_COPYPEN ); } // ----------------------------------------------------------------------- @@ -541,14 +541,14 @@ void ImplSalInitGraphics( WinSalGraphics* pData ) void ImplSalDeInitGraphics( WinSalGraphics* pData ) { // clear clip region - SelectClipRgn( pData->mhDC, 0 ); + SelectClipRgn( pData->getHDC(), 0 ); // select default objects if ( pData->mhDefPen ) - SelectPen( pData->mhDC, pData->mhDefPen ); + SelectPen( pData->getHDC(), pData->mhDefPen ); if ( pData->mhDefBrush ) - SelectBrush( pData->mhDC, pData->mhDefBrush ); + SelectBrush( pData->getHDC(), pData->mhDefBrush ); if ( pData->mhDefFont ) - SelectFont( pData->mhDC, pData->mhDefFont ); + SelectFont( pData->getHDC(), pData->mhDefFont ); } // ======================================================================= @@ -733,7 +733,7 @@ WinSalGraphics::WinSalGraphics() mfFontScale = 1.0; - mhDC = 0; + mhLocalDC = 0; mhPen = 0; mhBrush = 0; mhRegion = 0; @@ -795,8 +795,8 @@ WinSalGraphics::~WinSalGraphics() void WinSalGraphics::GetResolution( long& rDPIX, long& rDPIY ) { - rDPIX = GetDeviceCaps( mhDC, LOGPIXELSX ); - rDPIY = GetDeviceCaps( mhDC, LOGPIXELSY ); + rDPIX = GetDeviceCaps( getHDC(), LOGPIXELSX ); + rDPIY = GetDeviceCaps( getHDC(), LOGPIXELSY ); // #111139# this fixes the symptom of div by zero on startup // however, printing will fail most likely as communication with @@ -809,7 +809,7 @@ void WinSalGraphics::GetResolution( long& rDPIX, long& rDPIY ) sal_uInt16 WinSalGraphics::GetBitCount() { - return (sal_uInt16)GetDeviceCaps( mhDC, BITSPIXEL ); + return (sal_uInt16)GetDeviceCaps( getHDC(), BITSPIXEL ); } // ----------------------------------------------------------------------- @@ -846,7 +846,7 @@ void WinSalGraphics::ResetClipRegion() mhRegion = 0; } - SelectClipRgn( mhDC, 0 ); + SelectClipRgn( getHDC(), 0 ); } // ----------------------------------------------------------------------- @@ -1054,7 +1054,7 @@ bool WinSalGraphics::setClipRegion( const Region& i_rClip ) } if( mhRegion ) - SelectClipRgn( mhDC, mhRegion ); + SelectClipRgn( getHDC(), mhRegion ); return mhRegion != 0; } @@ -1064,7 +1064,7 @@ void WinSalGraphics::SetLineColor() { // create and select new pen HPEN hNewPen = GetStockPen( NULL_PEN ); - HPEN hOldPen = SelectPen( mhDC, hNewPen ); + HPEN hOldPen = SelectPen( getHDC(), hNewPen ); // destory or save old pen if ( mhPen ) @@ -1122,7 +1122,7 @@ void WinSalGraphics::SetLineColor( SalColor nSalColor ) } // select new pen - HPEN hOldPen = SelectPen( mhDC, hNewPen ); + HPEN hOldPen = SelectPen( getHDC(), hNewPen ); // destory or save old pen if ( mhPen ) @@ -1146,7 +1146,7 @@ void WinSalGraphics::SetFillColor() { // create and select new brush HBRUSH hNewBrush = GetStockBrush( NULL_BRUSH ); - HBRUSH hOldBrush = SelectBrush( mhDC, hNewBrush ); + HBRUSH hOldBrush = SelectBrush( getHDC(), hNewBrush ); // destory or save old brush if ( mhBrush ) @@ -1250,7 +1250,7 @@ void WinSalGraphics::SetFillColor( SalColor nSalColor ) } // select new brush - HBRUSH hOldBrush = SelectBrush( mhDC, hNewBrush ); + HBRUSH hOldBrush = SelectBrush( getHDC(), hNewBrush ); // destory or save old brush if ( mhBrush ) @@ -1273,7 +1273,7 @@ void WinSalGraphics::SetFillColor( SalColor nSalColor ) void WinSalGraphics::SetXORMode( bool bSet, bool ) { mbXORMode = bSet; - ::SetROP2( mhDC, bSet ? R2_XORPEN : R2_COPYPEN ); + ::SetROP2( getHDC(), bSet ? R2_XORPEN : R2_COPYPEN ); } // ----------------------------------------------------------------------- @@ -1297,13 +1297,13 @@ void WinSalGraphics::drawPixel( long nX, long nY ) if ( mbXORMode ) { HBRUSH hBrush = CreateSolidBrush( mnPenColor ); - HBRUSH hOldBrush = SelectBrush( mhDC, hBrush ); - PatBlt( mhDC, (int)nX, (int)nY, (int)1, (int)1, PATINVERT ); - SelectBrush( mhDC, hOldBrush ); + HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush ); + PatBlt( getHDC(), (int)nX, (int)nY, (int)1, (int)1, PATINVERT ); + SelectBrush( getHDC(), hOldBrush ); DeleteBrush( hBrush ); } else - SetPixel( mhDC, (int)nX, (int)nY, mnPenColor ); + SetPixel( getHDC(), (int)nX, (int)nY, mnPenColor ); } // ----------------------------------------------------------------------- @@ -1322,20 +1322,20 @@ void WinSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor ) if ( mbXORMode ) { HBRUSH hBrush = CreateSolidBrush( nCol ); - HBRUSH hOldBrush = SelectBrush( mhDC, hBrush ); - PatBlt( mhDC, (int)nX, (int)nY, (int)1, (int)1, PATINVERT ); - SelectBrush( mhDC, hOldBrush ); + HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush ); + PatBlt( getHDC(), (int)nX, (int)nY, (int)1, (int)1, PATINVERT ); + SelectBrush( getHDC(), hOldBrush ); DeleteBrush( hBrush ); } else - ::SetPixel( mhDC, (int)nX, (int)nY, nCol ); + ::SetPixel( getHDC(), (int)nX, (int)nY, nCol ); } // ----------------------------------------------------------------------- void WinSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) { - MoveToEx( mhDC, (int)nX1, (int)nY1, NULL ); + MoveToEx( getHDC(), (int)nX1, (int)nY1, NULL ); // we must paint the endpoint int bPaintEnd = TRUE; @@ -1356,20 +1356,20 @@ void WinSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 ) nX2--; } - LineTo( mhDC, (int)nX2, (int)nY2 ); + LineTo( getHDC(), (int)nX2, (int)nY2 ); if ( bPaintEnd && !mbPrinter ) { if ( mbXORMode ) { HBRUSH hBrush = CreateSolidBrush( mnPenColor ); - HBRUSH hOldBrush = SelectBrush( mhDC, hBrush ); - PatBlt( mhDC, (int)nX2, (int)nY2, (int)1, (int)1, PATINVERT ); - SelectBrush( mhDC, hOldBrush ); + HBRUSH hOldBrush = SelectBrush( getHDC(), hBrush ); + PatBlt( getHDC(), (int)nX2, (int)nY2, (int)1, (int)1, PATINVERT ); + SelectBrush( getHDC(), hOldBrush ); DeleteBrush( hBrush ); } else - SetPixel( mhDC, (int)nX2, (int)nY2, mnPenColor ); + SetPixel( getHDC(), (int)nX2, (int)nY2, mnPenColor ); } } @@ -1381,7 +1381,7 @@ void WinSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight ) { if ( !mbPrinter ) { - PatBlt( mhDC, (int)nX, (int)nY, (int)nWidth, (int)nHeight, + PatBlt( getHDC(), (int)nX, (int)nY, (int)nWidth, (int)nHeight, mbXORMode ? PATINVERT : PATCOPY ); } else @@ -1391,11 +1391,11 @@ void WinSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight ) aWinRect.top = nY; aWinRect.right = nX+nWidth; aWinRect.bottom = nY+nHeight; - ::FillRect( mhDC, &aWinRect, mhBrush ); + ::FillRect( getHDC(), &aWinRect, mhBrush ); } } else - WIN_Rectangle( mhDC, (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) ); + WIN_Rectangle( getHDC(), (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) ); } // ----------------------------------------------------------------------- @@ -1409,8 +1409,8 @@ void WinSalGraphics::drawPolyLine( sal_uLong nPoints, const SalPoint* pPtAry ) POINT* pWinPtAry = (POINT*)pPtAry; // Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl // von Punkten - if ( !Polyline( mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) - Polyline( mhDC, pWinPtAry, MAX_64KSALPOINTS ); + if ( !Polyline( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) + Polyline( getHDC(), pWinPtAry, MAX_64KSALPOINTS ); } // ----------------------------------------------------------------------- @@ -1424,8 +1424,8 @@ void WinSalGraphics::drawPolygon( sal_uLong nPoints, const SalPoint* pPtAry ) POINT* pWinPtAry = (POINT*)pPtAry; // Wegen Windows 95 und der Beschraenkung auf eine maximale Anzahl // von Punkten - if ( !WIN_Polygon( mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) - WIN_Polygon( mhDC, pWinPtAry, MAX_64KSALPOINTS ); + if ( !WIN_Polygon( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) + WIN_Polygon( getHDC(), pWinPtAry, MAX_64KSALPOINTS ); } // ----------------------------------------------------------------------- @@ -1471,7 +1471,7 @@ void WinSalGraphics::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoint n += nPoints; } - if ( !WIN_PolyPolygon( mhDC, pWinPointAryAry, (int*)pWinPointAry, (UINT)nPoly ) && + if ( !WIN_PolyPolygon( getHDC(), pWinPointAryAry, (int*)pWinPointAry, (UINT)nPoly ) && (nPolyPolyPoints > MAX_64KSALPOINTS) ) { nPolyPolyPoints = 0; @@ -1486,9 +1486,9 @@ void WinSalGraphics::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoint if ( pWinPointAry[(UINT)nPoly] > MAX_64KSALPOINTS ) pWinPointAry[(UINT)nPoly] = MAX_64KSALPOINTS; if ( nPoly == 1 ) - WIN_Polygon( mhDC, pWinPointAryAry, *pWinPointAry ); + WIN_Polygon( getHDC(), pWinPointAryAry, *pWinPointAry ); else - WIN_PolyPolygon( mhDC, pWinPointAryAry, (int*)pWinPointAry, nPoly ); + WIN_PolyPolygon( getHDC(), pWinPointAryAry, (int*)pWinPointAry, nPoly ); } if ( pWinPointAry != aWinPointAry ) @@ -1510,7 +1510,7 @@ sal_Bool WinSalGraphics::drawPolyLineBezier( sal_uLong nPoints, const SalPoint* DBG_ASSERT( sizeof( POINT ) == sizeof( SalPoint ), "WinSalGraphics::DrawPolyLineBezier(): POINT != SalPoint" ); - ImplRenderPath( mhDC, nPoints, pPtAry, pFlgAry ); + ImplRenderPath( getHDC(), nPoints, pPtAry, pFlgAry ); return sal_True; #else @@ -1546,13 +1546,13 @@ sal_Bool WinSalGraphics::drawPolygonBezier( sal_uLong nPoints, const SalPoint* p sal_Bool bRet( sal_False ); - if( BeginPath( mhDC ) ) + if( BeginPath( getHDC() ) ) { - PolyDraw(mhDC, pWinPointAry, pWinFlagAry, nPoints); + PolyDraw(getHDC(), pWinPointAry, pWinFlagAry, nPoints); - if( EndPath( mhDC ) ) + if( EndPath( getHDC() ) ) { - if( StrokeAndFillPath( mhDC ) ) + if( StrokeAndFillPath( getHDC() ) ) bRet = sal_True; } } @@ -1603,13 +1603,13 @@ sal_Bool WinSalGraphics::drawPolyPolygonBezier( sal_uInt32 nPoly, const sal_uInt sal_Bool bRet( sal_False ); - if( BeginPath( mhDC ) ) + if( BeginPath( getHDC() ) ) { - PolyDraw(mhDC, pWinPointAry, pWinFlagAry, nTotalPoints); + PolyDraw(getHDC(), pWinPointAry, pWinFlagAry, nTotalPoints); - if( EndPath( mhDC ) ) + if( EndPath( getHDC() ) ) { - if( StrokeAndFillPath( mhDC ) ) + if( StrokeAndFillPath( getHDC() ) ) bRet = sal_True; } } @@ -1719,7 +1719,7 @@ sal_Bool WinSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, v { int nEscape = POSTSCRIPT_PASSTHROUGH; - if ( Escape( mhDC, QUERYESCSUPPORT, sizeof( int ), ( LPSTR )&nEscape, 0 ) ) + if ( Escape( getHDC(), QUERYESCSUPPORT, sizeof( int ), ( LPSTR )&nEscape, 0 ) ) { double nBoundingBox[4]; @@ -1806,7 +1806,7 @@ sal_Bool WinSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, v // #107797# Write out buffer // ---------------------------------------------------------------------------------- *((sal_uInt16*)aBuf.getStr()) = (sal_uInt16)( aBuf.getLength() - 2 ); - Escape ( mhDC, nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 ); + Escape ( getHDC(), nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 ); // #107797# Write out EPS transformation code @@ -1826,7 +1826,7 @@ sal_Bool WinSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, v aBuf.append( "] concat\n" "%%BeginDocument:\n" ); *((sal_uInt16*)aBuf.getStr()) = (sal_uInt16)( aBuf.getLength() - 2 ); - Escape ( mhDC, nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 ); + Escape ( getHDC(), nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 ); // #107797# Write out actual EPS content @@ -1842,7 +1842,7 @@ sal_Bool WinSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, v // of size POSTSCRIPT_BUFSIZE at construction time of aBuf *((sal_uInt16*)aBuf.getStr()) = (sal_uInt16)nDoNow; memcpy( (void*)(aBuf.getStr() + 2), (BYTE*)pPtr + nSize - nToDo, nDoNow ); - sal_uLong nResult = Escape ( mhDC, nEscape, nDoNow + 2, (LPTSTR)aBuf.getStr(), 0 ); + sal_uLong nResult = Escape ( getHDC(), nEscape, nDoNow + 2, (LPTSTR)aBuf.getStr(), 0 ); if (!nResult ) break; nToDo -= nResult; @@ -1858,7 +1858,7 @@ sal_Bool WinSalGraphics::drawEPS( long nX, long nY, long nWidth, long nHeight, v "countdictstack dict_count_salWin sub {end} repeat\n" "b4_Inc_state_salWin restore\n\n" ); *((sal_uInt16*)aBuf.getStr()) = (sal_uInt16)( aBuf.getLength() - 2 ); - Escape ( mhDC, nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 ); + Escape ( getHDC(), nEscape, aBuf.getLength(), (LPTSTR)aBuf.getStr(), 0 ); bRetValue = TRUE; } } @@ -1873,7 +1873,7 @@ SystemGraphicsData WinSalGraphics::GetGraphicsData() const { SystemGraphicsData aRes; aRes.nSize = sizeof(aRes); - aRes.hDC = mhDC; + aRes.hDC = const_cast< WinSalGraphics* >(this)->getHDC(); return aRes; } diff --git a/vcl/win/source/gdi/salgdi2.cxx b/vcl/win/source/gdi/salgdi2.cxx index 9e40278368b1..5056458add56 100644 --- a/vcl/win/source/gdi/salgdi2.cxx +++ b/vcl/win/source/gdi/salgdi2.cxx @@ -59,42 +59,42 @@ bool WinSalGraphics::supportsOperation( OutDevSupportType eType ) const // ======================================================================= -void WinSalGraphics::copyBits( const SalTwoRect* pPosAry, SalGraphics* pSrcGraphics ) +void WinSalGraphics::copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) { HDC hSrcDC; DWORD nRop; if ( pSrcGraphics ) - hSrcDC = static_cast<WinSalGraphics*>(pSrcGraphics)->mhDC; + hSrcDC = static_cast<WinSalGraphics*>(pSrcGraphics)->getHDC(); else - hSrcDC = mhDC; + hSrcDC = getHDC(); if ( mbXORMode ) nRop = SRCINVERT; else nRop = SRCCOPY; - if ( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth) && - (pPosAry->mnSrcHeight == pPosAry->mnDestHeight) ) + if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) && + (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) ) { - BitBlt( mhDC, - (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, - (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, + BitBlt( getHDC(), + (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, + (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, hSrcDC, - (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, + (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, nRop ); } else { - int nOldStretchMode = SetStretchBltMode( mhDC, STRETCH_DELETESCANS ); - StretchBlt( mhDC, - (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, - (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, + int nOldStretchMode = SetStretchBltMode( getHDC(), STRETCH_DELETESCANS ); + StretchBlt( getHDC(), + (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, + (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, hSrcDC, - (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, - (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight, + (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, + (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight, nRop ); - SetStretchBltMode( mhDC, nOldStretchMode ); + SetStretchBltMode( getHDC(), nOldStretchMode ); } } @@ -285,19 +285,19 @@ void WinSalGraphics::copyArea( long nDestX, long nDestY, // we will prevent bitblt from copying useless data // epsecially now shadows from overlapping windows will appear (#i36344) hOldClipRgn = CreateRectRgn( 0, 0, 0, 0 ); - nOldClipRgnType = GetClipRgn( mhDC, hOldClipRgn ); + nOldClipRgnType = GetClipRgn( getHDC(), hOldClipRgn ); bRestoreClipRgn = TRUE; // indicate changed clipregion and force invalidate - ExtSelectClipRgn( mhDC, hInvalidateRgn, RGN_DIFF ); + ExtSelectClipRgn( getHDC(), hInvalidateRgn, RGN_DIFF ); } } } } - BitBlt( mhDC, + BitBlt( getHDC(), (int)nDestX, (int)nDestY, (int)nSrcWidth, (int)nSrcHeight, - mhDC, + getHDC(), (int)nSrcX, (int)nSrcY, SRCCOPY ); @@ -305,7 +305,7 @@ void WinSalGraphics::copyArea( long nDestX, long nDestY, { // restore old clip region if( nOldClipRgnType != ERROR ) - SelectClipRgn( mhDC, hOldClipRgn); + SelectClipRgn( getHDC(), hOldClipRgn); DeleteRegion( hOldClipRgn ); // invalidate regions that were not copied @@ -313,7 +313,7 @@ void WinSalGraphics::copyArea( long nDestX, long nDestY, // Combine Invalidate Region with existing ClipRegion HRGN hTempRgn = CreateRectRgn( 0, 0, 0, 0 ); - if ( GetClipRgn( mhDC, hTempRgn ) == 1 ) + if ( GetClipRgn( getHDC(), hTempRgn ) == 1 ) { int nRgnType = CombineRgn( hInvalidateRgn, hTempRgn, hInvalidateRgn, RGN_AND ); if ( (nRgnType == ERROR) || (nRgnType == NULLREGION) ) @@ -342,7 +342,7 @@ void WinSalGraphics::copyArea( long nDestX, long nDestY, // ----------------------------------------------------------------------- void ImplDrawBitmap( HDC hDC, - const SalTwoRect* pPosAry, const WinSalBitmap& rSalBitmap, + const SalTwoRect& rPosAry, const WinSalBitmap& rSalBitmap, sal_Bool bPrinter, int nDrawMode ) { if( hDC ) @@ -370,10 +370,10 @@ void ImplDrawBitmap( HDC hDC, const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS ); StretchDIBits( hDC, - (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, - (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, - (int)pPosAry->mnSrcX, (int)(pBIH->biHeight - pPosAry->mnSrcHeight - pPosAry->mnSrcY), - (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight, + (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, + (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, + (int)rPosAry.mnSrcX, (int)(pBIH->biHeight - rPosAry.mnSrcHeight - rPosAry.mnSrcY), + (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight, pBits, pBI, DIB_RGB_COLORS, nDrawMode ); GlobalUnlock( hDrawDIB ); @@ -392,14 +392,14 @@ void ImplDrawBitmap( HDC hDC, nOldTextColor = ::SetTextColor( hDC, RGB( 0x00, 0x00, 0x00 ) ); } - if ( (pPosAry->mnSrcWidth == pPosAry->mnDestWidth) && - (pPosAry->mnSrcHeight == pPosAry->mnDestHeight) ) + if ( (rPosAry.mnSrcWidth == rPosAry.mnDestWidth) && + (rPosAry.mnSrcHeight == rPosAry.mnDestHeight) ) { BitBlt( hDC, - (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, - (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, + (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, + (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, hBmpDC, - (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, + (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, nDrawMode ); } else @@ -407,11 +407,11 @@ void ImplDrawBitmap( HDC hDC, const int nOldStretchMode = SetStretchBltMode( hDC, STRETCH_DELETESCANS ); StretchBlt( hDC, - (int)pPosAry->mnDestX, (int)pPosAry->mnDestY, - (int)pPosAry->mnDestWidth, (int)pPosAry->mnDestHeight, + (int)rPosAry.mnDestX, (int)rPosAry.mnDestY, + (int)rPosAry.mnDestWidth, (int)rPosAry.mnDestHeight, hBmpDC, - (int)pPosAry->mnSrcX, (int)pPosAry->mnSrcY, - (int)pPosAry->mnSrcWidth, (int)pPosAry->mnSrcHeight, + (int)rPosAry.mnSrcX, (int)rPosAry.mnSrcY, + (int)rPosAry.mnSrcWidth, (int)rPosAry.mnSrcHeight, nDrawMode ); SetStretchBltMode( hDC, nOldStretchMode ); @@ -433,17 +433,36 @@ void ImplDrawBitmap( HDC hDC, // ----------------------------------------------------------------------- -void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, - const SalBitmap& rSalBitmap ) +void WinSalGraphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap) { - ImplDrawBitmap( mhDC, pPosAry, static_cast<const WinSalBitmap&>(rSalBitmap), - mbPrinter, - mbXORMode ? SRCINVERT : SRCCOPY ); + bool bTryDirectPaint(!mbPrinter && !mbXORMode); + + if(bTryDirectPaint) + { + // only paint direct when no scaling and no MapMode, else the + // more expensive conversions may be done for short-time Bitmap/BitmapEx + // used for buffering only + if(rPosAry.mnSrcWidth == rPosAry.mnDestWidth && rPosAry.mnSrcHeight == rPosAry.mnDestHeight) + { + bTryDirectPaint = false; + } + } + + // try to draw using GdiPlus directly + if(bTryDirectPaint && tryDrawBitmapGdiPlus(rPosAry, rSalBitmap)) + { + return; + } + + // fall back old stuff + ImplDrawBitmap(getHDC(), rPosAry, static_cast<const WinSalBitmap&>(rSalBitmap), + mbPrinter, + mbXORMode ? SRCINVERT : SRCCOPY ); } // ----------------------------------------------------------------------- -void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, +void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSSalBitmap, SalColor nTransparentColor ) { @@ -492,28 +511,46 @@ void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, // hMaskBitmap is destroyed by new SalBitmap 'pMask' ( bDIB==FALSE, bCopy == FALSE ) if( pMask->Create( hMaskBitmap, FALSE, FALSE ) ) - drawBitmap( pPosAry, rSalBitmap, *pMask ); + drawBitmap( rPosAry, rSalBitmap, *pMask ); delete pMask; } // ----------------------------------------------------------------------- -void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, +void WinSalGraphics::drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSSalBitmap, const SalBitmap& rSTransparentBitmap ) { DBG_ASSERT( !mbPrinter, "No transparency print possible!" ); + bool bTryDirectPaint(!mbPrinter && !mbXORMode); + + if(bTryDirectPaint) + { + // only paint direct when no scaling and no MapMode, else the + // more expensive conversions may be done for short-time Bitmap/BitmapEx + // used for buffering only + if(rPosAry.mnSrcWidth == rPosAry.mnDestWidth && rPosAry.mnSrcHeight == rPosAry.mnDestHeight) + { + bTryDirectPaint = false; + } + } + + // try to draw using GdiPlus directly + if(bTryDirectPaint && drawAlphaBitmap(rPosAry, rSSalBitmap, rSTransparentBitmap)) + { + return; + } const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap); const WinSalBitmap& rTransparentBitmap = static_cast<const WinSalBitmap&>(rSTransparentBitmap); - SalTwoRect aPosAry = *pPosAry; + SalTwoRect aPosAry = rPosAry; int nDstX = (int)aPosAry.mnDestX; int nDstY = (int)aPosAry.mnDestY; int nDstWidth = (int)aPosAry.mnDestWidth; int nDstHeight = (int)aPosAry.mnDestHeight; - HDC hDC = mhDC; + HDC hDC = getHDC(); HBITMAP hMemBitmap = 0; HBITMAP hMaskBitmap = 0; @@ -537,17 +574,17 @@ void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, WinSalBitmap aTmp; if( aTmp.Create( rTransparentBitmap, this ) ) - ImplDrawBitmap( hMaskDC, &aPosAry, aTmp, FALSE, SRCCOPY ); + ImplDrawBitmap( hMaskDC, aPosAry, aTmp, FALSE, SRCCOPY ); } else - ImplDrawBitmap( hMaskDC, &aPosAry, rTransparentBitmap, FALSE, SRCCOPY ); + ImplDrawBitmap( hMaskDC, aPosAry, rTransparentBitmap, FALSE, SRCCOPY ); // now MemDC contains background, MaskDC the transparency mask // #105055# Respect XOR mode if( mbXORMode ) { - ImplDrawBitmap( hMaskDC, &aPosAry, rSalBitmap, FALSE, SRCERASE ); + ImplDrawBitmap( hMaskDC, aPosAry, rSalBitmap, FALSE, SRCERASE ); // now MaskDC contains the bitmap area with black background BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCINVERT ); // now MemDC contains background XORed bitmap area ontop @@ -556,7 +593,7 @@ void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, { BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCAND ); // now MemDC contains background with masked-out bitmap area - ImplDrawBitmap( hMaskDC, &aPosAry, rSalBitmap, FALSE, SRCERASE ); + ImplDrawBitmap( hMaskDC, aPosAry, rSalBitmap, FALSE, SRCERASE ); // now MaskDC contains the bitmap area with black background BitBlt( hMemDC, 0, 0, nDstWidth, nDstHeight, hMaskDC, 0, 0, SRCPAINT ); // now MemDC contains background and bitmap merged together @@ -577,19 +614,6 @@ void WinSalGraphics::drawBitmap( const SalTwoRect* pPosAry, // ----------------------------------------------------------------------- -bool WinSalGraphics::drawAlphaBitmap( const SalTwoRect& rTR, - const SalBitmap& rSrcBitmap, - const SalBitmap& rAlphaBmp ) -{ - (void)rTR; (void)rSrcBitmap; (void)rAlphaBmp; - - // TODO(P3): implement alpha bmp blits. Catch: Windows only - // handles 32bpp, premultiplied bitmaps - return false; -} - -// ----------------------------------------------------------------------- - bool WinSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, long nHeight, sal_uInt8 nTransparency ) { @@ -608,7 +632,7 @@ bool WinSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, // hMemDC contains a 1x1 bitmap of the right color - stretch-blit // that to dest hdc - bool bRet = AlphaBlend( mhDC, nX, nY, nWidth, nHeight, + bool bRet = AlphaBlend( getHDC(), nX, nY, nWidth, nHeight, hMemDC, 0,0,1,1, aFunc ) == TRUE; @@ -619,7 +643,7 @@ bool WinSalGraphics::drawAlphaRect( long nX, long nY, long nWidth, // ----------------------------------------------------------------------- -void WinSalGraphics::drawMask( const SalTwoRect* pPosAry, +void WinSalGraphics::drawMask( const SalTwoRect& rPosAry, const SalBitmap& rSSalBitmap, SalColor nMaskColor ) { @@ -627,11 +651,11 @@ void WinSalGraphics::drawMask( const SalTwoRect* pPosAry, const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap); - SalTwoRect aPosAry = *pPosAry; + SalTwoRect aPosAry = rPosAry; const BYTE cRed = SALCOLOR_RED( nMaskColor ); const BYTE cGreen = SALCOLOR_GREEN( nMaskColor ); const BYTE cBlue = SALCOLOR_BLUE( nMaskColor ); - HDC hDC = mhDC; + HDC hDC = getHDC(); HBRUSH hMaskBrush = CreateSolidBrush( RGB( cRed, cGreen, cBlue ) ); HBRUSH hOldBrush = SelectBrush( hDC, hMaskBrush ); @@ -643,10 +667,10 @@ void WinSalGraphics::drawMask( const SalTwoRect* pPosAry, WinSalBitmap aTmp; if( aTmp.Create( rSalBitmap, this ) ) - ImplDrawBitmap( hDC, &aPosAry, aTmp, FALSE, 0x00B8074AUL ); + ImplDrawBitmap( hDC, aPosAry, aTmp, FALSE, 0x00B8074AUL ); } else - ImplDrawBitmap( hDC, &aPosAry, rSalBitmap, FALSE, 0x00B8074AUL ); + ImplDrawBitmap( hDC, aPosAry, rSalBitmap, FALSE, 0x00B8074AUL ); SelectBrush( hDC, hOldBrush ); DeleteBrush( hMaskBrush ); @@ -663,7 +687,7 @@ SalBitmap* WinSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY ) nDX = labs( nDX ); nDY = labs( nDY ); - HDC hDC = mhDC; + HDC hDC = getHDC(); HBITMAP hBmpBitmap = CreateCompatibleBitmap( hDC, nDX, nDY ); HDC hBmpDC = ImplGetCachedDC( CACHED_HDC_1, hBmpBitmap ); sal_Bool bRet; @@ -696,7 +720,7 @@ SalBitmap* WinSalGraphics::getBitmap( long nX, long nY, long nDX, long nDY ) SalColor WinSalGraphics::getPixel( long nX, long nY ) { - COLORREF aWinCol = ::GetPixel( mhDC, (int) nX, (int) nY ); + COLORREF aWinCol = ::GetPixel( getHDC(), (int) nX, (int) nY ); if ( CLR_INVALID == aWinCol ) return MAKE_SALCOLOR( 0, 0, 0 ); @@ -713,15 +737,15 @@ void WinSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInv if ( nFlags & SAL_INVERT_TRACKFRAME ) { HPEN hDotPen = CreatePen( PS_DOT, 0, 0 ); - HPEN hOldPen = SelectPen( mhDC, hDotPen ); - HBRUSH hOldBrush = SelectBrush( mhDC, GetStockBrush( NULL_BRUSH ) ); - int nOldROP = SetROP2( mhDC, R2_NOT ); + HPEN hOldPen = SelectPen( getHDC(), hDotPen ); + HBRUSH hOldBrush = SelectBrush( getHDC(), GetStockBrush( NULL_BRUSH ) ); + int nOldROP = SetROP2( getHDC(), R2_NOT ); - WIN_Rectangle( mhDC, (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) ); + WIN_Rectangle( getHDC(), (int)nX, (int)nY, (int)(nX+nWidth), (int)(nY+nHeight) ); - SetROP2( mhDC, nOldROP ); - SelectPen( mhDC, hOldPen ); - SelectBrush( mhDC, hOldBrush ); + SetROP2( getHDC(), nOldROP ); + SelectPen( getHDC(), hOldPen ); + SelectBrush( getHDC(), hOldBrush ); DeletePen( hDotPen ); } else if ( nFlags & SAL_INVERT_50 ) @@ -734,11 +758,11 @@ void WinSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInv pSalData->mh50Brush = CreatePatternBrush( pSalData->mh50Bmp ); } - COLORREF nOldTextColor = ::SetTextColor( mhDC, 0 ); - HBRUSH hOldBrush = SelectBrush( mhDC, pSalData->mh50Brush ); - PatBlt( mhDC, nX, nY, nWidth, nHeight, PATINVERT ); - ::SetTextColor( mhDC, nOldTextColor ); - SelectBrush( mhDC, hOldBrush ); + COLORREF nOldTextColor = ::SetTextColor( getHDC(), 0 ); + HBRUSH hOldBrush = SelectBrush( getHDC(), pSalData->mh50Brush ); + PatBlt( getHDC(), nX, nY, nWidth, nHeight, PATINVERT ); + ::SetTextColor( getHDC(), nOldTextColor ); + SelectBrush( getHDC(), hOldBrush ); } else { @@ -747,7 +771,7 @@ void WinSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInv aRect.top = (int)nY; aRect.right = (int)nX+nWidth; aRect.bottom = (int)nY+nHeight; - ::InvertRect( mhDC, &aRect ); + ::InvertRect( getHDC(), &aRect ); } } @@ -760,7 +784,7 @@ void WinSalGraphics::invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInver HBRUSH hBrush; HBRUSH hOldBrush = 0; COLORREF nOldTextColor RGB(0,0,0); - int nOldROP = SetROP2( mhDC, R2_NOT ); + int nOldROP = SetROP2( getHDC(), R2_NOT ); if ( nSalFlags & SAL_INVERT_TRACKFRAME ) hPen = CreatePen( PS_DOT, 0, 0 ); @@ -783,10 +807,10 @@ void WinSalGraphics::invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInver hBrush = GetStockBrush( BLACK_BRUSH ); hPen = GetStockPen( NULL_PEN ); - nOldTextColor = ::SetTextColor( mhDC, 0 ); - hOldBrush = SelectBrush( mhDC, hBrush ); + nOldTextColor = ::SetTextColor( getHDC(), 0 ); + hOldBrush = SelectBrush( getHDC(), hBrush ); } - hOldPen = SelectPen( mhDC, hPen ); + hOldPen = SelectPen( getHDC(), hPen ); POINT* pWinPtAry; // Unter NT koennen wir das Array direkt weiterreichen @@ -798,23 +822,23 @@ void WinSalGraphics::invert( sal_uLong nPoints, const SalPoint* pPtAry, SalInver // von Punkten if ( nSalFlags & SAL_INVERT_TRACKFRAME ) { - if ( !Polyline( mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) - Polyline( mhDC, pWinPtAry, MAX_64KSALPOINTS ); + if ( !Polyline( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) + Polyline( getHDC(), pWinPtAry, MAX_64KSALPOINTS ); } else { - if ( !WIN_Polygon( mhDC, pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) - WIN_Polygon( mhDC, pWinPtAry, MAX_64KSALPOINTS ); + if ( !WIN_Polygon( getHDC(), pWinPtAry, (int)nPoints ) && (nPoints > MAX_64KSALPOINTS) ) + WIN_Polygon( getHDC(), pWinPtAry, MAX_64KSALPOINTS ); } - SetROP2( mhDC, nOldROP ); - SelectPen( mhDC, hOldPen ); + SetROP2( getHDC(), nOldROP ); + SelectPen( getHDC(), hOldPen ); if ( nSalFlags & SAL_INVERT_TRACKFRAME ) DeletePen( hPen ); else { - ::SetTextColor( mhDC, nOldTextColor ); - SelectBrush( mhDC, hOldBrush ); + ::SetTextColor( getHDC(), nOldTextColor ); + SelectBrush( getHDC(), hOldBrush ); } } diff --git a/vcl/win/source/gdi/salgdi3.cxx b/vcl/win/source/gdi/salgdi3.cxx index 667166e0dc41..e2328c05d4d0 100644 --- a/vcl/win/source/gdi/salgdi3.cxx +++ b/vcl/win/source/gdi/salgdi3.cxx @@ -1339,7 +1339,7 @@ void WinSalGraphics::SetTextColor( SalColor nSalColor ) aCol = PALRGB_TO_RGB( aCol ); } - ::SetTextColor( mhDC, aCol ); + ::SetTextColor( getHDC(), aCol ); } // ----------------------------------------------------------------------- @@ -1545,7 +1545,7 @@ HFONT WinSalGraphics::ImplDoSetFont( ImplFontSelectData* i_pFont, float& o_rFont if( true/*aSalShlData.mbWNT*/ ) { LOGFONTW aLogFont; - ImplGetLogFontFromFontSelect( mhDC, i_pFont, aLogFont, true ); + ImplGetLogFontFromFontSelect( getHDC(), i_pFont, aLogFont, true ); // on the display we prefer Courier New when Courier is a // bitmap only font and we need to stretch or rotate it @@ -1587,17 +1587,17 @@ HFONT WinSalGraphics::ImplDoSetFont( ImplFontSelectData* i_pFont, float& o_rFont // "PRB: Fonts Not Drawn Antialiased on Device Context for DirectDraw Surface" SelectFont( hdcScreen, SelectFont( hdcScreen , hNewFont ) ); } - o_rOldFont = ::SelectFont( mhDC, hNewFont ); + o_rOldFont = ::SelectFont( getHDC(), hNewFont ); TEXTMETRICW aTextMetricW; - if( !::GetTextMetricsW( mhDC, &aTextMetricW ) ) + if( !::GetTextMetricsW( getHDC(), &aTextMetricW ) ) { // the selected font doesn't work => try a replacement // TODO: use its font fallback instead lstrcpynW( aLogFont.lfFaceName, L"Courier New", 11 ); aLogFont.lfPitchAndFamily = FIXED_PITCH; HFONT hNewFont2 = CreateFontIndirectW( &aLogFont ); - SelectFont( mhDC, hNewFont2 ); + SelectFont( getHDC(), hNewFont2 ); DeleteFont( hNewFont ); hNewFont = hNewFont2; } @@ -1616,7 +1616,7 @@ sal_uInt16 WinSalGraphics::SetFont( ImplFontSelectData* pFont, int nFallbackLeve { // deselect still active font if( mhDefFont ) - ::SelectFont( mhDC, mhDefFont ); + ::SelectFont( getHDC(), mhDefFont ); // release no longer referenced font handles for( int i = nFallbackLevel; i < MAX_FALLBACK; ++i ) { @@ -1657,7 +1657,7 @@ sal_uInt16 WinSalGraphics::SetFont( ImplFontSelectData* pFont, int nFallbackLeve mhFonts[ nFallbackLevel ] = hNewFont; // now the font is live => update font face if( mpWinFontData[ nFallbackLevel ] ) - mpWinFontData[ nFallbackLevel ]->UpdateFromHDC( mhDC ); + mpWinFontData[ nFallbackLevel ]->UpdateFromHDC( getHDC() ); if( !nFallbackLevel ) { @@ -1686,17 +1686,17 @@ sal_uInt16 WinSalGraphics::SetFont( ImplFontSelectData* pFont, int nFallbackLeve void WinSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLevel ) { // temporarily change the HDC to the font in the fallback level - HFONT hOldFont = SelectFont( mhDC, mhFonts[nFallbackLevel] ); + HFONT hOldFont = SelectFont( getHDC(), mhFonts[nFallbackLevel] ); wchar_t aFaceName[LF_FACESIZE+60]; - if( ::GetTextFaceW( mhDC, sizeof(aFaceName)/sizeof(wchar_t), aFaceName ) ) + if( ::GetTextFaceW( getHDC(), sizeof(aFaceName)/sizeof(wchar_t), aFaceName ) ) pMetric->maName = reinterpret_cast<const sal_Unicode*>(aFaceName); // get the font metric TEXTMETRICA aWinMetric; - const bool bOK = GetTextMetricsA( mhDC, &aWinMetric ); + const bool bOK = GetTextMetricsA( getHDC(), &aWinMetric ); // restore the HDC to the font in the base level - SelectFont( mhDC, hOldFont ); + SelectFont( getHDC(), hOldFont ); if( !bOK ) return; @@ -1715,7 +1715,7 @@ void WinSalGraphics::GetFontMetric( ImplFontMetricData* pMetric, int nFallbackLe { // check if there are kern pairs // TODO: does this work with GPOS kerning? - DWORD nKernPairs = ::GetKerningPairsA( mhDC, 0, NULL ); + DWORD nKernPairs = ::GetKerningPairsA( getHDC(), 0, NULL ); pMetric->mbKernableFont = (nKernPairs > 0); } else @@ -1787,8 +1787,8 @@ static void ImplGetAllFontCharSets( WinSalGraphics* pData ) LOGFONTA aLogFont; memset( &aLogFont, 0, sizeof( aLogFont ) ); aLogFont.lfCharSet = DEFAULT_CHARSET; - GetTextFaceA( pData->mhDC, sizeof( aLogFont.lfFaceName ), aLogFont.lfFaceName ); - EnumFontFamiliesExA( pData->mhDC, &aLogFont, (FONTENUMPROCA)SalEnumCharSetsProcExA, + GetTextFaceA( pData->getHDC(), sizeof( aLogFont.lfFaceName ), aLogFont.lfFaceName ); + EnumFontFamiliesExA( pData->getHDC(), &aLogFont, (FONTENUMPROCA)SalEnumCharSetsProcExA, (LPARAM)(void*)pData, 0 ); } @@ -1796,12 +1796,12 @@ static void ImplGetAllFontCharSets( WinSalGraphics* pData ) static void ImplAddKerningPairs( WinSalGraphics* pData ) { - sal_uLong nPairs = ::GetKerningPairsA( pData->mhDC, 0, NULL ); + sal_uLong nPairs = ::GetKerningPairsA( pData->getHDC(), 0, NULL ); if ( !nPairs ) return; CHARSETINFO aInfo; - if ( !TranslateCharsetInfo( (DWORD*)(sal_uLong)GetTextCharset( pData->mhDC ), &aInfo, TCI_SRCCHARSET ) ) + if ( !TranslateCharsetInfo( (DWORD*)(sal_uLong)GetTextCharset( pData->getHDC() ), &aInfo, TCI_SRCCHARSET ) ) return; if ( !pData->mpFontKernPairs ) @@ -1818,7 +1818,7 @@ static void ImplAddKerningPairs( WinSalGraphics* pData ) UINT nCP = aInfo.ciACP; sal_uLong nOldPairs = pData->mnFontKernPairCount; KERNINGPAIR* pTempPair = pData->mpFontKernPairs+pData->mnFontKernPairCount; - nPairs = ::GetKerningPairsA( pData->mhDC, nPairs, pTempPair ); + nPairs = ::GetKerningPairsA( pData->getHDC(), nPairs, pTempPair ); for ( sal_uLong i = 0; i < nPairs; i++ ) { unsigned char aBuf[2]; @@ -1908,18 +1908,18 @@ sal_uLong WinSalGraphics::GetKernPairs( sal_uLong nPairs, ImplKernPairData* pKer mnFontKernPairCount = 0; KERNINGPAIR* pPairs = NULL; - int nCount = ::GetKerningPairsW( mhDC, 0, NULL ); + int nCount = ::GetKerningPairsW( getHDC(), 0, NULL ); if( nCount ) { #ifdef GCP_KERN_HACK pPairs = new KERNINGPAIR[ nCount+1 ]; mpFontKernPairs = pPairs; mnFontKernPairCount = nCount; - ::GetKerningPairsW( mhDC, nCount, pPairs ); + ::GetKerningPairsW( getHDC(), nCount, pPairs ); #else // GCP_KERN_HACK pPairs = pKernPairs; nCount = (nCount < nPairs) : nCount : nPairs; - ::GetKerningPairsW( mhDC, nCount, pPairs ); + ::GetKerningPairsW( getHDC(), nCount, pPairs ); return nCount; #endif // GCP_KERN_HACK } @@ -2374,7 +2374,7 @@ void WinSalGraphics::GetDevFontList( ImplDevFontList* pFontList ) } ImplEnumInfo aInfo; - aInfo.mhDC = mhDC; + aInfo.mhDC = getHDC(); aInfo.mpList = pFontList; aInfo.mpName = NULL; aInfo.mpLogFontA = NULL; @@ -2403,7 +2403,7 @@ void WinSalGraphics::GetDevFontList( ImplDevFontList* pFontList ) memset( &aLogFont, 0, sizeof( aLogFont ) ); aLogFont.lfCharSet = DEFAULT_CHARSET; aInfo.mpLogFontW = &aLogFont; - EnumFontFamiliesExW( mhDC, &aLogFont, + EnumFontFamiliesExW( getHDC(), &aLogFont, (FONTENUMPROCW)SalEnumFontsProcExW, (LPARAM)(void*)&aInfo, 0 ); // Feststellen, was es fuer Courier-Schriften auf dem Bildschirm gibt, @@ -2415,7 +2415,7 @@ void WinSalGraphics::GetDevFontList( ImplDevFontList* pFontList ) } // set glyph fallback hook - static WinGlyphFallbackSubstititution aSubstFallback( mhDC ); + static WinGlyphFallbackSubstititution aSubstFallback( getHDC() ); pFontList->SetFallbackHook( &aSubstFallback ); } @@ -2428,7 +2428,7 @@ void WinSalGraphics::GetDevFontSubstList( OutputDevice* ) sal_Bool WinSalGraphics::GetGlyphBoundRect( long nIndex, Rectangle& rRect ) { - HDC hDC = mhDC; + HDC hDC = getHDC(); // use unity matrix MAT2 aMat; @@ -2463,7 +2463,7 @@ sal_Bool WinSalGraphics::GetGlyphOutline( long nIndex, { rB2DPolyPoly.clear(); - HDC hDC = mhDC; + HDC hDC = getHDC(); // use unity matrix MAT2 aMat; @@ -2667,7 +2667,7 @@ ScopedFont::~ScopedFont() // restore original font, destroy temporary font HFONT hTempFont = m_rData.mhFonts[0]; m_rData.mhFonts[0] = m_hOrigFont; - SelectObject( m_rData.mhDC, m_hOrigFont ); + SelectObject( m_rData.getHDC(), m_hOrigFont ); DeleteObject( hTempFont ); } } @@ -2722,7 +2722,7 @@ sal_Bool WinSalGraphics::CreateFontSubset( const rtl::OUString& rToFile, #if OSL_DEBUG_LEVEL > 1 // get font metrics TEXTMETRICA aWinMetric; - if( !::GetTextMetricsA( mhDC, &aWinMetric ) ) + if( !::GetTextMetricsA( getHDC(), &aWinMetric ) ) return FALSE; DBG_ASSERT( !(aWinMetric.tmPitchAndFamily & TMPF_DEVICE), "cannot subset device font" ); @@ -2737,10 +2737,10 @@ sal_Bool WinSalGraphics::CreateFontSubset( const rtl::OUString& rToFile, // check if the font has a CFF-table const DWORD nCffTag = CalcTag( "CFF " ); - const RawFontData aRawCffData( mhDC, nCffTag ); + const RawFontData aRawCffData( getHDC(), nCffTag ); if( aRawCffData.get() ) { - pWinFontData->UpdateFromHDC( mhDC ); + pWinFontData->UpdateFromHDC( getHDC() ); const ImplFontCharMap* pCharMap = pWinFontData->GetImplFontCharMap(); pCharMap->AddReference(); @@ -2770,7 +2770,7 @@ sal_Bool WinSalGraphics::CreateFontSubset( const rtl::OUString& rToFile, } // get raw font file data - const RawFontData xRawFontData( mhDC, NULL ); + const RawFontData xRawFontData( getHDC(), NULL ); if( !xRawFontData.get() ) return FALSE; @@ -2870,19 +2870,19 @@ const void* WinSalGraphics::GetEmbedFontData( const ImplFontData* pFont, SetFont( &aIFSD, 0 ); // get the raw font file data - RawFontData aRawFontData( mhDC ); + RawFontData aRawFontData( getHDC() ); *pDataLen = aRawFontData.size(); if( !aRawFontData.get() ) return NULL; // get important font properties TEXTMETRICA aTm; - if( !::GetTextMetricsA( mhDC, &aTm ) ) + if( !::GetTextMetricsA( getHDC(), &aTm ) ) *pDataLen = 0; const bool bPFA = (*aRawFontData.get() < 0x80); rInfo.m_nFontType = bPFA ? FontSubsetInfo::TYPE1_PFA : FontSubsetInfo::TYPE1_PFB; WCHAR aFaceName[64]; - int nFNLen = ::GetTextFaceW( mhDC, 64, aFaceName ); + int nFNLen = ::GetTextFaceW( getHDC(), 64, aFaceName ); // #i59854# strip eventual null byte while( nFNLen > 0 && aFaceName[nFNLen-1] == 0 ) nFNLen--; @@ -2900,7 +2900,7 @@ const void* WinSalGraphics::GetEmbedFontData( const ImplFontData* pFont, { int nCharWidth = 0; const sal_Unicode cChar = pUnicodes[i]; - if( !::GetCharWidth32W( mhDC, cChar, cChar, &nCharWidth ) ) + if( !::GetCharWidth32W( getHDC(), cChar, cChar, &nCharWidth ) ) *pDataLen = 0; pCharWidths[i] = nCharWidth; } @@ -2941,7 +2941,7 @@ const Ucs2SIntMap* WinSalGraphics::GetFontEncodingVector( const ImplFontData* pF // TODO: get correct encoding vector GLYPHSET aGlyphSet; aGlyphSet.cbThis = sizeof(aGlyphSet); - DWORD aW = ::GetFontUnicodeRanges( mhDC, &aGlyphSet); + DWORD aW = ::GetFontUnicodeRanges( getHDC(), &aGlyphSet); #else for( sal_Unicode i = 32; i < 256; ++i ) (*pNewEncoding)[i] = i; @@ -2974,7 +2974,7 @@ void WinSalGraphics::GetGlyphWidths( const ImplFontData* pFont, if( pFont->IsSubsettable() ) { // get raw font file data - const RawFontData xRawFontData( mhDC ); + const RawFontData xRawFontData( getHDC() ); if( !xRawFontData.get() ) return; @@ -3038,7 +3038,7 @@ void WinSalGraphics::GetGlyphWidths( const ImplFontData* pFont, for( sal_Unicode i = 32; i < 256; ++i ) { int nCharWidth = 0; - if( ::GetCharWidth32W( mhDC, i, i, &nCharWidth ) ) + if( ::GetCharWidth32W( getHDC(), i, i, &nCharWidth ) ) { rUnicodeEnc[ i ] = rWidths.size(); rWidths.push_back( nCharWidth ); diff --git a/vcl/win/source/gdi/salgdi_gdiplus.cxx b/vcl/win/source/gdi/salgdi_gdiplus.cxx index 6fc73b86d02c..9a0c8c4d7609 100644 --- a/vcl/win/source/gdi/salgdi_gdiplus.cxx +++ b/vcl/win/source/gdi/salgdi_gdiplus.cxx @@ -19,20 +19,17 @@ * *************************************************************/ - - // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" #include <stdio.h> #include <string.h> - #include <tools/svwin.h> #include <tools/debug.hxx> - #include <win/wincomp.hxx> #include <win/saldata.hxx> #include <win/salgdi.h> +#include <win/salbmp.h> #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) @@ -155,7 +152,7 @@ bool WinSalGraphics::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rPolyPoly if(mbBrush && nCount && (fTransparency >= 0.0 && fTransparency < 1.0)) { - Gdiplus::Graphics aGraphics(mhDC); + Gdiplus::Graphics aGraphics(getHDC()); 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::SolidBrush aTestBrush(aTestColor); @@ -198,7 +195,7 @@ bool WinSalGraphics::drawPolyLine( if(mbPen && nCount) { - Gdiplus::Graphics aGraphics(mhDC); + Gdiplus::Graphics aGraphics(getHDC()); 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::Pen aTestPen(aTestColor, Gdiplus::REAL(rLineWidths.getX())); @@ -287,3 +284,201 @@ bool WinSalGraphics::drawPolyLine( } // ----------------------------------------------------------------------- + +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) + { + rGraphics.SetInterpolationMode(Gdiplus::InterpolationModeInvalid); + } + 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; +} + +bool WinSalGraphics::drawAlphaBitmap( + const SalTwoRect& rTR, + 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; +} + +// ----------------------------------------------------------------------- + +bool WinSalGraphics::drawTransformedBitmap( + const basegfx::B2DPoint& rNull, + const basegfx::B2DPoint& rX, + const basegfx::B2DPoint& rY, + 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; +} + +// ----------------------------------------------------------------------- +// eof diff --git a/vcl/win/source/gdi/salnativewidgets-luna.cxx b/vcl/win/source/gdi/salnativewidgets-luna.cxx index a8e63a404e23..c24fc763ecdf 100644 --- a/vcl/win/source/gdi/salnativewidgets-luna.cxx +++ b/vcl/win/source/gdi/salnativewidgets-luna.cxx @@ -1157,15 +1157,15 @@ sal_Bool WinSalGraphics::drawNativeControl( ControlType nType, rc.bottom = buttonRect.Bottom()+1; // set default text alignment - int ta = SetTextAlign( mhDC, TA_LEFT|TA_TOP|TA_NOUPDATECP ); + int ta = SetTextAlign( getHDC(), TA_LEFT|TA_TOP|TA_NOUPDATECP ); OUString aCaptionStr( aCaption.replace('~', '&') ); // translate mnemonics - bOk = ImplDrawNativeControl(mhDC, hTheme, rc, + bOk = ImplDrawNativeControl(getHDC(), hTheme, rc, nType, nPart, nState, aValue, aCaptionStr ); // restore alignment - SetTextAlign( mhDC, ta ); + SetTextAlign( getHDC(), ta ); //GdiFlush(); diff --git a/vcl/win/source/gdi/salprn.cxx b/vcl/win/source/gdi/salprn.cxx index e2dae5fac0d7..79546dc1e402 100644 --- a/vcl/win/source/gdi/salprn.cxx +++ b/vcl/win/source/gdi/salprn.cxx @@ -1444,7 +1444,7 @@ static WinSalGraphics* ImplCreateSalPrnGraphics( HDC hDC ) { WinSalGraphics* pGraphics = new WinSalGraphics; pGraphics->SetLayout( 0 ); - pGraphics->mhDC = hDC; + pGraphics->setHDC(hDC); pGraphics->mhWnd = 0; pGraphics->mbPrinter = TRUE; pGraphics->mbVirDev = FALSE; @@ -1465,7 +1465,7 @@ static sal_Bool ImplUpdateSalPrnIC( WinSalInfoPrinter* pPrinter, ImplJobSetup* p if ( pPrinter->mpGraphics ) { ImplSalDeInitGraphics( pPrinter->mpGraphics ); - DeleteDC( pPrinter->mpGraphics->mhDC ); + DeleteDC( pPrinter->mpGraphics->getHDC() ); delete pPrinter->mpGraphics; } @@ -1533,7 +1533,7 @@ WinSalInfoPrinter::~WinSalInfoPrinter() if ( mpGraphics ) { ImplSalDeInitGraphics( mpGraphics ); - DeleteDC( mpGraphics->mhDC ); + DeleteDC( mpGraphics->getHDC() ); delete mpGraphics; } } diff --git a/vcl/win/source/gdi/salvd.cxx b/vcl/win/source/gdi/salvd.cxx index 0d4cce0be097..e0abdb4572db 100644 --- a/vcl/win/source/gdi/salvd.cxx +++ b/vcl/win/source/gdi/salvd.cxx @@ -94,11 +94,11 @@ SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics, } else { - hDC = CreateCompatibleDC( pGraphics->mhDC ); + hDC = CreateCompatibleDC( pGraphics->getHDC() ); if( !hDC ) ImplWriteLastError( GetLastError(), "CreateCompatibleDC in CreateVirtualDevice" ); - hBmp = ImplCreateVirDevBitmap( pGraphics->mhDC, + hBmp = ImplCreateVirDevBitmap( pGraphics->getHDC(), nDX, nDY, nBitCount ); if( !hBmp ) ImplWriteLastError( GetLastError(), "ImplCreateVirDevBitmap in CreateVirtualDevice" ); @@ -117,7 +117,7 @@ SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics, SalData* pSalData = GetSalData(); WinSalGraphics* pVirGraphics = new WinSalGraphics; pVirGraphics->SetLayout( 0 ); // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL() - pVirGraphics->mhDC = hDC; + pVirGraphics->setHDC(hDC); pVirGraphics->mhWnd = 0; pVirGraphics->mbPrinter = FALSE; pVirGraphics->mbVirDev = TRUE; @@ -130,7 +130,7 @@ SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics, } ImplSalInitGraphics( pVirGraphics ); - pVDev->mhDC = hDC; + pVDev->setHDC(hDC); pVDev->mhBmp = hBmp; if( hBmp ) pVDev->mhDefBmp = SelectBitmap( hDC, hBmp ); @@ -168,7 +168,7 @@ void WinSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice ) WinSalVirtualDevice::WinSalVirtualDevice() { - mhDC = (HDC) NULL; // HDC or 0 for Cache Device + setHDC((HDC)NULL); // HDC or 0 for Cache Device mhBmp = (HBITMAP) NULL; // Memory Bitmap mhDefBmp = (HBITMAP) NULL; // Default Bitmap mpGraphics = NULL; // current VirDev graphics @@ -191,12 +191,12 @@ WinSalVirtualDevice::~WinSalVirtualDevice() // destroy saved DC if( mpGraphics->mhDefPal ) - SelectPalette( mpGraphics->mhDC, mpGraphics->mhDefPal, TRUE ); + SelectPalette( mpGraphics->getHDC(), mpGraphics->mhDefPal, TRUE ); ImplSalDeInitGraphics( mpGraphics ); if( mhDefBmp ) - SelectBitmap( mpGraphics->mhDC, mhDefBmp ); + SelectBitmap( mpGraphics->getHDC(), mhDefBmp ); if( !mbForeignDC ) - DeleteDC( mpGraphics->mhDC ); + DeleteDC( mpGraphics->getHDC() ); if( mhBmp ) DeleteBitmap( mhBmp ); delete mpGraphics; @@ -231,11 +231,11 @@ sal_Bool WinSalVirtualDevice::SetSize( long nDX, long nDY ) return TRUE; // ??? else { - HBITMAP hNewBmp = ImplCreateVirDevBitmap( mhDC, nDX, nDY, + HBITMAP hNewBmp = ImplCreateVirDevBitmap( getHDC(), nDX, nDY, mnBitCount ); if ( hNewBmp ) { - SelectBitmap( mhDC, hNewBmp ); + SelectBitmap( getHDC(), hNewBmp ); DeleteBitmap( mhBmp ); mhBmp = hNewBmp; return TRUE; @@ -250,6 +250,6 @@ sal_Bool WinSalVirtualDevice::SetSize( long nDX, long nDY ) void WinSalVirtualDevice::GetSize( long& rWidth, long& rHeight ) { - rWidth = GetDeviceCaps( mhDC, HORZRES ); - rHeight= GetDeviceCaps( mhDC, VERTRES ); + rWidth = GetDeviceCaps( getHDC(), HORZRES ); + rHeight= GetDeviceCaps( getHDC(), VERTRES ); } diff --git a/vcl/win/source/gdi/winlayout.cxx b/vcl/win/source/gdi/winlayout.cxx index eb8c88985dc4..ca4d0428208e 100644 --- a/vcl/win/source/gdi/winlayout.cxx +++ b/vcl/win/source/gdi/winlayout.cxx @@ -644,7 +644,7 @@ void SimpleWinLayout::DrawText( SalGraphics& rGraphics ) const return; WinSalGraphics& rWinGraphics = static_cast<WinSalGraphics&>(rGraphics); - HDC aHDC = rWinGraphics.mhDC; + HDC aHDC = rWinGraphics.getHDC(); HFONT hOrigFont = DisableFontScaling(); @@ -3021,7 +3021,7 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe else #endif // ENABLE_GRAPHITE // script complexity is determined in upper layers - pWinLayout = new UniscribeLayout( mhDC, rFontFace, rFontInstance ); + pWinLayout = new UniscribeLayout( getHDC(), rFontFace, rFontInstance ); // NOTE: it must be guaranteed that the WinSalGraphics lives longer than // the created UniscribeLayout, otherwise the data passed into the // constructor might become invalid too early @@ -3047,7 +3047,7 @@ SalLayout* WinSalGraphics::GetTextLayout( ImplLayoutArgs& rArgs, int nFallbackLe pWinLayout = new GraphiteWinLayout(mhDC, rFontFace, rFontInstance); else #endif // ENABLE_GRAPHITE - pWinLayout = new SimpleWinLayout( mhDC, eCharSet, rFontFace, rFontInstance ); + pWinLayout = new SimpleWinLayout( getHDC(), eCharSet, rFontFace, rFontInstance ); } if( mfFontScale != 1.0 ) @@ -3062,7 +3062,7 @@ int WinSalGraphics::GetMinKashidaWidth() { if( !mpWinFontEntry[0] ) return 0; - mpWinFontEntry[0]->InitKashidaHandling( mhDC ); + mpWinFontEntry[0]->InitKashidaHandling( getHDC() ); int nMinKashida = static_cast<int>(mfFontScale * mpWinFontEntry[0]->GetMinKashidaWidth()); return nMinKashida; } diff --git a/vcl/win/source/window/salframe.cxx b/vcl/win/source/window/salframe.cxx index d2d76b1ad4c2..e0db2d123503 100644 --- a/vcl/win/source/window/salframe.cxx +++ b/vcl/win/source/window/salframe.cxx @@ -1053,16 +1053,16 @@ WinSalFrame::~WinSalFrame() // Release Cache DC if ( mpGraphics2 && - mpGraphics2->mhDC ) + mpGraphics2->getHDC() ) ReleaseGraphics( mpGraphics2 ); // destroy saved DC if ( mpGraphics ) { if ( mpGraphics->mhDefPal ) - SelectPalette( mpGraphics->mhDC, mpGraphics->mhDefPal, TRUE ); + SelectPalette( mpGraphics->getHDC(), mpGraphics->mhDefPal, TRUE ); ImplSalDeInitGraphics( mpGraphics ); - ReleaseDC( mhWnd, mpGraphics->mhDC ); + ReleaseDC( mhWnd, mpGraphics->getHDC() ); delete mpGraphics; mpGraphics = NULL; } @@ -1109,7 +1109,7 @@ SalGraphics* WinSalFrame::GetGraphics() if ( !mpGraphics2 ) { mpGraphics2 = new WinSalGraphics; - mpGraphics2->mhDC = 0; + mpGraphics2->setHDC(0); mpGraphics2->mhWnd = mhWnd; mpGraphics2->mbPrinter = FALSE; mpGraphics2->mbVirDev = FALSE; @@ -1122,7 +1122,7 @@ SalGraphics* WinSalFrame::GetGraphics() (WPARAM)mhWnd, 0 ); if ( hDC ) { - mpGraphics2->mhDC = hDC; + mpGraphics2->setHDC(hDC); if ( pSalData->mhDitherPal ) { mpGraphics2->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE ); @@ -1145,7 +1145,7 @@ SalGraphics* WinSalFrame::GetGraphics() if ( hDC ) { mpGraphics = new WinSalGraphics; - mpGraphics->mhDC = hDC; + mpGraphics->setHDC(hDC); mpGraphics->mhWnd = mhWnd; mpGraphics->mbPrinter = FALSE; mpGraphics->mbVirDev = FALSE; @@ -1173,17 +1173,17 @@ void WinSalFrame::ReleaseGraphics( SalGraphics* pGraphics ) { if ( mpGraphics2 == pGraphics ) { - if ( mpGraphics2->mhDC ) + if ( mpGraphics2->getHDC() ) { SalData* pSalData = GetSalData(); if ( mpGraphics2->mhDefPal ) - SelectPalette( mpGraphics2->mhDC, mpGraphics2->mhDefPal, TRUE ); + SelectPalette( mpGraphics2->getHDC(), mpGraphics2->mhDefPal, TRUE ); ImplSalDeInitGraphics( mpGraphics2 ); ImplSendMessage( pSalData->mpFirstInstance->mhComWnd, SAL_MSG_RELEASEDC, (WPARAM)mhWnd, - (LPARAM)mpGraphics2->mhDC ); - mpGraphics2->mhDC = 0; + (LPARAM)mpGraphics2->getHDC() ); + mpGraphics2->setHDC(0); pSalData->mnCacheDCInUse--; } } @@ -1679,12 +1679,12 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, sal_Bool // Release Cache DC if ( pThis->mpGraphics2 && - pThis->mpGraphics2->mhDC ) + pThis->mpGraphics2->getHDC() ) { // save current gdi objects before hdc is gone - hFont = (HFONT) GetCurrentObject( pThis->mpGraphics2->mhDC, OBJ_FONT); - hPen = (HPEN) GetCurrentObject( pThis->mpGraphics2->mhDC, OBJ_PEN); - hBrush = (HBRUSH) GetCurrentObject( pThis->mpGraphics2->mhDC, OBJ_BRUSH); + hFont = (HFONT) GetCurrentObject( pThis->mpGraphics2->getHDC(), OBJ_FONT); + hPen = (HPEN) GetCurrentObject( pThis->mpGraphics2->getHDC(), OBJ_PEN); + hBrush = (HBRUSH) GetCurrentObject( pThis->mpGraphics2->getHDC(), OBJ_BRUSH); pThis->ReleaseGraphics( pThis->mpGraphics2 ); // recreate cache dc only if it was destroyed @@ -1695,9 +1695,9 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, sal_Bool if ( pThis->mpGraphics ) { if ( pThis->mpGraphics->mhDefPal ) - SelectPalette( pThis->mpGraphics->mhDC, pThis->mpGraphics->mhDefPal, TRUE ); + SelectPalette( pThis->mpGraphics->getHDC(), pThis->mpGraphics->mhDefPal, TRUE ); ImplSalDeInitGraphics( pThis->mpGraphics ); - ReleaseDC( pThis->mhWnd, pThis->mpGraphics->mhDC ); + ReleaseDC( pThis->mhWnd, pThis->mpGraphics->getHDC() ); } // create a new hwnd with the same styles @@ -1725,7 +1725,7 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, sal_Bool (WPARAM) hWnd, 0 ); if ( hDC ) { - pThis->mpGraphics2->mhDC = hDC; + pThis->mpGraphics2->setHDC(hDC); if ( pSalData->mhDitherPal ) { pThis->mpGraphics2->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE ); @@ -1754,11 +1754,11 @@ static void ImplSetParentFrame( WinSalFrame* pThis, HWND hNewParentWnd, sal_Bool { // re-create DC pThis->mpGraphics->mhWnd = hWnd; - pThis->mpGraphics->mhDC = GetDC( hWnd ); + pThis->mpGraphics->setHDC( GetDC( hWnd ) ); if ( GetSalData()->mhDitherPal ) { - pThis->mpGraphics->mhDefPal = SelectPalette( pThis->mpGraphics->mhDC, GetSalData()->mhDitherPal, TRUE ); - RealizePalette( pThis->mpGraphics->mhDC ); + pThis->mpGraphics->mhDefPal = SelectPalette( pThis->mpGraphics->getHDC(), GetSalData()->mhDitherPal, TRUE ); + RealizePalette( pThis->mpGraphics->getHDC() ); } ImplSalInitGraphics( pThis->mpGraphics ); pThis->mbGraphics = TRUE; @@ -3724,8 +3724,8 @@ static long ImplHandleKeyMsg( HWND hWnd, UINT nMsg, // Wir restaurieren den Background-Modus bei jeder Texteingabe, // da einige Tools wie RichWin uns diesen hin- und wieder umsetzen if ( pFrame->mpGraphics && - pFrame->mpGraphics->mhDC ) - SetBkMode( pFrame->mpGraphics->mhDC, TRANSPARENT ); + pFrame->mpGraphics->getHDC() ) + SetBkMode( pFrame->mpGraphics->getHDC(), TRANSPARENT ); // determine modifiers if ( GetKeyState( VK_SHIFT ) & 0x8000 ) @@ -4088,7 +4088,7 @@ static bool ImplHandlePaintMsg( HWND hWnd ) // Clip-Region muss zurueckgesetzt werden, da wir sonst kein // ordentliches Bounding-Rectangle bekommen if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion ) - SelectClipRgn( pFrame->mpGraphics->mhDC, 0 ); + SelectClipRgn( pFrame->mpGraphics->getHDC(), 0 ); // Laut Window-Doku soll man erst abfragen, ob ueberhaupt eine // Paint-Region anliegt @@ -4105,7 +4105,7 @@ static bool ImplHandlePaintMsg( HWND hWnd ) // ClipRegion wieder herstellen if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion ) { - SelectClipRgn( pFrame->mpGraphics->mhDC, + SelectClipRgn( pFrame->mpGraphics->getHDC(), pFrame->mpGraphics->mhRegion ); } @@ -4127,7 +4127,7 @@ static bool ImplHandlePaintMsg( HWND hWnd ) // ClipRegion wieder herstellen if ( pFrame->mpGraphics && pFrame->mpGraphics->mhRegion ) { - SelectClipRgn( pFrame->mpGraphics->mhDC, + SelectClipRgn( pFrame->mpGraphics->getHDC(), pFrame->mpGraphics->mhRegion ); } } @@ -4510,8 +4510,8 @@ static void ImplHandleForcePalette( HWND hWnd ) WinSalGraphics* pGraphics = pFrame->mpGraphics; if ( pGraphics && pGraphics->mhDefPal ) { - SelectPalette( pGraphics->mhDC, hPal, FALSE ); - if ( RealizePalette( pGraphics->mhDC ) ) + SelectPalette( pGraphics->getHDC(), hPal, FALSE ); + if ( RealizePalette( pGraphics->getHDC() ) ) { InvalidateRect( hWnd, NULL, FALSE ); UpdateWindow( hWnd ); @@ -4575,7 +4575,7 @@ static LRESULT ImplHandlePalette( sal_Bool bFrame, HWND hWnd, UINT nMsg, pGraphics = pTempVD->mpGraphics; if ( pGraphics->mhDefPal ) { - SelectPalette( pGraphics->mhDC, + SelectPalette( pGraphics->getHDC(), pGraphics->mhDefPal, TRUE ); } @@ -4587,7 +4587,7 @@ static LRESULT ImplHandlePalette( sal_Bool bFrame, HWND hWnd, UINT nMsg, pGraphics = pTempFrame->mpGraphics; if ( pGraphics && pGraphics->mhDefPal ) { - SelectPalette( pGraphics->mhDC, + SelectPalette( pGraphics->getHDC(), pGraphics->mhDefPal, TRUE ); } @@ -4600,7 +4600,7 @@ static LRESULT ImplHandlePalette( sal_Bool bFrame, HWND hWnd, UINT nMsg, pFrame = GetWindowPtr( hWnd ); if ( pFrame && pFrame->mpGraphics ) { - hDC = pFrame->mpGraphics->mhDC; + hDC = pFrame->mpGraphics->getHDC(); bStdDC = TRUE; } else @@ -4625,8 +4625,8 @@ static LRESULT ImplHandlePalette( sal_Bool bFrame, HWND hWnd, UINT nMsg, pGraphics = pTempVD->mpGraphics; if ( pGraphics->mhDefPal ) { - SelectPalette( pGraphics->mhDC, hPal, TRUE ); - RealizePalette( pGraphics->mhDC ); + SelectPalette( pGraphics->getHDC(), hPal, TRUE ); + RealizePalette( pGraphics->getHDC() ); } pTempVD = pTempVD->mpNext; } @@ -4638,8 +4638,8 @@ static LRESULT ImplHandlePalette( sal_Bool bFrame, HWND hWnd, UINT nMsg, pGraphics = pTempFrame->mpGraphics; if ( pGraphics && pGraphics->mhDefPal ) { - SelectPalette( pGraphics->mhDC, hPal, TRUE ); - if ( RealizePalette( pGraphics->mhDC ) ) + SelectPalette( pGraphics->getHDC(), hPal, TRUE ); + if ( RealizePalette( pGraphics->getHDC() ) ) bUpdate = TRUE; } } @@ -5520,8 +5520,8 @@ static sal_Bool ImplHandleIMEComposition( HWND hWnd, LPARAM lParam ) // Wir restaurieren den Background-Modus bei jeder Texteingabe, // da einige Tools wie RichWin uns diesen hin- und wieder umsetzen if ( pFrame->mpGraphics && - pFrame->mpGraphics->mhDC ) - SetBkMode( pFrame->mpGraphics->mhDC, TRANSPARENT ); + pFrame->mpGraphics->getHDC() ) + SetBkMode( pFrame->mpGraphics->getHDC(), TRANSPARENT ); } if ( pFrame && pFrame->mbHandleIME ) |