Coverage Report

Created: 2026-05-31 06:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/qtbase/src/gui/kernel/qpaintdevicewindow.cpp
Line
Count
Source
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
// Qt-Security score:significant reason:default
4
5
#include "qpaintdevicewindow_p.h"
6
7
#include <QtGui/QGuiApplication>
8
#include <QtGui/QScreen>
9
10
QT_BEGIN_NAMESPACE
11
12
0
QPaintDeviceWindowPrivate::QPaintDeviceWindowPrivate()
13
    = default;
14
15
0
QPaintDeviceWindowPrivate::~QPaintDeviceWindowPrivate()
16
    = default;
17
18
/*!
19
    \class QPaintDeviceWindow
20
    \inmodule QtGui
21
    \since 5.4
22
    \brief Convenience subclass of QWindow that is also a QPaintDevice.
23
24
    QPaintDeviceWindow is like a regular QWindow, with the added functionality
25
    of being a paint device too. Whenever the content needs to be updated,
26
    the virtual paintEvent() function is called. Subclasses, that reimplement
27
    this function, can then simply open a QPainter on the window.
28
29
    \note This class cannot directly be used in applications. It rather serves
30
    as a base for subclasses like QOpenGLWindow.
31
32
    \sa QOpenGLWindow
33
*/
34
35
/*!
36
    Marks the entire window as dirty and schedules a repaint.
37
38
    \note Subsequent calls to this function before the next paint
39
    event will get ignored.
40
41
    \note For non-exposed windows the update is deferred until the
42
    window becomes exposed again.
43
*/
44
void QPaintDeviceWindow::update()
45
0
{
46
0
    update(QRect(QPoint(0,0), size()));
47
0
}
48
49
/*!
50
    Marks the \a rect of the window as dirty and schedules a repaint.
51
52
    \note Subsequent calls to this function before the next paint
53
    event will get ignored, but \a rect is added to the region to update.
54
55
    \note For non-exposed windows the update is deferred until the
56
    window becomes exposed again.
57
*/
58
void QPaintDeviceWindow::update(const QRect &rect)
59
0
{
60
0
    Q_D(QPaintDeviceWindow);
61
0
    d->dirtyRegion += rect;
62
0
    if (isExposed())
63
0
        requestUpdate();
64
0
}
65
66
/*!
67
    Marks the \a region of the window as dirty and schedules a repaint.
68
69
    \note Subsequent calls to this function before the next paint
70
    event will get ignored, but \a region is added to the region to update.
71
72
    \note For non-exposed windows the update is deferred until the
73
    window becomes exposed again.
74
*/
75
void QPaintDeviceWindow::update(const QRegion &region)
76
0
{
77
0
    Q_D(QPaintDeviceWindow);
78
0
    d->dirtyRegion += region;
79
0
    if (isExposed())
80
0
        requestUpdate();
81
0
}
82
83
/*!
84
    Handles paint events passed in the \a event parameter.
85
86
    The default implementation does nothing. Reimplement this function to
87
    perform painting. If necessary, the dirty area is retrievable from
88
    the \a event.
89
*/
90
void QPaintDeviceWindow::paintEvent(QPaintEvent *event)
91
0
{
92
0
    Q_UNUSED(event);
93
    // Do nothing
94
0
}
95
96
/*!
97
  \internal
98
 */
99
int QPaintDeviceWindow::metric(PaintDeviceMetric metric) const
100
0
{
101
0
    QScreen *screen = this->screen();
102
0
    if (!screen && QGuiApplication::primaryScreen())
103
0
        screen = QGuiApplication::primaryScreen();
104
105
0
    switch (metric) {
106
0
    case PdmWidth:
107
0
        return width();
108
0
    case PdmWidthMM:
109
0
        if (screen)
110
0
            return width() * screen->physicalSize().width() / screen->geometry().width();
111
0
        break;
112
0
    case PdmHeight:
113
0
        return height();
114
0
    case PdmHeightMM:
115
0
        if (screen)
116
0
            return height() * screen->physicalSize().height() / screen->geometry().height();
117
0
        break;
118
0
    case PdmDpiX:
119
0
        if (screen)
120
0
            return qRound(screen->logicalDotsPerInchX());
121
0
        break;
122
0
    case PdmDpiY:
123
0
        if (screen)
124
0
            return qRound(screen->logicalDotsPerInchY());
125
0
        break;
126
0
    case PdmPhysicalDpiX:
127
0
        if (screen)
128
0
            return qRound(screen->physicalDotsPerInchX());
129
0
        break;
130
0
    case PdmPhysicalDpiY:
131
0
        if (screen)
132
0
            return qRound(screen->physicalDotsPerInchY());
133
0
        break;
134
0
    case PdmDevicePixelRatio:
135
0
        return int(QWindow::devicePixelRatio());
136
0
        break;
137
0
    case PdmDevicePixelRatioScaled:
138
0
        return int(QWindow::devicePixelRatio() * devicePixelRatioFScale());
139
0
        break;
140
0
    case PdmDevicePixelRatioF_EncodedA:
141
0
        Q_FALLTHROUGH();
142
0
    case PdmDevicePixelRatioF_EncodedB:
143
0
        return QPaintDevice::encodeMetricF(metric, QWindow::devicePixelRatio());
144
0
        break;
145
0
    default:
146
0
        break;
147
0
    }
148
149
0
    return QPaintDevice::metric(metric);
150
0
}
151
152
/*!
153
  \internal
154
 */
155
void QPaintDeviceWindow::exposeEvent(QExposeEvent *exposeEvent)
156
0
{
157
0
    QWindow::exposeEvent(exposeEvent);
158
0
}
159
160
/*!
161
  \internal
162
 */
163
bool QPaintDeviceWindow::event(QEvent *event)
164
0
{
165
0
    Q_D(QPaintDeviceWindow);
166
167
0
    if (event->type() == QEvent::UpdateRequest) {
168
0
        if (handle()) // platform window may be gone when the window is closed during app exit
169
0
            d->handleUpdateEvent();
170
0
        return true;
171
0
    } else if (event->type() == QEvent::Paint) {
172
0
        d->markWindowAsDirty();
173
        // Do not rely on exposeEvent->region() as it has some issues for the
174
        // time being, namely that it is sometimes in local coordinates,
175
        // sometimes relative to the parent, depending on the platform plugin.
176
        // We require local coords here.
177
0
        auto region = QRect(QPoint(0, 0), size());
178
0
        d->doFlush(region); // Will end up calling paintEvent
179
0
        return true;
180
0
    } else if (event->type() == QEvent::Resize) {
181
0
        d->handleResizeEvent();
182
0
    }
183
184
0
    return QWindow::event(event);
185
0
}
186
187
/*!
188
  \internal
189
 */
190
QPaintDeviceWindow::QPaintDeviceWindow(QPaintDeviceWindowPrivate &dd, QWindow *parent)
191
0
    : QWindow(dd, parent)
192
0
{
193
0
}
194
195
/*!
196
  \internal
197
 */
198
QPaintEngine *QPaintDeviceWindow::paintEngine() const
199
0
{
200
0
    return nullptr;
201
0
}
202
203
QT_END_NAMESPACE
204
205
#include "moc_qpaintdevicewindow.cpp"