SVGImport.wiki
author kyberneticist@gmail.com
Mon, 25 Jun 2012 00:13:42 +0000
changeset 230 9584a3da2b87
parent 229 5c20e3d492e8
child 231 b5780c560285
permissions -rw-r--r--
Edited wiki page SVGImport through web user interface.

#summary Importing an SVG into Hedgewars

= Introduction =

This is a quick and dirty description of converting an SVG into hedgewars HWMAP format.  It is not at all pretty. Hopefully someone will make a prettier process.  It currently makes use of Inkscape, vim, perl, g++ and a bit of manual labour.  It looks best in 0.9.18 which makes use of the variable brush size (the examples below use the smallest size, or 16px wide)


= Details =

Open Inkscape.
Go to File->Inkscape Preferences and make sure that
    * SVG Output->Allow relative coordinates is unchecked
    * Transforms->Store transformation  is set to Optimized

Open an SVG. Ideally one of simple line art, without too much use of fill or filters.

1) Combine all paths in the drawing (select them, then choose Path->Combine). Note. I had some difficulty doing that with some images even after repeated use of ungroup. I ended up just going into the SVG file and deleting all the groups.
Also, some paths might be worth eliminating altogether.  In order to get a better idea of what it'll look like, try: View->Display Mode->Outline

2) select the combined path, and ungroup.

3) Click on the path, and choose dimensions for W and H that would look good in the game (no more than 4096 for W and 2048 for H).  The Lock button may be helpful here.

4) Go to File->Document Properties and choose Resize Page to Drawing or Selection.  You may want to then reposition the art to be more centred vertically or horizontally.

5) Save and Quit

6) Open in an editor and verify there is one path. change the path ID attribute to id="base" - this is to work around a bug in the current stable Inkscape extensions tool which was crashing it.

7) open the file in Inkscape again, Click on the path again, then go to Extensions->Modify Path->Flatten Beziers and flatten out the curves to your taste. Default of 10 seems fine.

8) Save and Quit again

9) Edit the file, and delete everything but the path data.  You should have a one-line file starting with something like  M1234.3 456.78L3298.3 9023.34 and so on.  The coordinates should now be rounded unless you plan to handle that yourself in some way.  Here is a vim one-liner to do it.
{{{:s/[0-9][0-9.]*/\=float2nr(floor(submatch(0)*1))/g}}}
If instead you have a format like M 1234.678,9875.323 2345.0,123.45  - you'll want to convert if you want to try the crude script in (10) - otherwise a smarter script would be needed.  Here's a Vim one-liner for that syntax {{{s/\(\d\) \(\d\)/\1 L\2/g}}}  and {{{s/,/ /g}}}

10) Convert the path data.  Here is a crude script to do that.
{{{
#!/usr/bin/perl
# just a one-line list of points. at least, it had better be one-line
open FILE, $ARGV[0];
while(<FILE>)
{
    chomp;
    s/([LM])(\d+) (\d+)\s*/point($1,$2,$3)/eg;
    print;
} 
sub point
{
    ($t, $x, $y) = @_;
    $x+=0;
    $y+=0; # just in case
    printf("%c%c%c%c%c",$x>>8,$x&0xff,$y>>8,$y&0xff,($t=~m/M/)?0x81:0x01);
    return;
}
}}}
{{{script pointdata > hwpointdata}}}

11) qCompress the data.
{{{g++ -I /usr/include/qt4 -I /usr/include/qt4/QtCore qcompress.cpp -lQtCore}}}
{{{
#include <QFile>
#include <QByteArray>
using namespace std;
int main(int argc, char **argv) 
{
    QFile fromFile(argv[1]);
    QFile toFile(argv[2]);
    if(fromFile.open(QIODevice::ReadOnly) && toFile.open(QIODevice::WriteOnly))
    {
        toFile.write(qCompress(fromFile.readAll()));
    }
}
}}}
{{{./a.out hwpointdata hwpointdata.Z}}}

12) Convert to base64 and you're done!

{{{base64 -w0 hwpointdata.Z > mynewhedgewars.hwmap}}}

Enjoy.

Here are some example hwmap files from the process above.  They look better in 0.9.18.
http://m8y.org/hw/drawn/