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

Support a vector drawable format (not SVG) #1831

Open
krisgiesing opened this Issue Feb 12, 2016 · 124 comments

Comments

Projects
None yet
@krisgiesing
Copy link
Contributor

krisgiesing commented Feb 12, 2016

From earlier discussion, some important considerations are:

  • We don't want full SVG support. There is too much in the spec that is expensive, heavyweight, and/or duplicates what we already have in Flutter.
  • We should emphasize in our supported format those operations are effective/efficient/optimized in our graphics engine (Skia).
  • We may want to process the format at build time rather than support a full run-time interpreter.

@krisgiesing krisgiesing changed the title Support some form of vector drawable format Support a vector drawable format Feb 12, 2016

@Hixie

This comment has been minimized.

Copy link
Contributor

Hixie commented Feb 12, 2016

Other random thoughts (not all mine):

  • We really want to avoid supporting a format where there's a preexisting expectation of implementing features that are not going to be performant. For example, implementing SVG will lead people to expect full SVG support including scripting, HTML, SMIL, etc.
  • We should design our format explicitly very closely aligned to performance features in Skia, e.g. drawAtlas.

@Hixie Hixie added this to the No Milestone Necessary milestone Feb 12, 2016

@appsforartists

This comment has been minimized.

Copy link
Contributor

appsforartists commented Mar 2, 2016

Vector support seems crucial for an app framework that supports various screen sizes and densities. Otherwise you end up with icons that look like this:

flutter-send-icon

Instead of this:

material-send-icon

@appsforartists

This comment has been minimized.

Copy link
Contributor

appsforartists commented Mar 2, 2016

@HansMuller

This comment has been minimized.

Copy link
Contributor

HansMuller commented Mar 2, 2016

Kris mentioned this as well: we could do some limited SVG processing at build time. For example we might generate MD icon Widgets based on the SVG descriptions. If done carefully that might save space and increase fidelity to the original designs.

@abarth

This comment has been minimized.

Copy link
Contributor

abarth commented Mar 2, 2016

For material design icons specifically, we should investigate using the material design icon font.

@appsforartists For what it's worth, neither Cocoa nor android.view use vector formats for icons.

@appsforartists

This comment has been minimized.

Copy link
Contributor

appsforartists commented Mar 2, 2016

@abarth Doesn't surprise me about iOS - seems like they started with a hardcoded 3.5" screen and have tried pretty hard to keep that mental model/simplicity of supported resolutions ever since (see: the width of each iPhone being the same, or the original iPad and iPad mini having the same resolution). I don't know much about mobile development, but that's slightly surprising about Android not being vector-based.

In any case, the icons should not look aliased like they do in the above screenshot, and vectors are a nice solution for resolution independence. How you guys choose to implement to solve for pretty icons is up to you. 😃

@abarth

This comment has been minimized.

Copy link
Contributor

abarth commented Mar 2, 2016

How you guys choose to implement to solve for pretty icons is up to you.

Would you be willing to file a separate issue about the resolution issue you were seeing with icons? @krisgiesing implemented a resolution-aware asset resolver that handles many cases. It would be valuable to learn about the cases that it doesn't handle.

@krisgiesing

This comment has been minimized.

Copy link
Contributor

krisgiesing commented Mar 2, 2016

I'm looking at adding some tests for the current resolution awareness support, so now would be a great time to understand if something's not working right.

@abarth

This comment has been minimized.

Copy link
Contributor

abarth commented Mar 2, 2016

It looks like the 3x has a device pixel ratio of 2.6, which we probably don't have an asset for.

@krisgiesing

This comment has been minimized.

Copy link
Contributor

krisgiesing commented Mar 2, 2016

I'm looking at this specific case now. The device pixel ratio is 2.625; we're choosing the 3.0x asset, which is expected. However, something seems to be going on during the rendering that is causing some kind of extra aliasing artifacts. So although @abarth fixed the case of the Material Design icons by switching to a font, I'm still investigating on behalf of other types of image assets that need resolution dependent scaling.

@krisgiesing

This comment has been minimized.

Copy link
Contributor

krisgiesing commented Mar 2, 2016

