Improve documentation of various pixel types
Also add a diagram showing the functions to use to convert between them, perhaps this can be more clear than textual description. Co-Authored-By: Stefan Csomor <csomor@advancedconcepts.ch>
This commit is contained in:
@@ -69,12 +69,13 @@ pixels**, abbreviated as "DIP", that are always of the same size on all
|
|||||||
displays and all platforms.
|
displays and all platforms.
|
||||||
|
|
||||||
Thus, the first thing do when preparing your application for high DPI support
|
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
|
is to stop using raw pixel values, as they mean different things under
|
||||||
recommended and replacing them with the values based on the text metrics, i.e.
|
different platforms when DPI scaling is used. Actually, using any pixel values
|
||||||
obtained using wxWindow::GetTextExtent(), or expressing them in dialog units
|
is not recommended and replacing them with the values based on the text
|
||||||
(see wxWindow::ConvertDialogToPixels()) is preferable. However the simplest
|
metrics, i.e. obtained using wxWindow::GetTextExtent(), or expressing them in
|
||||||
change is to just replace the pixel values with the values in DIP: for this,
|
dialog units (see wxWindow::ConvertDialogToPixels()) is preferable. However
|
||||||
just use wxWindow::FromDIP() to convert from one to the other.
|
the simplest change is to just replace the pixel values with the values in
|
||||||
|
DIP: for this, just use wxWindow::FromDIP() to convert from one to the other.
|
||||||
|
|
||||||
For example, if you have the existing code:
|
For example, if you have the existing code:
|
||||||
~~~{cpp}
|
~~~{cpp}
|
||||||
@@ -84,23 +85,73 @@ you can just replace it with
|
|||||||
~~~{cpp}
|
~~~{cpp}
|
||||||
myFrame->SetClientSize(myFrame->FromDIP(wxSize(400, 300)));
|
myFrame->SetClientSize(myFrame->FromDIP(wxSize(400, 300)));
|
||||||
~~~
|
~~~
|
||||||
|
although replacing it with something like
|
||||||
|
~~~{cpp}
|
||||||
|
const wxSize sizeM = myFrame->GetTextExtent("M");
|
||||||
|
myFrame->SetClientSize(100*sizeM.x, 40*sizeM.y));
|
||||||
|
~~~
|
||||||
|
might be even better.
|
||||||
|
|
||||||
|
In any case, remember that window and wxDC or wxGraphicsContext coordinates
|
||||||
|
must be in logical pixels that can depend on the current DPI scaling, and so
|
||||||
|
should never be fixed at compilation time.
|
||||||
|
|
||||||
|
|
||||||
Physical Pixels
|
Physical Pixels
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
In addition to (logical) pixels and DIPs discussed above, you may also need to
|
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.
|
work in physical pixel coordinates, corresponding to the actual display pixels.
|
||||||
Physical pixels are never scaled, on any platform, and must be used when
|
Physical pixels are never scaled, on any platform, and are used for the real
|
||||||
drawing graphics elements to ensure that the best possible resolution is used.
|
bitmap sizes. They are also used for drawing operations on wxGLCanvas, which
|
||||||
For example, all operations on wxGLCanvas use physical pixels.
|
is _different_ from wxDC and wxGraphicsContext that use logical pixels.
|
||||||
|
|
||||||
To convert between logical and physical pixels, you can use
|
Under MSW physical pixels are same as logical ones, but when writing portable
|
||||||
wxWindow::GetContentScaleFactor(): this is a value greater than or equal to 1,
|
code you need to convert between logical and physical pixels using
|
||||||
so a value in logical pixels needs to be multiplied by it in order to obtain
|
wxWindow::GetContentScaleFactor(): this function returns a value greater than
|
||||||
the value in physical pixels.
|
or equal to 1 (and always just 1 under MSW), 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
|
For example, in a wxGLCanvas created with the size of 100 (logical) pixels, the
|
||||||
rightmost physical pixel coordinate will be `100*GetContentScaleFactor()`.
|
rightmost physical pixel coordinate will be `100*GetContentScaleFactor()`
|
||||||
|
under all platforms.
|
||||||
|
|
||||||
|
You can convert from DIPs to physical pixels by converting DIPs to the logical
|
||||||
|
pixels first, but you can also do it directly, by using
|
||||||
|
wxWindow::GetDPIScaleFactor(). This function can return a value different from
|
||||||
|
1 even under MSW, i.e. it returns DPI scaling for physical display pixels.
|
||||||
|
|
||||||
|
Summary of Different Pixel Kinds
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
Under MSW, logical pixels are always the same as physical pixels, but are
|
||||||
|
different from DIPs, while under all the other platforms with DPI scaling
|
||||||
|
support (currently only GTK 3 and macOS), logical pixels are the same as DIP,
|
||||||
|
but different from physical pixels.
|
||||||
|
|
||||||
|
However under all platforms the following functions can be used to convert
|
||||||
|
between different kinds of pixels:
|
||||||
|
|
||||||
|
* From DIP to logical pixels: use wxWindow::FromDIP() or wxWindow::ToDIP().
|
||||||
|
* Logical pixels and physical pixels: multiply or divide by wxWindow::GetContentScaleFactor().
|
||||||
|
* From DIP to physical pixels: multiply or divide by wxWindow::GetDPIScaleFactor().
|
||||||
|
|
||||||
|
Or, in the diagram form:
|
||||||
|
|
||||||
|
@dot
|
||||||
|
digraph Pixels
|
||||||
|
{
|
||||||
|
node [shape = hexagon, style = filled, fontname = Helvetica];
|
||||||
|
|
||||||
|
LP [fillcolor = lightblue, label = "Logical\nPixels"];
|
||||||
|
DIP [fillcolor = yellow, label = "DI\nPixels"];
|
||||||
|
PP [fillcolor = green, label = "Physical\nPixels"];
|
||||||
|
|
||||||
|
LP -> PP [fontname = Helvetica, labeldistance = 5, labelangle = 30, dir = both, weight = 2, minlen = 3, label = "GetContentScaleFactor()", headlabel = "multiply by", taillabel = "divide by"];
|
||||||
|
LP -> DIP [fontname = Helvetica, labeldistance = 6, dir = both, weight = 2, minlen = 3, headlabel = "ToDIP()", taillabel = "FromDIP()"];
|
||||||
|
DIP -> PP [fontname = Helvetica, dir = both, minlen = 10, label = "GetDPIScaleFactor()" headlabel = "multiply by", taillabel = "divide by", constraint = false] ;
|
||||||
|
}
|
||||||
|
@enddot
|
||||||
|
|
||||||
|
|
||||||
High-Resolution Images and Artwork
|
High-Resolution Images and Artwork
|
||||||
|
|||||||
Reference in New Issue
Block a user