xref: /AOO41X/main/vcl/win/source/gdi/salvd.cxx (revision 47148b3bc50811ceb41802e4cc50a5db21535900)
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