Add support for configurable transparent background to SVGs
Closed, ResolvedPublic

Description

@huoni BTW, setAlphaBackgroundColor and setAlphaBackgroundMode are also broken for SVGs, but not sure how easy that is to fix.

Could we implement RasterImageView::drawAlphaBackground in SvgImageView?

Maybe, but it's probably more work than copy-and-paste. That's because for SVGs most of the work is done by QSvgRenderer, while drawAlphaBackground operates on QPainter level.

I figured there'd be something different about SVGs. I probably don't understand it properly, but could we just use a QPainter to draw the background behind the image? Currently the viewport background is visible through the transparent parts of an SVG, therefore it seems reasonable to me that it would be possible to draw another rectangle above the viewport but below the image.

Sounds good, this might work reading the following:

Using QSvgRenderer, Scalable Vector Graphics (SVG) can be rendered onto any QPaintDevice subclass, including QWidget, QImage, and QGLWidget.

drawAlphaBackground works on mCurrentBuffer, but there's nothing like that for SVGs. I guess this needs further investigation how QGraphicsWidget is used there.

huoni added a comment.Mar 23 2018, 4:17 AM

I managed to draw a QPixmap behind an SVG by implementing paint() in SvgImageView, which overrides QGraphicWidget::paint. This is how RasterImageView draws mCurrentBuffer (which contains the background as well as the image itself).

Therefore this is definitely possible. I'll keepworking on it!

huoni added a comment.EditedMar 23 2018, 8:34 AM

EDIT: I didn't see the need for waiting before submitting patches. Can continue discussion in D11629 and the related D11630.

I have a working patch that implements this. I have a couple of discussion points before submitting a revision:

  1. document()->hasAlphaChannel() returns false for SVGs. Is it reasonable to assume all SGVs have an alpha channel and therefore always draw the background?
  2. Currently SVGs just display on the main image viewport. Implementing this removes that 'option'. I propose a third option for "Transparent background" config: None. I can foresee implementing this simply by using AlphaBackgroundMode::SolidColor set to the current global background color.
rkflx added a comment.Mar 24 2018, 9:23 AM

Sorry I'm not always able to answer immediately… I'll look at your patches in a bit, thanks for working on this topic!

I didn't see the need for waiting before submitting patches.

Yup, if you have something to show, just make it available with "[WIP]" in the title or use arc paste. This way sometimes it's easier to comment.

Now for your discussion points:

In T8125#134033, @huoni wrote:
  1. document()->hasAlphaChannel() returns false for SVGs. Is it reasonable to assume all SGVs have an alpha channel and therefore always draw the background?

I guess for the most accurate answer you'd have to read the SVG spec. Leaving that aside, I guess even assigning the concept of a "channel" to SVGs has its problems: SVGs can contain raster images, which itself might have an alpha channel.

For our purpose I'd simply handle all SVGs as transparent, given how prevalent the concept of "opacity" is throughout the file format.

  1. Currently SVGs just display on the main image viewport. Implementing this removes that 'option'. I propose a third option for "Transparent background" config: None. I can foresee implementing this simply by using AlphaBackgroundMode::SolidColor set to the current global background color.

Sorry for not warning you about the texture in time :D There goes your foresight…