[vlc-devel] [PATCH 04/10] qt: respect Dpi while rendering Svg to QPixmap

Pierre Lamot pierre at videolabs.io
Fri Sep 29 10:25:06 CEST 2017


  Qt default behavior for rendering SVG is to ignore Dpi, which
  might leads to aliasing.
---
 modules/gui/qt/Makefile.am                         |  1 +
 modules/gui/qt/components/controller_widget.cpp    |  7 ++--
 .../gui/qt/components/playlist/standardpanel.cpp   | 10 +++--
 modules/gui/qt/dialogs/plugins.cpp                 | 12 ++++--
 modules/gui/qt/dialogs/toolbar.cpp                 |  3 +-
 modules/gui/qt/main_interface.cpp                  |  3 +-
 modules/gui/qt/util/imagehelper.cpp                | 47 ++++++++++++++++++++++
 modules/gui/qt/util/imagehelper.hpp                | 37 +++++++++++++++++
 8 files changed, 109 insertions(+), 11 deletions(-)
 create mode 100644 modules/gui/qt/util/imagehelper.cpp
 create mode 100644 modules/gui/qt/util/imagehelper.hpp

diff --git a/modules/gui/qt/Makefile.am b/modules/gui/qt/Makefile.am
index 141f4ae8f9..4c682e4e87 100644
--- a/modules/gui/qt/Makefile.am
+++ b/modules/gui/qt/Makefile.am
@@ -141,6 +141,7 @@ libqt_plugin_la_SOURCES = \
 	gui/qt/util/qvlcframe.hpp \
 	gui/qt/util/qvlcapp.hpp \
 	gui/qt/util/singleton.hpp \
+	gui/qt/util/imagehelper.cpp gui/qt/util/imagehelper.hpp \
 	gui/qt/styles/seekstyle.cpp gui/qt/styles/seekstyle.hpp
 if HAVE_WIN32
 libqt_plugin_la_SOURCES += \
diff --git a/modules/gui/qt/components/controller_widget.cpp b/modules/gui/qt/components/controller_widget.cpp
index 07e5e9fbb4..2cf7566745 100644
--- a/modules/gui/qt/components/controller_widget.cpp
+++ b/modules/gui/qt/components/controller_widget.cpp
@@ -30,6 +30,7 @@
 
 #include "input_manager.hpp"         /* Get notification of Volume Change */
 #include "util/input_slider.hpp"     /* SoundSlider */
+#include "util/imagehelper.hpp"
 
 #include <math.h>
 
@@ -52,7 +53,7 @@ SoundWidget::SoundWidget( QWidget *_parent, intf_thread_t * _p_intf,
 
     /* We need a Label for the pix */
     volMuteLabel = new QLabel;
-    volMuteLabel->setPixmap( QIcon( ":/toolbar/volume-medium" ).pixmap( 16, 16 ) );
+    volMuteLabel->setPixmap( ImageHelper::loadSvgToPixmap( ":/toolbar/volume-medium", 16, 16 ) );
 
     /* We might need a subLayout too */
     QVBoxLayout *subLayout;
@@ -131,7 +132,7 @@ void SoundWidget::refreshLabels()
 
     if( b_is_muted )
     {
-        volMuteLabel->setPixmap( QIcon( psz_icon ).pixmap( 16, 16 ) );
+        volMuteLabel->setPixmap( ImageHelper::loadSvgToPixmap( psz_icon, 16, 16 ) );
         volMuteLabel->setToolTip(qfu(vlc_pgettext("Tooltip|Unmute", "Unmute")));
         return;
     }
@@ -143,7 +144,7 @@ void SoundWidget::refreshLabels()
     else
         psz_icon = ":/toolbar/volume-medium";
 
-    volMuteLabel->setPixmap( QIcon( psz_icon ).pixmap( 16, 16 ) );
+    volMuteLabel->setPixmap( ImageHelper::loadSvgToPixmap( psz_icon, 16, 16 ) );
     volMuteLabel->setToolTip( qfu(vlc_pgettext("Tooltip|Mute", "Mute")) );
 }
 
diff --git a/modules/gui/qt/components/playlist/standardpanel.cpp b/modules/gui/qt/components/playlist/standardpanel.cpp
index 345c735892..3cc132eff1 100644
--- a/modules/gui/qt/components/playlist/standardpanel.cpp
+++ b/modules/gui/qt/components/playlist/standardpanel.cpp
@@ -40,6 +40,7 @@
 #include "dialogs/playlist.hpp"                   /* Playlist Dialog */
 #include "dialogs/mediainfo.hpp"                  /* MediaInfoDialog */
 #include "util/qt_dirs.hpp"
