Search code examples
dictionarysvginkscape

Write an equivalent <svg> for a <image xlink:href="something.svg" />


Feel free to ask for more context if you're wondering why this is necessary, or want to suggest a better way to solve the bigger problem. (It involves laying out a bunch of building floor plans onto a campus map and finding the absolute location of certain things that are in those building maps; more detail was bogging the question down.)

The short version is that I want to take an SVG file that has <image xlink:href="something.svg" /> references and merge it into one big file with each referenced SVG being embedded with an <svg> and inline SVG XML content.

So, my top-level source file (composed in Inkscape) looks like this:

<image xlink:href="floorplans/bldg1.svg"
width="165.52684" height="107.10559" y="-1937.7657"
x="2507.1565" transform="matrix(0,1,-1,0,0,0)" />

And my attempt at a merged version to inline all the vector data:

<svg x="2507.1565" y="-1937.7657" width="165.52684" height="107.10559"
transform="matrix(0,1,-1,0,0,0)" viewBox="0 0 1224 792">
<g id="surface0">
<path style="fill:none;stroke-width:0.72;stroke-linecap:round;stroke-linejoin:round;stroke:rgb(0%,0%,0%);...

So, basically I'm using a script to replace <image> with <svg> and paste in the contents of the root <svg> of "floorplans/bldg1.svg". (Copying attributes from the <image> to the <svg>, and copying the viewBox attribute from the original <svg> to the new one.)

This technique worked for things that aren't rotated, but Chrome seems to be saying this particular element is off the top of the viewport. I'm new to SVG, but I'm thinking the order of the transformations isn't the same on the <svg> as it is on the <image>. Did I make a dumb mistake I'm not spotting, or is there more involved in converting an <image xlink:href="something.svg" transform=... /> to an <svg> with inline XML?

Thanks.


Solution

  • The transform attribute doesn't apply to the <svg> element according to the SVG specification. You can put the transform that was on the <image> element on the <g> element either outside or inside the <svg> instead.

    The reason for transform behaving this way is that the <svg> element sets up the coordinate system, and the transform depends on that (a question that would arise if it did apply is "should the transform be interpreted in the coordinate-space before or after the svg coordinate system is setup?")