Unable to render a (simple?) gradient polygon. #69

Closed
teras opened this Issue Apr 14, 2013 · 18 comments

Comments

Projects
None yet
5 participants

teras commented Apr 14, 2013

I was experimenting with this library and I tried to load one of my SVG's which were manipulated through InkScape, unfortunately with no luck. The renderer was unable to render the file if it had gradient fills in it.

In your demos, this seems to be supported, so I managed to create a minimun implementation to present this problem.
The file can be downloaded from
http://www.panayotis.com/polygon.svg
(unfortunately github didn't allow me to upload an SVG file).

It is a yellow polygon in front of a red square. The red square could be rendered, but the yellow polygon not.

Can you direct me to any solution to this problem?
Thank you.

Contributor

adamgit commented Apr 14, 2013

Did you look at the console log?

teras commented Apr 14, 2013

First of all, thanks for the quick answer.

I haven't used SVGKFastImageView, if this is what you asked. I tried to render it through tSVGKImage -> UIImage first.

If I run this code through the demo application (and modify it to support only SVGKFastImageView instead), I get this message:

2013-04-14 18:48:04.529 Demo-iOS[3044:c07] An instance 0xf2731c0 of class SVGKLayer was deallocated 
while key value observers were still registered with it. Observation info was leaked, and may even become 
mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the 
debugger. Here's the current observation info:
<NSKeyValueObservationInfo 0xf273250> (
<NSKeyValueObservance 0xf273210: Observer: 0xf2731c0, Key path: showBorder, Options: <New: YES, Old: 
NO, Prior: NO> Context: 0x0, Property: 0x727c0c0>
)

In my code, which I use code something like:

SVGKImage * svg = [SVGKImage imageNamed:"polygon.svg"];
CGImageRef cgimage = svg.UIImage.CGImage;

I get the following (long) info log:

2013-04-14 18:44:40.645 ViewTest[2948:c07] [SVGLength] WARNING: you are running on the simulator; it's impossible for us to calculate centimeter/millimeter/inches units correctly
2013-04-14 18:44:40.649 ViewTest[2948:c07] [SVGSVGElement] WARNING: SVG spec says we should calculate the 'intrinsic aspect ratio'. Some badly-made SVG files work better if you do this and then post-multiply onto the specified viewBox attribute ... BUT they ALSO require that you 're-center' them inside the newly-created viewBox; and the SVG Spec DOES NOT SAY you should do that. All examples so far were authored in Inkscape, I think, so ... I think it's a serious bug in Inkscape that has tricked people into making incorrect SVG files. For example, c.f. http://en.wikipedia.org/wiki/File:BlankMap-World6-Equirectangular.svg
2013-04-14 18:44:40.650 ViewTest[2948:c07] [SVGSVGElement] DEBUG INFO: set document viewBox = {{0, 0}, {3.14919, 3.15}}
2013-04-14 18:44:40.654 ViewTest[2948:c07] [SVGKParser] WARN: found a tag with no namespace parser: (), using default parser(<SVGKParserDOM: 0xc8b01d0>)
2013-04-14 18:44:40.656 ViewTest[2948:c07] [SVGKParser] WARN: found a tag with no namespace parser: (), using default parser(<SVGKParserDOM: 0xc8b01d0>)
2013-04-14 18:44:40.658 ViewTest[2948:c07] [SVGKParser] WARN: found a tag with no namespace parser: (), using default parser(<SVGKParserDOM: 0xc8b01d0>)
2013-04-14 18:44:40.659 ViewTest[2948:c07] [SVGKParser] WARN: found a tag with no namespace parser: (), using default parser(<SVGKParserDOM: 0xc8b01d0>)
2013-04-14 18:44:40.661 ViewTest[2948:c07] [SVGKParser] WARN: found a tag with no namespace parser: (), using default parser(<SVGKParserDOM: 0xc8b01d0>)
2013-04-14 18:44:40.662 ViewTest[2948:c07] [SVGKParser] WARN: found a tag with no namespace parser: (), using default parser(<SVGKParserDOM: 0xc8b01d0>)
2013-04-14 18:44:40.664 ViewTest[2948:c07] [SVGKParser] WARN: found a tag with no namespace parser: (</title>), using default parser(<SVGKParserDOM: 0xc8b01d0>)
2013-04-14 18:44:40.673 ViewTest[2948:c07] [SVGKImage] DEBUG: Generating a UIImage using the current root-object's viewport (may have been overridden by user code): {0,0,283.430,283.500}
2013-04-14 18:44:40.675 ViewTest[2948:c07] [SVGKImage] WARNING: no CALayer tree found, creating a new one (will cache it once generated)
2013-04-14 18:44:40.677 ViewTest[2948:c07] [SVGGradientElement] set gradient layer start = {0.723329, 0.608127}
2013-04-14 18:44:40.678 ViewTest[2948:c07] [SVGGradientElement] set gradient layer end = {1.56424, 1.15997}
2013-04-14 18:44:40.679 ViewTest[2948:c07] [SVGGradientElement] set gradient layer colors = (
)
2013-04-14 18:44:40.680 ViewTest[2948:c07] [SVGGradientElement] set gradient layer locations = (
)
2013-04-14 18:44:40.682 ViewTest[2948:c07] DOESNT WORK, APPLE's API APPEARS BROKEN???? - About to mask layer frame ({{0, 0}, {3.14919, 3.15}}) with a mask of frame ({{22, 21}, {341, 240}})
2013-04-14 18:44:40.682 ViewTest[2948:c07] [SVGKImage] rendering to CGContext: time taken to convert from DOM to fresh CALayers: 0.008 seconds)
2013-04-14 18:44:40.683 ViewTest[2948:c07] [SVGKImage] DEBUG: rendering to CGContext using the current root-object's viewport (may have been overridden by user code): {0,0,283.430,283.500}
2013-04-14 18:44:40.688 ViewTest[2948:c07] [SVGKImage] renderToContext: time taken to render CALayers to CGContext (perf improvements: NO-ANTI-ALIAS): 0.004 seconds)

