chenbo007 / svg-edit

Automatically exported from code.google.com/p/svg-edit
0 stars 0 forks source link

Import SVG content into an existing drawing #72

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
this is a different behavior than loading a SVG (issue 60)

-when the user adds, only the shapes and paths of the SVG should be added.
not the background or the "envelope" 
-the contents should be pre-grouped and added in the center of the canvas,
shrunk at 1/3 of the height or 1/3 of the width (whichever is bigger)
-should use a new, topmost layer

(related to issue 71)

Original issue reported on code.google.com by Christia...@gmail.com on 10 Jul 2009 at 11:37

GoogleCodeExporter commented 9 years ago
So this is about importing SVG into the existing drawing, correct?

I am blocking this until we get a working Layers implementation (Issue 73)

Original comment by codedr...@gmail.com on 17 Sep 2009 at 3:22

GoogleCodeExporter commented 9 years ago

Original comment by codedr...@gmail.com on 9 Jan 2010 at 10:56

GoogleCodeExporter commented 9 years ago
A couple questions I have are:

  1) should the imported SVG get put on a new layer or the current layer?  (Photoshop
creates a new layer, I believe, which I'm fine with)
  2) is the imported SVG considered one big group once it has been imported? (if so,
then we would need to shove the entire contents of the import <svg> into a 
group - it
can of course later be ungrouped by the user)
  3) how should the size of an imported drawing be dealt with?  I see a suggestion of
1/3 the canvas but what if the canvas is zoomed?
  4) how should the IDs of the imported SVG be handled?  Do we iterate through the
entire drawing and replace IDs?  If so, need to be very careful we get 
references right
  5) how should the <defs> of the imported SVG be handled?  Do we just include the
<defs> in the group that we create in #2?  Do we put all those elements into the
'global' defs of the image?

Original comment by codedr...@gmail.com on 9 Jan 2010 at 11:20

GoogleCodeExporter commented 9 years ago

Original comment by codedr...@gmail.com on 9 Jan 2010 at 11:21

GoogleCodeExporter commented 9 years ago
A couple questions I have are:

  1) should the imported SVG get put on a new layer or the current layer?  (Photoshop
creates a new layer, I believe, which I'm fine with)
  2) is the imported SVG considered one big group once it has been imported? (if so,
then we would need to shove the entire contents of the import <svg> into a 
group - it
can of course later be ungrouped by the user)

Inkscape has grouping of groups. It would be nice to have the same. So my 
suggestion
woud be: new layer and each layer of the imported SVG to be grouped. This way 
the
editor may create and move the groups to new layers or manipulate the entire 
import
with ease. it's the middle ground. 

  3) how should the size of an imported drawing be dealt with?  I see a suggestion of
1/3 the canvas but what if the canvas is zoomed?

i suggest the svg canvas to be larger than the actual edit area (also solves 
other
issues) and imported draw 1:1 if it fits into the edit area. 1/n fixed ratio if 
it is
about n times bigger and n/1 if n times smaller.  
why it's so important to import 1:1 as preferred way? think animation: importing
previous frame. or other applications where frame reference remains unchanged.

  4) how should the IDs of the imported SVG be handled?  Do we iterate through the
entire drawing and replace IDs?  If so, need to be very careful we get 
references right

this one seems simple: if we would introduce a prefix to all ids of an image. 
say the
name of the image is "dog" we may prefix al by dog_<generated_id> if we import 
dog
image into another dog, all ids form first dog may become 
dog_dog_<old_generated_id>

  5) how should the <defs> of the imported SVG be handled?  Do we just include the
<defs> in the group that we create in #2?  Do we put all those elements into the
'global' defs of the image?

since the defs may use the same protocol as the ids, it may not matter where 
they are
stored. but i don't know what would be best.. either way seems to work

Original comment by Christia...@gmail.com on 10 Jan 2010 at 12:08

GoogleCodeExporter commented 9 years ago
The ID thing seems sensible (prefix), but we do need to be careful.  In cases 
like this:

<linearGradient id="linearGradient1234">...</linearGradient>

<rect id="rect6789" fill="url(#linearGradient1234)" />

It seems like we will have to build up a map of 'previous ID' to 'new ID' and 
then do
a search across all imported elements for any old IDs in attributes (fill, 
stroke,
pattern, xlink:href come to mind immediately).  Not really very fun :)

