Gui: HiDPI fixes for Sketcher (#21098)

* Gui: HiDPI fixes for Sketcher

(cherry picked from commit f043fd7c5c8a6ea003811453165eee7d643f3779)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

(cherry picked from commit 42567ca9fcf2d6bab612715391a7b1911367f75d)

* Apply suggestions from code review

Co-authored-by: Kacper Donat <kadet1090@gmail.com>
(cherry picked from commit 28b52086e9cceae0e095421985479c546df49e44)

* qreal to double

(cherry picked from commit 4434ef18affa082a88390c1e68274de42f7c181e)

* more qreal to double

(cherry picked from commit df15eb6200d4ceab730ca8cf25ab0a90efe1cf41)

* Restore previous code which converted label size to points. View scaling would result in text that is too big.

* Ensure scaled marker size is one of the supported sizes for CIRCLE_LINE otherwise it would default to 7  (or what was set to "MarkerSize" in hGrp)

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: Tim Ringenbach <tim.ringenbach@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Kacper Donat <kadet1090@gmail.com>
This commit is contained in:
Jacques Beaurain
2025-05-06 10:47:09 -07:00
committed by GitHub
parent 90190f8d13
commit 1bf656b6e3
5 changed files with 44 additions and 30 deletions

View File

@@ -371,51 +371,40 @@ void EditModeCoinManager::ParameterObserver::updateElementSizeParameters(
double viewScalingFactor = hGrp->GetFloat("ViewScalingFactor", 1.0);
viewScalingFactor = Base::clamp<double>(viewScalingFactor, 0.5, 5.0);
int markersize = hGrp->GetInt("MarkerSize", 7);
int markerSize = hGrp->GetInt("MarkerSize", 7);
int defaultFontSizePixels =
Client.defaultApplicationFontSizePixels(); // returns height in pixels, not points
int sketcherfontSize = hGrp->GetInt("EditSketcherFontSize", defaultFontSizePixels);
int dpi = Client.getApplicationLogicalDPIX();
double dpi = Client.getApplicationLogicalDPIX();
double devicePixelRatio = Client.getDevicePixelRatio();
// simple scaling factor for hardcoded pixel values in the Sketcher
Client.drawingParameters.pixelScalingFactor = viewScalingFactor * dpi
/ 96; // 96 ppi is the standard pixel density for which pixel quantities were calculated
Client.drawingParameters.pixelScalingFactor = devicePixelRatio;
// About sizes:
// SoDatumLabel takes the size in points, not in pixels. This is because it uses QFont
// internally. Coin, at least our coin at this time, takes pixels, not points.
//
// DPI considerations:
// With hdpi monitors, the coin font labels do not respect the size passed in pixels:
// https://forum.freecad.org/viewtopic.php?f=3&t=54347&p=467610#p467610
// https://forum.freecad.org/viewtopic.php?f=10&t=49972&start=40#p467471
//
// Because I (abdullah) have 96 dpi logical, 82 dpi physical, and I see a 35px font setting for
// a "1" in a datum label as 34px, and I see kilsore and Elyas screenshots showing 41px and 61px
// in higher resolution monitors for the same configuration, I think that coin pixel size has to
// be corrected by the logical dpi of the monitor. The rationale is that: a) it obviously needs
// dpi correction, b) with physical dpi, the ratio of representation between kilsore and me is
// too far away.
//
// This means that the following correction does not have a documented basis, but appears
// necessary so that the Sketcher is usable in HDPI monitors.
Client.drawingParameters.coinFontSize =
std::lround(sketcherfontSize * 96.0f / dpi); // this is in pixels
Client.drawingParameters.labelFontSize = std::lround(
sketcherfontSize * 72.0f / dpi); // this is in points, as SoDatumLabel uses points
Client.drawingParameters.constraintIconSize = std::lround(0.8 * sketcherfontSize);
std::lround(sketcherfontSize * devicePixelRatio); // this is in pixels
Client.drawingParameters.labelFontSize =
std::lround(sketcherfontSize * devicePixelRatio * 72.0f
/ dpi); // this is in points, as SoDatumLabel uses points
Client.drawingParameters.constraintIconSize =
std::lround(0.8 * sketcherfontSize * devicePixelRatio);
// For marker size the global default is used.
//
// Rationale:
// -> Other WBs use the default value as is
// -> If a user has a HDPI, he will eventually change the value for the other WBs
// -> If we correct the value here in addition, we would get two times a resize
Client.drawingParameters.markerSize = markersize;
auto supportedsizes = Gui::Inventor::MarkerBitmaps::getSupportedSizes("CIRCLE_LINE");
auto scaledMarkerSize = std::lround(markerSize * devicePixelRatio);
auto const it =
std::lower_bound(supportedsizes.begin(), supportedsizes.end(), scaledMarkerSize);
if (it != supportedsizes.end()) {
scaledMarkerSize = *it;
}
Client.drawingParameters.markerSize = scaledMarkerSize;
Client.updateInventorNodeSizes();
}
@@ -1083,6 +1072,11 @@ int EditModeCoinManager::defaultApplicationFontSizePixels() const
return ViewProviderSketchCoinAttorney::defaultApplicationFontSizePixels(viewProvider);
}
double EditModeCoinManager::getDevicePixelRatio() const
{
return ViewProviderSketchCoinAttorney::getDevicePixelRatio(viewProvider);
}
int EditModeCoinManager::getApplicationLogicalDPIX() const
{
return ViewProviderSketchCoinAttorney::getApplicationLogicalDPIX(viewProvider);

View File

@@ -280,6 +280,8 @@ private:
int defaultApplicationFontSizePixels() const;
double getDevicePixelRatio() const;
int getApplicationLogicalDPIX() const;
void updateInventorNodeSizes();

View File

@@ -3969,6 +3969,16 @@ int ViewProviderSketch::defaultFontSizePixels() const
return static_cast<int>(metrics.height());
}
qreal ViewProviderSketch::getDevicePixelRatio() const
{
if (auto activeView = qobject_cast<Gui::View3DInventor*>(this->getActiveView())) {
auto glWidget = activeView->getViewer()->getGLWidget();
return glWidget->devicePixelRatio();
}
return QApplication::primaryScreen()->devicePixelRatio();
}
int ViewProviderSketch::getApplicationLogicalDPIX() const
{
return int(QApplication::primaryScreen()->logicalDotsPerInchX());

View File

@@ -857,6 +857,8 @@ private:
int defaultFontSizePixels() const;
qreal getDevicePixelRatio() const;
int getApplicationLogicalDPIX() const;
double getRotation(SbVec3f pos0, SbVec3f pos1) const;

View File

@@ -97,6 +97,7 @@ private:
static inline QFont getApplicationFont(const ViewProviderSketch& vp);
static inline double getRotation(const ViewProviderSketch& vp, SbVec3f pos0, SbVec3f pos1);
static inline int defaultApplicationFontSizePixels(const ViewProviderSketch& vp);
static inline double getDevicePixelRatio(const ViewProviderSketch& vp);
static inline int getApplicationLogicalDPIX(const ViewProviderSketch& vp);
static inline int getViewOrientationFactor(const ViewProviderSketch& vp);
@@ -195,6 +196,11 @@ ViewProviderSketchCoinAttorney::defaultApplicationFontSizePixels(const ViewProvi
return vp.defaultFontSizePixels();
}
inline double ViewProviderSketchCoinAttorney::getDevicePixelRatio(const ViewProviderSketch& vp)
{
return vp.getDevicePixelRatio();
}
inline int ViewProviderSketchCoinAttorney::getApplicationLogicalDPIX(const ViewProviderSketch& vp)
{
return vp.getApplicationLogicalDPIX();