Contributor

adamgit commented Apr 14, 2013

Apple's massive bug in iOS also applies to UIImage / CGImage generation.

There is literally nothing we can do about this - Apple's own docs say something like "We might fix this sometime after OS X 10.5, but might not" (I guess it was working in OS X until 10.5? I don't know, I wasn't using the libs back then).

I suggest you file a bug against Apple / complain that their "renderInContext" method doesn't support the "mask" parameter (as per their docs). Maybe if enough people complain, they'll fix it?

Also: don't try to render images by hand, unless you REALLY need to. You are throwing away most/all the benefits of SVG's if you convert them straight to bitmap :).

@adamgit adamgit closed this Apr 14, 2013

teras commented Apr 14, 2013

Again thank you for the quick reply.

I'd be glad to leave a bug report in Apple's site, although I didn't quite understand what the problem is.
I'd complain as you said that the "renderInContext" method doesn't support the "mask" parameter

About the specific SVG: the problem is that the mask defined in this file, is not supported?
And thus the drawing is not performed at all?
Couldn't be another method to apply this mask - and is this restriction so strong that the polygon can not be drawn?

Sorry for this long questions, please allow me one more (probably the most important one) :
Is it possible to transform this SVG through Inkscape somehow, to make it compatible with this library?

(btw the UIWebView is able to properly display it).

Contributor

adamgit commented Apr 14, 2013

As per the console message, use SVGKLayeredInageView and it will work
perfectly.

Nothing else is possible. Apples bugs prevent any use of graidents unless
they are rectangular.

On Sunday, 14 April 2013, teras wrote:

Again thank you for the quick reply.

