Commit 836ec0e4 authored by Huon Imberger's avatar Huon Imberger
Browse files

Add support for configurable transparent background to SVGs

Summary:
SVGs do not honor the "Transparent background" config option, and simply have no
background at all. This patch ensures this option is applied to SVGs as well as
raster images.

Unlike `RasterImageView` that uses a `QPixmap` buffer (`mCurrentBuffer`) for drawing
the background and the image, SVGs are rendered directly on top of `SvgImageView`
(`QGraphicsWidget`). Therefore we just paint the background in `SvgImageView::paint`
which happens before the SVG is rendered.

We move the checkboard texture code to `AbstractImageView` now that it's used by
both subclasses `RasterImageView` and `SvgImageView`.

This patch also configures kconf_update due to the moving of the above enum.
Since I didn't want to litter `/app` with files, I've moved the update files to
`/kconf_update`.

Fixes T8125

Before:
{F5764298}

After:
{F5764299}
{F5764300}

Test Plan:
  - Open an SVG with solid color config option
  - Open and SVG with checkboard background config. At a high enough zoom (where the
    birdseye view shows up), panning/scrolling should have the checkboard pattern
    fixed to the image, like raster images
  - Ensure raster images with transparent backgrounds are unaffected

## kconf_update
The script `gwenview-imageview-alphabackgroundmode-update.pl` must be in
`/usr/share/kconf_update` in order for `/usr/lib/kf5/kconf_update` to find it.
If successfull, instances of `RasterImageView::AlphaBackground*` should change to
`AbstractImageView::AlphaBackground*`.

Reviewers: #gwenview, rkflx, ngraham

Reviewed By: #gwenview, rkflx, ngraham

Tags: #gwenview

Maniphest Tasks: T8125

