diff --git a/src/Mod/Sketcher/Gui/EditModeCoinManager.cpp b/src/Mod/Sketcher/Gui/EditModeCoinManager.cpp index 58c1fef4fe..e4bde67259 100644 --- a/src/Mod/Sketcher/Gui/EditModeCoinManager.cpp +++ b/src/Mod/Sketcher/Gui/EditModeCoinManager.cpp @@ -371,51 +371,40 @@ void EditModeCoinManager::ParameterObserver::updateElementSizeParameters( double viewScalingFactor = hGrp->GetFloat("ViewScalingFactor", 1.0); viewScalingFactor = Base::clamp(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); diff --git a/src/Mod/Sketcher/Gui/EditModeCoinManager.h b/src/Mod/Sketcher/Gui/EditModeCoinManager.h index 2d06a995a6..baa7a4801f 100644 --- a/src/Mod/Sketcher/Gui/EditModeCoinManager.h +++ b/src/Mod/Sketcher/Gui/EditModeCoinManager.h @@ -280,6 +280,8 @@ private: int defaultApplicationFontSizePixels() const; + double getDevicePixelRatio() const; + int getApplicationLogicalDPIX() const; void updateInventorNodeSizes(); diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 315c569be0..353cc55d7d 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -3969,6 +3969,16 @@ int ViewProviderSketch::defaultFontSizePixels() const return static_cast(metrics.height()); } +qreal ViewProviderSketch::getDevicePixelRatio() const +{ + if (auto activeView = qobject_cast(this->getActiveView())) { + auto glWidget = activeView->getViewer()->getGLWidget(); + return glWidget->devicePixelRatio(); + } + + return QApplication::primaryScreen()->devicePixelRatio(); +} + int ViewProviderSketch::getApplicationLogicalDPIX() const { return int(QApplication::primaryScreen()->logicalDotsPerInchX()); diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.h b/src/Mod/Sketcher/Gui/ViewProviderSketch.h index 0cf380a4ad..f78e7ffb00 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.h +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.h @@ -857,6 +857,8 @@ private: int defaultFontSizePixels() const; + qreal getDevicePixelRatio() const; + int getApplicationLogicalDPIX() const; double getRotation(SbVec3f pos0, SbVec3f pos1) const; diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketchCoinAttorney.h b/src/Mod/Sketcher/Gui/ViewProviderSketchCoinAttorney.h index 9e2296b562..30f8b77bc7 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketchCoinAttorney.h +++ b/src/Mod/Sketcher/Gui/ViewProviderSketchCoinAttorney.h @@ -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();