Skip to content

2013base#39

Open
mtrubnikov wants to merge 2 commits into
SVGKit:2013basefrom
mtrubnikov:2013base
Open

2013base#39
mtrubnikov wants to merge 2 commits into
SVGKit:2013basefrom
mtrubnikov:2013base

Conversation

@mtrubnikov

Copy link
Copy Markdown

Some code refactored;
Text implementation fixed;
Group elements and transforms done the right way (I hope so);
Matrix transforms parsing fixed;
Added OUTLINE_SHAPES option for debugging purposes - it draws bounding boxes for all elements.

starwars-computer-specialist
May the force be with you. ;)

Some code refactored; text implementation fixed.
Group elements fixed.
Added OUTLINE_SHAPES option for debugging purposes.
@adamgit

adamgit commented Jan 18, 2013

Copy link
Copy Markdown
Contributor

Thanks. There's some good stuff here, but I'll have to cherrypick it - a few bits won't work.

Good catch on fixes eg using a reserved keyword as a parameter (doh)

But some bits I can't merge, will comment for each separately...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question. Experimenting with the examples in the official SVG Spec (which have PNG renders included, so we can check the "expected" output), it seems there's two problems that this solves:

  1. SVG Spec requires that we calculate the bounds for the text based on SVG rules. We have to do that using the transform --- I was surprised at this, it makes implementation much harder than I'd like, but SVG spec's approach to text is ... weird
  2. Apple requires that you define the text-size BEFORE you render the layer, because Apple's clipping is applied early in the rendering --- I was suprised by this, seems that Apple did some bad API design, and made it so that CATextLayer doesn't have an "automatic" bounds based on the text contents. This is annoying :(.

...put those two together, and the font-size has to be downscaled BEFORE we scale the resulting layer. Yes, its weird - but turn it off, and then try some of the spec examples, and you'll see Apple apply "incorrect" clipping.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, OK, but the problem here is that text could not only be proportionally scaled, but all the valid SVG transforms can be applied, like rotation and skew.
I agree, that my implementation is wrong concerning SVG spec bounds calculation... But it lets us RENDER all transforms correctly, breaking layer bounds.

If you create a simple svg with transformed text, you'll easily understand what I mean.
Well, for example (sorry, I don't know, how to share files here):

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   version="1.1"
   width="744.09448"
   height="1052.3622"
   id="svg3018">
  <g
     id="layer1">
    <text
       x="14.464138"
       y="80.399139"
       transform="matrix(1.4614298,0.61852241,0.50594217,0.8983918,0,0)"
       id="text3030"
       xml:space="preserve"
       style="font-size:21.16327095px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Verdana"><tspan
         x="14.464138"
         y="80.399139"
         id="tspan3032">ROTATED AND SKEWED TEXT</tspan></text>
  </g>
</svg>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I see what you mean.

Perhaps we need to pull your last few lines in this method (which do the transforms) up to this point, and apply them to the results of Apple's CoreText methods from the 2013base code ... and work out the actual box needed to send to CATextLayer / etc?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should try.
As far as I see, according to spec, we have to get bounds look somehow like the red box.
With my code, we get the green one.

drawing

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So ... I've spent a long time looking at this.

The short answer is: your original comment "why do we do this?" is because you've misunderstood how the SVG library works.

The library - from day 0 - was built to do this:

  1. work out the position and transofrmation of everything
  2. position everything correctly on screen. If something needs rotating or skewing, do that to the shape itself
  3. build CALayers that make things appear in those places. NEVER SET THE TRANSFORM FOR ANY LAYER

Advantages:

a. Users can use 3D transforms, or custom Affine transforms, and it all works
b. Render speed and hit-test speed is - theoretically - much faster because the transforms only have to be calculated once

Disadvantages;

c. If you take a layer that's invisible (e.g. elements are defined as invisible in SVG), and make it visible - it will appear to be in the wrong place.
d. We need the "layoutLayer" method to be called on EVERYTHING after making the layers - because we don't know the correct size of ANY layer until we've rendered ALL layers

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know that the original version is "best" - but I've looked at the amount of code needed to change it (a lot!) and ... it would seem to make the library slower, so ... I'm going to undo my changes and leave it working the way it was previously.

@adamgit

adamgit commented Jan 18, 2013

Copy link
Copy Markdown
Contributor

I've commented on the commit itself, using GitHub's line-by-line.

Some of it is notes to myself - when I get some time, I'll do a careful bit-by-bit merge and test each change.

There's some questions in there too - if you get time, would be great to get your thoughts / help on some of those.

@mtrubnikov

Copy link
Copy Markdown
Author

For sure, I'll try to answer each question/comment.

Where, by the way, can I find official examples?
I tested on files made with Inkscape and CorelDraw.

@adamgit

adamgit commented Jan 18, 2013

Copy link
Copy Markdown
Contributor

In the SVG spec itself, ( http://www.w3.org/TR/SVG/ ) they often embed
inline SVG's with PNG files. Each time they do, there's a link either
immediately below - or sometimes a couple of paragraphs away - to "view
this example as SVG (if your brwoser supports it)".

The links resolve to plain SVG that you can save directly.

Also, every time a user reports a "broken" SVG, we ask them to create a
simple example that we can add to the "Demo-iOS" project (almost all of the
files there are ones that used to be broken / fail in SVGKit. A couple of
them still don't work correctly)

On 18 January 2013 14:08, Mark Trubnikov notifications@github.com wrote:

For sure, I'll try to answer each question/comment.

Where, by the way, can I find official examples?
I tested on files made with Inkscape and CorelDraw.


Reply to this email directly or view it on GitHubhttps://github.com//pull/39#issuecomment-12423099.

@mtrubnikov

Copy link
Copy Markdown
Author

Oh, by the way, do you have any performance issues when zooming in and out?
With my big svg files with lots of text... It really drives me crazy.

@adamgit

adamgit commented Jan 18, 2013

Copy link
Copy Markdown
Contributor

With SVGKFastImageView - no, that's why I made it :). I haven't tried it
with text, but it works well with VERY complicated shape/path data.

If FastImageView is slow, it suggests that CATextLayer is broken and
useless (thanks to Apple) and that we'll have to re-implement it using
CoreText :(.

On 18 January 2013 15:14, Mark Trubnikov notifications@github.com wrote:

Oh, by the way, do you have any performance issues when zooming in and
out?
With my big svg files with lots of text... It really drives me crazy.


Reply to this email directly or view it on GitHubhttps://github.com//pull/39#issuecomment-12425948.

@adamgit

adamgit commented Jan 31, 2013

Copy link
Copy Markdown
Contributor

Just a quick note to say: I'm swamped with work right now :(, haven't had time to finish merging this. But will get back to it ASAP when I can.

@adamgit adamgit mentioned this pull request Jan 31, 2013

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accoridng to SVG spec, there's no X nor Y in SVGShapeElement - they only exist in SVGRectElement

(some of these SVG*Element classes are badly wrong in SVGKit right now, but I'm moving them all towards being spec-compliant)

@adamgit

adamgit commented Feb 16, 2013

Copy link
Copy Markdown
Contributor

FINALLY merged ... great work, @mtrubnikov !

Because GitHub refused to auto-merge, I had to split it up into small pieces. There is ONE PIECE I haven't done which should work fine - I'd prefer you to submit it as a separate commit (so it shows up under your username) -- the two UIColor-Expanded files.

For the rest:

"Some code refactored;" -- I had to skip the changes to layoutLayer because they triggered some crashes elsewhere. I don't know why, I'll have to revist this later :(

"Text implementation fixed;" -- in the end, I used your approach of setting .affineTransform - but to make it work with ALL our text examples I had to do it differently (c.f. the code comments for detailed explanation of WTF I did and why)

"Group elements and transforms done the right way (I hope so);" -- as discussed, there's too many problems with Apple's .affineTransform code for us to use it throughout SVGKit. However, inspired by your fixes, I re-wrote the whole of transforms to be MUCH easier to read, and to be MUCH closer to SVG Spec compliance (c.f. the new protocol "SVGTransformable" that's part of the SVG Spec)

"Matrix transforms parsing fixed;" -- merged fine, but it had some problems with complex transforms, so I had to tweak it a little. Seems to work.

"Added OUTLINE_SHAPES option for debugging purposes - it draws bounding boxes for all elements." -- this is a great idea, but it can be done in user-code (as a runtime thing). I've moved your code into the Demo-iOS project, AND I've merged it with some code I wrote for hit-testing. Now whenever you tap anywehre on screen, it outlines the smallest containing object.

@mtrubnikov

Copy link
Copy Markdown
Author

Sorry, I had no time even to answer you here recently.
Thanks!
I'll try to commit the two above mentioned files as soon as possible.

@adamgit

adamgit commented Feb 17, 2013

Copy link
Copy Markdown
Contributor

No worries - if you don't have time, I can commit them. But I prefer to keep the commit history accurate, if possible.

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.

2 participants