Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't auto-split SVG floats before a -. #21123

Closed
wants to merge 1 commit into from
Closed

Conversation

xavidotron
Copy link

This is necessary to support numbers like 1e-6 with a - in the middle,
which happens in SVG produced by Inkscape.

Description

When SVGLoader loads an SVG file with a number like 1e-6 in a path, it parses that path incorrectly resulting in broken behavior. Because standard SVG-editing tools like Inkscape produce SVGs that contain numbers of this form, it can be easy to inadvertently produce SVGs that have this issue.

The attached broken.svg.zip contains a file that is handled correctly after this change and not before it.

@Mugen87
Copy link
Collaborator

Mugen87 commented Jan 21, 2021

Please change the examples/js version and generate the jsm version via node utils/modularize.js.

@yomboprime
Copy link
Collaborator

Related (same topic): #17306

This is necessary to support numbers like 1e-6 with a - in the middle,
which happens in SVG produced by Inkscape.
@xavidotron
Copy link
Author

Please change the examples/js version and generate the jsm version via node utils/modularize.js.

Done, thanks for the pointer.

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 1, 2021

This PR breaks the Zero Radius test file in webgl_loader_svg. Definitions like the following can't be processed anymore: "7,7,0,0,1-7-7".

1-7-7 becomes now 1-7-7 instead of 1, -7, -7.

@yomboprime
Copy link
Collaborator

yomboprime commented Feb 1, 2021

I've come to a regexp that passes all tests. Keep in mind that I'm no expert, I'd like it to be verified:
/[\s,]+|(?=\s?[(^e+)(^e\-)])/
This one divides on + or - only when there is not an e just before them (that is what the ^ does)

For comparison, here is the previous regexp used in the repo:
/[\s,]+|(?=\s?[+\-])/

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 1, 2021

Alternatively to a different regex, I've implement parseFloats() base on this project: https://github.com/ppvg/svg-numbers

Here is the commit: Mugen87@a2b9ed8

svg-numbers seems to implement the number parsing in a very robust way.

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 1, 2021

One thing that confuses me: The loader currently uses parseFloatWithUnits() in parseFloats().

It seems svg-numbers does not honor units. Is that a problem?

@yomboprime
Copy link
Collaborator

yomboprime commented Feb 1, 2021

One thing that confuses me: The loader currently uses parseFloatWithUnits() in parseFloats().

It seems svg-numbers does not honor units. Is that a problem?

I think you should implement parseFloat, which is used in parseFloatsWithUnit.

It is difficult to integrate units as it is right now...

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 1, 2021

svg-numbers is not intended to replace the JavaScript built-in parseFloat() function. The lib retrieves a string like "7,7,0,0,1-7-7" and outputs the split up numbers in an array.

@yomboprime
Copy link
Collaborator

Yes, I see. But the unit is just a string at the end, I think it should be not much work to add a new state to the parser.

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 1, 2021

@ppvg Is it possible that a list of coordinates in SVG documents such as the points attribute of a <polyline> element can have a unit? If so, is this handled in some way by svg-numbers?

@ppvg
Copy link

ppvg commented Feb 1, 2021

@Mugen87: oof, I wrote that 7 years ago. I'll have to refresh my memory. 😅
I'll try to find some time later this week.

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 2, 2021

@yomboprime Do you mind sharing a SVG file in this thread which can be used to evaluate the units issue?

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 2, 2021

According to my today's research SVG transform as well as shape definitions (like path, polygon or polyline) do not support units. Hence, it should be safe to not use parseFloatWithUnits() in parseFloats().

However, it would be good if this could be double-checked 😅 .

@yomboprime
Copy link
Collaborator

@yomboprime Do you mind sharing a SVG file in this thread which can be used to evaluate the units issue?

The test "Units" loads the file models/svg/tests/units.svg. It has three rectangles, with the same width expressed in different units. So at least the width of a rectangle can have units.

@yomboprime
Copy link
Collaborator

According to my today's research SVG transform as well as shape definitions (like path, polygon or polyline) do not support units. Hence, it should be safe to not use parseFloatWithUnits() in parseFloats().

However, it would be good if this could be double-checked sweat_smile .

I've made some reading of 1.1 and 2.0 SVG specs and it seems to be true.

@Mugen87
Copy link
Collaborator

Mugen87 commented Feb 3, 2021

Okay, let's give this PR a try. In this way, the more time we have to validate the change on dev.

@yomboprime
Copy link
Collaborator

Just as a final note, the OP's SVG test file broken.svg still renders incorrectly due to the other issues related to holes windings. If I delete the hole in the shape in Inkscape, it shows correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants