HiDPI support: Difference between revisions

From FreeCAD Documentation
(Marked this version for translation)
(Removed page from translation)
Line 1: Line 1:
<languages/>
<translate>


<!--T:63-->
{{VeryImportantMessage|
{{VeryImportantMessage|
This roadmap is probably obsolete. For more information see [[Development_roadmap|Development roadmap]].<br>
This roadmap is probably obsolete. For more information see [[Development_roadmap|Development roadmap]].<br>
Line 9: Line 6:
}}
}}


</translate>
{{TOCright}}
{{TOCright}}
<translate>


<!--T:61-->
[[File:HiDpiDevicePixelRatio.png|thumb|left|Device pixel ratio. 100% = 1, 200% = 2, 150% = 1.5]]
[[File:HiDpiDevicePixelRatio.png|thumb|left|Device pixel ratio. 100% = 1, 200% = 2, 150% = 1.5]]


<!--T:60-->
This is a [[Development_roadmap|project]] dedicated to support high-resolution displays in FreeCAD.
This is a [[Development_roadmap|project]] dedicated to support high-resolution displays in FreeCAD.


<!--T:1-->
HiDPI support refers to the issue of displaying raster graphics (fonts, cursors, images) and UI elements (buttons, menus, handles) on high-resolution displays. It's also a term introduced by Apple.
HiDPI support refers to the issue of displaying raster graphics (fonts, cursors, images) and UI elements (buttons, menus, handles) on high-resolution displays. It's also a term introduced by Apple.


<!--T:2-->
The issue is that the physical size of a display remains the same (from 21 to 32 inches) while its resolution increases (FullHD, 4K, 8K).
The issue is that the physical size of a display remains the same (from 21 to 32 inches) while its resolution increases (FullHD, 4K, 8K).


<!--T:62-->
To solve the issue, Apple introduced "HiDPI", that is scaling all the UI elements according to the font size. Font sizes are specified in points, while their pixel value is calculated using DPI and device pixel ratio which is a scale factor specified by a user in OS settings. At the same time, raster images are rendered at their true pixel size, so individual pixels are less noticeable. It means that raster images are provided at higher resolution to make up for their size on a screen. Vector graphics (UI elements) are rendered accordingly, at higher resolution.
To solve the issue, Apple introduced "HiDPI", that is scaling all the UI elements according to the font size. Font sizes are specified in points, while their pixel value is calculated using DPI and device pixel ratio which is a scale factor specified by a user in OS settings. At the same time, raster images are rendered at their true pixel size, so individual pixels are less noticeable. It means that raster images are provided at higher resolution to make up for their size on a screen. Vector graphics (UI elements) are rendered accordingly, at higher resolution.


== Master plan == <!--T:3-->
== Master plan ==


=== Part one === <!--T:4-->
=== Part one ===


<!--T:5-->
Goal: Make sure that we make the most out of Qt support.
Goal: Make sure that we make the most out of Qt support.


<!--T:6-->
* In progress. Migrate the user base to Qt > 5.6 and set the AA_EnableHighDpiScaling to true.
* In progress. Migrate the user base to Qt > 5.6 and set the AA_EnableHighDpiScaling to true.
* Scale all cursors and icons (multiplying them by devicePixelRatio) https://github.com/FreeCAD/FreeCAD/pull/3712
* Scale all cursors and icons (multiplying them by devicePixelRatio) https://github.com/FreeCAD/FreeCAD/pull/3712
* Make all pixel graphics vector or available at various pixel density
* Make all pixel graphics vector or available at various pixel density


=== Part two === <!--T:7-->
=== Part two ===


<!--T:8-->
Goal: Make sure that the system font is correctly determined.
Goal: Make sure that the system font is correctly determined.