I'll open another bug to track this since it's is tangential to support of a vector format.

@krisgiesing

This comment has been minimized.

Copy link
Contributor

krisgiesing commented Mar 2, 2016

See #2337

@themacguffinman

This comment has been minimized.

Copy link

themacguffinman commented Aug 24, 2016

Android supports the "VectorDrawable" format which is just a well-performing subset of SVG. I hope you consider using the same format, given that it already has some community support and the Android team has apparently deemed its performance adequate.

@Hixie

This comment has been minimized.

Copy link
Contributor

Hixie commented Aug 24, 2016

VectorDrawable is certainly influenced by SVG but it's not a subset. Also it uses XML, which pretty much guarantees that it's not going to be the most performant vector format one could come up with. :-)

@themacguffinman

This comment has been minimized.

Copy link

themacguffinman commented Aug 24, 2016

It was wrong to describe VectorDrawable as a strict subset, but it still seems to be a balanced compromise between ensuring good render performance and ease of use. The VectorDrawable specification frequently defers to the SVG specification for key areas like path data syntax, making it much easier to convert SVG assets that many developers already use and share VectorDrawables that existing Android apps already contain.

I can't imagine that XML is a significant performance blocker because it only affects parsing. It seems to me that render performance - the kind of performance that affects Flutter's goal of 60fps apps - is more dependent on the set of vector operations that Skia will have to draw, not a parsing step that can be done once and cached.

I don't want to belabour the point but I can't help feeling that the work for this has already been done and therefore doesn't need to be shelved in the "after 2.0 release" milestone.

@eseidelGoogle

This comment has been minimized.

Copy link
Contributor

eseidelGoogle commented Jan 26, 2017

We ended up using the Material Design font for the Material Design Icons. I'm not aware of any obstacles stopping someone from building this on top of Flutter today using direct dart:ui calls or a CustomPaint widget: https://docs.flutter.io/flutter/widgets/CustomPaint-class.html. We have no immediate plans to build such at this time.

@eseidelGoogle eseidelGoogle modified the milestones: No Milestone Necessary, 6: Future Future Jan 26, 2017

@deborah-ufw

This comment has been minimized.

Copy link

deborah-ufw commented Jun 4, 2017

$.02 - even janky browsers (and competitor framework React Native never mind, their solution is hacky) can render SVG. The image export option requires creating a minimum of 3 files for each icon or art asset for my team. That's a poor practice compared to one SVG file can be displayed at any resolution.

For the above comment by Hixie, pre-existing expectations shouldn't inhibit implementing a worthwhile feature. I'd much rather be able to have basic support for SVG display (which solves many problems for me and my team) and find out extended options aren't available than rely on an ever-increasing number of PNGs to accommodate the ever-increasing number of screen resolutions.

I'm falling back to making a font for my team but that's not as good as native SVG support because the font format adds extra formatting for line-height and letter spacing that has to be adjusted in the app. Also, fonts want to be displayed at fixed resolutions (12px, 16px, 20px, 36px...) which is also limiting.

Thank you for cool Flutter framework. :)

@Hixie

This comment has been minimized.

Copy link
Contributor

Hixie commented Jun 4, 2017

I would encourage anyone who wants SVG support to implement SVG support as a Dart package for Flutter.

@sethladd

This comment has been minimized.

Copy link
Contributor

sethladd commented Jun 5, 2017

For those interested, I'd point to https://docs.flutter.io/flutter/dart-ui/dart-ui-library.html which is the low-level library for drawing.

@deborah-ufw

This comment has been minimized.

Copy link

deborah-ufw commented Jun 5, 2017

From team: Dart library not good enough solution. Just passing it on.

@Hixie

This comment has been minimized.

Copy link
Contributor

Hixie commented Jun 5, 2017

Can you elaborate on that? The whole of Flutter's framework is a Dart library; anything we implement here will likely be a Dart library. What are the requirements for "good enough"?

@Hixie Hixie added this to the Stretch Goals milestone Jun 19, 2018

@lukepighetti

This comment has been minimized.

Copy link

lukepighetti commented Jun 23, 2018

