calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / vcl / win / gdi / salvd.cxx
blob7b3e7e11fc5c67a488a34e8347322caa73c4b11f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svsys.h>
22 #include <comphelper/windowserrorstring.hxx>
24 #include <vcl/sysdata.hxx>
26 #include <win/wincomp.hxx>
27 #include <win/saldata.hxx>
28 #include <win/salinst.h>
29 #include <win/salgdi.h>
30 #include <win/salvd.h>
31 #include <sal/log.hxx>
32 #include <o3tl/temporary.hxx>
34 HBITMAP WinSalVirtualDevice::ImplCreateVirDevBitmap(HDC hDC, tools::Long nDX, tools::Long nDY, sal_uInt16 nBitCount, void **ppData)
36 HBITMAP hBitmap;
38 if ( nBitCount == 1 )
40 hBitmap = CreateBitmap( static_cast<int>(nDX), static_cast<int>(nDY), 1, 1, nullptr );
41 SAL_WARN_IF( !hBitmap, "vcl", "CreateBitmap failed: " << WindowsErrorString( GetLastError() ) );
42 ppData = nullptr;
44 else
46 if (nBitCount == 0)
47 nBitCount = static_cast<WORD>(GetDeviceCaps(hDC, BITSPIXEL));
49 // #146839# Don't use CreateCompatibleBitmap() - there seem to
50 // be built-in limits for those HBITMAPs, at least this fails
51 // rather often on large displays/multi-monitor setups.
52 BITMAPINFO aBitmapInfo;
53 aBitmapInfo.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
54 aBitmapInfo.bmiHeader.biWidth = nDX;
55 aBitmapInfo.bmiHeader.biHeight = nDY;
56 aBitmapInfo.bmiHeader.biPlanes = 1;
57 aBitmapInfo.bmiHeader.biBitCount = nBitCount;
58 aBitmapInfo.bmiHeader.biCompression = BI_RGB;
59 aBitmapInfo.bmiHeader.biSizeImage = 0;
60 aBitmapInfo.bmiHeader.biXPelsPerMeter = 0;
61 aBitmapInfo.bmiHeader.biYPelsPerMeter = 0;
62 aBitmapInfo.bmiHeader.biClrUsed = 0;
63 aBitmapInfo.bmiHeader.biClrImportant = 0;
65 hBitmap = CreateDIBSection( hDC, &aBitmapInfo,
66 DIB_RGB_COLORS, ppData, nullptr,
67 0 );
68 SAL_WARN_IF( !hBitmap, "vcl", "CreateDIBSection failed: " << WindowsErrorString( GetLastError() ) );
71 return hBitmap;
74 std::unique_ptr<SalVirtualDevice> WinSalInstance::CreateVirtualDevice( SalGraphics& rSGraphics,
75 tools::Long &nDX, tools::Long &nDY,
76 DeviceFormat /*eFormat*/,
77 const SystemGraphicsData* pData )
79 WinSalGraphics& rGraphics = static_cast<WinSalGraphics&>(rSGraphics);
80 HDC hDC = nullptr;
82 if( pData )
84 hDC = (pData->hDC) ? pData->hDC : GetDC(pData->hWnd);
85 if (hDC)
87 nDX = GetDeviceCaps( hDC, HORZRES );
88 nDY = GetDeviceCaps( hDC, VERTRES );
90 else
92 nDX = 0;
93 nDY = 0;
96 else
98 hDC = CreateCompatibleDC( rGraphics.getHDC() );
99 SAL_WARN_IF( !hDC, "vcl", "CreateCompatibleDC failed: " << WindowsErrorString( GetLastError() ) );
102 if (!hDC)
103 return nullptr;
105 sal_uInt16 nBitCount = 0;
106 HBITMAP hBmp = nullptr;
107 if (!pData)
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 hBmp = WinSalVirtualDevice::ImplCreateVirDevBitmap(rGraphics.getHDC(),
113 nDX, nDY, nBitCount,
114 &o3tl::temporary<void*>(nullptr));
117 const bool bForeignDC = pData != nullptr && pData->hDC != nullptr;
118 const SalData* pSalData = GetSalData();
120 WinSalVirtualDevice* pVDev = new WinSalVirtualDevice(hDC, hBmp, nBitCount,
121 bForeignDC, nDX, nDY);
123 WinSalGraphics* pVirGraphics = new WinSalGraphics(WinSalGraphics::VIRTUAL_DEVICE,
124 rGraphics.isScreen(), nullptr, pVDev);
126 // by default no! mirroring for VirtualDevices, can be enabled with EnableRTL()
127 pVirGraphics->SetLayout( SalLayoutFlags::NONE );
128 pVirGraphics->setHDC(hDC);
130 if ( pSalData->mhDitherPal && pVirGraphics->isScreen() )
132 pVirGraphics->setPalette(pSalData->mhDitherPal);
133 RealizePalette( hDC );
136 pVDev->setGraphics(pVirGraphics);
138 return std::unique_ptr<SalVirtualDevice>(pVDev);
141 WinSalVirtualDevice::WinSalVirtualDevice(HDC hDC, HBITMAP hBMP, sal_uInt16 nBitCount, bool bForeignDC, tools::Long nWidth, tools::Long nHeight)
142 : mhLocalDC(hDC), // HDC or 0 for Cache Device
143 mhBmp(hBMP), // Memory Bitmap
144 mnBitCount(nBitCount), // BitCount (0 or 1)
145 mbGraphics(false), // is Graphics used
146 mbForeignDC(bForeignDC), // uses a foreign DC instead of a bitmap
147 mnWidth(nWidth),
148 mnHeight(nHeight)
150 // Default Bitmap
151 if (hBMP)
152 mhDefBmp = SelectBitmap(hDC, hBMP);
153 else
154 mhDefBmp = nullptr;
156 // insert VirDev into list of virtual devices
157 SalData* pSalData = GetSalData();
158 mpNext = pSalData->mpFirstVD;
159 pSalData->mpFirstVD = this;
162 WinSalVirtualDevice::~WinSalVirtualDevice()
164 // remove VirDev from list of virtual devices
165 SalData* pSalData = GetSalData();
166 WinSalVirtualDevice** ppVirDev = &pSalData->mpFirstVD;
167 for(; (*ppVirDev != this) && *ppVirDev; ppVirDev = &(*ppVirDev)->mpNext );
168 if( *ppVirDev )
169 *ppVirDev = mpNext;
171 HDC hDC = mpGraphics->getHDC();
172 // restore the mpGraphics' original HDC values, so the HDC can be deleted in the !mbForeignDC case
173 mpGraphics->setHDC(nullptr);
175 if( mhDefBmp )
176 SelectBitmap(hDC, mhDefBmp);
177 if( !mbForeignDC )
178 DeleteDC(hDC);
181 SalGraphics* WinSalVirtualDevice::AcquireGraphics()
183 if ( mbGraphics )
184 return nullptr;
186 if ( mpGraphics )
187 mbGraphics = true;
189 return mpGraphics.get();
192 void WinSalVirtualDevice::ReleaseGraphics( SalGraphics* )
194 mbGraphics = false;
197 bool WinSalVirtualDevice::SetSize( tools::Long nDX, tools::Long nDY )
199 if( mbForeignDC || !mhBmp )
200 return true; // ???
202 HBITMAP hNewBmp = ImplCreateVirDevBitmap(getHDC(), nDX, nDY, mnBitCount,
203 &o3tl::temporary<void*>(nullptr));
204 if (!hNewBmp)
206 mnWidth = 0;
207 mnHeight = 0;
208 return false;
211 mnWidth = nDX;
212 mnHeight = nDY;
214 SelectBitmap(getHDC(), hNewBmp);
215 mhBmp.reset(hNewBmp);
217 if (mpGraphics)
218 mpGraphics->GetImpl()->Init();
220 return true;
223 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */