Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qwindowsnativeimage.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <QtGui/private/qpaintengine_p.h>
7#include <QtGui/private/qpaintengine_raster_p.h>
8
10
17
18/*!
19 \class QWindowsNativeImage
20 \brief Windows Native image
21
22 Note that size can be 0 (widget autotests with zero size), which
23 causes CreateDIBSection() to fail.
24
25 \sa QWindowsBackingStore
26 \internal
27*/
28
29static inline HDC createDC()
30{
31 HDC display_dc = GetDC(0);
32 HDC hdc = CreateCompatibleDC(display_dc);
33 ReleaseDC(0, display_dc);
34 Q_ASSERT(hdc);
35 return hdc;
36}
37
38static inline HBITMAP createDIB(HDC hdc, int width, int height,
39 QImage::Format format,
40 uchar **bitsIn)
41{
42 BITMAPINFO_MASK bmi;
43 memset(&bmi, 0, sizeof(bmi));
44 bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
45 bmi.bmiHeader.biWidth = width;
46 bmi.bmiHeader.biHeight = -height; // top-down.
47 bmi.bmiHeader.biPlanes = 1;
48 bmi.bmiHeader.biSizeImage = 0;
49
50 if (format == QImage::Format_RGB16) {
51 bmi.bmiHeader.biBitCount = 16;
52 bmi.bmiHeader.biCompression = BI_BITFIELDS;
53 bmi.redMask = 0xF800;
54 bmi.greenMask = 0x07E0;
55 bmi.blueMask = 0x001F;
56 } else {
57 bmi.bmiHeader.biBitCount = 32;
58 bmi.bmiHeader.biCompression = BI_RGB;
59 bmi.redMask = 0;
60 bmi.greenMask = 0;
61 bmi.blueMask = 0;
62 }
63
64 uchar *bits = nullptr;
65 HBITMAP bitmap = CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO *>(&bmi),
66 DIB_RGB_COLORS, reinterpret_cast<void **>(&bits), 0, 0);
67 if (Q_UNLIKELY(!bitmap || !bits)) {
68 qFatal("%s: CreateDIBSection failed (%dx%d, format: %d)", __FUNCTION__,
69 width, height, int(format));
70 }
71
72 *bitsIn = bits;
73 return bitmap;
74}
75
76QWindowsNativeImage::QWindowsNativeImage(int width, int height,
77 QImage::Format format) :
78 m_hdc(createDC())
79{
80 if (width != 0 && height != 0) {
81 uchar *bits;
82 m_bitmap = createDIB(m_hdc, width, height, format, &bits);
83 m_null_bitmap = static_cast<HBITMAP>(SelectObject(m_hdc, m_bitmap));
84 m_image = QImage(bits, width, height, format);
85 Q_ASSERT(m_image.paintEngine()->type() == QPaintEngine::Raster);
86 static_cast<QRasterPaintEngine *>(m_image.paintEngine())->setDC(m_hdc);
87 } else {
88 m_image = QImage(width, height, format);
89 }
90
91 GdiFlush();
92}
93
94QWindowsNativeImage::~QWindowsNativeImage()
95{
96 if (m_hdc) {
97 if (m_bitmap) {
98 if (m_null_bitmap)
99 SelectObject(m_hdc, m_null_bitmap);
100 DeleteObject(m_bitmap);
101 }
102 DeleteDC(m_hdc);
103 }
104}
105
106QImage::Format QWindowsNativeImage::systemFormat()
107{
108 static int depth = -1;
109 if (depth == -1) {
110 if (HDC defaultDC = GetDC(0)) {
111 depth = GetDeviceCaps(defaultDC, BITSPIXEL);
112 ReleaseDC(0, defaultDC);
113 } else {
114 // FIXME Same remark as in QWindowsFontDatabase::defaultVerticalDPI()
115 // BONUS FIXME: Is 32 too generous/optimistic?
116 depth = 32;
117 }
118 }
119 return depth == 16 ? QImage::Format_RGB16 : QImage::Format_RGB32;
120}
121
122QT_END_NAMESPACE
static HDC createDC()
static HBITMAP createDIB(HDC hdc, int width, int height, QImage::Format format, uchar **bitsIn)
BITMAPINFOHEADER bmiHeader