Interesting conversation that leaves me with a simple question. How does Flutter team recommend we go from design phase (SVG) to vector graphics in Flutter?

@zoechi

This comment has been minimized.

Copy link
Contributor

zoechi commented Jun 24, 2018

@lukepighetti you can try https://github.com/dnfield/flutter_svg and check how far it takes you.

@SocialMammoth

This comment has been minimized.

Copy link

SocialMammoth commented Dec 11, 2018

Personally I am not happy with the solution offered for SVG files in Flutter. I used flutter_svg package and I'm not happy with it.

SVG support needs to be supported natively in my opinion in the standard library. If we're going to start using Flutter on bigger screens like desktop apps and websites this is a must.

@dnfield

This comment has been minimized.

Copy link
Member

dnfield commented Dec 11, 2018

@SocialMammoth can you elaborate on what deficiencies you're seeing?

@dnfield

This comment has been minimized.

Copy link
Member

dnfield commented Dec 12, 2018

One thing I've been mulling over for a while is whether it'd be worthwhile to support the .skp (SKIAPICT) format. I think there are good reasons to not do this directly - the format is not guarnateed to be stable from version to version of Skia being the big one.

However, it does have some interesting properties - in particular, it's possible to get Chrome/Chromium to generate an SKP (perhaps of a rendered SVG), and it's very likely that we already support most or all of the Skia drawing commands required to actually render the vast majority of SKPs.

I've been planning to create a code-gen type of solution for the SVG plugin, so that you could generate Dart/Flutter code from an SVG. I think at this point that it would probably be more interesting to investigate an SKP to Dart build process - some of the code written for Flutter SVG could be ported over to the framework (e.g. the RawPicture and related infrastructure, which roughly corresponds to a RawImage), and we could wire something up that would take the output of an SKP (perhaps generated from an SVG as rendered by Chrome, which is pretty much gold standard for SVG rendering anyway). It should be possible to make tooling that would take an SVG, invoke headless Chromium to render it to an SKP, and then transforming the SKP to some Dart file(s) that Flutter could render at runtime.

One large area this doesn't solve is dynamically loading a vector graphic at runtime (e.g. SvgPicture.network), but I'm interested in feedback on whether this would still be a worthwhile/acceptable solution even with that limitation.

I also say this with the belief that, at this point, we will never get "native" support for SVG in Flutter. This is partly because SVG itself has a lot of baggage (XML, CSS, ability to fetch external assets) that are non-trivial to implement outside of a browser/HTML rendering software and would add a lot of bloat to software we're trying to lean down. It's also partly because it's entirely possible to implement quite a bit of SVG without making any huge changes to the framework - although a few things (filterEffects and textPaths in particular right now) will probably benefit from some more tweaks to the engine.

@cachapa

This comment has been minimized.

Copy link

cachapa commented Dec 12, 2018

I think being able to load SVGs directly from the network is a major benefit even if it means we only support a subset of the format's functionality.

Having a Flutter-specific vectorial format sounds like what Android is doing with VectorDrawables, which while it works fine, it also means that can't benefit from a lot of the tooling that already exists for SVG. It also makes it awkward to iterate designs because of all the format conversions.

@lukepighetti

This comment has been minimized.

Copy link

lukepighetti commented Dec 12, 2018

I would like to see Flutter support SVGs natively because that is what front end devs expect from their frameworks in 2018. I would like front end devs to find Flutter accessible, because I want the ecosystem to grow.

@ohir

This comment has been minimized.

Copy link

ohir commented Dec 12, 2018

@dnfield

.skp (SKIAPICT) format. I think there are good reasons to not do this directly - the format is not guarnateed to be stable from version to version of Skia being the big one.

IMHO interesting approach. But then Flutter tooling (at least in AS) need to seamlessly deal with conversion. Designers are somewhat used to restrictions imposed by current Android's vector-drawable imports, so they surely will be able to deal with other set of dos and donts.

For the casual developer the manual should read: "Drop your svg drawings here, annotate here, use at will. If your svg does not abide to supported SVG subset (see here) compiler or analyzer (flutter analyze) will tell you what is wrong in your svg". Or something like that.

@dnfield

get Chrome/Chromium to generate

