Hidpi, font&icon scaling, etc....

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Elyas
Posts: 22
Joined: Fri Sep 04, 2020 12:25 pm

Hidpi, font&icon scaling, etc....

Postby Elyas » Wed Sep 16, 2020 11:03 am

When using FreeCAD on a 4K 24 '' display, I noticed some artifacts that I was able to fix.
1.Prefereces dialog listbox scaling
FCpreferences.png
FCpreferences.png (440.93 KiB) Viewed 281 times

Code: Select all

--- a/src/Gui/DlgPreferencesImp.cpp
+++ b/src/Gui/DlgPreferencesImp.cpp
 using namespace Gui::Dialog;
 
 /* TRANSLATOR Gui::Dialog::DlgPreferencesImp */
@@ -68,7 +67,7 @@ DlgPreferencesImp::DlgPreferencesImp(QWidget* parent, Qt::WindowFlags fl)
 {
     ui->setupUi(this);
     ui->listBox->setFixedWidth(130);
-    ui->listBox->setGridSize(QSize(108, 120));
+    ui->listBox->setGridSize(QSize(108, 108+QFontMetrics(ui->listBox->font()).height()));
 
     connect(ui->buttonBox,  SIGNAL (helpRequested()),
             getMainWindow(), SLOT (whatsThis()));^M
2. Scaling the font on NaviCube

Code: Select all

--- a/src/Gui/NaviCube.cpp
+++ b/src/Gui/NaviCube.cpp
@@ -394,7 +394,8 @@ GLuint NaviCubeImplementation::createCubeFaceTex(QtGLWidget* gl, float gap, floa
	if (text) {
		ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/NaviCube");
		paint.setPen(Qt::white);
-		QFont sansFont(str("Helvetica"), 0.18 * texSize);
+        QFont sansFont(str("Helvetica"));
+        sansFont.setPixelSize(0.22 * texSize);
		QString fontString = QString::fromUtf8((hGrp->GetASCII("FontString")).c_str());
 		if (fontString.isEmpty()) {
 			// Improving readability
3. Font size in Sketcher

Code: Select all

diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp
index 009d34142..440dcdfb6 100644
--- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp
+++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp
@@ -3523,6 +3523,15 @@ float ViewProviderSketch::getScaleFactor()
     }
 }
 
+int ViewProviderSketch::fontSizeForCoin()
+{
+    int ldpi = this->getActiveView()->logicalDpiX();
+    float k = 96./ldpi;
+    ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
+    int fontSize = hGrp->GetInt("EditSketcherFontSize", ldpi/8);
+    return fontSize*k;
+}
+
 void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer /*=true*/)
 {
     assert(edit);
@@ -3558,9 +3567,6 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer
         Gui::coinRemoveAllChildren(edit->infoGroup);
     }
 
-    ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
-    int fontSize = hGrp->GetInt("EditSketcherFontSize", 17);
-
     int currentInfoNode = 0;
 
     ParameterGrp::handle hGrpsk = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
@@ -3573,6 +3579,7 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer
 
     int GeoId = 0;
 
+    ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
     int stdcountsegments = hGrp->GetInt("SegmentsPerGeometry", 50);
     // value cannot be smaller than 3
     if (stdcountsegments < 3)
@@ -3927,7 +3934,7 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer
 
             SoFont *font = new SoFont;
             font->name.setValue("Helvetica");
-            font->size.setValue(fontSize);
+            font->size.setValue(fontSizeForCoin());
 
             SoText2 *degreetext = new SoText2;
             degreetext->string = SbString(spline->getDegree());
@@ -4206,7 +4213,7 @@ void ViewProviderSketch::draw(bool temp /*=false*/, bool rebuildinformationlayer
 
                 SoFont *font = new SoFont;
                 font->name.setValue("Helvetica");
-                font->size.setValue(fontSize);
+                font->size.setValue(fontSizeForCoin());
 
                 SoText2 *degreetext = new SoText2;
                 degreetext->string = SbString("(")+SbString(*itm)+SbString(")");
@@ -5332,9 +5339,6 @@ void ViewProviderSketch::rebuildConstraintsVisual(void)
     Gui::coinRemoveAllChildren(edit->constrGroup);
     edit->vConstrType.clear();
 
-    ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
-    int fontSize = hGrp->GetInt("EditSketcherFontSize", 17);
-
     for (std::vector<Sketcher::Constraint *>::const_iterator it=constrlist.begin(); it != constrlist.end(); ++it) {
         // root separator for one constraint
         SoSeparator *sep = new SoSeparator();
@@ -5378,7 +5382,7 @@ void ViewProviderSketch::rebuildConstraintsVisual(void)
                                             ConstrDimColor
                                             :NonDrivingConstrDimColor)
                                         :DeactivatedConstrDimColor;
-                text->size.setValue(fontSize);
+                text->size.setValue(fontSizeForCoin());
                 text->useAntialiasing = false;
                 SoAnnotation *anno = new SoAnnotation();
                 anno->renderCaching = SoSeparator::OFF;
@@ -6047,10 +6051,9 @@ void ViewProviderSketch::createEditInventorNodes(void)
     CoordTextMaterials->diffuseColor = cursorTextColor;
     Coordsep->addChild(CoordTextMaterials);
 
-    int fontSize = hGrp->GetInt("EditSketcherFontSize", 17);
-
     SoFont *font = new SoFont();
-    font->size.setValue(fontSize);
+    font->size.setValue(fontSizeForCoin());
+
     Coordsep->addChild(font);
 
     edit->textPos = new SoTranslation();
diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.h b/src/Mod/Sketcher/Gui/ViewProviderSketch.h
index 571ec209b..b60e81d52 100644
--- a/src/Mod/Sketcher/Gui/ViewProviderSketch.h
+++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.h
@@ -282,6 +282,9 @@ protected:
 
     void forceUpdateData();
 
+    /// Return value for SoFont.size to display labels fixed size in pixe
+    int fontSizeForCoin();
+
     /// Return display string for constraint including hiding units if
     //requested.
     QString getPresentationString(const Sketcher::Constraint *constraint);
FCNaviCubeSketcher.png
FCNaviCubeSketcher.png (617.84 KiB) Viewed 281 times
Left in the screenshots:
OS: openSUSE Leap 15.2 (KDE//usr/share/xsessions/plasma5)
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.19.22284 (Git) AppImage
Build type: Release
Branch: master
Hash: bf1e8e48389f5e9e25bd77b67fe98da4213e797c
Python version: 3.8.5
Qt version: 5.12.5
Coin version: 4.0.0
OCC version: 7.4.0
Locale: Russian/Russia (ru_RU)
On Right:
OS: openSUSE Leap 15.2 (KDE//usr/share/xsessions/plasma5)
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.19.22426 +6 (Git)
Build type: Debug
Branch: hidpifixes
Hash: 134ca18c326c4dad4ab487c3590a0ee795ec190c
Python version: 3.6.10
Qt version: 5.12.7
Coin version: 3.1.3
OCC version: 6.9.1.oce-0.18
Locale: Russian/Russia (ru_RU)

It would be nice if someone check the behavior, for example on macOS
Last edited by Elyas on Wed Sep 16, 2020 12:31 pm, edited 1 time in total.
User avatar
Kunda1
Posts: 8052
Joined: Thu Jan 05, 2017 9:03 pm

Re: Hidpi, font&icon scaling, etc....

Postby Kunda1 » Wed Sep 16, 2020 11:38 am

Wow, awesome! Haven't tested. Can you make a PR so it would be easy to pull all changes in and compile ?
Want to contribute back to FC? Checkout:
#lowhangingfruit | Use the Source, Luke. | How to Help FreeCAD | How to report FC bugs and features
User avatar
Kunda1
Posts: 8052
Joined: Thu Jan 05, 2017 9:03 pm

Re: Hidpi, font&icon scaling, etc....

Postby Kunda1 » Wed Sep 16, 2020 11:50 am

vanuan wrote: pinged by pinger macro
CC @vanuan
Want to contribute back to FC? Checkout:
#lowhangingfruit | Use the Source, Luke. | How to Help FreeCAD | How to report FC bugs and features
Elyas
Posts: 22
Joined: Fri Sep 04, 2020 12:25 pm

Re: Hidpi, font&icon scaling, etc....

Postby Elyas » Wed Sep 16, 2020 11:53 am

Kunda1 wrote:
Wed Sep 16, 2020 11:38 am
Can you make a PR so it would be easy to pull all changes in and compile ?
No soon, unfortunately

The edits are minor. It doesn't take long to make by hand.
User avatar
Kunda1
Posts: 8052
Joined: Thu Jan 05, 2017 9:03 pm

Re: Hidpi, font&icon scaling, etc....

Postby Kunda1 » Wed Sep 16, 2020 11:59 am

Elyas wrote:
Wed Sep 16, 2020 11:53 am
Kunda1 wrote:
Wed Sep 16, 2020 11:38 am
Can you make a PR so it would be easy to pull all changes in and compile ?
No soon, unfortunately

The edits are minor. It doesn't take long to make by hand.
If I make a Draft PR would that be OK ? I just want the credit to go to you.
Want to contribute back to FC? Checkout:
#lowhangingfruit | Use the Source, Luke. | How to Help FreeCAD | How to report FC bugs and features
Elyas
Posts: 22
Joined: Fri Sep 04, 2020 12:25 pm

Re: Hidpi, font&icon scaling, etc....

Postby Elyas » Wed Sep 16, 2020 12:04 pm

Kunda1 wrote:
Wed Sep 16, 2020 11:59 am
If I make a Draft PR would that be OK ? I just want the credit to go to you.
You can use everything published here without restrictions
User avatar
vanuan
Posts: 449
Joined: Wed Oct 24, 2018 9:49 pm

Re: Hidpi, font&icon scaling, etc....

Postby vanuan » Wed Sep 16, 2020 3:40 pm

1. I approve
2. That's not good. Would rather scale the navi box to fit the current text size, like you did for settings
3. Controversial. It is strange that the current font size doesn't fit constraints. Which scale factor did you use? Are you using some accessibility scaling? If you have a large physical size display, wouldn't you rather use a smaller scale factor since the text would still be readable? If it's not readable at smaller scale factor, then even users with low DPI should've seen the huge font size.

Please read the HiDPI master plan:
https://wiki.freecadweb.org/HiDPI_support

It's the UI that should be relative to the font size, not font sizes scaled to fix different screen resolutions. Font sizes should be fixed in points (pt).
Elyas
Posts: 22
Joined: Fri Sep 04, 2020 12:25 pm

Re: Hidpi, font&icon scaling, etc....

Postby Elyas » Wed Sep 16, 2020 5:35 pm

vanuan wrote:
Wed Sep 16, 2020 3:40 pm
2. That's not good. Would rather scale the navi box to fit the current text size, like you did for settings
Who and how will determine the font size to which NaviCube should be adjusted?
now:

Code: Select all

m_CubeWidgetSize = (hGrp->GetInt("CubeSize", 132));
I think it's right to let the user set the size of the cube they want.
vanuan wrote:
Wed Sep 16, 2020 3:40 pm
3. Controversial.
3.1 This change removes the inconsistency stated in the Preferences for font size in Sketcher.
3.2 Constraints size - it will next step (i hope).
3.3 I have not used generic scaling. The FreeCAD GUI behaves pretty well in terms of scale, except in a few places.
vanuan wrote:
Wed Sep 16, 2020 3:40 pm
It's the UI that should be relative to the font size, not font sizes scaled to fix different screen resolutions. Font sizes should be fixed in points (pt).
I'm trying to fix bugs by minimally affecting the existing code, and not rewrite everything.
User avatar
vanuan
Posts: 449
Joined: Wed Oct 24, 2018 9:49 pm

Re: Hidpi, font&icon scaling, etc....

Postby vanuan » Wed Sep 16, 2020 7:27 pm

Elyas wrote:
Wed Sep 16, 2020 5:35 pm
Who and how will determine the font size to which NaviCube should be adjusted?
Well, who and how determines the size for "ui->listBox->font()" that you used in the preferences dialog to adjust the listbox grid size?
Elyas wrote:
Wed Sep 16, 2020 5:35 pm
now:

Code: Select all

m_CubeWidgetSize = (hGrp->GetInt("CubeSize", 132));
I think it's right to let the user set the size of the cube they want.
Well, if the user sets both the cube size and the font size, those are in conflict, don't you think?
So if the cube text doesn't fit on the cube face there are the following options:

1. Make the cube font smaller
2. Make the cube size larger
3. Do nothing, let the text overflow and make the user adjust the corresponding settings
4. Auto-adjust the cube size or the cube font settings when changing one or the other

As I see it, the issue is that the cube size is specified in absolute units (pixels) while the font size is specified in relative units (points).

Your solution:

1. Ignores the font setting specified in the FreeCAD settings
2. Ignores the scale factor specified in the OS display settings
3. Uses the font size in pixels

So, it doesn't work well for HiDPI support. When switching from one display to another, user would have to adjust the Cube size to be able to read the text comfortably. HiDPI support implies that it is comfortable to use software without adjusting any software-specific settings. That is, all fonts should be specified in points, scaled accordingly to the OS display settings. All the UI elements should be automatically scaled so that the text would not overflow.

Those are the basic principles of HiDPI support.
Elyas wrote:
Wed Sep 16, 2020 5:35 pm
3.1 This change removes the inconsistency stated in the Preferences for font size in Sketcher.
3.2 Constraints size - it will next step (i hope).
3.3 I have not used generic scaling. The FreeCAD GUI behaves pretty well in terms of scale, except in a few places.
Before your change the default font size for EditSketcherFontSize was 17 pixels. After your change the default font size is 12 pixels multiplied by the dpi scale factor. So, before it was 17 hardware pixels, after it is 12 device independent pixels.

I would rather change the user setting so that it is specified in points and use a default size of 13 pt. Coin specifies the font size either in pixels (for 2D) or in inches (for 3D). So the font size in points can be easily converted to the Coin font size in pixels or inches by using dpi and dpi scale factor.
Elyas wrote:
Wed Sep 16, 2020 5:35 pm
vanuan wrote:
Wed Sep 16, 2020 3:40 pm
It's the UI that should be relative to the font size, not font sizes scaled to fix different screen resolutions. Font sizes should be fixed in points (pt).
I'm trying to fix bugs by minimally affecting the existing code, and not rewrite everything.
I'm afraid that those are small steps in the wrong direction. Eventually, somebody will have to step in and make huge steps to fix every "minimally affecting fix".
Elyas
Posts: 22
Joined: Fri Sep 04, 2020 12:25 pm

Re: Hidpi, font&icon scaling, etc....

Postby Elyas » Wed Sep 16, 2020 8:38 pm

Before your change the default font size for EditSketcherFontSize was 17 pixels. After your change the default font size is 12 pixels multiplied by the dpi scale factor. So, before it was 17 hardware pixels, after it is 12 device independent pixels.
The bug is:
If in Prefereces editSktcherFontSize = 17 (px - is it means pixels?)
The real font size in Sketcher window is not 17 pixels & not 17 points.(Coin font size - it is not pixels)
After my edits font size in window match preferences. (means pixels)
Is it wrong direction?

What do you suggest?
To define font size in Preferences as ponts - may be it right way. But this does not solve most of the questions.

NaviCube:
Neither before nor after the corrections the user has any control over the font size. There is no conflict. If you want to automatically scale the NaviCube dimensions, it is possible, but that is a different task. Matching the font size and cube should still be. Now it is being done wrong.