summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2015-03-16 17:27:11 +0000
committerMichael Meeks <michael.meeks@collabora.com>2015-04-10 11:32:24 +0100
commita13007adddadf7f5c7b503d6732cf11f3e62e619 (patch)
tree0b9bbc1c7019ba2d2396bc5affcca87ad61a9c00 /vcl
parentefa40d415046d377b293fea14a4a3c3fd1bf0129 (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.cxx8
-rw-r--r--vcl/source/filter/wmf/winmtf.cxx40
-rw-r--r--vcl/source/gdi/virdev.cxx8
-rw-r--r--vcl/source/outdev/outdev.cxx9
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();
}