Good for PoC and testing, but real solution IMHO may not require such a huge dependency -- and one that is hard to script as CI middle step. Of course at the beta and then as a second 'hard way' it might be ok -- eg. to get easy animated drawing that skPicture allows for. I may be wrong ofc. as designers usually have a big bucket with browsers under their laptop flap. Nonetheless, mind that artwork mutates often. Not only at prototyping stage but also as launch time approaches and devs are in bug hunting fever.

[Ie. We either need a flutter tools deal with conformant svg import or we need a way where chromium is entirely at designer's hands. Not developer's.]

PS. The launcher_icons package way might do at start: flutter packages pub run flutter_svg_to_skp:main -i path/to/svgs -o path/to/skps.

-- my ¢2

@ohir

This comment has been minimized.

Copy link

ohir commented Dec 12, 2018

@cachapa

being able to load SVGs directly from the network

This is a work for a separate huge package that will deal with validation and workarounds
around possible incompatibilities and producer's quirks.
First get engine to draw developer's supplied vector format that "Load SVG from network" package will surely use. :)

@dnfield

This comment has been minimized.

Copy link
Member

dnfield commented Dec 12, 2018

Just to be clear @cachapa and @ohir - flutter_svg already supports loading an SVG over the network (SvgPicture.network). However, that package will never end up supporting the entirety of the SVG specification - the goal is really only to support enough of the specification to render most SVGs. It already does that, with the major exceptions at this point being fliterEffects (so no blurs, color filters, etc.) and a lot of text related support - but there are some others (markers aren't supported, certian types of xlink:href references still aren't supported). There are also some issues that I am intentionally not supporting, like the full CSS specification, scripting, and interactivity.

@lukepighetti I think that expectation only really exists with web based front end developers. Qt supports SVG, but only a limited subset. GNOME supports a bit more with librsvg, but again that has some issues (and it's really difficult to use outside of Linux environments). I'm excited to see what happens with resvg, but I don't know of any GUI library that's integrating it.

@SocialMammoth

This comment has been minimized.

Copy link

SocialMammoth commented Dec 12, 2018

@dnfield I don't want to criticize your work since you did a great job and I thank you tremendously for that. I'm just disappointed that color does not work as expected. I had to pick my own color, I'm not an artist, I'm also colorblind.

Flutter needs to support SVGs the same way modern browsers do. It's a must. We need to be able to use assets copied or imported directly from a web page without modification.

Frankly thank god at least there's a package, but we need color, we need effects, if performance is an issue than make it optional for people to turn features off not force them to turn features on.

@SocialMammoth

This comment has been minimized.

Copy link

SocialMammoth commented Dec 12, 2018

We need full spec support for SVGs. I agree with @lukepighetti . With Hummingbird, this is a must, or web devs will laugh at Flutter and give it a hard pass.

@SocialMammoth

This comment has been minimized.

@cbazza

This comment has been minimized.

Copy link

cbazza commented Dec 12, 2018

Since @dnfield mentioned 'resvg', @SocialMammoth perhaps flutter_svg should also aim for 'SVG static' support instead of complete svg support:
http://www.w3.org/TR/SVG11/feature#SVG-static,
which I think should make everyone happy.

@jan-tosovsky-cz

This comment has been minimized.

Copy link

jan-tosovsky-cz commented Dec 12, 2018

Even Chrome doesn't support all SVG features and especially right-to-left text rendering is buggy (without any progress in last few years). In other words, I don't think the full SVG support is realistic. SVG-static seems to be a reasonable subset. In flutter_svg I miss text hadling (incl. text on path), filters and masks. It would be nice to have support in Flutter for building something like this https://drifted.in/horologium-app/

@ohir

This comment has been minimized.

Copy link

ohir commented Dec 13, 2018

@SocialMammoth

Flutter needs to support SVGs the same way modern browsers do

No. Flutter apps need to be lean. This issue is not about almighty package to deal with all of SVG, it explicitly says "support a vector drawable format" (not support SVG). The goal, as I understand it, so far is to get all flutter apps rid of bitmap assets as much as possible. And that on the engine level. @dnfield did a great job via a package. Now its time to just get some vector graphics available from Dart without ballooning the flutter (skia) engine or the app itself. The .skp use seems a good choice for that goal. It already allows for more than Android's vector-drawable does and it already is in the engine. Designers will accommodate to its feature set.

@SocialMammoth

This comment has been minimized.

Copy link

SocialMammoth commented Dec 13, 2018

@ohir I guess we disagree then. A front-end framework that doesn't support SVG files is a bad joke really.

@lukepighetti

This comment has been minimized.

Copy link

lukepighetti commented Dec 13, 2018

Well, I don't think flutter NEEDS svg to be useful, but it would be nice. And if not svg, than some format that is easy to obtain from your typical vector graphics application.

@cbazza

This comment has been minimized.

Copy link

cbazza commented Dec 13, 2018

Basically SVG is the standard vector format to use here but we can't possibly expect support for every feature of SVG. The goal has always been to support the minimum in order to import vector assets from typical vector graphics applications. Which vector graphics applications can read & write .skp ?

@lukepighetti

This comment has been minimized.

Copy link

lukepighetti commented Dec 13, 2018

My test for if a vector format is ubiquitous enough is if it's available in Adobe Illustrator, Affinity Designer, and Inkscape. As far as I know that pretty much leaves SVG. And I agree that we don't need every SVG feature. Just basic paths strokes and fills is fine.

I can't say this with authority but I suspect it would be easier to implement a subset of SVG than it would be to convince vector graphics applications to support .skp?

@ohir

This comment has been minimized.

Copy link

ohir commented Dec 13, 2018

@lukepighetti : Dan's idea is to use engine's internal format. The crux of this solution is to get SVG converted to the format the engine understands. It does not matter if Inkscape knows this format as long as any viable converter does exist.

I was in doubt yesterday, but today, after a bit of research, seems to me that chrome automation is well supported. If headless chrome can be used with a rendering proxy it can be made a svg->skp converter too. A bit heavy, but affordable. Low hanging fruit indeed, @dnfield :).