Original comment by codedr...@gmail.com on 19 Jan 2010 at 9:45

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago

Original comment by codedr...@gmail.com on 27 Jan 2010 at 9:34

GoogleCodeExporter commented 9 years ago

Original comment by codedr...@gmail.com on 28 Jan 2010 at 1:29

GoogleCodeExporter commented 9 years ago

Original comment by codedr...@gmail.com on 28 Jan 2010 at 2:38

GoogleCodeExporter commented 9 years ago
Actually the prefix idea will not work, since the user could import the same 
file
multiple times into the drawing.  We will probably just have to flat-out 
replace all
IDs with the 'next id' in the existing drawing.  We still will have to be 
careful
about getting all the references right.

Original comment by codedr...@gmail.com on 29 Jan 2010 at 1:57

GoogleCodeExporter commented 9 years ago
Are we planning to allow the user to set the ID of elements later in the 
roadmap?
I refrained myself from filing an issue about this so far, but I think it would 
be
useful at some point, as many authors use the ID to later modify their files 
with
JavaScript or CSS and might need this rather than svg_xxx.

Re. the importing size... I don't think it's a real problem, since the nature 
of SVG
is scalable and since we now can draw outside the canvas, and adjust the canvas 
to
the content. 
I think having a "fixed" ratio for importing would require many calculations
beforehand, and wouldn't be what the user wants in most cases, anyway.
The only "problem" is the actual user unit of the imported SVG. Since we assume
pixels so far, what would happen if the imported SVG chunk has other units, 
like pt
or in or whatever?

Re. where to place the imported SVG, I think putting it on a new layer on its 
own is
fine, and it's fine on the selected layer as well - if we would import the whole
thing as a group.
I would place it right in the middle of the canvas (of the actual canvas), 
regardless
of the bit of the canvas seen by the user (when the canvas is being zoomed or
panned). If not in the middle, at the canvas origin (0,0), aka top-left.

K.I.S.S :-)

Original comment by worms_...@yahoo.com on 29 Jan 2010 at 5:48

GoogleCodeExporter commented 9 years ago
Lots of things in there, wormsxulla! :)

  * yes absolutely developers should be able to modify the id values one day (see
that object browser issue)
  * the problem is that the imported SVG might be many thousands of pixels width/high
- well outside the realm of sanity, even - basically i think this means we need 
to
set the size of the imported svg and I'm thinking maybe 1/2 or 1/3 the size of 
the
canvas is a good idea (it can always be resized after the import)
  * yes, definitely a new layer at the 'top' of the stack

Original comment by codedr...@gmail.com on 29 Jan 2010 at 5:52

GoogleCodeExporter commented 9 years ago
I see two options:

1) an import is basically add <svg> elements as children to the root <svg> 
directly.
 This means we have to be able to move, resize, rotate the <svg> elements.  Also,
what if the user wants to break up the imported SVG and customize it?  Do we 
also
provide an 'ungroup' option?

2) an import is basically take everything in the imported <svg> and add it to a 
new
<g> element.

My current thinking is along the lines of #2 at the moment.  Once I finish up 
adding
a few more things to the whitelist (tspan, pattern, symbol at least), I'll get
working on code for actual importing.

Original comment by codedr...@gmail.com on 2 Feb 2010 at 6:37

GoogleCodeExporter commented 9 years ago
Just thought I'd throw in my 2 cents worth on the ID replacement issue. When a 
user
uploads an SVG file to our image library, a script replaces them all with a 
globally
unique ID via:

function uuid() {
// The field names refer to RFC 4122 section 4.1.2

return sprintf('%04x%04x%04x%03x4%04x%04x%04x%04x',
mt_rand(0, 65535), mt_rand(0, 65535), // 32 bits for "time_low"
mt_rand(0, 65535), // 16 bits for "time_mid"
mt_rand(0, 4095),  // 12 bits before the 0100 of (version) 4 for 
time_hi_and_version"
bindec(substr_replace(sprintf('%016b', mt_rand(0, 65535)), '01', 6, 2)),
// 8 bits, the last two of which (positions 6 and 7) are 01, for 
"clk_seq_hi_res"
// (hence, the 2nd hex digit after the 3rd hyphen can only be 1, 5, 9 or d)
// 8 bits for "clk_seq_low"
mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535) // 48 bits for "node"
);
}

