Kaydet (Commit) a13007ad authored tarafından Michael Meeks's avatar Michael Meeks

vcl: fix virtual device lifecycle.

Also remove an over-optimistic assert & ref-holding in dispose piece.

Change-Id: I6ce6abb666c8143502fc450a26e1ba2aac787455
üst efa40d41
......@@ -118,6 +118,7 @@ public:
sal_uInt16 nBitCount);
virtual ~VirtualDevice();
virtual void dispose() SAL_OVERRIDE;
virtual void EnableRTL( bool bEnable = true ) SAL_OVERRIDE;
......
......@@ -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,
......
......@@ -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() )
{
......
......@@ -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,
......
......@@ -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();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment