Changeset View
Changeset View
Standalone View
Standalone View
3rdparty/ext_qt/0032-Update-Dpi-and-scale-factor-computation.patch
- This file was added.
1 | From 3ef20bcb114c316efb74a0a704e918731847620c Mon Sep 17 00:00:00 2001 | ||||
---|---|---|---|---|---|
2 | From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io> | ||||
3 | Date: Mon, 25 Apr 2016 11:31:34 +0200 | ||||
4 | Subject: [PATCH 32/36] Update Dpi and scale factor computation | ||||
5 | | ||||
6 | Remove pixelScale() in favor of logicalBaseDpi(). Compute scale factor | ||||
7 | based on logical DPI and logical base DPI, or optionally based on the | ||||
8 | physical DPI. | ||||
9 | | ||||
10 | Add policies for running the scale factor and adjusting the logical | ||||
11 | DPI reported to the application. The policies are set via environment | ||||
12 | variables: | ||||
13 | | ||||
14 | QT_SCALE_FACTOR_ROUNDING_POLICY=Round|Ceil|Floor|RoundPreferFloor|PassThrough | ||||
15 | QT_DPI_ADJUSTMENT_POLICY=AdjustDpi|DontAdjustDpi|AdjustUpOnly | ||||
16 | QT_USE_PHYSICAL_DPI=0|1 | ||||
17 | | ||||
18 | Done-with: Friedemann Kleint <Friedemann.Kleint@qt.io> | ||||
19 | Task-number: QTBUG-53022 | ||||
20 | Change-Id: I4846f223186df665eb0a9c827eaef0a96d1f458f | ||||
21 | --- | ||||
22 | src/gui/kernel/qhighdpiscaling.cpp | 234 ++++++++++++++++-- | ||||
23 | src/gui/kernel/qhighdpiscaling_p.h | 29 +++ | ||||
24 | src/gui/kernel/qplatformscreen.cpp | 14 ++ | ||||
25 | src/gui/kernel/qplatformscreen.h | 1 + | ||||
26 | .../android/qandroidplatformscreen.cpp | 8 +- | ||||
27 | .../android/qandroidplatformscreen.h | 2 +- | ||||
28 | src/plugins/platforms/cocoa/qcocoascreen.h | 1 + | ||||
29 | .../platforms/windows/qwindowsscreen.cpp | 9 - | ||||
30 | .../platforms/windows/qwindowsscreen.h | 2 +- | ||||
31 | src/plugins/platforms/xcb/qxcbscreen.cpp | 11 - | ||||
32 | src/plugins/platforms/xcb/qxcbscreen.h | 3 +- | ||||
33 | tests/manual/highdpi/highdpi.pro | 1 + | ||||
34 | 12 files changed, 264 insertions(+), 51 deletions(-) | ||||
35 | | ||||
36 | diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp | ||||
37 | index 541d4f12af..ae531569ce 100644 | ||||
38 | --- a/src/gui/kernel/qhighdpiscaling.cpp | ||||
39 | +++ b/src/gui/kernel/qhighdpiscaling.cpp | ||||
40 | @@ -44,6 +44,9 @@ | ||||
41 | #include "private/qscreen_p.h" | ||||
42 | | ||||
43 | #include <QtCore/qdebug.h> | ||||
44 | +#include <QtCore/qmetaobject.h> | ||||
45 | + | ||||
46 | +#include <algorithm> | ||||
47 | | ||||
48 | QT_BEGIN_NAMESPACE | ||||
49 | | ||||
50 | @@ -54,6 +57,18 @@ static const char legacyDevicePixelEnvVar[] = "QT_DEVICE_PIXEL_RATIO"; | ||||
51 | static const char scaleFactorEnvVar[] = "QT_SCALE_FACTOR"; | ||||
52 | static const char autoScreenEnvVar[] = "QT_AUTO_SCREEN_SCALE_FACTOR"; | ||||
53 | static const char screenFactorsEnvVar[] = "QT_SCREEN_SCALE_FACTORS"; | ||||
54 | +static const char scaleFactorRoundingPolicyEnvVar[] = "QT_SCALE_FACTOR_ROUNDING_POLICY"; | ||||
55 | +static const char dpiAdjustmentPolicyEnvVar[] = "QT_DPI_ADJUSTMENT_POLICY"; | ||||
56 | +static const char usePhysicalDpiEnvVar[] = "QT_USE_PHYSICAL_DPI"; | ||||
57 | + | ||||
58 | +// Reads and interprets the given environment variable as a bool, | ||||
59 | +// returns the default value if not set. | ||||
60 | +static bool qEnvironmentVariableAsBool(const char *name, bool defaultValue) | ||||
61 | +{ | ||||
62 | + bool ok = false; | ||||
63 | + int value = qEnvironmentVariableIntValue(name, &ok); | ||||
64 | + return ok ? value > 0 : defaultValue; | ||||
65 | +} | ||||
66 | | ||||
67 | static inline qreal initialGlobalScaleFactor() | ||||
68 | { | ||||
69 | @@ -247,6 +262,191 @@ static inline bool usePixelDensity() | ||||
70 | qgetenv(legacyDevicePixelEnvVar).compare("auto", Qt::CaseInsensitive) == 0); | ||||
71 | } | ||||
72 | | ||||
73 | +qreal QHighDpiScaling::rawScaleFactor(const QPlatformScreen *screen) | ||||
74 | +{ | ||||
75 | + // Determine if physical DPI should be used | ||||
76 | + static bool usePhysicalDpi = qEnvironmentVariableAsBool(usePhysicalDpiEnvVar, false); | ||||
77 | + | ||||
78 | + // Calculate scale factor beased on platform screen DPI values | ||||
79 | + qreal factor; | ||||
80 | + QDpi platformBaseDpi = screen->logicalBaseDpi(); | ||||
81 | + if (usePhysicalDpi) { | ||||
82 | + qreal platformPhysicalDpi = screen->screen()->physicalDotsPerInch(); | ||||
83 | + factor = qreal(platformPhysicalDpi) / qreal(platformBaseDpi.first); | ||||
84 | + } else { | ||||
85 | + QDpi platformLogicalDpi = screen->logicalDpi(); | ||||
86 | + factor = qreal(platformLogicalDpi.first) / qreal(platformBaseDpi.first); | ||||
87 | + } | ||||
88 | + | ||||
89 | + return factor; | ||||
90 | +} | ||||
91 | + | ||||
92 | +template <class EnumType> | ||||
93 | +struct EnumLookup | ||||
94 | +{ | ||||
95 | + const char *name; | ||||
96 | + EnumType value; | ||||
97 | +}; | ||||
98 | + | ||||
99 | +template <class EnumType> | ||||
100 | +static bool operator==(const EnumLookup<EnumType> &e1, const EnumLookup<EnumType> &e2) | ||||
101 | +{ | ||||
102 | + return qstricmp(e1.name, e2.name) == 0; | ||||
103 | +} | ||||
104 | + | ||||
105 | +template <class EnumType> | ||||
106 | +static QByteArray joinEnumValues(const EnumLookup<EnumType> *i1, const EnumLookup<EnumType> *i2) | ||||
107 | +{ | ||||
108 | + QByteArray result; | ||||
109 | + for (; i1 < i2; ++i1) { | ||||
110 | + if (!result.isEmpty()) | ||||
111 | + result += QByteArrayLiteral(", "); | ||||
112 | + result += i1->name; | ||||
113 | + } | ||||
114 | + return result; | ||||
115 | +} | ||||
116 | + | ||||
117 | +using ScaleFactorRoundingPolicyLookup = EnumLookup<QHighDpiScaling::HighDpiScaleFactorRoundingPolicy>; | ||||
118 | + | ||||
119 | +static const ScaleFactorRoundingPolicyLookup scaleFactorRoundingPolicyLookup[] = | ||||
120 | +{ | ||||
121 | + {"Round", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::Round}, | ||||
122 | + {"Ceil", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::Ceil}, | ||||
123 | + {"Floor", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::Floor}, | ||||
124 | + {"RoundPreferFloor", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor}, | ||||
125 | + {"PassThrough", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::PassThrough} | ||||
126 | +}; | ||||
127 | + | ||||
128 | +static QHighDpiScaling::HighDpiScaleFactorRoundingPolicy | ||||
129 | + lookupScaleFactorRoundingPolicy(const QByteArray &v) | ||||
130 | +{ | ||||
131 | + auto end = std::end(scaleFactorRoundingPolicyLookup); | ||||
132 | + auto it = std::find(std::begin(scaleFactorRoundingPolicyLookup), end, | ||||
133 | + ScaleFactorRoundingPolicyLookup{v.constData(), QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::NotSet}); | ||||
134 | + return it != end ? it->value : QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::NotSet; | ||||
135 | +} | ||||
136 | + | ||||
137 | +using DpiAdjustmentPolicyLookup = EnumLookup<QHighDpiScaling::DpiAdjustmentPolicy>; | ||||
138 | + | ||||
139 | +static const DpiAdjustmentPolicyLookup dpiAdjustmentPolicyLookup[] = | ||||
140 | +{ | ||||
141 | + {"AdjustDpi", QHighDpiScaling::DpiAdjustmentPolicy::Enabled}, | ||||
142 | + {"DontAdjustDpi", QHighDpiScaling::DpiAdjustmentPolicy::Disabled}, | ||||
143 | + {"AdjustUpOnly", QHighDpiScaling::DpiAdjustmentPolicy::UpOnly} | ||||
144 | +}; | ||||
145 | + | ||||
146 | +static QHighDpiScaling::DpiAdjustmentPolicy | ||||
147 | + lookupDpiAdjustmentPolicy(const QByteArray &v) | ||||
148 | +{ | ||||
149 | + auto end = std::end(dpiAdjustmentPolicyLookup); | ||||
150 | + auto it = std::find(std::begin(dpiAdjustmentPolicyLookup), end, | ||||
151 | + DpiAdjustmentPolicyLookup{v.constData(), QHighDpiScaling::DpiAdjustmentPolicy::NotSet}); | ||||
152 | + return it != end ? it->value : QHighDpiScaling::DpiAdjustmentPolicy::NotSet; | ||||
153 | +} | ||||
154 | + | ||||
155 | +qreal QHighDpiScaling::roundScaleFactor(qreal rawFactor) | ||||
156 | +{ | ||||
157 | + // Apply scale factor rounding policy. Using mathematically correct rounding | ||||
158 | + // may not give the most desirable visual results, especially for | ||||
159 | + // critical fractions like .5. In general, rounding down results in visual | ||||
160 | + // sizes that are smaller than the ideal size, and opposite for rounding up. | ||||
161 | + // Rounding down is then preferable since "small UI" is a more acceptable | ||||
162 | + // high-DPI experience than "large UI". | ||||
163 | + static auto scaleFactorRoundingPolicy = HighDpiScaleFactorRoundingPolicy::NotSet; | ||||
164 | + | ||||
165 | + // Determine rounding policy | ||||
166 | + if (scaleFactorRoundingPolicy == HighDpiScaleFactorRoundingPolicy::NotSet) { | ||||
167 | + // Check environment | ||||
168 | + if (qEnvironmentVariableIsSet(scaleFactorRoundingPolicyEnvVar)) { | ||||
169 | + QByteArray policyText = qgetenv(scaleFactorRoundingPolicyEnvVar); | ||||
170 | + auto policyEnumValue = lookupScaleFactorRoundingPolicy(policyText); | ||||
171 | + if (policyEnumValue != HighDpiScaleFactorRoundingPolicy::NotSet) { | ||||
172 | + scaleFactorRoundingPolicy = policyEnumValue; | ||||
173 | + } else { | ||||
174 | + auto values = joinEnumValues(std::begin(scaleFactorRoundingPolicyLookup), | ||||
175 | + std::end(scaleFactorRoundingPolicyLookup)); | ||||
176 | + qWarning("Unknown scale factor rounding policy: %s. Supported values are: %s.", | ||||
177 | + policyText.constData(), values.constData()); | ||||
178 | + } | ||||
179 | + } else { | ||||
180 | + // Set default policy if no environment variable is set. | ||||
181 | + scaleFactorRoundingPolicy = HighDpiScaleFactorRoundingPolicy::RoundPreferFloor; | ||||
182 | + } | ||||
183 | + } | ||||
184 | + | ||||
185 | + // Apply rounding policy. | ||||
186 | + qreal roundedFactor = rawFactor; | ||||
187 | + switch (scaleFactorRoundingPolicy) { | ||||
188 | + case HighDpiScaleFactorRoundingPolicy::Round: | ||||
189 | + roundedFactor = qRound(rawFactor); | ||||
190 | + break; | ||||
191 | + case HighDpiScaleFactorRoundingPolicy::Ceil: | ||||
192 | + roundedFactor = qCeil(rawFactor); | ||||
193 | + break; | ||||
194 | + case HighDpiScaleFactorRoundingPolicy::Floor: | ||||
195 | + roundedFactor = qFloor(rawFactor); | ||||
196 | + break; | ||||
197 | + case HighDpiScaleFactorRoundingPolicy::RoundPreferFloor: | ||||
198 | + // Round up for .75 and higher. This favors "small UI" over "large UI". | ||||
199 | + roundedFactor = rawFactor - qFloor(rawFactor) < 0.75 | ||||
200 | + ? qFloor(rawFactor) : qCeil(rawFactor); | ||||
201 | + break; | ||||
202 | + case HighDpiScaleFactorRoundingPolicy::PassThrough: | ||||
203 | + case HighDpiScaleFactorRoundingPolicy::NotSet: | ||||
204 | + break; | ||||
205 | + } | ||||
206 | + | ||||
207 | + // Don't round down to to zero; clamp the minimum (rounded) factor to 1. | ||||
208 | + // This is not a common case but can happen if a display reports a very | ||||
209 | + // low DPI. | ||||
210 | + if (scaleFactorRoundingPolicy != HighDpiScaleFactorRoundingPolicy::PassThrough) | ||||
211 | + roundedFactor = qMax(roundedFactor, qreal(1)); | ||||
212 | + | ||||
213 | + return roundedFactor; | ||||
214 | +} | ||||
215 | + | ||||
216 | +QDpi QHighDpiScaling::effectiveLogicalDpi(const QPlatformScreen *screen, qreal rawFactor, qreal roundedFactor) | ||||
217 | +{ | ||||
218 | + // Apply DPI adjustment policy, if needed. If enabled this will change | ||||
219 | + // the reported logical DPI to account for the difference between the | ||||
220 | + // rounded scale factor and the actual scale factor. The effect | ||||
221 | + // is that text size will be correct for the screen dpi, but may be (slightly) | ||||
222 | + // out of sync with the rest of the UI. The amount of out-of-synch-ness | ||||
223 | + // depends on how well user code handles a non-standard DPI values, but | ||||
224 | + // since the adjustment is small (typically +/- 48 max) this might be OK. | ||||
225 | + static auto dpiAdjustmentPolicy = DpiAdjustmentPolicy::NotSet; | ||||
226 | + | ||||
227 | + // Determine adjustment policy. | ||||
228 | + if (dpiAdjustmentPolicy == DpiAdjustmentPolicy::NotSet) { | ||||
229 | + if (qEnvironmentVariableIsSet(dpiAdjustmentPolicyEnvVar)) { | ||||
230 | + QByteArray policyText = qgetenv(dpiAdjustmentPolicyEnvVar); | ||||
231 | + auto policyEnumValue = lookupDpiAdjustmentPolicy(policyText); | ||||
232 | + if (policyEnumValue != DpiAdjustmentPolicy::NotSet) { | ||||
233 | + dpiAdjustmentPolicy = policyEnumValue; | ||||
234 | + } else { | ||||
235 | + auto values = joinEnumValues(std::begin(dpiAdjustmentPolicyLookup), | ||||
236 | + std::end(dpiAdjustmentPolicyLookup)); | ||||
237 | + qWarning("Unknown DPI adjustment policy: %s. Supported values are: %s.", | ||||
238 | + policyText.constData(), values.constData()); | ||||
239 | + } | ||||
240 | + } | ||||
241 | + if (dpiAdjustmentPolicy == DpiAdjustmentPolicy::NotSet) | ||||
242 | + dpiAdjustmentPolicy = DpiAdjustmentPolicy::UpOnly; | ||||
243 | + } | ||||
244 | + | ||||
245 | + // Apply adjustment policy. | ||||
246 | + const QDpi baseDpi = screen->logicalBaseDpi(); | ||||
247 | + const qreal dpiAdjustmentFactor = rawFactor / roundedFactor; | ||||
248 | + | ||||
249 | + // Return the base DPI for cases where there is no adjustment | ||||
250 | + if (dpiAdjustmentPolicy == DpiAdjustmentPolicy::Disabled) | ||||
251 | + return baseDpi; | ||||
252 | + if (dpiAdjustmentPolicy == DpiAdjustmentPolicy::UpOnly && dpiAdjustmentFactor < 1) | ||||
253 | + return baseDpi; | ||||
254 | + | ||||
255 | + return QDpi(baseDpi.first * dpiAdjustmentFactor, baseDpi.second * dpiAdjustmentFactor); | ||||
256 | +} | ||||
257 | + | ||||
258 | void QHighDpiScaling::initHighDpiScaling() | ||||
259 | { | ||||
260 | // Determine if there is a global scale factor set. | ||||
261 | @@ -257,8 +457,6 @@ void QHighDpiScaling::initHighDpiScaling() | ||||
262 | | ||||
263 | m_pixelDensityScalingActive = false; //set in updateHighDpiScaling below | ||||
264 | | ||||
265 | - // we update m_active in updateHighDpiScaling, but while we create the | ||||
266 | - // screens, we have to assume that m_usePixelDensity implies scaling | ||||
267 | m_active = m_globalScalingActive || m_usePixelDensity; | ||||
268 | } | ||||
269 | | ||||
270 | @@ -310,7 +508,7 @@ void QHighDpiScaling::updateHighDpiScaling() | ||||
271 | ++i; | ||||
272 | } | ||||
273 | } | ||||
274 | - m_active = m_globalScalingActive || m_screenFactorSet || m_pixelDensityScalingActive; | ||||
275 | + m_active = m_globalScalingActive || m_usePixelDensity; | ||||
276 | } | ||||
277 | | ||||
278 | /* | ||||
279 | @@ -371,22 +569,8 @@ qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen) | ||||
280 | { | ||||
281 | qreal factor = qreal(1.0); | ||||
282 | if (screen) { | ||||
283 | - if (m_usePixelDensity) { | ||||
284 | - qreal pixelDensity = screen->pixelDensity(); | ||||
285 | - | ||||
286 | - // Pixel density reported by the screen is sometimes not precise enough, | ||||
287 | - // so recalculate it: divide px (physical pixels) by dp (device-independent pixels) | ||||
288 | - // for both width and height, and then use the average if it is different from | ||||
289 | - // the one initially reported by the screen | ||||
290 | - QRect screenGeometry = screen->geometry(); | ||||
291 | - qreal wFactor = qreal(screenGeometry.width()) / qRound(screenGeometry.width() / pixelDensity); | ||||
292 | - qreal hFactor = qreal(screenGeometry.height()) / qRound(screenGeometry.height() / pixelDensity); | ||||
293 | - qreal averageDensity = (wFactor + hFactor) / 2; | ||||
294 | - if (!qFuzzyCompare(pixelDensity, averageDensity)) | ||||
295 | - pixelDensity = averageDensity; | ||||
296 | - | ||||
297 | - factor *= pixelDensity; | ||||
298 | - } | ||||
299 | + if (m_usePixelDensity) | ||||
300 | + factor *= roundScaleFactor(rawScaleFactor(screen)); | ||||
301 | if (m_screenFactorSet) { | ||||
302 | QVariant screenFactor = screen->screen()->property(scaleFactorProperty); | ||||
303 | if (screenFactor.isValid()) | ||||
304 | @@ -399,13 +583,15 @@ qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen) | ||||
305 | QDpi QHighDpiScaling::logicalDpi(const QScreen *screen) | ||||
306 | { | ||||
307 | // (Note: m_active test is performed at call site.) | ||||
308 | - if (!screen) | ||||
309 | + if (!screen || !screen->handle()) | ||||
310 | return QDpi(96, 96); | ||||
311 | | ||||
312 | - qreal platformScreenfactor = screenSubfactor(screen->handle()); | ||||
313 | - QDpi platformScreenDpi = screen->handle()->logicalDpi(); | ||||
314 | - return QDpi(platformScreenDpi.first / platformScreenfactor, | ||||
315 | - platformScreenDpi.second / platformScreenfactor); | ||||
316 | + if (!m_usePixelDensity) | ||||
317 | + return screen->handle()->logicalDpi(); | ||||
318 | + | ||||
319 | + const qreal scaleFactor = rawScaleFactor(screen->handle()); | ||||
320 | + const qreal roundedScaleFactor = roundScaleFactor(scaleFactor); | ||||
321 | + return effectiveLogicalDpi(screen->handle(), scaleFactor, roundedScaleFactor); | ||||
322 | } | ||||
323 | | ||||
324 | qreal QHighDpiScaling::factor(const QScreen *screen) | ||||
325 | diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h | ||||
326 | index ecd9ed6515..55bddfeb88 100644 | ||||
327 | --- a/src/gui/kernel/qhighdpiscaling_p.h | ||||
328 | +++ b/src/gui/kernel/qhighdpiscaling_p.h | ||||
329 | @@ -71,7 +71,33 @@ typedef QPair<qreal, qreal> QDpi; | ||||
330 | | ||||
331 | #ifndef QT_NO_HIGHDPISCALING | ||||
332 | class Q_GUI_EXPORT QHighDpiScaling { | ||||
333 | + Q_GADGET | ||||
334 | public: | ||||
335 | + enum class HighDpiScaleFactorRoundingPolicy { | ||||
336 | + NotSet, | ||||
337 | + Round, | ||||
338 | + Ceil, | ||||
339 | + Floor, | ||||
340 | + RoundPreferFloor, | ||||
341 | + PassThrough | ||||
342 | + }; | ||||
343 | + Q_ENUM(HighDpiScaleFactorRoundingPolicy) | ||||
344 | + | ||||
345 | + enum class DpiAdjustmentPolicy { | ||||
346 | + NotSet, | ||||
347 | + Enabled, | ||||
348 | + Disabled, | ||||
349 | + UpOnly | ||||
350 | + }; | ||||
351 | + Q_ENUM(DpiAdjustmentPolicy) | ||||
352 | + | ||||
353 | + QHighDpiScaling() = delete; | ||||
354 | + ~QHighDpiScaling() = delete; | ||||
355 | + QHighDpiScaling(const QHighDpiScaling &) = delete; | ||||
356 | + QHighDpiScaling &operator=(const QHighDpiScaling &) = delete; | ||||
357 | + QHighDpiScaling(QHighDpiScaling &&) = delete; | ||||
358 | + QHighDpiScaling &operator=(QHighDpiScaling &&) = delete; | ||||
359 | + | ||||
360 | static void initHighDpiScaling(); | ||||
361 | static void updateHighDpiScaling(); | ||||
362 | static void setGlobalFactor(qreal factor); | ||||
363 | @@ -88,6 +114,9 @@ public: | ||||
364 | static QDpi logicalDpi(const QScreen *screen); | ||||
365 | | ||||
366 | private: | ||||
367 | + static qreal rawScaleFactor(const QPlatformScreen *screen); | ||||
368 | + static qreal roundScaleFactor(qreal rawFactor); | ||||
369 | + static QDpi effectiveLogicalDpi(const QPlatformScreen *screen, qreal rawFactor, qreal roundedFactor); | ||||
370 | static qreal screenSubfactor(const QPlatformScreen *screen); | ||||
371 | | ||||
372 | static qreal m_factor; | ||||
373 | diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp | ||||
374 | index b7b312e89e..07a2231228 100644 | ||||
375 | --- a/src/gui/kernel/qplatformscreen.cpp | ||||
376 | +++ b/src/gui/kernel/qplatformscreen.cpp | ||||
377 | @@ -194,6 +194,20 @@ QDpi QPlatformScreen::logicalDpi() const | ||||
378 | 25.4 * s.height() / ps.height()); | ||||
379 | } | ||||
380 | | ||||
381 | +/*! | ||||
382 | + Reimplement to return the base logical DPI for the platform. This | ||||
383 | + DPI value should correspond to a standard-DPI (1x) display. The | ||||
384 | + default implementation returns 96. | ||||
385 | + | ||||
386 | + QtGui will use this value (together with logicalDpi) to compute | ||||
387 | + the scale factor when high-DPI scaling is enabled: | ||||
388 | + factor = logicalDPI / baseDPI | ||||
389 | +*/ | ||||
390 | +QDpi QPlatformScreen::logicalBaseDpi() const | ||||
391 | +{ | ||||
392 | + return QDpi(96, 96); | ||||
393 | +} | ||||
394 | + | ||||
395 | /*! | ||||
396 | Reimplement this function in subclass to return the device pixel ratio | ||||
397 | for the screen. This is the ratio between physical pixels and the | ||||
398 | diff --git a/src/gui/kernel/qplatformscreen.h b/src/gui/kernel/qplatformscreen.h | ||||
399 | index e9d64c8a29..63b5d5a4a7 100644 | ||||
400 | --- a/src/gui/kernel/qplatformscreen.h | ||||
401 | +++ b/src/gui/kernel/qplatformscreen.h | ||||
402 | @@ -113,6 +113,7 @@ public: | ||||
403 | | ||||
404 | virtual QSizeF physicalSize() const; | ||||
405 | virtual QDpi logicalDpi() const; | ||||
406 | + virtual QDpi logicalBaseDpi() const; | ||||
407 | virtual qreal devicePixelRatio() const; | ||||
408 | virtual qreal pixelDensity() const; | ||||
409 | | ||||
410 | diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp | ||||
411 | index 7dc8bb8080..80757c2135 100644 | ||||
412 | --- a/src/plugins/platforms/android/qandroidplatformscreen.cpp | ||||
413 | +++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp | ||||
414 | @@ -401,15 +401,17 @@ void QAndroidPlatformScreen::doRedraw() | ||||
415 | m_dirtyRect = QRect(); | ||||
416 | } | ||||
417 | | ||||
418 | +static const int androidLogicalDpi = 72; | ||||
419 | + | ||||
420 | QDpi QAndroidPlatformScreen::logicalDpi() const | ||||
421 | { | ||||
422 | - qreal lDpi = QtAndroid::scaledDensity() * 72; | ||||
423 | + qreal lDpi = QtAndroid::scaledDensity() * androidLogicalDpi; | ||||
424 | return QDpi(lDpi, lDpi); | ||||
425 | } | ||||
426 | | ||||
427 | -qreal QAndroidPlatformScreen::pixelDensity() const | ||||
428 | +QDpi QAndroidPlatformScreen::logicalBaseDpi() const | ||||
429 | { | ||||
430 | - return QtAndroid::pixelDensity(); | ||||
431 | + return QDpi(androidLogicalDpi, androidLogicalDpi); | ||||
432 | } | ||||
433 | | ||||
434 | Qt::ScreenOrientation QAndroidPlatformScreen::orientation() const | ||||
435 | diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h | ||||
436 | index f15aeae3fd..5dc158e351 100644 | ||||
437 | --- a/src/plugins/platforms/android/qandroidplatformscreen.h | ||||
438 | +++ b/src/plugins/platforms/android/qandroidplatformscreen.h | ||||
439 | @@ -103,7 +103,7 @@ protected: | ||||
440 | | ||||
441 | private: | ||||
442 | QDpi logicalDpi() const override; | ||||
443 | - qreal pixelDensity() const override; | ||||
444 | + QDpi logicalBaseDpi() const override; | ||||
445 | Qt::ScreenOrientation orientation() const override; | ||||
446 | Qt::ScreenOrientation nativeOrientation() const override; | ||||
447 | void surfaceChanged(JNIEnv *env, jobject surface, int w, int h) override; | ||||
448 | diff --git a/src/plugins/platforms/cocoa/qcocoascreen.h b/src/plugins/platforms/cocoa/qcocoascreen.h | ||||
449 | index 9ded98df32..a73b97c771 100644 | ||||
450 | --- a/src/plugins/platforms/cocoa/qcocoascreen.h | ||||
451 | +++ b/src/plugins/platforms/cocoa/qcocoascreen.h | ||||
452 | @@ -64,6 +64,7 @@ public: | ||||
453 | qreal devicePixelRatio() const override; | ||||
454 | QSizeF physicalSize() const override { return m_physicalSize; } | ||||
455 | QDpi logicalDpi() const override { return m_logicalDpi; } | ||||
456 | + QDpi logicalBaseDpi() const override { return m_logicalDpi; } | ||||
457 | qreal refreshRate() const override { return m_refreshRate; } | ||||
458 | QString name() const override { return m_name; } | ||||
459 | QPlatformCursor *cursor() const override { return m_cursor; } | ||||
460 | diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp | ||||
461 | index 8a5f0e6577..ebde684038 100644 | ||||
462 | --- a/src/plugins/platforms/windows/qwindowsscreen.cpp | ||||
463 | +++ b/src/plugins/platforms/windows/qwindowsscreen.cpp | ||||
464 | @@ -254,15 +254,6 @@ QWindow *QWindowsScreen::windowAt(const QPoint &screenPoint, unsigned flags) | ||||
465 | return result; | ||||
466 | } | ||||
467 | | ||||
468 | -qreal QWindowsScreen::pixelDensity() const | ||||
469 | -{ | ||||
470 | - // QTBUG-49195: Use logical DPI instead of physical DPI to calculate | ||||
471 | - // the pixel density since it is reflects the Windows UI scaling. | ||||
472 | - // High DPI auto scaling should be disabled when the user chooses | ||||
473 | - // small fonts on a High DPI monitor, resulting in lower logical DPI. | ||||
474 | - return qMax(1, qRound(logicalDpi().first / 96)); | ||||
475 | -} | ||||
476 | - | ||||
477 | /*! | ||||
478 | \brief Determine siblings in a virtual desktop system. | ||||
479 | | ||||
480 | diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h | ||||
481 | index 33c9effa2a..a7b1c64e29 100644 | ||||
482 | --- a/src/plugins/platforms/windows/qwindowsscreen.h | ||||
483 | +++ b/src/plugins/platforms/windows/qwindowsscreen.h | ||||
484 | @@ -87,7 +87,7 @@ public: | ||||
485 | QImage::Format format() const override { return m_data.format; } | ||||
486 | QSizeF physicalSize() const override { return m_data.physicalSizeMM; } | ||||
487 | QDpi logicalDpi() const override { return m_data.dpi; } | ||||
488 | - qreal pixelDensity() const override; | ||||
489 | + QDpi logicalBaseDpi() const override { return QDpi(96, 96); }; | ||||
490 | qreal devicePixelRatio() const override { return 1.0; } | ||||
491 | qreal refreshRate() const override { return m_data.refreshRateHz; } | ||||
492 | QString name() const override { return m_data.name; } | ||||
493 | diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp | ||||
494 | index 57dbdc9bec..9af0794d29 100644 | ||||
495 | --- a/src/plugins/platforms/xcb/qxcbscreen.cpp | ||||
496 | +++ b/src/plugins/platforms/xcb/qxcbscreen.cpp | ||||
497 | @@ -671,11 +671,6 @@ QDpi QXcbScreen::logicalDpi() const | ||||
498 | return m_virtualDesktop->dpi(); | ||||
499 | } | ||||
500 | | ||||
501 | -qreal QXcbScreen::pixelDensity() const | ||||
502 | -{ | ||||
503 | - return m_pixelDensity; | ||||
504 | -} | ||||
505 | - | ||||
506 | QPlatformCursor *QXcbScreen::cursor() const | ||||
507 | { | ||||
508 | return m_cursor; | ||||
509 | @@ -739,12 +734,6 @@ void QXcbScreen::updateGeometry(const QRect &geometry, uint8_t rotation) | ||||
510 | if (m_sizeMillimeters.isEmpty()) | ||||
511 | m_sizeMillimeters = sizeInMillimeters(geometry.size(), m_virtualDesktop->dpi()); | ||||
512 | | ||||
513 | - qreal dpi = geometry.width() / physicalSize().width() * qreal(25.4); | ||||
514 | - | ||||
515 | - // Use 128 as a reference DPI on small screens. This favors "small UI" over "large UI". | ||||
516 | - qreal referenceDpi = physicalSize().width() <= 320 ? 128 : 96; | ||||
517 | - | ||||
518 | - m_pixelDensity = qMax(1, qRound(dpi/referenceDpi)); | ||||
519 | m_geometry = geometry; | ||||
520 | m_availableGeometry = geometry & m_virtualDesktop->workArea(); | ||||
521 | QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), m_geometry, m_availableGeometry); | ||||
522 | diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h | ||||
523 | index be6c45e415..3f619d71c2 100644 | ||||
524 | --- a/src/plugins/platforms/xcb/qxcbscreen.h | ||||
525 | +++ b/src/plugins/platforms/xcb/qxcbscreen.h | ||||
526 | @@ -161,7 +161,7 @@ public: | ||||
527 | QImage::Format format() const override; | ||||
528 | QSizeF physicalSize() const override { return m_sizeMillimeters; } | ||||
529 | QDpi logicalDpi() const override; | ||||
530 | - qreal pixelDensity() const override; | ||||
531 | + QDpi logicalBaseDpi() const override { return QDpi(96, 96); }; | ||||
532 | QPlatformCursor *cursor() const override; | ||||
533 | qreal refreshRate() const override { return m_refreshRate; } | ||||
534 | Qt::ScreenOrientation orientation() const override { return m_orientation; } | ||||
535 | @@ -226,7 +226,6 @@ private: | ||||
536 | Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation; | ||||
537 | QXcbCursor *m_cursor; | ||||
538 | int m_refreshRate = 60; | ||||
539 | - int m_pixelDensity = 1; | ||||
540 | QEdidParser m_edid; | ||||
541 | }; | ||||
542 | | ||||
543 | diff --git a/tests/manual/highdpi/highdpi.pro b/tests/manual/highdpi/highdpi.pro | ||||
544 | index 9db083cd82..2de8ed3bb5 100644 | ||||
545 | --- a/tests/manual/highdpi/highdpi.pro | ||||
546 | +++ b/tests/manual/highdpi/highdpi.pro | ||||
547 | @@ -15,3 +15,4 @@ HEADERS += \ | ||||
548 | RESOURCES += \ | ||||
549 | highdpi.qrc | ||||
550 | | ||||
551 | +DEFINES += HAVE_SCREEN_BASE_DPI | ||||
552 | -- | ||||
553 | 2.18.0.windows.1 | ||||
554 | |