<!--T:9-->
* Bundle appropriate QPA theme plugins on all major platforms (AppImage, etc)
* Bundle appropriate QPA theme plugins on all major platforms (AppImage, etc)
* Find ways to detect that system's font is changed
* Find ways to detect that system's font is changed
Line 53: Line 39:
* Gather user feedback whether we need the customizable toolbar icon size
* Gather user feedback whether we need the customizable toolbar icon size


=== Part three === <!--T:10-->
=== Part three ===


<!--T:11-->
Goal: Make all UI widgets size relative to the font size
Goal: Make all UI widgets size relative to the font size


<!--T:12-->
* In all appropriate places, get system font metrics to determine the size of a widget.
* In all appropriate places, get system font metrics to determine the size of a widget.
* In places where real size is referenced, assume font size as a relative measure (72 points = 96 virtual pixels = 1 inch).
* In places where real size is referenced, assume font size as a relative measure (72 points = 96 virtual pixels = 1 inch).
Line 66: Line 50:
* Turn off AA_EnableHighDpiScaling
* Turn off AA_EnableHighDpiScaling


=== Part four === <!--T:13-->
=== Part four ===


<!--T:14-->
Goal: Support rescaling when the window is moved from one screen to another
Goal: Support rescaling when the window is moved from one screen to another


<!--T:15-->
* Detect that device pixel ratio has changed
* Detect that device pixel ratio has changed
* Notify all widgets depending on device pixel ratio or the font size
* Notify all widgets depending on device pixel ratio or the font size


== Background == <!--T:16-->
== Background ==


=== Display resolutions === <!--T:17-->
=== Display resolutions ===
</translate>
[[File:Vector Video Standards8.svg|800px]]
[[File:Vector Video Standards8.svg|800px]]
=== Device pixel ratio ===
<translate>
=== Device pixel ratio === <!--T:18-->


<!--T:19-->
It's a well-known concept for Web and Android developers. But not so much for desktop developers.
It's a well-known concept for Web and Android developers. But not so much for desktop developers.


<!--T:20-->
Basically, it's the ratio between physical pixels and device-independent pixels.
Basically, it's the ratio between physical pixels and device-independent pixels.


<!--T:21-->
First things first. UI positioning and size (x, y, width, height) are historically defined in pixels.
First things first. UI positioning and size (x, y, width, height) are historically defined in pixels.


<!--T:22-->
But as more variety of displays resolutions become available at many different physical sizes, it's become a problem software developers need to be aware of.
But as more variety of displays resolutions become available at many different physical sizes, it's become a problem software developers need to be aware of.


<!--T:23-->
FreeCAD development was started in 2002, long before such a problem was even foreseen.
FreeCAD development was started in 2002, long before such a problem was even foreseen.


<!--T:24-->
Ok, why not just increase DPI, you ask. Well, the issue is that you still want to benefit from the high-resolution display.
Ok, why not just increase DPI, you ask. Well, the issue is that you still want to benefit from the high-resolution display.


<!--T:25-->
All the raster graphics need to contain more pixels, while vector graphics (fonts and icons) should be of the same physical size as visible on the display.
All the raster graphics need to contain more pixels, while vector graphics (fonts and icons) should be of the same physical size as visible on the display.


<!--T:26-->
If you just change DPI, you would scale everything up and down. But in fact, you need all the pixel sizes to remain the same, while resources (images) to be displayed in a higher resolution.
If you just change DPI, you would scale everything up and down. But in fact, you need all the pixel sizes to remain the same, while resources (images) to be displayed in a higher resolution.


<!--T:27-->
So the concept of "Device-independent pixels" was introduced. The idea was that developers could keep not worrying about the physical size of a display and design UIs in virtual pixels.
So the concept of "Device-independent pixels" was introduced. The idea was that developers could keep not worrying about the physical size of a display and design UIs in virtual pixels.