+#include "util/imagehelper.hpp"
 
 #include <vlc_services_discovery.h>               /* SD_CMD_SEARCH */
 #include <vlc_intf_strings.h>                     /* POP_ */
@@ -71,6 +72,8 @@
 
 #include <assert.h>
 
+#define DROPZONE_SIZE 112
+
 /* local helper */
 inline QModelIndex popupIndex( QAbstractItemView *view );
 
@@ -554,14 +557,15 @@ bool StandardPLPanel::eventFilter ( QObject *obj, QEvent * event )
         {
             QWidget *viewport = qobject_cast<QWidget *>( obj );
             QStylePainter painter( viewport );
-            QPixmap dropzone(":/dropzone");
+            QPixmap dropzone = ImageHelper::loadSvgToPixmap(":/dropzone", DROPZONE_SIZE, DROPZONE_SIZE);
+            qreal scale = dropzone.devicePixelRatio();
             QRect rect = viewport->geometry();
-            QSize size = rect.size() / 2 - dropzone.size() / 2;
+            QSize size = rect.size()  / 2 - dropzone.size() / (2 * scale);
             rect.adjust( 0, size.height(), 0 , 0 );
             painter.drawItemPixmap( rect, Qt::AlignHCenter, dropzone );
             /* now select the zone just below the drop zone and let Qt center
                the text by itself */
-            rect.adjust( 0, dropzone.size().height() + 10, 0, 0 );
+            rect.adjust( 0, dropzone.height() / scale + 10, 0, 0 );
             rect.setRight( viewport->geometry().width() );
             rect.setLeft( 0 );
             painter.drawItemText( rect,
diff --git a/modules/gui/qt/dialogs/plugins.cpp b/modules/gui/qt/dialogs/plugins.cpp
index d5f7edfdb5..83a5fcf709 100644
--- a/modules/gui/qt/dialogs/plugins.cpp
+++ b/modules/gui/qt/dialogs/plugins.cpp
@@ -32,6 +32,7 @@
 #include "extensions_manager.hpp"
 #include "managers/addons_manager.hpp"
 #include "util/animators.hpp"
+#include "util/imagehelper.hpp"
 
 #include <assert.h>
 
@@ -66,6 +67,9 @@
 #include <QToolButton>
 #include <QStackedWidget>
 
+//match the image source (width/height)
+#define SCORE_ICON_WIDTH_SCALE 4
+
 static QPixmap *loadPixmapFromData( char *, int size );
 
 
@@ -1209,9 +1213,11 @@ void AddonItemDelegate::paint( QPainter *painter,
     QPixmap scoreicon;
     if ( i_score )
     {
-        scoreicon = QPixmap( ":/addons/score" ).scaledToHeight(
-                    newopt.fontMetrics.height(), Qt::SmoothTransformation );
-        int i_width = ( (float) i_score / ADDON_MAX_SCORE ) * scoreicon.width();
+        int i_scoreicon_height = newopt.fontMetrics.height();
+        int i_scoreicon_width = i_scoreicon_height * SCORE_ICON_WIDTH_SCALE;
+        scoreicon = ImageHelper::loadSvgToPixmap( ":/addons/score",
+                    i_scoreicon_width, i_scoreicon_height );
+        int i_width = ( (float) i_score / ADDON_MAX_SCORE ) * i_scoreicon_width;
         /* Erase the end (value) of our pixmap with a shadow */
         QPainter erasepainter( &scoreicon );
         erasepainter.setCompositionMode( QPainter::CompositionMode_SourceIn );
diff --git a/modules/gui/qt/dialogs/toolbar.cpp b/modules/gui/qt/dialogs/toolbar.cpp
index 9e8da6d20f..755eaf30d9 100644
--- a/modules/gui/qt/dialogs/toolbar.cpp
+++ b/modules/gui/qt/dialogs/toolbar.cpp
@@ -34,6 +34,7 @@
 #include "util/buttons/DeckButtonsLayout.hpp"
 #include "util/buttons/BrowseButton.hpp"
 #include "util/buttons/RoundButton.hpp"
+#include "util/imagehelper.hpp"
 
 #include "qt.hpp"
 #include "input_manager.hpp"
@@ -668,7 +669,7 @@ void DroppingController::createAndAddWidget( QBoxLayout *newControlLayout,
     if( i_type == WIDGET_SPACER || i_type == WIDGET_SPACER_EXTEND )
     {
         QLabel *label = new QLabel( this );
-        label->setPixmap( QPixmap( ":/toolbar/space" ) );
+        label->setPixmap( ImageHelper::loadSvgToPixmap( ":/toolbar/space", height(), height() ) );
         if( i_type == WIDGET_SPACER_EXTEND )
         {
             label->setSizePolicy( QSizePolicy::MinimumExpanding,
diff --git a/modules/gui/qt/main_interface.cpp b/modules/gui/qt/main_interface.cpp
index 3a52373ad0..9624c36a5f 100644
--- a/modules/gui/qt/main_interface.cpp
+++ b/modules/gui/qt/main_interface.cpp
@@ -35,6 +35,7 @@
 
 #include "util/customwidgets.hpp"               // qtEventToVLCKey, QVLCStackedWidget
 #include "util/qt_dirs.hpp"                     // toNativeSeparators
+#include "util/imagehelper.hpp"
 
 #include "components/interface_widgets.hpp"     // bgWidget, videoWidget
 #include "components/controller.hpp"            // controllers
@@ -354,7 +355,7 @@ void MainInterface::createResumePanel( QWidget *w )
     resumePanelLayout->setSpacing( 0 ); resumePanelLayout->setMargin( 0 );
 
     QLabel *continuePixmapLabel = new QLabel();
-    continuePixmapLabel->setPixmap( QPixmap( ":/menu/help" ) );
+    continuePixmapLabel->setPixmap( ImageHelper::loadSvgToPixmap( ":/menu/help" , fontMetrics().height(), fontMetrics().height()) );
     continuePixmapLabel->setContentsMargins( 5, 0, 5, 0 );
 
     QLabel *continueLabel = new QLabel( qtr( "Do you want to restart the playback where left off?") );
diff --git a/modules/gui/qt/util/imagehelper.cpp b/modules/gui/qt/util/imagehelper.cpp
new file mode 100644
index 0000000000..30ee346323
--- /dev/null
+++ b/modules/gui/qt/util/imagehelper.cpp
@@ -0,0 +1,47 @@
+/*****************************************************************************
+ * input_slider.cpp : VolumeSlider and SeekSlider
+ ****************************************************************************
+ * Copyright (C) 2006-2017 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Pierre Lamot <pierre at videolabs.io>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#include <QApplication>
+#include <QPainter>
+#include <QScreen>
+#include <QSvgRenderer>
+#include "imagehelper.hpp"
+
+QPixmap ImageHelper::loadSvgToPixmap( const QString &path, qint32 i_width, qint32 i_height )
+{
+    qreal ratio = QApplication::primaryScreen()->devicePixelRatio();
+
+    QPixmap pixmap( QSize( i_width, i_height ) * ratio );
+
+    pixmap.fill( Qt::transparent );
+
+    QSvgRenderer renderer( path );
+    QPainter painter;
+
+    painter.begin( &pixmap );
+    renderer.render( &painter );
+    painter.end();
+
+    pixmap.setDevicePixelRatio( ratio );
+    return pixmap;
+}
diff --git a/modules/gui/qt/util/imagehelper.hpp b/modules/gui/qt/util/imagehelper.hpp
new file mode 100644
index 0000000000..e13aa02200
--- /dev/null
+++ b/modules/gui/qt/util/imagehelper.hpp
@@ -0,0 +1,37 @@
+/*****************************************************************************
+ * input_slider.cpp : VolumeSlider and SeekSlider
+ ****************************************************************************
+ * Copyright (C) 2006-2017 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Pierre Lamot <pierre at videolabs.io>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef IMAGEHELPER_HPP
+#define IMAGEHELPER_HPP
+
+#include <QString>
+#include <QPixmap>
+
+class ImageHelper
+{
+public:
+    /* render a Svg to a pixmap with current device pixel ratio */
+    static QPixmap loadSvgToPixmap(const QString& path, qint32 i_width, qint32 i_height);
+};
+
+#endif // IMAGEHELPER_HPP
-- 
2.14.1



More information about the vlc-devel mailing list