I'd be glad to leave a bug report in Apple's site, although I didn't quite
understand what the problem is.
I'd complain as you said that the "renderInContext" method doesn't
support the "mask" parameter

About the specific SVG: the problem is that the mask defined in this file,
is not supported?
And thus the drawing is not performed at all?
Couldn't be another method to apply this mask - and is this restriction so
strong that the polygon can not be drawn?

Sorry for this long questions, please allow me one more (probably the most
important one) :
Is it possible to transform this SVG through Inkscape somehow, to make it
compatible with this library?

(btw the UIWebView is able to properly display it).


Reply to this email directly or view it on GitHubhttps://github.com/SVGKit/SVGKit/issues/69#issuecomment-16355146
.

teras commented Apr 14, 2013

Sorry to disturb you again, but it seems that even when I use the SVGKLayeredImageView, it doesn't work.

Here is a quick code to demonstrate it.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    self.window.backgroundColor = [UIColor whiteColor];

    SVGKLayeredImageView * v = [[SVGKLayeredImageView alloc] initWithSVGKImage:[SVGKImage imageNamed:@"polygon.svg"]];
    [v setFrame:CGRectMake(20, 20, 100, 100)];
    [self.window addSubview:v];    
    [v release];

    [self.window makeKeyAndVisible];
    return YES;
}

The red box is present, but the yellow polygon is not.

Contributor

adamgit commented May 11, 2013

What happens if you do NOT call "setFrame" ?

teras commented Nov 14, 2013

Same thing
Nothing changed
(sorry for the late answer)

Contributor

adamgit commented Dec 11, 2013

If you can pin it down to a specific call that's broken, I'll have a look. I suggest you edit the SVG and remove lines until you get to a point where one line in particular does the wrong thing. (you shouldn't need the background, the gradient, etc - just the shape that's failing to render).

Also, make sure you do a git pull first, and you're using the "1.x" branch ( this is displayed by default on the homepage now) - lots of fixes always being added there :)

Do you still need the fix for this? It is in another thread/issue.

I personally could use a fix for this, currently using the 2.x branch. Using the following Swift code, I can't get a radial or linear gradient to render.

var source = SVGKSource(inputSteam: NSInputStream(fileAtPath: imagePath))
var parser = SVGKParser(source: source)

parser.addDefaultSVGParserExtensions()
parser.addParserExtension(SVGKParserPatternsAndGradients())
parser.addParserExtension(SVGKParserGradient())

var result = parser.parseSynchronously()

image = SVGKImage(parsedSVG: result, fromSource: source)
imageView = SVGKLayeredImageView(SVGKImage: image)
myView.addSubview(imageView as UIView)

teras commented Dec 11, 2014

tomfitango, yes I'd like to see a solution for this.
Is it possible to direct me to the thread that fixes this problem?
Thank you.

Just comment addObserver @"DOM.Tree" in SVGImage.m . Someone commented remove observer but not add observer in this case. You can search the discussions if you need for it. It obviously wasn't merged into the main trunk yet.

But we maybe be talking about a different issue - I'm only referring to this message which you received:

2013-04-14 18:48:04.529 Demo-iOS[3044:c07] An instance 0xf2731c0 of class SVGKLayer was deallocated
while key value observers were still registered with it. Observation info was leaked, and may even become
mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the
debugger. Here's the current observation info:
<NSKeyValueObservationInfo 0xf273250> (
<NSKeyValueObservance 0xf273210: Observer: 0xf2731c0, Key path: showBorder, Options: <New: YES, Old:
NO, Prior: NO> Context: 0x0, Property: 0x727c0c0>
)

You might also check SVGKLayer.m if it does not inherit for add/remove observers.

I have the same issue, al I found is that commit SHA: 4a52de6 works fine

Contributor

adamgit commented Mar 20, 2015

So ... this is now fixed? (as a side-effect of that commit)

teras commented Mar 20, 2015

I tried it just now.
The problem is still not fixed.
I remind that my test SVG is here

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