<!--T:28-->
But the reality is that if you use raster graphics, it becomes pixelized, blurry, or aliased as it is displayed in non-native resolution. So developers now need to provide multiple versions of raster images, for each device pixel ratio. Usually, it's whole numbers: 1, 2, 3, 4. But it can also be fractional (125%, 150%, 175% = 1.25, 1.5, 1.75) meaning that there's still some scaling involved, but not as apparent.
But the reality is that if you use raster graphics, it becomes pixelized, blurry, or aliased as it is displayed in non-native resolution. So developers now need to provide multiple versions of raster images, for each device pixel ratio. Usually, it's whole numbers: 1, 2, 3, 4. But it can also be fractional (125%, 150%, 175% = 1.25, 1.5, 1.75) meaning that there's still some scaling involved, but not as apparent.


<!--T:29-->
* https://stackoverflow.com/questions/8785643/what-exactly-is-device-pixel-ratio
* https://stackoverflow.com/questions/8785643/what-exactly-is-device-pixel-ratio
* https://stackoverflow.com/questions/13911786/what-is-device-pixel-ratio-for
* https://stackoverflow.com/questions/13911786/what-is-device-pixel-ratio-for


== Issue testing/demonstration == <!--T:30-->
== Issue testing/demonstration ==


=== OS X === <!--T:31-->
=== OS X ===


<!--T:32-->
# Open "Display"
# Open "Display"
# Choose "Scaled"
# Choose "Scaled"
# Choose "Larger text" - this increases device pixel ratio
# Choose "Larger text" - this increases device pixel ratio


<!--T:33-->
Video: https://www.youtube.com/watch?v=4U3eh_fMo4o
Video: https://www.youtube.com/watch?v=4U3eh_fMo4o


=== X Window === <!--T:34-->
=== X Window ===


<!--T:35-->
Useful commands:
Useful commands:
</translate>
<pre>
<pre>
~$ xrdb -query
~$ xrdb -query
Line 152: Line 117:
resolution: 96x96 dots per inch
resolution: 96x96 dots per inch
</pre>
</pre>
=== Ubuntu (GNOME Shell) ===
<translate>
=== Ubuntu (GNOME Shell) === <!--T:36-->


<!--T:37-->
# Open "Displays" (Settings > Devices > Displays)
# Open "Displays" (Settings > Devices > Displays)
# Select the highest resolution available
# Select the highest resolution available
# Select scaling higher than 100%
# Select scaling higher than 100%


== Issues and solutions == <!--T:38-->
== Issues and solutions ==


<!--T:39-->
* Raster images (cursors, icons)
* Raster images (cursors, icons)
* Fonts (defined in pixels rather than points)
* Fonts (defined in pixels rather than points)
Line 170: Line 132:
* Selection distance (the hot area around selectable objects)
* Selection distance (the hot area around selectable objects)


=== Font size === <!--T:40-->
=== Font size ===


<!--T:41-->
Fonts are usually vector. So they don't require a higher resolution version to be able to scale up (in pixels). However, we can't just increase every font size and call it a day. People are used to font sizes in relation to how they look on paper. And on paper, it is known that 72pt font takes one inch, and on displays of old days, an inch was equal to 96 pixels at 1:1 zoom level.
Fonts are usually vector. So they don't require a higher resolution version to be able to scale up (in pixels). However, we can't just increase every font size and call it a day. People are used to font sizes in relation to how they look on paper. And on paper, it is known that 72pt font takes one inch, and on displays of old days, an inch was equal to 96 pixels at 1:1 zoom level.


<!--T:42-->
So, as display resolutions become higher, displays could fit more text lines of the same size. So naturally, as display physical size remains the same and our eyes don't become better at discerning smaller detail, we perceive the same font point size as smaller on higher resolutions.
So, as display resolutions become higher, displays could fit more text lines of the same size. So naturally, as display physical size remains the same and our eyes don't become better at discerning smaller detail, we perceive the same font point size as smaller on higher resolutions.