It all fits nicely with goals set by @Hixie almost three years ago.

@cbazza

This comment has been minimized.

Copy link

cbazza commented Dec 13, 2018

@dnfield please correct me if I am wrong.
I am assuming that .skp is basically the binary format for a Skia Picture.

Given that dart:ui also has a wrapper for Skia Picture that can be generated from Dart land, won't the contents of these pictures contain different Skia capabilities? Basically the one from Chrome will use all Skia functionality, while the one from dart:ui will not (limited by what was made available via Flutter engine)? Kind of weird for the 'performance' argument, isn't it? Flutter engine & dart:ui removes all of Skia that was deemed slow (without showing performance numbers) but then you can use all of that if it comes in via the Chrome generated .skp file?

Another thing, when using .skp how would you specify the colors of an icon, if for example the icon uses 2 colors or more?

How about the old argument that by using Dart in Flutter you have control over every pixel? To me flutter_svg package supporting 'svg static' is the way to go because it will enable future innovation in Dart land. By bypassing Dart and just letting C++ handle it, it seems like Dart couldn't hack it.

@xuexin

This comment has been minimized.

Copy link
Contributor

xuexin commented Jan 4, 2019

Skia seems to support SVG. Why doesn't Flutter provide SVG support directly?

@lukepighetti

This comment has been minimized.

Copy link

lukepighetti commented Jan 4, 2019

From what I can tell the Flutter team wants to keep the Skia package size as small as possible. I did not know that Skia supports SVG, but if it does, that is low hanging fruit. As a note, there is another issue on adding Lottie support fo Flutter because Skia supports it.

@dnfield

This comment has been minimized.

Copy link
Member

dnfield commented Jan 4, 2019

Skia does not support importing drawings from SVG, but has some experimental support for creating SVGs (which isn't as useful here).

And yes, package size is a concern.

@Hixie

This comment has been minimized.

Copy link
Contributor

Hixie commented Jan 6, 2019

Please if you want to ask for SVG support see: #15501

This bug is specifically about supporting vector graphics without supporting SVG.

@Hixie Hixie changed the title Support a vector drawable format Support a vector drawable format (not SVG) Jan 6, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment