Open Bug 697692 Opened 14 years ago Updated 3 years ago

SVG rendering looks too soft

Categories

(Core :: SVG, defect)

7 Branch
x86
Windows Vista
defect

Tracking

()

UNCONFIRMED

People

(Reporter: david, Unassigned)

References

()

Details

Attachments

(4 files)

User Agent: Mozilla/5.0 (Windows NT 6.0; rv:7.0.1) Gecko/20100101 Firefox/7.0.1 Build ID: 20110928134238 Steps to reproduce: Developed a site using SVG Actual results: SVG rendering looks too soft on Firefox. Much softer than other browsers and very much softer than Inkscape Expected results: Should look crisp and sharp with suitable anti-aliasing rather than blurred.
Please provide an example using the Add an attachment link above. Or alternatively a link to the site.
Example site http://www.refresh2012.org/ I'll add screen shots comparing rendering.
This is the SVG banner image for http://www.refresh2012.org/. This looks very soft, softer than any other browser I've checked.
This is the SVG image as rendered in Inkscape (used to create the SVG banner). Note that this is only a screenshot and not the ultimate quality it can produce. This is how I would dearly wish it rendered in Firefox.
You seem to have a filter that is deliberately designed to blur the letters with id="filter3406" on the <g> that surrounds the letter paths. If you remove the filter you get the sharpness you want. I'm not sure I see a firefox bug here.
Component: General → SVG
Product: Firefox → Core
QA Contact: general → general
(In reply to Robert Longson from comment #6) > You seem to have a filter that is deliberately designed to blur the letters > with id="filter3406" on the <g> that surrounds the letter paths. If you > remove the filter you get the sharpness you want. I'm not sure I see a > firefox bug here. That's very interesting. hacking the SVG in firebug reveals that taking the filter off sharpens up the letters. But, there is a bug - it's not the letters that are blurred. The filter consists of: 1. a blur which is applied to the alpha of the source graphic (the letters) 2. colour matrix to make the results of (1) black 3. An offset 4. A merge, taking the results of (3) and rendering them beneath the source graphic (letters). It's a drop shadow. What is making the letters soft is step (4) which shouldn't be the case. That's the bug. The spatial sampling frequency of the filter should be at least 2x pixel frequency but it seems that it is less than this, resulting in a soft result.
The sampling frequency is specified by setting filterRes on the filter. The SVG specification simply says: "If not provided, the user agent will use reasonable values to produce a high-quality result on the output device" I'm not sure we're going to change our implementation to quadruple the memory we use by default. Setting filterRes="1600 222" to the filter element should do what you want.
Thanks for looking at this Robert. The problem with setting filterRes is that it goes against the whole usefulness of SVGs, which is that you can scale them without loss of quality. You effectively turn an element of the graphic into a bitmap of fixed resolution. Also, it's a work-around not supported by the graphics packages. I'm using XSLT to process SVGs to make them inline but it's going to be very complex to work out the correct resolution of an item to insert the parameters. Looking at the problem differently, the in this case merge is just doing a composite just like rendering any other objects on top of each other. Can it be treated in this way? Even if the memory used for filters has to be increased it would solve the problem that Firefox SVG rendering isn't good quality atm if you apply a drop-shadow or a glow effect.
(In reply to David White from comment #9) > Looking at the problem differently, the in this case merge is just doing a > composite just like rendering any other objects on top of each other. Can it > be treated in this way? That is how it's done. We render both the inputs to the same output surface.
(In reply to Robert Longson from comment #10) > (In reply to David White from comment #9) > > Looking at the problem differently, the in this case merge is just doing a > > composite just like rendering any other objects on top of each other. Can it > > be treated in this way? > > That is how it's done. We render both the inputs to the same output surface. I'm perplexed. If the lettering and the drop-shadow are rendered and composited the same as any other shapes in the stack, why does the lettering go soft?
Perhaps it's due to the scaling transforms you have on the <g> elements.
(In reply to Robert Longson from comment #12) > Perhaps it's due to the scaling transforms you have on the <g> elements. Just tried the following in Firebug to see the effect of transform vs. filter independently. 1) remove transform on group. 2) reload page 3) remove the drop-shadown filter on group 4) reload page The result was that removing the transform did nothing to alter the softness of the text. Removing the filter made the text sharp.
There are 2 <g> elements. Did you remove both transforms? I did and the drawing disappeared.
(In reply to Robert Longson from comment #14) > There are 2 <g> elements. Did you remove both transforms? I did and the > drawing disappeared. This is the slightly unfortunate way Inkscape does page resizing - it does a transform on the root group to move the items into the new page area. If you take the root transform off everything jumps off the page. However, can take out any scaling by setting the scaling parameters to identity (1). Note that the Y scaling parameter is still negative, I think this is because Inkscape uses cartesian coordinates (origin bottom left). With a bit of jigging around I managed to work out what the translation values should be to the image back in the right place Anyway, I tried following transforms on the root group an the text group using firebug: matrix(1, 0, 0, -1, -45, 800) on root group matrix(1, 0, 0, -1, 37, 776) on text group So, all scaling is set to identity and all translations to a whole number of pixels. The text still looked soft. I then removed the drop-shadow filter on the text and it became sharp. I think it's the filter that is causing the softness.
(In reply to David White from comment #15) Filters, patterns and masks work by drawing the graphic into a raster image, manipulating the image bytes and then drawing the resultant bitmap. Most other things e.g. gradients just get drawn directly to the screen. If the raster gets scaled somehow a bicubic interpolation is used to convert the image from one scale to another. We try to create the surface at the size it needs to be drawn to avoid that.
Does the interpolation kick in for whole pixel translations or sub-pixel translations as well? How about for scaling by -1? Can the merge be done by writing directly to screen if it is the last filter in a chain? I might have a look at creating the SVG without any transforms at all to test this but it'll have to be next week now. Could you consider treating this as a bug anyway? At the moment Firefox is worse than any other browser I've seen (Chrome, IE, Safari). I'd hate to work-around problems in Firefox! Screen shot to follow.
This is how Chrome manages to render the SVG banner on http://www.refresh2012.org/. The text is nice and sharp.
(In reply to David White from comment #17) > Could you consider treating this as a bug anyway? At the moment Firefox is > worse than any other browser I've seen (Chrome, IE, Safari). I'd hate to > work-around problems in Firefox! Screen shot to follow. It's not closed as wontfix so if anyone, including you wants to work on improving things then they are free to do so. Patches are always welcome.
(In reply to David White from comment #3) > Created attachment 569998 [details] > SVG image inlined into http://www.refresh2012.org/ FWIW, in this testcase the filter is scaled by 1.2276223.
And the filter itself does not have an integer size. Its width is 977.49609375000000 for instance. We have to create integer sized surfaces to write the filter data to so that also means there will be some scaling.
Actuall comment 12 is the main issue here, not the transforms but the fact that the filter is not quite integer sized. The filter width is "1.5" but that's in objectBoundingBox units so that's dependent on the size of the object being filtered.
Hi Robert. Thanks for spending time on this. I've a question about the way around the scaling is done. Why is the filter being scaled or translated by floating point amounts? I might have missed something about the filter width but anyway my thinking is like this (I hope this makes sense!): There are two ways of implementing filtering and transforms. The first is to render the object to be filtered, filter the result and then apply scaling and translations to the filtered output. This is the logical sequence but it makes the interpolation kick in. The second is to calculate the output area for the filtered object by applying all transforms to the object's coordinates. This gives a buffer size and a "buffer translation" value. And then modify all coordinates (including the filter parameters) by all transforms including the buffer translation. With these transformed values you can then render the object and filter it using intermediate buffers but these buffers will be pixel-aligned with the screen. What I mean is I think you can transform the parameters so that you don't have to interpolate intermediate buffers. What do you think?
Firefox implements the second method. The issue is that the filter surface we create internally must be an integer size but the drawing is not an integer size. We then scale the filter to make it a very slightly bigger - a fraction of a pixel bigger so it fits the drawing area.
Is this an implicit transformation step that also needs to be applied to the coordinates of filtered objects? I guess that the fraction-of-a-pixel scaling can be applied to the object-to-be-filtered's coordinates rather than post-filter. To be honest you could probably ignore this scaling effect and just not bother to do the scaling. At a fraction of a pixel size difference, the scaling parameter is probably close enough to unity to just ignore it. Or maybe that would have unforeseen consequences.
It might be significant if the filter area was say 9.5 pixels wide and you put it in a pattern so it was tiled.
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: