xref: /aoo41x/main/vcl/win/source/gdi/salvd.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <tools/svwin.h>
32 
33 #include <vcl/sysdata.hxx>
34 
35 #include <win/wincomp.hxx>
36 #include <win/saldata.hxx>
37 #include <win/salinst.h>
38 #include <win/salgdi.h>
39 #include <win/salvd.h>
40 
41 // =======================================================================
42 
43 static HBITMAP ImplCreateVirDevBitmap( HDC hDC, long nDX, long nDY,
44 									   sal_uInt16 nBitCount )
45 {
46 	HBITMAP hBitmap;
47 
48  	if ( nBitCount == 1 )
49  	{
50  		hBitmap = CreateBitmap( (int)nDX, (int)nDY, 1, 1, NULL );
51  	}
52  	else
53  	{
54         // #146839# Don't use CreateCompatibleBitmap() - there seem to
55         // be build-in limits for those HBITMAPs, at least this fails
56         // rather often on large displays/multi-monitor setups.
57  		BITMAPINFO aBitmapInfo;
58  		aBitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
59  		aBitmapInfo.bmiHeader.biWidth = nDX;
60  		aBitmapInfo.bmiHeader.biHeight = nDY;
61  		aBitmapInfo.bmiHeader.biPlanes = 1;
62  		aBitmapInfo.bmiHeader.biBitCount = (WORD)GetDeviceCaps( hDC,
63  														        BITSPIXEL );
64  		aBitmapInfo.bmiHeader.biCompression = BI_RGB;
65  		aBitmapInfo.bmiHeader.biSizeImage = 0;
66  		aBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
67  		aBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
68  		aBitmapInfo.bmiHeader.biClrUsed = 0;
69  		aBitmapInfo.bmiHeader.biClrImportant = 0;
70 
71  		void* pDummy;
72  		hBitmap = CreateDIBSection( hDC, &aBitmapInfo,
73  									DIB_RGB_COLORS, &pDummy, NULL,
74  									0 );
75  	}
76 
77 	return hBitmap;
78 }
79 
80 // =======================================================================
81 
82 SalVirtualDevice* WinSalInstance::CreateVirtualDevice( SalGraphics* pSGraphics,
83                                                        long nDX, long nDY,
84                                                        sal_uInt16 nBitCount,
85                                                        const SystemGraphicsData* pData )
86 {
87     WinSalGraphics* pGraphics = static_cast<WinSalGraphics*>(pSGraphics);
88 
89 	HDC 	hDC = NULL;
90 	HBITMAP hBmp = NULL;
91     sal_Bool    bOk = FALSE;
92 
93     if( pData )
94     {
95         hDC = pData->hDC;
96         hBmp = NULL;
97         bOk = (hDC != NULL);
98     }
99     else
100     {
101 	    hDC 	= CreateCompatibleDC( pGraphics->mhDC );
102         if( !hDC )
103             ImplWriteLastError( GetLastError(), "CreateCompatibleDC in CreateVirtualDevice" );
104 
105 	    hBmp	= ImplCreateVirDevBitmap( pGraphics->mhDC,
106 		                                nDX, nDY, nBitCount );
107         if( !hBmp )
108             ImplWriteLastError( GetLastError(), "ImplCreateVirDevBitmap in CreateVirtualDevice" );
109         // #124826# continue even if hBmp could not be created
110         // if we would return a failure in this case, the process
111         // would terminate which is not required
112 
113         DBG_ASSERT( hBmp, "WinSalInstance::CreateVirtualDevice(), could not create Bitmap!" );
114 
115         bOk = (hDC != NULL);
116     }
117 
118 	if ( bOk )
119 	{
120 		WinSalVirtualDevice*	pVDev = new WinSalVirtualDevice;
121 		SalData*                pSalData = GetSalData();
122 		WinSalGraphics*         pVirGraphics = new WinSalGraphics;
123         pVirGraphics->SetLayout( 0 );   // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL()
124 		pVirGraphics->mhDC	   = hDC;
125 		pVirGraphics->mhWnd	   = 0;
126 		pVirGraphics->mbPrinter = FALSE;
127 		pVirGraphics->mbVirDev  = TRUE;
128 		pVirGraphics->mbWindow  = FALSE;
129 		pVirGraphics->mbScreen  = pGraphics->mbScreen;
130 		if ( pSalData->mhDitherPal && pVirGraphics->mbScreen )
131 		{
132 			pVirGraphics->mhDefPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
133 			RealizePalette( hDC );
134 		}
135 		ImplSalInitGraphics( pVirGraphics );
136 
137 		pVDev->mhDC		    = hDC;
138 		pVDev->mhBmp		= hBmp;
139         if( hBmp )
140 		    pVDev->mhDefBmp	= SelectBitmap( hDC, hBmp );
141         else
142             pVDev->mhDefBmp = NULL;
143 		pVDev->mpGraphics	= pVirGraphics;
144 		pVDev->mnBitCount	= nBitCount;
145 		pVDev->mbGraphics	= FALSE;
146         pVDev->mbForeignDC  = (pData != NULL);
147 
148 		// insert VirDev in VirDevList
149 		pVDev->mpNext = pSalData->mpFirstVD;
150 		pSalData->mpFirstVD = pVDev;
151 
152 		return pVDev;
153 	}
154 	else
155 	{
156 		if ( hDC && !pData )
157 			DeleteDC( hDC );
158 		if ( hBmp )
159 			DeleteBitmap( hBmp );
160 		return NULL;
161 	}
162 }
163 
164 // -----------------------------------------------------------------------
165 
166 void WinSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
167 {
168 	delete pDevice;
169 }
170 
171 // =======================================================================
172 
173 WinSalVirtualDevice::WinSalVirtualDevice()
174 {
175 	mhDC = (HDC) NULL;			// HDC or 0 for Cache Device
176 	mhBmp = (HBITMAP) NULL;		// Memory Bitmap
177 	mhDefBmp = (HBITMAP) NULL;	// Default Bitmap
178 	mpGraphics = NULL; 			// current VirDev graphics
179 	mpNext = NULL; 				// next VirDev
180 	mnBitCount = 0; 			// BitCount (0 or 1)
181 	mbGraphics = FALSE; 		// is Graphics used
182     mbForeignDC = FALSE;        // uses a foreign DC instead of a bitmap
183 }
184 
185 // -----------------------------------------------------------------------
186 
187 WinSalVirtualDevice::~WinSalVirtualDevice()
188 {
189     // remove VirDev from list of virtual devices
190     SalData* pSalData = GetSalData();
191     WinSalVirtualDevice** ppVirDev = &pSalData->mpFirstVD;
192     for(; (*ppVirDev != this) && *ppVirDev; ppVirDev = &(*ppVirDev)->mpNext );
193     if( *ppVirDev )
194         *ppVirDev = mpNext;
195 
196     // destroy saved DC
197     if( mpGraphics->mhDefPal )
198         SelectPalette( mpGraphics->mhDC, mpGraphics->mhDefPal, TRUE );
199     ImplSalDeInitGraphics( mpGraphics );
200     if( mhDefBmp )
201         SelectBitmap( mpGraphics->mhDC, mhDefBmp );
202     if( !mbForeignDC )
203         DeleteDC( mpGraphics->mhDC );
204     if( mhBmp )
205         DeleteBitmap( mhBmp );
206     delete mpGraphics;
207     mpGraphics = NULL;
208 }
209 
210 // -----------------------------------------------------------------------
211 
212 SalGraphics* WinSalVirtualDevice::GetGraphics()
213 {
214 	if ( mbGraphics )
215 		return NULL;
216 
217 	if ( mpGraphics )
218 		mbGraphics = TRUE;
219 
220 	return mpGraphics;
221 }
222 
223 // -----------------------------------------------------------------------
224 
225 void WinSalVirtualDevice::ReleaseGraphics( SalGraphics* )
226 {
227 	mbGraphics = FALSE;
228 }
229 
230 // -----------------------------------------------------------------------
231 
232 sal_Bool WinSalVirtualDevice::SetSize( long nDX, long nDY )
233 {
234     if( mbForeignDC || !mhBmp )
235         return TRUE;    // ???
236     else
237     {
238 	    HBITMAP hNewBmp = ImplCreateVirDevBitmap( mhDC, nDX, nDY,
239 											  mnBitCount );
240 	    if ( hNewBmp )
241 	    {
242 		    SelectBitmap( mhDC, hNewBmp );
243 		    DeleteBitmap( mhBmp );
244 		    mhBmp = hNewBmp;
245 		    return TRUE;
246 	    }
247 	    else
248         {
249             ImplWriteLastError( GetLastError(), "ImplCreateVirDevBitmap in SetSize" );
250             return FALSE;
251         }
252     }
253 }
254 
255 void WinSalVirtualDevice::GetSize( long& rWidth, long& rHeight )
256 {
257     rWidth = GetDeviceCaps( mhDC, HORZRES );
258     rHeight= GetDeviceCaps( mhDC, VERTRES );
259 }
260