/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 ®ion) |
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" |