Open Bug 1742583 Opened 4 years ago Updated 4 years ago

Firefox draws antialiased fringes of content from outside the viewBox, when <svg> has fractional pixel value for 'width' and height'

Categories

(Core :: SVG, defect)

defect

Tracking

()

People

(Reporter: leveophan667, Unassigned)

Details

Attachments

(6 files)

Attached image 1.svg

Steps to reproduce:

Opened attached SVG with firefox

Actual results:

SVG rendered incorrectly. A black thin line is appearing on the right side when viewed with firefox which should not be there as the clipping completely covers the whole surface of svg.

Expected results:

View the svg without black thin line on the left side.

(In reply to leveophan667 from comment #0)

View the svg without black thin line on the left side.

I meant right side.

Can't edit the comment for some reason.

OS: Unspecified → All
Hardware: Unspecified → All

The Bugbug bot thinks this bug should belong to the 'Core::SVG' component, and is moving the bug to that component. Please revert this change in case you think the bot is wrong.

Component: Untriaged → SVG
Product: Firefox → Core

I don't see a black line but I imagine it's antialiasing. You can turn that off via shape-rendering.

(In reply to Robert Longson [:longsonr] from comment #3)

I don't see a black line but I imagine it's antialiasing. You can turn that off via shape-rendering.

View it on a white background and zoom it in or out (example in line.PNG). The line appears on different zoom levels depending on screen size and resolution.
I don't think it has anything to do with antialiasing as the line is basically the background color which becomes visible depending on zoom level. No smoothening happens here

The severity field is not set for this bug.
:dholbert, could you have a look please?

For more information, please visit auto_nag documentation.

Flags: needinfo?(dholbert)

I can see the black line. I can see it on Chrome as well if I increase the viewBox slightly. So, browsers agree that a little bit of color may bleed outside of the clipping area; the difference here seems to be on a second level of clipping which is happening at the viewBox level.

I don't think it has anything to do with antialiasing as the line is basically the background color which becomes visible depending on zoom level. No smoothening happens here

It is antialiasing, in the sense of handling what to do when the edge of shape edge doesn't precisely map to a display-pixel boundary.

The "595" right-coordinate presumably ends up landing just a little bit past a pixel boundary in your display (and mine as well), so the black rect gets a little bit of antialiased partially-black "fringe" at its extreme right edge. The foreground 595px-clipped-shape also has its extreme right edge at the same spot, but we can't draw a clipped partial pixel, so it ends up ever-so-slightly smaller.

As Robert noted (and I confirmed locally), you can avoid this by e.g. setting shape-rendering: crispEdges on the black rect in your example.

Flags: needinfo?(dholbert)

(In reply to Daniel Holbert [:dholbert] from comment #6)

I can see the black line. I can see it on Chrome as well if I increase the viewBox slightly.

Here's a testcase with a slightly-larger viewBox to demonstrate this (i.e. to demonstrate that browsers agree that the black shape might paint slightly larger than the foreground clipped shape, depending on scale, due to antialiasing differences between clipped and non-clipped shapes).

(In reply to Daniel Holbert [:dholbert] from comment #6)

As Robert noted (and I confirmed locally), you can avoid this by e.g. setting shape-rendering: crispEdges on the black rect in your example.

Hmm -- actually, I had confirmed this on a simplified local version of the testcase, but it doesn't actually fix things on the original testcase; it actually makes the line darker for me. :)

I'm guessing that's because crispEdges makes us round up in this case (but we don't round up the edge of the clipped element). So I'm not sure what the best workaround is here; it might be that there's not a great way to mock up a clipped shape to fully-mask a non-clipped shape, due to differences in pixel rounding for clipping vs. potentially-antialiased-or-rounded-out painted borders...

Here's an example that gets to the root of the difference between us and Chrome in the original example here. Note that you have to ctrl-click it on Bugzilla to view it in a new-tab -- bugzilla's modal-popup display of the image doesn't easily show the issue.

This testcase has an SVG element with...

     width="100pt" height="100pt"
     viewBox="0 0 100 100"

...and Chrome seems to strictly clip such that no fringe outside of 100px is visible, whereas Firefox may have a little bit of fringe (it draws a faint red outline on my machine, where I have 200% pixel scaling [i.e. high-DPI]] configured in my Ubuntu display settings).

Note the pt units here, which is kind-of special; 100pt works out to 133.333px on my machine (in both Firefox and Chrome).

If you use 100px as the width and height, then Firefox agrees with Chrome and doesn't show any red. Similarly, in the original testcase, if you use px units instead of pt units for sizing the SVG element, then there's no "fringe" at all, and you get expected results.

(Maybe that's the best workaround to suggest here -- use an exact px-unit size for your <svg> element, rather than pt sizes, if possible?)

I'm adjusting the bug title to focus in on the piece where we do seem to differ from Chromium (the issue highlighted by testcase 3).

Summary: SVG is rendered wrong → Firefox draws content from outside the viewBox, when given fractional pixel value for 'width' and height'
Severity: -- → S3
Status: UNCONFIRMED → NEW
Ever confirmed: true
Summary: Firefox draws content from outside the viewBox, when given fractional pixel value for 'width' and height' → Firefox draws antialiased fringes of content from outside the viewBox, when given fractional pixel value for 'width' and height'
Version: Firefox 94 → Trunk
Summary: Firefox draws antialiased fringes of content from outside the viewBox, when given fractional pixel value for 'width' and height' → Firefox draws antialiased fringes of content from outside the viewBox, when <svg> has fractional pixel value for 'width' and height'

Here's a screenshot to show the issue with testcase 3 (taken on my ThinkPad, connected to a high-res Samsung 27" display, with 200% pixel scaling configured in Ubuntu display settings).

Note that the fringe goes away at some full-page zoom values. For me, it's present at full-page-zoom levels of 100% (default), 133%, 240% (as well as 80% and 67%).

Attachment #9254850 - Attachment description: testcase 3 (100pt width and height, with 100px viewBox entirely filled by white rect) → testcase 3 (100pt width and height, with 100px viewBox entirely filled by white rect, which covers a larger red rect)
Attachment #9254850 - Attachment description: testcase 3 (100pt width and height, with 100px viewBox entirely filled by white rect, which covers a larger red rect) → testcase 3 (100pt width and height, with 100px viewBox, entirely filled by white rect which covers a larger red rect)
Attached image svg_with_px.png

(In reply to Daniel Holbert [:dholbert] from comment #9)

If you use 100px as the width and height, then Firefox agrees with Chrome and doesn't show any red. Similarly, in the original testcase, if you use px units instead of pt units for sizing the SVG element, then there's no "fringe" at all, and you get expected results.

(Maybe that's the best workaround to suggest here -- use an exact px-unit size for your <svg> element, rather than pt sizes, if possible?)

Thanks for looking into this but changing pt units to px doesn't seem to improve anything. The line just becomes visible on other zoom levels.

Right, my point in suggesting that workaround was: using px units would reduce the number of users who might experience the fringe (i.e. only users with a particular set of fractional full-page zoom levels, and maybe fractional OS zoom levels like the Windows 10 125% zoom level perhaps)

But yeah, the underlying bug remains, which is that we seem to be doing our device-pixel-rounding a bit inconsistently here.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: