diff options
author | Michael Meeks <michael.meeks@collabora.com> | 2015-03-16 17:27:11 +0000 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2015-04-10 11:32:24 +0100 |
commit | a13007adddadf7f5c7b503d6732cf11f3e62e619 (patch) | |
tree | 0b9bbc1c7019ba2d2396bc5affcca87ad61a9c00 /vcl | |
parent | efa40d415046d377b293fea14a4a3c3fd1bf0129 (diff) |
vcl: fix virtual device lifecycle.
Also remove an over-optimistic assert & ref-holding in dispose piece.
Change-Id: I6ce6abb666c8143502fc450a26e1ba2aac787455
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/qa/cppunit/lifecycle.cxx | 8 | ||||
-rw-r--r-- | vcl/source/filter/wmf/winmtf.cxx | 40 | ||||
-rw-r--r-- | vcl/source/gdi/virdev.cxx | 8 | ||||
-rw-r--r-- | vcl/source/outdev/outdev.cxx | 9 |
4 files changed, 42 insertions, 23 deletions
diff --git a/vcl/qa/cppunit/lifecycle.cxx b/vcl/qa/cppunit/lifecycle.cxx index 04a4719d2e3f..8be94a5f6c3e 100644 --- a/vcl/qa/cppunit/lifecycle.cxx +++ b/vcl/qa/cppunit/lifecycle.cxx @@ -15,6 +15,7 @@ #include <vcl/edit.hxx> #include <vcl/combobox.hxx> #include <vcl/field.hxx> +#include <vcl/virdev.hxx> class LifecycleTest : public test::BootstrapFixture { @@ -24,6 +25,7 @@ public: LifecycleTest() : BootstrapFixture(true, false) {} void testCast(); + void testVirtualDevice(); void testMultiDispose(); void testIsolatedWidgets(); void testParentedWidgets(); @@ -31,6 +33,7 @@ public: CPPUNIT_TEST_SUITE(LifecycleTest); CPPUNIT_TEST(testCast); + CPPUNIT_TEST(testVirtualDevice); CPPUNIT_TEST(testMultiDispose); CPPUNIT_TEST(testIsolatedWidgets); CPPUNIT_TEST(testParentedWidgets); @@ -52,6 +55,11 @@ void LifecycleTest::testCast() // VclPtr<PushButton> xButton2(xWindow); } +void LifecycleTest::testVirtualDevice() +{ + VclPtr<VirtualDevice> pVDev = new VirtualDevice(); +} + void LifecycleTest::testMultiDispose() { VclPtr<WorkWindow> xWin(new WorkWindow((vcl::Window *)NULL, diff --git a/vcl/source/filter/wmf/winmtf.cxx b/vcl/source/filter/wmf/winmtf.cxx index 72c20cb0ac25..1e807f1bb001 100644 --- a/vcl/source/filter/wmf/winmtf.cxx +++ b/vcl/source/filter/wmf/winmtf.cxx @@ -236,12 +236,12 @@ WinMtfFontStyle::WinMtfFontStyle( LOGFONTW& rFont ) { // #i117968# VirtualDevice is not thread safe, but filter is used in multithreading SolarMutexGuard aGuard; - VirtualDevice aVDev; + VclPtr<VirtualDevice> pVDev = new VirtualDevice(); // converting the cell height into a font height aFont.SetSize( aFontSize ); - aVDev.SetFont( aFont ); - FontMetric aMetric( aVDev.GetFontMetric() ); + pVDev->SetFont( aFont ); + FontMetric aMetric( pVDev->GetFontMetric() ); long nHeight = aMetric.GetAscent() + aMetric.GetDescent(); if (nHeight) { @@ -1448,20 +1448,20 @@ void WinMtfOutput::DrawText( Point& rPosition, OUString& rText, long* pDXArry, b { // #i117968# VirtualDevice is not thread safe, but filter is used in multithreading SolarMutexGuard aGuard; - VirtualDevice aVDev; + VclPtr<VirtualDevice> pVDev = new VirtualDevice(); sal_Int32 nTextWidth; - aVDev.SetMapMode( MapMode( MAP_100TH_MM ) ); - aVDev.SetFont( maFont ); + pVDev->SetMapMode( MapMode( MAP_100TH_MM ) ); + pVDev->SetFont( maFont ); if( pDXArry ) { sal_uInt32 nLen = rText.getLength(); - nTextWidth = aVDev.GetTextWidth( OUString(rText[ nLen - 1 ]) ); + nTextWidth = pVDev->GetTextWidth( OUString(rText[ nLen - 1 ]) ); if( nLen > 1 ) nTextWidth += pDXArry[ nLen - 2 ]; } else - nTextWidth = aVDev.GetTextWidth( rText ); + nTextWidth = pVDev->GetTextWidth( rText ); if( mnTextAlign & TA_UPDATECP ) rPosition = maActPos; @@ -1497,12 +1497,12 @@ void WinMtfOutput::DrawText( Point& rPosition, OUString& rText, long* pDXArry, b { // #i117968# VirtualDevice is not thread safe, but filter is used in multithreading SolarMutexGuard aGuard; - VirtualDevice aVDev; + VclPtr<VirtualDevice> pVDev = new VirtualDevice(); pDX = new long[ rText.getLength() ]; - aVDev.SetMapMode( MAP_100TH_MM ); - aVDev.SetFont( maLatestFont ); - aVDev.GetTextArray( rText, pDX, 0, rText.getLength()); + pVDev->SetMapMode( MAP_100TH_MM ); + pVDev->SetFont( maLatestFont ); + pVDev->GetTextArray( rText, pDX, 0, rText.getLength()); } mpGDIMetaFile->AddAction( new MetaTextArrayAction( rPosition, rText, pDX, 0, rText.getLength() ) ); if ( !pDXArry ) // this means we have created our own array @@ -1516,26 +1516,26 @@ void WinMtfOutput::ImplDrawBitmap( const Point& rPos, const Size& rSize, const B BitmapEx aBmpEx( rBitmap ); if ( mbComplexClip ) { - VirtualDevice aVDev; + VclPtr<VirtualDevice> pVDev = new VirtualDevice(); MapMode aMapMode( MAP_100TH_MM ); aMapMode.SetOrigin( Point( -rPos.X(), -rPos.Y() ) ); - const Size aOutputSizePixel( aVDev.LogicToPixel( rSize, aMapMode ) ); + const Size aOutputSizePixel( pVDev->LogicToPixel( rSize, aMapMode ) ); const Size aSizePixel( rBitmap.GetSizePixel() ); if ( aOutputSizePixel.Width() && aOutputSizePixel.Height() ) { aMapMode.SetScaleX( Fraction( aSizePixel.Width(), aOutputSizePixel.Width() ) ); aMapMode.SetScaleY( Fraction( aSizePixel.Height(), aOutputSizePixel.Height() ) ); } - aVDev.SetMapMode( aMapMode ); - aVDev.SetOutputSizePixel( aSizePixel ); - aVDev.SetFillColor( Color( COL_BLACK ) ); + pVDev->SetMapMode( aMapMode ); + pVDev->SetOutputSizePixel( aSizePixel ); + pVDev->SetFillColor( Color( COL_BLACK ) ); const tools::PolyPolygon aClip( aClipPath.getClipPath() ); - aVDev.DrawPolyPolygon( aClip ); + pVDev->DrawPolyPolygon( aClip ); const Point aEmptyPoint; // #i50672# Extract whole VDev content (to match size of rBitmap) - aVDev.EnableMapMode( false ); - Bitmap aMask( aVDev.GetBitmap( aEmptyPoint, aSizePixel ).CreateMask( Color( COL_WHITE ) ) ); + pVDev->EnableMapMode( false ); + Bitmap aMask( pVDev->GetBitmap( aEmptyPoint, aSizePixel ).CreateMask( Color( COL_WHITE ) ) ); if ( aBmpEx.IsTransparent() ) { diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx index eec2fa98768b..b8ce392e1773 100644 --- a/vcl/source/gdi/virdev.cxx +++ b/vcl/source/gdi/virdev.cxx @@ -255,6 +255,12 @@ VirtualDevice::VirtualDevice(const SystemGraphicsData *pData, const Size &rSize, VirtualDevice::~VirtualDevice() { SAL_INFO( "vcl.gdi", "VirtualDevice::~VirtualDevice()" ); + disposeOnce(); +} + +void VirtualDevice::dispose() +{ + SAL_INFO( "vcl.gdi", "VirtualDevice::dispose()" ); ImplSVData* pSVData = ImplGetSVData(); @@ -272,6 +278,8 @@ VirtualDevice::~VirtualDevice() mpNext->mpPrev = mpPrev; else pSVData->maGDIData.mpLastVirDev = mpPrev; + + OutputDevice::dispose(); } bool VirtualDevice::InnerImplSetOutputSizePixel( const Size& rNewSize, bool bErase, diff --git a/vcl/source/outdev/outdev.cxx b/vcl/source/outdev/outdev.cxx index 5d59ee104029..d39a76d5ce57 100644 --- a/vcl/source/outdev/outdev.cxx +++ b/vcl/source/outdev/outdev.cxx @@ -82,6 +82,7 @@ namespace { // Begin initializer and accessor public functions OutputDevice::OutputDevice() : + mnRefCnt(0), maRegion(true), maFillColor( COL_WHITE ), maTextLineColor( COL_TRANSPARENT ), @@ -179,6 +180,8 @@ OutputDevice::OutputDevice() : // #i75163# mpOutDevData->mpViewTransform = NULL; mpOutDevData->mpInverseViewTransform = NULL; + + mbDisposed = false; } OutputDevice::~OutputDevice() @@ -194,10 +197,10 @@ void OutputDevice::disposeOnce() // catch badness where our OutputDevice sub-class was not // wrapped safely in a VclPtr cosily. - assert( mnRefCnt > 0 ); + // FIXME: as/when we make our destructors all protected, + // we should introduce this assert: + // assert( mnRefCnt > 0 ); - // hold a ref in case something unusual happens during dispose. - VclPtr<OutputDevice> aRef(this); dispose(); } |