mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-08 04:50:07 +01:00
Add the High DPI Overview doc from wxWidgets
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
@@ -31,6 +31,7 @@ various aspects of the library, which are listed here.
|
||||
font_encodings
|
||||
font_overview
|
||||
grid_overview
|
||||
high_dpi_overview
|
||||
html_overview
|
||||
internationalization
|
||||
writing_non_english_applications
|
||||
|
||||
180
docs/sphinx/rest_substitutions/overviews/high_dpi_overview.rst
Normal file
180
docs/sphinx/rest_substitutions/overviews/high_dpi_overview.rst
Normal file
@@ -0,0 +1,180 @@
|
||||
.. include:: headings.inc
|
||||
|
||||
|
||||
.. _html overview:
|
||||
|
||||
======================================
|
||||
|phoenix_title| **High DPI Overview**
|
||||
======================================
|
||||
|
||||
|
||||
|
||||
|
||||
High DPI Support in wxWidgets
|
||||
=============================
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Many modern displays have way more pixels on the same surface than used to be
|
||||
the norm, resulting in much higher values of DPI (dots, i.e. pixels, per inch)
|
||||
than the traditionally used values. This allows to render texts, or geometric
|
||||
shapes in general much more smoothly.
|
||||
|
||||
As an illustration here are two scaled up views of the same text in 11 pt
|
||||
Helvetica using up the same space on screen. First on an original Mac display
|
||||
at 72 dpi, then on a High DPI Display, called "Retina" by Apple with twice as
|
||||
many pixels in both dimensions (144 dpi), thus 4 times the number of pixels on
|
||||
the same surface. Using these the contours are much more detailed.
|
||||
|
||||
.. figure:: _static/images/overviews/overview_highdpi_text_72.png
|
||||
:alt: 11 pt Helvetica at 72 DPI
|
||||
:align: center
|
||||
|
||||
11 pt Helvetica at 72 DPI
|
||||
|
||||
|
||||
.. figure:: _static/images/overviews/overview_highdpi_text_144.png
|
||||
:alt: 11 pt Helvetica at 144 DPI
|
||||
:align: center
|
||||
|
||||
11 pt Helvetica at 144 DPI
|
||||
|
||||
|
||||
To the user the DPI is typically expressed using a scaling factor, by which the
|
||||
baseline DPI value is multiplied. For example, MSW systems may use 125% or 150%
|
||||
scaling, meaning that they use DPI of 120 or 144 respectively, as baseline DPI
|
||||
value is 96. Similarly, Linux systems may use "2x" scaling, resulting in DPI
|
||||
value of 192. Macs are slightly different, as even they also may use "2x"
|
||||
scaling, as in the example above, the effective DPI corresponding to it is 144,
|
||||
as the baseline value on this platform is 72.
|
||||
|
||||
|
||||
The Problem with High DPI Displays
|
||||
----------------------------------
|
||||
|
||||
If high DPI displays were treated in the same way as normal ones, existing
|
||||
applications would look tiny on them. For example, a square window 500 pixels
|
||||
in size would take half of a standard 1920×1080 ("Full HD") display vertically,
|
||||
but only a quarter on a 3840×2160 ("4K UHD") display. To prevent this from
|
||||
happening, most platforms automatically scale the windows by the scaling
|
||||
factor, defined above, when displaying them on high DPI displays. In this
|
||||
example, scaling factor is 2 and so the actual size of the window on screen
|
||||
would become 1000 when automatic scaling is in effect.
|
||||
|
||||
Automatic scaling is convenient, but doesn't really allow the application to
|
||||
use the extra pixels available on the display. Visually, this means that the
|
||||
scaled application appears blurry, in contrast to sharper applications using
|
||||
the full display resolution, so a better solution for interpreting pixel values
|
||||
on high DPI displays is needed: one which allows to scale some pixel values
|
||||
(e.g. the total window size), but not some other ones (e.g. those used for
|
||||
drawing, which should remain unscaled to use the full available resolution).
|
||||
|
||||
|
||||
Pixel Values in wxWidgets
|
||||
=========================
|
||||
|
||||
Logical and Device-Independent Pixels
|
||||
-------------------------------------
|
||||
|
||||
Some systems like eg Apple's OSes automatically scale all the coordinates by
|
||||
the DPI scaling factor, however not all systems supported by wxWidgets do it --
|
||||
notably, MSW does not. This means that **logical pixels**, in which all
|
||||
coordinates and sizes are expressed in wxWidgets API, do *not* have the same
|
||||
meaning on all platforms when using high DPI displays. So while on macOS you
|
||||
can always pass in a size of (500,500) to create the window from the previous
|
||||
paragraph, whatever the resolution of the display is, you would have to
|
||||
increase this to (1000,1000) on MSW when working on a 200% display. To hide
|
||||
this difference from the application, wxWidgets provides **device-independent
|
||||
pixels**, abbreviated as "DIP", that are always of the same size on all
|
||||
displays and all platforms.
|
||||
|
||||
Thus, the first thing do when preparing your application for high DPI support
|
||||
is to stop using raw pixel values. Actually, using any pixel values is not
|
||||
recommended and replacing them with the values based on the text metrics, i.e.
|
||||
obtained using :meth:`wx.Window.GetTextExtent`, or expressing them in dialog units
|
||||
(see :meth:`wx.Window.ConvertDialogToPixels`) is preferable. However the simplest
|
||||
change is to just replace the pixel values with the values in DIP: for this,
|
||||
just use :meth:`wx.Window.FromDIP` to convert from one to the other.
|
||||
|
||||
For example, if you have the existing code::
|
||||
|
||||
myFrame.SetClientSize(wx.Size(400, 300))
|
||||
|
||||
you can just replace it with::
|
||||
|
||||
myFrame.SetClientSize(myFrame.FromDIP(wx.Size(400, 300)))
|
||||
|
||||
|
||||
Physical Pixels
|
||||
---------------
|
||||
|
||||
In addition to (logical) pixels and DIPs discussed above, you may also need to
|
||||
work in physical pixel coordinates, corresponding to the actual display pixels.
|
||||
Physical pixels are never scaled, on any platform, and must be used when
|
||||
drawing graphics elements to ensure that the best possible resolution is used.
|
||||
For example, all operations on wxGLCanvas use physical pixels.
|
||||
|
||||
To convert between logical and physical pixels, you can use
|
||||
:meth:`wx.Window.GetContentScaleFactor` this is a value greater than or equal to 1,
|
||||
so a value in logical pixels needs to be multiplied by it in order to obtain
|
||||
the value in physical pixels.
|
||||
|
||||
For example, in a wxGLCanvas created with the size of 100 (logical) pixels, the
|
||||
rightmost physical pixel coordinate will be ``100*GetContentScaleFactor()``.
|
||||
|
||||
|
||||
High-Resolution Images and Artwork
|
||||
==================================
|
||||
|
||||
In order to benefit from the increased detail on High DPI devices you might want
|
||||
to provide the images or artwork your application uses in higher resolutions as
|
||||
well. Note that it is not recommended to just provide a high-resolution version
|
||||
and let the system scale that down on 1x displays. Apart from performance
|
||||
consideration also the quality might suffer, contours become more blurry.
|
||||
|
||||
You can use vector based graphics like SVG or you can add the same image at different
|
||||
sizes / resolutions.
|
||||
|
||||
|
||||
|
||||
Platform-Specific Build Issues
|
||||
==============================
|
||||
|
||||
Generally speaking, all systems handle applications not specifically marked as
|
||||
being "DPI-aware" by emulating low-resolution display for them and scaling them
|
||||
up, resulting in blurry graphics and fonts, but globally preserving the
|
||||
application appearance. For the best results, the application needs to be
|
||||
explicitly marked as DPI-aware in a platform-dependent way.
|
||||
|
||||
|
||||
|
||||
Microsoft Windows
|
||||
-----------------
|
||||
|
||||
.. todo:: This section still needs to be updated to include Python-specific instructions.
|
||||
|
||||
The behaviour of the application when running on a high-DPI display depends on
|
||||
the values in its `manifest <https://docs.microsoft.com/en-us/windows/win32/sbscs/application-manifests>`_.
|
||||
If your application includes ``wx/msw/wx.rc``
|
||||
from its resource file, you need to predefine ``wxUSE_DPI_AWARE_MANIFEST`` to
|
||||
opt-in into `high DPI support <https://docs.microsoft.com/en-us/windows/win32/hidpi/high-dpi-desktop-application-development-on-windows>`_: define it as ``1`` for minimal DPI awareness and
|
||||
``2`` for full, per-monitor DPI awareness supported by Windows 10 version 1703 or
|
||||
later.
|
||||
|
||||
|
||||
|
||||
macOS
|
||||
-----
|
||||
|
||||
DPI-aware applications must set their ``NSPrincipalClass`` to ``wxNSApplication`` (or at
|
||||
least ``NSApplication``) in their ``Info.plist`` file. For wxPython applications the
|
||||
``Info.plist`` file is typically created when building an application bundle for your
|
||||
application. It is part of what is needed to make your collection of files into an
|
||||
application that macOS will recognize as being as being a GUI application. If you are
|
||||
using a tool like PyInstaller to build your application bundle then it will likely provide
|
||||
a way to add to or modify the content of the ``Info.plist`` file, or it can be edited by
|
||||
hand. Also see the Apple
|
||||
`high resolution guidelines <https://developer.apple.com/library/archive/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html>`_ for more information.
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
def OnUpdateUI(self, event):
|
||||
....
|
||||
if event.IsCheckable()
|
||||
event.Check(...some condition...)
|
||||
Reference in New Issue
Block a user