I tried using this sample SVG icon for my app.
The actual generated icon appeared as the circle/center (correctly), but only one of the triangles (the one pointing straight to the left).
Any idea why? The icon appears correctly in my browser and on Linux under the image viewer.
(I also have a second icon I made with SWG-Edit, which used “Infinity” for some point coordinates and generated errors in the console at build time)
Edit: Here’s another sun icon that doesn’t generate properly; you get the top-left quarter (which, IMO, still looks good), but it’s not the full icon.
The SVG parser is written in Haxe, it relies on the shape drawing of OpenFL native, which is not quite perfect. “Next” has more accurate shape drawing (I believe) but it’s not ready to handle SVG rendering just yet. This is something that should continually improve, its a bummer, but you can generate PNG images on your own, and include multiple icon nodes for them, and the tools will pick the most appropriate size to use when copying or resizing icons
Yes, this is my conclusion as well; even if you have an SVG, chances are good that you will want to dumb down the detail level for smaller images, by hand.
Cheers though. SVG seems to be quite a complex standard, going by the first icon.
@singmajesty I’m interested in looking at the code, but couldn’t find references to
parser in the
openfl repository. Can you point me in the direction of this code?
I also get an error about an unknown operation for
Translate with a float. I’m curious to see if I can track down what this is (I’m guessing the parser wants an integer).
Is it simply SVGExport.hx?
Yep, for the moment, the SVG parsing is not compiled as part of the same tool, but instead runs as it’s own little tool. The source code is “tools/SVGExport.hx”, then the HXML is “tools/svg.hxml”:
It relies upon the SVG library, which decomposes the SVG into Flash drawing instructions. There would be improvements to the SVG parsing, but there might also be an area where the rendering is not quite as accurate. You could use the SVG library on your own (similar to how it is used in the SVGExport file) to test in both the Flash and other targets in your test project, if it does not work in Flash, it surely means the parsing is wrong, otherwise perhaps the rendering could be improved or the translated drawing instructions could be done a little simpler, anyway, worth taking a look
So to confirm and restate what you’re saying:
- The SVG library is located here (GitHub)
- Create a simple OpenFL app that loads and displays SVG files.
- Run this app with the Flash target. If the graphics appear wrong, the SVG parsing needs to be fixed.
Is that right?
That’s where I would start, it would be easier to create a quick empty project, then to use that to load and display the SVG content, then to keep looping within the command-line tools. It should be a faster flow for playing/developing on it, and gives you more flexibility for comparing targets, yep
I don’t think I’ll be able to actually fix anything, but I should be able to isolate specific problems, for example:
translate(x, [y]) has an optional
y coordinate (defaults to zero). You get a warning about an unknown
translate operation if you omit it.
viewBox properties on the SVG tag (eg.
viewBox="0 0 747.49 744.62") ignores the size, and you end up with a (often truncated) default width and height of
Where can I accumulate known issues? Perhaps I should open a GitHub issue for this with a checklist? These are useful a) to fix later, and b) for people to be able to work around these problems by hand-editing the SVG
Yeah, the more specific you can be, and especially, a test project to reproduce, is really valuable. You can post on the https://github.com/openfl/svg/issues page, that would be great
I would like your feedback on something @singmajesty.
My philosophy on libraries is that they just work. Users shouldn’t need to think about it. From that, I would want SVG parsing to work with as many SVGs as possible – not just those that follow the “official” specs.
If you agree to that, I would look at generating SVGs with the most common editors (eg.
svg-edit, InkSpace, and
snap.svg), as well as some random samples from web.
Also, I was thinking that as this code-base changes more, it would be really good to be able to run an automated test-suite to make sure nothing breaks. It’s probably possible to write tests as a set of “here’s the SVG, here’s how the icon should render, did the actual icon render the same?”
What do you think? I don’t have much experience with
munit. I think this approach would make the code-base better and make it easier to maintain and use.
The SVG library is broken out separately so it can be improved separate from the tools.
Unit testing could be a good idea, take a look at the Lime or OpenFL tests (which use munit) if you want an idea of how this could happen.
I think there are two potential problems right now, with SVG graphics that don’t appear to render properly. First is how it is parsed, which would be the job of the SVG library. I think those kinds of improvements would be great!
The other problem might be how scaled objects work in OpenFL currently. If the SVG output uses
matrix to transform DisplayObjects with SVG content, it may alias. If you use
graphics.drawRect (0, 0, 100, 100); it would be sharp, but
graphics.drawRect (0, 0, 1, 1); and scaled 100x could be very blurry.
Okay. The first step is to add the unit testing piece, and populate it with a bunch of passing test-cases (so I can be sure I don’t break things further).
I’m currently in the early stages of a new (HaxeFlixel) game. When I get around to finding an icon, I’ll come back to this to add in the unit testing first, and hopefully I can sort out some or all of the issues with my SVG of choice.
Thanks for the feedback.
I’ve made good progress on this; in my fork of svg, I wrote a test which can:
- Scan the
images folder for
.svg files (with corresponding
- Do a comparison (hash) of a dummy string against the PNG file contents
- Generate a report showing successes and failures
All I’m missing is the actual “generate the PNG for this SVG” part.
Please take a look at a few lines of code starting here; I know how to load the .SVG file into an
SVG class instance, I just don’t know how to write it out as a PNG. Could you please tell me how to do this?
I took a look at the
SVG class, including how it internally handles data, and the
DislpayObject classes, but I’m not clear on how to get the data (in whatever format PNG uses).
Once this last item is done, I will have working test infrastructure with one passing test
This code on Stack Overflow seems to answer this question. I’ll try it.
Edit: I’m not sure how to make this work. I’m using
neko so I can read files off the file system. But, the SVG classes (
SVGData at least) both import
flash.foo classes. I can’t access those in Neko.
I must be doing something wrong; HaxeFlixel uses OpenFL to generate app icons (for Android et all) without running a Flash instance (as far as I can tell), and this simple SVG viewer project runs in
How do I make this work?
Have you looked at https://github.com/openfl/lime/blob/develop/tools/SVGExport.hx?
cd tools && haxe svg.hxml compiles the
svg.n tool within Lime, used when generating icons. You can
lime update windows -clean on a project to generate a new icon using this tool
It’s just one example of a Neko-based command-line tool, which uses SVG and OpenFL
Thanks, that’s an easier method than the one I’m using.
The exact code provided works fine in the context of a project generated with
openfl (I used
openfl create DisplayABitmap). But, it doesn’t work when I run the tests.
Right now, I see two possibilities:
- I need to tell
munit to invoke the test with some additional command-line arguments of some sort. Or,
- We need to make the test run in the context of an OpenFL application/process.
I don’t know enough about OpenFL to figure this out. @singmajesty can you please take a quick review of my code and see what you think (you may have already done this)?
MUnit uses the contents of
test.mxml to specify command-line arguments.
The exact compiler exceptions I see right now are below. This includes some
munit output (which includes the entire command-line including arguments).
I’m also building with
svg as from haxelib, but the source code line references are pointing to my local
Massive Unit - Copyright 2016 Massive Interactive. Version 2.1.2
haxe -main TestMain -lib munit -lib hamcrest -lib svg -lib openfl -cp src -cp test -neko build/neko_test.n
HaxeWrapper.hx:73: src/format/SVG.hx:4: characters 7-29 : You cannot access the flash package while targeting neko (for flash.display.Graphics)
Take a look at svg.hxml from Lime, it’s got some things in to allow use of OpenFL classes on the command-line
--remap flash:openfl seemed to resolve those errors.
Here’s how my
test.hxml looks now (not checked in yet):
The error I get is
characters 7-32 : Type not found : lime.graphics.cairo.Cairo.
I updated to the latest Lime/OpenFL versions, and it persists. It’s strange, because I can see the
-D lime_cairo parameter on the command-line:
Massive Unit - Copyright 2016 Massive Interactive. Version 2.1.2
haxe -main TestMain -lib munit -lib hamcrest -lib svg -lib openfl -cp src -cp test -D lime -D lime_cairo --remap flash:openfl -neko build/neko_test.n
It’s also strange because
Cairo.hx isn’t wrapped in an
#if (lime_cairo) call or anything like that.
Can you suggest how I can resolve this?
You need to add
-lib lime manually.