Merge pull request #20594 from captain0xff/icon-res
Gui: make BitmapFactory::pixmapFromSvg dpi aware
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
# include <QImageReader>
|
||||
# include <QPainter>
|
||||
# include <QPalette>
|
||||
# include <QScreen>
|
||||
# include <QString>
|
||||
# include <QSvgRenderer>
|
||||
# include <QStyleOption>
|
||||
@@ -277,6 +278,8 @@ QPixmap BitmapFactoryInst::pixmap(const char* name) const
|
||||
QPixmap BitmapFactoryInst::pixmapFromSvg(const char* name, const QSizeF& size,
|
||||
const ColorMap& colorMapping) const
|
||||
{
|
||||
static qreal dpr = getMaximumDPR();
|
||||
|
||||
// If an absolute path is given
|
||||
QPixmap icon;
|
||||
QString iconPath;
|
||||
@@ -304,21 +307,15 @@ QPixmap BitmapFactoryInst::pixmapFromSvg(const char* name, const QSizeF& size,
|
||||
QFile file(iconPath);
|
||||
if (file.open(QFile::ReadOnly | QFile::Text)) {
|
||||
QByteArray content = file.readAll();
|
||||
icon = pixmapFromSvg(content, size, colorMapping);
|
||||
icon = pixmapFromSvg(content, size * dpr, colorMapping);
|
||||
}
|
||||
}
|
||||
|
||||
return icon;
|
||||
}
|
||||
if (!icon.isNull()) {
|
||||
icon.setDevicePixelRatio(dpr);
|
||||
}
|
||||
|
||||
QPixmap BitmapFactoryInst::pixmapFromSvg(const char* name, const QSizeF& size, qreal dpr,
|
||||
const ColorMap& colorMapping) const
|
||||
{
|
||||
qreal width = size.width() * dpr;
|
||||
qreal height = size.height() * dpr;
|
||||
QPixmap px(pixmapFromSvg(name, QSizeF(width, height), colorMapping));
|
||||
px.setDevicePixelRatio(dpr);
|
||||
return px;
|
||||
return icon;
|
||||
}
|
||||
|
||||
QPixmap BitmapFactoryInst::pixmapFromSvg(const QByteArray& originalContents, const QSizeF& size,
|
||||
@@ -677,3 +674,14 @@ QIcon BitmapFactoryInst::mergePixmap (const QIcon &base, const QPixmap &px, Gui:
|
||||
|
||||
return overlayedIcon;
|
||||
}
|
||||
|
||||
qreal BitmapFactoryInst::getMaximumDPR()
|
||||
{
|
||||
qreal dpr = 1.0F;
|
||||
|
||||
for (QScreen* screen: QGuiApplication::screens()) {
|
||||
dpr = std::max(screen->devicePixelRatio(), dpr);
|
||||
}
|
||||
|
||||
return dpr;
|
||||
}
|
||||
|
||||
@@ -87,14 +87,6 @@ public:
|
||||
*/
|
||||
QPixmap pixmapFromSvg(const char* name, const QSizeF& size,
|
||||
const ColorMap& colorMapping = ColorMap()) const;
|
||||
/** Retrieves a pixmap by name and size created by an
|
||||
* scalable vector graphics (SVG) and a device pixel ratio
|
||||
*
|
||||
* @param colorMapping - a dictionary of substitute colors.
|
||||
* Can be used to customize icon color scheme, e.g. crosshair color
|
||||
*/
|
||||
QPixmap pixmapFromSvg(const char* name, const QSizeF& size, qreal dpr,
|
||||
const ColorMap& colorMapping = ColorMap()) const;
|
||||
/** This method is provided for convenience and does the same
|
||||
* as the method above except that it creates the pixmap from
|
||||
* a byte array.
|
||||
@@ -149,6 +141,8 @@ public:
|
||||
/// Helper method to merge a pixmap into one corner of a QIcon
|
||||
static QIcon mergePixmap (const QIcon &base, const QPixmap &px, Gui::BitmapFactoryInst::Position position);
|
||||
|
||||
static qreal getMaximumDPR();
|
||||
|
||||
private:
|
||||
bool loadPixmap(const QString& path, QPixmap&) const;
|
||||
void restoreCustomPaths();
|
||||
|
||||
@@ -2697,10 +2697,7 @@ public:
|
||||
hotYF *= pRatio;
|
||||
}
|
||||
#endif
|
||||
qreal cursorWidth = size.width() * pRatio;
|
||||
qreal cursorHeight = size.height() * pRatio;
|
||||
QPixmap px(Gui::BitmapFactory().pixmapFromSvg(svgFile, QSizeF(cursorWidth, cursorHeight)));
|
||||
px.setDevicePixelRatio(pRatio);
|
||||
QPixmap px(Gui::BitmapFactory().pixmapFromSvg(svgFile, size));
|
||||
return QCursor(px, hotXF, hotYF);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -120,7 +120,7 @@ void ToolHandler::setSvgCursor(const QString& cursorName,
|
||||
//
|
||||
qreal pRatio = devicePixelRatio();
|
||||
bool isRatioOne = (pRatio == 1.0);
|
||||
qreal defaultCursorSize = isRatioOne ? 64 : 32;
|
||||
qreal cursorSize = isRatioOne ? 64 : 32;
|
||||
qreal hotX = x;
|
||||
qreal hotY = y;
|
||||
#if !defined(Q_OS_WIN32) && !defined(Q_OS_MACOS)
|
||||
@@ -129,15 +129,13 @@ void ToolHandler::setSvgCursor(const QString& cursorName,
|
||||
hotY *= pRatio;
|
||||
}
|
||||
#endif
|
||||
qreal cursorSize = defaultCursorSize * pRatio;
|
||||
|
||||
QPixmap pointer = Gui::BitmapFactory().pixmapFromSvg(cursorName.toStdString().c_str(),
|
||||
QSizeF(cursorSize, cursorSize),
|
||||
QSizeF{cursorSize, cursorSize},
|
||||
colorMapping);
|
||||
if (isRatioOne) {
|
||||
pointer = pointer.scaled(32, 32);
|
||||
}
|
||||
pointer.setDevicePixelRatio(pRatio);
|
||||
setCursor(pointer, hotX, hotY, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -5488,7 +5488,7 @@ void DocumentObjectItem::testStatus(bool resetStatus, QIcon& icon1, QIcon& icon2
|
||||
|
||||
if (currentStatus & Status::External) {
|
||||
static QPixmap pxExternal;
|
||||
int px = 12 * getMainWindow()->devicePixelRatioF();
|
||||
constexpr int px = 12;
|
||||
if (pxExternal.isNull()) {
|
||||
pxExternal = Gui::BitmapFactory().pixmapFromSvg("LinkOverlay",
|
||||
QSize(px, px));
|
||||
|
||||
@@ -1730,7 +1730,7 @@ QIcon ViewProviderLink::getIcon() const {
|
||||
|
||||
QPixmap ViewProviderLink::getOverlayPixmap() const {
|
||||
auto ext = getLinkExtension();
|
||||
int px = 12 * getMainWindow()->devicePixelRatioF();
|
||||
constexpr int px = 12;
|
||||
if(ext && ext->getLinkedObjectProperty() && ext->_getElementCountValue())
|
||||
return BitmapFactory().pixmapFromSvg("LinkArrayOverlay", QSizeF(px,px));
|
||||
else if(hasSubElement)
|
||||
|
||||
@@ -1129,8 +1129,8 @@ private:
|
||||
auto colorMapping = std::map<unsigned long, unsigned long>();
|
||||
colorMapping[defaultCrosshairColor] = color;
|
||||
|
||||
qreal fullIconWidth = 32 * pixelRatio;
|
||||
qreal iconWidth = 16 * pixelRatio;
|
||||
constexpr qreal fullIconWidth = 32;
|
||||
constexpr qreal iconWidth = 16;
|
||||
QPixmap cursorPixmap =
|
||||
Gui::BitmapFactory().pixmapFromSvg("Sketcher_Crosshair",
|
||||
QSizeF(fullIconWidth, fullIconWidth),
|
||||
@@ -1143,7 +1143,6 @@ private:
|
||||
cursorPainter.end();
|
||||
int hotX = 8;
|
||||
int hotY = 8;
|
||||
cursorPixmap.setDevicePixelRatio(pixelRatio);
|
||||
// only X11 needs hot point coordinates to be scaled
|
||||
if (qGuiApp->platformName() == QLatin1String("xcb")) {
|
||||
hotX *= pixelRatio;
|
||||
@@ -1422,17 +1421,16 @@ public:
|
||||
auto colorMapping = std::map<unsigned long, unsigned long>();
|
||||
colorMapping[defaultCrosshairColor] = color;
|
||||
|
||||
qreal fullIconWidth = 32 * pixelRatio;
|
||||
qreal iconWidth = 16 * pixelRatio;
|
||||
QPixmap cursorPixmap = Gui::BitmapFactory().pixmapFromSvg("Sketcher_Crosshair", QSizeF(fullIconWidth, fullIconWidth), colorMapping),
|
||||
icon = Gui::BitmapFactory().pixmapFromSvg("Constraint_Dimension", QSizeF(iconWidth, iconWidth));
|
||||
constexpr qreal fullIconWidth = 32;
|
||||
constexpr qreal iconWidth = 16;
|
||||
QPixmap cursorPixmap = Gui::BitmapFactory().pixmapFromSvg("Sketcher_Crosshair", QSizeF(fullIconWidth, fullIconWidth), colorMapping);
|
||||
QPixmap icon = Gui::BitmapFactory().pixmapFromSvg("Constraint_Dimension", QSizeF(iconWidth, iconWidth));
|
||||
QPainter cursorPainter;
|
||||
cursorPainter.begin(&cursorPixmap);
|
||||
cursorPainter.drawPixmap(16 * pixelRatio, 16 * pixelRatio, icon);
|
||||
cursorPainter.end();
|
||||
int hotX = 8;
|
||||
int hotY = 8;
|
||||
cursorPixmap.setDevicePixelRatio(pixelRatio);
|
||||
// only X11 needs hot point coordinates to be scaled
|
||||
if (qGuiApp->platformName() == QLatin1String("xcb")) {
|
||||
hotX *= pixelRatio;
|
||||
|
||||
@@ -406,12 +406,7 @@ DrawSketchHandler::suggestedConstraintsPixmaps(std::vector<AutoConstraint>& sugg
|
||||
break;
|
||||
}
|
||||
if (!iconType.isEmpty()) {
|
||||
qreal pixelRatio = 1;
|
||||
Gui::View3DInventorViewer* viewer = getViewer();
|
||||
if (viewer) {
|
||||
pixelRatio = viewer->devicePixelRatio();
|
||||
}
|
||||
int iconWidth = 16 * pixelRatio;
|
||||
constexpr int iconWidth = 16;
|
||||
QPixmap icon = Gui::BitmapFactory().pixmapFromSvg(iconType.toStdString().c_str(),
|
||||
QSize(iconWidth, iconWidth));
|
||||
pixmaps.push_back(icon);
|
||||
|
||||
@@ -1364,12 +1364,7 @@ protected:
|
||||
|
||||
QPixmap icon(std::string name)
|
||||
{
|
||||
qreal pixelRatio = 1;
|
||||
Gui::View3DInventorViewer* viewer = getViewer();
|
||||
if (viewer) {
|
||||
pixelRatio = viewer->devicePixelRatio();
|
||||
}
|
||||
int width = 16 * pixelRatio;
|
||||
constexpr int width = 16;
|
||||
return Gui::BitmapFactory().pixmapFromSvg(name.c_str(), QSize(width, width));
|
||||
}
|
||||
|
||||
|
||||
@@ -557,29 +557,14 @@ QColor QGVPage::getBackgroundColor()
|
||||
return fcColor.asValue<QColor>();
|
||||
}
|
||||
|
||||
double QGVPage::getDevicePixelRatio() const
|
||||
{
|
||||
for (Gui::MDIView* view : m_vpPage->getDocument()->getMDIViews()) {
|
||||
if (view->isDerivedFrom<Gui::View3DInventor>()) {
|
||||
return static_cast<Gui::View3DInventor*>(view)->getViewer()->devicePixelRatio();
|
||||
}
|
||||
}
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
QPixmap QGVPage::prepareCursorPixmap(const char* iconName, QPoint& hotspot)
|
||||
{
|
||||
|
||||
QPointF floatHotspot(hotspot);
|
||||
double pixelRatio = getDevicePixelRatio();
|
||||
|
||||
// Due to impossibility to query cursor size via Qt API, we stick to (32x32)*device_pixel_ratio
|
||||
// Due to impossibility to query cursor size via Qt API, we stick to (32x32)
|
||||
// as FreeCAD Wiki suggests - see https://wiki.freecad.org/HiDPI_support#Custom_cursor_size
|
||||
double cursorSize = 32.0 * pixelRatio;
|
||||
|
||||
QPixmap pixmap = Gui::BitmapFactory().pixmapFromSvg(iconName, QSizeF(cursorSize, cursorSize));
|
||||
pixmap.setDevicePixelRatio(pixelRatio);
|
||||
QPixmap pixmap = Gui::BitmapFactory().pixmapFromSvg(iconName, QSizeF(32, 32));
|
||||
|
||||
// The default (and here expected) SVG cursor graphics size is 64x64 pixels, thus we must adjust
|
||||
// the 64x64 based hotspot position for our 32x32 based cursor pixmaps accordingly
|
||||
@@ -590,7 +575,7 @@ QPixmap QGVPage::prepareCursorPixmap(const char* iconName, QPoint& hotspot)
|
||||
// therefore we must take care of the transformation ourselves...
|
||||
// Refer to QTBUG-68571 - https://bugreports.qt.io/browse/QTBUG-68571
|
||||
if (qGuiApp->platformName() == QLatin1String("xcb")) {
|
||||
floatHotspot *= pixelRatio;
|
||||
floatHotspot *= Gui::BitmapFactoryInst::getMaximumDPR();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -152,7 +152,6 @@ protected:
|
||||
|
||||
QColor getBackgroundColor();
|
||||
|
||||
double getDevicePixelRatio() const;
|
||||
QPixmap prepareCursorPixmap(const char* iconName, QPoint& hotspot);
|
||||
|
||||
void drawForeground(QPainter* painter, const QRectF& rect) override;
|
||||
|
||||
Reference in New Issue
Block a user