Bug 75781 - Rounding artifact in SVGTextNode.getBBox()
Summary: Rounding artifact in SVGTextNode.getBBox()
Status: NEW
Alias: None
Product: WebKit
Classification: Unclassified
Component: SVG (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Major
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2012-01-07 12:41 PST by Gene Selkov
Modified: 2022-06-09 10:15 PDT (History)
13 users (show)

See Also:


Attachments
A test for SVGTextNode.getBBox() (1.27 KB, application/xhtml+xml)
2012-01-07 12:43 PST, Gene Selkov
no flags Details
Safari 15.5 matches other browsers (464.99 KB, image/png)
2022-06-08 15:30 PDT, Ahmad Saleem
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Gene Selkov 2012-01-07 12:41:13 PST
When the user space is transformed to small units, for example, when the entire world is smaller than [0 .. 1], the getBBox() method becomes unusable because it returns integer values (please see the attached test). It is also unusable with larger spaces, say, [0 .. 100], but the effect is less conspicuous.

It works correctly in Mozilla.

The test only demonstrates the effect on a bounding box for a text node, but I suspect the problem is more widespread in Webkit.

The rounding is also apparent in hit-testing. For example, when a set of nodes form a grid spaced 0.5 world units apart, the pointer events fire on all nodes, but only those nodes located at integer grid values are reported as targets of those events. That only happens when the co-ordinates are transformed using the viewBox attribute on the svg root node and does not happen when the transformation is defined as an attribute on a group, but I suspect the culprit is the same or similar. Apparently, parts of the code were only tested in pixel-minded applications.

I can provide a separate test for the viewBox artefact, if that will help.
Comment 1 Gene Selkov 2012-01-07 12:43:24 PST
Created attachment 121558 [details]
A test for SVGTextNode.getBBox()
Comment 2 Radar WebKit Bug Importer 2012-01-09 15:54:29 PST
<rdar://problem/10665932>
Comment 3 Philip Rogers 2012-01-10 08:48:39 PST
I looked into this and it looks like we punt directly through to Skia in this case. The following bug was filed on the Skia side: http://code.google.com/p/skia/issues/detail?id=440

Once that is closed this will most likely be a trivial fix.
Comment 4 Dominik Röttsches (drott) 2012-06-18 09:12:06 PDT
This seems to be the root cause of bug 88772. SVGRootInlineBox::layoutRootBox() rounds to integers. We need higher precision there.
Comment 5 Nikolas Zimmermann 2012-06-18 12:44:27 PDT
(In reply to comment #4)
> This seems to be the root cause of bug 88772. SVGRootInlineBox::layoutRootBox() rounds to integers. We need higher precision there.
This is finally possible by enabling SUBPIXEL_LAYOUT by default for all ports, once that happens, we can finally use non-integer precision in all parts of SVG that interfere with HTML, where currently rounding is needed.
It's on my list :-)
Comment 6 Gene Selkov 2012-06-18 13:14:06 PDT
Please forgive me if I get it all wrong: how can the rounding of user co-ordinates be needed for anything? They have nothing to do with pixels and rendering. They are exactly one transformation away from pixels and sub-pixels, and it is the transformed co-ordinates that I see rounded.
Comment 7 Dominik Röttsches (drott) 2012-06-19 00:28:52 PDT
(In reply to comment #5)
> (In reply to comment #4)
> > This seems to be the root cause of bug 88772. SVGRootInlineBox::layoutRootBox() rounds to integers. We need higher precision there.
> This is finally possible by enabling SUBPIXEL_LAYOUT by default for all ports, once that happens, we can finally use non-integer precision in all parts of SVG that interfere with HTML, where currently rounding is needed.
> It's on my list :-)

If I understood the code correctly even with SUBPIXEL_LAYOUT we'll only get precision to a point of 1/60th fractional increments. For large upscaling from viewbox to viewport we'll still see inaccuracies, right?
Comment 8 Dominik Röttsches (drott) 2012-06-19 00:32:11 PDT
(In reply to comment #6)
> Please forgive me if I get it all wrong: how can the rounding of user co-ordinates be needed for anything? They have nothing to do with pixels and rendering. They are exactly one transformation away from pixels and sub-pixels, and it is the transformed co-ordinates that I see rounded.

As far as my understanding of the code goes: The rounding happens because SVG and HTML text rendering share common code - HTML layout in WebKit traditionally had only integer precision (which is overcome by the SUBPIXEL_LAYOUT changes). So SVG had to map its representations to the integer space of HTML. This happens before the transformation and results in incorrect values after the upscaling.
Comment 9 Gene Selkov 2012-06-19 02:53:58 PDT
I still can't say I see the problem I reported as a layout problem. The thing is, all nodes defined in user co-ordinates are laid out correctly (as far as I can tell). The problem is in going back from the display co-ordinates to user space, which is what getBBox() is supposed to do. It does that approximately correctly when the user space spans many enough whole units that the effects of rounding can be ignored.

Now, imagine a user space defined as [0, 0, 1, 1]. Let's say it is laid out on a display rectangle with these co-ordinates: [50, 50, 250, 250]. I understand you as saying that because of rounding in the display co-ordinates, my user co-ordinates can only be precise to 0.005. I could live with that, but that's not what I see. What I see is the co-ordinates of the bounding box rounded to 0 or 1. I either get a zero-size box or one that spans my entire space.
Comment 10 Dominik Röttsches (drott) 2012-06-19 03:45:08 PDT
(In reply to comment #9)
As I mentioned, it's a problem with bounding box calculation rather than the actual transformations at draw time. At layout time the bounding box is calculated accurately in floats, but then is simplified down to integers. Cmp. SVGRootInlineBox::layoutRootBox() - don't get mislead by the keyword layout in it. It's just that bounding boxes for text objects are calculated during layout phase.

> Now, imagine a user space defined as [0, 0, 1, 1]. Let's say it is laid out on a display rectangle with these co-ordinates: [50, 50, 250, 250]. I understand you as saying that because of rounding in the display co-ordinates, my user co-ordinates can only be precise to 0.005. I could live with that, but that's not what I see. What I see is the co-ordinates of the bounding box rounded to 0 or 1. I either get a zero-size box or one that spans my entire space.

Yep, that's more or less exactly the test case in bug 88772.
Comment 11 Dominik Röttsches (drott) 2013-01-25 02:27:26 PST
Duplicate of bug 107771?
Comment 12 Dominik Röttsches (drott) 2013-01-25 02:28:32 PST
Gene, can you retest after r140728, on a port that has subpixel-layout enabled?
Comment 13 Ahmad Saleem 2022-06-08 15:30:51 PDT
Created attachment 460105 [details]
Safari 15.5 matches other browsers

I am not able to reproduce the bug based on attached test case in Safari 15.5 on macOS 12.4. Please refer to attached screenshot for reference. Thanks!
Comment 14 Alexey Proskuryakov 2022-06-09 10:07:40 PDT
This test doesn't work from an attachment any more. It embeds YUI over plain http, and loading that from https is blocked. One needs to download it, and open as a file.

With that, the test still fails:

Expected width = 1.43 and height = 0.09. Returned by getBBox(): width = 1.296875, height = 0.09375

I do not know if that's a bug or expected behavior at this point.
Comment 15 Ahmad Saleem 2022-06-09 10:15:12 PDT
I tried to use YUI 3.5 library from JSFiddle and built this test case - https://jsfiddle.net/rcge4q5f/1/

I can see your expected width issue as well. Thanks!