and a simple preg_match_all.

So far this has been working perfectly. I have been generating "contact sheets" 
of
all our illustrations by category and album and am yet to see a conflict.

Note sure if this approach is ideal for SVGEdit, but I like the idea that users 
who
save multiple illustrations from SVGEdit and then place these into the same 
file in
Illustrator or Inkscape, won't have to worry about conflicts.

Original comment by adrianbj...@gmail.com on 9 Feb 2010 at 12:58

GoogleCodeExporter commented 9 years ago
I encountered a bit of a roadblock here:  <svg> elements cannot be transformed. 
 This
means that we can't actually use them as elements you can move/resize/rotate.  
We can
wrap <svg> elements in <g> elements, but this means that upon ungrouping we 
need to
handle this case differently than normal ungrouping and still need to 
eventually deal
with viewBox.

I'm not thinking that, upon import, replacing the <svg> element with a <g> 
element
removing the width/height/viewBox attributes and replacing it with a transform 
that
sizes and positions the image correctly.

What do people think?

Original comment by codedr...@gmail.com on 20 Feb 2010 at 11:15

GoogleCodeExporter commented 9 years ago
As of r1423, this is starting to work a little.

Things broken in the rough order in which I plan to fix them:

 * imports directly into the current layer (will fix this soon so it imports into a
new layer)
 * does not re-identify all imported elements (so there could be duplicate IDs in the
document)
 * ignores the preserveAspectRatio attribute on the imported <svg>
 * won't handle percentages or other units on imported <svg>
 * imports into top-left of the canvas and at 1/3 the size of the canvas.  In
thinking about this, it's arguable that this should be the top-left of the 
currently
zoomed viewport and that the import size should be 1/3 of the viewport.\

Note that you can currently only import SVG into a drawing in browsers that 
support
the W3C File API (Firefox 3.6+).  See Issue 499 for ideas on how to let other 
browser
users import SVG into their drawings.

Original comment by codedr...@gmail.com on 21 Feb 2010 at 4:41

GoogleCodeExporter commented 9 years ago
Ok, as of r1427 the imported SVG elements are re-identified so the IDs in the 
drawing
should be unique.  I'm closing this issue now.

I dropped the idea of creating a new layer upon import as this might be
unnecessary/annoying to the user.  If the user wants to imported things put 
into a
new layer, they will have to create their own layer beforehand.

There are other things to take care of (units/percentages, 
preserveAspectRatio), but
I will handle these later.  Individual bugs with minimal test cases are welcome.

Note that SVG-edit support for arbitrary SVG is still pretty weak I'm noticing. 
Especially for content that has lots of transformations.  This means we will 
probably
have to go over recalculateDimensions() again.  Ugh!

Original comment by codedr...@gmail.com on 22 Feb 2010 at 2:54

GoogleCodeExporter commented 9 years ago
This issue notes several points regarding how SVGs should be imported. In 
comment #14, Jeff mentions two options, of which the second one was chosen 
(convert to group rather than leave as <svg> element). While I agree this made 
sense at the time, the biggest reason not to leave it as an <svg> element was 
the complexities involved in dealing with them.

For issue 71 I have added decent support for manipulating <svg> elements 
(indeed, by putting them in a "special" group element), and importing files 
from the library browser adds them that way. After that, they can be converted 
to a group using the "ungroup" button (I intend to change its tooltip for these 
cases to "convert to group" to avoid confusion).

So my suggestion is that we use the same method as in issue 71 for file-picked 
imported images, as that way all imports work consistently. I actually plan on 
changing that method too, by converting the <svg> to a <symbol> (really just 
changes the element's name), putting it in the <defs> and adding a <use> to the 
current layer. The <use> instance could still be converted to a group, so the 
user's experience wouldn't change. As adrianbjones mentioned, this would keep 
the file small whenever the image would be duplicated. 

Any objections or questions about this?

Original comment by adeve...@gmail.com on 22 Jul 2010 at 8:06

GoogleCodeExporter commented 9 years ago
I also realize that in the third paragraph there I basically negate the 
significance of the second paragraph...still, being able to support child <svg> 
elements will still be helpful for arbitrary import purposes. :) 

Original comment by adeve...@gmail.com on 22 Jul 2010 at 8:08