<!--T:43-->
To overcome this issue, OS implemented what it's called DPI scaling (or DPI font settings in the older days) or High-DPI scaling of the recent 4K displays. Users could change the DPI and benefit from much more real estate in terms of pixels while keeping a comfortable to read font size.
To overcome this issue, OS implemented what it's called DPI scaling (or DPI font settings in the older days) or High-DPI scaling of the recent 4K displays. Users could change the DPI and benefit from much more real estate in terms of pixels while keeping a comfortable to read font size.


=== Custom cursor size === <!--T:52-->
=== Custom cursor size ===


<!--T:53-->
The cursor size is kind of difficult. Qt recommends using a hardcoded image size of 32x32. As of 5.x it doesn't provide any functionality to integrate with OS and query the size of the mouse pointer. It's a shame since it means you can't benefit from accessibility settings, where cursor size can be set to an arbitrarily large value.
The cursor size is kind of difficult. Qt recommends using a hardcoded image size of 32x32. As of 5.x it doesn't provide any functionality to integrate with OS and query the size of the mouse pointer. It's a shame since it means you can't benefit from accessibility settings, where cursor size can be set to an arbitrarily large value.


<!--T:54-->
So, until Qt provides better guidance on the cursor size, let's use an image of 32 * device pixel ratio.
So, until Qt provides better guidance on the cursor size, let's use an image of 32 * device pixel ratio.


<!--T:55-->
In OS, for example in GNOME, cursor size appears to be fixed in terms of virtual pixels. That is, it respects the device pixel ratio (keep the same apparent size). But it does increase when you change the display resolution (that is, stays the same in pixels, but increase in apparent size).
In OS, for example in GNOME, cursor size appears to be fixed in terms of virtual pixels. That is, it respects the device pixel ratio (keep the same apparent size). But it does increase when you change the display resolution (that is, stays the same in pixels, but increase in apparent size).


<!--T:56-->
For example, here's a default setting for virtual pixels in GNOME:
For example, here's a default setting for virtual pixels in GNOME:


<!--T:57-->
<pre>
<pre>
~$ gsettings get org.gnome.desktop.interface cursor-size
~$ gsettings get org.gnome.desktop.interface cursor-size
Line 201: Line 155:
</pre>
</pre>


<!--T:58-->
Taking into account the scale factor, it means the physical pixel size of 128.
Taking into account the scale factor, it means the physical pixel size of 128.


<!--T:59-->
Qt doesn't provide the functionality to retrieve that value. So we have to either hard code it or provide a user setting to change that.
Qt doesn't provide the functionality to retrieve that value. So we have to either hard code it or provide a user setting to change that.


== Forum threads == <!--T:44-->
== Forum threads ==