Differential Revision: https://phabricator.kde.org/D11629
parent d0d97b8e
......@@ -154,5 +154,6 @@ add_subdirectory(images)
add_subdirectory(cursors)
add_subdirectory(color-schemes)
add_subdirectory(doc)
add_subdirectory(kconf_update)
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
......@@ -114,5 +114,3 @@ install(FILES org.kde.gwenview.appdata.xml
DESTINATION ${KDE_INSTALL_METAINFODIR})
install(FILES slideshow.desktop
DESTINATION ${KDE_INSTALL_KSERVICES5DIR}/ServiceMenus)
install(FILES gwenview.upd
DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR})
......@@ -68,8 +68,8 @@ ConfigDialog::ConfigDialog(QWidget* parent)
mAlphaBackgroundModeGroup = new InvisibleButtonGroup(widget);
mAlphaBackgroundModeGroup->setObjectName(QLatin1String("kcfg_AlphaBackgroundMode"));
mAlphaBackgroundModeGroup->addButton(mImageViewConfigPage.checkBoardRadioButton, int(RasterImageView::AlphaBackgroundCheckBoard));
mAlphaBackgroundModeGroup->addButton(mImageViewConfigPage.solidColorRadioButton, int(RasterImageView::AlphaBackgroundSolid));
mAlphaBackgroundModeGroup->addButton(mImageViewConfigPage.checkBoardRadioButton, int(AbstractImageView::AlphaBackgroundCheckBoard));
mAlphaBackgroundModeGroup->addButton(mImageViewConfigPage.solidColorRadioButton, int(AbstractImageView::AlphaBackgroundSolid));
mWheelBehaviorGroup = new InvisibleButtonGroup(widget);
mWheelBehaviorGroup->setObjectName(QLatin1String("kcfg_MouseWheelBehavior"));
......
install(FILES gwenview.upd
DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR})
install(PROGRAMS gwenview-imageview-alphabackgroundmode-update.pl
DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR})
#!/usr/bin/env perl
use strict;
while (<STDIN>) {
s/RasterImageView::AlphaBackgroundSolid/AbstractImageView::AlphaBackgroundSolid/;
print $_;
}
Version=5
Id=SideBar_StatusBar_Rename
File=gwenviewrc
......@@ -18,3 +20,10 @@ Group=General,StatusBar
Key=StatusBarIsVisible,IsVisible BrowseMode
Key=StatusBarIsVisible,IsVisible ViewMode
RemoveKey=StatusBarIsVisible
Id=ImageView_AlphaBackgroundMode_Update
File=gwenviewrc
Options=overwrite
Group=ImageView
Script=gwenview-imageview-alphabackgroundmode-update.pl,perl
......@@ -30,6 +30,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA
#include <QCursor>
#include <QGraphicsSceneMouseEvent>
#include <QStandardPaths>
#include <QPainter>
namespace Gwenview
{
......@@ -56,6 +57,8 @@ struct AbstractImageViewPrivate
QPointF mScrollPos;
QPointF mLastDragPos;
const QPixmap mAlphaBackgroundTexture = createAlphaBackgroundTexture();
void adjustImageOffset(Verbosity verbosity = Notify)
{
QSizeF zoomedDocSize = q->documentSize() * mZoom;
......@@ -109,6 +112,17 @@ struct AbstractImageViewPrivate
QPixmap cursorPixmap = QPixmap(path);
mZoomCursor = QCursor(cursorPixmap, 11, 11);
}
QPixmap createAlphaBackgroundTexture()
{
QPixmap pix = QPixmap(32, 32);
QPainter painter(&pix);
painter.fillRect(pix.rect(), QColor(128, 128, 128));
const QColor light = QColor(192, 192, 192);
painter.fillRect(0, 0, 16, 16, light);
painter.fillRect(16, 16, 16, 16, light);
return pix;
}
};
AbstractImageView::AbstractImageView(QGraphicsItem* parent)
......@@ -258,6 +272,11 @@ void AbstractImageView::setZoomToFill(bool on)
zoomToFillChanged(d->mZoomToFill);
}
const QPixmap& AbstractImageView::alphaBackgroundTexture() const
{
return d->mAlphaBackgroundTexture;
}
void AbstractImageView::resizeEvent(QGraphicsSceneResizeEvent* event)
{
QGraphicsWidget::resizeEvent(event);
......
......@@ -44,6 +44,11 @@ public:
UpdateIfNecessary,
ForceUpdate
};
enum AlphaBackgroundMode {
AlphaBackgroundCheckBoard,
AlphaBackgroundSolid
};
AbstractImageView(QGraphicsItem* parent);
~AbstractImageView();
......@@ -115,6 +120,10 @@ Q_SIGNALS:
void toggleFullScreenRequested();
protected:
virtual void setAlphaBackgroundMode(AlphaBackgroundMode mode) = 0;
virtual void setAlphaBackgroundColor(const QColor& color) = 0;
const QPixmap& alphaBackgroundTexture() const;
virtual void loadFromDocument() = 0;
virtual void onZoomChanged() = 0;
/**
......
......@@ -44,11 +44,10 @@ struct RasterImageViewPrivate
{
RasterImageView* q;
ImageScaler* mScaler;
QPixmap mBackgroundTexture;
bool mEmittedCompleted;
// Config
RasterImageView::AlphaBackgroundMode mAlphaBackgroundMode;
AbstractImageView::AlphaBackgroundMode mAlphaBackgroundMode;
QColor mAlphaBackgroundColor;
cmsUInt32Number mRenderingIntent;
bool mEnlargeSmallerImages;
......@@ -111,16 +110,6 @@ struct RasterImageViewPrivate
mApplyDisplayTransform = true;
}
void createBackgroundTexture()
{
mBackgroundTexture = QPixmap(32, 32);
QPainter painter(&mBackgroundTexture);
painter.fillRect(mBackgroundTexture.rect(), QColor(128, 128, 128));
QColor light = QColor(192, 192, 192);
painter.fillRect(0, 0, 16, 16, light);
painter.fillRect(16, 16, 16, 16, light);
}
void setupUpdateTimer()
{
mUpdateTimer = new QTimer(q);
......@@ -173,16 +162,16 @@ struct RasterImageViewPrivate
mAlternateBuffer = QPixmap();
}
void drawAlphaBackground(QPainter* painter, const QRect& viewportRect, const QPoint& zoomedImageTopLeft)
void drawAlphaBackground(QPainter* painter, const QRect& viewportRect, const QPoint& zoomedImageTopLeft, QPixmap texture)
{
if (mAlphaBackgroundMode == RasterImageView::AlphaBackgroundCheckBoard) {
if (mAlphaBackgroundMode == AbstractImageView::AlphaBackgroundCheckBoard) {
QPoint textureOffset(
zoomedImageTopLeft.x() % mBackgroundTexture.width(),
zoomedImageTopLeft.y() % mBackgroundTexture.height()
zoomedImageTopLeft.x() % texture.width(),
zoomedImageTopLeft.y() % texture.height()
);
painter->drawTiledPixmap(
viewportRect,
mBackgroundTexture,
texture,
textureOffset);
} else {
painter->fillRect(viewportRect, mAlphaBackgroundColor);
......@@ -208,7 +197,6 @@ RasterImageView::RasterImageView(QGraphicsItem* parent)
d->mScaler = new ImageScaler(this);
connect(d->mScaler, &ImageScaler::scaledRect, this, &RasterImageView::updateFromScaler);
d->createBackgroundTexture();
d->setupUpdateTimer();
}
......@@ -347,7 +335,8 @@ void RasterImageView::updateFromScaler(int zoomedImageLeft, int zoomedImageTop,
if (document()->hasAlphaChannel()) {
d->drawAlphaBackground(
&painter, QRect(viewportLeft, viewportTop, image.width(), image.height()),
QPoint(zoomedImageLeft, zoomedImageTop)
QPoint(zoomedImageLeft, zoomedImageTop),
alphaBackgroundTexture()
);
} else {
painter.setCompositionMode(QPainter::CompositionMode_Source);
......
......@@ -41,11 +41,6 @@ class GWENVIEWLIB_EXPORT RasterImageView : public AbstractImageView
{
Q_OBJECT
public:
enum AlphaBackgroundMode {
AlphaBackgroundCheckBoard,
AlphaBackgroundSolid
};
RasterImageView(QGraphicsItem* parent = 0);
~RasterImageView();
......@@ -54,8 +49,8 @@ public:
void setCurrentTool(AbstractRasterImageViewTool* tool);
AbstractRasterImageViewTool* currentTool() const;
void setAlphaBackgroundMode(AlphaBackgroundMode mode);
void setAlphaBackgroundColor(const QColor& color);
void setAlphaBackgroundMode(AlphaBackgroundMode mode) override;
void setAlphaBackgroundColor(const QColor& color) override;
void setRenderingIntent(const RenderingIntent::Enum& renderingIntent);
Q_SIGNALS:
......
......@@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA
#include <QGraphicsSvgItem>
#include <QGraphicsTextItem>
#include <QGraphicsWidget>
#include <QPainter>
#include <QSvgRenderer>
#include <QDebug>
......@@ -44,7 +45,12 @@ namespace Gwenview
SvgImageView::SvgImageView(QGraphicsItem* parent)
: AbstractImageView(parent)
, mSvgItem(new QGraphicsSvgItem(this))
, mAlphaBackgroundMode(AbstractImageView::AlphaBackgroundCheckBoard)
, mAlphaBackgroundColor(Qt::black)
, mImageFullyLoaded(false)
{
// So we aren't unnecessarily drawing the background for every paint()
setCacheMode(QGraphicsItem::DeviceCoordinateCache);
}
void SvgImageView::loadFromDocument()
......@@ -74,6 +80,7 @@ void SvgImageView::finishLoadFromDocument()
}
applyPendingScrollPos();
completed();
mImageFullyLoaded = true;
}
void SvgImageView::onZoomChanged()
......@@ -96,6 +103,42 @@ void SvgImageView::onScrollPosChanged(const QPointF& /* oldPos */)
void SvgImageView::adjustItemPos()
{
mSvgItem->setPos(imageOffset() - scrollPos());
update();
}
void SvgImageView::setAlphaBackgroundMode(AbstractImageView::AlphaBackgroundMode mode)
{
mAlphaBackgroundMode = mode;
update();
}
void SvgImageView::setAlphaBackgroundColor(const QColor& color)
{
mAlphaBackgroundColor = color;
update();
}
void SvgImageView::drawAlphaBackground(QPainter* painter)
{
const QRectF imageRect = QRectF(imageOffset(), visibleImageSize());
switch (mAlphaBackgroundMode) {
case AbstractImageView::AlphaBackgroundCheckBoard:
painter->drawTiledPixmap(imageRect, alphaBackgroundTexture(), scrollPos());
break;
case AbstractImageView::AlphaBackgroundSolid:
painter->fillRect(imageRect, mAlphaBackgroundColor);
break;
default:
Q_ASSERT(0);
}
}
void SvgImageView::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
{
if (mImageFullyLoaded) {
drawAlphaBackground(painter);
}
}
//// SvgViewAdapter ////
......@@ -148,6 +191,8 @@ Document::Ptr SvgViewAdapter::document() const
void SvgViewAdapter::loadConfig()
{
d->mView->setAlphaBackgroundMode(GwenviewConfig::alphaBackgroundMode());
d->mView->setAlphaBackgroundColor(GwenviewConfig::alphaBackgroundColor());
d->mView->setEnlargeSmallerImages(GwenviewConfig::enlargeSmallerImages());
}
......
......@@ -42,6 +42,8 @@ class SvgImageView : public AbstractImageView
Q_OBJECT
public:
SvgImageView(QGraphicsItem* parent = 0);
void setAlphaBackgroundMode(AlphaBackgroundMode mode) Q_DECL_OVERRIDE;
void setAlphaBackgroundColor(const QColor& color) Q_DECL_OVERRIDE;
protected:
void loadFromDocument() Q_DECL_OVERRIDE;
......@@ -54,7 +56,13 @@ private Q_SLOTS:
private:
QGraphicsSvgItem* mSvgItem;
AbstractImageView::AlphaBackgroundMode mAlphaBackgroundMode;
QColor mAlphaBackgroundColor;
bool mImageFullyLoaded;
void adjustItemPos();
void drawAlphaBackground(QPainter* painter);
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
};
struct SvgViewAdapterPrivate;
......
......@@ -118,11 +118,11 @@
<group name="ImageView">
<entry name="AlphaBackgroundMode" type="Enum">
<choices name="Gwenview::RasterImageView::AlphaBackgroundMode">
<choice name="RasterImageView::AlphaBackgroundCheckBoard"/>
<choice name="RasterImageView::AlphaBackgroundSolid"/>
<choices name="Gwenview::AbstractImageView::AlphaBackgroundMode">
<choice name="AbstractImageView::AlphaBackgroundCheckBoard"/>
<choice name="AbstractImageView::AlphaBackgroundSolid"/>
</choices>
<default>RasterImageView::AlphaBackgroundCheckBoard</default>
<default>AbstractImageView::AlphaBackgroundCheckBoard</default>
</entry>
<entry name="AlphaBackgroundColor" type="Color">
<default>#ffffff</default>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment