summaryrefslogtreecommitdiff
path: root/vcl/source/gdi/virdev.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/gdi/virdev.cxx')
-rw-r--r--vcl/source/gdi/virdev.cxx452
1 files changed, 452 insertions, 0 deletions
diff --git a/vcl/source/gdi/virdev.cxx b/vcl/source/gdi/virdev.cxx
new file mode 100644
index 000000000000..a13e272e368b
--- /dev/null
+++ b/vcl/source/gdi/virdev.cxx
@@ -0,0 +1,452 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: virdev.cxx,v $
+ * $Revision: 1.33 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_vcl.hxx"
+
+#ifndef _SV_SVSYS_HXX
+#include <svsys.h>
+#endif
+#include <vcl/salinst.hxx>
+#include <vcl/salgdi.hxx>
+#include <vcl/salframe.hxx>
+#include <vcl/salvd.hxx>
+#include <tools/debug.hxx>
+#include <vcl/svdata.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/wrkwin.hxx>
+#include <vcl/outdev.h>
+#include <vcl/virdev.hxx>
+
+using namespace ::com::sun::star::uno;
+
+// =======================================================================
+
+void VirtualDevice::ImplInitVirDev( const OutputDevice* pOutDev,
+ long nDX, long nDY, USHORT nBitCount, const SystemGraphicsData *pData )
+{
+ DBG_ASSERT( nBitCount <= 1,
+ "VirtualDevice::VirtualDevice(): Only 0 or 1 is for BitCount allowed" );
+
+ if ( nDX < 1 )
+ nDX = 1;
+
+ if ( nDY < 1 )
+ nDY = 1;
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if ( !pOutDev )
+ pOutDev = ImplGetDefaultWindow();
+ if( !pOutDev )
+ return;
+
+ SalGraphics* pGraphics;
+ if ( !pOutDev->mpGraphics )
+ ((OutputDevice*)pOutDev)->ImplGetGraphics();
+ pGraphics = pOutDev->mpGraphics;
+ if ( pGraphics )
+ mpVirDev = pSVData->mpDefInst->CreateVirtualDevice( pGraphics, nDX, nDY, nBitCount, pData );
+ else
+ mpVirDev = NULL;
+ if ( !mpVirDev )
+ {
+ // do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario)
+ throw ::com::sun::star::uno::RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not create system bitmap!" ) ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+ //GetpApp()->Exception( EXC_SYSOBJNOTCREATED );
+ }
+
+ mnBitCount = ( nBitCount ? nBitCount : pOutDev->GetBitCount() );
+ mnOutWidth = nDX;
+ mnOutHeight = nDY;
+ mbScreenComp = TRUE;
+ mnAlphaDepth = -1;
+
+ // #i59315# init vdev size from system object, when passed a
+ // SystemGraphicsData. Otherwise, output size will always
+ // incorrectly stay at (1,1)
+ if( pData && mpVirDev )
+ mpVirDev->GetSize(mnOutWidth,mnOutHeight);
+
+ if( mnBitCount < 8 )
+ SetAntialiasing( ANTIALIASING_DISABLE_TEXT );
+
+ if ( pOutDev->GetOutDevType() == OUTDEV_PRINTER )
+ mbScreenComp = FALSE;
+ else if ( pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
+ mbScreenComp = ((VirtualDevice*)pOutDev)->mbScreenComp;
+
+ meOutDevType = OUTDEV_VIRDEV;
+ mbDevOutput = TRUE;
+ mpFontList = pSVData->maGDIData.mpScreenFontList;
+ mpFontCache = pSVData->maGDIData.mpScreenFontCache;
+ mnDPIX = pOutDev->mnDPIX;
+ mnDPIY = pOutDev->mnDPIY;
+ maFont = pOutDev->maFont;
+
+ if( maTextColor != pOutDev->maTextColor )
+ {
+ maTextColor = pOutDev->maTextColor;
+ mbInitTextColor = true;
+ }
+
+ // Virtuelle Devices haben defaultmaessig einen weissen Hintergrund
+ SetBackground( Wallpaper( Color( COL_WHITE ) ) );
+
+ // #i59283# don't erase user-provided surface
+ if( !pData )
+ Erase();
+
+ // VirDev in Liste eintragen
+ mpNext = pSVData->maGDIData.mpFirstVirDev;
+ mpPrev = NULL;
+ if ( mpNext )
+ mpNext->mpPrev = this;
+ else
+ pSVData->maGDIData.mpLastVirDev = this;
+ pSVData->maGDIData.mpFirstVirDev = this;
+}
+
+// -----------------------------------------------------------------------
+
+VirtualDevice::VirtualDevice( USHORT nBitCount )
+: mpVirDev( NULL ),
+ meRefDevMode( REFDEV_NONE )
+{
+ DBG_TRACE1( "VirtualDevice::VirtualDevice( %hu )", nBitCount );
+
+ ImplInitVirDev( Application::GetDefaultDevice(), 1, 1, nBitCount );
+}
+
+// -----------------------------------------------------------------------
+
+VirtualDevice::VirtualDevice( const OutputDevice& rCompDev, USHORT nBitCount )
+ : mpVirDev( NULL ),
+ meRefDevMode( REFDEV_NONE )
+{
+ DBG_TRACE1( "VirtualDevice::VirtualDevice( %hu )", nBitCount );
+
+ ImplInitVirDev( &rCompDev, 1, 1, nBitCount );
+}
+
+// -----------------------------------------------------------------------
+
+VirtualDevice::VirtualDevice( const OutputDevice& rCompDev, USHORT nBitCount, USHORT nAlphaBitCount )
+ : mpVirDev( NULL ),
+ meRefDevMode( REFDEV_NONE )
+{
+ DBG_TRACE1( "VirtualDevice::VirtualDevice( %hu )", nBitCount );
+
+ ImplInitVirDev( &rCompDev, 1, 1, nBitCount );
+
+ // #110958# Enable alpha channel
+ mnAlphaDepth = sal::static_int_cast<sal_Int8>(nAlphaBitCount);
+}
+
+// -----------------------------------------------------------------------
+
+VirtualDevice::VirtualDevice( const SystemGraphicsData *pData, USHORT nBitCount )
+: mpVirDev( NULL ),
+ meRefDevMode( REFDEV_NONE )
+{
+ DBG_TRACE1( "VirtualDevice::VirtualDevice( %hu )", nBitCount );
+
+ ImplInitVirDev( Application::GetDefaultDevice(), 1, 1, nBitCount, pData );
+}
+
+// -----------------------------------------------------------------------
+
+VirtualDevice::~VirtualDevice()
+{
+ DBG_TRACE( "VirtualDevice::~VirtualDevice()" );
+
+ ImplSVData* pSVData = ImplGetSVData();
+
+ ImplReleaseGraphics();
+
+ if ( mpVirDev )
+ pSVData->mpDefInst->DestroyVirtualDevice( mpVirDev );
+
+ // remove this VirtualDevice from the double-linked global list
+ if( mpPrev )
+ mpPrev->mpNext = mpNext;
+ else
+ pSVData->maGDIData.mpFirstVirDev = mpNext;
+
+ if( mpNext )
+ mpNext->mpPrev = mpPrev;
+ else
+ pSVData->maGDIData.mpLastVirDev = mpPrev;
+}
+
+// -----------------------------------------------------------------------
+
+BOOL VirtualDevice::ImplSetOutputSizePixel( const Size& rNewSize, BOOL bErase )
+{
+ DBG_TRACE3( "VirtualDevice::ImplSetOutputSizePixel( %ld, %ld, %d )", rNewSize.Width(), rNewSize.Height(), (int)bErase );
+
+ if ( !mpVirDev )
+ return FALSE;
+ else if ( rNewSize == GetOutputSizePixel() )
+ {
+ if ( bErase )
+ Erase();
+ return TRUE;
+ }
+
+ BOOL bRet;
+ long nNewWidth = rNewSize.Width(), nNewHeight = rNewSize.Height();
+
+ if ( nNewWidth < 1 )
+ nNewWidth = 1;
+
+ if ( nNewHeight < 1 )
+ nNewHeight = 1;
+
+ if ( bErase )
+ {
+ bRet = mpVirDev->SetSize( nNewWidth, nNewHeight );
+
+ if ( bRet )
+ {
+ mnOutWidth = rNewSize.Width();
+ mnOutHeight = rNewSize.Height();
+ Erase();
+ }
+ }
+ else
+ {
+ SalVirtualDevice* pNewVirDev;
+ ImplSVData* pSVData = ImplGetSVData();
+
+ // we need a graphics
+ if ( !mpGraphics )
+ {
+ if ( !ImplGetGraphics() )
+ return FALSE;
+ }
+
+ pNewVirDev = pSVData->mpDefInst->CreateVirtualDevice( mpGraphics, nNewWidth, nNewHeight, mnBitCount );
+ if ( pNewVirDev )
+ {
+ SalGraphics* pGraphics = pNewVirDev->GetGraphics();
+ if ( pGraphics )
+ {
+ SalTwoRect aPosAry;
+ long nWidth;
+ long nHeight;
+ if ( mnOutWidth < nNewWidth )
+ nWidth = mnOutWidth;
+ else
+ nWidth = nNewWidth;
+ if ( mnOutHeight < nNewHeight )
+ nHeight = mnOutHeight;
+ else
+ nHeight = nNewHeight;
+ aPosAry.mnSrcX = 0;
+ aPosAry.mnSrcY = 0;
+ aPosAry.mnSrcWidth = nWidth;
+ aPosAry.mnSrcHeight = nHeight;
+ aPosAry.mnDestX = 0;
+ aPosAry.mnDestY = 0;
+ aPosAry.mnDestWidth = nWidth;
+ aPosAry.mnDestHeight = nHeight;
+
+ pGraphics->CopyBits( &aPosAry, mpGraphics, this, this );
+ pNewVirDev->ReleaseGraphics( pGraphics );
+ ImplReleaseGraphics();
+ pSVData->mpDefInst->DestroyVirtualDevice( mpVirDev );
+ mpVirDev = pNewVirDev;
+ mnOutWidth = rNewSize.Width();
+ mnOutHeight = rNewSize.Height();
+ bRet = TRUE;
+ }
+ else
+ {
+ bRet = FALSE;
+ pSVData->mpDefInst->DestroyVirtualDevice( pNewVirDev );
+ }
+ }
+ else
+ bRet = FALSE;
+ }
+
+ return bRet;
+}
+
+// -----------------------------------------------------------------------
+
+// #i32109#: Fill opaque areas correctly (without relying on
+// fill/linecolor state)
+void VirtualDevice::ImplFillOpaqueRectangle( const Rectangle& rRect )
+{
+ // Set line and fill color to black (->opaque),
+ // fill rect with that (linecolor, too, because of
+ // those pesky missing pixel problems)
+ Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
+ SetLineColor( COL_BLACK );
+ SetFillColor( COL_BLACK );
+ DrawRect( rRect );
+ Pop();
+}
+
+// -----------------------------------------------------------------------
+
+BOOL VirtualDevice::SetOutputSizePixel( const Size& rNewSize, BOOL bErase )
+{
+ if( ImplSetOutputSizePixel(rNewSize, bErase) )
+ {
+ if( mnAlphaDepth != -1 )
+ {
+ // #110958# Setup alpha bitmap
+ if(mpAlphaVDev && mpAlphaVDev->GetOutputSizePixel() != rNewSize)
+ {
+ delete mpAlphaVDev;
+ mpAlphaVDev = 0L;
+ }
+
+ if( !mpAlphaVDev )
+ {
+ mpAlphaVDev = new VirtualDevice( *this, mnAlphaDepth );
+ mpAlphaVDev->ImplSetOutputSizePixel(rNewSize, bErase);
+ }
+
+ // TODO: copy full outdev state to new one, here. Also needed in outdev2.cxx:DrawOutDev
+ if( GetLineColor() != Color( COL_TRANSPARENT ) )
+ mpAlphaVDev->SetLineColor( COL_BLACK );
+
+ if( GetFillColor() != Color( COL_TRANSPARENT ) )
+ mpAlphaVDev->SetFillColor( COL_BLACK );
+
+ mpAlphaVDev->SetMapMode( GetMapMode() );
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+// -----------------------------------------------------------------------
+
+void VirtualDevice::SetReferenceDevice( RefDevMode i_eRefDevMode )
+{
+ sal_Int32 nDPIX = 600, nDPIY = 600;
+ switch( i_eRefDevMode )
+ {
+ case REFDEV_NONE:
+ default:
+ DBG_ASSERT( FALSE, "VDev::SetRefDev illegal argument!" );
+ break;
+ case REFDEV_MODE06:
+ nDPIX = nDPIY = 600;
+ break;
+ case REFDEV_MODE48:
+ nDPIX = nDPIY = 4800;
+ break;
+ case REFDEV_MODE_MSO1:
+ nDPIX = nDPIY = 6*1440;
+ break;
+ case REFDEV_MODE_PDF1:
+ nDPIX = nDPIY = 720;
+ break;
+ }
+ ImplSetReferenceDevice( i_eRefDevMode, nDPIX, nDPIY );
+}
+
+void VirtualDevice::SetReferenceDevice( sal_Int32 i_nDPIX, sal_Int32 i_nDPIY )
+{
+ ImplSetReferenceDevice( REFDEV_CUSTOM, i_nDPIX, i_nDPIY );
+}
+
+void VirtualDevice::ImplSetReferenceDevice( RefDevMode i_eRefDevMode, sal_Int32 i_nDPIX, sal_Int32 i_nDPIY )
+{
+ mnDPIX = i_nDPIX;
+ mnDPIY = i_nDPIY;
+
+ EnableOutput( FALSE ); // prevent output on reference device
+ mbScreenComp = FALSE;
+
+ // invalidate currently selected fonts
+ mbInitFont = TRUE;
+ mbNewFont = TRUE;
+
+ // avoid adjusting font lists when already in refdev mode
+ BYTE nOldRefDevMode = meRefDevMode;
+ BYTE nOldCompatFlag = (BYTE)meRefDevMode & REFDEV_FORCE_ZERO_EXTLEAD;
+ meRefDevMode = (BYTE)(i_eRefDevMode | nOldCompatFlag);
+ if( (nOldRefDevMode ^ nOldCompatFlag) != REFDEV_NONE )
+ return;
+
+ // the reference device should have only scalable fonts
+ // => clean up the original font lists before getting new ones
+ if ( mpFontEntry )
+ {
+ mpFontCache->Release( mpFontEntry );
+ mpFontEntry = NULL;
+ }
+ if ( mpGetDevFontList )
+ {
+ delete mpGetDevFontList;
+ mpGetDevFontList = NULL;
+ }
+ if ( mpGetDevSizeList )
+ {
+ delete mpGetDevSizeList;
+ mpGetDevSizeList = NULL;
+ }
+
+ // preserve global font lists
+ ImplSVData* pSVData = ImplGetSVData();
+ if( mpFontList && (mpFontList != pSVData->maGDIData.mpScreenFontList) )
+ delete mpFontList;
+ if( mpFontCache && (mpFontCache != pSVData->maGDIData.mpScreenFontCache) )
+ delete mpFontCache;
+
+ // get font list with scalable fonts only
+ ImplGetGraphics();
+ mpFontList = pSVData->maGDIData.mpScreenFontList->Clone( true, false );
+
+ // prepare to use new font lists
+ mpFontCache = new ImplFontCache( false );
+}
+
+// -----------------------------------------------------------------------
+
+void VirtualDevice::Compat_ZeroExtleadBug()
+{
+ meRefDevMode = (BYTE)meRefDevMode | REFDEV_FORCE_ZERO_EXTLEAD;
+}
+
+// -----------------------------------------------------------------------
+