<!--T:45-->
* [https://forum.freecadweb.org/viewtopic.php?t=34916 Improve support of high DPI displays] - general Qt support
* [https://forum.freecadweb.org/viewtopic.php?t=34916 Improve support of high DPI displays] - general Qt support
* [https://forum.freecadweb.org/viewtopic.php?t=39325 News: Qt 5.14 Is Bringing Significantly Better HiDPI Support] - general Qt support
* [https://forum.freecadweb.org/viewtopic.php?t=39325 News: Qt 5.14 Is Bringing Significantly Better HiDPI Support] - general Qt support
Line 227: Line 178:
* [https://forum.freecadweb.org/viewtopic.php?p=450061#p450061 Navigation cube scaling 2]
* [https://forum.freecadweb.org/viewtopic.php?p=450061#p450061 Navigation cube scaling 2]


== Relevant changes == <!--T:46-->
== Relevant changes ==


<!--T:47-->
* {{commit|a14b99e77}}
* {{commit|a14b99e77}}
* {{commit|2f2d50535}}
* {{commit|2f2d50535}}
Line 242: Line 192:
* {{commit|7dfeb801a}}
* {{commit|7dfeb801a}}


== Bugtracker Issues == <!--T:48-->
== Bugtracker Issues ==


<!--T:49-->
* Tickets tagged with [https://tracker.freecadweb.org/search.php?tag_string=HiDPI HiDPI]
* Tickets tagged with [https://tracker.freecadweb.org/search.php?tag_string=HiDPI HiDPI]


== External references == <!--T:50-->
== External references ==


<!--T:51-->
* https://doc.qt.io/qt-5/highdpi.html
* https://doc.qt.io/qt-5/highdpi.html
* https://doc.qt.io/qt-5/scalability.html
* https://doc.qt.io/qt-5/scalability.html
Line 255: Line 203:
* https://docs.microsoft.com/en-us/windows/win32/w8cookbook/high-dpi-for-desktop-apps-in-windows-8-1?redirectedfrom=MSDN
* https://docs.microsoft.com/en-us/windows/win32/w8cookbook/high-dpi-for-desktop-apps-in-windows-8-1?redirectedfrom=MSDN


</translate>
[[Category:Roadmap{{#translation:}}]]
[[Category:Roadmap{{#translation:}}]]
{{clear}}
{{clear}}

Revision as of 22:00, 4 March 2022

This roadmap is probably obsolete. For more information see Development roadmap.
If you are not involved with the development discussed here:
!!! PLEASE DO NOT EDIT OR TRANSLATE !!!

Device pixel ratio. 100% = 1, 200% = 2, 150% = 1.5

This is a project dedicated to support high-resolution displays in FreeCAD.

HiDPI support refers to the issue of displaying raster graphics (fonts, cursors, images) and UI elements (buttons, menus, handles) on high-resolution displays. It's also a term introduced by Apple.

The issue is that the physical size of a display remains the same (from 21 to 32 inches) while its resolution increases (FullHD, 4K, 8K).

To solve the issue, Apple introduced "HiDPI", that is scaling all the UI elements according to the font size. Font sizes are specified in points, while their pixel value is calculated using DPI and device pixel ratio which is a scale factor specified by a user in OS settings. At the same time, raster images are rendered at their true pixel size, so individual pixels are less noticeable. It means that raster images are provided at higher resolution to make up for their size on a screen. Vector graphics (UI elements) are rendered accordingly, at higher resolution.

Master plan

Part one

Goal: Make sure that we make the most out of Qt support.

  • In progress. Migrate the user base to Qt > 5.6 and set the AA_EnableHighDpiScaling to true.
  • Scale all cursors and icons (multiplying them by devicePixelRatio) https://github.com/FreeCAD/FreeCAD/pull/3712
  • Make all pixel graphics vector or available at various pixel density

Part two

Goal: Make sure that the system font is correctly determined.

  • Bundle appropriate QPA theme plugins on all major platforms (AppImage, etc)
  • Find ways to detect that system's font is changed
  • Remove the toolbar/icon size setting and make the toolbar size relative to the system font
  • Add an experimental setting "scale factor" which will depend on device pixel ratio and/or system font size
  • Rescale the toolbar/icon size according to the new experimental setting
  • Gather user feedback whether we need the customizable toolbar icon size

Part three

Goal: Make all UI widgets size relative to the font size

  • In all appropriate places, get system font metrics to determine the size of a widget.
  • In places where real size is referenced, assume font size as a relative measure (72 points = 96 virtual pixels = 1 inch).
  • Choose a reference device relative to which UI could scale up and down.
  • 2D coordinates and sizes should assume device-independent pixels.
  • Make sure qreal versions of APIs are used.
  • Turn off AA_EnableHighDpiScaling

Part four

Goal: Support rescaling when the window is moved from one screen to another

  • Detect that device pixel ratio has changed
  • Notify all widgets depending on device pixel ratio or the font size

Background

Display resolutions

Device pixel ratio

It's a well-known concept for Web and Android developers. But not so much for desktop developers.

Basically, it's the ratio between physical pixels and device-independent pixels.

First things first. UI positioning and size (x, y, width, height) are historically defined in pixels.

But as more variety of displays resolutions become available at many different physical sizes, it's become a problem software developers need to be aware of.

FreeCAD development was started in 2002, long before such a problem was even foreseen.

Ok, why not just increase DPI, you ask. Well, the issue is that you still want to benefit from the high-resolution display.

All the raster graphics need to contain more pixels, while vector graphics (fonts and icons) should be of the same physical size as visible on the display.

If you just change DPI, you would scale everything up and down. But in fact, you need all the pixel sizes to remain the same, while resources (images) to be displayed in a higher resolution.

So the concept of "Device-independent pixels" was introduced. The idea was that developers could keep not worrying about the physical size of a display and design UIs in virtual pixels.

But the reality is that if you use raster graphics, it becomes pixelized, blurry, or aliased as it is displayed in non-native resolution. So developers now need to provide multiple versions of raster images, for each device pixel ratio. Usually, it's whole numbers: 1, 2, 3, 4. But it can also be fractional (125%, 150%, 175% = 1.25, 1.5, 1.75) meaning that there's still some scaling involved, but not as apparent.

Issue testing/demonstration

OS X

  1. Open "Display"
  2. Choose "Scaled"
  3. Choose "Larger text" - this increases device pixel ratio

Video: https://www.youtube.com/watch?v=4U3eh_fMo4o

X Window

Useful commands:

~$ xrdb -query
*customization:	-color
Xft.dpi:	192
Xft.antialias:	1
Xft.hinting:	1
Xft.hintstyle:	hintslight
Xft.rgba:	rgb
Xcursor.size:	128
Xcursor.theme:	DMZ-White
~$ xdpyinfo | grep -B 2 resolution
screen #0:
  dimensions:    3840x2160 pixels (1016x572 millimeters)
  resolution:    96x96 dots per inch

Ubuntu (GNOME Shell)

  1. Open "Displays" (Settings > Devices > Displays)
  2. Select the highest resolution available
  3. Select scaling higher than 100%

Issues and solutions

  • Raster images (cursors, icons)
  • Fonts (defined in pixels rather than points)
  • Cursor hot point
  • Zoom/Rotate origin
  • Snap distance
  • Selection distance (the hot area around selectable objects)

Font size

Fonts are usually vector. So they don't require a higher resolution version to be able to scale up (in pixels). However, we can't just increase every font size and call it a day. People are used to font sizes in relation to how they look on paper. And on paper, it is known that 72pt font takes one inch, and on displays of old days, an inch was equal to 96 pixels at 1:1 zoom level.

So, as display resolutions become higher, displays could fit more text lines of the same size. So naturally, as display physical size remains the same and our eyes don't become better at discerning smaller detail, we perceive the same font point size as smaller on higher resolutions.

To overcome this issue, OS implemented what it's called DPI scaling (or DPI font settings in the older days) or High-DPI scaling of the recent 4K displays. Users could change the DPI and benefit from much more real estate in terms of pixels while keeping a comfortable to read font size.

Custom cursor size

The cursor size is kind of difficult. Qt recommends using a hardcoded image size of 32x32. As of 5.x it doesn't provide any functionality to integrate with OS and query the size of the mouse pointer. It's a shame since it means you can't benefit from accessibility settings, where cursor size can be set to an arbitrarily large value.

So, until Qt provides better guidance on the cursor size, let's use an image of 32 * device pixel ratio.

In OS, for example in GNOME, cursor size appears to be fixed in terms of virtual pixels. That is, it respects the device pixel ratio (keep the same apparent size). But it does increase when you change the display resolution (that is, stays the same in pixels, but increase in apparent size).

For example, here's a default setting for virtual pixels in GNOME:

~$ gsettings get org.gnome.desktop.interface cursor-size
64

Taking into account the scale factor, it means the physical pixel size of 128.

Qt doesn't provide the functionality to retrieve that value. So we have to either hard code it or provide a user setting to change that.

Forum threads

Relevant changes

Bugtracker Issues

  • Tickets tagged with HiDPI

External references