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