[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

gEDA-cvs: pcb.git: branch: master updated (a096a8b84c1d0e2beb94a859bde9f2bc2799fe73)



The branch, master has been updated
       via  a096a8b84c1d0e2beb94a859bde9f2bc2799fe73 (commit)
       via  beb4c7c5626b8b28c0a203a23fb41f28e5662618 (commit)
       via  fd1c65c236bdcd4b36400e82074d66ab83bc5de3 (commit)
       via  b6378a3845066adb23601d8fa781fd58233176dd (commit)
       via  c544e63eca400b33127ac539e4737c7959e8db2c (commit)
       via  9babb216b2921ad716b740068988d04a0d9dfe45 (commit)
       via  0e008cb83dcfc4fc6a3455bdd3c8dd86ed65b374 (commit)
       via  290c968566837132afbfc63d5fe1436c03dcec1e (commit)
       via  073463e605095692e2cf8d4238df0c817e68e3c3 (commit)
       via  ca738957694927538dad15f037d5622571fd3173 (commit)
       via  7467c8b2cedb80ee32e2ff19662d6894a6d7f345 (commit)
       via  19f7443c3249a9cc40efd04c1895b89445add385 (commit)
       via  47edc12beab88ea5a6d7608e5741131eb5c0e8d4 (commit)
       via  e402b491c199d1df9808e129461d585346a03c9e (commit)
      from  b4ca96d312884a8bc2314e490c2c957ab590b427 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 INSTALL                                            |    3 +
 configure.ac                                       |   13 +-
 doc/pcb.1                                          |    5 +-
 src/Makefile.am                                    |   29 +-
 src/hid/gcode/auxiliary.h                          |   87 ++
 src/hid/gcode/bitmap.h                             |  116 ++
 src/hid/gcode/curve.c                              |  123 ++
 src/hid/gcode/curve.h                              |   79 +
 src/hid/gcode/decompose.c                          |  599 ++++++++
 src/hid/gcode/decompose.h                          |   16 +
 src/hid/gcode/gcode.c                              | 1100 +++++++++++++++
 src/hid/gcode/gcode.h                              |    3 +
 src/hid/{bom => gcode}/hid.conf                    |    0 
 src/hid/gcode/lists.h                              |  285 ++++
 src/hid/gcode/potracelib.h                         |  138 ++
 src/hid/gcode/trace.c                              | 1485 ++++++++++++++++++++
 src/hid/gcode/trace.h                              |   15 +
 tests/golden/Makefile.am                           |   12 +-
 tests/golden/hid_gcode1/Makefile.am                |    6 +
 .../golden/hid_gcode1/gcode_oneline.gcode.back.cnc |   34 +
 .../hid_gcode1/gcode_oneline.gcode.drill.cnc       |   12 +
 .../hid_gcode1/gcode_oneline.gcode.front.cnc       |   34 +
 tests/golden/hid_gcode10/Makefile.am               |    6 +
 .../hid_gcode10/gcode_oneline.gcode.back.cnc       |   34 +
 .../hid_gcode10/gcode_oneline.gcode.drill.cnc      |   12 +
 .../hid_gcode10/gcode_oneline.gcode.front.cnc      |   34 +
 tests/golden/hid_gcode11/Makefile.am               |    6 +
 .../hid_gcode11/gcode_oneline.gcode.back.cnc       |   49 +
 .../hid_gcode11/gcode_oneline.gcode.drill.cnc      |   12 +
 .../hid_gcode11/gcode_oneline.gcode.front.cnc      |   45 +
 tests/golden/hid_gcode2/Makefile.am                |    6 +
 tests/golden/hid_gcode2/out.back.cnc               |   34 +
 tests/golden/hid_gcode2/out.drill.cnc              |   12 +
 tests/golden/hid_gcode2/out.front.cnc              |   34 +
 tests/golden/hid_gcode3/Makefile.am                |    6 +
 .../golden/hid_gcode3/gcode_oneline.gcode.back.cnc |   40 +
 .../hid_gcode3/gcode_oneline.gcode.drill.cnc       |   12 +
 .../hid_gcode3/gcode_oneline.gcode.front.cnc       |   40 +
 tests/golden/hid_gcode4/Makefile.am                |    6 +
 .../golden/hid_gcode4/gcode_oneline.gcode.back.cnc |   34 +
 .../hid_gcode4/gcode_oneline.gcode.drill.cnc       |   12 +
 .../hid_gcode4/gcode_oneline.gcode.front.cnc       |   34 +
 tests/golden/hid_gcode5/Makefile.am                |    6 +
 .../golden/hid_gcode5/gcode_oneline.gcode.back.cnc |   34 +
 .../hid_gcode5/gcode_oneline.gcode.drill.cnc       |   12 +
 .../hid_gcode5/gcode_oneline.gcode.front.cnc       |   34 +
 tests/golden/hid_gcode6/Makefile.am                |    6 +
 .../golden/hid_gcode6/gcode_oneline.gcode.back.cnc |   43 +
 .../hid_gcode6/gcode_oneline.gcode.drill.cnc       |   12 +
 .../hid_gcode6/gcode_oneline.gcode.front.cnc       |   43 +
 tests/golden/hid_gcode7/Makefile.am                |    6 +
 .../golden/hid_gcode7/gcode_oneline.gcode.back.cnc |   34 +
 .../hid_gcode7/gcode_oneline.gcode.drill.cnc       |   12 +
 .../hid_gcode7/gcode_oneline.gcode.front.cnc       |   34 +
 tests/golden/hid_gcode8/Makefile.am                |    6 +
 .../golden/hid_gcode8/gcode_oneline.gcode.back.cnc |   34 +
 .../hid_gcode8/gcode_oneline.gcode.drill.cnc       |   12 +
 .../hid_gcode8/gcode_oneline.gcode.front.cnc       |   34 +
 tests/golden/hid_gcode9/Makefile.am                |    6 +
 .../golden/hid_gcode9/gcode_oneline.gcode.back.cnc |   34 +
 .../hid_gcode9/gcode_oneline.gcode.drill.cnc       |   12 +
 .../hid_gcode9/gcode_oneline.gcode.front.cnc       |   34 +
 .../{gerber_oneline.pcb => gcode_oneline.pcb}      |    0 
 tests/run_tests.sh                                 |   51 +-
 tests/tests.list                                   |   35 +-
 65 files changed, 5187 insertions(+), 9 deletions(-)
 create mode 100644 src/hid/gcode/auxiliary.h
 create mode 100644 src/hid/gcode/bitmap.h
 create mode 100644 src/hid/gcode/curve.c
 create mode 100644 src/hid/gcode/curve.h
 create mode 100644 src/hid/gcode/decompose.c
 create mode 100644 src/hid/gcode/decompose.h
 create mode 100644 src/hid/gcode/gcode.c
 create mode 100644 src/hid/gcode/gcode.h
 copy src/hid/{bom => gcode}/hid.conf (100%)
 create mode 100644 src/hid/gcode/lists.h
 create mode 100644 src/hid/gcode/potracelib.h
 create mode 100644 src/hid/gcode/trace.c
 create mode 100644 src/hid/gcode/trace.h
 create mode 100644 tests/golden/hid_gcode1/Makefile.am
 create mode 100644 tests/golden/hid_gcode1/gcode_oneline.gcode.back.cnc
 create mode 100644 tests/golden/hid_gcode1/gcode_oneline.gcode.drill.cnc
 create mode 100644 tests/golden/hid_gcode1/gcode_oneline.gcode.front.cnc
 create mode 100644 tests/golden/hid_gcode10/Makefile.am
 create mode 100644 tests/golden/hid_gcode10/gcode_oneline.gcode.back.cnc
 create mode 100644 tests/golden/hid_gcode10/gcode_oneline.gcode.drill.cnc
 create mode 100644 tests/golden/hid_gcode10/gcode_oneline.gcode.front.cnc
 create mode 100644 tests/golden/hid_gcode11/Makefile.am
 create mode 100644 tests/golden/hid_gcode11/gcode_oneline.gcode.back.cnc
 create mode 100644 tests/golden/hid_gcode11/gcode_oneline.gcode.drill.cnc
 create mode 100644 tests/golden/hid_gcode11/gcode_oneline.gcode.front.cnc
 create mode 100644 tests/golden/hid_gcode2/Makefile.am
 create mode 100644 tests/golden/hid_gcode2/out.back.cnc
 create mode 100644 tests/golden/hid_gcode2/out.drill.cnc
 create mode 100644 tests/golden/hid_gcode2/out.front.cnc
 create mode 100644 tests/golden/hid_gcode3/Makefile.am
 create mode 100644 tests/golden/hid_gcode3/gcode_oneline.gcode.back.cnc
 create mode 100644 tests/golden/hid_gcode3/gcode_oneline.gcode.drill.cnc
 create mode 100644 tests/golden/hid_gcode3/gcode_oneline.gcode.front.cnc
 create mode 100644 tests/golden/hid_gcode4/Makefile.am
 create mode 100644 tests/golden/hid_gcode4/gcode_oneline.gcode.back.cnc
 create mode 100644 tests/golden/hid_gcode4/gcode_oneline.gcode.drill.cnc
 create mode 100644 tests/golden/hid_gcode4/gcode_oneline.gcode.front.cnc
 create mode 100644 tests/golden/hid_gcode5/Makefile.am
 create mode 100644 tests/golden/hid_gcode5/gcode_oneline.gcode.back.cnc
 create mode 100644 tests/golden/hid_gcode5/gcode_oneline.gcode.drill.cnc
 create mode 100644 tests/golden/hid_gcode5/gcode_oneline.gcode.front.cnc
 create mode 100644 tests/golden/hid_gcode6/Makefile.am
 create mode 100644 tests/golden/hid_gcode6/gcode_oneline.gcode.back.cnc
 create mode 100644 tests/golden/hid_gcode6/gcode_oneline.gcode.drill.cnc
 create mode 100644 tests/golden/hid_gcode6/gcode_oneline.gcode.front.cnc
 create mode 100644 tests/golden/hid_gcode7/Makefile.am
 create mode 100644 tests/golden/hid_gcode7/gcode_oneline.gcode.back.cnc
 create mode 100644 tests/golden/hid_gcode7/gcode_oneline.gcode.drill.cnc
 create mode 100644 tests/golden/hid_gcode7/gcode_oneline.gcode.front.cnc
 create mode 100644 tests/golden/hid_gcode8/Makefile.am
 create mode 100644 tests/golden/hid_gcode8/gcode_oneline.gcode.back.cnc
 create mode 100644 tests/golden/hid_gcode8/gcode_oneline.gcode.drill.cnc
 create mode 100644 tests/golden/hid_gcode8/gcode_oneline.gcode.front.cnc
 create mode 100644 tests/golden/hid_gcode9/Makefile.am
 create mode 100644 tests/golden/hid_gcode9/gcode_oneline.gcode.back.cnc
 create mode 100644 tests/golden/hid_gcode9/gcode_oneline.gcode.drill.cnc
 create mode 100644 tests/golden/hid_gcode9/gcode_oneline.gcode.front.cnc
 copy tests/inputs/{gerber_oneline.pcb => gcode_oneline.pcb} (100%)


=================
 Commit Messages
=================

commit a096a8b84c1d0e2beb94a859bde9f2bc2799fe73
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Make the xy file check actually do something.

:100755 100755 0667fb8... 5320c54... M	tests/run_tests.sh

commit beb4c7c5626b8b28c0a203a23fb41f28e5662618
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Add testsuite entries to test the gcode export HID and all of its
    command line options.

:100644 100644 356e02e... 3f8ed62... M	configure.ac
:100644 100644 1c7afa2... de5bb08... M	tests/golden/Makefile.am
:000000 100644 0000000... b071e19... A	tests/golden/hid_gcode1/Makefile.am
:000000 100644 0000000... 2031270... A	tests/golden/hid_gcode1/gcode_oneline.gcode.back.cnc
:000000 100644 0000000... 63f6a2d... A	tests/golden/hid_gcode1/gcode_oneline.gcode.drill.cnc
:000000 100644 0000000... afd6cb2... A	tests/golden/hid_gcode1/gcode_oneline.gcode.front.cnc
:000000 100644 0000000... b071e19... A	tests/golden/hid_gcode10/Makefile.am
:000000 100644 0000000... 19a703d... A	tests/golden/hid_gcode10/gcode_oneline.gcode.back.cnc
:000000 100644 0000000... 7deace0... A	tests/golden/hid_gcode10/gcode_oneline.gcode.drill.cnc
:000000 100644 0000000... a1d48bd... A	tests/golden/hid_gcode10/gcode_oneline.gcode.front.cnc
:000000 100644 0000000... b071e19... A	tests/golden/hid_gcode11/Makefile.am
:000000 100644 0000000... c144b05... A	tests/golden/hid_gcode11/gcode_oneline.gcode.back.cnc
:000000 100644 0000000... 37b9668... A	tests/golden/hid_gcode11/gcode_oneline.gcode.drill.cnc
:000000 100644 0000000... ddf7394... A	tests/golden/hid_gcode11/gcode_oneline.gcode.front.cnc
:000000 100644 0000000... a757c9e... A	tests/golden/hid_gcode2/Makefile.am
:000000 100644 0000000... c3b0526... A	tests/golden/hid_gcode2/out.back.cnc
:000000 100644 0000000... f7c6d78... A	tests/golden/hid_gcode2/out.drill.cnc
:000000 100644 0000000... ca2b079... A	tests/golden/hid_gcode2/out.front.cnc
:000000 100644 0000000... b071e19... A	tests/golden/hid_gcode3/Makefile.am
:000000 100644 0000000... e67b085... A	tests/golden/hid_gcode3/gcode_oneline.gcode.back.cnc
:000000 100644 0000000... e7be01d... A	tests/golden/hid_gcode3/gcode_oneline.gcode.drill.cnc
:000000 100644 0000000... d7c8c9f... A	tests/golden/hid_gcode3/gcode_oneline.gcode.front.cnc
:000000 100644 0000000... b071e19... A	tests/golden/hid_gcode4/Makefile.am
:000000 100644 0000000... d049972... A	tests/golden/hid_gcode4/gcode_oneline.gcode.back.cnc
:000000 100644 0000000... c648655... A	tests/golden/hid_gcode4/gcode_oneline.gcode.drill.cnc
:000000 100644 0000000... 78e64a5... A	tests/golden/hid_gcode4/gcode_oneline.gcode.front.cnc
:000000 100644 0000000... b071e19... A	tests/golden/hid_gcode5/Makefile.am
:000000 100644 0000000... 8041f98... A	tests/golden/hid_gcode5/gcode_oneline.gcode.back.cnc
:000000 100644 0000000... 77d8d60... A	tests/golden/hid_gcode5/gcode_oneline.gcode.drill.cnc
:000000 100644 0000000... e3bbd7e... A	tests/golden/hid_gcode5/gcode_oneline.gcode.front.cnc
:000000 100644 0000000... b071e19... A	tests/golden/hid_gcode6/Makefile.am
:000000 100644 0000000... 7d33799... A	tests/golden/hid_gcode6/gcode_oneline.gcode.back.cnc
:000000 100644 0000000... 6b44265... A	tests/golden/hid_gcode6/gcode_oneline.gcode.drill.cnc
:000000 100644 0000000... 7dfd6a0... A	tests/golden/hid_gcode6/gcode_oneline.gcode.front.cnc
:000000 100644 0000000... b071e19... A	tests/golden/hid_gcode7/Makefile.am
:000000 100644 0000000... b92e532... A	tests/golden/hid_gcode7/gcode_oneline.gcode.back.cnc
:000000 100644 0000000... e8c41bf... A	tests/golden/hid_gcode7/gcode_oneline.gcode.drill.cnc
:000000 100644 0000000... 4c64804... A	tests/golden/hid_gcode7/gcode_oneline.gcode.front.cnc
:000000 100644 0000000... b071e19... A	tests/golden/hid_gcode8/Makefile.am
:000000 100644 0000000... 286cab5... A	tests/golden/hid_gcode8/gcode_oneline.gcode.back.cnc
:000000 100644 0000000... 77ac526... A	tests/golden/hid_gcode8/gcode_oneline.gcode.drill.cnc
:000000 100644 0000000... a57aeb7... A	tests/golden/hid_gcode8/gcode_oneline.gcode.front.cnc
:000000 100644 0000000... b071e19... A	tests/golden/hid_gcode9/Makefile.am
:000000 100644 0000000... 49ebcd5... A	tests/golden/hid_gcode9/gcode_oneline.gcode.back.cnc
:000000 100644 0000000... c4b730a... A	tests/golden/hid_gcode9/gcode_oneline.gcode.drill.cnc
:000000 100644 0000000... 638cec1... A	tests/golden/hid_gcode9/gcode_oneline.gcode.front.cnc
:000000 100644 0000000... c20eacf... A	tests/inputs/gcode_oneline.pcb
:100755 100755 3892856... 0667fb8... M	tests/run_tests.sh
:100644 100644 8949763... 95af71d... M	tests/tests.list

commit fd1c65c236bdcd4b36400e82074d66ab83bc5de3
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Remove RCSID.  We don't use those anymore.

:100644 100644 3767ad4... bbc1d53... M	src/hid/gcode/gcode.c

commit b6378a3845066adb23601d8fa781fd58233176dd
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Change options like 'drill depth' to 'drill-depth' as a space in
    a command line option is non-standard.  Also be consistent with
    having or not having a "." at the end of the option help strings.

:100644 100644 c5ca8df... 3767ad4... M	src/hid/gcode/gcode.c

commit c544e63eca400b33127ac539e4737c7959e8db2c
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Remove unix2dos system() call.  It was not needed.

:100644 100644 317e6a1... c5ca8df... M	src/hid/gcode/gcode.c

commit 9babb216b2921ad716b740068988d04a0d9dfe45
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Get rid of compiler warnings.

:100644 100644 5f1c48e... 8d7e5e6... M	src/hid/gcode/trace.c

commit 0e008cb83dcfc4fc6a3455bdd3c8dd86ed65b374
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Get rid of some gcc warnings.

:100644 100644 6d022ce... 317e6a1... M	src/hid/gcode/gcode.c

commit 290c968566837132afbfc63d5fe1436c03dcec1e
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    C++ style comments -> C style comments

:100644 100644 e8c38db... 6d022ce... M	src/hid/gcode/gcode.c

commit 073463e605095692e2cf8d4238df0c817e68e3c3
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Fix nroff error.   Noted in sf patch #2889227 by Ahmed El-Mahmoudy.

:100644 100644 3dd9867... b84c653... M	doc/pcb.1

commit ca738957694927538dad15f037d5622571fd3173
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    add the gcode exporter to the export hid list

:100644 100644 d5578fb... 356e02e... M	configure.ac

commit 7467c8b2cedb80ee32e2ff19662d6894a6d7f345
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    add notes about what libs may be needed (none) for the gcode exporter.

:100644 100644 1dfa0f8... db27639... M	INSTALL

commit 19f7443c3249a9cc40efd04c1895b89445add385
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    indent to conform to the coding style used by pcb.

:100644 100644 7baab85... 254e4c0... M	src/hid/gcode/auxiliary.h
:100644 100644 2a172b1... 589b80b... M	src/hid/gcode/bitmap.h
:100644 100644 0dc1005... abf85d7... M	src/hid/gcode/curve.c
:100644 100644 45c0790... 6f7e8a1... M	src/hid/gcode/curve.h
:100644 100644 abc5e0a... 0b42882... M	src/hid/gcode/decompose.c
:100644 100644 d5be99c... 333003e... M	src/hid/gcode/decompose.h
:100644 100644 5792d0c... e8c38db... M	src/hid/gcode/gcode.c
:100644 100644 352cbd9... ae9d7a0... M	src/hid/gcode/gcode.h
:100644 100644 931cbb0... 2a2353f... M	src/hid/gcode/lists.h
:100644 100644 0b93d65... 2456c01... M	src/hid/gcode/potracelib.h
:100644 100644 2c615e6... 5f1c48e... M	src/hid/gcode/trace.c
:100644 100644 4a9683c... 2a07e61... M	src/hid/gcode/trace.h

commit 47edc12beab88ea5a6d7608e5741131eb5c0e8d4
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    gcode_lists.h should depend on gcode sources, not png sources.

:100644 100644 371173a... a5441d6... M	src/Makefile.am

commit e402b491c199d1df9808e129461d585346a03c9e
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Apply sf patch 2948711 from Alberto Maccioni which adds a g-code
    exporter.

:000000 100644 0000000... 7baab85... A	src/hid/gcode/auxiliary.h
:000000 100644 0000000... 2a172b1... A	src/hid/gcode/bitmap.h
:000000 100644 0000000... 0dc1005... A	src/hid/gcode/curve.c
:000000 100644 0000000... 45c0790... A	src/hid/gcode/curve.h
:000000 100644 0000000... abc5e0a... A	src/hid/gcode/decompose.c
:000000 100644 0000000... d5be99c... A	src/hid/gcode/decompose.h
:000000 100644 0000000... 5792d0c... A	src/hid/gcode/gcode.c
:000000 100644 0000000... 352cbd9... A	src/hid/gcode/gcode.h
:000000 100644 0000000... 7be6c4c... A	src/hid/gcode/hid.conf
:000000 100644 0000000... 931cbb0... A	src/hid/gcode/lists.h
:000000 100644 0000000... 0b93d65... A	src/hid/gcode/potracelib.h
:000000 100644 0000000... 2c615e6... A	src/hid/gcode/trace.c
:000000 100644 0000000... 4a9683c... A	src/hid/gcode/trace.h

=========
 Changes
=========

commit a096a8b84c1d0e2beb94a859bde9f2bc2799fe73
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Make the xy file check actually do something.

diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 0667fb8..5320c54 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -347,10 +347,24 @@ compare_bom() {
 # X-Y (centroid) comparison routines
 #
 
+# used to remove things like creation date from BOM files
+normalize_xy() {
+    f1="$1"
+    f2="$2"
+    $AWK '
+	/^# Date:/ {print "# Date: today"; next}
+	/^# Author:/ {print "# Author: PCB"; next}
+	{print}' \
+	$f1 > $f2
+}
+
 compare_xy() {
     f1="$1"
     f2="$2"
     compare_check "compare_xy" "$f1" "$f2" || return 1
+    normalize_xy "$f1" "$cf1"
+    normalize_xy "$f2" "$cf2"
+    run_diff "$cf1" "$cf2" || test_failed=yes
 }
 
 ##########################################################################

commit beb4c7c5626b8b28c0a203a23fb41f28e5662618
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Add testsuite entries to test the gcode export HID and all of its
    command line options.

diff --git a/configure.ac b/configure.ac
index 356e02e..3f8ed62 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1152,6 +1152,17 @@ AC_CONFIG_FILES(tests/golden/hid_bom1/Makefile)
 AC_CONFIG_FILES(tests/golden/hid_bom2/Makefile)
 AC_CONFIG_FILES(tests/golden/hid_bom3/Makefile)
 AC_CONFIG_FILES(tests/golden/hid_bom4/Makefile)
+AC_CONFIG_FILES(tests/golden/hid_gcode1/Makefile)
+AC_CONFIG_FILES(tests/golden/hid_gcode2/Makefile)
+AC_CONFIG_FILES(tests/golden/hid_gcode3/Makefile)
+AC_CONFIG_FILES(tests/golden/hid_gcode4/Makefile)
+AC_CONFIG_FILES(tests/golden/hid_gcode5/Makefile)
+AC_CONFIG_FILES(tests/golden/hid_gcode6/Makefile)
+AC_CONFIG_FILES(tests/golden/hid_gcode7/Makefile)
+AC_CONFIG_FILES(tests/golden/hid_gcode8/Makefile)
+AC_CONFIG_FILES(tests/golden/hid_gcode9/Makefile)
+AC_CONFIG_FILES(tests/golden/hid_gcode10/Makefile)
+AC_CONFIG_FILES(tests/golden/hid_gcode11/Makefile)
 AC_CONFIG_FILES(tests/golden/hid_gerber1/Makefile)
 AC_CONFIG_FILES(tests/golden/hid_gerber2/Makefile)
 AC_CONFIG_FILES(tests/golden/hid_png1/Makefile)
diff --git a/tests/golden/Makefile.am b/tests/golden/Makefile.am
index 1c7afa2..de5bb08 100644
--- a/tests/golden/Makefile.am
+++ b/tests/golden/Makefile.am
@@ -5,7 +5,17 @@ SUBDIRS=	\
 	hid_bom2 \
 	hid_bom3 \
 	hid_bom4 \
+	hid_gcode1 \
+	hid_gcode2 \
+	hid_gcode3 \
+	hid_gcode4 \
+	hid_gcode5 \
+	hid_gcode6 \
+	hid_gcode7 \
+	hid_gcode8 \
+	hid_gcode9 \
+	hid_gcode10 \
+	hid_gcode11 \
 	hid_gerber1 \
 	hid_gerber2 \
 	hid_png1
-
diff --git a/tests/golden/hid_gcode1/Makefile.am b/tests/golden/hid_gcode1/Makefile.am
new file mode 100644
index 0000000..b071e19
--- /dev/null
+++ b/tests/golden/hid_gcode1/Makefile.am
@@ -0,0 +1,6 @@
+## -*- makefile -*-
+
+EXTRA_DIST= \
+	gcode_oneline.gcode.back.cnc \
+	gcode_oneline.gcode.drill.cnc \
+	gcode_oneline.gcode.front.cnc
diff --git a/tests/golden/hid_gcode1/gcode_oneline.gcode.back.cnc b/tests/golden/hid_gcode1/gcode_oneline.gcode.back.cnc
new file mode 100644
index 0000000..2031270
--- /dev/null
+++ b/tests/golden/hid_gcode1/gcode_oneline.gcode.back.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:31:54 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X27.770667 Y13.546667    (start point)
+G1 Z#101
+G1 X27.559000 Y13.462000
+G1 X27.305000 Y13.292667
+G1 X7.450667 Y13.292667
+G1 X7.196667 Y13.081000
+G1 X6.985000 Y12.827000
+G1 X6.985000 Y12.530667
+G1 X7.196667 Y12.276667
+G1 X7.450667 Y12.065000
+G1 X27.305000 Y12.065000
+G1 X27.643667 Y11.853333
+G1 X28.194000 Y11.853333
+G1 X28.532667 Y12.065000
+G1 X28.744333 Y12.403667
+G1 X28.744333 Y12.954000
+G1 X28.532667 Y13.292667
+G1 X28.194000 Y13.504333
+G1 X27.770667 Y13.546667
+G0 Z#100
+(polygon end, distance 45.38)
+(end, total distance 45.38mm = 1.79in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode1/gcode_oneline.gcode.drill.cnc b/tests/golden/hid_gcode1/gcode_oneline.gcode.drill.cnc
new file mode 100644
index 0000000..63f6a2d
--- /dev/null
+++ b/tests/golden/hid_gcode1/gcode_oneline.gcode.drill.cnc
@@ -0,0 +1,12 @@
+(Created by G-code exporter)
+(drill file: 1 drills)
+( Tue Mar  9 17:31:54 2010 )
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-2.000000  (drill depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G81 X27.940000 Y12.700000 Z#101 R#100
+M5 M9 M2
+(end, total distance 0.00mm = 0.00in)
diff --git a/tests/golden/hid_gcode1/gcode_oneline.gcode.front.cnc b/tests/golden/hid_gcode1/gcode_oneline.gcode.front.cnc
new file mode 100644
index 0000000..afd6cb2
--- /dev/null
+++ b/tests/golden/hid_gcode1/gcode_oneline.gcode.front.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:31:51 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X22.733000 Y13.546667    (start point)
+G1 Z#101
+G1 X22.521333 Y13.462000
+G1 X22.267333 Y13.292667
+G1 X2.413000 Y13.292667
+G1 X2.159000 Y13.081000
+G1 X1.947333 Y12.827000
+G1 X1.947333 Y12.530667
+G1 X2.159000 Y12.276667
+G1 X2.413000 Y12.065000
+G1 X22.267333 Y12.065000
+G1 X22.606000 Y11.853333
+G1 X23.156333 Y11.853333
+G1 X23.495000 Y12.065000
+G1 X23.706667 Y12.403667
+G1 X23.706667 Y12.954000
+G1 X23.495000 Y13.292667
+G1 X23.156333 Y13.504333
+G1 X22.733000 Y13.546667
+G0 Z#100
+(polygon end, distance 45.38)
+(end, total distance 45.38mm = 1.79in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode10/Makefile.am b/tests/golden/hid_gcode10/Makefile.am
new file mode 100644
index 0000000..b071e19
--- /dev/null
+++ b/tests/golden/hid_gcode10/Makefile.am
@@ -0,0 +1,6 @@
+## -*- makefile -*-
+
+EXTRA_DIST= \
+	gcode_oneline.gcode.back.cnc \
+	gcode_oneline.gcode.drill.cnc \
+	gcode_oneline.gcode.front.cnc
diff --git a/tests/golden/hid_gcode10/gcode_oneline.gcode.back.cnc b/tests/golden/hid_gcode10/gcode_oneline.gcode.back.cnc
new file mode 100644
index 0000000..19a703d
--- /dev/null
+++ b/tests/golden/hid_gcode10/gcode_oneline.gcode.back.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:45:32 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=0.002000  (safe Z)
+#101=-0.000050  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X27.770667 Y13.462000    (start point)
+G1 Z#101
+G1 X27.516667 Y13.335000
+G1 X27.347333 Y13.208000
+G1 X7.408333 Y13.165667
+G1 X7.112000 Y12.869333
+G1 X7.112000 Y12.488333
+G1 X7.408333 Y12.192000
+G1 X27.347333 Y12.149667
+G1 X27.643667 Y11.938000
+G1 X27.940000 Y11.895667
+G1 X28.278667 Y11.980333
+G1 X28.532667 Y12.192000
+G1 X28.702000 Y12.530667
+G1 X28.702000 Y12.827000
+G1 X28.532667 Y13.165667
+G1 X28.321000 Y13.335000
+G1 X28.024667 Y13.462000
+G1 X27.770667 Y13.462000
+G0 Z#100
+(polygon end, distance 44.84)
+(end, total distance 44.84mm = 1.77in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode10/gcode_oneline.gcode.drill.cnc b/tests/golden/hid_gcode10/gcode_oneline.gcode.drill.cnc
new file mode 100644
index 0000000..7deace0
--- /dev/null
+++ b/tests/golden/hid_gcode10/gcode_oneline.gcode.drill.cnc
@@ -0,0 +1,12 @@
+(Created by G-code exporter)
+(drill file: 1 drills)
+( Tue Mar  9 17:45:32 2010 )
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=0.002000  (safe Z)
+#101=-0.002000  (drill depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G81 X27.940000 Y12.700000 Z#101 R#100
+M5 M9 M2
+(end, total distance 0.00mm = 0.00in)
diff --git a/tests/golden/hid_gcode10/gcode_oneline.gcode.front.cnc b/tests/golden/hid_gcode10/gcode_oneline.gcode.front.cnc
new file mode 100644
index 0000000..a1d48bd
--- /dev/null
+++ b/tests/golden/hid_gcode10/gcode_oneline.gcode.front.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:45:28 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=0.002000  (safe Z)
+#101=-0.000050  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X22.733000 Y13.462000    (start point)
+G1 Z#101
+G1 X22.479000 Y13.335000
+G1 X22.309667 Y13.208000
+G1 X2.370667 Y13.165667
+G1 X2.074333 Y12.869333
+G1 X2.074333 Y12.488333
+G1 X2.370667 Y12.192000
+G1 X22.309667 Y12.149667
+G1 X22.606000 Y11.938000
+G1 X22.902333 Y11.895667
+G1 X23.241000 Y11.980333
+G1 X23.495000 Y12.192000
+G1 X23.664333 Y12.530667
+G1 X23.664333 Y12.827000
+G1 X23.495000 Y13.165667
+G1 X23.283333 Y13.335000
+G1 X22.987000 Y13.462000
+G1 X22.733000 Y13.462000
+G0 Z#100
+(polygon end, distance 44.84)
+(end, total distance 44.84mm = 1.77in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode11/Makefile.am b/tests/golden/hid_gcode11/Makefile.am
new file mode 100644
index 0000000..b071e19
--- /dev/null
+++ b/tests/golden/hid_gcode11/Makefile.am
@@ -0,0 +1,6 @@
+## -*- makefile -*-
+
+EXTRA_DIST= \
+	gcode_oneline.gcode.back.cnc \
+	gcode_oneline.gcode.drill.cnc \
+	gcode_oneline.gcode.front.cnc
diff --git a/tests/golden/hid_gcode11/gcode_oneline.gcode.back.cnc b/tests/golden/hid_gcode11/gcode_oneline.gcode.back.cnc
new file mode 100644
index 0000000..c144b05
--- /dev/null
+++ b/tests/golden/hid_gcode11/gcode_oneline.gcode.back.cnc
@@ -0,0 +1,49 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:45:55 2010 )
+(600 dpi)
+(Unit: inch)
+(Board size: 2.00x1.00 inches)
+#100=2.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G20 G90 G64 P0.003 M3 S3000 M7 F1
+G0 Z#100
+(polygon 1)
+G0 X1.085000 Y0.630000    (start point)
+G1 Z#101
+G1 X1.063333 Y0.625000
+G1 X1.055000 Y0.621667
+G1 X0.276667 Y0.618333
+G1 X0.251667 Y0.610000
+G1 X0.230000 Y0.598333
+G1 X0.200000 Y0.568333
+G1 X0.188333 Y0.546667
+G1 X0.180000 Y0.521667
+G1 X0.180000 Y0.476667
+G1 X0.188333 Y0.451667
+G1 X0.200000 Y0.430000
+G1 X0.230000 Y0.400000
+G1 X0.251667 Y0.388333
+G1 X0.276667 Y0.380000
+G1 X1.055000 Y0.376667
+G1 X1.068333 Y0.371667
+G1 X1.093333 Y0.368333
+G1 X1.121667 Y0.370000
+G1 X1.140000 Y0.375000
+G1 X1.171667 Y0.390000
+G1 X1.191667 Y0.406667
+G1 X1.208333 Y0.426667
+G1 X1.223333 Y0.458333
+G1 X1.228333 Y0.478333
+G1 X1.228333 Y0.520000
+G1 X1.223333 Y0.540000
+G1 X1.208333 Y0.571667
+G1 X1.191667 Y0.591667
+G1 X1.171667 Y0.608333
+G1 X1.140000 Y0.623333
+G1 X1.121667 Y0.628333
+G1 X1.085000 Y0.630000
+G0 Z#100
+(polygon end, distance 2.39)
+(end, total distance 60.74mm = 2.39in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode11/gcode_oneline.gcode.drill.cnc b/tests/golden/hid_gcode11/gcode_oneline.gcode.drill.cnc
new file mode 100644
index 0000000..37b9668
--- /dev/null
+++ b/tests/golden/hid_gcode11/gcode_oneline.gcode.drill.cnc
@@ -0,0 +1,12 @@
+(Created by G-code exporter)
+(drill file: 1 drills)
+( Tue Mar  9 17:45:55 2010 )
+(Unit: inch)
+(Board size: 2.00x1.00 inches)
+#100=2.000000  (safe Z)
+#101=-2.000000  (drill depth)
+(---------------------------------)
+G17 G20 G90 G64 P0.003 M3 S3000 M7 F1
+G81 X1.100000 Y0.500000 Z#101 R#100
+M5 M9 M2
+(end, total distance 0.00mm = 0.00in)
diff --git a/tests/golden/hid_gcode11/gcode_oneline.gcode.front.cnc b/tests/golden/hid_gcode11/gcode_oneline.gcode.front.cnc
new file mode 100644
index 0000000..ddf7394
--- /dev/null
+++ b/tests/golden/hid_gcode11/gcode_oneline.gcode.front.cnc
@@ -0,0 +1,45 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:45:43 2010 )
+(600 dpi)
+(Unit: inch)
+(Board size: 2.00x1.00 inches)
+#100=2.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G20 G90 G64 P0.003 M3 S3000 M7 F1
+G0 Z#100
+(polygon 1)
+G0 X0.886667 Y0.630000    (start point)
+G1 Z#101
+G1 X0.865000 Y0.625000
+G1 X0.856667 Y0.621667
+G1 X0.078333 Y0.618333
+G1 X0.053333 Y0.610000
+G1 X0.031667 Y0.598333
+G1 X0.000000 Y0.566667
+G1 X0.000000 Y0.431667
+G1 X0.031667 Y0.400000
+G1 X0.053333 Y0.388333
+G1 X0.078333 Y0.380000
+G1 X0.856667 Y0.376667
+G1 X0.870000 Y0.371667
+G1 X0.895000 Y0.368333
+G1 X0.923333 Y0.370000
+G1 X0.941667 Y0.375000
+G1 X0.973333 Y0.390000
+G1 X0.993333 Y0.406667
+G1 X1.010000 Y0.426667
+G1 X1.025000 Y0.458333
+G1 X1.030000 Y0.478333
+G1 X1.030000 Y0.520000
+G1 X1.025000 Y0.540000
+G1 X1.010000 Y0.571667
+G1 X0.993333 Y0.591667
+G1 X0.973333 Y0.608333
+G1 X0.941667 Y0.623333
+G1 X0.923333 Y0.628333
+G1 X0.886667 Y0.630000
+G0 Z#100
+(polygon end, distance 2.38)
+(end, total distance 60.56mm = 2.38in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode2/Makefile.am b/tests/golden/hid_gcode2/Makefile.am
new file mode 100644
index 0000000..a757c9e
--- /dev/null
+++ b/tests/golden/hid_gcode2/Makefile.am
@@ -0,0 +1,6 @@
+## -*- makefile -*-
+
+EXTRA_DIST= \
+	out.back.cnc \
+	out.drill.cnc \
+	out.front.cnc
diff --git a/tests/golden/hid_gcode2/out.back.cnc b/tests/golden/hid_gcode2/out.back.cnc
new file mode 100644
index 0000000..c3b0526
--- /dev/null
+++ b/tests/golden/hid_gcode2/out.back.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:35:19 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X27.770667 Y13.546667    (start point)
+G1 Z#101
+G1 X27.559000 Y13.462000
+G1 X27.305000 Y13.292667
+G1 X7.450667 Y13.292667
+G1 X7.196667 Y13.081000
+G1 X6.985000 Y12.827000
+G1 X6.985000 Y12.530667
+G1 X7.196667 Y12.276667
+G1 X7.450667 Y12.065000
+G1 X27.305000 Y12.065000
+G1 X27.643667 Y11.853333
+G1 X28.194000 Y11.853333
+G1 X28.532667 Y12.065000
+G1 X28.744333 Y12.403667
+G1 X28.744333 Y12.954000
+G1 X28.532667 Y13.292667
+G1 X28.194000 Y13.504333
+G1 X27.770667 Y13.546667
+G0 Z#100
+(polygon end, distance 45.38)
+(end, total distance 45.38mm = 1.79in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode2/out.drill.cnc b/tests/golden/hid_gcode2/out.drill.cnc
new file mode 100644
index 0000000..f7c6d78
--- /dev/null
+++ b/tests/golden/hid_gcode2/out.drill.cnc
@@ -0,0 +1,12 @@
+(Created by G-code exporter)
+(drill file: 1 drills)
+( Tue Mar  9 17:35:19 2010 )
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-2.000000  (drill depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G81 X27.940000 Y12.700000 Z#101 R#100
+M5 M9 M2
+(end, total distance 0.00mm = 0.00in)
diff --git a/tests/golden/hid_gcode2/out.front.cnc b/tests/golden/hid_gcode2/out.front.cnc
new file mode 100644
index 0000000..ca2b079
--- /dev/null
+++ b/tests/golden/hid_gcode2/out.front.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:35:16 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X22.733000 Y13.546667    (start point)
+G1 Z#101
+G1 X22.521333 Y13.462000
+G1 X22.267333 Y13.292667
+G1 X2.413000 Y13.292667
+G1 X2.159000 Y13.081000
+G1 X1.947333 Y12.827000
+G1 X1.947333 Y12.530667
+G1 X2.159000 Y12.276667
+G1 X2.413000 Y12.065000
+G1 X22.267333 Y12.065000
+G1 X22.606000 Y11.853333
+G1 X23.156333 Y11.853333
+G1 X23.495000 Y12.065000
+G1 X23.706667 Y12.403667
+G1 X23.706667 Y12.954000
+G1 X23.495000 Y13.292667
+G1 X23.156333 Y13.504333
+G1 X22.733000 Y13.546667
+G0 Z#100
+(polygon end, distance 45.38)
+(end, total distance 45.38mm = 1.79in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode3/Makefile.am b/tests/golden/hid_gcode3/Makefile.am
new file mode 100644
index 0000000..b071e19
--- /dev/null
+++ b/tests/golden/hid_gcode3/Makefile.am
@@ -0,0 +1,6 @@
+## -*- makefile -*-
+
+EXTRA_DIST= \
+	gcode_oneline.gcode.back.cnc \
+	gcode_oneline.gcode.drill.cnc \
+	gcode_oneline.gcode.front.cnc
diff --git a/tests/golden/hid_gcode3/gcode_oneline.gcode.back.cnc b/tests/golden/hid_gcode3/gcode_oneline.gcode.back.cnc
new file mode 100644
index 0000000..e67b085
--- /dev/null
+++ b/tests/golden/hid_gcode3/gcode_oneline.gcode.back.cnc
@@ -0,0 +1,40 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:36:04 2010 )
+(1200 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X27.813000 Y13.546667    (start point)
+G1 Z#101
+G1 X27.664833 Y13.504333
+G1 X27.453167 Y13.398500
+G1 X27.326167 Y13.292667
+G1 X7.535333 Y13.292667
+G1 X7.323667 Y13.229167
+G1 X7.069667 Y12.975167
+G1 X7.006167 Y12.763500
+G1 X7.006167 Y12.615333
+G1 X7.069667 Y12.403667
+G1 X7.323667 Y12.149667
+G1 X7.535333 Y12.086167
+G1 X27.326167 Y12.086167
+G1 X27.495500 Y11.959167
+G1 X27.728333 Y11.853333
+G1 X28.130500 Y11.853333
+G1 X28.448000 Y12.001500
+G1 X28.638500 Y12.213167
+G1 X28.765500 Y12.488333
+G1 X28.765500 Y12.890500
+G1 X28.638500 Y13.165667
+G1 X28.448000 Y13.377333
+G1 X28.130500 Y13.525500
+G1 X27.813000 Y13.546667
+G0 Z#100
+(polygon end, distance 45.35)
+(end, total distance 45.35mm = 1.79in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode3/gcode_oneline.gcode.drill.cnc b/tests/golden/hid_gcode3/gcode_oneline.gcode.drill.cnc
new file mode 100644
index 0000000..e7be01d
--- /dev/null
+++ b/tests/golden/hid_gcode3/gcode_oneline.gcode.drill.cnc
@@ -0,0 +1,12 @@
+(Created by G-code exporter)
+(drill file: 1 drills)
+( Tue Mar  9 17:36:04 2010 )
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-2.000000  (drill depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G81 X27.940000 Y12.700000 Z#101 R#100
+M5 M9 M2
+(end, total distance 0.00mm = 0.00in)
diff --git a/tests/golden/hid_gcode3/gcode_oneline.gcode.front.cnc b/tests/golden/hid_gcode3/gcode_oneline.gcode.front.cnc
new file mode 100644
index 0000000..d7c8c9f
--- /dev/null
+++ b/tests/golden/hid_gcode3/gcode_oneline.gcode.front.cnc
@@ -0,0 +1,40 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:35:46 2010 )
+(1200 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X22.754167 Y13.546667    (start point)
+G1 Z#101
+G1 X22.606000 Y13.504333
+G1 X22.394333 Y13.398500
+G1 X22.267333 Y13.292667
+G1 X2.476500 Y13.292667
+G1 X2.264833 Y13.229167
+G1 X2.010833 Y12.975167
+G1 X1.947333 Y12.763500
+G1 X1.947333 Y12.615333
+G1 X2.010833 Y12.403667
+G1 X2.264833 Y12.149667
+G1 X2.476500 Y12.086167
+G1 X22.267333 Y12.086167
+G1 X22.436667 Y11.959167
+G1 X22.669500 Y11.853333
+G1 X23.071667 Y11.853333
+G1 X23.389167 Y12.001500
+G1 X23.579667 Y12.213167
+G1 X23.706667 Y12.488333
+G1 X23.706667 Y12.890500
+G1 X23.579667 Y13.165667
+G1 X23.389167 Y13.377333
+G1 X23.071667 Y13.525500
+G1 X22.754167 Y13.546667
+G0 Z#100
+(polygon end, distance 45.35)
+(end, total distance 45.35mm = 1.79in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode4/Makefile.am b/tests/golden/hid_gcode4/Makefile.am
new file mode 100644
index 0000000..b071e19
--- /dev/null
+++ b/tests/golden/hid_gcode4/Makefile.am
@@ -0,0 +1,6 @@
+## -*- makefile -*-
+
+EXTRA_DIST= \
+	gcode_oneline.gcode.back.cnc \
+	gcode_oneline.gcode.drill.cnc \
+	gcode_oneline.gcode.front.cnc
diff --git a/tests/golden/hid_gcode4/gcode_oneline.gcode.back.cnc b/tests/golden/hid_gcode4/gcode_oneline.gcode.back.cnc
new file mode 100644
index 0000000..d049972
--- /dev/null
+++ b/tests/golden/hid_gcode4/gcode_oneline.gcode.back.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:36:12 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=5.000000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X27.770667 Y13.546667    (start point)
+G1 Z#101
+G1 X27.559000 Y13.462000
+G1 X27.305000 Y13.292667
+G1 X7.450667 Y13.292667
+G1 X7.196667 Y13.081000
+G1 X6.985000 Y12.827000
+G1 X6.985000 Y12.530667
+G1 X7.196667 Y12.276667
+G1 X7.450667 Y12.065000
+G1 X27.305000 Y12.065000
+G1 X27.643667 Y11.853333
+G1 X28.194000 Y11.853333
+G1 X28.532667 Y12.065000
+G1 X28.744333 Y12.403667
+G1 X28.744333 Y12.954000
+G1 X28.532667 Y13.292667
+G1 X28.194000 Y13.504333
+G1 X27.770667 Y13.546667
+G0 Z#100
+(polygon end, distance 45.38)
+(end, total distance 45.38mm = 1.79in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode4/gcode_oneline.gcode.drill.cnc b/tests/golden/hid_gcode4/gcode_oneline.gcode.drill.cnc
new file mode 100644
index 0000000..c648655
--- /dev/null
+++ b/tests/golden/hid_gcode4/gcode_oneline.gcode.drill.cnc
@@ -0,0 +1,12 @@
+(Created by G-code exporter)
+(drill file: 1 drills)
+( Tue Mar  9 17:36:12 2010 )
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-2.000000  (drill depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G81 X27.940000 Y12.700000 Z#101 R#100
+M5 M9 M2
+(end, total distance 0.00mm = 0.00in)
diff --git a/tests/golden/hid_gcode4/gcode_oneline.gcode.front.cnc b/tests/golden/hid_gcode4/gcode_oneline.gcode.front.cnc
new file mode 100644
index 0000000..78e64a5
--- /dev/null
+++ b/tests/golden/hid_gcode4/gcode_oneline.gcode.front.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:36:08 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=5.000000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X22.733000 Y13.546667    (start point)
+G1 Z#101
+G1 X22.521333 Y13.462000
+G1 X22.267333 Y13.292667
+G1 X2.413000 Y13.292667
+G1 X2.159000 Y13.081000
+G1 X1.947333 Y12.827000
+G1 X1.947333 Y12.530667
+G1 X2.159000 Y12.276667
+G1 X2.413000 Y12.065000
+G1 X22.267333 Y12.065000
+G1 X22.606000 Y11.853333
+G1 X23.156333 Y11.853333
+G1 X23.495000 Y12.065000
+G1 X23.706667 Y12.403667
+G1 X23.706667 Y12.954000
+G1 X23.495000 Y13.292667
+G1 X23.156333 Y13.504333
+G1 X22.733000 Y13.546667
+G0 Z#100
+(polygon end, distance 45.38)
+(end, total distance 45.38mm = 1.79in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode5/Makefile.am b/tests/golden/hid_gcode5/Makefile.am
new file mode 100644
index 0000000..b071e19
--- /dev/null
+++ b/tests/golden/hid_gcode5/Makefile.am
@@ -0,0 +1,6 @@
+## -*- makefile -*-
+
+EXTRA_DIST= \
+	gcode_oneline.gcode.back.cnc \
+	gcode_oneline.gcode.drill.cnc \
+	gcode_oneline.gcode.front.cnc
diff --git a/tests/golden/hid_gcode5/gcode_oneline.gcode.back.cnc b/tests/golden/hid_gcode5/gcode_oneline.gcode.back.cnc
new file mode 100644
index 0000000..8041f98
--- /dev/null
+++ b/tests/golden/hid_gcode5/gcode_oneline.gcode.back.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 18:06:42 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=10.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X27.770667 Y13.546667    (start point)
+G1 Z#101
+G1 X27.559000 Y13.462000
+G1 X27.305000 Y13.292667
+G1 X7.450667 Y13.292667
+G1 X7.196667 Y13.081000
+G1 X6.985000 Y12.827000
+G1 X6.985000 Y12.530667
+G1 X7.196667 Y12.276667
+G1 X7.450667 Y12.065000
+G1 X27.305000 Y12.065000
+G1 X27.643667 Y11.853333
+G1 X28.194000 Y11.853333
+G1 X28.532667 Y12.065000
+G1 X28.744333 Y12.403667
+G1 X28.744333 Y12.954000
+G1 X28.532667 Y13.292667
+G1 X28.194000 Y13.504333
+G1 X27.770667 Y13.546667
+G0 Z#100
+(polygon end, distance 45.38)
+(end, total distance 45.38mm = 1.79in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode5/gcode_oneline.gcode.drill.cnc b/tests/golden/hid_gcode5/gcode_oneline.gcode.drill.cnc
new file mode 100644
index 0000000..77d8d60
--- /dev/null
+++ b/tests/golden/hid_gcode5/gcode_oneline.gcode.drill.cnc
@@ -0,0 +1,12 @@
+(Created by G-code exporter)
+(drill file: 1 drills)
+( Tue Mar  9 18:06:42 2010 )
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=10.000000  (safe Z)
+#101=-2.000000  (drill depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G81 X27.940000 Y12.700000 Z#101 R#100
+M5 M9 M2
+(end, total distance 0.00mm = 0.00in)
diff --git a/tests/golden/hid_gcode5/gcode_oneline.gcode.front.cnc b/tests/golden/hid_gcode5/gcode_oneline.gcode.front.cnc
new file mode 100644
index 0000000..e3bbd7e
--- /dev/null
+++ b/tests/golden/hid_gcode5/gcode_oneline.gcode.front.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 18:06:40 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=10.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X22.733000 Y13.546667    (start point)
+G1 Z#101
+G1 X22.521333 Y13.462000
+G1 X22.267333 Y13.292667
+G1 X2.413000 Y13.292667
+G1 X2.159000 Y13.081000
+G1 X1.947333 Y12.827000
+G1 X1.947333 Y12.530667
+G1 X2.159000 Y12.276667
+G1 X2.413000 Y12.065000
+G1 X22.267333 Y12.065000
+G1 X22.606000 Y11.853333
+G1 X23.156333 Y11.853333
+G1 X23.495000 Y12.065000
+G1 X23.706667 Y12.403667
+G1 X23.706667 Y12.954000
+G1 X23.495000 Y13.292667
+G1 X23.156333 Y13.504333
+G1 X22.733000 Y13.546667
+G0 Z#100
+(polygon end, distance 45.38)
+(end, total distance 45.38mm = 1.79in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode6/Makefile.am b/tests/golden/hid_gcode6/Makefile.am
new file mode 100644
index 0000000..b071e19
--- /dev/null
+++ b/tests/golden/hid_gcode6/Makefile.am
@@ -0,0 +1,6 @@
+## -*- makefile -*-
+
+EXTRA_DIST= \
+	gcode_oneline.gcode.back.cnc \
+	gcode_oneline.gcode.drill.cnc \
+	gcode_oneline.gcode.front.cnc
diff --git a/tests/golden/hid_gcode6/gcode_oneline.gcode.back.cnc b/tests/golden/hid_gcode6/gcode_oneline.gcode.back.cnc
new file mode 100644
index 0000000..7d33799
--- /dev/null
+++ b/tests/golden/hid_gcode6/gcode_oneline.gcode.back.cnc
@@ -0,0 +1,43 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:45:05 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X0.000000 Y25.400000    (start point)
+G1 Z#101
+G1 X0.000000 Y0.000000
+G1 X37.295667 Y0.000000
+G1 X38.057667 Y0.635000
+G1 X39.073667 Y1.524000
+G1 X39.962667 Y2.540000
+G1 X40.597667 Y3.302000
+G1 X41.486667 Y4.656667
+G1 X41.952333 Y5.503333
+G1 X42.418000 Y6.477000
+G1 X42.883667 Y7.704667
+G1 X43.264667 Y9.017000
+G1 X43.518667 Y10.329333
+G1 X43.645667 Y11.514667
+G1 X43.645667 Y13.843000
+G1 X43.518667 Y15.028333
+G1 X43.264667 Y16.340667
+G1 X42.883667 Y17.653000
+G1 X42.418000 Y18.880667
+G1 X41.952333 Y19.854333
+G1 X41.486667 Y20.701000
+G1 X40.597667 Y22.055667
+G1 X39.962667 Y22.817667
+G1 X39.073667 Y23.833667
+G1 X38.057667 Y24.722667
+G1 X37.253333 Y25.400000
+G1 X0.000000 Y25.400000
+G0 Z#100
+(polygon end, distance 129.45)
+(end, total distance 129.45mm = 5.10in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode6/gcode_oneline.gcode.drill.cnc b/tests/golden/hid_gcode6/gcode_oneline.gcode.drill.cnc
new file mode 100644
index 0000000..6b44265
--- /dev/null
+++ b/tests/golden/hid_gcode6/gcode_oneline.gcode.drill.cnc
@@ -0,0 +1,12 @@
+(Created by G-code exporter)
+(drill file: 1 drills)
+( Tue Mar  9 17:45:05 2010 )
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-2.000000  (drill depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G81 X27.940000 Y12.700000 Z#101 R#100
+M5 M9 M2
+(end, total distance 0.00mm = 0.00in)
diff --git a/tests/golden/hid_gcode6/gcode_oneline.gcode.front.cnc b/tests/golden/hid_gcode6/gcode_oneline.gcode.front.cnc
new file mode 100644
index 0000000..7dfd6a0
--- /dev/null
+++ b/tests/golden/hid_gcode6/gcode_oneline.gcode.front.cnc
@@ -0,0 +1,43 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:39:31 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X0.000000 Y25.400000    (start point)
+G1 Z#101
+G1 X0.000000 Y0.000000
+G1 X32.258000 Y0.000000
+G1 X33.020000 Y0.635000
+G1 X34.036000 Y1.524000
+G1 X34.925000 Y2.540000
+G1 X35.560000 Y3.302000
+G1 X36.449000 Y4.656667
+G1 X36.914667 Y5.503333
+G1 X37.380333 Y6.477000
+G1 X37.846000 Y7.704667
+G1 X38.227000 Y9.017000
+G1 X38.481000 Y10.329333
+G1 X38.608000 Y11.514667
+G1 X38.608000 Y13.843000
+G1 X38.481000 Y15.028333
+G1 X38.227000 Y16.340667
+G1 X37.846000 Y17.653000
+G1 X37.380333 Y18.880667
+G1 X36.914667 Y19.854333
+G1 X36.449000 Y20.701000
+G1 X35.560000 Y22.055667
+G1 X34.925000 Y22.817667
+G1 X34.036000 Y23.833667
+G1 X33.020000 Y24.722667
+G1 X32.215667 Y25.400000
+G1 X0.000000 Y25.400000
+G0 Z#100
+(polygon end, distance 119.38)
+(end, total distance 119.38mm = 4.70in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode7/Makefile.am b/tests/golden/hid_gcode7/Makefile.am
new file mode 100644
index 0000000..b071e19
--- /dev/null
+++ b/tests/golden/hid_gcode7/Makefile.am
@@ -0,0 +1,6 @@
+## -*- makefile -*-
+
+EXTRA_DIST= \
+	gcode_oneline.gcode.back.cnc \
+	gcode_oneline.gcode.drill.cnc \
+	gcode_oneline.gcode.front.cnc
diff --git a/tests/golden/hid_gcode7/gcode_oneline.gcode.back.cnc b/tests/golden/hid_gcode7/gcode_oneline.gcode.back.cnc
new file mode 100644
index 0000000..b92e532
--- /dev/null
+++ b/tests/golden/hid_gcode7/gcode_oneline.gcode.back.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:45:12 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X27.770667 Y13.546667    (start point)
+G1 Z#101
+G1 X27.559000 Y13.462000
+G1 X27.305000 Y13.292667
+G1 X7.450667 Y13.292667
+G1 X7.196667 Y13.081000
+G1 X6.985000 Y12.827000
+G1 X6.985000 Y12.530667
+G1 X7.196667 Y12.276667
+G1 X7.450667 Y12.065000
+G1 X27.305000 Y12.065000
+G1 X27.643667 Y11.853333
+G1 X28.194000 Y11.853333
+G1 X28.532667 Y12.065000
+G1 X28.744333 Y12.403667
+G1 X28.744333 Y12.954000
+G1 X28.532667 Y13.292667
+G1 X28.194000 Y13.504333
+G1 X27.770667 Y13.546667
+G0 Z#100
+(polygon end, distance 45.38)
+(end, total distance 45.38mm = 1.79in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode7/gcode_oneline.gcode.drill.cnc b/tests/golden/hid_gcode7/gcode_oneline.gcode.drill.cnc
new file mode 100644
index 0000000..e8c41bf
--- /dev/null
+++ b/tests/golden/hid_gcode7/gcode_oneline.gcode.drill.cnc
@@ -0,0 +1,12 @@
+(Created by G-code exporter)
+(drill file: 1 drills)
+( Tue Mar  9 17:45:12 2010 )
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=70.000000  (drill depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G81 X27.940000 Y12.700000 Z#101 R#100
+M5 M9 M2
+(end, total distance 0.00mm = 0.00in)
diff --git a/tests/golden/hid_gcode7/gcode_oneline.gcode.front.cnc b/tests/golden/hid_gcode7/gcode_oneline.gcode.front.cnc
new file mode 100644
index 0000000..4c64804
--- /dev/null
+++ b/tests/golden/hid_gcode7/gcode_oneline.gcode.front.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:45:08 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X22.733000 Y13.546667    (start point)
+G1 Z#101
+G1 X22.521333 Y13.462000
+G1 X22.267333 Y13.292667
+G1 X2.413000 Y13.292667
+G1 X2.159000 Y13.081000
+G1 X1.947333 Y12.827000
+G1 X1.947333 Y12.530667
+G1 X2.159000 Y12.276667
+G1 X2.413000 Y12.065000
+G1 X22.267333 Y12.065000
+G1 X22.606000 Y11.853333
+G1 X23.156333 Y11.853333
+G1 X23.495000 Y12.065000
+G1 X23.706667 Y12.403667
+G1 X23.706667 Y12.954000
+G1 X23.495000 Y13.292667
+G1 X23.156333 Y13.504333
+G1 X22.733000 Y13.546667
+G0 Z#100
+(polygon end, distance 45.38)
+(end, total distance 45.38mm = 1.79in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode8/Makefile.am b/tests/golden/hid_gcode8/Makefile.am
new file mode 100644
index 0000000..b071e19
--- /dev/null
+++ b/tests/golden/hid_gcode8/Makefile.am
@@ -0,0 +1,6 @@
+## -*- makefile -*-
+
+EXTRA_DIST= \
+	gcode_oneline.gcode.back.cnc \
+	gcode_oneline.gcode.drill.cnc \
+	gcode_oneline.gcode.front.cnc
diff --git a/tests/golden/hid_gcode8/gcode_oneline.gcode.back.cnc b/tests/golden/hid_gcode8/gcode_oneline.gcode.back.cnc
new file mode 100644
index 0000000..286cab5
--- /dev/null
+++ b/tests/golden/hid_gcode8/gcode_oneline.gcode.back.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:45:19 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X27.770667 Y13.546667    (start point)
+G1 Z#101
+G1 X27.559000 Y13.462000
+G1 X27.305000 Y13.292667
+G1 X7.450667 Y13.292667
+G1 X7.196667 Y13.081000
+G1 X6.985000 Y12.827000
+G1 X6.985000 Y12.530667
+G1 X7.196667 Y12.276667
+G1 X7.450667 Y12.065000
+G1 X27.305000 Y12.065000
+G1 X27.643667 Y11.853333
+G1 X28.194000 Y11.853333
+G1 X28.532667 Y12.065000
+G1 X28.744333 Y12.403667
+G1 X28.744333 Y12.954000
+G1 X28.532667 Y13.292667
+G1 X28.194000 Y13.504333
+G1 X27.770667 Y13.546667
+G0 Z#100
+(polygon end, distance 45.38)
+(end, total distance 45.38mm = 1.79in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode8/gcode_oneline.gcode.drill.cnc b/tests/golden/hid_gcode8/gcode_oneline.gcode.drill.cnc
new file mode 100644
index 0000000..77ac526
--- /dev/null
+++ b/tests/golden/hid_gcode8/gcode_oneline.gcode.drill.cnc
@@ -0,0 +1,12 @@
+(Created by G-code exporter)
+(drill file: 1 drills)
+( Tue Mar  9 17:45:19 2010 )
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-2.000000  (drill depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G81 X27.940000 Y12.700000 Z#101 R#100
+M5 M9 M2
+(end, total distance 0.00mm = 0.00in)
diff --git a/tests/golden/hid_gcode8/gcode_oneline.gcode.front.cnc b/tests/golden/hid_gcode8/gcode_oneline.gcode.front.cnc
new file mode 100644
index 0000000..a57aeb7
--- /dev/null
+++ b/tests/golden/hid_gcode8/gcode_oneline.gcode.front.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:45:16 2010 )
+(600 dpi)
+(Unit: mm)
+(Board size: 50.80x25.40 mm)
+#100=2.000000  (safe Z)
+#101=-0.050000  (cutting depth)
+(---------------------------------)
+G17 G21 G90 G64 P0.003 M3 S3000 M7 F25
+G0 Z#100
+(polygon 1)
+G0 X22.733000 Y13.546667    (start point)
+G1 Z#101
+G1 X22.521333 Y13.462000
+G1 X22.267333 Y13.292667
+G1 X2.413000 Y13.292667
+G1 X2.159000 Y13.081000
+G1 X1.947333 Y12.827000
+G1 X1.947333 Y12.530667
+G1 X2.159000 Y12.276667
+G1 X2.413000 Y12.065000
+G1 X22.267333 Y12.065000
+G1 X22.606000 Y11.853333
+G1 X23.156333 Y11.853333
+G1 X23.495000 Y12.065000
+G1 X23.706667 Y12.403667
+G1 X23.706667 Y12.954000
+G1 X23.495000 Y13.292667
+G1 X23.156333 Y13.504333
+G1 X22.733000 Y13.546667
+G0 Z#100
+(polygon end, distance 45.38)
+(end, total distance 45.38mm = 1.79in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode9/Makefile.am b/tests/golden/hid_gcode9/Makefile.am
new file mode 100644
index 0000000..b071e19
--- /dev/null
+++ b/tests/golden/hid_gcode9/Makefile.am
@@ -0,0 +1,6 @@
+## -*- makefile -*-
+
+EXTRA_DIST= \
+	gcode_oneline.gcode.back.cnc \
+	gcode_oneline.gcode.drill.cnc \
+	gcode_oneline.gcode.front.cnc
diff --git a/tests/golden/hid_gcode9/gcode_oneline.gcode.back.cnc b/tests/golden/hid_gcode9/gcode_oneline.gcode.back.cnc
new file mode 100644
index 0000000..49ebcd5
--- /dev/null
+++ b/tests/golden/hid_gcode9/gcode_oneline.gcode.back.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:45:25 2010 )
+(600 dpi)
+(Unit: inch)
+(Board size: 2.00x1.00 inches)
+#100=0.002000  (safe Z)
+#101=-0.000050  (cutting depth)
+(---------------------------------)
+G17 G20 G90 G64 P0.003 M3 S3000 M7 F1
+G0 Z#100
+(polygon 1)
+G0 X1.093333 Y0.530000    (start point)
+G1 Z#101
+G1 X1.083333 Y0.525000
+G1 X1.076667 Y0.520000
+G1 X0.291667 Y0.518333
+G1 X0.280000 Y0.506667
+G1 X0.280000 Y0.491667
+G1 X0.291667 Y0.480000
+G1 X1.076667 Y0.478333
+G1 X1.088333 Y0.470000
+G1 X1.100000 Y0.468333
+G1 X1.113333 Y0.471667
+G1 X1.123333 Y0.480000
+G1 X1.130000 Y0.493333
+G1 X1.130000 Y0.505000
+G1 X1.123333 Y0.518333
+G1 X1.115000 Y0.525000
+G1 X1.103333 Y0.530000
+G1 X1.093333 Y0.530000
+G0 Z#100
+(polygon end, distance 1.77)
+(end, total distance 44.84mm = 1.77in)
+M5 M9 M2
diff --git a/tests/golden/hid_gcode9/gcode_oneline.gcode.drill.cnc b/tests/golden/hid_gcode9/gcode_oneline.gcode.drill.cnc
new file mode 100644
index 0000000..c4b730a
--- /dev/null
+++ b/tests/golden/hid_gcode9/gcode_oneline.gcode.drill.cnc
@@ -0,0 +1,12 @@
+(Created by G-code exporter)
+(drill file: 1 drills)
+( Tue Mar  9 17:45:25 2010 )
+(Unit: inch)
+(Board size: 2.00x1.00 inches)
+#100=0.002000  (safe Z)
+#101=-0.002000  (drill depth)
+(---------------------------------)
+G17 G20 G90 G64 P0.003 M3 S3000 M7 F1
+G81 X1.100000 Y0.500000 Z#101 R#100
+M5 M9 M2
+(end, total distance 0.00mm = 0.00in)
diff --git a/tests/golden/hid_gcode9/gcode_oneline.gcode.front.cnc b/tests/golden/hid_gcode9/gcode_oneline.gcode.front.cnc
new file mode 100644
index 0000000..638cec1
--- /dev/null
+++ b/tests/golden/hid_gcode9/gcode_oneline.gcode.front.cnc
@@ -0,0 +1,34 @@
+(Created by G-code exporter)
+( Tue Mar  9 17:45:22 2010 )
+(600 dpi)
+(Unit: inch)
+(Board size: 2.00x1.00 inches)
+#100=0.002000  (safe Z)
+#101=-0.000050  (cutting depth)
+(---------------------------------)
+G17 G20 G90 G64 P0.003 M3 S3000 M7 F1
+G0 Z#100
+(polygon 1)
+G0 X0.895000 Y0.530000    (start point)
+G1 Z#101
+G1 X0.885000 Y0.525000
+G1 X0.878333 Y0.520000
+G1 X0.093333 Y0.518333
+G1 X0.081667 Y0.506667
+G1 X0.081667 Y0.491667
+G1 X0.093333 Y0.480000
+G1 X0.878333 Y0.478333
+G1 X0.890000 Y0.470000
+G1 X0.901667 Y0.468333
+G1 X0.915000 Y0.471667
+G1 X0.925000 Y0.480000
+G1 X0.931667 Y0.493333
+G1 X0.931667 Y0.505000
+G1 X0.925000 Y0.518333
+G1 X0.916667 Y0.525000
+G1 X0.905000 Y0.530000
+G1 X0.895000 Y0.530000
+G0 Z#100
+(polygon end, distance 1.77)
+(end, total distance 44.84mm = 1.77in)
+M5 M9 M2
diff --git a/tests/inputs/gcode_oneline.pcb b/tests/inputs/gcode_oneline.pcb
new file mode 100644
index 0000000..c20eacf
--- /dev/null
+++ b/tests/inputs/gcode_oneline.pcb
@@ -0,0 +1,832 @@
+# release: pcb 1.99y
+# date:    Wed Jun 24 12:26:14 2009
+# user:    dan (Dan McMahill,At Home ,258-8142,)
+# host:    bondage
+
+# To read pcb files, the pcb version (or the cvs source date) must be >= the file version
+FileVersion[20070407]
+
+PCB["Basic Single Trace RS274-X Test" 200000 100000]
+
+Grid[10000.000000 0 0 1]
+Cursor[0 500000 0.000000]
+PolyArea[200000000.000000]
+Thermal[0.500000]
+DRC[1000 1000 1000 1000 1500 1000]
+Flags("nameonpcb,uniquename,clearnew,snappin")
+Groups("1,c:2,s:3:4:5:6:7:8")
+Styles["Signal,1000,3600,2000,1000:Power,2500,6000,3500,1000:Fat,4000,6000,3500,1000:Skinny,600,2402,1181,600"]
+
+Symbol(' ' 18)
+(
+)
+Symbol('!' 12)
+(
+	SymbolLine(0 45 0 50 8)
+	SymbolLine(0 10 0 35 8)
+)
+Symbol('"' 12)
+(
+	SymbolLine(0 10 0 20 8)
+	SymbolLine(10 10 10 20 8)
+)
+Symbol('#' 12)
+(
+	SymbolLine(0 35 20 35 8)
+	SymbolLine(0 25 20 25 8)
+	SymbolLine(15 20 15 40 8)
+	SymbolLine(5 20 5 40 8)
+)
+Symbol('$' 12)
+(
+	SymbolLine(15 15 20 20 8)
+	SymbolLine(5 15 15 15 8)
+	SymbolLine(0 20 5 15 8)
+	SymbolLine(0 20 0 25 8)
+	SymbolLine(0 25 5 30 8)
+	SymbolLine(5 30 15 30 8)
+	SymbolLine(15 30 20 35 8)
+	SymbolLine(20 35 20 40 8)
+	SymbolLine(15 45 20 40 8)
+	SymbolLine(5 45 15 45 8)
+	SymbolLine(0 40 5 45 8)
+	SymbolLine(10 10 10 50 8)
+)
+Symbol('%' 12)
+(
+	SymbolLine(0 15 0 20 8)
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(5 10 10 10 8)
+	SymbolLine(10 10 15 15 8)
+	SymbolLine(15 15 15 20 8)
+	SymbolLine(10 25 15 20 8)
+	SymbolLine(5 25 10 25 8)
+	SymbolLine(0 20 5 25 8)
+	SymbolLine(0 50 40 10 8)
+	SymbolLine(35 50 40 45 8)
+	SymbolLine(40 40 40 45 8)
+	SymbolLine(35 35 40 40 8)
+	SymbolLine(30 35 35 35 8)
+	SymbolLine(25 40 30 35 8)
+	SymbolLine(25 40 25 45 8)
+	SymbolLine(25 45 30 50 8)
+	SymbolLine(30 50 35 50 8)
+)
+Symbol('&' 12)
+(
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(0 15 0 25 8)
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(0 35 15 20 8)
+	SymbolLine(5 50 10 50 8)
+	SymbolLine(10 50 20 40 8)
+	SymbolLine(0 25 25 50 8)
+	SymbolLine(5 10 10 10 8)
+	SymbolLine(10 10 15 15 8)
+	SymbolLine(15 15 15 20 8)
+	SymbolLine(0 35 0 45 8)
+)
+Symbol(''' 12)
+(
+	SymbolLine(0 20 10 10 8)
+)
+Symbol('(' 12)
+(
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(0 15 0 45 8)
+)
+Symbol(')' 12)
+(
+	SymbolLine(0 10 5 15 8)
+	SymbolLine(5 15 5 45 8)
+	SymbolLine(0 50 5 45 8)
+)
+Symbol('*' 12)
+(
+	SymbolLine(0 20 20 40 8)
+	SymbolLine(0 40 20 20 8)
+	SymbolLine(0 30 20 30 8)
+	SymbolLine(10 20 10 40 8)
+)
+Symbol('+' 12)
+(
+	SymbolLine(0 30 20 30 8)
+	SymbolLine(10 20 10 40 8)
+)
+Symbol(',' 12)
+(
+	SymbolLine(0 60 10 50 8)
+)
+Symbol('-' 12)
+(
+	SymbolLine(0 30 20 30 8)
+)
+Symbol('.' 12)
+(
+	SymbolLine(0 50 5 50 8)
+)
+Symbol('/' 12)
+(
+	SymbolLine(0 45 30 15 8)
+)
+Symbol('0' 12)
+(
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(0 15 0 45 8)
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(5 10 15 10 8)
+	SymbolLine(15 10 20 15 8)
+	SymbolLine(20 15 20 45 8)
+	SymbolLine(15 50 20 45 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(0 40 20 20 8)
+)
+Symbol('1' 12)
+(
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(10 10 10 50 8)
+	SymbolLine(0 20 10 10 8)
+)
+Symbol('2' 12)
+(
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(5 10 20 10 8)
+	SymbolLine(20 10 25 15 8)
+	SymbolLine(25 15 25 25 8)
+	SymbolLine(0 50 25 25 8)
+	SymbolLine(0 50 25 50 8)
+)
+Symbol('3' 12)
+(
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(5 10 15 10 8)
+	SymbolLine(15 10 20 15 8)
+	SymbolLine(20 15 20 45 8)
+	SymbolLine(15 50 20 45 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(5 30 20 30 8)
+)
+Symbol('4' 12)
+(
+	SymbolLine(0 30 20 10 8)
+	SymbolLine(0 30 25 30 8)
+	SymbolLine(20 10 20 50 8)
+)
+Symbol('5' 12)
+(
+	SymbolLine(0 10 20 10 8)
+	SymbolLine(0 10 0 30 8)
+	SymbolLine(0 30 5 25 8)
+	SymbolLine(5 25 15 25 8)
+	SymbolLine(15 25 20 30 8)
+	SymbolLine(20 30 20 45 8)
+	SymbolLine(15 50 20 45 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(0 45 5 50 8)
+)
+Symbol('6' 12)
+(
+	SymbolLine(15 10 20 15 8)
+	SymbolLine(5 10 15 10 8)
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(0 15 0 45 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(15 30 20 35 8)
+	SymbolLine(0 30 15 30 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(15 50 20 45 8)
+	SymbolLine(20 35 20 45 8)
+)
+Symbol('7' 12)
+(
+	SymbolLine(0 50 25 25 8)
+	SymbolLine(25 10 25 25 8)
+	SymbolLine(0 10 25 10 8)
+)
+Symbol('8' 12)
+(
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(0 35 0 45 8)
+	SymbolLine(0 35 5 30 8)
+	SymbolLine(5 30 15 30 8)
+	SymbolLine(15 30 20 35 8)
+	SymbolLine(20 35 20 45 8)
+	SymbolLine(15 50 20 45 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(0 25 5 30 8)
+	SymbolLine(0 15 0 25 8)
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(5 10 15 10 8)
+	SymbolLine(15 10 20 15 8)
+	SymbolLine(20 15 20 25 8)
+	SymbolLine(15 30 20 25 8)
+)
+Symbol('9' 12)
+(
+	SymbolLine(0 50 20 30 8)
+	SymbolLine(20 15 20 30 8)
+	SymbolLine(15 10 20 15 8)
+	SymbolLine(5 10 15 10 8)
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(0 15 0 25 8)
+	SymbolLine(0 25 5 30 8)
+	SymbolLine(5 30 20 30 8)
+)
+Symbol(':' 12)
+(
+	SymbolLine(0 25 5 25 8)
+	SymbolLine(0 35 5 35 8)
+)
+Symbol(';' 12)
+(
+	SymbolLine(0 50 10 40 8)
+	SymbolLine(10 25 10 30 8)
+)
+Symbol('<' 12)
+(
+	SymbolLine(0 30 10 20 8)
+	SymbolLine(0 30 10 40 8)
+)
+Symbol('=' 12)
+(
+	SymbolLine(0 25 20 25 8)
+	SymbolLine(0 35 20 35 8)
+)
+Symbol('>' 12)
+(
+	SymbolLine(0 20 10 30 8)
+	SymbolLine(0 40 10 30 8)
+)
+Symbol('?' 12)
+(
+	SymbolLine(10 30 10 35 8)
+	SymbolLine(10 45 10 50 8)
+	SymbolLine(0 15 0 20 8)
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(5 10 15 10 8)
+	SymbolLine(15 10 20 15 8)
+	SymbolLine(20 15 20 20 8)
+	SymbolLine(10 30 20 20 8)
+)
+Symbol('@' 12)
+(
+	SymbolLine(0 10 0 40 8)
+	SymbolLine(0 40 10 50 8)
+	SymbolLine(10 50 40 50 8)
+	SymbolLine(50 35 50 10 8)
+	SymbolLine(50 10 40 0 8)
+	SymbolLine(40 0 10 0 8)
+	SymbolLine(10 0 0 10 8)
+	SymbolLine(15 20 15 30 8)
+	SymbolLine(15 30 20 35 8)
+	SymbolLine(20 35 30 35 8)
+	SymbolLine(30 35 35 30 8)
+	SymbolLine(35 30 40 35 8)
+	SymbolLine(35 30 35 15 8)
+	SymbolLine(35 20 30 15 8)
+	SymbolLine(20 15 30 15 8)
+	SymbolLine(20 15 15 20 8)
+	SymbolLine(40 35 50 35 8)
+)
+Symbol('A' 12)
+(
+	SymbolLine(0 15 0 50 8)
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(5 10 20 10 8)
+	SymbolLine(20 10 25 15 8)
+	SymbolLine(25 15 25 50 8)
+	SymbolLine(0 30 25 30 8)
+)
+Symbol('B' 12)
+(
+	SymbolLine(0 50 20 50 8)
+	SymbolLine(20 50 25 45 8)
+	SymbolLine(25 35 25 45 8)
+	SymbolLine(20 30 25 35 8)
+	SymbolLine(5 30 20 30 8)
+	SymbolLine(5 10 5 50 8)
+	SymbolLine(0 10 20 10 8)
+	SymbolLine(20 10 25 15 8)
+	SymbolLine(25 15 25 25 8)
+	SymbolLine(20 30 25 25 8)
+)
+Symbol('C' 12)
+(
+	SymbolLine(5 50 20 50 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(0 15 0 45 8)
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(5 10 20 10 8)
+)
+Symbol('D' 12)
+(
+	SymbolLine(5 10 5 50 8)
+	SymbolLine(20 10 25 15 8)
+	SymbolLine(25 15 25 45 8)
+	SymbolLine(20 50 25 45 8)
+	SymbolLine(0 50 20 50 8)
+	SymbolLine(0 10 20 10 8)
+)
+Symbol('E' 12)
+(
+	SymbolLine(0 30 15 30 8)
+	SymbolLine(0 50 20 50 8)
+	SymbolLine(0 10 0 50 8)
+	SymbolLine(0 10 20 10 8)
+)
+Symbol('F' 12)
+(
+	SymbolLine(0 10 0 50 8)
+	SymbolLine(0 10 20 10 8)
+	SymbolLine(0 30 15 30 8)
+)
+Symbol('G' 12)
+(
+	SymbolLine(20 10 25 15 8)
+	SymbolLine(5 10 20 10 8)
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(0 15 0 45 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(5 50 20 50 8)
+	SymbolLine(20 50 25 45 8)
+	SymbolLine(25 35 25 45 8)
+	SymbolLine(20 30 25 35 8)
+	SymbolLine(10 30 20 30 8)
+)
+Symbol('H' 12)
+(
+	SymbolLine(0 10 0 50 8)
+	SymbolLine(25 10 25 50 8)
+	SymbolLine(0 30 25 30 8)
+)
+Symbol('I' 12)
+(
+	SymbolLine(0 10 10 10 8)
+	SymbolLine(5 10 5 50 8)
+	SymbolLine(0 50 10 50 8)
+)
+Symbol('J' 12)
+(
+	SymbolLine(0 10 15 10 8)
+	SymbolLine(15 10 15 45 8)
+	SymbolLine(10 50 15 45 8)
+	SymbolLine(5 50 10 50 8)
+	SymbolLine(0 45 5 50 8)
+)
+Symbol('K' 12)
+(
+	SymbolLine(0 10 0 50 8)
+	SymbolLine(0 30 20 10 8)
+	SymbolLine(0 30 20 50 8)
+)
+Symbol('L' 12)
+(
+	SymbolLine(0 10 0 50 8)
+	SymbolLine(0 50 20 50 8)
+)
+Symbol('M' 12)
+(
+	SymbolLine(0 10 0 50 8)
+	SymbolLine(0 10 15 25 8)
+	SymbolLine(15 25 30 10 8)
+	SymbolLine(30 10 30 50 8)
+)
+Symbol('N' 12)
+(
+	SymbolLine(0 10 0 50 8)
+	SymbolLine(0 10 0 15 8)
+	SymbolLine(0 15 25 40 8)
+	SymbolLine(25 10 25 50 8)
+)
+Symbol('O' 12)
+(
+	SymbolLine(0 15 0 45 8)
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(5 10 15 10 8)
+	SymbolLine(15 10 20 15 8)
+	SymbolLine(20 15 20 45 8)
+	SymbolLine(15 50 20 45 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(0 45 5 50 8)
+)
+Symbol('P' 12)
+(
+	SymbolLine(5 10 5 50 8)
+	SymbolLine(0 10 20 10 8)
+	SymbolLine(20 10 25 15 8)
+	SymbolLine(25 15 25 25 8)
+	SymbolLine(20 30 25 25 8)
+	SymbolLine(5 30 20 30 8)
+)
+Symbol('Q' 12)
+(
+	SymbolLine(0 15 0 45 8)
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(5 10 15 10 8)
+	SymbolLine(15 10 20 15 8)
+	SymbolLine(20 15 20 45 8)
+	SymbolLine(15 50 20 45 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(10 40 20 50 8)
+)
+Symbol('R' 12)
+(
+	SymbolLine(0 10 20 10 8)
+	SymbolLine(20 10 25 15 8)
+	SymbolLine(25 15 25 25 8)
+	SymbolLine(20 30 25 25 8)
+	SymbolLine(5 30 20 30 8)
+	SymbolLine(5 10 5 50 8)
+	SymbolLine(5 30 25 50 8)
+)
+Symbol('S' 12)
+(
+	SymbolLine(20 10 25 15 8)
+	SymbolLine(5 10 20 10 8)
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(0 15 0 25 8)
+	SymbolLine(0 25 5 30 8)
+	SymbolLine(5 30 20 30 8)
+	SymbolLine(20 30 25 35 8)
+	SymbolLine(25 35 25 45 8)
+	SymbolLine(20 50 25 45 8)
+	SymbolLine(5 50 20 50 8)
+	SymbolLine(0 45 5 50 8)
+)
+Symbol('T' 12)
+(
+	SymbolLine(0 10 20 10 8)
+	SymbolLine(10 10 10 50 8)
+)
+Symbol('U' 12)
+(
+	SymbolLine(0 10 0 45 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(15 50 20 45 8)
+	SymbolLine(20 10 20 45 8)
+)
+Symbol('V' 12)
+(
+	SymbolLine(0 10 0 40 8)
+	SymbolLine(0 40 10 50 8)
+	SymbolLine(10 50 20 40 8)
+	SymbolLine(20 10 20 40 8)
+)
+Symbol('W' 12)
+(
+	SymbolLine(0 10 0 50 8)
+	SymbolLine(0 50 15 35 8)
+	SymbolLine(15 35 30 50 8)
+	SymbolLine(30 10 30 50 8)
+)
+Symbol('X' 12)
+(
+	SymbolLine(0 10 0 15 8)
+	SymbolLine(0 15 25 40 8)
+	SymbolLine(25 40 25 50 8)
+	SymbolLine(0 40 0 50 8)
+	SymbolLine(0 40 25 15 8)
+	SymbolLine(25 10 25 15 8)
+)
+Symbol('Y' 12)
+(
+	SymbolLine(0 10 0 15 8)
+	SymbolLine(0 15 10 25 8)
+	SymbolLine(10 25 20 15 8)
+	SymbolLine(20 10 20 15 8)
+	SymbolLine(10 25 10 50 8)
+)
+Symbol('Z' 12)
+(
+	SymbolLine(0 10 25 10 8)
+	SymbolLine(25 10 25 15 8)
+	SymbolLine(0 40 25 15 8)
+	SymbolLine(0 40 0 50 8)
+	SymbolLine(0 50 25 50 8)
+)
+Symbol('[' 12)
+(
+	SymbolLine(0 10 5 10 8)
+	SymbolLine(0 10 0 50 8)
+	SymbolLine(0 50 5 50 8)
+)
+Symbol('\' 12)
+(
+	SymbolLine(0 15 30 45 8)
+)
+Symbol(']' 12)
+(
+	SymbolLine(0 10 5 10 8)
+	SymbolLine(5 10 5 50 8)
+	SymbolLine(0 50 5 50 8)
+)
+Symbol('^' 12)
+(
+	SymbolLine(0 15 5 10 8)
+	SymbolLine(5 10 10 15 8)
+)
+Symbol('_' 12)
+(
+	SymbolLine(0 50 20 50 8)
+)
+Symbol('a' 12)
+(
+	SymbolLine(15 30 20 35 8)
+	SymbolLine(5 30 15 30 8)
+	SymbolLine(0 35 5 30 8)
+	SymbolLine(0 35 0 45 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(20 30 20 45 8)
+	SymbolLine(20 45 25 50 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(15 50 20 45 8)
+)
+Symbol('b' 12)
+(
+	SymbolLine(0 10 0 50 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(15 50 20 45 8)
+	SymbolLine(20 35 20 45 8)
+	SymbolLine(15 30 20 35 8)
+	SymbolLine(5 30 15 30 8)
+	SymbolLine(0 35 5 30 8)
+)
+Symbol('c' 12)
+(
+	SymbolLine(5 30 20 30 8)
+	SymbolLine(0 35 5 30 8)
+	SymbolLine(0 35 0 45 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(5 50 20 50 8)
+)
+Symbol('d' 12)
+(
+	SymbolLine(20 10 20 50 8)
+	SymbolLine(15 50 20 45 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(0 35 0 45 8)
+	SymbolLine(0 35 5 30 8)
+	SymbolLine(5 30 15 30 8)
+	SymbolLine(15 30 20 35 8)
+)
+Symbol('e' 12)
+(
+	SymbolLine(5 50 20 50 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(0 35 0 45 8)
+	SymbolLine(0 35 5 30 8)
+	SymbolLine(5 30 15 30 8)
+	SymbolLine(15 30 20 35 8)
+	SymbolLine(0 40 20 40 8)
+	SymbolLine(20 40 20 35 8)
+)
+Symbol('f' 10)
+(
+	SymbolLine(5 15 5 50 8)
+	SymbolLine(5 15 10 10 8)
+	SymbolLine(10 10 15 10 8)
+	SymbolLine(0 30 10 30 8)
+)
+Symbol('g' 12)
+(
+	SymbolLine(15 30 20 35 8)
+	SymbolLine(5 30 15 30 8)
+	SymbolLine(0 35 5 30 8)
+	SymbolLine(0 35 0 45 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(15 50 20 45 8)
+	SymbolLine(0 60 5 65 8)
+	SymbolLine(5 65 15 65 8)
+	SymbolLine(15 65 20 60 8)
+	SymbolLine(20 30 20 60 8)
+)
+Symbol('h' 12)
+(
+	SymbolLine(0 10 0 50 8)
+	SymbolLine(0 35 5 30 8)
+	SymbolLine(5 30 15 30 8)
+	SymbolLine(15 30 20 35 8)
+	SymbolLine(20 35 20 50 8)
+)
+Symbol('i' 10)
+(
+	SymbolLine(0 20 0 25 8)
+	SymbolLine(0 35 0 50 8)
+)
+Symbol('j' 10)
+(
+	SymbolLine(5 20 5 25 8)
+	SymbolLine(5 35 5 60 8)
+	SymbolLine(0 65 5 60 8)
+)
+Symbol('k' 12)
+(
+	SymbolLine(0 10 0 50 8)
+	SymbolLine(0 35 15 50 8)
+	SymbolLine(0 35 10 25 8)
+)
+Symbol('l' 10)
+(
+	SymbolLine(0 10 0 45 8)
+	SymbolLine(0 45 5 50 8)
+)
+Symbol('m' 12)
+(
+	SymbolLine(5 35 5 50 8)
+	SymbolLine(5 35 10 30 8)
+	SymbolLine(10 30 15 30 8)
+	SymbolLine(15 30 20 35 8)
+	SymbolLine(20 35 20 50 8)
+	SymbolLine(20 35 25 30 8)
+	SymbolLine(25 30 30 30 8)
+	SymbolLine(30 30 35 35 8)
+	SymbolLine(35 35 35 50 8)
+	SymbolLine(0 30 5 35 8)
+)
+Symbol('n' 12)
+(
+	SymbolLine(5 35 5 50 8)
+	SymbolLine(5 35 10 30 8)
+	SymbolLine(10 30 15 30 8)
+	SymbolLine(15 30 20 35 8)
+	SymbolLine(20 35 20 50 8)
+	SymbolLine(0 30 5 35 8)
+)
+Symbol('o' 12)
+(
+	SymbolLine(0 35 0 45 8)
+	SymbolLine(0 35 5 30 8)
+	SymbolLine(5 30 15 30 8)
+	SymbolLine(15 30 20 35 8)
+	SymbolLine(20 35 20 45 8)
+	SymbolLine(15 50 20 45 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(0 45 5 50 8)
+)
+Symbol('p' 12)
+(
+	SymbolLine(5 35 5 65 8)
+	SymbolLine(0 30 5 35 8)
+	SymbolLine(5 35 10 30 8)
+	SymbolLine(10 30 20 30 8)
+	SymbolLine(20 30 25 35 8)
+	SymbolLine(25 35 25 45 8)
+	SymbolLine(20 50 25 45 8)
+	SymbolLine(10 50 20 50 8)
+	SymbolLine(5 45 10 50 8)
+)
+Symbol('q' 12)
+(
+	SymbolLine(20 35 20 65 8)
+	SymbolLine(15 30 20 35 8)
+	SymbolLine(5 30 15 30 8)
+	SymbolLine(0 35 5 30 8)
+	SymbolLine(0 35 0 45 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(15 50 20 45 8)
+)
+Symbol('r' 12)
+(
+	SymbolLine(5 35 5 50 8)
+	SymbolLine(5 35 10 30 8)
+	SymbolLine(10 30 20 30 8)
+	SymbolLine(0 30 5 35 8)
+)
+Symbol('s' 12)
+(
+	SymbolLine(5 50 20 50 8)
+	SymbolLine(20 50 25 45 8)
+	SymbolLine(20 40 25 45 8)
+	SymbolLine(5 40 20 40 8)
+	SymbolLine(0 35 5 40 8)
+	SymbolLine(0 35 5 30 8)
+	SymbolLine(5 30 20 30 8)
+	SymbolLine(20 30 25 35 8)
+	SymbolLine(0 45 5 50 8)
+)
+Symbol('t' 10)
+(
+	SymbolLine(5 10 5 45 8)
+	SymbolLine(5 45 10 50 8)
+	SymbolLine(0 25 10 25 8)
+)
+Symbol('u' 12)
+(
+	SymbolLine(0 30 0 45 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(15 50 20 45 8)
+	SymbolLine(20 30 20 45 8)
+)
+Symbol('v' 12)
+(
+	SymbolLine(0 30 0 40 8)
+	SymbolLine(0 40 10 50 8)
+	SymbolLine(10 50 20 40 8)
+	SymbolLine(20 30 20 40 8)
+)
+Symbol('w' 12)
+(
+	SymbolLine(0 30 0 45 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(5 50 10 50 8)
+	SymbolLine(10 50 15 45 8)
+	SymbolLine(15 30 15 45 8)
+	SymbolLine(15 45 20 50 8)
+	SymbolLine(20 50 25 50 8)
+	SymbolLine(25 50 30 45 8)
+	SymbolLine(30 30 30 45 8)
+)
+Symbol('x' 12)
+(
+	SymbolLine(0 30 20 50 8)
+	SymbolLine(0 50 20 30 8)
+)
+Symbol('y' 12)
+(
+	SymbolLine(0 30 0 45 8)
+	SymbolLine(0 45 5 50 8)
+	SymbolLine(20 30 20 60 8)
+	SymbolLine(15 65 20 60 8)
+	SymbolLine(5 65 15 65 8)
+	SymbolLine(0 60 5 65 8)
+	SymbolLine(5 50 15 50 8)
+	SymbolLine(15 50 20 45 8)
+)
+Symbol('z' 12)
+(
+	SymbolLine(0 30 20 30 8)
+	SymbolLine(0 50 20 30 8)
+	SymbolLine(0 50 20 50 8)
+)
+Symbol('{' 12)
+(
+	SymbolLine(5 15 10 10 8)
+	SymbolLine(5 15 5 25 8)
+	SymbolLine(0 30 5 25 8)
+	SymbolLine(0 30 5 35 8)
+	SymbolLine(5 35 5 45 8)
+	SymbolLine(5 45 10 50 8)
+)
+Symbol('|' 12)
+(
+	SymbolLine(0 10 0 50 8)
+)
+Symbol('}' 12)
+(
+	SymbolLine(0 10 5 15 8)
+	SymbolLine(5 15 5 25 8)
+	SymbolLine(5 25 10 30 8)
+	SymbolLine(5 35 10 30 8)
+	SymbolLine(5 35 5 45 8)
+	SymbolLine(0 50 5 45 8)
+)
+Symbol('~' 12)
+(
+	SymbolLine(0 35 5 30 8)
+	SymbolLine(5 30 10 30 8)
+	SymbolLine(10 30 15 35 8)
+	SymbolLine(15 35 20 35 8)
+	SymbolLine(20 35 25 30 8)
+)
+Via[90000 50000 6000 2000 0 3500 "" ""]
+Layer(1 "component")
+(
+	Line[10000 50000 90000 50000 4000 2000 "clearline"]
+)
+Layer(2 "solder")
+(
+	Line[170000 50000 90000 50000 4000 2000 "clearline"]
+)
+Layer(3 "GND")
+(
+)
+Layer(4 "power")
+(
+)
+Layer(5 "signal1")
+(
+)
+Layer(6 "signal2")
+(
+)
+Layer(7 "signal3")
+(
+)
+Layer(8 "signal4")
+(
+)
+Layer(9 "silk")
+(
+)
+Layer(10 "silk")
+(
+)
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 3892856..0667fb8 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -333,7 +333,7 @@ compare_bom() {
     #  8,"Dual in-line package, narrow (300 mil)","DIP8",UDIP90_TOP UDIP180_TOP UDIP270_TOP UDIP0_TOP UDIP270_BOT UDIP180_BOT UDIP90_BOT UDIP0_BOT 
     #  8,"Small outline package, narrow (150mil)","SO8",USO90_TOP USO180_TOP USO270_TOP USO0_TOP USO270_BOT USO180_BOT USO90_BOT USO0_BOT 
 
-    #  For comparison, we need to ignore chnages in the Date and Author lines.
+    #  For comparison, we need to ignore changes in the Date and Author lines.
     cf1=${tmpd}/`basename $f1` 
     cf2=${tmpd}/`basename $f2` 
 
@@ -355,6 +355,36 @@ compare_xy() {
 
 ##########################################################################
 #
+# GCODE comparison routines
+#
+
+# used to remove things like creation date from gcode files
+normalize_gcode() {
+    f1="$1"
+    f2="$2"
+    $AWK '
+	d == 1 {gsub(/ .* /, "Creation Date and Time"); d = 0;}
+	/^\(Created by G-code exporter\)/ {d=1}
+	{print}' \
+	$f1 > $f2
+}
+
+compare_gcode() {
+    f1="$1"
+    f2="$2"
+    compare_check "compare_gcode" "$f1" "$f2" || return 1
+
+    #  For comparison, we need to ignore changes in the Date and Author lines.
+    cf1=${tmpd}/`basename $f1` 
+    cf2=${tmpd}/`basename $f2` 
+
+    normalize_gcode $f1 $cf1
+    normalize_gcode $f2 $cf2
+    run_diff "$cf1" "$cf2" || test_failed=yes
+}
+
+##########################################################################
+#
 # RS274-X and Excellon comparison
 #
 
@@ -549,6 +579,11 @@ for t in $all_tests ; do
 		    compare_xy ${refdir}/${fn} ${rundir}/${fn}
 		    ;;
 
+		# GCODE HID
+		gcode)
+		    compare_gcode ${refdir}/${fn} ${rundir}/${fn}
+		    ;;
+
 		# GERBER HID
 		cnc)
 		    compare_cnc ${refdir}/${fn} ${rundir}/${fn}
diff --git a/tests/tests.list b/tests/tests.list
index 8949763..95af71d 100644
--- a/tests/tests.list
+++ b/tests/tests.list
@@ -55,6 +55,12 @@
 #    bom -- PCB bill of materials file
 #    xy  -- PCB centroid file
 #
+# GCODE
+#
+#    gcode -- G-Code file.  Note that these typically have .cnc as the 
+#             extension but we're already using the 'cnc' type for 
+#             Excellon drill files.
+#
 # GERBER
 #
 #    cnc -- Excellon drill file
@@ -66,7 +72,6 @@
 #    jpg -- JPEG file
 #    png -- Portable network graphics (PNG) file
 #
-#    
 ######################################################################
 # ---------------------------------------------
 # BOM export HID
@@ -88,6 +93,33 @@ hid_bom4 | bom_general.pcb | bom | --xy-in-mm | |  bom:bom_general.bom xy:bom_ge
 #
 ######################################################################
 # ---------------------------------------------
+# Gcode export HID
+# ---------------------------------------------
+######################################################################
+#
+# options:
+# --basename <string>            File name prefix
+# --dpi <num>                    Resolution of intermediate image (pixels/inch).
+# --mill depth <num>             Milling depth.
+# --safe Z <num>                 Safe Z for traverse move.
+# --tool radius <num>            Milling tool radius compensation.
+# --drill depth <num>            Drilling depth.
+# --measurement unit <mm|mil|um|inch>    Measurement unit
+#
+hid_gcode1 | gcode_oneline.pcb | gcode | | | gcode:gcode_oneline.gcode.front.cnc gcode:gcode_oneline.gcode.back.cnc gcode:gcode_oneline.gcode.drill.cnc
+hid_gcode2 | gcode_oneline.pcb | gcode | --basename out | | gcode:out.front.cnc gcode:out.back.cnc gcode:out.drill.cnc
+hid_gcode3 | gcode_oneline.pcb | gcode | --dpi 1200 | | gcode:gcode_oneline.gcode.front.cnc gcode:gcode_oneline.gcode.back.cnc gcode:gcode_oneline.gcode.drill.cnc
+hid_gcode4 | gcode_oneline.pcb | gcode | --mill-depth 5 | | gcode:gcode_oneline.gcode.front.cnc gcode:gcode_oneline.gcode.back.cnc gcode:gcode_oneline.gcode.drill.cnc
+hid_gcode5 | gcode_oneline.pcb | gcode | --safe-Z 10 | | gcode:gcode_oneline.gcode.front.cnc gcode:gcode_oneline.gcode.back.cnc gcode:gcode_oneline.gcode.drill.cnc
+hid_gcode6 | gcode_oneline.pcb | gcode | --tool-radius 15 | | gcode:gcode_oneline.gcode.front.cnc gcode:gcode_oneline.gcode.back.cnc gcode:gcode_oneline.gcode.drill.cnc
+hid_gcode7 | gcode_oneline.pcb | gcode | --drill-depth 70 | | gcode:gcode_oneline.gcode.front.cnc gcode:gcode_oneline.gcode.back.cnc gcode:gcode_oneline.gcode.drill.cnc
+hid_gcode8 | gcode_oneline.pcb | gcode | --measurement-unit mm | | gcode:gcode_oneline.gcode.front.cnc gcode:gcode_oneline.gcode.back.cnc gcode:gcode_oneline.gcode.drill.cnc
+hid_gcode9 | gcode_oneline.pcb | gcode | --measurement-unit mil | | gcode:gcode_oneline.gcode.front.cnc gcode:gcode_oneline.gcode.back.cnc gcode:gcode_oneline.gcode.drill.cnc
+hid_gcode10 | gcode_oneline.pcb | gcode | --measurement-unit um | | gcode:gcode_oneline.gcode.front.cnc gcode:gcode_oneline.gcode.back.cnc gcode:gcode_oneline.gcode.drill.cnc
+hid_gcode11 | gcode_oneline.pcb | gcode | --measurement-unit inch | | gcode:gcode_oneline.gcode.front.cnc gcode:gcode_oneline.gcode.back.cnc gcode:gcode_oneline.gcode.drill.cnc
+#
+######################################################################
+# ---------------------------------------------
 # Gerber export HID
 # ---------------------------------------------
 ######################################################################
@@ -129,4 +161,3 @@ hid_gerber2 | gerber_oneline.pcb | gerber | --gerberfile out | | gbx:out.back.gb
 hid_png1 | gerber_oneline.pcb | png | | | png:gerber_oneline.png
 #
 
-

commit fd1c65c236bdcd4b36400e82074d66ab83bc5de3
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Remove RCSID.  We don't use those anymore.

diff --git a/src/hid/gcode/gcode.c b/src/hid/gcode/gcode.c
index 3767ad4..bbc1d53 100644
--- a/src/hid/gcode/gcode.c
+++ b/src/hid/gcode/gcode.c
@@ -64,8 +64,6 @@
 #include <dmalloc.h>
 #endif
 
-RCSID ("$Id: gcode.c, v 0.1 2010/2/8 14:00:00 Alberto Maccioni Exp $");
-
 #define CRASH fprintf(stderr, "HID error: pcb called unimplemented GCODE function %s.\n", __FUNCTION__); abort()
 #define pcb_unit 100000.0	/* pcb internal units per inch */
 struct color_struct

commit b6378a3845066adb23601d8fa781fd58233176dd
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Change options like 'drill depth' to 'drill-depth' as a space in
    a command line option is non-standard.  Also be consistent with
    having or not having a "." at the end of the option help strings.

diff --git a/src/hid/gcode/gcode.c b/src/hid/gcode/gcode.c
index c5ca8df..3767ad4 100644
--- a/src/hid/gcode/gcode.c
+++ b/src/hid/gcode/gcode.c
@@ -148,27 +148,27 @@ HID_Attribute gcode_attribute_list[] = {
    HID_String, 0, 0, {0, 0, 0}, 0, 0},
 #define HA_basename 0
 
-  {"dpi", "Resolution of intermediate image (pixels/inch).",
+  {"dpi", "Resolution of intermediate image (pixels/inch)",
    HID_Integer, 0, 2000, {600, 0, 0}, 0, 0},
 #define HA_dpi 1
 
-  {"mill depth", "Milling depth.",
+  {"mill-depth", "Milling depth",
    HID_Real, -1000, 1000, {0, 0, -0.05}, 0, 0},
 #define HA_cutdepth 2
 
-  {"safe Z", "Safe Z for traverse move.",
+  {"safe-Z", "Safe Z for traverse move",
    HID_Real, -1000, 10000, {0, 0, 2}, 0, 0},
 #define HA_safeZ 3
 
-  {"tool radius", "Milling tool radius compensation.",
+  {"tool-radius", "Milling tool radius compensation",
    HID_Real, 0, 10000, {0, 0, 0.1}, 0, 0},
 #define HA_toolradius 4
 
-  {"drill depth", "Drilling depth.",
+  {"drill-depth", "Drilling depth",
    HID_Real, -10000, 10000, {0, 0, -2}, 0, 0},
 #define HA_drilldepth 5
 
-  {"measurement unit", "Measurement unit",
+  {"measurement-unit", "Measurement unit",
    HID_Enum, 0, 0, {0, 0, 0}, units, 0},
 #define HA_unit 6
 

commit c544e63eca400b33127ac539e4737c7959e8db2c
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Remove unix2dos system() call.  It was not needed.

diff --git a/src/hid/gcode/gcode.c b/src/hid/gcode/gcode.c
index 317e6a1..c5ca8df 100644
--- a/src/hid/gcode/gcode.c
+++ b/src/hid/gcode/gcode.c
@@ -617,7 +617,7 @@ gcode_do_export (HID_Attr_Val * options)
 	      n_drill = nmax_drill = 0;
 	    }
 	  free (filename);
-	  system ("unix2dos *.cnc");
+
 /* ******************* end gcode conversion **************************** */
 	  gcode_finish_png ();
 	}

commit 9babb216b2921ad716b740068988d04a0d9dfe45
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Get rid of compiler warnings.

diff --git a/src/hid/gcode/trace.c b/src/hid/gcode/trace.c
index 5f1c48e..8d7e5e6 100644
--- a/src/hid/gcode/trace.c
+++ b/src/hid/gcode/trace.c
@@ -12,6 +12,7 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include "global.h"
 #include "potracelib.h"
 #include "curve.h"
 #include "lists.h"
@@ -968,7 +969,7 @@ malloc_error:
 
 /* Always succeeds and returns 0 */
 static int
-smooth (privcurve_t * curve, int sign, double alphamax)
+ATTRIBUTE_UNUSED smooth (privcurve_t * curve, int sign, double alphamax)
 {
   int m = curve->n;
 
@@ -1233,7 +1234,7 @@ opti_penalty (privpath_t * pp, int i, int j, opti_t * res,
    single segment when possible. Return 0 on success, 1 with errno set
    on failure. */
 static int
-opticurve (privpath_t * pp, double opttolerance)
+ATTRIBUTE_UNUSED opticurve (privpath_t * pp, double opttolerance)
 {
   int m = pp->curve.n;
   int *pt = NULL;		/* pt[m+1] */
@@ -1404,15 +1405,23 @@ plotpolygon (privpath_t * pp, FILE * f, double scale)
 {
   int i;
   int m = pp->m;
-  if (!m)
-    return 0;
   int *po = pp->po;
   int n = pp->len;
   point_t *pt = pp->pt;
   int x0 = pp->x0;
   int y0 = pp->y0;
-  //double scale=1.0/dpi;
+  /* double scale=1.0/dpi; */
   double dm = 0;
+
+  if (!m)
+    return 0;
+
+  po = pp->po;
+  n = pp->len;
+  pt = pp->pt;
+  x0 = pp->x0;
+  y0 = pp->y0;
+
   fprintf (f, "G0 X%f Y%f    (start point)\n", pt[po[0]].x * scale,
 	   pt[po[0]].y * scale);
   fprintf (f, "G1 Z#101\n");
@@ -1447,7 +1456,6 @@ process_path (path_t * plist, const potrace_param_t * param,
 	      const potrace_bitmap_t * bm, FILE * f, double scale)
 {
   path_t *p;
-  double nn = 0, cn = 0;
   double dm = 0;
   int n = 0;
   /* call downstream function with each path */
@@ -1469,7 +1477,7 @@ process_path (path_t * plist, const potrace_param_t * param,
     }
     privcurve_to_curve(p->priv->fcurve, &p->curve);*/
   }
-//      fprintf(f,"(end, total distance %.2fmm = %.2fin)\n",25.4*dm,dm);
+/*      fprintf(f,"(end, total distance %.2fmm = %.2fin)\n",25.4*dm,dm); */
   return dm;
 
 try_error:

commit 0e008cb83dcfc4fc6a3455bdd3c8dd86ed65b374
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Get rid of some gcc warnings.

diff --git a/src/hid/gcode/gcode.c b/src/hid/gcode/gcode.c
index 6d022ce..317e6a1 100644
--- a/src/hid/gcode/gcode.c
+++ b/src/hid/gcode/gcode.c
@@ -216,6 +216,7 @@ sort_drill (struct drill_struct *drill, int n_drill)
   for (j = 0; j < n_drill; j++)
     {
       dmin = 1e20;
+      imin = 0;
       for (i = 0; i < n_drill - j; i++)
 	{
 	  d =
@@ -626,7 +627,7 @@ gcode_do_export (HID_Attr_Val * options)
 /* *** PNG export (slightly modified code from PNG export HID) ************* */
 
 static int
-gcode_set_layer (const char *name, int group)
+gcode_set_layer (const char *name, int group, int empty)
 {
   int idx = (group >= 0 && group < max_layer) ?
     PCB->LayerGroups.Entries[group][0] : group;

commit 290c968566837132afbfc63d5fe1436c03dcec1e
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    C++ style comments -> C style comments

diff --git a/src/hid/gcode/gcode.c b/src/hid/gcode/gcode.c
index e8c38db..6d022ce 100644
--- a/src/hid/gcode/gcode.c
+++ b/src/hid/gcode/gcode.c
@@ -67,7 +67,7 @@
 RCSID ("$Id: gcode.c, v 0.1 2010/2/8 14:00:00 Alberto Maccioni Exp $");
 
 #define CRASH fprintf(stderr, "HID error: pcb called unimplemented GCODE function %s.\n", __FUNCTION__); abort()
-#define pcb_unit 100000.0	//pcb internal units per inch
+#define pcb_unit 100000.0	/* pcb internal units per inch */
 struct color_struct
 {
   /* the descriptor used by the gd library */
@@ -119,10 +119,10 @@ static char *gcode_basename = NULL;
 /* Horizontal DPI (grid points per inch) */
 static int gcode_dpi = -1;
 
-static double gcode_cutdepth = 0;	//milling depth (inch)
-static double gcode_drilldepth = 0;	//drilling depth (inch)
-static double gcode_safeZ = 100;	//safe Z (inch)
-static double gcode_toolradius = 0;	//tool radius(inch)
+static double gcode_cutdepth = 0;	/* milling depth (inch) */
+static double gcode_drilldepth = 0;	/* drilling depth (inch) */
+static double gcode_safeZ = 100;	/* safe Z (inch) */
+static double gcode_toolradius = 0;	/* tool radius(inch) */
 static int save_drill = 0;
 static int n_drill = 0;
 static int nmax_drill = 0;
@@ -186,7 +186,7 @@ REGISTER_ATTRIBUTES (gcode_attribute_list)
 {
   int gcode;
 
-  gcode = (pcb * gcode_dpi) / pcb_unit;	//100000;
+  gcode = (pcb * gcode_dpi) / pcb_unit;
 
   return gcode;
 }
@@ -205,7 +205,7 @@ gcode_get_png_name (const char *basename, const char *suffix)
   return buf;
 }
 
-//Sorts drills in order of distance from the origin
+/* Sorts drills in order of distance from the origin */
 struct drill_struct *
 sort_drill (struct drill_struct *drill, int n_drill)
 {
@@ -228,7 +228,7 @@ sort_drill (struct drill_struct *drill, int n_drill)
 	      dmin = d;
 	    }
 	}
-      //printf("j=%d imin=%d dmin=%f p=(%f,%f)\n",j,imin,dmin,p.x,p.y);
+      /* printf("j=%d imin=%d dmin=%f p=(%f,%f)\n",j,imin,dmin,p.x,p.y); */
       temp[j] = drill[imin];
       drill[imin] = drill[n_drill - j - 1];
       p = temp[j];
@@ -390,16 +390,16 @@ gcode_do_export (HID_Attr_Val * options)
   path_t *plist = NULL;
   potrace_bitmap_t *bm = NULL;
   potrace_param_t param_default = {
-    2,				// turdsize
-    POTRACE_TURNPOLICY_MINORITY,	// turnpolicy 
-    1.0,			// alphamax 
-    1,				// opticurve 
-    0.2,			// opttolerance 
+    2,				/* turnsize */
+    POTRACE_TURNPOLICY_MINORITY,	/* turnpolicy */
+    1.0,			/* alphamax */
+    1,				/* opticurve */
+    0.2,			/* opttolerance */
     {
-     NULL,			// callback function 
-     NULL,			// callback data 
-     0.0, 1.0,			// progress range 
-     0.0,			// granularity 
+     NULL,			/* callback function */
+     NULL,			/* callback data */
+     0.0, 1.0,			/* progress range  */
+     0.0,			/* granularity  */
      },
   };
 
@@ -428,25 +428,25 @@ gcode_do_export (HID_Attr_Val * options)
   switch (options[HA_unit].int_value)
     {
     case 0:
-      scale = 1.0;		//mm
+      scale = 1.0;		/* mm */
       metric = 1;
       break;
     case 1:
-      scale = 0.001;		//mil
+      scale = 0.001;		/* mil */
       metric = 0;
       break;
     case 2:
-      scale = 0.001;		//um
+      scale = 0.001;		/* um */
       metric = 1;
       break;
     default:
-      scale = 1.0;		//inch
+      scale = 1.0;		/* inch */
       metric = 0;
     }
   gcode_cutdepth = options[HA_cutdepth].real_value * scale;
   gcode_drilldepth = options[HA_drilldepth].real_value * scale;
   gcode_safeZ = options[HA_safeZ].real_value * scale;
-  gcode_toolradius = options[HA_toolradius].real_value * scale * pcb_unit;	//in PCB units (1/100 mil)
+  gcode_toolradius = options[HA_toolradius].real_value * scale * pcb_unit;	/* in PCB units (1/100 mil) */
   if (metric)
     gcode_toolradius *= 1 / 25.4;
   gcode_choose_groups ();
@@ -465,19 +465,19 @@ gcode_do_export (HID_Attr_Val * options)
 	  is_solder =
 	    (GetLayerGroupNumberByNumber (idx) ==
 	     GetLayerGroupNumberByNumber (max_layer + SOLDER_LAYER)) ? 1 : 0;
-	  save_drill = is_solder;	//save drills for one layer only
+	  save_drill = is_solder;	/* save drills for one layer only */
 	  gcode_start_png (gcode_basename, layer_type_to_file_name (idx));
 	  hid_save_and_show_layer_ons (save_ons);
 	  gcode_start_png_export ();
 	  hid_restore_layer_ons (save_ons);
 
-//***************** gcode conversion ***************************
-// potrace uses a different kind of bitmap; for simplicity gcode_im is copied to this format
+/* ***************** gcode conversion *************************** */
+/* potrace uses a different kind of bitmap; for simplicity gcode_im is copied to this format */
 	  bm = bm_new (gdImageSX (gcode_im), gdImageSY (gcode_im));
 	  filename = malloc (512);
 	  plist = NULL;
 	  if (is_solder)
-	    {			//only for back layer
+	    {			/* only for back layer */
 	      gdImagePtr temp_im =
 		gdImageCreate (gdImageSX (gcode_im), gdImageSY (gcode_im));
 	      gdImageCopy (temp_im, gcode_im, 0, 0, 0, 0,
@@ -532,14 +532,14 @@ gcode_do_export (HID_Attr_Val * options)
 	  fprintf (gcode_f2, "G17 G%d G90 G64 P0.003 M3 S3000 M7 F%d\n",
 		   metric ? 21 : 20, metric ? 25 : 1);
 	  fprintf (gcode_f2, "G0 Z#100\n");
-	  //extract contour points from image
+	  /* extract contour points from image */
 	  r = bm_to_pathlist (bm, &plist, &param_default);
 	  if (r)
 	    {
 	      fprintf (stderr, "ERROR: pathlist function failed\n");
 	      return;
 	    }
-	  //generate best polygon and write vertices in g-code format
+	  /* generate best polygon and write vertices in g-code format */
 	  d =
 	    process_path (plist, &param_default, bm, gcode_f2,
 			  metric ? 25.4 / gcode_dpi : 1.0 / gcode_dpi);
@@ -587,19 +587,19 @@ gcode_do_export (HID_Attr_Val * options)
 	      fprintf (gcode_f2, "(---------------------------------)\n");
 	      fprintf (gcode_f2, "G17 G%d G90 G64 P0.003 M3 S3000 M7 F%d\n",
 		       metric ? 21 : 20, metric ? 25 : 1);
-//                              fprintf(gcode_f2,"G0 Z#100\n");
+/*                              fprintf(gcode_f2,"G0 Z#100\n"); */
 	      for (r = 0; r < n_drill; r++)
 		{
-//                                      if(metric) fprintf(gcode_f2,"G0 X%f Y%f\n",drill[r].x*25.4,drill[r].y*25.4);
-//                                      else fprintf(gcode_f2,"G0 X%f Y%f\n",drill[r].x,drill[r].y);
+/*                                      if(metric) fprintf(gcode_f2,"G0 X%f Y%f\n",drill[r].x*25.4,drill[r].y*25.4); */
+/*                                      else fprintf(gcode_f2,"G0 X%f Y%f\n",drill[r].x,drill[r].y); */
 		  if (metric)
 		    fprintf (gcode_f2, "G81 X%f Y%f Z#101 R#100\n",
 			     drill[r].x * 25.4, drill[r].y * 25.4);
 		  else
 		    fprintf (gcode_f2, "G81 X%f Y%f Z#101 R#100\n",
 			     drill[r].x, drill[r].y);
-//                                      fprintf(gcode_f2,"G1 Z#101\n");
-//                                      fprintf(gcode_f2,"G0 Z#100\n");
+/*                                      fprintf(gcode_f2,"G1 Z#101\n"); */
+/*                                      fprintf(gcode_f2,"G0 Z#100\n"); */
 		  if (r > 0)
 		    d +=
 		      sqrt ((drill[r].x - drill[r - 1].x) * (drill[r].x -
@@ -617,7 +617,7 @@ gcode_do_export (HID_Attr_Val * options)
 	    }
 	  free (filename);
 	  system ("unix2dos *.cnc");
-//******************* end gcode conversion ****************************
+/* ******************* end gcode conversion **************************** */
 	  gcode_finish_png ();
 	}
     }
@@ -873,7 +873,7 @@ gcode_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
 		    pcb_to_gcode (y1 - gcode_toolradius),
 		    pcb_to_gcode (x2 + gcode_toolradius),
 		    pcb_to_gcode (y2 + gcode_toolradius), gc->color->c);
-//      printf("Rect %d %d %d %d\n",x1,y1,x2,y2);
+/*      printf("Rect %d %d %d %d\n",x1,y1,x2,y2); */
 }
 
 static void
@@ -887,7 +887,7 @@ gcode_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
 			  pcb_to_gcode (y1 - gcode_toolradius),
 			  pcb_to_gcode (x2 + gcode_toolradius),
 			  pcb_to_gcode (y2 + gcode_toolradius), gc->color->c);
-//      printf("FillRect %d %d %d %d\n",x1,y1,x2,y2);
+/*      printf("FillRect %d %d %d %d\n",x1,y1,x2,y2); */
 }
 
 static void
@@ -983,10 +983,10 @@ gcode_fill_circle (hidGC gc, int cx, int cy, int radius)
 					     sizeof (struct drill_struct));
 	  nmax_drill += 100;
 	}
-      drill[n_drill].x = (PCB->MaxWidth - cx) / pcb_unit;	//convert to inch, flip: will drill from bottom side
-      drill[n_drill].y = (PCB->MaxHeight - cy) / pcb_unit;	//PCB reverses y axis
+      drill[n_drill].x = (PCB->MaxWidth - cx) / pcb_unit;	/* convert to inch, flip: will drill from bottom side */
+      drill[n_drill].y = (PCB->MaxHeight - cy) / pcb_unit;	/* PCB reverses y axis */
       n_drill++;
-//              printf("Circle %d %d\n",cx,cy);
+/*              printf("Circle %d %d\n",cx,cy); */
     }
 }
 
@@ -1012,7 +1012,7 @@ gcode_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
   linewidth = 0;
   gdImageFilledPolygon (gcode_im, points, n_coords, gc->color->c);
   free (points);
-//      printf("FillPoly\n");
+/*      printf("FillPoly\n"); */
 }
 
 static void
@@ -1098,3 +1098,4 @@ hid_gcode_init ()
 
 #include "gcode_lists.h"
 }
+

commit 073463e605095692e2cf8d4238df0c817e68e3c3
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Fix nroff error.   Noted in sf patch #2889227 by Ahmed El-Mahmoudy.

diff --git a/doc/pcb.1 b/doc/pcb.1
index 3dd9867..b84c653 100644
--- a/doc/pcb.1
+++ b/doc/pcb.1
@@ -1,4 +1,3 @@
-.\"  $Id$
 .\"
 .\"  This program is free software; you can redistribute it and/or modify
 .\"  it under the terms of the GNU General Public License as published by
@@ -36,8 +35,8 @@ The texinfo version of the manual is typically viewed with the
 program or alternatively with 
 .B emacs
 or a graphical info viewer such as
-.B tkinfo
-.  The PDF and HTML documentation is typically installed as
+.B tkinfo.
+The PDF and HTML documentation is typically installed as
 /usr/local/share/pcb/pcb.html and /usr/local/share/pcb/pcb.pdf.
 The prefix "/usr/local" may vary at your site.
 

commit ca738957694927538dad15f037d5622571fd3173
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    add the gcode exporter to the export hid list

diff --git a/configure.ac b/configure.ac
index d5578fb..356e02e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -395,7 +395,7 @@ esac
 
 AC_MSG_CHECKING([for which exporters to use])
 AC_ARG_WITH([exporters],
-[  --with-exporters=       Enable export devices: bom gerber nelma png ps [[default=bom gerber nelma png ps]]],
+[  --with-exporters=       Enable export devices: bom gerber gcode nelma png ps [[default=bom gerber gcode nelma png ps]]],
 [],[with_exporters=$hid_exporters])
 AC_MSG_RESULT([$with_exporters])
 for e in `echo $with_exporters | sed 's/,/ /g'`; do

commit 7467c8b2cedb80ee32e2ff19662d6894a6d7f345
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    add notes about what libs may be needed (none) for the gcode exporter.

diff --git a/INSTALL b/INSTALL
index 1dfa0f8..db27639 100644
--- a/INSTALL
+++ b/INSTALL
@@ -59,6 +59,9 @@ Export HID's:
 		 formats hopefully it will avoid suprises when the
 		 disabled formats are not available at runtime.
 
+     gcode   -- CNC G-CODE output (experimental).  No
+		 additional libraries are needed for this.
+
     The choice of which export HID's to compile is indicated with:
 
       --with-exporters="ps gerber bom png"

commit 19f7443c3249a9cc40efd04c1895b89445add385
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    indent to conform to the coding style used by pcb.

diff --git a/src/hid/gcode/auxiliary.h b/src/hid/gcode/auxiliary.h
index 7baab85..254e4c0 100644
--- a/src/hid/gcode/auxiliary.h
+++ b/src/hid/gcode/auxiliary.h
@@ -17,7 +17,8 @@
 
 #include "potracelib.h"
 
-struct point_s {
+struct point_s
+{
   long x;
   long y;
 };
@@ -26,7 +27,9 @@ typedef struct point_s point_t;
 typedef potrace_dpoint_t dpoint_t;
 
 /* convert point_t to dpoint_t */
-static inline dpoint_t dpoint(point_t p) {
+static inline dpoint_t
+dpoint (point_t p)
+{
   dpoint_t res;
   res.x = p.x;
   res.y = p.y;
@@ -34,7 +37,9 @@ static inline dpoint_t dpoint(point_t p) {
 }
 
 /* range over the straight line segment [a,b] when lambda ranges over [0,1] */
-static inline dpoint_t interval(double lambda, dpoint_t a, dpoint_t b) {
+static inline dpoint_t
+interval (double lambda, dpoint_t a, dpoint_t b)
+{
   dpoint_t res;
 
   res.x = a.x + lambda * (b.x - a.x);
@@ -53,12 +58,16 @@ static inline dpoint_t interval(double lambda, dpoint_t a, dpoint_t b) {
 
 /* integer arithmetic */
 
-static inline int mod(int a, int n) {
-  return a>=n ? a%n : a>=0 ? a : n-1-(-1-a)%n;
+static inline int
+mod (int a, int n)
+{
+  return a >= n ? a % n : a >= 0 ? a : n - 1 - (-1 - a) % n;
 }
 
-static inline int floordiv(int a, int n) {
-  return a>=0 ? a/n : -1-(-1-a)/n;
+static inline int
+floordiv (int a, int n)
+{
+  return a >= 0 ? a / n : -1 - (-1 - a) / n;
 }
 
 /* Note: the following work for integers and other numeric types. */
diff --git a/src/hid/gcode/bitmap.h b/src/hid/gcode/bitmap.h
index 2a172b1..589b80b 100644
--- a/src/hid/gcode/bitmap.h
+++ b/src/hid/gcode/bitmap.h
@@ -48,54 +48,69 @@
 #define BM_PUT(bm, x, y, b) (bm_safe(bm, x, y) ? BM_UPUT(bm, x, y, b) : 0)
 
 /* free the given bitmap. Leaves errno untouched. */
-static inline void bm_free(potrace_bitmap_t *bm) {
-  if (bm) {
-    free(bm->map);
-  }
-  free(bm);
+static inline void
+bm_free (potrace_bitmap_t * bm)
+{
+  if (bm)
+    {
+      free (bm->map);
+    }
+  free (bm);
 }
 
 /* return new un-initialized bitmap. NULL with errno on error */
-static inline potrace_bitmap_t *bm_new(int w, int h) {
+static inline potrace_bitmap_t *
+bm_new (int w, int h)
+{
   potrace_bitmap_t *bm;
   int dy = (w + BM_WORDBITS - 1) / BM_WORDBITS;
 
-  bm = (potrace_bitmap_t *) malloc(sizeof(potrace_bitmap_t));
-  if (!bm) {
-    return NULL;
-  }
+  bm = (potrace_bitmap_t *) malloc (sizeof (potrace_bitmap_t));
+  if (!bm)
+    {
+      return NULL;
+    }
   bm->w = w;
   bm->h = h;
   bm->dy = dy;
-  bm->map = (potrace_word *) malloc(dy * h * BM_WORDSIZE);
-  if (!bm->map) {
-    free(bm);
-    return NULL;
-  }
+  bm->map = (potrace_word *) malloc (dy * h * BM_WORDSIZE);
+  if (!bm->map)
+    {
+      free (bm);
+      return NULL;
+    }
   return bm;
 }
 
 /* clear the given bitmap. Set all bits to c. */
-static inline void bm_clear(potrace_bitmap_t *bm, int c) {
-  memset(bm->map, c ? -1 : 0, bm->dy * bm->h * BM_WORDSIZE);
+static inline void
+bm_clear (potrace_bitmap_t * bm, int c)
+{
+  memset (bm->map, c ? -1 : 0, bm->dy * bm->h * BM_WORDSIZE);
 }
 
 /* duplicate the given bitmap. Return NULL on error with errno set. */
-static inline potrace_bitmap_t *bm_dup(const potrace_bitmap_t *bm) {
-  potrace_bitmap_t *bm1 = bm_new(bm->w, bm->h);
-  if (!bm1) {
-    return NULL;
-  }
-  memcpy(bm1->map, bm->map, bm->dy * bm->h * BM_WORDSIZE);
+static inline potrace_bitmap_t *
+bm_dup (const potrace_bitmap_t * bm)
+{
+  potrace_bitmap_t *bm1 = bm_new (bm->w, bm->h);
+  if (!bm1)
+    {
+      return NULL;
+    }
+  memcpy (bm1->map, bm->map, bm->dy * bm->h * BM_WORDSIZE);
   return bm1;
 }
 
 /* invert the given bitmap. */
-static inline void bm_invert(potrace_bitmap_t *bm) {
+static inline void
+bm_invert (potrace_bitmap_t * bm)
+{
   int i;
-  for (i = 0; i < bm->dy * bm->h; i++) {
-    bm->map[i] ^= BM_ALLBITS;
-  }
+  for (i = 0; i < bm->dy * bm->h; i++)
+    {
+      bm->map[i] ^= BM_ALLBITS;
+    }
 }
 
 #endif /* BITMAP_H */
diff --git a/src/hid/gcode/curve.c b/src/hid/gcode/curve.c
index 0dc1005..abf85d7 100644
--- a/src/hid/gcode/curve.c
+++ b/src/hid/gcode/curve.c
@@ -14,61 +14,72 @@
 #include "curve.h"
 
 #define SAFE_MALLOC(var, n, typ) \
-  if ((var = (typ *)malloc((n)*sizeof(typ))) == NULL) goto malloc_error 
+  if ((var = (typ *)malloc((n)*sizeof(typ))) == NULL) goto malloc_error
 
 /* ---------------------------------------------------------------------- */
 /* allocate and free path objects */
 
-path_t *path_new(void) {
+path_t *
+path_new (void)
+{
   path_t *p = NULL;
   privpath_t *priv = NULL;
 
-  SAFE_MALLOC(p, 1, path_t);
-  memset(p, 0, sizeof(path_t));
-  SAFE_MALLOC(priv, 1, privpath_t);
-  memset(priv, 0, sizeof(privpath_t));
+  SAFE_MALLOC (p, 1, path_t);
+  memset (p, 0, sizeof (path_t));
+  SAFE_MALLOC (priv, 1, privpath_t);
+  memset (priv, 0, sizeof (privpath_t));
   p->priv = priv;
   return p;
 
- malloc_error:
-  free(p);
-  free(priv);
+malloc_error:
+  free (p);
+  free (priv);
   return NULL;
 }
 
 /* free the members of the given curve structure. Leave errno unchanged. */
-static void privcurve_free_members(privcurve_t *curve) {
-  free(curve->tag);
-  free(curve->c);
-  free(curve->vertex);
-  free(curve->alpha);
-  free(curve->alpha0);
-  free(curve->beta);
+static void
+privcurve_free_members (privcurve_t * curve)
+{
+  free (curve->tag);
+  free (curve->c);
+  free (curve->vertex);
+  free (curve->alpha);
+  free (curve->alpha0);
+  free (curve->beta);
 }
 
 /* free a path. Leave errno untouched. */
-void path_free(path_t *p) {
-  if (p) {
-    if (p->priv) {
-      free(p->priv->pt);
-      free(p->priv->lon);
-      free(p->priv->sums);
-      free(p->priv->po);
-      privcurve_free_members(&p->priv->curve);
-      privcurve_free_members(&p->priv->ocurve);
+void
+path_free (path_t * p)
+{
+  if (p)
+    {
+      if (p->priv)
+	{
+	  free (p->priv->pt);
+	  free (p->priv->lon);
+	  free (p->priv->sums);
+	  free (p->priv->po);
+	  privcurve_free_members (&p->priv->curve);
+	  privcurve_free_members (&p->priv->ocurve);
+	}
+      free (p->priv);
+      /* do not free p->fcurve ! */
     }
-    free(p->priv);
-    /* do not free p->fcurve ! */
-  }
-  free(p);
-}  
+  free (p);
+}
 
 /* free a pathlist, leaving errno untouched. */
-void pathlist_free(path_t *plist) {
+void
+pathlist_free (path_t * plist)
+{
   path_t *p;
 
-  list_forall_unlink(p, plist) {
-    path_free(p);
+  list_forall_unlink (p, plist)
+  {
+    path_free (p);
   }
 }
 
@@ -79,31 +90,34 @@ typedef dpoint_t dpoint3_t[3];
 
 /* initialize the members of the given curve structure to size m.
    Return 0 on success, 1 on error with errno set. */
-int privcurve_init(privcurve_t *curve, int n) {
-  memset(curve, 0, sizeof(privcurve_t));
+int
+privcurve_init (privcurve_t * curve, int n)
+{
+  memset (curve, 0, sizeof (privcurve_t));
   curve->n = n;
-  SAFE_MALLOC(curve->tag, n, int);
-  SAFE_MALLOC(curve->c, n, dpoint3_t);
-  SAFE_MALLOC(curve->vertex, n, dpoint_t);
-  SAFE_MALLOC(curve->alpha, n, double);
-  SAFE_MALLOC(curve->alpha0, n, double);
-  SAFE_MALLOC(curve->beta, n, double);
+  SAFE_MALLOC (curve->tag, n, int);
+  SAFE_MALLOC (curve->c, n, dpoint3_t);
+  SAFE_MALLOC (curve->vertex, n, dpoint_t);
+  SAFE_MALLOC (curve->alpha, n, double);
+  SAFE_MALLOC (curve->alpha0, n, double);
+  SAFE_MALLOC (curve->beta, n, double);
   return 0;
 
- malloc_error:
-  free(curve->tag);
-  free(curve->c);
-  free(curve->vertex);
-  free(curve->alpha);
-  free(curve->alpha0);
-  free(curve->beta);
+malloc_error:
+  free (curve->tag);
+  free (curve->c);
+  free (curve->vertex);
+  free (curve->alpha);
+  free (curve->alpha0);
+  free (curve->beta);
   return 1;
 }
 
 /* copy private to public curve structure */
-void privcurve_to_curve(privcurve_t *pc, potrace_curve_t *c) {
+void
+privcurve_to_curve (privcurve_t * pc, potrace_curve_t * c)
+{
   c->n = pc->n;
   c->tag = pc->tag;
   c->c = pc->c;
 }
-    
diff --git a/src/hid/gcode/curve.h b/src/hid/gcode/curve.h
index 45c0790..6f7e8a1 100644
--- a/src/hid/gcode/curve.h
+++ b/src/hid/gcode/curve.h
@@ -15,23 +15,25 @@
    Beta is so that (.beta[i])[.vertex[i],.vertex[i+1]] = .c[i][2].
 */
 
-struct privcurve_s {
-  int n;            /* number of segments */
-  int *tag;         /* tag[n]: POTRACE_CORNER or POTRACE_CURVETO */
-  dpoint_t (*c)[3]; /* c[n][i]: control points. 
-		       c[n][0] is unused for tag[n]=POTRACE_CORNER */
+struct privcurve_s
+{
+  int n;			/* number of segments */
+  int *tag;			/* tag[n]: POTRACE_CORNER or POTRACE_CURVETO */
+    dpoint_t (*c)[3];		/* c[n][i]: control points. 
+				   c[n][0] is unused for tag[n]=POTRACE_CORNER */
   /* the remainder of this structure is special to privcurve, and is
      used in EPS debug output and special EPS "short coding". These
      fields are valid only if "alphacurve" is set. */
-  int alphacurve;   /* have the following fields been initialized? */
-  dpoint_t *vertex; /* for POTRACE_CORNER, this equals c[1] */
-  double *alpha;    /* only for POTRACE_CURVETO */
-  double *alpha0;   /* "uncropped" alpha parameter - for debug output only */
+  int alphacurve;		/* have the following fields been initialized? */
+  dpoint_t *vertex;		/* for POTRACE_CORNER, this equals c[1] */
+  double *alpha;		/* only for POTRACE_CURVETO */
+  double *alpha0;		/* "uncropped" alpha parameter - for debug output only */
   double *beta;
 };
 typedef struct privcurve_s privcurve_t;
 
-struct sums_s {
+struct sums_s
+{
   double x;
   double y;
   double x2;
@@ -45,21 +47,22 @@ typedef struct sums_s sums_t;
    Potrace algorithm. Backends only need to read the fcurve and fm
    fields of this data structure, but debugging backends may read
    other fields. */
-struct potrace_privpath_s {
+struct potrace_privpath_s
+{
   int len;
-  point_t *pt;     /* pt[len]: path as extracted from bitmap */
-  int *lon;        /* lon[len]: (i,lon[i]) = longest straight line from i */
+  point_t *pt;			/* pt[len]: path as extracted from bitmap */
+  int *lon;			/* lon[len]: (i,lon[i]) = longest straight line from i */
 
-  int x0, y0;      /* origin for sums */
-  sums_t *sums;    /* sums[len+1]: cache for fast summing */
+  int x0, y0;			/* origin for sums */
+  sums_t *sums;			/* sums[len+1]: cache for fast summing */
 
-  int m;           /* length of optimal polygon */
-  int *po;         /* po[m]: optimal polygon */
+  int m;			/* length of optimal polygon */
+  int *po;			/* po[m]: optimal polygon */
 
-  privcurve_t curve;   /* curve[m]: array of curve elements */
-  privcurve_t ocurve;  /* ocurve[om]: array of curve elements */
-  privcurve_t *fcurve;  /* final curve: this points to either curve or
-		       ocurve. Do not free this separately. */
+  privcurve_t curve;		/* curve[m]: array of curve elements */
+  privcurve_t ocurve;		/* ocurve[om]: array of curve elements */
+  privcurve_t *fcurve;		/* final curve: this points to either curve or
+				   ocurve. Do not free this separately. */
 };
 typedef struct potrace_privpath_s potrace_privpath_t;
 
@@ -67,11 +70,10 @@ typedef struct potrace_privpath_s potrace_privpath_t;
 typedef potrace_privpath_t privpath_t;
 typedef potrace_path_t path_t;
 
-path_t *path_new(void);
-void path_free(path_t *p);
-void pathlist_free(path_t *plist);
-int privcurve_init(privcurve_t *curve, int n);
-void privcurve_to_curve(privcurve_t *pc, potrace_curve_t *c);
+path_t *path_new (void);
+void path_free (path_t * p);
+void pathlist_free (path_t * plist);
+int privcurve_init (privcurve_t * curve, int n);
+void privcurve_to_curve (privcurve_t * pc, potrace_curve_t * c);
 
 #endif /* CURVE_H */
-
diff --git a/src/hid/gcode/decompose.c b/src/hid/gcode/decompose.c
index abc5e0a..0b42882 100644
--- a/src/hid/gcode/decompose.c
+++ b/src/hid/gcode/decompose.c
@@ -21,85 +21,105 @@
 /* auxiliary bitmap manipulations */
 
 /* set the excess padding to 0 */
-static void bm_clearexcess(potrace_bitmap_t *bm) {
+static void
+bm_clearexcess (potrace_bitmap_t * bm)
+{
   potrace_word mask;
   int y;
 
-  if (bm->w % BM_WORDBITS != 0) {
-    mask = BM_ALLBITS << (BM_WORDBITS - (bm->w % BM_WORDBITS));
-    for (y=0; y<bm->h; y++) {
-      *bm_index(bm, bm->w, y) &= mask;
+  if (bm->w % BM_WORDBITS != 0)
+    {
+      mask = BM_ALLBITS << (BM_WORDBITS - (bm->w % BM_WORDBITS));
+      for (y = 0; y < bm->h; y++)
+	{
+	  *bm_index (bm, bm->w, y) &= mask;
+	}
     }
-  }
 }
 
-struct bbox_s {
-  int x0, x1, y0, y1;    /* bounding box */
+struct bbox_s
+{
+  int x0, x1, y0, y1;		/* bounding box */
 };
 typedef struct bbox_s bbox_t;
 
 /* clear the bm, assuming the bounding box is set correctly (faster
    than clearing the whole bitmap) */
-static void clear_bm_with_bbox(potrace_bitmap_t *bm, bbox_t *bbox) {
+static void
+clear_bm_with_bbox (potrace_bitmap_t * bm, bbox_t * bbox)
+{
   int imin = (bbox->x0 / BM_WORDBITS);
-  int imax = ((bbox->x1 + BM_WORDBITS-1) / BM_WORDBITS);
+  int imax = ((bbox->x1 + BM_WORDBITS - 1) / BM_WORDBITS);
   int i, y;
 
-  for (y=bbox->y0; y<bbox->y1; y++) {
-    for (i=imin; i<imax; i++) {
-      bm_scanline(bm, y)[i] = 0;
+  for (y = bbox->y0; y < bbox->y1; y++)
+    {
+      for (i = imin; i < imax; i++)
+	{
+	  bm_scanline (bm, y)[i] = 0;
+	}
     }
-  }
 }
 
 /* ---------------------------------------------------------------------- */
 /* auxiliary functions */
 
 /* deterministically and efficiently hash (x,y) into a pseudo-random bit */
-static inline int detrand(int x, int y) {
+static inline int
+detrand (int x, int y)
+{
   unsigned int z;
-  static const unsigned char t[256] = { 
+  static const unsigned char t[256] = {
     /* non-linear sequence: constant term of inverse in GF(8), 
        mod x^8+x^4+x^3+x+1 */
-    0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 
-    0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 
-    0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 
-    1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 
-    0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 
-    0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 
-    0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 
-    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 
-    1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 
-    0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 
-    1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 
+    0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1,
+    0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0,
+    0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+    1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1,
+    0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0,
+    0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0,
+    0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0,
+    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1,
+    1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0,
+    0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1,
+    1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
   };
 
   /* 0x04b3e375 and 0x05a8ef93 are chosen to contain every possible
      5-bit sequence */
   z = ((0x04b3e375 * x) ^ y) * 0x05a8ef93;
-  z = t[z & 0xff] ^ t[(z>>8) & 0xff] ^ t[(z>>16) & 0xff] ^ t[(z>>24) & 0xff];
+  z =
+    t[z & 0xff] ^ t[(z >> 8) & 0xff] ^ t[(z >> 16) & 0xff] ^ t[(z >> 24) &
+							       0xff];
   return z & 1;
 }
 
 /* return the "majority" value of bitmap bm at intersection (x,y). We
    assume that the bitmap is balanced at "radius" 1.  */
-static int majority(potrace_bitmap_t *bm, int x, int y) {
+static int
+majority (potrace_bitmap_t * bm, int x, int y)
+{
   int i, a, ct;
 
-  for (i=2; i<5; i++) { /* check at "radius" i */
-    ct = 0;
-    for (a=-i+1; a<=i-1; a++) {
-      ct += BM_GET(bm, x+a, y+i-1) ? 1 : -1;
-      ct += BM_GET(bm, x+i-1, y+a-1) ? 1 : -1;
-      ct += BM_GET(bm, x+a-1, y-i) ? 1 : -1;
-      ct += BM_GET(bm, x-i, y+a) ? 1 : -1;
-    }
-    if (ct>0) {
-      return 1;
-    } else if (ct<0) {
-      return 0;
+  for (i = 2; i < 5; i++)
+    {				/* check at "radius" i */
+      ct = 0;
+      for (a = -i + 1; a <= i - 1; a++)
+	{
+	  ct += BM_GET (bm, x + a, y + i - 1) ? 1 : -1;
+	  ct += BM_GET (bm, x + i - 1, y + a - 1) ? 1 : -1;
+	  ct += BM_GET (bm, x + a - 1, y - i) ? 1 : -1;
+	  ct += BM_GET (bm, x - i, y + a) ? 1 : -1;
+	}
+      if (ct > 0)
+	{
+	  return 1;
+	}
+      else if (ct < 0)
+	{
+	  return 0;
+	}
     }
-  }
   return 0;
 }
 
@@ -108,25 +128,33 @@ static int majority(potrace_bitmap_t *bm, int x, int y) {
 
 /* efficiently invert bits [x,infty) and [xa,infty) in line y. Here xa
    must be a multiple of BM_WORDBITS. */
-static void xor_to_ref(potrace_bitmap_t *bm, int x, int y, int xa) {
+static void
+xor_to_ref (potrace_bitmap_t * bm, int x, int y, int xa)
+{
   int xhi = x & -BM_WORDBITS;
-  int xlo = x & (BM_WORDBITS-1);  /* = x % BM_WORDBITS */
+  int xlo = x & (BM_WORDBITS - 1);	/* = x % BM_WORDBITS */
   int i;
-  
-  if (xhi<xa) {
-    for (i = xhi; i < xa; i+=BM_WORDBITS) {
-      *bm_index(bm, i, y) ^= BM_ALLBITS;
+
+  if (xhi < xa)
+    {
+      for (i = xhi; i < xa; i += BM_WORDBITS)
+	{
+	  *bm_index (bm, i, y) ^= BM_ALLBITS;
+	}
     }
-  } else {
-    for (i = xa; i < xhi; i+=BM_WORDBITS) {
-      *bm_index(bm, i, y) ^= BM_ALLBITS;
+  else
+    {
+      for (i = xa; i < xhi; i += BM_WORDBITS)
+	{
+	  *bm_index (bm, i, y) ^= BM_ALLBITS;
+	}
     }
-  }
   /* note: the following "if" is needed because x86 treats a<<b as
      a<<(b&31). I spent hours looking for this bug. */
-  if (xlo) {
-    *bm_index(bm, xhi, y) ^= (BM_ALLBITS << (BM_WORDBITS - xlo));
-  }
+  if (xlo)
+    {
+      *bm_index (bm, xhi, y) ^= (BM_ALLBITS << (BM_WORDBITS - xlo));
+    }
 }
 
 /* a path is represented as an array of points, which are thought to
@@ -137,31 +165,38 @@ static void xor_to_ref(potrace_bitmap_t *bm, int x, int y, int xa) {
 
 /* xor the given pixmap with the interior of the given path. Note: the
    path must be within the dimensions of the pixmap. */
-static void xor_path(potrace_bitmap_t *bm, path_t *p) {
+static void
+xor_path (potrace_bitmap_t * bm, path_t * p)
+{
   int xa, x, y, k, y1;
 
-  if (p->priv->len <= 0) {  /* a path of length 0 is silly, but legal */
-    return;
-  }
+  if (p->priv->len <= 0)
+    {				/* a path of length 0 is silly, but legal */
+      return;
+    }
 
-  y1 = p->priv->pt[p->priv->len-1].y;
+  y1 = p->priv->pt[p->priv->len - 1].y;
 
   xa = p->priv->pt[0].x & -BM_WORDBITS;
-  for (k=0; k<p->priv->len; k++) {
-    x = p->priv->pt[k].x;
-    y = p->priv->pt[k].y;
-
-    if (y != y1) {
-      /* efficiently invert the rectangle [x,xa] x [y,y1] */
-      xor_to_ref(bm, x, min(y,y1), xa);
-      y1 = y;
+  for (k = 0; k < p->priv->len; k++)
+    {
+      x = p->priv->pt[k].x;
+      y = p->priv->pt[k].y;
+
+      if (y != y1)
+	{
+	  /* efficiently invert the rectangle [x,xa] x [y,y1] */
+	  xor_to_ref (bm, x, min (y, y1), xa);
+	  y1 = y;
+	}
     }
-  }
 }
 
 /* Find the bounding box of a given path. Path is assumed to be of
    non-zero length. */
-static void setbbox_path(bbox_t *bbox, path_t *p) {
+static void
+setbbox_path (bbox_t * bbox, path_t * p)
+{
   int x, y;
   int k;
 
@@ -170,23 +205,28 @@ static void setbbox_path(bbox_t *bbox, path_t *p) {
   bbox->x0 = INT_MAX;
   bbox->x1 = 0;
 
-  for (k=0; k<p->priv->len; k++) {
-    x = p->priv->pt[k].x;
-    y = p->priv->pt[k].y;
+  for (k = 0; k < p->priv->len; k++)
+    {
+      x = p->priv->pt[k].x;
+      y = p->priv->pt[k].y;
 
-    if (x < bbox->x0) {
-      bbox->x0 = x;
-    }
-    if (x > bbox->x1) {
-      bbox->x1 = x;
-    }
-    if (y < bbox->y0) {
-      bbox->y0 = y;
-    }
-    if (y > bbox->y1) {
-      bbox->y1 = y;
+      if (x < bbox->x0)
+	{
+	  bbox->x0 = x;
+	}
+      if (x > bbox->x1)
+	{
+	  bbox->x1 = x;
+	}
+      if (y < bbox->y0)
+	{
+	  bbox->y0 = y;
+	}
+      if (y > bbox->y1)
+	{
+	  bbox->y1 = y;
+	}
     }
-  }
 }
 
 /* compute a path in the given pixmap, separating black from white.
@@ -195,7 +235,9 @@ static void setbbox_path(bbox_t *bbox, path_t *p) {
    new path_t object, or NULL on error (note that a legitimate path
    cannot have length 0). Sign is required for correct interpretation
    of turnpolicies. */
-static path_t *findpath(potrace_bitmap_t *bm, int x0, int y0, int sign, int turnpolicy) {
+static path_t *
+findpath (potrace_bitmap_t * bm, int x0, int y0, int sign, int turnpolicy)
+{
   int x, y, dirx, diry, len, size, area;
   int c, d, tmp;
   point_t *pt, *pt1;
@@ -209,67 +251,82 @@ static path_t *findpath(potrace_bitmap_t *bm, int x0, int y0, int sign, int turn
   len = size = 0;
   pt = NULL;
   area = 0;
-  
-  while (1) {
-    /* add point to path */
-    if (len>=size) {
-      size += 100;
-      size = (int)(1.3 * size);
-      pt1 = (point_t *)realloc(pt, size * sizeof(point_t));
-      if (!pt1) {
-	goto error;
-      }
-      pt = pt1;
-    }
-    pt[len].x = x;
-    pt[len].y = y;
-    len++;
-    
-    /* move to next point */
-    x += dirx;
-    y += diry;
-    area += x*diry;
-    
-    /* path complete? */
-    if (x==x0 && y==y0) {
-      break;
-    }
-    
-    /* determine next direction */
-    c = BM_GET(bm, x + (dirx+diry-1)/2, y + (diry-dirx-1)/2);
-    d = BM_GET(bm, x + (dirx-diry-1)/2, y + (diry+dirx-1)/2);
-    
-    if (c && !d) {               /* ambiguous turn */
-      if (turnpolicy == POTRACE_TURNPOLICY_RIGHT
-	  || (turnpolicy == POTRACE_TURNPOLICY_BLACK && sign == '+')
-	  || (turnpolicy == POTRACE_TURNPOLICY_WHITE && sign == '-')
-	  || (turnpolicy == POTRACE_TURNPOLICY_RANDOM && detrand(x,y))
-	  || (turnpolicy == POTRACE_TURNPOLICY_MAJORITY && majority(bm, x, y))
-	  || (turnpolicy == POTRACE_TURNPOLICY_MINORITY && !majority(bm, x, y))) {
-	tmp = dirx;              /* right turn */
-	dirx = diry;
-	diry = -tmp;
-      } else {
-	tmp = dirx;              /* left turn */
-	dirx = -diry;
-	diry = tmp;
-      }
-    } else if (c) {              /* right turn */
-      tmp = dirx;
-      dirx = diry;
-      diry = -tmp;
-    } else if (!d) {             /* left turn */
-      tmp = dirx;
-      dirx = -diry;
-      diry = tmp;
-    }
-  } /* while this path */
+
+  while (1)
+    {
+      /* add point to path */
+      if (len >= size)
+	{
+	  size += 100;
+	  size = (int) (1.3 * size);
+	  pt1 = (point_t *) realloc (pt, size * sizeof (point_t));
+	  if (!pt1)
+	    {
+	      goto error;
+	    }
+	  pt = pt1;
+	}
+      pt[len].x = x;
+      pt[len].y = y;
+      len++;
+
+      /* move to next point */
+      x += dirx;
+      y += diry;
+      area += x * diry;
+
+      /* path complete? */
+      if (x == x0 && y == y0)
+	{
+	  break;
+	}
+
+      /* determine next direction */
+      c = BM_GET (bm, x + (dirx + diry - 1) / 2, y + (diry - dirx - 1) / 2);
+      d = BM_GET (bm, x + (dirx - diry - 1) / 2, y + (diry + dirx - 1) / 2);
+
+      if (c && !d)
+	{			/* ambiguous turn */
+	  if (turnpolicy == POTRACE_TURNPOLICY_RIGHT
+	      || (turnpolicy == POTRACE_TURNPOLICY_BLACK && sign == '+')
+	      || (turnpolicy == POTRACE_TURNPOLICY_WHITE && sign == '-')
+	      || (turnpolicy == POTRACE_TURNPOLICY_RANDOM && detrand (x, y))
+	      || (turnpolicy == POTRACE_TURNPOLICY_MAJORITY
+		  && majority (bm, x, y))
+	      || (turnpolicy == POTRACE_TURNPOLICY_MINORITY
+		  && !majority (bm, x, y)))
+	    {
+	      tmp = dirx;	/* right turn */
+	      dirx = diry;
+	      diry = -tmp;
+	    }
+	  else
+	    {
+	      tmp = dirx;	/* left turn */
+	      dirx = -diry;
+	      diry = tmp;
+	    }
+	}
+      else if (c)
+	{			/* right turn */
+	  tmp = dirx;
+	  dirx = diry;
+	  diry = -tmp;
+	}
+      else if (!d)
+	{			/* left turn */
+	  tmp = dirx;
+	  dirx = -diry;
+	  diry = tmp;
+	}
+    }				/* while this path */
 
   /* allocate new path object */
-  p = path_new();
-  if (!p) {
-    goto error;
-  }
+  p = path_new ();
+  if (!p)
+    {
+      goto error;
+    }
 
   p->priv->pt = pt;
   p->priv->len = len;
@@ -277,10 +334,10 @@ static path_t *findpath(potrace_bitmap_t *bm, int x0, int y0, int sign, int turn
   p->sign = sign;
 
   return p;
- 
- error:
-   free(pt);
-   return NULL; 
+
+error:
+  free (pt);
+  return NULL;
 }
 
 /* Give a tree structure to the given path list, based on "insideness"
@@ -299,22 +356,25 @@ static path_t *findpath(potrace_bitmap_t *bm, int x0, int y0, int sign, int turn
    and will be used as scratch space. Return 0 on success or -1 on
    error with errno set. */
 
-static void pathlist_to_tree(path_t *plist, potrace_bitmap_t *bm) {
+static void
+pathlist_to_tree (path_t * plist, potrace_bitmap_t * bm)
+{
   path_t *p, *p1;
   path_t *heap, *heap1;
   path_t *cur;
   path_t *head;
-  path_t **hook, **hook_in, **hook_out; /* for fast appending to linked list */
+  path_t **hook, **hook_in, **hook_out;	/* for fast appending to linked list */
   bbox_t bbox;
-  
-  bm_clear(bm, 0);
+
+  bm_clear (bm, 0);
 
   /* save original "next" pointers */
-  list_forall(p, plist) {
+  list_forall (p, plist)
+  {
     p->sibling = p->next;
     p->childlist = NULL;
   }
-  
+
   heap = plist;
 
   /* the heap holds a list of lists of paths. Use "childlist" field
@@ -324,62 +384,71 @@ static void pathlist_to_tree(path_t *plist, potrace_bitmap_t *bm) {
      heap to get a tail recursive algorithm: the heap holds a list of
      pathlists which still need to be transformed. */
 
-  while (heap) {
-    /* unlink first sublist */
-    cur = heap;
-    heap = heap->childlist;
-    cur->childlist = NULL;
-  
-    /* unlink first path */
-    head = cur;
-    cur = cur->next;
-    head->next = NULL;
-
-    /* render path */
-    xor_path(bm, head);
-    setbbox_path(&bbox, head);
-
-    /* now do insideness test for each element of cur; append it to
-       head->childlist if it's inside head, else append it to
-       head->next. */
-    hook_in=&head->childlist;
-    hook_out=&head->next;
-    list_forall_unlink(p, cur) {
-      if (p->priv->pt[0].y <= bbox.y0) {
-	list_insert_beforehook(p, hook_out);
-	/* append the remainder of the list to hook_out */
-	*hook_out = cur;
-	break;
-      }
-      if (BM_GET(bm, p->priv->pt[0].x, p->priv->pt[0].y-1)) {
-	list_insert_beforehook(p, hook_in);
-      } else {
-	list_insert_beforehook(p, hook_out);
+  while (heap)
+    {
+      /* unlink first sublist */
+      cur = heap;
+      heap = heap->childlist;
+      cur->childlist = NULL;
+
+      /* unlink first path */
+      head = cur;
+      cur = cur->next;
+      head->next = NULL;
+
+      /* render path */
+      xor_path (bm, head);
+      setbbox_path (&bbox, head);
+
+      /* now do insideness test for each element of cur; append it to
+         head->childlist if it's inside head, else append it to
+         head->next. */
+      hook_in = &head->childlist;
+      hook_out = &head->next;
+      list_forall_unlink (p, cur)
+      {
+	if (p->priv->pt[0].y <= bbox.y0)
+	  {
+	    list_insert_beforehook (p, hook_out);
+	    /* append the remainder of the list to hook_out */
+	    *hook_out = cur;
+	    break;
+	  }
+	if (BM_GET (bm, p->priv->pt[0].x, p->priv->pt[0].y - 1))
+	  {
+	    list_insert_beforehook (p, hook_in);
+	  }
+	else
+	  {
+	    list_insert_beforehook (p, hook_out);
+	  }
       }
-    }
 
-    /* clear bm */
-    clear_bm_with_bbox(bm, &bbox);
+      /* clear bm */
+      clear_bm_with_bbox (bm, &bbox);
 
-    /* now schedule head->childlist and head->next for further
-       processing */
-    if (head->next) {
-      head->next->childlist = heap;
-      heap = head->next;
-    }
-    if (head->childlist) {
-      head->childlist->childlist = heap;
-      heap = head->childlist;
+      /* now schedule head->childlist and head->next for further
+         processing */
+      if (head->next)
+	{
+	  head->next->childlist = heap;
+	  heap = head->next;
+	}
+      if (head->childlist)
+	{
+	  head->childlist->childlist = heap;
+	  heap = head->childlist;
+	}
     }
-  }
-  
+
   /* copy sibling structure from "next" to "sibling" component */
   p = plist;
-  while (p) {
-    p1 = p->sibling;
-    p->sibling = p->next;
-    p = p1;
-  }
+  while (p)
+    {
+      p1 = p->sibling;
+      p->sibling = p->next;
+      p = p1;
+    }
 
   /* reconstruct a new linked list ("next") structure from tree
      ("childlist", "sibling") structure. This code is slightly messy,
@@ -387,30 +456,35 @@ static void pathlist_to_tree(path_t *plist, potrace_bitmap_t *bm) {
      contains a list of childlists which still need to be
      processed. */
   heap = plist;
-  if (heap) {
-    heap->next = NULL;  /* heap is a linked list of childlists */
-  }
+  if (heap)
+    {
+      heap->next = NULL;	/* heap is a linked list of childlists */
+    }
   plist = NULL;
   hook = &plist;
-  while (heap) {
-    heap1 = heap->next;
-    for (p=heap; p; p=p->sibling) {
-      /* p is a positive path */
-      /* append to linked list */
-      list_insert_beforehook(p, hook);
-      
-      /* go through its children */
-      for (p1=p->childlist; p1; p1=p1->sibling) {
-	/* append to linked list */
-	list_insert_beforehook(p1, hook);
-	/* append its childlist to heap, if non-empty */
-	if (p1->childlist) {
-	  list_append(path_t, heap1, p1->childlist);
+  while (heap)
+    {
+      heap1 = heap->next;
+      for (p = heap; p; p = p->sibling)
+	{
+	  /* p is a positive path */
+	  /* append to linked list */
+	  list_insert_beforehook (p, hook);
+
+	  /* go through its children */
+	  for (p1 = p->childlist; p1; p1 = p1->sibling)
+	    {
+	      /* append to linked list */
+	      list_insert_beforehook (p1, hook);
+	      /* append its childlist to heap, if non-empty */
+	      if (p1->childlist)
+		{
+		  list_append (path_t, heap1, p1->childlist);
+		}
+	    }
 	}
-      }
+      heap = heap1;
     }
-    heap = heap1;
-  }
 
   return;
 }
@@ -420,23 +494,29 @@ static void pathlist_to_tree(path_t *plist, potrace_bitmap_t *bm) {
    or y=y' and x<x'. If found, return 0 and store pixel in
    (*xp,*yp). Else return 1. Note that this function assumes that
    excess bytes have been cleared with bm_clearexcess. */
-static int findnext(potrace_bitmap_t *bm, int *xp, int *yp) {
+static int
+findnext (potrace_bitmap_t * bm, int *xp, int *yp)
+{
   int x;
   int y;
 
-  for (y=*yp; y>=0; y--) {
-    for (x=0; x<bm->w; x+=BM_WORDBITS) {
-      if (*bm_index(bm, x, y)) {
-	while (!BM_GET(bm, x, y)) {
-	  x++;
+  for (y = *yp; y >= 0; y--)
+    {
+      for (x = 0; x < bm->w; x += BM_WORDBITS)
+	{
+	  if (*bm_index (bm, x, y))
+	    {
+	      while (!BM_GET (bm, x, y))
+		{
+		  x++;
+		}
+	      /* found */
+	      *xp = x;
+	      *yp = y;
+	      return 0;
+	    }
 	}
-	/* found */
-	*xp = x;
-	*yp = y;
-	return 0;
-      }
     }
-  }
   /* not found */
   return 1;
 }
@@ -446,63 +526,74 @@ static int findnext(potrace_bitmap_t *bm, int *xp, int *yp) {
    in. Returns 0 on success with plistp set, or -1 on error with errno
    set. */
 
-int bm_to_pathlist(const potrace_bitmap_t *bm, path_t **plistp, const potrace_param_t *param) {
+int
+bm_to_pathlist (const potrace_bitmap_t * bm, path_t ** plistp,
+		const potrace_param_t * param)
+{
   int x;
   int y;
   path_t *p;
-  path_t *plist = NULL;  /* linked list of path objects */
-  path_t **hook = &plist;  /* used to speed up appending to linked list */
+  path_t *plist = NULL;		/* linked list of path objects */
+  path_t **hook = &plist;	/* used to speed up appending to linked list */
   potrace_bitmap_t *bm1 = NULL;
   int sign;
 
-  bm1 = bm_dup(bm);
-  if (!bm1) {
-    goto error;
-  }
+  bm1 = bm_dup (bm);
+  if (!bm1)
+    {
+      goto error;
+    }
 
   /* be sure the byte padding on the right is set to 0, as the fast
      pixel search below relies on it */
-  bm_clearexcess(bm1);
+  bm_clearexcess (bm1);
 
   /* iterate through components */
   y = bm1->h - 1;
-  while (findnext(bm1, &x, &y) == 0) { 
-    /* calculate the sign by looking at the original */
-    sign = BM_GET(bm, x, y) ? '+' : '-';
-
-    /* calculate the path */
-    p = findpath(bm1, x, y+1, sign, param->turnpolicy);
-    if (p==NULL) {
-      goto error;
-    }
+  while (findnext (bm1, &x, &y) == 0)
+    {
+      /* calculate the sign by looking at the original */
+      sign = BM_GET (bm, x, y) ? '+' : '-';
+
+      /* calculate the path */
+      p = findpath (bm1, x, y + 1, sign, param->turnpolicy);
+      if (p == NULL)
+	{
+	  goto error;
+	}
 
-    /* update buffered image */
-    xor_path(bm1, p);
+      /* update buffered image */
+      xor_path (bm1, p);
 
-    /* if it's a turd, eliminate it, else append it to the list */
-    if (p->area <= param->turdsize) {
-      path_free(p);
-    } else {
-      list_insert_beforehook(p, hook);
-    }
+      /* if it's a turd, eliminate it, else append it to the list */
+      if (p->area <= param->turdsize)
+	{
+	  path_free (p);
+	}
+      else
+	{
+	  list_insert_beforehook (p, hook);
+	}
 
-    if (bm1->h > 0) { /* to be sure */
-      //progress_update(1-y/(double)bm1->h, progress);
+      if (bm1->h > 0)
+	{			/* to be sure */
+	  //progress_update(1-y/(double)bm1->h, progress);
+	}
     }
-  }
 
-  pathlist_to_tree(plist, bm1);
-  bm_free(bm1);
+  pathlist_to_tree (plist, bm1);
+  bm_free (bm1);
   *plistp = plist;
 
 //  progress_update(1.0, progress);
 
   return 0;
 
- error:
-  bm_free(bm1);
-  list_forall_unlink(p, plist) {
-    path_free(p);
+error:
+  bm_free (bm1);
+  list_forall_unlink (p, plist)
+  {
+    path_free (p);
   }
   return -1;
 }
diff --git a/src/hid/gcode/decompose.h b/src/hid/gcode/decompose.h
index d5be99c..333003e 100644
--- a/src/hid/gcode/decompose.h
+++ b/src/hid/gcode/decompose.h
@@ -10,7 +10,7 @@
 #include "potracelib.h"
 //#include "progress.h"
 
-int bm_to_pathlist(const potrace_bitmap_t *bm, path_t **plistp, const potrace_param_t *param);
+int bm_to_pathlist (const potrace_bitmap_t * bm, path_t ** plistp,
+		    const potrace_param_t * param);
 
 #endif /* DECOMPOSE_H */
-
diff --git a/src/hid/gcode/gcode.c b/src/hid/gcode/gcode.c
index 5792d0c..e8c38db 100644
--- a/src/hid/gcode/gcode.c
+++ b/src/hid/gcode/gcode.c
@@ -64,925 +64,1037 @@
 #include <dmalloc.h>
 #endif
 
-RCSID("$Id: gcode.c, v 0.1 2010/2/8 14:00:00 Alberto Maccioni Exp $");
+RCSID ("$Id: gcode.c, v 0.1 2010/2/8 14:00:00 Alberto Maccioni Exp $");
 
 #define CRASH fprintf(stderr, "HID error: pcb called unimplemented GCODE function %s.\n", __FUNCTION__); abort()
-#define pcb_unit 100000.0 //pcb internal units per inch
-struct color_struct {
-	/* the descriptor used by the gd library */
-	int             c;
+#define pcb_unit 100000.0	//pcb internal units per inch
+struct color_struct
+{
+  /* the descriptor used by the gd library */
+  int c;
 
-	/* so I can figure out what rgb value c refers to */
-	unsigned int    r, g, b;
+  /* so I can figure out what rgb value c refers to */
+  unsigned int r, g, b;
 };
 
-struct hid_gc_struct {
-	HID            *me_pointer;
-	EndCapStyle     cap;
-	int             width;
-	unsigned char   r, g, b;
-	int             erase;
-	int             faded;
-	struct color_struct *color;
-	gdImagePtr      brush;
+struct hid_gc_struct
+{
+  HID *me_pointer;
+  EndCapStyle cap;
+  int width;
+  unsigned char r, g, b;
+  int erase;
+  int faded;
+  struct color_struct *color;
+  gdImagePtr brush;
 };
 
 static struct color_struct *black = NULL, *white = NULL;
-static int      linewidth = -1;
-static int      lastgroup = -1;
+static int linewidth = -1;
+static int lastgroup = -1;
 static gdImagePtr lastbrush = (void *) -1;
-static int      lastcap = -1;
-static int      lastcolor = -1;
+static int lastcap = -1;
+static int lastcolor = -1;
 
 /* gd image and file for PNG export */
 static gdImagePtr gcode_im = NULL;
-static FILE    *gcode_f = NULL,*gcode_f2 = NULL;
+static FILE *gcode_f = NULL, *gcode_f2 = NULL;
 
-static int      is_mask;
-static int      is_drill;
-static int      is_solder;
+static int is_mask;
+static int is_drill;
+static int is_solder;
 
 /*
  * Which groups of layers to export into PNG layer masks. 1 means export, 0
  * means do not export.
  */
-static int      gcode_export_group[MAX_LAYER];
+static int gcode_export_group[MAX_LAYER];
 
 /* Group that is currently exported. */
-static int      gcode_cur_group;
+static int gcode_cur_group;
 
 /* Filename prefix that will be used when saving files. */
-static char    *gcode_basename = NULL;
+static char *gcode_basename = NULL;
 
 /* Horizontal DPI (grid points per inch) */
-static int      gcode_dpi = -1;
-
-static double	gcode_cutdepth = 0; 	//milling depth (inch)
-static double	gcode_drilldepth = 0; 	//drilling depth (inch)
-static double	gcode_safeZ = 100; 		//safe Z (inch)
-static double	gcode_toolradius = 0; 	//tool radius(inch)
-static int      save_drill=0;
-static int      n_drill=0;
-static int      nmax_drill=0;
-struct drill_struct {
-	double x;
-	double y;
+static int gcode_dpi = -1;
+
+static double gcode_cutdepth = 0;	//milling depth (inch)
+static double gcode_drilldepth = 0;	//drilling depth (inch)
+static double gcode_safeZ = 100;	//safe Z (inch)
+static double gcode_toolradius = 0;	//tool radius(inch)
+static int save_drill = 0;
+static int n_drill = 0;
+static int nmax_drill = 0;
+struct drill_struct
+{
+  double x;
+  double y;
 };
 
-static struct drill_struct *drill=0;
+static struct drill_struct *drill = 0;
 
 static const char *units[] = {
-	"mm",
-	"mil",
-	"um",
-	"inch",
-	NULL
+  "mm",
+  "mil",
+  "um",
+  "inch",
+  NULL
 };
 
-HID_Attribute   gcode_attribute_list[] = {
-	/* other HIDs expect this to be first.  */
-	{"basename", "File name prefix",
-	HID_String, 0, 0, {0, 0, 0}, 0, 0},
+HID_Attribute gcode_attribute_list[] = {
+  /* other HIDs expect this to be first.  */
+  {"basename", "File name prefix",
+   HID_String, 0, 0, {0, 0, 0}, 0, 0},
 #define HA_basename 0
 
-	{"dpi", "Resolution of intermediate image (pixels/inch).",
-	HID_Integer, 0, 2000, {600, 0, 0}, 0, 0},
+  {"dpi", "Resolution of intermediate image (pixels/inch).",
+   HID_Integer, 0, 2000, {600, 0, 0}, 0, 0},
 #define HA_dpi 1
-	
-	{"mill depth", "Milling depth.",
-	HID_Real, -1000, 1000, {0, 0, -0.05}, 0, 0},
+
+  {"mill depth", "Milling depth.",
+   HID_Real, -1000, 1000, {0, 0, -0.05}, 0, 0},
 #define HA_cutdepth 2
-	
-	{"safe Z", "Safe Z for traverse move.",
-	HID_Real, -1000, 10000, {0, 0, 2}, 0, 0},
+
+  {"safe Z", "Safe Z for traverse move.",
+   HID_Real, -1000, 10000, {0, 0, 2}, 0, 0},
 #define HA_safeZ 3
-	
-	{"tool radius", "Milling tool radius compensation.",
-	HID_Real, 0, 10000, {0, 0, 0.1}, 0, 0},
+
+  {"tool radius", "Milling tool radius compensation.",
+   HID_Real, 0, 10000, {0, 0, 0.1}, 0, 0},
 #define HA_toolradius 4
 
-	{"drill depth", "Drilling depth.",
-	HID_Real, -10000, 10000, {0, 0, -2}, 0, 0},
+  {"drill depth", "Drilling depth.",
+   HID_Real, -10000, 10000, {0, 0, -2}, 0, 0},
 #define HA_drilldepth 5
-		
-	{"measurement unit", "Measurement unit",
-	HID_Enum, 0, 0, {0, 0, 0}, units, 0},
+
+  {"measurement unit", "Measurement unit",
+   HID_Enum, 0, 0, {0, 0, 0}, units, 0},
 #define HA_unit 6
 
 };
 
 #define NUM_OPTIONS (sizeof(gcode_attribute_list)/sizeof(gcode_attribute_list[0]))
 
-REGISTER_ATTRIBUTES(gcode_attribute_list)
-	static HID_Attr_Val gcode_values[NUM_OPTIONS];
+REGISTER_ATTRIBUTES (gcode_attribute_list)
+     static HID_Attr_Val gcode_values[NUM_OPTIONS];
 
 /* *** Utility funcions **************************************************** */
 
 /* convert from default PCB units (1/100 mil) to gcode units */
-	static int      pcb_to_gcode(int pcb)
+     static int pcb_to_gcode (int pcb)
 {
-	int             gcode;
+  int gcode;
 
-	gcode = (pcb * gcode_dpi) / pcb_unit; //100000;
+  gcode = (pcb * gcode_dpi) / pcb_unit;	//100000;
 
-	return gcode;
+  return gcode;
 }
 
-static char    *
-gcode_get_png_name(const char *basename, const char *suffix)
+static char *
+gcode_get_png_name (const char *basename, const char *suffix)
 {
-	char           *buf;
-	int             len;
+  char *buf;
+  int len;
 
-	len = strlen(basename) + strlen(suffix) + 6;
-	buf = malloc(sizeof(*buf) * len);
+  len = strlen (basename) + strlen (suffix) + 6;
+  buf = malloc (sizeof (*buf) * len);
 
-	sprintf(buf, "%s.%s.png", basename, suffix);
+  sprintf (buf, "%s.%s.png", basename, suffix);
 
-	return buf;
+  return buf;
 }
 
 //Sorts drills in order of distance from the origin
-struct drill_struct* sort_drill(struct drill_struct *drill,int n_drill){
-	int i,j,imin;
-	double dmin,d;
-	struct drill_struct p={0,0};
-	struct drill_struct* temp=malloc(n_drill*sizeof(struct drill_struct));
-	for(j=0;j<n_drill;j++){
-		dmin=1e20;
-		for(i=0;i<n_drill-j;i++){
-			d=(drill[i].x-p.x)*(drill[i].x-p.x)+(drill[i].y-p.y)*(drill[i].y-p.y);
-			if(d<dmin){
-				imin=i;
-				dmin=d;
-			}
-		}
-		//printf("j=%d imin=%d dmin=%f p=(%f,%f)\n",j,imin,dmin,p.x,p.y);
-		temp[j]=drill[imin];
-		drill[imin]=drill[n_drill-j-1];
-		p=temp[j];
+struct drill_struct *
+sort_drill (struct drill_struct *drill, int n_drill)
+{
+  int i, j, imin;
+  double dmin, d;
+  struct drill_struct p = { 0, 0 };
+  struct drill_struct *temp = malloc (n_drill * sizeof (struct drill_struct));
+  for (j = 0; j < n_drill; j++)
+    {
+      dmin = 1e20;
+      for (i = 0; i < n_drill - j; i++)
+	{
+	  d =
+	    (drill[i].x - p.x) * (drill[i].x - p.x) + (drill[i].y -
+						       p.y) * (drill[i].y -
+							       p.y);
+	  if (d < dmin)
+	    {
+	      imin = i;
+	      dmin = d;
+	    }
 	}
-	free(drill);
-	return temp;
+      //printf("j=%d imin=%d dmin=%f p=(%f,%f)\n",j,imin,dmin,p.x,p.y);
+      temp[j] = drill[imin];
+      drill[imin] = drill[n_drill - j - 1];
+      p = temp[j];
+    }
+  free (drill);
+  return temp;
 }
 
 /* *** Main export callback ************************************************ */
 
-extern void     hid_parse_command_line(int *argc, char ***argv);
+extern void hid_parse_command_line (int *argc, char ***argv);
 
-static void 
-gcode_parse_arguments(int *argc, char ***argv)
+static void
+gcode_parse_arguments (int *argc, char ***argv)
 {
-	hid_register_attributes(gcode_attribute_list,
-				sizeof(gcode_attribute_list) /
-				sizeof(gcode_attribute_list[0]));
-	hid_parse_command_line(argc, argv);
+  hid_register_attributes (gcode_attribute_list,
+			   sizeof (gcode_attribute_list) /
+			   sizeof (gcode_attribute_list[0]));
+  hid_parse_command_line (argc, argv);
 }
 
 static HID_Attribute *
-gcode_get_export_options(int *n)
+gcode_get_export_options (int *n)
 {
-	static char    *last_made_filename = 0;
-
-	if (PCB) {
-		derive_default_filename(PCB->Filename,
-					&gcode_attribute_list[HA_basename],
-					".gcode",
-					&last_made_filename);
-	}
-	if (n) {
-		*n = NUM_OPTIONS;
-	}
-	return gcode_attribute_list;
+  static char *last_made_filename = 0;
+
+  if (PCB)
+    {
+      derive_default_filename (PCB->Filename,
+			       &gcode_attribute_list[HA_basename],
+			       ".gcode", &last_made_filename);
+    }
+  if (n)
+    {
+      *n = NUM_OPTIONS;
+    }
+  return gcode_attribute_list;
 }
 
 /* Populates gcode_export_group array */
-void 
-gcode_choose_groups()
+void
+gcode_choose_groups ()
 {
-	int             n, m;
-	LayerType      *layer;
+  int n, m;
+  LayerType *layer;
 
-	/* Set entire array to 0 (don't export any layer groups by default */
-	memset(gcode_export_group, 0, sizeof(gcode_export_group));
+  /* Set entire array to 0 (don't export any layer groups by default */
+  memset (gcode_export_group, 0, sizeof (gcode_export_group));
 
-	for (n = 0; n < max_layer; n++) {
-		layer = &PCB->Data->Layer[n];
+  for (n = 0; n < max_layer; n++)
+    {
+      layer = &PCB->Data->Layer[n];
 
-		if (layer->LineN || layer->TextN || layer->ArcN ||
-		    layer->PolygonN) {
-			/* layer isn't empty */
+      if (layer->LineN || layer->TextN || layer->ArcN || layer->PolygonN)
+	{
+	  /* layer isn't empty */
 
-			/*
-			 * is this check necessary? It seems that special
-			 * layers have negative indexes?
-			 */
+	  /*
+	   * is this check necessary? It seems that special
+	   * layers have negative indexes?
+	   */
 
-			if (SL_TYPE(n) == 0) {
-				/* layer is a copper layer */
-				m = GetLayerGroupNumberByNumber(n);
+	  if (SL_TYPE (n) == 0)
+	    {
+	      /* layer is a copper layer */
+	      m = GetLayerGroupNumberByNumber (n);
 
-				/* the export layer */
-				gcode_export_group[m] = 1;
-			}
-		}
+	      /* the export layer */
+	      gcode_export_group[m] = 1;
+	    }
 	}
+    }
 }
 
-static void 
-gcode_alloc_colors()
+static void
+gcode_alloc_colors ()
 {
-	/*
-	 * Allocate white and black -- the first color allocated becomes the
-	 * background color
-	 */
-
-	white = (struct color_struct *) malloc(sizeof(*white));
-	white->r = white->g = white->b = 255;
-	white->c = gdImageColorAllocate(gcode_im, white->r, white->g, white->b);
-
-	black = (struct color_struct *) malloc(sizeof(*black));
-	black->r = black->g = black->b = 0;
-	black->c = gdImageColorAllocate(gcode_im, black->r, black->g, black->b);
+  /*
+   * Allocate white and black -- the first color allocated becomes the
+   * background color
+   */
+
+  white = (struct color_struct *) malloc (sizeof (*white));
+  white->r = white->g = white->b = 255;
+  white->c = gdImageColorAllocate (gcode_im, white->r, white->g, white->b);
+
+  black = (struct color_struct *) malloc (sizeof (*black));
+  black->r = black->g = black->b = 0;
+  black->c = gdImageColorAllocate (gcode_im, black->r, black->g, black->b);
 }
 
-static void 
-gcode_start_png(const char *basename, const char *suffix)
+static void
+gcode_start_png (const char *basename, const char *suffix)
 {
-	int             h, w;
-	char           *buf;
+  int h, w;
+  char *buf;
 
-	buf = gcode_get_png_name(basename, suffix);
+  buf = gcode_get_png_name (basename, suffix);
 
-	h = pcb_to_gcode(PCB->MaxHeight);
-	w = pcb_to_gcode(PCB->MaxWidth);
+  h = pcb_to_gcode (PCB->MaxHeight);
+  w = pcb_to_gcode (PCB->MaxWidth);
 
-	/* Nelma only works with true color images */
-	gcode_im = gdImageCreate(w, h);
-	gcode_f = fopen(buf, "wb");
+  /* Nelma only works with true color images */
+  gcode_im = gdImageCreate (w, h);
+  gcode_f = fopen (buf, "wb");
 
-	gcode_alloc_colors();
+  gcode_alloc_colors ();
 
-	free(buf);
+  free (buf);
 }
 
-static void 
-gcode_finish_png()
+static void
+gcode_finish_png ()
 {
 #ifdef HAVE_GDIMAGEPNG
-	gdImagePng(gcode_im, gcode_f);
+  gdImagePng (gcode_im, gcode_f);
 #else
-	Message("GCODE: PNG not supported by gd. Can't write layer mask.\n");
+  Message ("GCODE: PNG not supported by gd. Can't write layer mask.\n");
 #endif
-	gdImageDestroy(gcode_im);
-	fclose(gcode_f);
+  gdImageDestroy (gcode_im);
+  fclose (gcode_f);
 
-	free(white);
-	free(black);
+  free (white);
+  free (black);
 
-	gcode_im = NULL;
-	gcode_f = NULL;
+  gcode_im = NULL;
+  gcode_f = NULL;
 }
 
-void 
-gcode_start_png_export()
+void
+gcode_start_png_export ()
 {
-	BoxType         region;
+  BoxType region;
 
-	region.X1 = 0;
-	region.Y1 = 0;
-	region.X2 = PCB->MaxWidth;
-	region.Y2 = PCB->MaxHeight;
+  region.X1 = 0;
+  region.Y1 = 0;
+  region.X2 = PCB->MaxWidth;
+  region.Y2 = PCB->MaxHeight;
 
-	linewidth = -1;
-	lastbrush = (void *) -1;
-	lastcap = -1;
-	lastgroup = -1;
-	lastcolor = -1;
-	lastgroup = -1;
+  linewidth = -1;
+  lastbrush = (void *) -1;
+  lastcap = -1;
+  lastgroup = -1;
+  lastcolor = -1;
+  lastgroup = -1;
 
-	hid_expose_callback(&gcode_hid, &region, 0);
+  hid_expose_callback (&gcode_hid, &region, 0);
 }
 
-static void 
-gcode_do_export(HID_Attr_Val * options)
-{
-	int             save_ons[MAX_LAYER + 2];
-	int             i, idx;
-	time_t          t;
-	double scale=0,d=0,Bx,By;
-	int r,c,v,p,metric;
-	char* filename;
-	path_t *plist = NULL;
-	potrace_bitmap_t *bm = NULL;
-	potrace_param_t param_default = {
-	  2,                             // turdsize
-	  POTRACE_TURNPOLICY_MINORITY,   // turnpolicy 
-	  1.0,                           // alphamax 
-	  1,                             // opticurve 
-	  0.2,                           // opttolerance 
-	  {
-	    NULL,                        // callback function 
-	    NULL,                        // callback data 
-	    0.0, 1.0,                    // progress range 
-	    0.0,                         // granularity 
-	  },
-	};
-
-	Bx=PCB->MaxWidth/pcb_unit;
-	By=PCB->MaxHeight/pcb_unit;
-	if (!options) {
-		gcode_get_export_options(0);
-		for (i = 0; i < NUM_OPTIONS; i++) {
-			gcode_values[i] = gcode_attribute_list[i].default_val;
-		}
-		options = gcode_values;
-	}
-	gcode_basename = options[HA_basename].str_value;
-	if (!gcode_basename) {
-		gcode_basename = "pcb-out";
-	}
-	gcode_dpi = options[HA_dpi].int_value;
-	if (gcode_dpi < 0) {
-		fprintf(stderr, "ERROR:  dpi may not be < 0\n");
-		return;
-	}
-	switch(options[HA_unit].int_value){
-		case 0:
-			scale=1.0;			//mm
-			metric=1;
-			break;
-		case 1:
-			scale=0.001;		//mil
-			metric=0;
-			break;
-		case 2:
-			scale=0.001;		//um
-			metric=1;
-			break;
-		default:
-			scale=1.0;			//inch
-			metric=0;
+static void
+gcode_do_export (HID_Attr_Val * options)
+{
+  int save_ons[MAX_LAYER + 2];
+  int i, idx;
+  time_t t;
+  double scale = 0, d = 0, Bx, By;
+  int r, c, v, p, metric;
+  char *filename;
+  path_t *plist = NULL;
+  potrace_bitmap_t *bm = NULL;
+  potrace_param_t param_default = {
+    2,				// turdsize
+    POTRACE_TURNPOLICY_MINORITY,	// turnpolicy 
+    1.0,			// alphamax 
+    1,				// opticurve 
+    0.2,			// opttolerance 
+    {
+     NULL,			// callback function 
+     NULL,			// callback data 
+     0.0, 1.0,			// progress range 
+     0.0,			// granularity 
+     },
+  };
+
+  Bx = PCB->MaxWidth / pcb_unit;
+  By = PCB->MaxHeight / pcb_unit;
+  if (!options)
+    {
+      gcode_get_export_options (0);
+      for (i = 0; i < NUM_OPTIONS; i++)
+	{
+	  gcode_values[i] = gcode_attribute_list[i].default_val;
 	}
-	gcode_cutdepth = options[HA_cutdepth].real_value*scale;
-	gcode_drilldepth = options[HA_drilldepth].real_value*scale;
-	gcode_safeZ = options[HA_safeZ].real_value*scale;
-	gcode_toolradius = options[HA_toolradius].real_value*scale*pcb_unit; //in PCB units (1/100 mil)
-	if(metric) gcode_toolradius*=1/25.4;
-	gcode_choose_groups();
-
-	for (i = 0; i < MAX_LAYER; i++) {
-		if (gcode_export_group[i]) {
-
-			gcode_cur_group = i;
-
-			/* magic */
-			idx = (i >= 0 && i < max_layer) ?
-				PCB->LayerGroups.Entries[i][0] : i;
-			printf("idx=%d %s\n",idx,layer_type_to_file_name(idx));
-			is_solder=(GetLayerGroupNumberByNumber(idx)==GetLayerGroupNumberByNumber(max_layer+SOLDER_LAYER))?1:0;
-			save_drill=is_solder; //save drills for one layer only
-			gcode_start_png(gcode_basename,layer_type_to_file_name(idx));
-			hid_save_and_show_layer_ons(save_ons);
-			gcode_start_png_export();
-			hid_restore_layer_ons(save_ons);
+      options = gcode_values;
+    }
+  gcode_basename = options[HA_basename].str_value;
+  if (!gcode_basename)
+    {
+      gcode_basename = "pcb-out";
+    }
+  gcode_dpi = options[HA_dpi].int_value;
+  if (gcode_dpi < 0)
+    {
+      fprintf (stderr, "ERROR:  dpi may not be < 0\n");
+      return;
+    }
+  switch (options[HA_unit].int_value)
+    {
+    case 0:
+      scale = 1.0;		//mm
+      metric = 1;
+      break;
+    case 1:
+      scale = 0.001;		//mil
+      metric = 0;
+      break;
+    case 2:
+      scale = 0.001;		//um
+      metric = 1;
+      break;
+    default:
+      scale = 1.0;		//inch
+      metric = 0;
+    }
+  gcode_cutdepth = options[HA_cutdepth].real_value * scale;
+  gcode_drilldepth = options[HA_drilldepth].real_value * scale;
+  gcode_safeZ = options[HA_safeZ].real_value * scale;
+  gcode_toolradius = options[HA_toolradius].real_value * scale * pcb_unit;	//in PCB units (1/100 mil)
+  if (metric)
+    gcode_toolradius *= 1 / 25.4;
+  gcode_choose_groups ();
+
+  for (i = 0; i < MAX_LAYER; i++)
+    {
+      if (gcode_export_group[i])
+	{
+
+	  gcode_cur_group = i;
+
+	  /* magic */
+	  idx = (i >= 0 && i < max_layer) ?
+	    PCB->LayerGroups.Entries[i][0] : i;
+	  printf ("idx=%d %s\n", idx, layer_type_to_file_name (idx));
+	  is_solder =
+	    (GetLayerGroupNumberByNumber (idx) ==
+	     GetLayerGroupNumberByNumber (max_layer + SOLDER_LAYER)) ? 1 : 0;
+	  save_drill = is_solder;	//save drills for one layer only
+	  gcode_start_png (gcode_basename, layer_type_to_file_name (idx));
+	  hid_save_and_show_layer_ons (save_ons);
+	  gcode_start_png_export ();
+	  hid_restore_layer_ons (save_ons);
 
 //***************** gcode conversion ***************************
 // potrace uses a different kind of bitmap; for simplicity gcode_im is copied to this format
-			bm = bm_new(gdImageSX(gcode_im),gdImageSY(gcode_im));
-			filename=malloc(512);
-			plist = NULL;
-			if(is_solder){			//only for back layer
-				gdImagePtr temp_im=gdImageCreate(gdImageSX(gcode_im), gdImageSY(gcode_im));
-				gdImageCopy(temp_im,gcode_im,0,0,0,0,gdImageSX(gcode_im),gdImageSY(gcode_im));
-				for(r=0;r<gdImageSX(gcode_im);r++){
-					for(c=0;c<gdImageSY(gcode_im);c++){
-						gdImageSetPixel(gcode_im,r,c,gdImageGetPixel(temp_im,gdImageSX(gcode_im)-1-r,c));
-					}
-				}
-				gdImageDestroy(temp_im);
-			}
-			sprintf(filename,"%s.%s.cnc",gcode_basename,layer_type_to_file_name(idx));
-			for(r=0;r<gdImageSX(gcode_im);r++){
-				for(c=0;c<gdImageSY(gcode_im);c++){
-					v=gdImageGetPixel(gcode_im,r,gdImageSY(gcode_im)-1-c);
-					p=(gcode_im->red[v]||gcode_im->green[v]||gcode_im->blue[v])?0:0xFFFFFF;
-					BM_PUT(bm, r, c, p);
-				}
-			}
-			gcode_f2 = fopen (filename, "wb");
-			if (!gcode_f2)
-			{
-			  perror (filename);
-			  return;
-			}
-			fprintf(gcode_f2,"(Created by G-code exporter)\n");
-			t = time(NULL);
-			sprintf(filename,"%s", ctime(&t));
-			filename[strlen(filename)-1]=0;
-			fprintf(gcode_f2,"( %s )\n", filename);
-			fprintf(gcode_f2,"(%d dpi)\n",gcode_dpi);
-			fprintf(gcode_f2,"(Unit: %s)\n",metric?"mm":"inch");
-			if(metric) fprintf(gcode_f2,"(Board size: %.2fx%.2f mm)\n",Bx*25.4,By*25.4);
-			else fprintf(gcode_f2,"(Board size: %.2fx%.2f inches)\n",Bx,By);
-			fprintf(gcode_f2,"#100=%f  (safe Z)\n",gcode_safeZ);
-			fprintf(gcode_f2,"#101=%f  (cutting depth)\n",gcode_cutdepth);
-			fprintf(gcode_f2,"(---------------------------------)\n");
-			fprintf(gcode_f2,"G17 G%d G90 G64 P0.003 M3 S3000 M7 F%d\n",metric?21:20,metric?25:1);
-			fprintf(gcode_f2,"G0 Z#100\n");
-			//extract contour points from image
-			r = bm_to_pathlist(bm, &plist, &param_default);
-			if (r) {
-				fprintf(stderr, "ERROR: pathlist function failed\n");
-				return;
-			}
-			//generate best polygon and write vertices in g-code format
-			d=process_path(plist,&param_default,bm,gcode_f2,metric?25.4/gcode_dpi:1.0/gcode_dpi); 
-			if (d<0) {
-				fprintf(stderr, "ERROR: path process function failed\n");
-				return;
-			}
-			if(metric) fprintf(gcode_f2,"(end, total distance %.2fmm = %.2fin)\n",d,d*1/25.4);
-			else fprintf(gcode_f2,"(end, total distance %.2fmm = %.2fin)\n",25.4*d,d);
-			fprintf(gcode_f2,"M5 M9 M2\n");
-			pathlist_free(plist);
-			bm_free(bm);
-			fclose (gcode_f2);
-			if(save_drill){
-				d=0;
-				drill=sort_drill(drill,n_drill);
-				sprintf(filename,"%s.drill.cnc",gcode_basename);
-				gcode_f2 = fopen (filename, "wb");
-				if (!gcode_f2)
-				{
-				  perror (filename);
-				  return;
-				}
-				fprintf(gcode_f2,"(Created by G-code exporter)\n");
-				fprintf(gcode_f2,"(drill file: %d drills)\n",n_drill);
-				sprintf(filename,"%s", ctime(&t));
-				filename[strlen(filename)-1]=0;
-				fprintf(gcode_f2,"( %s )\n", filename);
-				fprintf(gcode_f2,"(Unit: %s)\n",metric?"mm":"inch");
-				if(metric) fprintf(gcode_f2,"(Board size: %.2fx%.2f mm)\n",Bx*25.4,By*25.4);
-				else fprintf(gcode_f2,"(Board size: %.2fx%.2f inches)\n",Bx,By);
-				fprintf(gcode_f2,"#100=%f  (safe Z)\n",gcode_safeZ);
-				fprintf(gcode_f2,"#101=%f  (drill depth)\n",gcode_drilldepth);
-				fprintf(gcode_f2,"(---------------------------------)\n");
-				fprintf(gcode_f2,"G17 G%d G90 G64 P0.003 M3 S3000 M7 F%d\n",metric?21:20,metric?25:1);
-//				fprintf(gcode_f2,"G0 Z#100\n");
-				for(r=0;r<n_drill;r++){
-//					if(metric) fprintf(gcode_f2,"G0 X%f Y%f\n",drill[r].x*25.4,drill[r].y*25.4);
-//					else fprintf(gcode_f2,"G0 X%f Y%f\n",drill[r].x,drill[r].y);
-					if(metric) fprintf(gcode_f2,"G81 X%f Y%f Z#101 R#100\n",drill[r].x*25.4,drill[r].y*25.4);
-					else fprintf(gcode_f2,"G81 X%f Y%f Z#101 R#100\n",drill[r].x,drill[r].y);
-//					fprintf(gcode_f2,"G1 Z#101\n");
-//					fprintf(gcode_f2,"G0 Z#100\n");
-					if(r>0) d+=sqrt((drill[r].x-drill[r-1].x)*(drill[r].x-drill[r-1].x)+\
-									(drill[r].y-drill[r-1].y)*(drill[r].y-drill[r-1].y));
-				}
-				fprintf(gcode_f2,"M5 M9 M2\n");
-				fprintf(gcode_f2,"(end, total distance %.2fmm = %.2fin)\n",25.4*d,d);
-				fclose (gcode_f2);
-				free(drill);
-				drill=NULL;
-				n_drill=nmax_drill=0;
-			}
-			free(filename);
-			system("unix2dos *.cnc");
-//******************* end gcode conversion ****************************
-			gcode_finish_png();
+	  bm = bm_new (gdImageSX (gcode_im), gdImageSY (gcode_im));
+	  filename = malloc (512);
+	  plist = NULL;
+	  if (is_solder)
+	    {			//only for back layer
+	      gdImagePtr temp_im =
+		gdImageCreate (gdImageSX (gcode_im), gdImageSY (gcode_im));
+	      gdImageCopy (temp_im, gcode_im, 0, 0, 0, 0,
+			   gdImageSX (gcode_im), gdImageSY (gcode_im));
+	      for (r = 0; r < gdImageSX (gcode_im); r++)
+		{
+		  for (c = 0; c < gdImageSY (gcode_im); c++)
+		    {
+		      gdImageSetPixel (gcode_im, r, c,
+				       gdImageGetPixel (temp_im,
+							gdImageSX (gcode_im) -
+							1 - r, c));
+		    }
+		}
+	      gdImageDestroy (temp_im);
+	    }
+	  sprintf (filename, "%s.%s.cnc", gcode_basename,
+		   layer_type_to_file_name (idx));
+	  for (r = 0; r < gdImageSX (gcode_im); r++)
+	    {
+	      for (c = 0; c < gdImageSY (gcode_im); c++)
+		{
+		  v =
+		    gdImageGetPixel (gcode_im, r,
+				     gdImageSY (gcode_im) - 1 - c);
+		  p = (gcode_im->red[v] || gcode_im->green[v]
+		       || gcode_im->blue[v]) ? 0 : 0xFFFFFF;
+		  BM_PUT (bm, r, c, p);
 		}
+	    }
+	  gcode_f2 = fopen (filename, "wb");
+	  if (!gcode_f2)
+	    {
+	      perror (filename);
+	      return;
+	    }
+	  fprintf (gcode_f2, "(Created by G-code exporter)\n");
+	  t = time (NULL);
+	  sprintf (filename, "%s", ctime (&t));
+	  filename[strlen (filename) - 1] = 0;
+	  fprintf (gcode_f2, "( %s )\n", filename);
+	  fprintf (gcode_f2, "(%d dpi)\n", gcode_dpi);
+	  fprintf (gcode_f2, "(Unit: %s)\n", metric ? "mm" : "inch");
+	  if (metric)
+	    fprintf (gcode_f2, "(Board size: %.2fx%.2f mm)\n", Bx * 25.4,
+		     By * 25.4);
+	  else
+	    fprintf (gcode_f2, "(Board size: %.2fx%.2f inches)\n", Bx, By);
+	  fprintf (gcode_f2, "#100=%f  (safe Z)\n", gcode_safeZ);
+	  fprintf (gcode_f2, "#101=%f  (cutting depth)\n", gcode_cutdepth);
+	  fprintf (gcode_f2, "(---------------------------------)\n");
+	  fprintf (gcode_f2, "G17 G%d G90 G64 P0.003 M3 S3000 M7 F%d\n",
+		   metric ? 21 : 20, metric ? 25 : 1);
+	  fprintf (gcode_f2, "G0 Z#100\n");
+	  //extract contour points from image
+	  r = bm_to_pathlist (bm, &plist, &param_default);
+	  if (r)
+	    {
+	      fprintf (stderr, "ERROR: pathlist function failed\n");
+	      return;
+	    }
+	  //generate best polygon and write vertices in g-code format
+	  d =
+	    process_path (plist, &param_default, bm, gcode_f2,
+			  metric ? 25.4 / gcode_dpi : 1.0 / gcode_dpi);
+	  if (d < 0)
+	    {
+	      fprintf (stderr, "ERROR: path process function failed\n");
+	      return;
+	    }
+	  if (metric)
+	    fprintf (gcode_f2, "(end, total distance %.2fmm = %.2fin)\n", d,
+		     d * 1 / 25.4);
+	  else
+	    fprintf (gcode_f2, "(end, total distance %.2fmm = %.2fin)\n",
+		     25.4 * d, d);
+	  fprintf (gcode_f2, "M5 M9 M2\n");
+	  pathlist_free (plist);
+	  bm_free (bm);
+	  fclose (gcode_f2);
+	  if (save_drill)
+	    {
+	      d = 0;
+	      drill = sort_drill (drill, n_drill);
+	      sprintf (filename, "%s.drill.cnc", gcode_basename);
+	      gcode_f2 = fopen (filename, "wb");
+	      if (!gcode_f2)
+		{
+		  perror (filename);
+		  return;
+		}
+	      fprintf (gcode_f2, "(Created by G-code exporter)\n");
+	      fprintf (gcode_f2, "(drill file: %d drills)\n", n_drill);
+	      sprintf (filename, "%s", ctime (&t));
+	      filename[strlen (filename) - 1] = 0;
+	      fprintf (gcode_f2, "( %s )\n", filename);
+	      fprintf (gcode_f2, "(Unit: %s)\n", metric ? "mm" : "inch");
+	      if (metric)
+		fprintf (gcode_f2, "(Board size: %.2fx%.2f mm)\n", Bx * 25.4,
+			 By * 25.4);
+	      else
+		fprintf (gcode_f2, "(Board size: %.2fx%.2f inches)\n", Bx,
+			 By);
+	      fprintf (gcode_f2, "#100=%f  (safe Z)\n", gcode_safeZ);
+	      fprintf (gcode_f2, "#101=%f  (drill depth)\n",
+		       gcode_drilldepth);
+	      fprintf (gcode_f2, "(---------------------------------)\n");
+	      fprintf (gcode_f2, "G17 G%d G90 G64 P0.003 M3 S3000 M7 F%d\n",
+		       metric ? 21 : 20, metric ? 25 : 1);
+//                              fprintf(gcode_f2,"G0 Z#100\n");
+	      for (r = 0; r < n_drill; r++)
+		{
+//                                      if(metric) fprintf(gcode_f2,"G0 X%f Y%f\n",drill[r].x*25.4,drill[r].y*25.4);
+//                                      else fprintf(gcode_f2,"G0 X%f Y%f\n",drill[r].x,drill[r].y);
+		  if (metric)
+		    fprintf (gcode_f2, "G81 X%f Y%f Z#101 R#100\n",
+			     drill[r].x * 25.4, drill[r].y * 25.4);
+		  else
+		    fprintf (gcode_f2, "G81 X%f Y%f Z#101 R#100\n",
+			     drill[r].x, drill[r].y);
+//                                      fprintf(gcode_f2,"G1 Z#101\n");
+//                                      fprintf(gcode_f2,"G0 Z#100\n");
+		  if (r > 0)
+		    d +=
+		      sqrt ((drill[r].x - drill[r - 1].x) * (drill[r].x -
+							     drill[r - 1].x) +
+			    (drill[r].y - drill[r - 1].y) * (drill[r].y -
+							     drill[r - 1].y));
+		}
+	      fprintf (gcode_f2, "M5 M9 M2\n");
+	      fprintf (gcode_f2, "(end, total distance %.2fmm = %.2fin)\n",
+		       25.4 * d, d);
+	      fclose (gcode_f2);
+	      free (drill);
+	      drill = NULL;
+	      n_drill = nmax_drill = 0;
+	    }
+	  free (filename);
+	  system ("unix2dos *.cnc");
+//******************* end gcode conversion ****************************
+	  gcode_finish_png ();
 	}
+    }
 }
 
 /* *** PNG export (slightly modified code from PNG export HID) ************* */
 
-static int 
-gcode_set_layer(const char *name, int group)
+static int
+gcode_set_layer (const char *name, int group)
 {
-	int             idx = (group >= 0 && group < max_layer) ?
-	PCB->LayerGroups.Entries[group][0] : group;
-
-	if (name == 0) {
-		name = PCB->Data->Layer[idx].Name;
-	}
-	if (strcmp(name, "invisible") == 0) {
-		return 0;
-	}
-	is_drill = (SL_TYPE(idx) == SL_PDRILL || SL_TYPE(idx) == SL_UDRILL);
-	is_mask = (SL_TYPE(idx) == SL_MASK);
-
-	if (is_mask) {
-		/* Don't print masks */
-		return 0;
-	}
-	if (is_drill) {
-		/*
-		 * Print 'holes', so that we can fill gaps in the copper
-		 * layer
-		 */
-		return 1;
-	}
-	if (group == gcode_cur_group) {
-		return 1;
-	}
-	return 0;
+  int idx = (group >= 0 && group < max_layer) ?
+    PCB->LayerGroups.Entries[group][0] : group;
+
+  if (name == 0)
+    {
+      name = PCB->Data->Layer[idx].Name;
+    }
+  if (strcmp (name, "invisible") == 0)
+    {
+      return 0;
+    }
+  is_drill = (SL_TYPE (idx) == SL_PDRILL || SL_TYPE (idx) == SL_UDRILL);
+  is_mask = (SL_TYPE (idx) == SL_MASK);
+
+  if (is_mask)
+    {
+      /* Don't print masks */
+      return 0;
+    }
+  if (is_drill)
+    {
+      /*
+       * Print 'holes', so that we can fill gaps in the copper
+       * layer
+       */
+      return 1;
+    }
+  if (group == gcode_cur_group)
+    {
+      return 1;
+    }
+  return 0;
 }
 
-static hidGC 
-gcode_make_gc(void)
-{
-	hidGC           rv = (hidGC) malloc(sizeof(struct hid_gc_struct));
-	rv->me_pointer = &gcode_hid;
-	rv->cap = Trace_Cap;
-	rv->width = 1;
-	rv->color = (struct color_struct *) malloc(sizeof(*rv->color));
-	rv->color->r = rv->color->g = rv->color->b = 0;
-	rv->color->c = 0;
-	return rv;
+static hidGC
+gcode_make_gc (void)
+{
+  hidGC rv = (hidGC) malloc (sizeof (struct hid_gc_struct));
+  rv->me_pointer = &gcode_hid;
+  rv->cap = Trace_Cap;
+  rv->width = 1;
+  rv->color = (struct color_struct *) malloc (sizeof (*rv->color));
+  rv->color->r = rv->color->g = rv->color->b = 0;
+  rv->color->c = 0;
+  return rv;
 }
 
-static void 
-gcode_destroy_gc(hidGC gc)
+static void
+gcode_destroy_gc (hidGC gc)
 {
-	free(gc);
+  free (gc);
 }
 
-static void 
-gcode_use_mask(int use_it)
+static void
+gcode_use_mask (int use_it)
 {
-	/* does nothing */
+  /* does nothing */
 }
 
-static void 
-gcode_set_color(hidGC gc, const char *name)
+static void
+gcode_set_color (hidGC gc, const char *name)
 {
-	if (gcode_im == NULL) {
-		return;
-	}
-	if (name == NULL) {
-		name = "#ff0000";
-	}
-	if (!strcmp(name, "drill")) {
-		gc->color = black;
-		gc->erase = 0;
-		return;
-	}
-	if (!strcmp(name, "erase")) {
-		/* FIXME -- should be background, not white */
-		gc->color = white;
-		gc->erase = 1;
-		return;
-	}
-	gc->color = black;
-	gc->erase = 0;
-	return;
+  if (gcode_im == NULL)
+    {
+      return;
+    }
+  if (name == NULL)
+    {
+      name = "#ff0000";
+    }
+  if (!strcmp (name, "drill"))
+    {
+      gc->color = black;
+      gc->erase = 0;
+      return;
+    }
+  if (!strcmp (name, "erase"))
+    {
+      /* FIXME -- should be background, not white */
+      gc->color = white;
+      gc->erase = 1;
+      return;
+    }
+  gc->color = black;
+  gc->erase = 0;
+  return;
 }
 
 static void
-gcode_set_line_cap(hidGC gc, EndCapStyle style)
+gcode_set_line_cap (hidGC gc, EndCapStyle style)
 {
-	gc->cap = style;
+  gc->cap = style;
 }
 
 static void
-gcode_set_line_width(hidGC gc, int width)
+gcode_set_line_width (hidGC gc, int width)
 {
-	gc->width = width;
+  gc->width = width;
 }
 
 static void
-gcode_set_draw_xor(hidGC gc, int xor)
+gcode_set_draw_xor (hidGC gc, int xor)
 {
-	;
+  ;
 }
 
 static void
-gcode_set_draw_faded(hidGC gc, int faded)
+gcode_set_draw_faded (hidGC gc, int faded)
 {
-	gc->faded = faded;
+  gc->faded = faded;
 }
 
 static void
-gcode_set_line_cap_angle(hidGC gc, int x1, int y1, int x2, int y2)
+gcode_set_line_cap_angle (hidGC gc, int x1, int y1, int x2, int y2)
 {
-	CRASH;
+  CRASH;
 }
 
 static void
-use_gc(hidGC gc)
+use_gc (hidGC gc)
 {
-	int             need_brush = 0;
+  int need_brush = 0;
+
+  if (gc->me_pointer != &gcode_hid)
+    {
+      fprintf (stderr, "Fatal: GC from another HID passed to gcode HID\n");
+      abort ();
+    }
+  if (linewidth != gc->width)
+    {
+      /* Make sure the scaling doesn't erase lines completely */
+      /*
+         if (SCALE (gc->width) == 0 && gc->width > 0)
+         gdImageSetThickness (im, 1);
+         else
+       */
+      gdImageSetThickness (gcode_im,
+			   pcb_to_gcode (gc->width + 2 * gcode_toolradius));
+      linewidth = gc->width;
+      need_brush = 1;
+    }
+  if (lastbrush != gc->brush || need_brush)
+    {
+      static void *bcache = 0;
+      hidval bval;
+      char name[256];
+      char type;
+      int r;
+
+      switch (gc->cap)
+	{
+	case Round_Cap:
+	case Trace_Cap:
+	  type = 'C';
+	  r = pcb_to_gcode (gc->width / 2 + gcode_toolradius);
+	  break;
+	default:
+	case Square_Cap:
+	  r = pcb_to_gcode (gc->width + gcode_toolradius * 2);
+	  type = 'S';
+	  break;
+	}
+      sprintf (name, "#%.2x%.2x%.2x_%c_%d", gc->color->r, gc->color->g,
+	       gc->color->b, type, r);
 
-	if (gc->me_pointer != &gcode_hid) {
-		fprintf(stderr, "Fatal: GC from another HID passed to gcode HID\n");
-		abort();
+      if (hid_cache_color (0, name, &bval, &bcache))
+	{
+	  gc->brush = bval.ptr;
 	}
-	if (linewidth != gc->width) {
-		/* Make sure the scaling doesn't erase lines completely */
-		/*
-	        if (SCALE (gc->width) == 0 && gc->width > 0)
-		  gdImageSetThickness (im, 1);
-	        else
-	        */
-		gdImageSetThickness(gcode_im, pcb_to_gcode(gc->width + 2*gcode_toolradius));
-		linewidth = gc->width;
-		need_brush = 1;
+      else
+	{
+	  int bg, fg;
+	  if (type == 'C')
+	    gc->brush = gdImageCreate (2 * r + 1, 2 * r + 1);
+	  else
+	    gc->brush = gdImageCreate (r + 1, r + 1);
+	  bg = gdImageColorAllocate (gc->brush, 255, 255, 255);
+	  fg =
+	    gdImageColorAllocate (gc->brush, gc->color->r, gc->color->g,
+				  gc->color->b);
+	  gdImageColorTransparent (gc->brush, bg);
+
+	  /*
+	   * if we shrunk to a radius/box width of zero, then just use
+	   * a single pixel to draw with.
+	   */
+	  if (r == 0)
+	    gdImageFilledRectangle (gc->brush, 0, 0, 0, 0, fg);
+	  else
+	    {
+	      if (type == 'C')
+		gdImageFilledEllipse (gc->brush, r, r, 2 * r, 2 * r, fg);
+	      else
+		gdImageFilledRectangle (gc->brush, 0, 0, r, r, fg);
+	    }
+	  bval.ptr = gc->brush;
+	  hid_cache_color (1, name, &bval, &bcache);
 	}
-	if (lastbrush != gc->brush || need_brush) {
-		static void    *bcache = 0;
-		hidval          bval;
-		char            name[256];
-		char            type;
-		int             r;
-
-		switch (gc->cap) {
-		case Round_Cap:
-		case Trace_Cap:
-			type = 'C';
-			r = pcb_to_gcode(gc->width / 2 + gcode_toolradius);
-			break;
-		default:
-		case Square_Cap:
-			r = pcb_to_gcode(gc->width+gcode_toolradius*2);
-			type = 'S';
-			break;
-		}
-		sprintf(name, "#%.2x%.2x%.2x_%c_%d", gc->color->r, gc->color->g,
-			gc->color->b, type, r);
-
-		if (hid_cache_color(0, name, &bval, &bcache)) {
-			gc->brush = bval.ptr;
-		} else {
-			int             bg, fg;
-			if (type == 'C')
-				gc->brush = gdImageCreate(2 * r + 1, 2 * r + 1);
-			else
-				gc->brush = gdImageCreate(r + 1, r + 1);
-			bg = gdImageColorAllocate(gc->brush, 255, 255, 255);
-			fg =
-				gdImageColorAllocate(gc->brush, gc->color->r, gc->color->g,
-						     gc->color->b);
-			gdImageColorTransparent(gc->brush, bg);
-
-			/*
-		         * if we shrunk to a radius/box width of zero, then just use
-		         * a single pixel to draw with.
-		         */
-			if (r == 0)
-				gdImageFilledRectangle(gc->brush, 0, 0, 0, 0, fg);
-			else {
-				if (type == 'C')
-					gdImageFilledEllipse(gc->brush, r, r, 2 * r, 2 * r, fg);
-				else
-					gdImageFilledRectangle(gc->brush, 0, 0, r, r, fg);
-			}
-			bval.ptr = gc->brush;
-			hid_cache_color(1, name, &bval, &bcache);
-		}
 
-		gdImageSetBrush(gcode_im, gc->brush);
-		lastbrush = gc->brush;
+      gdImageSetBrush (gcode_im, gc->brush);
+      lastbrush = gc->brush;
 
-	}
+    }
 #define CBLEND(gc) (((gc->r)<<24)|((gc->g)<<16)|((gc->b)<<8)|(gc->faded))
-	if (lastcolor != CBLEND(gc)) {
-		if (is_drill || is_mask) {
+  if (lastcolor != CBLEND (gc))
+    {
+      if (is_drill || is_mask)
+	{
 #ifdef FIXME
-			fprintf(f, "%d gray\n", gc->erase ? 0 : 1);
+	  fprintf (f, "%d gray\n", gc->erase ? 0 : 1);
 #endif
-			lastcolor = 0;
-		} else {
-			double          r, g, b;
-			r = gc->r;
-			g = gc->g;
-			b = gc->b;
-			if (gc->faded) {
-				r = 0.8 * 255 + 0.2 * r;
-				g = 0.8 * 255 + 0.2 * g;
-				b = 0.8 * 255 + 0.2 * b;
-			}
+	  lastcolor = 0;
+	}
+      else
+	{
+	  double r, g, b;
+	  r = gc->r;
+	  g = gc->g;
+	  b = gc->b;
+	  if (gc->faded)
+	    {
+	      r = 0.8 * 255 + 0.2 * r;
+	      g = 0.8 * 255 + 0.2 * g;
+	      b = 0.8 * 255 + 0.2 * b;
+	    }
 #ifdef FIXME
-			if (gc->r == gc->g && gc->g == gc->b)
-				fprintf(f, "%g gray\n", r / 255.0);
-			else
-				fprintf(f, "%g %g %g rgb\n", r / 255.0, g / 255.0, b / 255.0);
+	  if (gc->r == gc->g && gc->g == gc->b)
+	    fprintf (f, "%g gray\n", r / 255.0);
+	  else
+	    fprintf (f, "%g %g %g rgb\n", r / 255.0, g / 255.0, b / 255.0);
 #endif
-			lastcolor = CBLEND(gc);
-		}
+	  lastcolor = CBLEND (gc);
 	}
+    }
 }
 
 static void
-gcode_draw_rect(hidGC gc, int x1, int y1, int x2, int y2)
+gcode_draw_rect (hidGC gc, int x1, int y1, int x2, int y2)
 {
-	use_gc(gc);
-	gdImageRectangle(gcode_im,
-			 pcb_to_gcode(x1-gcode_toolradius), pcb_to_gcode(y1-gcode_toolradius),
-			 pcb_to_gcode(x2+gcode_toolradius), pcb_to_gcode(y2+gcode_toolradius), gc->color->c);
-//	printf("Rect %d %d %d %d\n",x1,y1,x2,y2);
+  use_gc (gc);
+  gdImageRectangle (gcode_im,
+		    pcb_to_gcode (x1 - gcode_toolradius),
+		    pcb_to_gcode (y1 - gcode_toolradius),
+		    pcb_to_gcode (x2 + gcode_toolradius),
+		    pcb_to_gcode (y2 + gcode_toolradius), gc->color->c);
+//      printf("Rect %d %d %d %d\n",x1,y1,x2,y2);
 }
 
 static void
-gcode_fill_rect(hidGC gc, int x1, int y1, int x2, int y2)
-{
-	use_gc(gc);
-	gdImageSetThickness(gcode_im, 0);
-	linewidth = 0;
-	gdImageFilledRectangle(gcode_im, 
-			  pcb_to_gcode(x1-gcode_toolradius), pcb_to_gcode(y1-gcode_toolradius),
-			  pcb_to_gcode(x2+gcode_toolradius), pcb_to_gcode(y2+gcode_toolradius), gc->color->c);
-//	printf("FillRect %d %d %d %d\n",x1,y1,x2,y2);
+gcode_fill_rect (hidGC gc, int x1, int y1, int x2, int y2)
+{
+  use_gc (gc);
+  gdImageSetThickness (gcode_im, 0);
+  linewidth = 0;
+  gdImageFilledRectangle (gcode_im,
+			  pcb_to_gcode (x1 - gcode_toolradius),
+			  pcb_to_gcode (y1 - gcode_toolradius),
+			  pcb_to_gcode (x2 + gcode_toolradius),
+			  pcb_to_gcode (y2 + gcode_toolradius), gc->color->c);
+//      printf("FillRect %d %d %d %d\n",x1,y1,x2,y2);
 }
 
 static void
-gcode_draw_line(hidGC gc, int x1, int y1, int x2, int y2)
+gcode_draw_line (hidGC gc, int x1, int y1, int x2, int y2)
 {
-	if (x1 == x2 && y1 == y2) {
-		int             w = gc->width / 2;
-		gcode_fill_rect(gc, x1 - w, y1 - w, x1 + w, y1 + w);
-		return;
-	}
-	use_gc(gc);
-
-	gdImageSetThickness(gcode_im, 0);
-	linewidth = 0;
-	gdImageLine(gcode_im, pcb_to_gcode(x1), pcb_to_gcode(y1),
-		    pcb_to_gcode(x2), pcb_to_gcode(y2), gdBrushed);
+  if (x1 == x2 && y1 == y2)
+    {
+      int w = gc->width / 2;
+      gcode_fill_rect (gc, x1 - w, y1 - w, x1 + w, y1 + w);
+      return;
+    }
+  use_gc (gc);
+
+  gdImageSetThickness (gcode_im, 0);
+  linewidth = 0;
+  gdImageLine (gcode_im, pcb_to_gcode (x1), pcb_to_gcode (y1),
+	       pcb_to_gcode (x2), pcb_to_gcode (y2), gdBrushed);
 }
 
 static void
-gcode_draw_arc(hidGC gc, int cx, int cy, int width, int height,
-	       int start_angle, int delta_angle)
-{
-	int             sa, ea;
-
-	/*
-	 * in gdImageArc, 0 degrees is to the right and +90 degrees is down
-	 * in pcb, 0 degrees is to the left and +90 degrees is down
-	 */
-	start_angle = 180 - start_angle;
-	delta_angle = -delta_angle;
-	if (delta_angle > 0) {
-		sa = start_angle;
-		ea = start_angle + delta_angle;
-	} else {
-		sa = start_angle + delta_angle;
-		ea = start_angle;
-	}
-
-	/*
-	 * make sure we start between 0 and 360 otherwise gd does strange
-	 * things
-	 */
-	while (sa < 0) {
-		sa += 360;
-		ea += 360;
-	}
-	while (sa >= 360) {
-		sa -= 360;
-		ea -= 360;
-	}
+gcode_draw_arc (hidGC gc, int cx, int cy, int width, int height,
+		int start_angle, int delta_angle)
+{
+  int sa, ea;
+
+  /*
+   * in gdImageArc, 0 degrees is to the right and +90 degrees is down
+   * in pcb, 0 degrees is to the left and +90 degrees is down
+   */
+  start_angle = 180 - start_angle;
+  delta_angle = -delta_angle;
+  if (delta_angle > 0)
+    {
+      sa = start_angle;
+      ea = start_angle + delta_angle;
+    }
+  else
+    {
+      sa = start_angle + delta_angle;
+      ea = start_angle;
+    }
+
+  /*
+   * make sure we start between 0 and 360 otherwise gd does strange
+   * things
+   */
+  while (sa < 0)
+    {
+      sa += 360;
+      ea += 360;
+    }
+  while (sa >= 360)
+    {
+      sa -= 360;
+      ea -= 360;
+    }
 
 #if 0
-	printf("draw_arc %d,%d %dx%d %d..%d %d..%d\n",
-	       cx, cy, width, height, start_angle, delta_angle, sa, ea);
-	printf("gdImageArc (%p, %d, %d, %d, %d, %d, %d, %d)\n",
-	       im, SCALE_X(cx), SCALE_Y(cy),
-	       SCALE(width), SCALE(height), sa, ea, gc->color->c);
+  printf ("draw_arc %d,%d %dx%d %d..%d %d..%d\n",
+	  cx, cy, width, height, start_angle, delta_angle, sa, ea);
+  printf ("gdImageArc (%p, %d, %d, %d, %d, %d, %d, %d)\n",
+	  im, SCALE_X (cx), SCALE_Y (cy),
+	  SCALE (width), SCALE (height), sa, ea, gc->color->c);
 #endif
-	use_gc(gc);
-	gdImageSetThickness(gcode_im, 0);
-	linewidth = 0;
-	gdImageArc(gcode_im, pcb_to_gcode(cx), pcb_to_gcode(cy),
-		   pcb_to_gcode(2 * width + gcode_toolradius*2), pcb_to_gcode(2 * height + gcode_toolradius*2), sa, ea, gdBrushed);
+  use_gc (gc);
+  gdImageSetThickness (gcode_im, 0);
+  linewidth = 0;
+  gdImageArc (gcode_im, pcb_to_gcode (cx), pcb_to_gcode (cy),
+	      pcb_to_gcode (2 * width + gcode_toolradius * 2),
+	      pcb_to_gcode (2 * height + gcode_toolradius * 2), sa, ea,
+	      gdBrushed);
 }
 
 static void
-gcode_fill_circle(hidGC gc, int cx, int cy, int radius)
-{
-	use_gc(gc);
-
-	gdImageSetThickness(gcode_im, 0);
-	linewidth = 0;
-	gdImageFilledEllipse(gcode_im, pcb_to_gcode(cx), pcb_to_gcode(cy),
-	  pcb_to_gcode(2 * radius + gcode_toolradius*2), pcb_to_gcode(2 * radius + gcode_toolradius*2), gc->color->c);
-	if(save_drill&&is_drill){
-		if(n_drill==nmax_drill){
-			drill=(struct drill_struct*) realloc(drill,(nmax_drill+100)*sizeof(struct drill_struct));
-			nmax_drill+=100;
-		}
-		drill[n_drill].x=(PCB->MaxWidth-cx)/pcb_unit;	//convert to inch, flip: will drill from bottom side
-		drill[n_drill].y=(PCB->MaxHeight-cy)/pcb_unit;	//PCB reverses y axis
-		n_drill++;
-//		printf("Circle %d %d\n",cx,cy);
+gcode_fill_circle (hidGC gc, int cx, int cy, int radius)
+{
+  use_gc (gc);
+
+  gdImageSetThickness (gcode_im, 0);
+  linewidth = 0;
+  gdImageFilledEllipse (gcode_im, pcb_to_gcode (cx), pcb_to_gcode (cy),
+			pcb_to_gcode (2 * radius + gcode_toolradius * 2),
+			pcb_to_gcode (2 * radius + gcode_toolradius * 2),
+			gc->color->c);
+  if (save_drill && is_drill)
+    {
+      if (n_drill == nmax_drill)
+	{
+	  drill =
+	    (struct drill_struct *) realloc (drill,
+					     (nmax_drill +
+					      100) *
+					     sizeof (struct drill_struct));
+	  nmax_drill += 100;
 	}
+      drill[n_drill].x = (PCB->MaxWidth - cx) / pcb_unit;	//convert to inch, flip: will drill from bottom side
+      drill[n_drill].y = (PCB->MaxHeight - cy) / pcb_unit;	//PCB reverses y axis
+      n_drill++;
+//              printf("Circle %d %d\n",cx,cy);
+    }
 }
 
 static void
-gcode_fill_polygon(hidGC gc, int n_coords, int *x, int *y)
+gcode_fill_polygon (hidGC gc, int n_coords, int *x, int *y)
 {
-	int             i;
-	gdPoint        *points;
-
-	points = (gdPoint *) malloc(n_coords * sizeof(gdPoint));
-	if (points == NULL) {
-		fprintf(stderr, "ERROR:  gcode_fill_polygon():  malloc failed\n");
-		exit(1);
-	}
-	use_gc(gc);
-	for (i = 0; i < n_coords; i++) {
-		points[i].x = pcb_to_gcode(x[i]);
-		points[i].y = pcb_to_gcode(y[i]);
-	}
-	gdImageSetThickness(gcode_im, 0);
-	linewidth = 0;
-	gdImageFilledPolygon(gcode_im, points, n_coords, gc->color->c);
-	free(points);
-//	printf("FillPoly\n");
+  int i;
+  gdPoint *points;
+
+  points = (gdPoint *) malloc (n_coords * sizeof (gdPoint));
+  if (points == NULL)
+    {
+      fprintf (stderr, "ERROR:  gcode_fill_polygon():  malloc failed\n");
+      exit (1);
+    }
+  use_gc (gc);
+  for (i = 0; i < n_coords; i++)
+    {
+      points[i].x = pcb_to_gcode (x[i]);
+      points[i].y = pcb_to_gcode (y[i]);
+    }
+  gdImageSetThickness (gcode_im, 0);
+  linewidth = 0;
+  gdImageFilledPolygon (gcode_im, points, n_coords, gc->color->c);
+  free (points);
+//      printf("FillPoly\n");
 }
 
 static void
-gcode_calibrate(double xval, double yval)
+gcode_calibrate (double xval, double yval)
 {
-	CRASH;
+  CRASH;
 }
 
 static void
-gcode_set_crosshair(int x, int y, int a)
+gcode_set_crosshair (int x, int y, int a)
 {
 }
 
 /* *** Miscellaneous ******************************************************* */
 
-HID             gcode_hid = {
-	sizeof(HID),
-	"gcode",
-	"G-CODE export.",
-	0,			/* gui */
-	0,			/* printer */
-	1,			/* exporter */
-	1,			/* poly before */
-	0,			/* poly after */
-	0,			/* poly dicer */
-	gcode_get_export_options,
-	gcode_do_export,
-	gcode_parse_arguments,
-	0 /* gcode_invalidate_wh */ ,
-	0 /* gcode_invalidate_lr */ ,
-	0 /* gcode_invalidate_all */ ,
-	gcode_set_layer,
-	gcode_make_gc,
-	gcode_destroy_gc,
-	gcode_use_mask,
-	gcode_set_color,
-	gcode_set_line_cap,
-	gcode_set_line_width,
-	gcode_set_draw_xor,
-	gcode_set_draw_faded,
-	gcode_set_line_cap_angle,
-	gcode_draw_line,
-	gcode_draw_arc,
-	gcode_draw_rect,
-	gcode_fill_circle,
-	gcode_fill_polygon,
-	common_fill_pcb_polygon,
-	0 /* nelma_thindraw_pcb_polygon */ ,
-	gcode_fill_rect,
-	gcode_calibrate,
-	0 /* gcode_shift_is_pressed */ ,
-	0 /* gcode_control_is_pressed */ ,
-	0 /* gcode_mod1_is_pressed */ ,
-	0 /* gcode_get_coords */ ,
-	gcode_set_crosshair,
-	0 /* gcode_add_timer */ ,
-	0 /* gcode_stop_timer */ ,
-	0 /* gcode_watch_file */ ,
-	0 /* gcode_unwatch_file */ ,
-	0 /* gcode_add_block_hook */ ,
-	0 /* gcode_stop_block_hook */ ,
-	0 /* gcode_log */ ,
-	0 /* gcode_logv */ ,
-	0 /* gcode_confirm_dialog */ ,
-	0 /* gcode_close_confirm_dialog */ ,
-	0 /* gcode_report_dialog */ ,
-	0 /* gcode_prompt_for */ ,
-	0 /* gcode_fileselect */ ,
-	0 /* gcode_attribute_dialog */ ,
-	0 /* gcode_show_item */ ,
-	0 /* gcode_beep */ ,
-	0 /* gcode_progress */ ,
-	0 /* gcode_drc_gui */
+HID gcode_hid = {
+  sizeof (HID),
+  "gcode",
+  "G-CODE export.",
+  0,				/* gui */
+  0,				/* printer */
+  1,				/* exporter */
+  1,				/* poly before */
+  0,				/* poly after */
+  0,				/* poly dicer */
+  gcode_get_export_options,
+  gcode_do_export,
+  gcode_parse_arguments,
+  0 /* gcode_invalidate_wh */ ,
+  0 /* gcode_invalidate_lr */ ,
+  0 /* gcode_invalidate_all */ ,
+  gcode_set_layer,
+  gcode_make_gc,
+  gcode_destroy_gc,
+  gcode_use_mask,
+  gcode_set_color,
+  gcode_set_line_cap,
+  gcode_set_line_width,
+  gcode_set_draw_xor,
+  gcode_set_draw_faded,
+  gcode_set_line_cap_angle,
+  gcode_draw_line,
+  gcode_draw_arc,
+  gcode_draw_rect,
+  gcode_fill_circle,
+  gcode_fill_polygon,
+  common_fill_pcb_polygon,
+  0 /* nelma_thindraw_pcb_polygon */ ,
+  gcode_fill_rect,
+  gcode_calibrate,
+  0 /* gcode_shift_is_pressed */ ,
+  0 /* gcode_control_is_pressed */ ,
+  0 /* gcode_mod1_is_pressed */ ,
+  0 /* gcode_get_coords */ ,
+  gcode_set_crosshair,
+  0 /* gcode_add_timer */ ,
+  0 /* gcode_stop_timer */ ,
+  0 /* gcode_watch_file */ ,
+  0 /* gcode_unwatch_file */ ,
+  0 /* gcode_add_block_hook */ ,
+  0 /* gcode_stop_block_hook */ ,
+  0 /* gcode_log */ ,
+  0 /* gcode_logv */ ,
+  0 /* gcode_confirm_dialog */ ,
+  0 /* gcode_close_confirm_dialog */ ,
+  0 /* gcode_report_dialog */ ,
+  0 /* gcode_prompt_for */ ,
+  0 /* gcode_fileselect */ ,
+  0 /* gcode_attribute_dialog */ ,
+  0 /* gcode_show_item */ ,
+  0 /* gcode_beep */ ,
+  0 /* gcode_progress */ ,
+  0				/* gcode_drc_gui */
 };
 
 #include "dolists.h"
 
 void
-hid_gcode_init()
+hid_gcode_init ()
 {
-	apply_default_hid(&gcode_hid, 0);
-	hid_register_hid(&gcode_hid);
+  apply_default_hid (&gcode_hid, 0);
+  hid_register_hid (&gcode_hid);
 
 #include "gcode_lists.h"
 }
diff --git a/src/hid/gcode/gcode.h b/src/hid/gcode/gcode.h
index 352cbd9..ae9d7a0 100644
--- a/src/hid/gcode/gcode.h
+++ b/src/hid/gcode/gcode.h
@@ -1,3 +1,3 @@
 /* $Id: nelma.h,v 1.2 2007/04/20 11:31:15 danmc Exp $ */
 
-extern HID      gcode_hid;
+extern HID gcode_hid;
diff --git a/src/hid/gcode/lists.h b/src/hid/gcode/lists.h
index 931cbb0..2a2353f 100644
--- a/src/hid/gcode/lists.h
+++ b/src/hid/gcode/lists.h
@@ -283,4 +283,3 @@
   MACRO_END
 
 #endif /* _PS_LISTS_H */
-
diff --git a/src/hid/gcode/potracelib.h b/src/hid/gcode/potracelib.h
index 0b93d65..2456c01 100644
--- a/src/hid/gcode/potracelib.h
+++ b/src/hid/gcode/potracelib.h
@@ -21,22 +21,24 @@
 #define POTRACE_TURNPOLICY_RANDOM 6
 
 /* structure to hold progress bar callback data */
-struct potrace_progress_s {
-  void (*callback)(double progress, void *privdata); /* callback fn */
-  void *data;          /* callback function's private data */
-  double min, max;     /* desired range of progress, e.g. 0.0 to 1.0 */
-  double epsilon;      /* granularity: can skip smaller increments */
+struct potrace_progress_s
+{
+  void (*callback) (double progress, void *privdata);	/* callback fn */
+  void *data;			/* callback function's private data */
+  double min, max;		/* desired range of progress, e.g. 0.0 to 1.0 */
+  double epsilon;		/* granularity: can skip smaller increments */
 };
 typedef struct potrace_progress_s potrace_progress_t;
 
 /* structure to hold tracing parameters */
-struct potrace_param_s {
-  int turdsize;        /* area of largest path to be ignored */
-  int turnpolicy;      /* resolves ambiguous turns in path decomposition */
-  double alphamax;     /* corner threshold */
-  int opticurve;       /* use curve optimization? */
-  double opttolerance; /* curve optimization tolerance */
-  potrace_progress_t progress; /* progress callback function */
+struct potrace_param_s
+{
+  int turdsize;			/* area of largest path to be ignored */
+  int turnpolicy;		/* resolves ambiguous turns in path decomposition */
+  double alphamax;		/* corner threshold */
+  int opticurve;		/* use curve optimization? */
+  double opttolerance;		/* curve optimization tolerance */
+  potrace_progress_t progress;	/* progress callback function */
 };
 typedef struct potrace_param_s potrace_param_t;
 
@@ -50,10 +52,11 @@ typedef unsigned long potrace_word;
    (map + n*dy). Raster data is stored as a sequence of potrace_words
    (NOT bytes). The leftmost bit of scanline n is the most significant
    bit of scanline(n)[0]. */
-struct potrace_bitmap_s {
-  int w, h;              /* width and height, in pixels */
-  int dy;                /* words per scanline (not bytes) */
-  potrace_word *map;     /* raw data, dy*h words */
+struct potrace_bitmap_s
+{
+  int w, h;			/* width and height, in pixels */
+  int dy;			/* words per scanline (not bytes) */
+  potrace_word *map;		/* raw data, dy*h words */
 };
 typedef struct potrace_bitmap_s potrace_bitmap_t;
 
@@ -61,7 +64,8 @@ typedef struct potrace_bitmap_s potrace_bitmap_t;
 /* curves */
 
 /* point */
-struct potrace_dpoint_s {
+struct potrace_dpoint_s
+{
   double x, y;
 };
 typedef struct potrace_dpoint_s potrace_dpoint_t;
@@ -71,28 +75,30 @@ typedef struct potrace_dpoint_s potrace_dpoint_t;
 #define POTRACE_CORNER 2
 
 /* closed curve segment */
-struct potrace_curve_s {
-  int n;                    /* number of segments */
-  int *tag;                 /* tag[n]: POTRACE_CURVETO or POTRACE_CORNER */
-  potrace_dpoint_t (*c)[3]; /* c[n][3]: control points. 
-			       c[n][0] is unused for tag[n]=POTRACE_CORNER */
+struct potrace_curve_s
+{
+  int n;			/* number of segments */
+  int *tag;			/* tag[n]: POTRACE_CURVETO or POTRACE_CORNER */
+    potrace_dpoint_t (*c)[3];	/* c[n][3]: control points. 
+				   c[n][0] is unused for tag[n]=POTRACE_CORNER */
 };
 typedef struct potrace_curve_s potrace_curve_t;
 
 /* Linked list of signed curve segments. Also carries a tree structure. */
-struct potrace_path_s {
-  int area;                         /* area of the bitmap path */
-  int sign;                         /* '+' or '-', depending on orientation */
-  potrace_curve_t curve;            /* this path's vector data */
+struct potrace_path_s
+{
+  int area;			/* area of the bitmap path */
+  int sign;			/* '+' or '-', depending on orientation */
+  potrace_curve_t curve;	/* this path's vector data */
 
-  struct potrace_path_s *next;      /* linked list structure */
+  struct potrace_path_s *next;	/* linked list structure */
 
-  struct potrace_path_s *childlist; /* tree structure */
-  struct potrace_path_s *sibling;   /* tree structure */
+  struct potrace_path_s *childlist;	/* tree structure */
+  struct potrace_path_s *sibling;	/* tree structure */
 
-  struct potrace_privpath_s *priv;  /* private state */
+  struct potrace_privpath_s *priv;	/* private state */
 };
-typedef struct potrace_path_s potrace_path_t;  
+typedef struct potrace_path_s potrace_path_t;
 
 /* ---------------------------------------------------------------------- */
 /* Potrace state */
@@ -100,11 +106,12 @@ typedef struct potrace_path_s potrace_path_t;
 #define POTRACE_STATUS_OK         0
 #define POTRACE_STATUS_INCOMPLETE 1
 
-struct potrace_state_s {
-  int status;                       
-  potrace_path_t *plist;            /* vector data */
+struct potrace_state_s
+{
+  int status;
+  potrace_path_t *plist;	/* vector data */
 
-  struct potrace_privstate_s *priv; /* private state */
+  struct potrace_privstate_s *priv;	/* private state */
 };
 typedef struct potrace_state_s potrace_state_t;
 
@@ -112,20 +119,20 @@ typedef struct potrace_state_s potrace_state_t;
 /* API functions */
 
 /* get default parameters */
-potrace_param_t *potrace_param_default(void);
+potrace_param_t *potrace_param_default (void);
 
 /* free parameter set */
-void potrace_param_free(potrace_param_t *p);
+void potrace_param_free (potrace_param_t * p);
 
 /* trace a bitmap*/
-potrace_state_t *potrace_trace(const potrace_param_t *param, 
-			       const potrace_bitmap_t *bm);
+potrace_state_t *potrace_trace (const potrace_param_t * param,
+				const potrace_bitmap_t * bm);
 
 /* free a Potrace state */
-void potrace_state_free(potrace_state_t *st);
+void potrace_state_free (potrace_state_t * st);
 
 /* return a static plain text version string identifying this version
    of potracelib */
-char *potrace_version(void);
+char *potrace_version (void);
 
 #endif /* POTRACELIB_H */
diff --git a/src/hid/gcode/trace.c b/src/hid/gcode/trace.c
index 2c615e6..5f1c48e 100644
--- a/src/hid/gcode/trace.c
+++ b/src/hid/gcode/trace.c
@@ -19,60 +19,73 @@
 #include "trace.h"
 //#include "progress.h"
 
-#define INFTY 10000000	/* it suffices that this is longer than any
-			   path; it need not be really infinite */
-#define COS179 -0.999847695156	 /* the cosine of 179 degrees */
+#define INFTY 10000000		/* it suffices that this is longer than any
+				   path; it need not be really infinite */
+#define COS179 -0.999847695156	/* the cosine of 179 degrees */
 
 /* ---------------------------------------------------------------------- */
 #define SAFE_MALLOC(var, n, typ) \
-  if ((var = (typ *)malloc((n)*sizeof(typ))) == NULL) goto malloc_error 
+  if ((var = (typ *)malloc((n)*sizeof(typ))) == NULL) goto malloc_error
 
 /* ---------------------------------------------------------------------- */
 /* auxiliary functions */
 
 /* return a direction that is 90 degrees counterclockwise from p2-p0,
    but then restricted to one of the major wind directions (n, nw, w, etc) */
-static inline point_t dorth_infty(dpoint_t p0, dpoint_t p2) {
+static inline point_t
+dorth_infty (dpoint_t p0, dpoint_t p2)
+{
   point_t r;
-  
-  r.y = sign(p2.x-p0.x);
-  r.x = -sign(p2.y-p0.y);
+
+  r.y = sign (p2.x - p0.x);
+  r.x = -sign (p2.y - p0.y);
 
   return r;
 }
 
 /* return (p1-p0)x(p2-p0), the area of the parallelogram */
-static inline double dpara(dpoint_t p0, dpoint_t p1, dpoint_t p2) {
+static inline double
+dpara (dpoint_t p0, dpoint_t p1, dpoint_t p2)
+{
   double x1, y1, x2, y2;
 
-  x1 = p1.x-p0.x;
-  y1 = p1.y-p0.y;
-  x2 = p2.x-p0.x;
-  y2 = p2.y-p0.y;
+  x1 = p1.x - p0.x;
+  y1 = p1.y - p0.y;
+  x2 = p2.x - p0.x;
+  y2 = p2.y - p0.y;
 
-  return x1*y2 - x2*y1;
+  return x1 * y2 - x2 * y1;
 }
 
 /* ddenom/dpara have the property that the square of radius 1 centered
    at p1 intersects the line p0p2 iff |dpara(p0,p1,p2)| <= ddenom(p0,p2) */
-static inline double ddenom(dpoint_t p0, dpoint_t p2) {
-  point_t r = dorth_infty(p0, p2);
+static inline double
+ddenom (dpoint_t p0, dpoint_t p2)
+{
+  point_t r = dorth_infty (p0, p2);
 
-  return r.y*(p2.x-p0.x) - r.x*(p2.y-p0.y);
+  return r.y * (p2.x - p0.x) - r.x * (p2.y - p0.y);
 }
 
 /* return 1 if a <= b < c < a, in a cyclic sense (mod n) */
-static inline int cyclic(int a, int b, int c) {
-  if (a<=c) {
-    return (a<=b && b<c);
-  } else {
-    return (a<=b || b<c);
-  }
+static inline int
+cyclic (int a, int b, int c)
+{
+  if (a <= c)
+    {
+      return (a <= b && b < c);
+    }
+  else
+    {
+      return (a <= b || b < c);
+    }
 }
 
 /* determine the center and slope of the line i..j. Assume i<j. Needs
    "sum" components of p to be set. */
-static void pointslope(privpath_t *pp, int i, int j, dpoint_t *ctr, dpoint_t *dir) {
+static void
+pointslope (privpath_t * pp, int i, int j, dpoint_t * ctr, dpoint_t * dir)
+{
   /* assume i<j */
 
   int n = pp->len;
@@ -81,62 +94,72 @@ static void pointslope(privpath_t *pp, int i, int j, dpoint_t *ctr, dpoint_t *di
   double x, y, x2, xy, y2;
   double k;
   double a, b, c, lambda2, l;
-  int r=0; /* rotations from i to j */
+  int r = 0;			/* rotations from i to j */
 
-  while (j>=n) {
-    j-=n;
-    r+=1;
-  }
-  while (i>=n) {
-    i-=n;
-    r-=1;
-  }
-  while (j<0) {
-    j+=n;
-    r-=1;
-  }
-  while (i<0) {
-    i+=n;
-    r+=1;
-  }
-  
-  x = sums[j+1].x-sums[i].x+r*sums[n].x;
-  y = sums[j+1].y-sums[i].y+r*sums[n].y;
-  x2 = sums[j+1].x2-sums[i].x2+r*sums[n].x2;
-  xy = sums[j+1].xy-sums[i].xy+r*sums[n].xy;
-  y2 = sums[j+1].y2-sums[i].y2+r*sums[n].y2;
-  k = j+1-i+r*n;
-  
-  ctr->x = x/k;
-  ctr->y = y/k;
-
-  a = (x2-(double)x*x/k)/k;
-  b = (xy-(double)x*y/k)/k;
-  c = (y2-(double)y*y/k)/k;
-  
-  lambda2 = (a+c+sqrt((a-c)*(a-c)+4*b*b))/2; /* larger e.value */
+  while (j >= n)
+    {
+      j -= n;
+      r += 1;
+    }
+  while (i >= n)
+    {
+      i -= n;
+      r -= 1;
+    }
+  while (j < 0)
+    {
+      j += n;
+      r -= 1;
+    }
+  while (i < 0)
+    {
+      i += n;
+      r += 1;
+    }
+
+  x = sums[j + 1].x - sums[i].x + r * sums[n].x;
+  y = sums[j + 1].y - sums[i].y + r * sums[n].y;
+  x2 = sums[j + 1].x2 - sums[i].x2 + r * sums[n].x2;
+  xy = sums[j + 1].xy - sums[i].xy + r * sums[n].xy;
+  y2 = sums[j + 1].y2 - sums[i].y2 + r * sums[n].y2;
+  k = j + 1 - i + r * n;
+
+  ctr->x = x / k;
+  ctr->y = y / k;
+
+  a = (x2 - (double) x * x / k) / k;
+  b = (xy - (double) x * y / k) / k;
+  c = (y2 - (double) y * y / k) / k;
+
+  lambda2 = (a + c + sqrt ((a - c) * (a - c) + 4 * b * b)) / 2;	/* larger e.value */
 
   /* now find e.vector for lambda2 */
   a -= lambda2;
   c -= lambda2;
 
-  if (fabs(a) >= fabs(c)) {
-    l = sqrt(a*a+b*b);
-    if (l!=0) {
-      dir->x = -b/l;
-      dir->y = a/l;
+  if (fabs (a) >= fabs (c))
+    {
+      l = sqrt (a * a + b * b);
+      if (l != 0)
+	{
+	  dir->x = -b / l;
+	  dir->y = a / l;
+	}
     }
-  } else {
-    l = sqrt(c*c+b*b);
-    if (l!=0) {
-      dir->x = -c/l;
-      dir->y = b/l;
+  else
+    {
+      l = sqrt (c * c + b * b);
+      if (l != 0)
+	{
+	  dir->x = -c / l;
+	  dir->y = b / l;
+	}
+    }
+  if (l == 0)
+    {
+      dir->x = dir->y = 0;	/* sometimes this can happen when k=4:
+				   the two eigenvalues coincide */
     }
-  }
-  if (l==0) {
-    dir->x = dir->y = 0;   /* sometimes this can happen when k=4:
-			      the two eigenvalues coincide */
-  }
 }
 
 /* the type of (affine) quadratic forms, represented as symmetric 3x3
@@ -145,7 +168,9 @@ static void pointslope(privpath_t *pp, int i, int j, dpoint_t *ctr, dpoint_t *di
 typedef double quadform_t[3][3];
 
 /* Apply quadratic form Q to vector w = (w.x,w.y) */
-static inline double quadform(quadform_t Q, dpoint_t w) {
+static inline double
+quadform (quadform_t Q, dpoint_t w)
+{
   double v[3];
   int i, j;
   double sum;
@@ -155,21 +180,27 @@ static inline double quadform(quadform_t Q, dpoint_t w) {
   v[2] = 1;
   sum = 0.0;
 
-  for (i=0; i<3; i++) {
-    for (j=0; j<3; j++) {
-      sum += v[i] * Q[i][j] * v[j];
+  for (i = 0; i < 3; i++)
+    {
+      for (j = 0; j < 3; j++)
+	{
+	  sum += v[i] * Q[i][j] * v[j];
+	}
     }
-  }
   return sum;
 }
 
 /* calculate p1 x p2 */
-static inline int xprod(point_t p1, point_t p2) {
-  return p1.x*p2.y - p1.y*p2.x;
+static inline int
+xprod (point_t p1, point_t p2)
+{
+  return p1.x * p2.y - p1.y * p2.x;
 }
 
 /* calculate (p1-p0)x(p3-p2) */
-static inline double cprod(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
+static inline double
+cprod (dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3)
+{
   double x1, y1, x2, y2;
 
   x1 = p1.x - p0.x;
@@ -177,11 +208,13 @@ static inline double cprod(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
   x2 = p3.x - p2.x;
   y2 = p3.y - p2.y;
 
-  return x1*y2 - x2*y1;
+  return x1 * y2 - x2 * y1;
 }
 
 /* calculate (p1-p0)*(p2-p0) */
-static inline double iprod(dpoint_t p0, dpoint_t p1, dpoint_t p2) {
+static inline double
+iprod (dpoint_t p0, dpoint_t p1, dpoint_t p2)
+{
   double x1, y1, x2, y2;
 
   x1 = p1.x - p0.x;
@@ -189,11 +222,13 @@ static inline double iprod(dpoint_t p0, dpoint_t p1, dpoint_t p2) {
   x2 = p2.x - p0.x;
   y2 = p2.y - p0.y;
 
-  return x1*x2 + y1*y2;
+  return x1 * x2 + y1 * y2;
 }
 
 /* calculate (p1-p0)*(p3-p2) */
-static inline double iprod1(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
+static inline double
+iprod1 (dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3)
+{
   double x1, y1, x2, y2;
 
   x1 = p1.x - p0.x;
@@ -201,25 +236,33 @@ static inline double iprod1(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3)
   x2 = p3.x - p2.x;
   y2 = p3.y - p2.y;
 
-  return x1*x2 + y1*y2;
+  return x1 * x2 + y1 * y2;
 }
 
 /* calculate distance between two points */
-static inline double ddist(dpoint_t p, dpoint_t q) {
-  return sqrt(sq(p.x-q.x)+sq(p.y-q.y));
+static inline double
+ddist (dpoint_t p, dpoint_t q)
+{
+  return sqrt (sq (p.x - q.x) + sq (p.y - q.y));
 }
 
 /* calculate point of a bezier curve */
-static inline dpoint_t bezier(double t, dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
-  double s = 1-t;
+static inline dpoint_t
+bezier (double t, dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3)
+{
+  double s = 1 - t;
   dpoint_t res;
 
   /* Note: a good optimizing compiler (such as gcc-3) reduces the
      following to 16 multiplications, using common subexpression
      elimination. */
 
-  res.x = s*s*s*p0.x + 3*(s*s*t)*p1.x + 3*(t*t*s)*p2.x + t*t*t*p3.x;
-  res.y = s*s*s*p0.y + 3*(s*s*t)*p1.y + 3*(t*t*s)*p2.y + t*t*t*p3.y;
+  res.x =
+    s * s * s * p0.x + 3 * (s * s * t) * p1.x + 3 * (t * t * s) * p2.x +
+    t * t * t * p3.x;
+  res.y =
+    s * s * s * p0.y + 3 * (s * s * t) * p1.y + 3 * (t * t * s) * p2.y +
+    t * t * t * p3.y;
 
   return res;
 }
@@ -227,67 +270,80 @@ static inline dpoint_t bezier(double t, dpoint_t p0, dpoint_t p1, dpoint_t p2, d
 /* calculate the point t in [0..1] on the (convex) bezier curve
    (p0,p1,p2,p3) which is tangent to q1-q0. Return -1.0 if there is no
    solution in [0..1]. */
-static double tangent(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3, dpoint_t q0, dpoint_t q1) {
-  double A, B, C;   /* (1-t)^2 A + 2(1-t)t B + t^2 C = 0 */
-  double a, b, c;   /* a t^2 + b t + c = 0 */
+static double
+tangent (dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3, dpoint_t q0,
+	 dpoint_t q1)
+{
+  double A, B, C;		/* (1-t)^2 A + 2(1-t)t B + t^2 C = 0 */
+  double a, b, c;		/* a t^2 + b t + c = 0 */
   double d, s, r1, r2;
 
-  A = cprod(p0, p1, q0, q1);
-  B = cprod(p1, p2, q0, q1);
-  C = cprod(p2, p3, q0, q1);
+  A = cprod (p0, p1, q0, q1);
+  B = cprod (p1, p2, q0, q1);
+  C = cprod (p2, p3, q0, q1);
 
-  a = A - 2*B + C;
-  b = -2*A + 2*B;
+  a = A - 2 * B + C;
+  b = -2 * A + 2 * B;
   c = A;
-  
-  d = b*b - 4*a*c;
 
-  if (a==0 || d<0) {
-    return -1.0;
-  }
+  d = b * b - 4 * a * c;
 
-  s = sqrt(d);
+  if (a == 0 || d < 0)
+    {
+      return -1.0;
+    }
+
+  s = sqrt (d);
 
   r1 = (-b + s) / (2 * a);
   r2 = (-b - s) / (2 * a);
 
-  if (r1 >= 0 && r1 <= 1) {
-    return r1;
-  } else if (r2 >= 0 && r2 <= 1) {
-    return r2;
-  } else {
-    return -1.0;
-  }
+  if (r1 >= 0 && r1 <= 1)
+    {
+      return r1;
+    }
+  else if (r2 >= 0 && r2 <= 1)
+    {
+      return r2;
+    }
+  else
+    {
+      return -1.0;
+    }
 }
 
 /* ---------------------------------------------------------------------- */
 /* Preparation: fill in the sum* fields of a path (used for later
    rapid summing). Return 0 on success, 1 with errno set on
    failure. */
-static int calc_sums(privpath_t *pp) {
+static int
+calc_sums (privpath_t * pp)
+{
   int i, x, y;
   int n = pp->len;
 
-  SAFE_MALLOC(pp->sums, pp->len+1, sums_t);
+  SAFE_MALLOC (pp->sums, pp->len + 1, sums_t);
 
   /* origin */
   pp->x0 = pp->pt[0].x;
   pp->y0 = pp->pt[0].y;
 
   /* preparatory computation for later fast summing */
-  pp->sums[0].x2 = pp->sums[0].xy = pp->sums[0].y2 = pp->sums[0].x = pp->sums[0].y = 0;
-  for (i=0; i<n; i++) {
-    x = pp->pt[i].x - pp->x0;
-    y = pp->pt[i].y - pp->y0;
-    pp->sums[i+1].x = pp->sums[i].x + x;
-    pp->sums[i+1].y = pp->sums[i].y + y;
-    pp->sums[i+1].x2 = pp->sums[i].x2 + x*x;
-    pp->sums[i+1].xy = pp->sums[i].xy + x*y;
-    pp->sums[i+1].y2 = pp->sums[i].y2 + y*y;
-  }
-  return 0;  
+  pp->sums[0].x2 = pp->sums[0].xy = pp->sums[0].y2 = pp->sums[0].x =
+    pp->sums[0].y = 0;
+  for (i = 0; i < n; i++)
+    {
+      x = pp->pt[i].x - pp->x0;
+      y = pp->pt[i].y - pp->y0;
+      pp->sums[i + 1].x = pp->sums[i].x + x;
+      pp->sums[i + 1].y = pp->sums[i].y + y;
+      pp->sums[i + 1].x2 = pp->sums[i].x2 + x * x;
+      pp->sums[i + 1].xy = pp->sums[i].xy + x * y;
+      pp->sums[i + 1].y2 = pp->sums[i].y2 + y * y;
+    }
+  return 0;
 
- malloc_error:
+malloc_error:
   return 1;
 }
 
@@ -321,7 +377,9 @@ static int calc_sums(privpath_t *pp) {
    substantial. */
 
 /* returns 0 on success, 1 on error with errno set */
-static int calc_lon(privpath_t *pp) {
+static int
+calc_lon (privpath_t * pp)
+{
   point_t *pt = pp->pt;
   int n = pp->len;
   int i, j, k, k1;
@@ -329,13 +387,13 @@ static int calc_lon(privpath_t *pp) {
   point_t constraint[2];
   point_t cur;
   point_t off;
-  int *pivk = NULL;  /* pivk[n] */
-  int *nc = NULL;    /* nc[n]: next corner */
-  point_t dk;  /* direction of k-k1 */
+  int *pivk = NULL;		/* pivk[n] */
+  int *nc = NULL;		/* nc[n]: next corner */
+  point_t dk;			/* direction of k-k1 */
   int a, b, c, d;
 
-  SAFE_MALLOC(pivk, n, int);
-  SAFE_MALLOC(nc, n, int);
+  SAFE_MALLOC (pivk, n, int);
+  SAFE_MALLOC (nc, n, int);
 
   /* initialize the nc data structure. Point from each point to the
      furthest future point to which it is connected by a vertical or
@@ -345,136 +403,164 @@ static int calc_lon(privpath_t *pp) {
      in practice, correctness does not depend on the word "furthest"
      above.  */
   k = 0;
-  for (i=n-1; i>=0; i--) {
-    if (pt[i].x != pt[k].x && pt[i].y != pt[k].y) {
-      k = i+1;  /* necessarily i<n-1 in this case */
+  for (i = n - 1; i >= 0; i--)
+    {
+      if (pt[i].x != pt[k].x && pt[i].y != pt[k].y)
+	{
+	  k = i + 1;		/* necessarily i<n-1 in this case */
+	}
+      nc[i] = k;
     }
-    nc[i] = k;
-  }
 
-  SAFE_MALLOC(pp->lon, n, int);
+  SAFE_MALLOC (pp->lon, n, int);
 
   /* determine pivot points: for each i, let pivk[i] be the furthest k
      such that all j with i<j<k lie on a line connecting i,k. */
-  
-  for (i=n-1; i>=0; i--) {
-    ct[0] = ct[1] = ct[2] = ct[3] = 0;
-
-    /* keep track of "directions" that have occurred */
-    dir = (3+3*(pt[mod(i+1,n)].x-pt[i].x)+(pt[mod(i+1,n)].y-pt[i].y))/2;
-    ct[dir]++;
-
-    constraint[0].x = 0;
-    constraint[0].y = 0;
-    constraint[1].x = 0;
-    constraint[1].y = 0;
-
-    /* find the next k such that no straight line from i to k */
-    k = nc[i];
-    k1 = i;
-    while (1) {
-      
-      dir = (3+3*sign(pt[k].x-pt[k1].x)+sign(pt[k].y-pt[k1].y))/2;
+
+  for (i = n - 1; i >= 0; i--)
+    {
+      ct[0] = ct[1] = ct[2] = ct[3] = 0;
+
+      /* keep track of "directions" that have occurred */
+      dir =
+	(3 + 3 * (pt[mod (i + 1, n)].x - pt[i].x) +
+	 (pt[mod (i + 1, n)].y - pt[i].y)) / 2;
       ct[dir]++;
 
-      /* if all four "directions" have occurred, cut this path */
-      if (ct[0] && ct[1] && ct[2] && ct[3]) {
-	pivk[i] = k1;
-	goto foundk;
-      }
-
-      cur.x = pt[k].x - pt[i].x;
-      cur.y = pt[k].y - pt[i].y;
-
-      /* see if current constraint is violated */
-      if (xprod(constraint[0], cur) < 0 || xprod(constraint[1], cur) > 0) {
-	goto constraint_viol;
-      }
-
-      /* else, update constraint */
-      if (abs(cur.x) <= 1 && abs(cur.y) <= 1) {
-	/* no constraint */
-      } else {
-	off.x = cur.x + ((cur.y>=0 && (cur.y>0 || cur.x<0)) ? 1 : -1);
-	off.y = cur.y + ((cur.x<=0 && (cur.x<0 || cur.y<0)) ? 1 : -1);
-	if (xprod(constraint[0], off) >= 0) {
-	  constraint[0] = off;
+      constraint[0].x = 0;
+      constraint[0].y = 0;
+      constraint[1].x = 0;
+      constraint[1].y = 0;
+
+      /* find the next k such that no straight line from i to k */
+      k = nc[i];
+      k1 = i;
+      while (1)
+	{
+
+	  dir =
+	    (3 + 3 * sign (pt[k].x - pt[k1].x) +
+	     sign (pt[k].y - pt[k1].y)) / 2;
+	  ct[dir]++;
+
+	  /* if all four "directions" have occurred, cut this path */
+	  if (ct[0] && ct[1] && ct[2] && ct[3])
+	    {
+	      pivk[i] = k1;
+	      goto foundk;
+	    }
+
+	  cur.x = pt[k].x - pt[i].x;
+	  cur.y = pt[k].y - pt[i].y;
+
+	  /* see if current constraint is violated */
+	  if (xprod (constraint[0], cur) < 0
+	      || xprod (constraint[1], cur) > 0)
+	    {
+	      goto constraint_viol;
+	    }
+
+	  /* else, update constraint */
+	  if (abs (cur.x) <= 1 && abs (cur.y) <= 1)
+	    {
+	      /* no constraint */
+	    }
+	  else
+	    {
+	      off.x =
+		cur.x + ((cur.y >= 0 && (cur.y > 0 || cur.x < 0)) ? 1 : -1);
+	      off.y =
+		cur.y + ((cur.x <= 0 && (cur.x < 0 || cur.y < 0)) ? 1 : -1);
+	      if (xprod (constraint[0], off) >= 0)
+		{
+		  constraint[0] = off;
+		}
+	      off.x =
+		cur.x + ((cur.y <= 0 && (cur.y < 0 || cur.x < 0)) ? 1 : -1);
+	      off.y =
+		cur.y + ((cur.x >= 0 && (cur.x > 0 || cur.y < 0)) ? 1 : -1);
+	      if (xprod (constraint[1], off) <= 0)
+		{
+		  constraint[1] = off;
+		}
+	    }
+	  k1 = k;
+	  k = nc[k1];
+	  if (!cyclic (k, i, k1))
+	    {
+	      break;
+	    }
 	}
-	off.x = cur.x + ((cur.y<=0 && (cur.y<0 || cur.x<0)) ? 1 : -1);
-	off.y = cur.y + ((cur.x>=0 && (cur.x>0 || cur.y<0)) ? 1 : -1);
-	if (xprod(constraint[1], off) <= 0) {
-	  constraint[1] = off;
+    constraint_viol:
+      /* k1 was the last "corner" satisfying the current constraint, and
+         k is the first one violating it. We now need to find the last
+         point along k1..k which satisfied the constraint. */
+      dk.x = sign (pt[k].x - pt[k1].x);
+      dk.y = sign (pt[k].y - pt[k1].y);
+      cur.x = pt[k1].x - pt[i].x;
+      cur.y = pt[k1].y - pt[i].y;
+      /* find largest integer j such that xprod(constraint[0], cur+j*dk)
+         >= 0 and xprod(constraint[1], cur+j*dk) <= 0. Use bilinearity
+         of xprod. */
+      a = xprod (constraint[0], cur);
+      b = xprod (constraint[0], dk);
+      c = xprod (constraint[1], cur);
+      d = xprod (constraint[1], dk);
+      /* find largest integer j such that a+j*b>=0 and c+j*d<=0. This
+         can be solved with integer arithmetic. */
+      j = INFTY;
+      if (b < 0)
+	{
+	  j = floordiv (a, -b);
 	}
-      }	
-      k1 = k;
-      k = nc[k1];
-      if (!cyclic(k,i,k1)) {
-	break;
-      }
-    }
-  constraint_viol:
-    /* k1 was the last "corner" satisfying the current constraint, and
-       k is the first one violating it. We now need to find the last
-       point along k1..k which satisfied the constraint. */
-    dk.x = sign(pt[k].x-pt[k1].x);
-    dk.y = sign(pt[k].y-pt[k1].y);
-    cur.x = pt[k1].x - pt[i].x;
-    cur.y = pt[k1].y - pt[i].y;
-    /* find largest integer j such that xprod(constraint[0], cur+j*dk)
-       >= 0 and xprod(constraint[1], cur+j*dk) <= 0. Use bilinearity
-       of xprod. */
-    a = xprod(constraint[0], cur);
-    b = xprod(constraint[0], dk);
-    c = xprod(constraint[1], cur);
-    d = xprod(constraint[1], dk);
-    /* find largest integer j such that a+j*b>=0 and c+j*d<=0. This
-       can be solved with integer arithmetic. */
-    j = INFTY;
-    if (b<0) {
-      j = floordiv(a,-b);
-    }
-    if (d>0) {
-      j = min(j, floordiv(-c,d));
-    }
-    pivk[i] = mod(k1+j,n);
-  foundk:
-    ;
-  } /* for i */
+      if (d > 0)
+	{
+	  j = min (j, floordiv (-c, d));
+	}
+      pivk[i] = mod (k1 + j, n);
+    foundk:
+      ;
+    }				/* for i */
 
   /* clean up: for each i, let lon[i] be the largest k such that for
      all i' with i<=i'<k, i'<k<=pivk[i']. */
 
-  j=pivk[n-1];
-  pp->lon[n-1]=j;
-  for (i=n-2; i>=0; i--) {
-    if (cyclic(i+1,pivk[i],j)) {
-      j=pivk[i];
+  j = pivk[n - 1];
+  pp->lon[n - 1] = j;
+  for (i = n - 2; i >= 0; i--)
+    {
+      if (cyclic (i + 1, pivk[i], j))
+	{
+	  j = pivk[i];
+	}
+      pp->lon[i] = j;
     }
-    pp->lon[i]=j;
-  }
 
-  for (i=n-1; cyclic(mod(i+1,n),j,pp->lon[i]); i--) {
-    pp->lon[i] = j;
-  }
+  for (i = n - 1; cyclic (mod (i + 1, n), j, pp->lon[i]); i--)
+    {
+      pp->lon[i] = j;
+    }
 
-  free(pivk);
-  free(nc);
+  free (pivk);
+  free (nc);
   return 0;
 
- malloc_error:
-  free(pivk);
-  free(nc);
+malloc_error:
+  free (pivk);
+  free (nc);
   return 1;
 }
 
 
 /* ---------------------------------------------------------------------- */
-/* Stage 2: calculate the optimal polygon (Sec. 2.2.2-2.2.4). */ 
+/* Stage 2: calculate the optimal polygon (Sec. 2.2.2-2.2.4). */
 
 /* Auxiliary function: calculate the penalty of an edge from i to j in
    the given path. This needs the "lon" and "sum*" data. */
 
-static double penalty3(privpath_t *pp, int i, int j) {
+static double
+penalty3 (privpath_t * pp, int i, int j)
+{
   int n = pp->len;
   point_t *pt = pp->pt;
   sums_t *sums = pp->sums;
@@ -485,141 +571,157 @@ static double penalty3(privpath_t *pp, int i, int j) {
   double a, b, c, s;
   double px, py, ex, ey;
 
-  int r=0; /* rotations from i to j */
+  int r = 0;			/* rotations from i to j */
 
-  if (j>=n) {
-    j-=n;
-    r+=1;
-  }
-  
-  x = sums[j+1].x-sums[i].x+r*sums[n].x;
-  y = sums[j+1].y-sums[i].y+r*sums[n].y;
-  x2 = sums[j+1].x2-sums[i].x2+r*sums[n].x2;
-  xy = sums[j+1].xy-sums[i].xy+r*sums[n].xy;
-  y2 = sums[j+1].y2-sums[i].y2+r*sums[n].y2;
-  k = j+1-i+r*n;
-  
-  px = (pt[i].x+pt[j].x)/2.0-pt[0].x;
-  py = (pt[i].y+pt[j].y)/2.0-pt[0].y;
-  ey = (pt[j].x-pt[i].x);
-  ex = -(pt[j].y-pt[i].y);
-
-  a = ((x2-2*x*px)/k+px*px);
-  b = ((xy-x*py-y*px)/k+px*py);
-  c = ((y2-2*y*py)/k+py*py);
-  
-  s = ex*ex*a + 2*ex*ey*b + ey*ey*c;
-
-  return sqrt(s);
+  if (j >= n)
+    {
+      j -= n;
+      r += 1;
+    }
+
+  x = sums[j + 1].x - sums[i].x + r * sums[n].x;
+  y = sums[j + 1].y - sums[i].y + r * sums[n].y;
+  x2 = sums[j + 1].x2 - sums[i].x2 + r * sums[n].x2;
+  xy = sums[j + 1].xy - sums[i].xy + r * sums[n].xy;
+  y2 = sums[j + 1].y2 - sums[i].y2 + r * sums[n].y2;
+  k = j + 1 - i + r * n;
+
+  px = (pt[i].x + pt[j].x) / 2.0 - pt[0].x;
+  py = (pt[i].y + pt[j].y) / 2.0 - pt[0].y;
+  ey = (pt[j].x - pt[i].x);
+  ex = -(pt[j].y - pt[i].y);
+
+  a = ((x2 - 2 * x * px) / k + px * px);
+  b = ((xy - x * py - y * px) / k + px * py);
+  c = ((y2 - 2 * y * py) / k + py * py);
+
+  s = ex * ex * a + 2 * ex * ey * b + ey * ey * c;
+
+  return sqrt (s);
 }
 
 /* find the optimal polygon. Fill in the m and po components. Return 1
    on failure with errno set, else 0. Non-cyclic version: assumes i=0
    is in the polygon. Fixme: ### implement cyclic version. */
-static int bestpolygon(privpath_t *pp)
+static int
+bestpolygon (privpath_t * pp)
 {
-  int i, j, m, k;     
+  int i, j, m, k;
   int n = pp->len;
-  double *pen = NULL; /* pen[n+1]: penalty vector */
-  int *prev = NULL;   /* prev[n+1]: best path pointer vector */
-  int *clip0 = NULL;  /* clip0[n]: longest segment pointer, non-cyclic */
-  int *clip1 = NULL;  /* clip1[n+1]: backwards segment pointer, non-cyclic */
-  int *seg0 = NULL;    /* seg0[m+1]: forward segment bounds, m<=n */
-  int *seg1 = NULL;   /* seg1[m+1]: backward segment bounds, m<=n */
+  double *pen = NULL;		/* pen[n+1]: penalty vector */
+  int *prev = NULL;		/* prev[n+1]: best path pointer vector */
+  int *clip0 = NULL;		/* clip0[n]: longest segment pointer, non-cyclic */
+  int *clip1 = NULL;		/* clip1[n+1]: backwards segment pointer, non-cyclic */
+  int *seg0 = NULL;		/* seg0[m+1]: forward segment bounds, m<=n */
+  int *seg1 = NULL;		/* seg1[m+1]: backward segment bounds, m<=n */
   double thispen;
   double best;
   int c;
 
-  SAFE_MALLOC(pen, n+1, double);
-  SAFE_MALLOC(prev, n+1, int);
-  SAFE_MALLOC(clip0, n, int);
-  SAFE_MALLOC(clip1, n+1, int);
-  SAFE_MALLOC(seg0, n+1, int);
-  SAFE_MALLOC(seg1, n+1, int);
+  SAFE_MALLOC (pen, n + 1, double);
+  SAFE_MALLOC (prev, n + 1, int);
+  SAFE_MALLOC (clip0, n, int);
+  SAFE_MALLOC (clip1, n + 1, int);
+  SAFE_MALLOC (seg0, n + 1, int);
+  SAFE_MALLOC (seg1, n + 1, int);
 
   /* calculate clipped paths */
-  for (i=0; i<n; i++) {
-    c = mod(pp->lon[mod(i-1,n)]-1,n);
-    if (c == i) {
-      c = mod(i+1,n);
-    }
-    if (c < i) {
-      clip0[i] = n;
-    } else {
-      clip0[i] = c;
+  for (i = 0; i < n; i++)
+    {
+      c = mod (pp->lon[mod (i - 1, n)] - 1, n);
+      if (c == i)
+	{
+	  c = mod (i + 1, n);
+	}
+      if (c < i)
+	{
+	  clip0[i] = n;
+	}
+      else
+	{
+	  clip0[i] = c;
+	}
     }
-  }
 
   /* calculate backwards path clipping, non-cyclic. j <= clip0[i] iff
      clip1[j] <= i, for i,j=0..n. */
   j = 1;
-  for (i=0; i<n; i++) {
-    while (j <= clip0[i]) {
-      clip1[j] = i;
-      j++;
+  for (i = 0; i < n; i++)
+    {
+      while (j <= clip0[i])
+	{
+	  clip1[j] = i;
+	  j++;
+	}
     }
-  }
 
   /* calculate seg0[j] = longest path from 0 with j segments */
   i = 0;
-  for (j=0; i<n; j++) {
-    seg0[j] = i;
-    i = clip0[i];
-  }
+  for (j = 0; i < n; j++)
+    {
+      seg0[j] = i;
+      i = clip0[i];
+    }
   seg0[j] = n;
   m = j;
 
   /* calculate seg1[j] = longest path to n with m-j segments */
   i = n;
-  for (j=m; j>0; j--) {
-    seg1[j] = i;
-    i = clip1[i];
-  }
+  for (j = m; j > 0; j--)
+    {
+      seg1[j] = i;
+      i = clip1[i];
+    }
   seg1[0] = 0;
 
   /* now find the shortest path with m segments, based on penalty3 */
   /* note: the outer 2 loops jointly have at most n interations, thus
      the worst-case behavior here is quadratic. In practice, it is
      close to linear since the inner loop tends to be short. */
-  pen[0]=0;
-  for (j=1; j<=m; j++) {
-    for (i=seg1[j]; i<=seg0[j]; i++) {
-      best = -1;
-      for (k=seg0[j-1]; k>=clip1[i]; k--) {
-	thispen = penalty3(pp, k, i) + pen[k];
-	if (best < 0 || thispen < best) {
-	  prev[i] = k;
-	  best = thispen;
+  pen[0] = 0;
+  for (j = 1; j <= m; j++)
+    {
+      for (i = seg1[j]; i <= seg0[j]; i++)
+	{
+	  best = -1;
+	  for (k = seg0[j - 1]; k >= clip1[i]; k--)
+	    {
+	      thispen = penalty3 (pp, k, i) + pen[k];
+	      if (best < 0 || thispen < best)
+		{
+		  prev[i] = k;
+		  best = thispen;
+		}
+	    }
+	  pen[i] = best;
 	}
-      }
-      pen[i] = best;
     }
-  }
 
   pp->m = m;
-  SAFE_MALLOC(pp->po, m, int);
+  SAFE_MALLOC (pp->po, m, int);
 
   /* read off shortest path */
-  for (i=n, j=m-1; i>0; j--) {
-    i = prev[i];
-    pp->po[j] = i;
-  }
+  for (i = n, j = m - 1; i > 0; j--)
+    {
+      i = prev[i];
+      pp->po[j] = i;
+    }
 
-  free(pen);
-  free(prev);
-  free(clip0);
-  free(clip1);
-  free(seg0);
-  free(seg1);
+  free (pen);
+  free (prev);
+  free (clip0);
+  free (clip1);
+  free (seg0);
+  free (seg1);
   return 0;
-  
- malloc_error:
-  free(pen);
-  free(prev);
-  free(clip0);
-  free(clip1);
-  free(seg0);
-  free(seg1);
+
+malloc_error:
+  free (pen);
+  free (prev);
+  free (clip0);
+  free (clip1);
+  free (seg0);
+  free (seg1);
   return 1;
 }
 
@@ -631,7 +733,9 @@ static int bestpolygon(privpath_t *pp)
    if it lies outside. Return 1 with errno set on error; 0 on
    success. */
 
-static int adjust_vertices(privpath_t *pp) {
+static int
+adjust_vertices (privpath_t * pp)
+{
   int m = pp->m;
   int *po = pp->po;
   int n = pp->len;
@@ -639,191 +743,223 @@ static int adjust_vertices(privpath_t *pp) {
   int x0 = pp->x0;
   int y0 = pp->y0;
 
-  dpoint_t *ctr = NULL;      /* ctr[m] */
-  dpoint_t *dir = NULL;      /* dir[m] */
-  quadform_t *q = NULL;      /* q[m] */
+  dpoint_t *ctr = NULL;		/* ctr[m] */
+  dpoint_t *dir = NULL;		/* dir[m] */
+  quadform_t *q = NULL;		/* q[m] */
   double v[3];
   double d;
   int i, j, k, l;
   dpoint_t s;
   int r;
 
-  SAFE_MALLOC(ctr, m, dpoint_t);
-  SAFE_MALLOC(dir, m, dpoint_t);
-  SAFE_MALLOC(q, m, quadform_t);
+  SAFE_MALLOC (ctr, m, dpoint_t);
+  SAFE_MALLOC (dir, m, dpoint_t);
+  SAFE_MALLOC (q, m, quadform_t);
+
+  r = privcurve_init (&pp->curve, m);
+  if (r)
+    {
+      goto malloc_error;
+    }
 
-  r = privcurve_init(&pp->curve, m);
-  if (r) {
-    goto malloc_error;
-  }
-  
   /* calculate "optimal" point-slope representation for each line
      segment */
-  for (i=0; i<m; i++) {
-    j = po[mod(i+1,m)];
-    j = mod(j-po[i],n)+po[i];
-    pointslope(pp, po[i], j, &ctr[i], &dir[i]);
-  }
+  for (i = 0; i < m; i++)
+    {
+      j = po[mod (i + 1, m)];
+      j = mod (j - po[i], n) + po[i];
+      pointslope (pp, po[i], j, &ctr[i], &dir[i]);
+    }
 
   /* represent each line segment as a singular quadratic form; the
      distance of a point (x,y) from the line segment will be
      (x,y,1)Q(x,y,1)^t, where Q=q[i]. */
-  for (i=0; i<m; i++) {
-    d = sq(dir[i].x) + sq(dir[i].y);
-    if (d == 0.0) {
-      for (j=0; j<3; j++) {
-	for (k=0; k<3; k++) {
-	  q[i][j][k] = 0;
+  for (i = 0; i < m; i++)
+    {
+      d = sq (dir[i].x) + sq (dir[i].y);
+      if (d == 0.0)
+	{
+	  for (j = 0; j < 3; j++)
+	    {
+	      for (k = 0; k < 3; k++)
+		{
+		  q[i][j][k] = 0;
+		}
+	    }
 	}
-      }
-    } else {
-      v[0] = dir[i].y;
-      v[1] = -dir[i].x;
-      v[2] = - v[1] * ctr[i].y - v[0] * ctr[i].x;
-      for (l=0; l<3; l++) {
-	for (k=0; k<3; k++) {
-	  q[i][l][k] = v[l] * v[k] / d;
+      else
+	{
+	  v[0] = dir[i].y;
+	  v[1] = -dir[i].x;
+	  v[2] = -v[1] * ctr[i].y - v[0] * ctr[i].x;
+	  for (l = 0; l < 3; l++)
+	    {
+	      for (k = 0; k < 3; k++)
+		{
+		  q[i][l][k] = v[l] * v[k] / d;
+		}
+	    }
 	}
-      }
     }
-  }
 
   /* now calculate the "intersections" of consecutive segments.
      Instead of using the actual intersection, we find the point
      within a given unit square which minimizes the square distance to
      the two lines. */
-  for (i=0; i<m; i++) {
-    quadform_t Q;
-    dpoint_t w;
-    double dx, dy;
-    double det;
-    double min, cand; /* minimum and candidate for minimum of quad. form */
-    double xmin, ymin;	/* coordinates of minimum */
-    int z;
-
-    /* let s be the vertex, in coordinates relative to x0/y0 */
-    s.x = pt[po[i]].x-x0;
-    s.y = pt[po[i]].y-y0;
-
-    /* intersect segments i-1 and i */
-
-    j = mod(i-1,m);
-
-    /* add quadratic forms */
-    for (l=0; l<3; l++) {
-      for (k=0; k<3; k++) {
-	Q[l][k] = q[j][l][k] + q[i][l][k];
-      }
-    }
-    
-    while(1) {
-      /* minimize the quadratic form Q on the unit square */
-      /* find intersection */
+  for (i = 0; i < m; i++)
+    {
+      quadform_t Q;
+      dpoint_t w;
+      double dx, dy;
+      double det;
+      double min, cand;		/* minimum and candidate for minimum of quad. form */
+      double xmin, ymin;	/* coordinates of minimum */
+      int z;
+
+      /* let s be the vertex, in coordinates relative to x0/y0 */
+      s.x = pt[po[i]].x - x0;
+      s.y = pt[po[i]].y - y0;
+
+      /* intersect segments i-1 and i */
+
+      j = mod (i - 1, m);
+
+      /* add quadratic forms */
+      for (l = 0; l < 3; l++)
+	{
+	  for (k = 0; k < 3; k++)
+	    {
+	      Q[l][k] = q[j][l][k] + q[i][l][k];
+	    }
+	}
+
+      while (1)
+	{
+	  /* minimize the quadratic form Q on the unit square */
+	  /* find intersection */
 
 #ifdef HAVE_GCC_LOOP_BUG
-      /* work around gcc bug #12243 */
-      free(NULL);
+	  /* work around gcc bug #12243 */
+	  free (NULL);
 #endif
-      
-      det = Q[0][0]*Q[1][1] - Q[0][1]*Q[1][0];
-      if (det != 0.0) {
-	w.x = (-Q[0][2]*Q[1][1] + Q[1][2]*Q[0][1]) / det;
-	w.y = ( Q[0][2]*Q[1][0] - Q[1][2]*Q[0][0]) / det;
-	break;
-      }
-
-      /* matrix is singular - lines are parallel. Add another,
-	 orthogonal axis, through the center of the unit square */
-      if (Q[0][0]>Q[1][1]) {
-	v[0] = -Q[0][1];
-	v[1] = Q[0][0];
-      } else if (Q[1][1]) {
-	v[0] = -Q[1][1];
-	v[1] = Q[1][0];
-      } else {
-	v[0] = 1;
-	v[1] = 0;
-      }
-      d = sq(v[0]) + sq(v[1]);
-      v[2] = - v[1] * s.y - v[0] * s.x;
-      for (l=0; l<3; l++) {
-	for (k=0; k<3; k++) {
-	  Q[l][k] += v[l] * v[k] / d;
+
+	  det = Q[0][0] * Q[1][1] - Q[0][1] * Q[1][0];
+	  if (det != 0.0)
+	    {
+	      w.x = (-Q[0][2] * Q[1][1] + Q[1][2] * Q[0][1]) / det;
+	      w.y = (Q[0][2] * Q[1][0] - Q[1][2] * Q[0][0]) / det;
+	      break;
+	    }
+
+	  /* matrix is singular - lines are parallel. Add another,
+	     orthogonal axis, through the center of the unit square */
+	  if (Q[0][0] > Q[1][1])
+	    {
+	      v[0] = -Q[0][1];
+	      v[1] = Q[0][0];
+	    }
+	  else if (Q[1][1])
+	    {
+	      v[0] = -Q[1][1];
+	      v[1] = Q[1][0];
+	    }
+	  else
+	    {
+	      v[0] = 1;
+	      v[1] = 0;
+	    }
+	  d = sq (v[0]) + sq (v[1]);
+	  v[2] = -v[1] * s.y - v[0] * s.x;
+	  for (l = 0; l < 3; l++)
+	    {
+	      for (k = 0; k < 3; k++)
+		{
+		  Q[l][k] += v[l] * v[k] / d;
+		}
+	    }
+	}
+      dx = fabs (w.x - s.x);
+      dy = fabs (w.y - s.y);
+      if (dx <= .5 && dy <= .5)
+	{
+	  pp->curve.vertex[i].x = w.x + x0;
+	  pp->curve.vertex[i].y = w.y + y0;
+	  continue;
 	}
-      }
-    }
-    dx = fabs(w.x-s.x);
-    dy = fabs(w.y-s.y);
-    if (dx <= .5 && dy <= .5) {
-      pp->curve.vertex[i].x = w.x+x0;
-      pp->curve.vertex[i].y = w.y+y0;
-      continue;
-    }
 
-    /* the minimum was not in the unit square; now minimize quadratic
-       on boundary of square */
-    min = quadform(Q, s);
-    xmin = s.x;
-    ymin = s.y;
+      /* the minimum was not in the unit square; now minimize quadratic
+         on boundary of square */
+      min = quadform (Q, s);
+      xmin = s.x;
+      ymin = s.y;
 
-    if (Q[0][0] == 0.0) {
-      goto fixx;
-    }
-    for (z=0; z<2; z++) {   /* value of the y-coordinate */
-      w.y = s.y-0.5+z;
-      w.x = - (Q[0][1] * w.y + Q[0][2]) / Q[0][0];
-      dx = fabs(w.x-s.x);
-      cand = quadform(Q, w);
-      if (dx <= .5 && cand < min) {
-	min = cand;
-	xmin = w.x;
-	ymin = w.y;
-      }
-    }
-  fixx:
-    if (Q[1][1] == 0.0) {
-      goto corners;
-    }
-    for (z=0; z<2; z++) {   /* value of the x-coordinate */
-      w.x = s.x-0.5+z;
-      w.y = - (Q[1][0] * w.x + Q[1][2]) / Q[1][1];
-      dy = fabs(w.y-s.y);
-      cand = quadform(Q, w);
-      if (dy <= .5 && cand < min) {
-	min = cand;
-	xmin = w.x;
-	ymin = w.y;
-      }
-    }
-  corners:
-    /* check four corners */
-    for (l=0; l<2; l++) {
-      for (k=0; k<2; k++) {
-	w.x = s.x-0.5+l;
-	w.y = s.y-0.5+k;
-	cand = quadform(Q, w);
-	if (cand < min) {
-	  min = cand;
-	  xmin = w.x;
-	  ymin = w.y;
+      if (Q[0][0] == 0.0)
+	{
+	  goto fixx;
+	}
+      for (z = 0; z < 2; z++)
+	{			/* value of the y-coordinate */
+	  w.y = s.y - 0.5 + z;
+	  w.x = -(Q[0][1] * w.y + Q[0][2]) / Q[0][0];
+	  dx = fabs (w.x - s.x);
+	  cand = quadform (Q, w);
+	  if (dx <= .5 && cand < min)
+	    {
+	      min = cand;
+	      xmin = w.x;
+	      ymin = w.y;
+	    }
+	}
+    fixx:
+      if (Q[1][1] == 0.0)
+	{
+	  goto corners;
+	}
+      for (z = 0; z < 2; z++)
+	{			/* value of the x-coordinate */
+	  w.x = s.x - 0.5 + z;
+	  w.y = -(Q[1][0] * w.x + Q[1][2]) / Q[1][1];
+	  dy = fabs (w.y - s.y);
+	  cand = quadform (Q, w);
+	  if (dy <= .5 && cand < min)
+	    {
+	      min = cand;
+	      xmin = w.x;
+	      ymin = w.y;
+	    }
+	}
+    corners:
+      /* check four corners */
+      for (l = 0; l < 2; l++)
+	{
+	  for (k = 0; k < 2; k++)
+	    {
+	      w.x = s.x - 0.5 + l;
+	      w.y = s.y - 0.5 + k;
+	      cand = quadform (Q, w);
+	      if (cand < min)
+		{
+		  min = cand;
+		  xmin = w.x;
+		  ymin = w.y;
+		}
+	    }
 	}
-      }
-    }
 
-    pp->curve.vertex[i].x = xmin + x0;
-    pp->curve.vertex[i].y = ymin + y0;
-    continue;
-  }
+      pp->curve.vertex[i].x = xmin + x0;
+      pp->curve.vertex[i].y = ymin + y0;
+      continue;
+    }
 
-  free(ctr);
-  free(dir);
-  free(q);
+  free (ctr);
+  free (dir);
+  free (q);
   return 0;
 
- malloc_error:
-  free(ctr);
-  free(dir);
-  free(q);
+malloc_error:
+  free (ctr);
+  free (dir);
+  free (q);
   return 1;
 }
 
@@ -831,60 +967,76 @@ static int adjust_vertices(privpath_t *pp) {
 /* Stage 4: smoothing and corner analysis (Sec. 2.3.3) */
 
 /* Always succeeds and returns 0 */
-static int smooth(privcurve_t *curve, int sign, double alphamax) {
+static int
+smooth (privcurve_t * curve, int sign, double alphamax)
+{
   int m = curve->n;
 
   int i, j, k;
   double dd, denom, alpha;
   dpoint_t p2, p3, p4;
 
-  if (sign == '-') {
-    /* reverse orientation of negative paths */
-    for (i=0, j=m-1; i<j; i++, j--) {
-      dpoint_t tmp;
-      tmp = curve->vertex[i];
-      curve->vertex[i] = curve->vertex[j];
-      curve->vertex[j] = tmp;
+  if (sign == '-')
+    {
+      /* reverse orientation of negative paths */
+      for (i = 0, j = m - 1; i < j; i++, j--)
+	{
+	  dpoint_t tmp;
+	  tmp = curve->vertex[i];
+	  curve->vertex[i] = curve->vertex[j];
+	  curve->vertex[j] = tmp;
+	}
     }
-  }
 
   /* examine each vertex and find its best fit */
-  for (i=0; i<m; i++) {
-    j = mod(i+1, m);
-    k = mod(i+2, m);
-    p4 = interval(1/2.0, curve->vertex[k], curve->vertex[j]);
-
-    denom = ddenom(curve->vertex[i], curve->vertex[k]);
-    if (denom != 0.0) {
-      dd = dpara(curve->vertex[i], curve->vertex[j], curve->vertex[k]) / denom;
-      dd = fabs(dd);
-      alpha = dd>1 ? (1 - 1.0/dd) : 0;
-      alpha = alpha / 0.75;
-    } else {
-      alpha = 4/3.0;
-    }
-    curve->alpha0[j] = alpha;	 /* remember "original" value of alpha */
+  for (i = 0; i < m; i++)
+    {
+      j = mod (i + 1, m);
+      k = mod (i + 2, m);
+      p4 = interval (1 / 2.0, curve->vertex[k], curve->vertex[j]);
+
+      denom = ddenom (curve->vertex[i], curve->vertex[k]);
+      if (denom != 0.0)
+	{
+	  dd =
+	    dpara (curve->vertex[i], curve->vertex[j],
+		   curve->vertex[k]) / denom;
+	  dd = fabs (dd);
+	  alpha = dd > 1 ? (1 - 1.0 / dd) : 0;
+	  alpha = alpha / 0.75;
+	}
+      else
+	{
+	  alpha = 4 / 3.0;
+	}
+      curve->alpha0[j] = alpha;	/* remember "original" value of alpha */
 
-    if (alpha > alphamax) {  /* pointed corner */
-      curve->tag[j] = POTRACE_CORNER;
-      curve->c[j][1] = curve->vertex[j];
-      curve->c[j][2] = p4;
-    } else {
-      if (alpha < 0.55) {
-	alpha = 0.55;
-      } else if (alpha > 1) {
-	alpha = 1;
-      }
-      p2 = interval(.5+.5*alpha, curve->vertex[i], curve->vertex[j]);
-      p3 = interval(.5+.5*alpha, curve->vertex[k], curve->vertex[j]);
-      curve->tag[j] = POTRACE_CURVETO;
-      curve->c[j][0] = p2;
-      curve->c[j][1] = p3;
-      curve->c[j][2] = p4;
+      if (alpha > alphamax)
+	{			/* pointed corner */
+	  curve->tag[j] = POTRACE_CORNER;
+	  curve->c[j][1] = curve->vertex[j];
+	  curve->c[j][2] = p4;
+	}
+      else
+	{
+	  if (alpha < 0.55)
+	    {
+	      alpha = 0.55;
+	    }
+	  else if (alpha > 1)
+	    {
+	      alpha = 1;
+	    }
+	  p2 = interval (.5 + .5 * alpha, curve->vertex[i], curve->vertex[j]);
+	  p3 = interval (.5 + .5 * alpha, curve->vertex[k], curve->vertex[j]);
+	  curve->tag[j] = POTRACE_CURVETO;
+	  curve->c[j][0] = p2;
+	  curve->c[j][1] = p3;
+	  curve->c[j][2] = p4;
+	}
+      curve->alpha[j] = alpha;	/* store the "cropped" value of alpha */
+      curve->beta[j] = 0.5;
     }
-    curve->alpha[j] = alpha;	/* store the "cropped" value of alpha */
-    curve->beta[j] = 0.5;
-  }
   curve->alphacurve = 1;
 
   return 0;
@@ -894,18 +1046,22 @@ static int smooth(privcurve_t *curve, int sign, double alphamax) {
 /* Stage 5: Curve optimization (Sec. 2.4) */
 
 /* a private type for the result of opti_penalty */
-struct opti_s {
-  double pen;	   /* penalty */
-  dpoint_t c[2];   /* curve parameters */
-  double t, s;	   /* curve parameters */
-  double alpha;	   /* curve parameter */
+struct opti_s
+{
+  double pen;			/* penalty */
+  dpoint_t c[2];		/* curve parameters */
+  double t, s;			/* curve parameters */
+  double alpha;			/* curve parameter */
 };
 typedef struct opti_s opti_t;
 
 /* calculate best fit from i+.5 to j+.5.  Assume i<j (cyclically).
    Return 0 and set badness and parameters (alpha, beta), if
    possible. Return 1 if impossible. */
-static int opti_penalty(privpath_t *pp, int i, int j, opti_t *res, double opttolerance, int *convc, double *areac) {
+static int
+opti_penalty (privpath_t * pp, int i, int j, opti_t * res,
+	      double opttolerance, int *convc, double *areac)
+{
   int m = pp->curve.n;
   int k, k1, k2, conv, i1;
   double area, alpha, d, d1, d2;
@@ -915,130 +1071,160 @@ static int opti_penalty(privpath_t *pp, int i, int j, opti_t *res, double opttol
 
   /* check convexity, corner-freeness, and maximum bend < 179 degrees */
 
-  if (i==j) {  /* sanity - a full loop can never be an opticurve */
-    return 1;
-  }
+  if (i == j)
+    {				/* sanity - a full loop can never be an opticurve */
+      return 1;
+    }
 
   k = i;
-  i1 = mod(i+1, m);
-  k1 = mod(k+1, m);
+  i1 = mod (i + 1, m);
+  k1 = mod (k + 1, m);
   conv = convc[k1];
-  if (conv == 0) {
-    return 1;
-  }
-  d = ddist(pp->curve.vertex[i], pp->curve.vertex[i1]);
-  for (k=k1; k!=j; k=k1) {
-    k1 = mod(k+1, m);
-    k2 = mod(k+2, m);
-    if (convc[k1] != conv) {
-      return 1;
-    }
-    if (sign(cprod(pp->curve.vertex[i], pp->curve.vertex[i1], pp->curve.vertex[k1], pp->curve.vertex[k2])) != conv) {
+  if (conv == 0)
+    {
       return 1;
     }
-    if (iprod1(pp->curve.vertex[i], pp->curve.vertex[i1], pp->curve.vertex[k1], pp->curve.vertex[k2]) < d * ddist(pp->curve.vertex[k1], pp->curve.vertex[k2]) * COS179) {
-      return 1;
+  d = ddist (pp->curve.vertex[i], pp->curve.vertex[i1]);
+  for (k = k1; k != j; k = k1)
+    {
+      k1 = mod (k + 1, m);
+      k2 = mod (k + 2, m);
+      if (convc[k1] != conv)
+	{
+	  return 1;
+	}
+      if (sign
+	  (cprod
+	   (pp->curve.vertex[i], pp->curve.vertex[i1], pp->curve.vertex[k1],
+	    pp->curve.vertex[k2])) != conv)
+	{
+	  return 1;
+	}
+      if (iprod1
+	  (pp->curve.vertex[i], pp->curve.vertex[i1], pp->curve.vertex[k1],
+	   pp->curve.vertex[k2]) < d * ddist (pp->curve.vertex[k1],
+					      pp->curve.vertex[k2]) * COS179)
+	{
+	  return 1;
+	}
     }
-  }
 
   /* the curve we're working in: */
-  p0 = pp->curve.c[mod(i,m)][2];
-  p1 = pp->curve.vertex[mod(i+1,m)];
-  p2 = pp->curve.vertex[mod(j,m)];
-  p3 = pp->curve.c[mod(j,m)][2];
+  p0 = pp->curve.c[mod (i, m)][2];
+  p1 = pp->curve.vertex[mod (i + 1, m)];
+  p2 = pp->curve.vertex[mod (j, m)];
+  p3 = pp->curve.c[mod (j, m)][2];
 
   /* determine its area */
   area = areac[j] - areac[i];
-  area -= dpara(pp->curve.vertex[0], pp->curve.c[i][2], pp->curve.c[j][2])/2;
-  if (i>=j) {
-    area += areac[m];
-  }
+  area -=
+    dpara (pp->curve.vertex[0], pp->curve.c[i][2], pp->curve.c[j][2]) / 2;
+  if (i >= j)
+    {
+      area += areac[m];
+    }
 
   /* find intersection o of p0p1 and p2p3. Let t,s such that o =
      interval(t,p0,p1) = interval(s,p3,p2). Let A be the area of the
      triangle (p0,o,p3). */
 
-  A1 = dpara(p0, p1, p2);
-  A2 = dpara(p0, p1, p3);
-  A3 = dpara(p0, p2, p3);
+  A1 = dpara (p0, p1, p2);
+  A2 = dpara (p0, p1, p3);
+  A3 = dpara (p0, p2, p3);
   /* A4 = dpara(p1, p2, p3); */
-  A4 = A1+A3-A2;    
-  
-  if (A2 == A1) {  /* this should never happen */
-    return 1;
-  }
+  A4 = A1 + A3 - A2;
+
+  if (A2 == A1)
+    {				/* this should never happen */
+      return 1;
+    }
 
-  t = A3/(A3-A4);
-  s = A2/(A2-A1);
+  t = A3 / (A3 - A4);
+  s = A2 / (A2 - A1);
   A = A2 * t / 2.0;
-  
-  if (A == 0.0) {  /* this should never happen */
-    return 1;
-  }
 
-  R = area / A;	 /* relative area */
-  alpha = 2 - sqrt(4 - R / 0.3);  /* overall alpha for p0-o-p3 curve */
+  if (A == 0.0)
+    {				/* this should never happen */
+      return 1;
+    }
 
-  res->c[0] = interval(t * alpha, p0, p1);
-  res->c[1] = interval(s * alpha, p3, p2);
+  R = area / A;			/* relative area */
+  alpha = 2 - sqrt (4 - R / 0.3);	/* overall alpha for p0-o-p3 curve */
+
+  res->c[0] = interval (t * alpha, p0, p1);
+  res->c[1] = interval (s * alpha, p3, p2);
   res->alpha = alpha;
   res->t = t;
   res->s = s;
 
   p1 = res->c[0];
-  p2 = res->c[1];  /* the proposed curve is now (p0,p1,p2,p3) */
+  p2 = res->c[1];		/* the proposed curve is now (p0,p1,p2,p3) */
 
   res->pen = 0;
 
   /* calculate penalty */
   /* check tangency with edges */
-  for (k=mod(i+1,m); k!=j; k=k1) {
-    k1 = mod(k+1,m);
-    t = tangent(p0, p1, p2, p3, pp->curve.vertex[k], pp->curve.vertex[k1]);
-    if (t<-.5) {
-      return 1;
-    }
-    pt = bezier(t, p0, p1, p2, p3);
-    d = ddist(pp->curve.vertex[k], pp->curve.vertex[k1]);
-    if (d == 0.0) {  /* this should never happen */
-      return 1;
-    }
-    d1 = dpara(pp->curve.vertex[k], pp->curve.vertex[k1], pt) / d;
-    if (fabs(d1) > opttolerance) {
-      return 1;
-    }
-    if (iprod(pp->curve.vertex[k], pp->curve.vertex[k1], pt) < 0 || iprod(pp->curve.vertex[k1], pp->curve.vertex[k], pt) < 0) {
-      return 1;
+  for (k = mod (i + 1, m); k != j; k = k1)
+    {
+      k1 = mod (k + 1, m);
+      t = tangent (p0, p1, p2, p3, pp->curve.vertex[k], pp->curve.vertex[k1]);
+      if (t < -.5)
+	{
+	  return 1;
+	}
+      pt = bezier (t, p0, p1, p2, p3);
+      d = ddist (pp->curve.vertex[k], pp->curve.vertex[k1]);
+      if (d == 0.0)
+	{			/* this should never happen */
+	  return 1;
+	}
+      d1 = dpara (pp->curve.vertex[k], pp->curve.vertex[k1], pt) / d;
+      if (fabs (d1) > opttolerance)
+	{
+	  return 1;
+	}
+      if (iprod (pp->curve.vertex[k], pp->curve.vertex[k1], pt) < 0
+	  || iprod (pp->curve.vertex[k1], pp->curve.vertex[k], pt) < 0)
+	{
+	  return 1;
+	}
+      res->pen += sq (d1);
     }
-    res->pen += sq(d1);
-  }
 
   /* check corners */
-  for (k=i; k!=j; k=k1) {
-    k1 = mod(k+1,m);
-    t = tangent(p0, p1, p2, p3, pp->curve.c[k][2], pp->curve.c[k1][2]);
-    if (t<-.5) {
-      return 1;
-    }
-    pt = bezier(t, p0, p1, p2, p3);
-    d = ddist(pp->curve.c[k][2], pp->curve.c[k1][2]);
-    if (d == 0.0) {  /* this should never happen */
-      return 1;
-    }
-    d1 = dpara(pp->curve.c[k][2], pp->curve.c[k1][2], pt) / d;
-    d2 = dpara(pp->curve.c[k][2], pp->curve.c[k1][2], pp->curve.vertex[k1]) / d;
-    d2 *= 0.75 * pp->curve.alpha[k1];
-    if (d2 < 0) {
-      d1 = -d1;
-      d2 = -d2;
-    }
-    if (d1 < d2 - opttolerance) {
-      return 1;
-    }
-    if (d1 < d2) {
-      res->pen += sq(d1 - d2);
+  for (k = i; k != j; k = k1)
+    {
+      k1 = mod (k + 1, m);
+      t = tangent (p0, p1, p2, p3, pp->curve.c[k][2], pp->curve.c[k1][2]);
+      if (t < -.5)
+	{
+	  return 1;
+	}
+      pt = bezier (t, p0, p1, p2, p3);
+      d = ddist (pp->curve.c[k][2], pp->curve.c[k1][2]);
+      if (d == 0.0)
+	{			/* this should never happen */
+	  return 1;
+	}
+      d1 = dpara (pp->curve.c[k][2], pp->curve.c[k1][2], pt) / d;
+      d2 =
+	dpara (pp->curve.c[k][2], pp->curve.c[k1][2],
+	       pp->curve.vertex[k1]) / d;
+      d2 *= 0.75 * pp->curve.alpha[k1];
+      if (d2 < 0)
+	{
+	  d1 = -d1;
+	  d2 = -d2;
+	}
+      if (d1 < d2 - opttolerance)
+	{
+	  return 1;
+	}
+      if (d1 < d2)
+	{
+	  res->pen += sq (d1 - d2);
+	}
     }
-  }
 
   return 0;
 }
@@ -1046,14 +1232,16 @@ static int opti_penalty(privpath_t *pp, int i, int j, opti_t *res, double opttol
 /* optimize the path p, replacing sequences of Bezier segments by a
    single segment when possible. Return 0 on success, 1 with errno set
    on failure. */
-static int opticurve(privpath_t *pp, double opttolerance) {
+static int
+opticurve (privpath_t * pp, double opttolerance)
+{
   int m = pp->curve.n;
-  int *pt = NULL;     /* pt[m+1] */
-  double *pen = NULL; /* pen[m+1] */
-  int *len = NULL;    /* len[m+1] */
-  opti_t *opt = NULL; /* opt[m+1] */
+  int *pt = NULL;		/* pt[m+1] */
+  double *pen = NULL;		/* pen[m+1] */
+  int *len = NULL;		/* len[m+1] */
+  opti_t *opt = NULL;		/* opt[m+1] */
   int om;
-  int i,j,r;
+  int i, j, r;
   opti_t o;
   dpoint_t p0;
   int i1;
@@ -1062,38 +1250,50 @@ static int opticurve(privpath_t *pp, double opttolerance) {
   double *s = NULL;
   double *t = NULL;
 
-  int *convc = NULL; /* conv[m]: pre-computed convexities */
-  double *areac = NULL; /* cumarea[m+1]: cache for fast area computation */
+  int *convc = NULL;		/* conv[m]: pre-computed convexities */
+  double *areac = NULL;		/* cumarea[m+1]: cache for fast area computation */
 
-  SAFE_MALLOC(pt, m+1, int);
-  SAFE_MALLOC(pen, m+1, double);
-  SAFE_MALLOC(len, m+1, int);
-  SAFE_MALLOC(opt, m+1, opti_t);
-  SAFE_MALLOC(convc, m, int);
-  SAFE_MALLOC(areac, m+1, double);
+  SAFE_MALLOC (pt, m + 1, int);
+  SAFE_MALLOC (pen, m + 1, double);
+  SAFE_MALLOC (len, m + 1, int);
+  SAFE_MALLOC (opt, m + 1, opti_t);
+  SAFE_MALLOC (convc, m, int);
+  SAFE_MALLOC (areac, m + 1, double);
 
   /* pre-calculate convexity: +1 = right turn, -1 = left turn, 0 = corner */
-  for (i=0; i<m; i++) {
-    if (pp->curve.tag[i] == POTRACE_CURVETO) {
-      convc[i] = sign(dpara(pp->curve.vertex[mod(i-1,m)], pp->curve.vertex[i], pp->curve.vertex[mod(i+1,m)]));
-    } else {
-      convc[i] = 0;
+  for (i = 0; i < m; i++)
+    {
+      if (pp->curve.tag[i] == POTRACE_CURVETO)
+	{
+	  convc[i] =
+	    sign (dpara
+		  (pp->curve.vertex[mod (i - 1, m)], pp->curve.vertex[i],
+		   pp->curve.vertex[mod (i + 1, m)]));
+	}
+      else
+	{
+	  convc[i] = 0;
+	}
     }
-  }
 
   /* pre-calculate areas */
   area = 0.0;
   areac[0] = 0.0;
   p0 = pp->curve.vertex[0];
-  for (i=0; i<m; i++) {
-    i1 = mod(i+1, m);
-    if (pp->curve.tag[i1] == POTRACE_CURVETO) {
-      alpha = pp->curve.alpha[i1];
-      area += 0.3*alpha*(4-alpha)*dpara(pp->curve.c[i][2], pp->curve.vertex[i1], pp->curve.c[i1][2])/2;
-      area += dpara(p0, pp->curve.c[i][2], pp->curve.c[i1][2])/2;
+  for (i = 0; i < m; i++)
+    {
+      i1 = mod (i + 1, m);
+      if (pp->curve.tag[i1] == POTRACE_CURVETO)
+	{
+	  alpha = pp->curve.alpha[i1];
+	  area +=
+	    0.3 * alpha * (4 - alpha) * dpara (pp->curve.c[i][2],
+					       pp->curve.vertex[i1],
+					       pp->curve.c[i1][2]) / 2;
+	  area += dpara (p0, pp->curve.c[i][2], pp->curve.c[i1][2]) / 2;
+	}
+      areac[i + 1] = area;
     }
-    areac[i+1] = area;
-  }
 
   pt[0] = -1;
   pen[0] = 0;
@@ -1102,132 +1302,163 @@ static int opticurve(privpath_t *pp, double opttolerance) {
   /* Fixme: we always start from a fixed point -- should find the best
      curve cyclically ### */
 
-  for (j=1; j<=m; j++) {
-    /* calculate best path from 0 to j */
-    pt[j] = j-1;
-    pen[j] = pen[j-1];
-    len[j] = len[j-1]+1;
-
-    for (i=j-2; i>=0; i--) {
-      r = opti_penalty(pp, i, mod(j,m), &o, opttolerance, convc, areac);
-      if (r) {
-	break;
-      }
-      if (len[j] > len[i]+1 || (len[j] == len[i]+1 && pen[j] > pen[i] + o.pen)) {
-	pt[j] = i;
-	pen[j] = pen[i] + o.pen;
-	len[j] = len[i] + 1;
-	opt[j] = o;
-      }
+  for (j = 1; j <= m; j++)
+    {
+      /* calculate best path from 0 to j */
+      pt[j] = j - 1;
+      pen[j] = pen[j - 1];
+      len[j] = len[j - 1] + 1;
+
+      for (i = j - 2; i >= 0; i--)
+	{
+	  r =
+	    opti_penalty (pp, i, mod (j, m), &o, opttolerance, convc, areac);
+	  if (r)
+	    {
+	      break;
+	    }
+	  if (len[j] > len[i] + 1
+	      || (len[j] == len[i] + 1 && pen[j] > pen[i] + o.pen))
+	    {
+	      pt[j] = i;
+	      pen[j] = pen[i] + o.pen;
+	      len[j] = len[i] + 1;
+	      opt[j] = o;
+	    }
+	}
     }
-  }
   om = len[m];
-  r = privcurve_init(&pp->ocurve, om);
-  if (r) {
-    goto malloc_error;
-  }
-  SAFE_MALLOC(s, om, double);
-  SAFE_MALLOC(t, om, double);
+  r = privcurve_init (&pp->ocurve, om);
+  if (r)
+    {
+      goto malloc_error;
+    }
+  SAFE_MALLOC (s, om, double);
+  SAFE_MALLOC (t, om, double);
 
   j = m;
-  for (i=om-1; i>=0; i--) {
-    if (pt[j]==j-1) {
-      pp->ocurve.tag[i]     = pp->curve.tag[mod(j,m)];
-      pp->ocurve.c[i][0]    = pp->curve.c[mod(j,m)][0];
-      pp->ocurve.c[i][1]    = pp->curve.c[mod(j,m)][1];
-      pp->ocurve.c[i][2]    = pp->curve.c[mod(j,m)][2];
-      pp->ocurve.vertex[i]  = pp->curve.vertex[mod(j,m)];
-      pp->ocurve.alpha[i]   = pp->curve.alpha[mod(j,m)];
-      pp->ocurve.alpha0[i]  = pp->curve.alpha0[mod(j,m)];
-      pp->ocurve.beta[i]    = pp->curve.beta[mod(j,m)];
-      s[i] = t[i] = 1.0;
-    } else {
-      pp->ocurve.tag[i] = POTRACE_CURVETO;
-      pp->ocurve.c[i][0] = opt[j].c[0];
-      pp->ocurve.c[i][1] = opt[j].c[1];
-      pp->ocurve.c[i][2] = pp->curve.c[mod(j,m)][2];
-      pp->ocurve.vertex[i] = interval(opt[j].s, pp->curve.c[mod(j,m)][2], pp->curve.vertex[mod(j,m)]);
-      pp->ocurve.alpha[i] = opt[j].alpha;
-      pp->ocurve.alpha0[i] = opt[j].alpha;
-      s[i] = opt[j].s;
-      t[i] = opt[j].t;
+  for (i = om - 1; i >= 0; i--)
+    {
+      if (pt[j] == j - 1)
+	{
+	  pp->ocurve.tag[i] = pp->curve.tag[mod (j, m)];
+	  pp->ocurve.c[i][0] = pp->curve.c[mod (j, m)][0];
+	  pp->ocurve.c[i][1] = pp->curve.c[mod (j, m)][1];
+	  pp->ocurve.c[i][2] = pp->curve.c[mod (j, m)][2];
+	  pp->ocurve.vertex[i] = pp->curve.vertex[mod (j, m)];
+	  pp->ocurve.alpha[i] = pp->curve.alpha[mod (j, m)];
+	  pp->ocurve.alpha0[i] = pp->curve.alpha0[mod (j, m)];
+	  pp->ocurve.beta[i] = pp->curve.beta[mod (j, m)];
+	  s[i] = t[i] = 1.0;
+	}
+      else
+	{
+	  pp->ocurve.tag[i] = POTRACE_CURVETO;
+	  pp->ocurve.c[i][0] = opt[j].c[0];
+	  pp->ocurve.c[i][1] = opt[j].c[1];
+	  pp->ocurve.c[i][2] = pp->curve.c[mod (j, m)][2];
+	  pp->ocurve.vertex[i] =
+	    interval (opt[j].s, pp->curve.c[mod (j, m)][2],
+		      pp->curve.vertex[mod (j, m)]);
+	  pp->ocurve.alpha[i] = opt[j].alpha;
+	  pp->ocurve.alpha0[i] = opt[j].alpha;
+	  s[i] = opt[j].s;
+	  t[i] = opt[j].t;
+	}
+      j = pt[j];
     }
-    j = pt[j];
-  }
 
   /* calculate beta parameters */
-  for (i=0; i<om; i++) {
-    i1 = mod(i+1,om);
-    pp->ocurve.beta[i] = s[i] / (s[i] + t[i1]);
-  }
+  for (i = 0; i < om; i++)
+    {
+      i1 = mod (i + 1, om);
+      pp->ocurve.beta[i] = s[i] / (s[i] + t[i1]);
+    }
   pp->ocurve.alphacurve = 1;
 
-  free(pt);
-  free(pen);
-  free(len);
-  free(opt);
-  free(s);
-  free(t);
-  free(convc);
-  free(areac);
+  free (pt);
+  free (pen);
+  free (len);
+  free (opt);
+  free (s);
+  free (t);
+  free (convc);
+  free (areac);
   return 0;
 
- malloc_error:
-  free(pt);
-  free(pen);
-  free(len);
-  free(opt);
-  free(s);
-  free(t);
-  free(convc);
-  free(areac);
+malloc_error:
+  free (pt);
+  free (pen);
+  free (len);
+  free (opt);
+  free (s);
+  free (t);
+  free (convc);
+  free (areac);
   return 1;
 }
 
 /* ---------------------------------------------------------------------- */
-double plotpolygon(privpath_t *pp,FILE* f,double scale)
+double
+plotpolygon (privpath_t * pp, FILE * f, double scale)
 {
-  int i;     
+  int i;
   int m = pp->m;
-	if(!m) return 0;
+  if (!m)
+    return 0;
   int *po = pp->po;
   int n = pp->len;
   point_t *pt = pp->pt;
   int x0 = pp->x0;
   int y0 = pp->y0;
-	//double scale=1.0/dpi;
-	double dm=0;
-	fprintf(f,"G0 X%f Y%f    (start point)\n",pt[po[0]].x*scale,pt[po[0]].y*scale);
-	fprintf(f,"G1 Z#101\n");
-	for (i=1; i<m; i++) {
-		fprintf(f,"G1 X%f Y%f\n",pt[po[i]].x*scale,pt[po[i]].y*scale);
-		dm+=sqrt((pt[po[i]].x-pt[po[i-1]].x)*scale*(pt[po[i]].x-pt[po[i-1]].x)*scale+\
-			(pt[po[i]].y-pt[po[i-1]].y)*scale*(pt[po[i]].y-pt[po[i-1]].y)*scale);
-	}
-	fprintf(f,"G1 X%f Y%f\n",pt[po[0]].x*scale,pt[po[0]].y*scale);
-	fprintf(f,"G0 Z#100\n");
-	dm+=sqrt((pt[po[m-1]].x-pt[po[0]].x)*scale*(pt[po[m-1]].x-pt[po[0]].x)*scale+\
-		(pt[po[m-1]].y-pt[po[0]].y)*scale*(pt[po[m-1]].y-pt[po[0]].y)*scale);
-	fprintf(f,"(polygon end, distance %.2f)\n",dm);
-	return dm;
+  //double scale=1.0/dpi;
+  double dm = 0;
+  fprintf (f, "G0 X%f Y%f    (start point)\n", pt[po[0]].x * scale,
+	   pt[po[0]].y * scale);
+  fprintf (f, "G1 Z#101\n");
+  for (i = 1; i < m; i++)
+    {
+      fprintf (f, "G1 X%f Y%f\n", pt[po[i]].x * scale, pt[po[i]].y * scale);
+      dm +=
+	sqrt ((pt[po[i]].x - pt[po[i - 1]].x) * scale * (pt[po[i]].x -
+							 pt[po[i - 1]].x) *
+	      scale + (pt[po[i]].y - pt[po[i - 1]].y) * scale * (pt[po[i]].y -
+								 pt[po
+								    [i -
+								     1]].y) *
+	      scale);
+    }
+  fprintf (f, "G1 X%f Y%f\n", pt[po[0]].x * scale, pt[po[0]].y * scale);
+  fprintf (f, "G0 Z#100\n");
+  dm +=
+    sqrt ((pt[po[m - 1]].x - pt[po[0]].x) * scale * (pt[po[m - 1]].x -
+						     pt[po[0]].x) * scale +
+	  (pt[po[m - 1]].y - pt[po[0]].y) * scale * (pt[po[m - 1]].y -
+						     pt[po[0]].y) * scale);
+  fprintf (f, "(polygon end, distance %.2f)\n", dm);
+  return dm;
 }
 
 #define TRY(x) if (x) goto try_error
 
 /* return distance on success, -1 on error with errno set. */
-double process_path(path_t *plist, const potrace_param_t *param,const potrace_bitmap_t *bm,FILE *f,double scale) {
+double
+process_path (path_t * plist, const potrace_param_t * param,
+	      const potrace_bitmap_t * bm, FILE * f, double scale)
+{
   path_t *p;
   double nn = 0, cn = 0;
-	double dm=0;
-	int n=0;
+  double dm = 0;
+  int n = 0;
   /* call downstream function with each path */
-  list_forall (p, plist) {
-    TRY(calc_sums(p->priv));
-    TRY(calc_lon(p->priv));
-    TRY(bestpolygon(p->priv));
-    TRY(adjust_vertices(p->priv));
-	fprintf(f,"(polygon %d)\n",++n);
-    dm+=plotpolygon(p->priv,f,scale);
+  list_forall (p, plist)
+  {
+    TRY (calc_sums (p->priv));
+    TRY (calc_lon (p->priv));
+    TRY (bestpolygon (p->priv));
+    TRY (adjust_vertices (p->priv));
+    fprintf (f, "(polygon %d)\n", ++n);
+    dm += plotpolygon (p->priv, f, scale);
 /*  No need to extract curves
 	TRY(smooth(&p->priv->curve, p->sign, param->alphamax));
     if (param->opticurve) {
@@ -1238,9 +1469,9 @@ double process_path(path_t *plist, const potrace_param_t *param,const potrace_bi
     }
     privcurve_to_curve(p->priv->fcurve, &p->curve);*/
   }
-//	fprintf(f,"(end, total distance %.2fmm = %.2fin)\n",25.4*dm,dm);
+//      fprintf(f,"(end, total distance %.2fmm = %.2fin)\n",25.4*dm,dm);
   return dm;
 
- try_error:
+try_error:
   return -1;
 }
diff --git a/src/hid/gcode/trace.h b/src/hid/gcode/trace.h
index 4a9683c..2a07e61 100644
--- a/src/hid/gcode/trace.h
+++ b/src/hid/gcode/trace.h
@@ -9,6 +9,7 @@
 
 #include "potracelib.h"
 
-double process_path(path_t *plist, const potrace_param_t *param,const potrace_bitmap_t *bm,FILE *f,double scale);
+double process_path (path_t * plist, const potrace_param_t * param,
+		     const potrace_bitmap_t * bm, FILE * f, double scale);
 
 #endif /* TRACE_H */

commit 47edc12beab88ea5a6d7608e5741131eb5c0e8d4
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    gcode_lists.h should depend on gcode sources, not png sources.

diff --git a/src/Makefile.am b/src/Makefile.am
index 371173a..a5441d6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,7 +12,8 @@ HIDLIST = @HIDLIST@
 noinst_LIBRARIES = @HIDLIBS@
 EXTRA_LIBRARIES = \
 	libgtk.a liblesstif.a libbatch.a \
-	liblpr.a libgerber.a libbom.a libpng.a libps.a libnelma.a libgts.a
+	liblpr.a libgerber.a libbom.a libpng.a libps.a libnelma.a libgts.a \
+	libgcode.a
 
 pcblib_DATA=	\
 	default_font \
@@ -163,6 +164,7 @@ BUILT_SOURCES = \
 	hid/lesstif/lesstif_lists.h \
 	hid/batch/batch_lists.h \
 	hid/png/png_lists.h \
+	hid/gcode/gcode_lists.h \
 	hid/nelma/nelma_lists.h \
 	hid/ps/ps_lists.h \
 	parse_y.h \
@@ -206,6 +208,7 @@ EXTRA_DIST= \
 	$(srcdir)/hid/lesstif/hid.conf \
 	$(srcdir)/hid/lpr/hid.conf \
 	$(srcdir)/hid/png/hid.conf \
+	$(srcdir)/hid/gcode/gcode.conf \
 	$(srcdir)/hid/nelma/hid.conf \
 	$(srcdir)/hid/ps/hid.conf \
 	gpcb-menu.res \
@@ -413,6 +416,29 @@ hid/png/png_lists.h : ${LIBPNG_SRCS} Makefile
 	(for f in ${LIBPNG_SRCS} ; do cat $(srcdir)/$$f ; done) | grep "^REGISTER" > $@.tmp
 	mv $@.tmp $@
 
+libgcode_a_CPPFLAGS = -I./hid/gcode
+LIBGCODE_SRCS = \
+	dolists.h \
+	hid/hidint.h \
+	hid/gcode/gcode.c \
+	hid/gcode/gcode.h \
+	hid/gcode/decompose.c \
+	hid/gcode/decompose.h \
+	hid/gcode/trace.c \
+	hid/gcode/trace.h \
+	hid/gcode/curve.c \
+	hid/gcode/curve.h \
+	hid/gcode/auxiliary.h \
+	hid/gcode/bitmap.h \
+	hid/gcode/lists.h \
+	hid/gcode/potracelib.h 
+libgcode_a_SOURCES = ${LIBGCODE_SRCS} hid/gcode/gcode_lists.h
+
+hid/gcode/gcode_lists.h : ${LIBGCODE_SRCS} Makefile
+	true > $@
+	(for f in ${LIBGCODE_SRCS} ; do cat $(srcdir)/$$f ; done) | grep "^REGISTER" > $@.tmp
+	mv $@.tmp $@
+
 libnelma_a_CPPFLAGS = -I./hid/nelma
 LIBNELMA_SRCS = \
 	dolists.h \
@@ -436,6 +462,7 @@ DISTCLEANFILES= pcbtest.sh gpcb-menu.h pcb-menu.h \
 	hid/gtk/gtk_lists.h \
 	hid/lesstif/lesstif_lists.h \
 	hid/png/png_lists.h \
+	hid/gcode/gcode_lists.h \
 	hid/nelma/nelma_lists.h \
 	hid/ps/ps_lists.h \
 	gts/gts_lists.h \

commit e402b491c199d1df9808e129461d585346a03c9e
Author: Dan McMahill <dan@xxxxxxxxxxxx>
Commit: Dan McMahill <dan@xxxxxxxxxxxx>

    Apply sf patch 2948711 from Alberto Maccioni which adds a g-code
    exporter.

diff --git a/src/hid/gcode/auxiliary.h b/src/hid/gcode/auxiliary.h
new file mode 100644
index 0000000..7baab85
--- /dev/null
+++ b/src/hid/gcode/auxiliary.h
@@ -0,0 +1,78 @@
+/* Copyright (C) 2001-2007 Peter Selinger.
+   This file is part of Potrace. It is free software and it is covered
+   by the GNU General Public License. See the file COPYING for details. */
+
+/* This header file collects some general-purpose macros (and static
+   inline functions) that are used in various places. */
+
+#ifndef AUXILIARY_H
+#define AUXILIARY_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* ---------------------------------------------------------------------- */
+/* point arithmetic */
+
+#include "potracelib.h"
+
+struct point_s {
+  long x;
+  long y;
+};
+typedef struct point_s point_t;
+
+typedef potrace_dpoint_t dpoint_t;
+
+/* convert point_t to dpoint_t */
+static inline dpoint_t dpoint(point_t p) {
+  dpoint_t res;
+  res.x = p.x;
+  res.y = p.y;
+  return res;
+}
+
+/* range over the straight line segment [a,b] when lambda ranges over [0,1] */
+static inline dpoint_t interval(double lambda, dpoint_t a, dpoint_t b) {
+  dpoint_t res;
+
+  res.x = a.x + lambda * (b.x - a.x);
+  res.y = a.y + lambda * (b.y - a.y);
+  return res;
+}
+
+/* ---------------------------------------------------------------------- */
+/* some useful macros. Note: the "mod" macro works correctly for
+   negative a. Also note that the test for a>=n, while redundant,
+   speeds up the mod function by 70% in the average case (significant
+   since the program spends about 16% of its time here - or 40%
+   without the test). The "floordiv" macro returns the largest integer
+   <= a/n, and again this works correctly for negative a, as long as
+   a,n are integers and n>0. */
+
+/* integer arithmetic */
+
+static inline int mod(int a, int n) {
+  return a>=n ? a%n : a>=0 ? a : n-1-(-1-a)%n;
+}
+
+static inline int floordiv(int a, int n) {
+  return a>=0 ? a/n : -1-(-1-a)/n;
+}
+
+/* Note: the following work for integers and other numeric types. */
+#undef sign
+#undef abs
+#undef min
+#undef max
+#undef sq
+#undef cu
+#define sign(x) ((x)>0 ? 1 : (x)<0 ? -1 : 0)
+#define abs(a) ((a)>0 ? (a) : -(a))
+#define min(a,b) ((a)<(b) ? (a) : (b))
+#define max(a,b) ((a)>(b) ? (a) : (b))
+#define sq(a) ((a)*(a))
+#define cu(a) ((a)*(a)*(a))
+
+#endif /* AUXILIARY_H */
diff --git a/src/hid/gcode/bitmap.h b/src/hid/gcode/bitmap.h
new file mode 100644
index 0000000..2a172b1
--- /dev/null
+++ b/src/hid/gcode/bitmap.h
@@ -0,0 +1,101 @@
+/* Copyright (C) 2001-2007 Peter Selinger.
+   This file is part of Potrace. It is free software and it is covered
+   by the GNU General Public License. See the file COPYING for details. */
+
+#ifndef BITMAP_H
+#define BITMAP_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+/* The bitmap type is defined in potracelib.h */
+#include "potracelib.h"
+
+/* The present file defines some convenient macros and static inline
+   functions for accessing bitmaps. Since they only produce inline
+   code, they can be conveniently shared by the library and frontends,
+   if desired */
+
+/* ---------------------------------------------------------------------- */
+/* some measurements */
+
+#define BM_WORDSIZE ((int)sizeof(potrace_word))
+#define BM_WORDBITS (8*BM_WORDSIZE)
+#define BM_HIBIT (((potrace_word)1)<<(BM_WORDBITS-1))
+#define BM_ALLBITS (~(potrace_word)0)
+
+/* macros for accessing pixel at index (x,y). U* macros omit the
+   bounds check. */
+
+#define bm_scanline(bm, y) ((bm)->map + (y)*(bm)->dy)
+#define bm_index(bm, x, y) (&bm_scanline(bm, y)[(x)/BM_WORDBITS])
+#define bm_mask(x) (BM_HIBIT >> ((x) & (BM_WORDBITS-1)))
+#define bm_range(x, a) ((int)(x) >= 0 && (int)(x) < (a))
+#define bm_safe(bm, x, y) (bm_range(x, (bm)->w) && bm_range(y, (bm)->h))
+#define BM_UGET(bm, x, y) ((*bm_index(bm, x, y) & bm_mask(x)) != 0)
+#define BM_USET(bm, x, y) (*bm_index(bm, x, y) |= bm_mask(x))
+#define BM_UCLR(bm, x, y) (*bm_index(bm, x, y) &= ~bm_mask(x))
+#define BM_UINV(bm, x, y) (*bm_index(bm, x, y) ^= bm_mask(x))
+#define BM_UPUT(bm, x, y, b) ((b) ? BM_USET(bm, x, y) : BM_UCLR(bm, x, y))
+#define BM_GET(bm, x, y) (bm_safe(bm, x, y) ? BM_UGET(bm, x, y) : 0)
+#define BM_SET(bm, x, y) (bm_safe(bm, x, y) ? BM_USET(bm, x, y) : 0)
+#define BM_CLR(bm, x, y) (bm_safe(bm, x, y) ? BM_UCLR(bm, x, y) : 0)
+#define BM_INV(bm, x, y) (bm_safe(bm, x, y) ? BM_UINV(bm, x, y) : 0)
+#define BM_PUT(bm, x, y, b) (bm_safe(bm, x, y) ? BM_UPUT(bm, x, y, b) : 0)
+
+/* free the given bitmap. Leaves errno untouched. */
+static inline void bm_free(potrace_bitmap_t *bm) {
+  if (bm) {
+    free(bm->map);
+  }
+  free(bm);
+}
+
+/* return new un-initialized bitmap. NULL with errno on error */
+static inline potrace_bitmap_t *bm_new(int w, int h) {
+  potrace_bitmap_t *bm;
+  int dy = (w + BM_WORDBITS - 1) / BM_WORDBITS;
+
+  bm = (potrace_bitmap_t *) malloc(sizeof(potrace_bitmap_t));
+  if (!bm) {
+    return NULL;
+  }
+  bm->w = w;
+  bm->h = h;
+  bm->dy = dy;
+  bm->map = (potrace_word *) malloc(dy * h * BM_WORDSIZE);
+  if (!bm->map) {
+    free(bm);
+    return NULL;
+  }
+  return bm;
+}
+
+/* clear the given bitmap. Set all bits to c. */
+static inline void bm_clear(potrace_bitmap_t *bm, int c) {
+  memset(bm->map, c ? -1 : 0, bm->dy * bm->h * BM_WORDSIZE);
+}
+
+/* duplicate the given bitmap. Return NULL on error with errno set. */
+static inline potrace_bitmap_t *bm_dup(const potrace_bitmap_t *bm) {
+  potrace_bitmap_t *bm1 = bm_new(bm->w, bm->h);
+  if (!bm1) {
+    return NULL;
+  }
+  memcpy(bm1->map, bm->map, bm->dy * bm->h * BM_WORDSIZE);
+  return bm1;
+}
+
+/* invert the given bitmap. */
+static inline void bm_invert(potrace_bitmap_t *bm) {
+  int i;
+  for (i = 0; i < bm->dy * bm->h; i++) {
+    bm->map[i] ^= BM_ALLBITS;
+  }
+}
+
+#endif /* BITMAP_H */
diff --git a/src/hid/gcode/curve.c b/src/hid/gcode/curve.c
new file mode 100644
index 0000000..0dc1005
--- /dev/null
+++ b/src/hid/gcode/curve.c
@@ -0,0 +1,109 @@
+/* Copyright (C) 2001-2007 Peter Selinger.
+   This file is part of Potrace. It is free software and it is covered
+   by the GNU General Public License. See the file COPYING for details. */
+
+/* $Id: curve.c 147 2007-04-09 00:44:09Z selinger $ */
+/* private part of the path and curve data structures */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "potracelib.h"
+#include "lists.h"
+#include "curve.h"
+
+#define SAFE_MALLOC(var, n, typ) \
+  if ((var = (typ *)malloc((n)*sizeof(typ))) == NULL) goto malloc_error 
+
+/* ---------------------------------------------------------------------- */
+/* allocate and free path objects */
+
+path_t *path_new(void) {
+  path_t *p = NULL;
+  privpath_t *priv = NULL;
+
+  SAFE_MALLOC(p, 1, path_t);
+  memset(p, 0, sizeof(path_t));
+  SAFE_MALLOC(priv, 1, privpath_t);
+  memset(priv, 0, sizeof(privpath_t));
+  p->priv = priv;
+  return p;
+
+ malloc_error:
+  free(p);
+  free(priv);
+  return NULL;
+}
+
+/* free the members of the given curve structure. Leave errno unchanged. */
+static void privcurve_free_members(privcurve_t *curve) {
+  free(curve->tag);
+  free(curve->c);
+  free(curve->vertex);
+  free(curve->alpha);
+  free(curve->alpha0);
+  free(curve->beta);
+}
+
+/* free a path. Leave errno untouched. */
+void path_free(path_t *p) {
+  if (p) {
+    if (p->priv) {
+      free(p->priv->pt);
+      free(p->priv->lon);
+      free(p->priv->sums);
+      free(p->priv->po);
+      privcurve_free_members(&p->priv->curve);
+      privcurve_free_members(&p->priv->ocurve);
+    }
+    free(p->priv);
+    /* do not free p->fcurve ! */
+  }
+  free(p);
+}  
+
+/* free a pathlist, leaving errno untouched. */
+void pathlist_free(path_t *plist) {
+  path_t *p;
+
+  list_forall_unlink(p, plist) {
+    path_free(p);
+  }
+}
+
+/* ---------------------------------------------------------------------- */
+/* initialize and finalize curve structures */
+
+typedef dpoint_t dpoint3_t[3];
+
+/* initialize the members of the given curve structure to size m.
+   Return 0 on success, 1 on error with errno set. */
+int privcurve_init(privcurve_t *curve, int n) {
+  memset(curve, 0, sizeof(privcurve_t));
+  curve->n = n;
+  SAFE_MALLOC(curve->tag, n, int);
+  SAFE_MALLOC(curve->c, n, dpoint3_t);
+  SAFE_MALLOC(curve->vertex, n, dpoint_t);
+  SAFE_MALLOC(curve->alpha, n, double);
+  SAFE_MALLOC(curve->alpha0, n, double);
+  SAFE_MALLOC(curve->beta, n, double);
+  return 0;
+
+ malloc_error:
+  free(curve->tag);
+  free(curve->c);
+  free(curve->vertex);
+  free(curve->alpha);
+  free(curve->alpha0);
+  free(curve->beta);
+  return 1;
+}
+
+/* copy private to public curve structure */
+void privcurve_to_curve(privcurve_t *pc, potrace_curve_t *c) {
+  c->n = pc->n;
+  c->tag = pc->tag;
+  c->c = pc->c;
+}
+    
diff --git a/src/hid/gcode/curve.h b/src/hid/gcode/curve.h
new file mode 100644
index 0000000..45c0790
--- /dev/null
+++ b/src/hid/gcode/curve.h
@@ -0,0 +1,77 @@
+/* Copyright (C) 2001-2007 Peter Selinger.
+   This file is part of Potrace. It is free software and it is covered
+   by the GNU General Public License. See the file COPYING for details. */
+
+#ifndef CURVE_H
+#define CURVE_H
+
+#include "auxiliary.h"
+
+/* vertex is c[1] for tag=POTRACE_CORNER, and the intersection of
+   .c[-1][2]..c[0] and c[1]..c[2] for tag=POTRACE_CURVETO. alpha is only
+   defined for tag=POTRACE_CURVETO and is the alpha parameter of the curve:
+   .c[-1][2]..c[0] = alpha*(.c[-1][2]..vertex), and
+   c[2]..c[1] = alpha*(c[2]..vertex).
+   Beta is so that (.beta[i])[.vertex[i],.vertex[i+1]] = .c[i][2].
+*/
+
+struct privcurve_s {
+  int n;            /* number of segments */
+  int *tag;         /* tag[n]: POTRACE_CORNER or POTRACE_CURVETO */
+  dpoint_t (*c)[3]; /* c[n][i]: control points. 
+		       c[n][0] is unused for tag[n]=POTRACE_CORNER */
+  /* the remainder of this structure is special to privcurve, and is
+     used in EPS debug output and special EPS "short coding". These
+     fields are valid only if "alphacurve" is set. */
+  int alphacurve;   /* have the following fields been initialized? */
+  dpoint_t *vertex; /* for POTRACE_CORNER, this equals c[1] */
+  double *alpha;    /* only for POTRACE_CURVETO */
+  double *alpha0;   /* "uncropped" alpha parameter - for debug output only */
+  double *beta;
+};
+typedef struct privcurve_s privcurve_t;
+
+struct sums_s {
+  double x;
+  double y;
+  double x2;
+  double xy;
+  double y2;
+};
+typedef struct sums_s sums_t;
+
+/* the path structure is filled in with information about a given path
+   as it is accumulated and passed through the different stages of the
+   Potrace algorithm. Backends only need to read the fcurve and fm
+   fields of this data structure, but debugging backends may read
+   other fields. */
+struct potrace_privpath_s {
+  int len;
+  point_t *pt;     /* pt[len]: path as extracted from bitmap */
+  int *lon;        /* lon[len]: (i,lon[i]) = longest straight line from i */
+
+  int x0, y0;      /* origin for sums */
+  sums_t *sums;    /* sums[len+1]: cache for fast summing */
+
+  int m;           /* length of optimal polygon */
+  int *po;         /* po[m]: optimal polygon */
+
+  privcurve_t curve;   /* curve[m]: array of curve elements */
+  privcurve_t ocurve;  /* ocurve[om]: array of curve elements */
+  privcurve_t *fcurve;  /* final curve: this points to either curve or
+		       ocurve. Do not free this separately. */
+};
+typedef struct potrace_privpath_s potrace_privpath_t;
+
+/* shorter names */
+typedef potrace_privpath_t privpath_t;
+typedef potrace_path_t path_t;
+
+path_t *path_new(void);
+void path_free(path_t *p);
+void pathlist_free(path_t *plist);
+int privcurve_init(privcurve_t *curve, int n);
+void privcurve_to_curve(privcurve_t *pc, potrace_curve_t *c);
+
+#endif /* CURVE_H */
+
diff --git a/src/hid/gcode/decompose.c b/src/hid/gcode/decompose.c
new file mode 100644
index 0000000..abc5e0a
--- /dev/null
+++ b/src/hid/gcode/decompose.c
@@ -0,0 +1,508 @@
+/* Copyright (C) 2001-2007 Peter Selinger.
+   This file is part of Potrace. It is free software and it is covered
+   by the GNU General Public License. See the file COPYING for details. */
+
+/* $Id: decompose.c 146 2007-04-09 00:43:46Z selinger $ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
+#include "potracelib.h"
+#include "curve.h"
+#include "lists.h"
+#include "auxiliary.h"
+#include "bitmap.h"
+#include "decompose.h"
+//#include "progress.h"
+
+/* ---------------------------------------------------------------------- */
+/* auxiliary bitmap manipulations */
+
+/* set the excess padding to 0 */
+static void bm_clearexcess(potrace_bitmap_t *bm) {
+  potrace_word mask;
+  int y;
+
+  if (bm->w % BM_WORDBITS != 0) {
+    mask = BM_ALLBITS << (BM_WORDBITS - (bm->w % BM_WORDBITS));
+    for (y=0; y<bm->h; y++) {
+      *bm_index(bm, bm->w, y) &= mask;
+    }
+  }
+}
+
+struct bbox_s {
+  int x0, x1, y0, y1;    /* bounding box */
+};
+typedef struct bbox_s bbox_t;
+
+/* clear the bm, assuming the bounding box is set correctly (faster
+   than clearing the whole bitmap) */
+static void clear_bm_with_bbox(potrace_bitmap_t *bm, bbox_t *bbox) {
+  int imin = (bbox->x0 / BM_WORDBITS);
+  int imax = ((bbox->x1 + BM_WORDBITS-1) / BM_WORDBITS);
+  int i, y;
+
+  for (y=bbox->y0; y<bbox->y1; y++) {
+    for (i=imin; i<imax; i++) {
+      bm_scanline(bm, y)[i] = 0;
+    }
+  }
+}
+
+/* ---------------------------------------------------------------------- */
+/* auxiliary functions */
+
+/* deterministically and efficiently hash (x,y) into a pseudo-random bit */
+static inline int detrand(int x, int y) {
+  unsigned int z;
+  static const unsigned char t[256] = { 
+    /* non-linear sequence: constant term of inverse in GF(8), 
+       mod x^8+x^4+x^3+x+1 */
+    0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 
+    0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 
+    0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 
+    1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 
+    0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 
+    0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 
+    0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 
+    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 
+    1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 
+    0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 
+    1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 
+  };
+
+  /* 0x04b3e375 and 0x05a8ef93 are chosen to contain every possible
+     5-bit sequence */
+  z = ((0x04b3e375 * x) ^ y) * 0x05a8ef93;
+  z = t[z & 0xff] ^ t[(z>>8) & 0xff] ^ t[(z>>16) & 0xff] ^ t[(z>>24) & 0xff];
+  return z & 1;
+}
+
+/* return the "majority" value of bitmap bm at intersection (x,y). We
+   assume that the bitmap is balanced at "radius" 1.  */
+static int majority(potrace_bitmap_t *bm, int x, int y) {
+  int i, a, ct;
+
+  for (i=2; i<5; i++) { /* check at "radius" i */
+    ct = 0;
+    for (a=-i+1; a<=i-1; a++) {
+      ct += BM_GET(bm, x+a, y+i-1) ? 1 : -1;
+      ct += BM_GET(bm, x+i-1, y+a-1) ? 1 : -1;
+      ct += BM_GET(bm, x+a-1, y-i) ? 1 : -1;
+      ct += BM_GET(bm, x-i, y+a) ? 1 : -1;
+    }
+    if (ct>0) {
+      return 1;
+    } else if (ct<0) {
+      return 0;
+    }
+  }
+  return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+/* decompose image into paths */
+
+/* efficiently invert bits [x,infty) and [xa,infty) in line y. Here xa
+   must be a multiple of BM_WORDBITS. */
+static void xor_to_ref(potrace_bitmap_t *bm, int x, int y, int xa) {
+  int xhi = x & -BM_WORDBITS;
+  int xlo = x & (BM_WORDBITS-1);  /* = x % BM_WORDBITS */
+  int i;
+  
+  if (xhi<xa) {
+    for (i = xhi; i < xa; i+=BM_WORDBITS) {
+      *bm_index(bm, i, y) ^= BM_ALLBITS;
+    }
+  } else {
+    for (i = xa; i < xhi; i+=BM_WORDBITS) {
+      *bm_index(bm, i, y) ^= BM_ALLBITS;
+    }
+  }
+  /* note: the following "if" is needed because x86 treats a<<b as
+     a<<(b&31). I spent hours looking for this bug. */
+  if (xlo) {
+    *bm_index(bm, xhi, y) ^= (BM_ALLBITS << (BM_WORDBITS - xlo));
+  }
+}
+
+/* a path is represented as an array of points, which are thought to
+   lie on the corners of pixels (not on their centers). The path point
+   (x,y) is the lower left corner of the pixel (x,y). Paths are
+   represented by the len/pt components of a path_t object (which
+   also stores other information about the path) */
+
+/* xor the given pixmap with the interior of the given path. Note: the
+   path must be within the dimensions of the pixmap. */
+static void xor_path(potrace_bitmap_t *bm, path_t *p) {
+  int xa, x, y, k, y1;
+
+  if (p->priv->len <= 0) {  /* a path of length 0 is silly, but legal */
+    return;
+  }
+
+  y1 = p->priv->pt[p->priv->len-1].y;
+
+  xa = p->priv->pt[0].x & -BM_WORDBITS;
+  for (k=0; k<p->priv->len; k++) {
+    x = p->priv->pt[k].x;
+    y = p->priv->pt[k].y;
+
+    if (y != y1) {
+      /* efficiently invert the rectangle [x,xa] x [y,y1] */
+      xor_to_ref(bm, x, min(y,y1), xa);
+      y1 = y;
+    }
+  }
+}
+
+/* Find the bounding box of a given path. Path is assumed to be of
+   non-zero length. */
+static void setbbox_path(bbox_t *bbox, path_t *p) {
+  int x, y;
+  int k;
+
+  bbox->y0 = INT_MAX;
+  bbox->y1 = 0;
+  bbox->x0 = INT_MAX;
+  bbox->x1 = 0;
+
+  for (k=0; k<p->priv->len; k++) {
+    x = p->priv->pt[k].x;
+    y = p->priv->pt[k].y;
+
+    if (x < bbox->x0) {
+      bbox->x0 = x;
+    }
+    if (x > bbox->x1) {
+      bbox->x1 = x;
+    }
+    if (y < bbox->y0) {
+      bbox->y0 = y;
+    }
+    if (y > bbox->y1) {
+      bbox->y1 = y;
+    }
+  }
+}
+
+/* compute a path in the given pixmap, separating black from white.
+   Start path at the point (x0,x1), which must be an upper left corner
+   of the path. Also compute the area enclosed by the path. Return a
+   new path_t object, or NULL on error (note that a legitimate path
+   cannot have length 0). Sign is required for correct interpretation
+   of turnpolicies. */
+static path_t *findpath(potrace_bitmap_t *bm, int x0, int y0, int sign, int turnpolicy) {
+  int x, y, dirx, diry, len, size, area;
+  int c, d, tmp;
+  point_t *pt, *pt1;
+  path_t *p = NULL;
+
+  x = x0;
+  y = y0;
+  dirx = 0;
+  diry = -1;
+
+  len = size = 0;
+  pt = NULL;
+  area = 0;
+  
+  while (1) {
+    /* add point to path */
+    if (len>=size) {
+      size += 100;
+      size = (int)(1.3 * size);
+      pt1 = (point_t *)realloc(pt, size * sizeof(point_t));
+      if (!pt1) {
+	goto error;
+      }
+      pt = pt1;
+    }
+    pt[len].x = x;
+    pt[len].y = y;
+    len++;
+    
+    /* move to next point */
+    x += dirx;
+    y += diry;
+    area += x*diry;
+    
+    /* path complete? */
+    if (x==x0 && y==y0) {
+      break;
+    }
+    
+    /* determine next direction */
+    c = BM_GET(bm, x + (dirx+diry-1)/2, y + (diry-dirx-1)/2);
+    d = BM_GET(bm, x + (dirx-diry-1)/2, y + (diry+dirx-1)/2);
+    
+    if (c && !d) {               /* ambiguous turn */
+      if (turnpolicy == POTRACE_TURNPOLICY_RIGHT
+	  || (turnpolicy == POTRACE_TURNPOLICY_BLACK && sign == '+')
+	  || (turnpolicy == POTRACE_TURNPOLICY_WHITE && sign == '-')
+	  || (turnpolicy == POTRACE_TURNPOLICY_RANDOM && detrand(x,y))
+	  || (turnpolicy == POTRACE_TURNPOLICY_MAJORITY && majority(bm, x, y))
+	  || (turnpolicy == POTRACE_TURNPOLICY_MINORITY && !majority(bm, x, y))) {
+	tmp = dirx;              /* right turn */
+	dirx = diry;
+	diry = -tmp;
+      } else {
+	tmp = dirx;              /* left turn */
+	dirx = -diry;
+	diry = tmp;
+      }
+    } else if (c) {              /* right turn */
+      tmp = dirx;
+      dirx = diry;
+      diry = -tmp;
+    } else if (!d) {             /* left turn */
+      tmp = dirx;
+      dirx = -diry;
+      diry = tmp;
+    }
+  } /* while this path */
+
+  /* allocate new path object */
+  p = path_new();
+  if (!p) {
+    goto error;
+  }
+
+  p->priv->pt = pt;
+  p->priv->len = len;
+  p->area = area;
+  p->sign = sign;
+
+  return p;
+ 
+ error:
+   free(pt);
+   return NULL; 
+}
+
+/* Give a tree structure to the given path list, based on "insideness"
+   testing. I.e., path A is considered "below" path B if it is inside
+   path B. The input pathlist is assumed to be ordered so that "outer"
+   paths occur before "inner" paths. The tree structure is stored in
+   the "childlist" and "sibling" components of the path_t
+   structure. The linked list structure is also changed so that
+   negative path components are listed immediately after their
+   positive parent.  Note: some backends may ignore the tree
+   structure, others may use it e.g. to group path components. We
+   assume that in the input, point 0 of each path is an "upper left"
+   corner of the path, as returned by bm_to_pathlist. This makes it
+   easy to find an "interior" point. The bm argument should be a
+   bitmap of the correct size (large enough to hold all the paths),
+   and will be used as scratch space. Return 0 on success or -1 on
+   error with errno set. */
+
+static void pathlist_to_tree(path_t *plist, potrace_bitmap_t *bm) {
+  path_t *p, *p1;
+  path_t *heap, *heap1;
+  path_t *cur;
+  path_t *head;
+  path_t **hook, **hook_in, **hook_out; /* for fast appending to linked list */
+  bbox_t bbox;
+  
+  bm_clear(bm, 0);
+
+  /* save original "next" pointers */
+  list_forall(p, plist) {
+    p->sibling = p->next;
+    p->childlist = NULL;
+  }
+  
+  heap = plist;
+
+  /* the heap holds a list of lists of paths. Use "childlist" field
+     for outer list, "next" field for inner list. Each of the sublists
+     is to be turned into a tree. This code is messy, but it is
+     actually fast. Each path is rendered exactly once. We use the
+     heap to get a tail recursive algorithm: the heap holds a list of
+     pathlists which still need to be transformed. */
+
+  while (heap) {
+    /* unlink first sublist */
+    cur = heap;
+    heap = heap->childlist;
+    cur->childlist = NULL;
+  
+    /* unlink first path */
+    head = cur;
+    cur = cur->next;
+    head->next = NULL;
+
+    /* render path */
+    xor_path(bm, head);
+    setbbox_path(&bbox, head);
+
+    /* now do insideness test for each element of cur; append it to
+       head->childlist if it's inside head, else append it to
+       head->next. */
+    hook_in=&head->childlist;
+    hook_out=&head->next;
+    list_forall_unlink(p, cur) {
+      if (p->priv->pt[0].y <= bbox.y0) {
+	list_insert_beforehook(p, hook_out);
+	/* append the remainder of the list to hook_out */
+	*hook_out = cur;
+	break;
+      }
+      if (BM_GET(bm, p->priv->pt[0].x, p->priv->pt[0].y-1)) {
+	list_insert_beforehook(p, hook_in);
+      } else {
+	list_insert_beforehook(p, hook_out);
+      }
+    }
+
+    /* clear bm */
+    clear_bm_with_bbox(bm, &bbox);
+
+    /* now schedule head->childlist and head->next for further
+       processing */
+    if (head->next) {
+      head->next->childlist = heap;
+      heap = head->next;
+    }
+    if (head->childlist) {
+      head->childlist->childlist = heap;
+      heap = head->childlist;
+    }
+  }
+  
+  /* copy sibling structure from "next" to "sibling" component */
+  p = plist;
+  while (p) {
+    p1 = p->sibling;
+    p->sibling = p->next;
+    p = p1;
+  }
+
+  /* reconstruct a new linked list ("next") structure from tree
+     ("childlist", "sibling") structure. This code is slightly messy,
+     because we use a heap to make it tail recursive: the heap
+     contains a list of childlists which still need to be
+     processed. */
+  heap = plist;
+  if (heap) {
+    heap->next = NULL;  /* heap is a linked list of childlists */
+  }
+  plist = NULL;
+  hook = &plist;
+  while (heap) {
+    heap1 = heap->next;
+    for (p=heap; p; p=p->sibling) {
+      /* p is a positive path */
+      /* append to linked list */
+      list_insert_beforehook(p, hook);
+      
+      /* go through its children */
+      for (p1=p->childlist; p1; p1=p1->sibling) {
+	/* append to linked list */
+	list_insert_beforehook(p1, hook);
+	/* append its childlist to heap, if non-empty */
+	if (p1->childlist) {
+	  list_append(path_t, heap1, p1->childlist);
+	}
+      }
+    }
+    heap = heap1;
+  }
+
+  return;
+}
+
+/* find the next set pixel in a row <= y. Pixels are searched first
+   left-to-right, then top-down. In other words, (x,y)<(x',y') if y>y'
+   or y=y' and x<x'. If found, return 0 and store pixel in
+   (*xp,*yp). Else return 1. Note that this function assumes that
+   excess bytes have been cleared with bm_clearexcess. */
+static int findnext(potrace_bitmap_t *bm, int *xp, int *yp) {
+  int x;
+  int y;
+
+  for (y=*yp; y>=0; y--) {
+    for (x=0; x<bm->w; x+=BM_WORDBITS) {
+      if (*bm_index(bm, x, y)) {
+	while (!BM_GET(bm, x, y)) {
+	  x++;
+	}
+	/* found */
+	*xp = x;
+	*yp = y;
+	return 0;
+      }
+    }
+  }
+  /* not found */
+  return 1;
+}
+
+/* Decompose the given bitmap into paths. Returns a linked list of
+   path_t objects with the fields len, pt, area, sign filled
+   in. Returns 0 on success with plistp set, or -1 on error with errno
+   set. */
+
+int bm_to_pathlist(const potrace_bitmap_t *bm, path_t **plistp, const potrace_param_t *param) {
+  int x;
+  int y;
+  path_t *p;
+  path_t *plist = NULL;  /* linked list of path objects */
+  path_t **hook = &plist;  /* used to speed up appending to linked list */
+  potrace_bitmap_t *bm1 = NULL;
+  int sign;
+
+  bm1 = bm_dup(bm);
+  if (!bm1) {
+    goto error;
+  }
+
+  /* be sure the byte padding on the right is set to 0, as the fast
+     pixel search below relies on it */
+  bm_clearexcess(bm1);
+
+  /* iterate through components */
+  y = bm1->h - 1;
+  while (findnext(bm1, &x, &y) == 0) { 
+    /* calculate the sign by looking at the original */
+    sign = BM_GET(bm, x, y) ? '+' : '-';
+
+    /* calculate the path */
+    p = findpath(bm1, x, y+1, sign, param->turnpolicy);
+    if (p==NULL) {
+      goto error;
+    }
+
+    /* update buffered image */
+    xor_path(bm1, p);
+
+    /* if it's a turd, eliminate it, else append it to the list */
+    if (p->area <= param->turdsize) {
+      path_free(p);
+    } else {
+      list_insert_beforehook(p, hook);
+    }
+
+    if (bm1->h > 0) { /* to be sure */
+      //progress_update(1-y/(double)bm1->h, progress);
+    }
+  }
+
+  pathlist_to_tree(plist, bm1);
+  bm_free(bm1);
+  *plistp = plist;
+
+//  progress_update(1.0, progress);
+
+  return 0;
+
+ error:
+  bm_free(bm1);
+  list_forall_unlink(p, plist) {
+    path_free(p);
+  }
+  return -1;
+}
diff --git a/src/hid/gcode/decompose.h b/src/hid/gcode/decompose.h
new file mode 100644
index 0000000..d5be99c
--- /dev/null
+++ b/src/hid/gcode/decompose.h
@@ -0,0 +1,16 @@
+/* Copyright (C) 2001-2007 Peter Selinger.
+   This file is part of Potrace. It is free software and it is covered
+   by the GNU General Public License. See the file COPYING for details. */
+
+/* $Id: decompose.h 147 2007-04-09 00:44:09Z selinger $ */
+
+#ifndef DECOMPOSE_H
+#define DECOMPOSE_H
+
+#include "potracelib.h"
+//#include "progress.h"
+
+int bm_to_pathlist(const potrace_bitmap_t *bm, path_t **plistp, const potrace_param_t *param);
+
+#endif /* DECOMPOSE_H */
+
diff --git a/src/hid/gcode/gcode.c b/src/hid/gcode/gcode.c
new file mode 100644
index 0000000..5792d0c
--- /dev/null
+++ b/src/hid/gcode/gcode.c
@@ -0,0 +1,988 @@
+/*
+ *                            COPYRIGHT
+ *
+ *  PCB, interactive printed circuit board design
+ *
+ *  GCODE export HID
+ *  Copyright (C) 2010 Alberto Maccioni
+ *  this code is based on the NELMA export HID, the PNG export HID,
+ *  and potrace, a tracing program by Peter Selinger
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+ * This HID exports a PCB layout into: 
+ * one layer mask file (PNG format) per copper layer,
+ * one G-CODE CNC drill file.
+ * one G-CODE CNC file per copper layer.
+ * The latter is used by a CNC milling machine to mill the pcb.  
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include <time.h>
+
+#include "global.h"
+#include "data.h"
+#include "misc.h"
+#include "rats.h"
+
+#include "hid.h"
+#include "../hidint.h"
+#include <gd.h>
+#include "hid/common/draw_helpers.h"
+#include "gcode.h"
+#include "bitmap.h"
+#include "curve.h"
+#include "potracelib.h"
+#include "trace.h"
+#include "decompose.h"
+
+#ifdef HAVE_LIBDMALLOC
+#include <dmalloc.h>
+#endif
+
+RCSID("$Id: gcode.c, v 0.1 2010/2/8 14:00:00 Alberto Maccioni Exp $");
+
+#define CRASH fprintf(stderr, "HID error: pcb called unimplemented GCODE function %s.\n", __FUNCTION__); abort()
+#define pcb_unit 100000.0 //pcb internal units per inch
+struct color_struct {
+	/* the descriptor used by the gd library */
+	int             c;
+
+	/* so I can figure out what rgb value c refers to */
+	unsigned int    r, g, b;
+};
+
+struct hid_gc_struct {
+	HID            *me_pointer;
+	EndCapStyle     cap;
+	int             width;
+	unsigned char   r, g, b;
+	int             erase;
+	int             faded;
+	struct color_struct *color;
+	gdImagePtr      brush;
+};
+
+static struct color_struct *black = NULL, *white = NULL;
+static int      linewidth = -1;
+static int      lastgroup = -1;
+static gdImagePtr lastbrush = (void *) -1;
+static int      lastcap = -1;
+static int      lastcolor = -1;
+
+/* gd image and file for PNG export */
+static gdImagePtr gcode_im = NULL;
+static FILE    *gcode_f = NULL,*gcode_f2 = NULL;
+
+static int      is_mask;
+static int      is_drill;
+static int      is_solder;
+
+/*
+ * Which groups of layers to export into PNG layer masks. 1 means export, 0
+ * means do not export.
+ */
+static int      gcode_export_group[MAX_LAYER];
+
+/* Group that is currently exported. */
+static int      gcode_cur_group;
+
+/* Filename prefix that will be used when saving files. */
+static char    *gcode_basename = NULL;
+
+/* Horizontal DPI (grid points per inch) */
+static int      gcode_dpi = -1;
+
+static double	gcode_cutdepth = 0; 	//milling depth (inch)
+static double	gcode_drilldepth = 0; 	//drilling depth (inch)
+static double	gcode_safeZ = 100; 		//safe Z (inch)
+static double	gcode_toolradius = 0; 	//tool radius(inch)
+static int      save_drill=0;
+static int      n_drill=0;
+static int      nmax_drill=0;
+struct drill_struct {
+	double x;
+	double y;
+};
+
+static struct drill_struct *drill=0;
+
+static const char *units[] = {
+	"mm",
+	"mil",
+	"um",
+	"inch",
+	NULL
+};
+
+HID_Attribute   gcode_attribute_list[] = {
+	/* other HIDs expect this to be first.  */
+	{"basename", "File name prefix",
+	HID_String, 0, 0, {0, 0, 0}, 0, 0},
+#define HA_basename 0
+
+	{"dpi", "Resolution of intermediate image (pixels/inch).",
+	HID_Integer, 0, 2000, {600, 0, 0}, 0, 0},
+#define HA_dpi 1
+	
+	{"mill depth", "Milling depth.",
+	HID_Real, -1000, 1000, {0, 0, -0.05}, 0, 0},
+#define HA_cutdepth 2
+	
+	{"safe Z", "Safe Z for traverse move.",
+	HID_Real, -1000, 10000, {0, 0, 2}, 0, 0},
+#define HA_safeZ 3
+	
+	{"tool radius", "Milling tool radius compensation.",
+	HID_Real, 0, 10000, {0, 0, 0.1}, 0, 0},
+#define HA_toolradius 4
+
+	{"drill depth", "Drilling depth.",
+	HID_Real, -10000, 10000, {0, 0, -2}, 0, 0},
+#define HA_drilldepth 5
+		
+	{"measurement unit", "Measurement unit",
+	HID_Enum, 0, 0, {0, 0, 0}, units, 0},
+#define HA_unit 6
+
+};
+
+#define NUM_OPTIONS (sizeof(gcode_attribute_list)/sizeof(gcode_attribute_list[0]))
+
+REGISTER_ATTRIBUTES(gcode_attribute_list)
+	static HID_Attr_Val gcode_values[NUM_OPTIONS];
+
+/* *** Utility funcions **************************************************** */
+
+/* convert from default PCB units (1/100 mil) to gcode units */
+	static int      pcb_to_gcode(int pcb)
+{
+	int             gcode;
+
+	gcode = (pcb * gcode_dpi) / pcb_unit; //100000;
+
+	return gcode;
+}
+
+static char    *
+gcode_get_png_name(const char *basename, const char *suffix)
+{
+	char           *buf;
+	int             len;
+
+	len = strlen(basename) + strlen(suffix) + 6;
+	buf = malloc(sizeof(*buf) * len);
+
+	sprintf(buf, "%s.%s.png", basename, suffix);
+
+	return buf;
+}
+
+//Sorts drills in order of distance from the origin
+struct drill_struct* sort_drill(struct drill_struct *drill,int n_drill){
+	int i,j,imin;
+	double dmin,d;
+	struct drill_struct p={0,0};
+	struct drill_struct* temp=malloc(n_drill*sizeof(struct drill_struct));
+	for(j=0;j<n_drill;j++){
+		dmin=1e20;
+		for(i=0;i<n_drill-j;i++){
+			d=(drill[i].x-p.x)*(drill[i].x-p.x)+(drill[i].y-p.y)*(drill[i].y-p.y);
+			if(d<dmin){
+				imin=i;
+				dmin=d;
+			}
+		}
+		//printf("j=%d imin=%d dmin=%f p=(%f,%f)\n",j,imin,dmin,p.x,p.y);
+		temp[j]=drill[imin];
+		drill[imin]=drill[n_drill-j-1];
+		p=temp[j];
+	}
+	free(drill);
+	return temp;
+}
+
+/* *** Main export callback ************************************************ */
+
+extern void     hid_parse_command_line(int *argc, char ***argv);
+
+static void 
+gcode_parse_arguments(int *argc, char ***argv)
+{
+	hid_register_attributes(gcode_attribute_list,
+				sizeof(gcode_attribute_list) /
+				sizeof(gcode_attribute_list[0]));
+	hid_parse_command_line(argc, argv);
+}
+
+static HID_Attribute *
+gcode_get_export_options(int *n)
+{
+	static char    *last_made_filename = 0;
+
+	if (PCB) {
+		derive_default_filename(PCB->Filename,
+					&gcode_attribute_list[HA_basename],
+					".gcode",
+					&last_made_filename);
+	}
+	if (n) {
+		*n = NUM_OPTIONS;
+	}
+	return gcode_attribute_list;
+}
+
+/* Populates gcode_export_group array */
+void 
+gcode_choose_groups()
+{
+	int             n, m;
+	LayerType      *layer;
+
+	/* Set entire array to 0 (don't export any layer groups by default */
+	memset(gcode_export_group, 0, sizeof(gcode_export_group));
+
+	for (n = 0; n < max_layer; n++) {
+		layer = &PCB->Data->Layer[n];
+
+		if (layer->LineN || layer->TextN || layer->ArcN ||
+		    layer->PolygonN) {
+			/* layer isn't empty */
+
+			/*
+			 * is this check necessary? It seems that special
+			 * layers have negative indexes?
+			 */
+
+			if (SL_TYPE(n) == 0) {
+				/* layer is a copper layer */
+				m = GetLayerGroupNumberByNumber(n);
+
+				/* the export layer */
+				gcode_export_group[m] = 1;
+			}
+		}
+	}
+}
+
+static void 
+gcode_alloc_colors()
+{
+	/*
+	 * Allocate white and black -- the first color allocated becomes the
+	 * background color
+	 */
+
+	white = (struct color_struct *) malloc(sizeof(*white));
+	white->r = white->g = white->b = 255;
+	white->c = gdImageColorAllocate(gcode_im, white->r, white->g, white->b);
+
+	black = (struct color_struct *) malloc(sizeof(*black));
+	black->r = black->g = black->b = 0;
+	black->c = gdImageColorAllocate(gcode_im, black->r, black->g, black->b);
+}
+
+static void 
+gcode_start_png(const char *basename, const char *suffix)
+{
+	int             h, w;
+	char           *buf;
+
+	buf = gcode_get_png_name(basename, suffix);
+
+	h = pcb_to_gcode(PCB->MaxHeight);
+	w = pcb_to_gcode(PCB->MaxWidth);
+
+	/* Nelma only works with true color images */
+	gcode_im = gdImageCreate(w, h);
+	gcode_f = fopen(buf, "wb");
+
+	gcode_alloc_colors();
+
+	free(buf);
+}
+
+static void 
+gcode_finish_png()
+{
+#ifdef HAVE_GDIMAGEPNG
+	gdImagePng(gcode_im, gcode_f);
+#else
+	Message("GCODE: PNG not supported by gd. Can't write layer mask.\n");
+#endif
+	gdImageDestroy(gcode_im);
+	fclose(gcode_f);
+
+	free(white);
+	free(black);
+
+	gcode_im = NULL;
+	gcode_f = NULL;
+}
+
+void 
+gcode_start_png_export()
+{
+	BoxType         region;
+
+	region.X1 = 0;
+	region.Y1 = 0;
+	region.X2 = PCB->MaxWidth;
+	region.Y2 = PCB->MaxHeight;
+
+	linewidth = -1;
+	lastbrush = (void *) -1;
+	lastcap = -1;
+	lastgroup = -1;
+	lastcolor = -1;
+	lastgroup = -1;
+
+	hid_expose_callback(&gcode_hid, &region, 0);
+}
+
+static void 
+gcode_do_export(HID_Attr_Val * options)
+{
+	int             save_ons[MAX_LAYER + 2];
+	int             i, idx;
+	time_t          t;
+	double scale=0,d=0,Bx,By;
+	int r,c,v,p,metric;
+	char* filename;
+	path_t *plist = NULL;
+	potrace_bitmap_t *bm = NULL;
+	potrace_param_t param_default = {
+	  2,                             // turdsize
+	  POTRACE_TURNPOLICY_MINORITY,   // turnpolicy 
+	  1.0,                           // alphamax 
+	  1,                             // opticurve 
+	  0.2,                           // opttolerance 
+	  {
+	    NULL,                        // callback function 
+	    NULL,                        // callback data 
+	    0.0, 1.0,                    // progress range 
+	    0.0,                         // granularity 
+	  },
+	};
+
+	Bx=PCB->MaxWidth/pcb_unit;
+	By=PCB->MaxHeight/pcb_unit;
+	if (!options) {
+		gcode_get_export_options(0);
+		for (i = 0; i < NUM_OPTIONS; i++) {
+			gcode_values[i] = gcode_attribute_list[i].default_val;
+		}
+		options = gcode_values;
+	}
+	gcode_basename = options[HA_basename].str_value;
+	if (!gcode_basename) {
+		gcode_basename = "pcb-out";
+	}
+	gcode_dpi = options[HA_dpi].int_value;
+	if (gcode_dpi < 0) {
+		fprintf(stderr, "ERROR:  dpi may not be < 0\n");
+		return;
+	}
+	switch(options[HA_unit].int_value){
+		case 0:
+			scale=1.0;			//mm
+			metric=1;
+			break;
+		case 1:
+			scale=0.001;		//mil
+			metric=0;
+			break;
+		case 2:
+			scale=0.001;		//um
+			metric=1;
+			break;
+		default:
+			scale=1.0;			//inch
+			metric=0;
+	}
+	gcode_cutdepth = options[HA_cutdepth].real_value*scale;
+	gcode_drilldepth = options[HA_drilldepth].real_value*scale;
+	gcode_safeZ = options[HA_safeZ].real_value*scale;
+	gcode_toolradius = options[HA_toolradius].real_value*scale*pcb_unit; //in PCB units (1/100 mil)
+	if(metric) gcode_toolradius*=1/25.4;
+	gcode_choose_groups();
+
+	for (i = 0; i < MAX_LAYER; i++) {
+		if (gcode_export_group[i]) {
+
+			gcode_cur_group = i;
+
+			/* magic */
+			idx = (i >= 0 && i < max_layer) ?
+				PCB->LayerGroups.Entries[i][0] : i;
+			printf("idx=%d %s\n",idx,layer_type_to_file_name(idx));
+			is_solder=(GetLayerGroupNumberByNumber(idx)==GetLayerGroupNumberByNumber(max_layer+SOLDER_LAYER))?1:0;
+			save_drill=is_solder; //save drills for one layer only
+			gcode_start_png(gcode_basename,layer_type_to_file_name(idx));
+			hid_save_and_show_layer_ons(save_ons);
+			gcode_start_png_export();
+			hid_restore_layer_ons(save_ons);
+
+//***************** gcode conversion ***************************
+// potrace uses a different kind of bitmap; for simplicity gcode_im is copied to this format
+			bm = bm_new(gdImageSX(gcode_im),gdImageSY(gcode_im));
+			filename=malloc(512);
+			plist = NULL;
+			if(is_solder){			//only for back layer
+				gdImagePtr temp_im=gdImageCreate(gdImageSX(gcode_im), gdImageSY(gcode_im));
+				gdImageCopy(temp_im,gcode_im,0,0,0,0,gdImageSX(gcode_im),gdImageSY(gcode_im));
+				for(r=0;r<gdImageSX(gcode_im);r++){
+					for(c=0;c<gdImageSY(gcode_im);c++){
+						gdImageSetPixel(gcode_im,r,c,gdImageGetPixel(temp_im,gdImageSX(gcode_im)-1-r,c));
+					}
+				}
+				gdImageDestroy(temp_im);
+			}
+			sprintf(filename,"%s.%s.cnc",gcode_basename,layer_type_to_file_name(idx));
+			for(r=0;r<gdImageSX(gcode_im);r++){
+				for(c=0;c<gdImageSY(gcode_im);c++){
+					v=gdImageGetPixel(gcode_im,r,gdImageSY(gcode_im)-1-c);
+					p=(gcode_im->red[v]||gcode_im->green[v]||gcode_im->blue[v])?0:0xFFFFFF;
+					BM_PUT(bm, r, c, p);
+				}
+			}
+			gcode_f2 = fopen (filename, "wb");
+			if (!gcode_f2)
+			{
+			  perror (filename);
+			  return;
+			}
+			fprintf(gcode_f2,"(Created by G-code exporter)\n");
+			t = time(NULL);
+			sprintf(filename,"%s", ctime(&t));
+			filename[strlen(filename)-1]=0;
+			fprintf(gcode_f2,"( %s )\n", filename);
+			fprintf(gcode_f2,"(%d dpi)\n",gcode_dpi);
+			fprintf(gcode_f2,"(Unit: %s)\n",metric?"mm":"inch");
+			if(metric) fprintf(gcode_f2,"(Board size: %.2fx%.2f mm)\n",Bx*25.4,By*25.4);
+			else fprintf(gcode_f2,"(Board size: %.2fx%.2f inches)\n",Bx,By);
+			fprintf(gcode_f2,"#100=%f  (safe Z)\n",gcode_safeZ);
+			fprintf(gcode_f2,"#101=%f  (cutting depth)\n",gcode_cutdepth);
+			fprintf(gcode_f2,"(---------------------------------)\n");
+			fprintf(gcode_f2,"G17 G%d G90 G64 P0.003 M3 S3000 M7 F%d\n",metric?21:20,metric?25:1);
+			fprintf(gcode_f2,"G0 Z#100\n");
+			//extract contour points from image
+			r = bm_to_pathlist(bm, &plist, &param_default);
+			if (r) {
+				fprintf(stderr, "ERROR: pathlist function failed\n");
+				return;
+			}
+			//generate best polygon and write vertices in g-code format
+			d=process_path(plist,&param_default,bm,gcode_f2,metric?25.4/gcode_dpi:1.0/gcode_dpi); 
+			if (d<0) {
+				fprintf(stderr, "ERROR: path process function failed\n");
+				return;
+			}
+			if(metric) fprintf(gcode_f2,"(end, total distance %.2fmm = %.2fin)\n",d,d*1/25.4);
+			else fprintf(gcode_f2,"(end, total distance %.2fmm = %.2fin)\n",25.4*d,d);
+			fprintf(gcode_f2,"M5 M9 M2\n");
+			pathlist_free(plist);
+			bm_free(bm);
+			fclose (gcode_f2);
+			if(save_drill){
+				d=0;
+				drill=sort_drill(drill,n_drill);
+				sprintf(filename,"%s.drill.cnc",gcode_basename);
+				gcode_f2 = fopen (filename, "wb");
+				if (!gcode_f2)
+				{
+				  perror (filename);
+				  return;
+				}
+				fprintf(gcode_f2,"(Created by G-code exporter)\n");
+				fprintf(gcode_f2,"(drill file: %d drills)\n",n_drill);
+				sprintf(filename,"%s", ctime(&t));
+				filename[strlen(filename)-1]=0;
+				fprintf(gcode_f2,"( %s )\n", filename);
+				fprintf(gcode_f2,"(Unit: %s)\n",metric?"mm":"inch");
+				if(metric) fprintf(gcode_f2,"(Board size: %.2fx%.2f mm)\n",Bx*25.4,By*25.4);
+				else fprintf(gcode_f2,"(Board size: %.2fx%.2f inches)\n",Bx,By);
+				fprintf(gcode_f2,"#100=%f  (safe Z)\n",gcode_safeZ);
+				fprintf(gcode_f2,"#101=%f  (drill depth)\n",gcode_drilldepth);
+				fprintf(gcode_f2,"(---------------------------------)\n");
+				fprintf(gcode_f2,"G17 G%d G90 G64 P0.003 M3 S3000 M7 F%d\n",metric?21:20,metric?25:1);
+//				fprintf(gcode_f2,"G0 Z#100\n");
+				for(r=0;r<n_drill;r++){
+//					if(metric) fprintf(gcode_f2,"G0 X%f Y%f\n",drill[r].x*25.4,drill[r].y*25.4);
+//					else fprintf(gcode_f2,"G0 X%f Y%f\n",drill[r].x,drill[r].y);
+					if(metric) fprintf(gcode_f2,"G81 X%f Y%f Z#101 R#100\n",drill[r].x*25.4,drill[r].y*25.4);
+					else fprintf(gcode_f2,"G81 X%f Y%f Z#101 R#100\n",drill[r].x,drill[r].y);
+//					fprintf(gcode_f2,"G1 Z#101\n");
+//					fprintf(gcode_f2,"G0 Z#100\n");
+					if(r>0) d+=sqrt((drill[r].x-drill[r-1].x)*(drill[r].x-drill[r-1].x)+\
+									(drill[r].y-drill[r-1].y)*(drill[r].y-drill[r-1].y));
+				}
+				fprintf(gcode_f2,"M5 M9 M2\n");
+				fprintf(gcode_f2,"(end, total distance %.2fmm = %.2fin)\n",25.4*d,d);
+				fclose (gcode_f2);
+				free(drill);
+				drill=NULL;
+				n_drill=nmax_drill=0;
+			}
+			free(filename);
+			system("unix2dos *.cnc");
+//******************* end gcode conversion ****************************
+			gcode_finish_png();
+		}
+	}
+}
+
+/* *** PNG export (slightly modified code from PNG export HID) ************* */
+
+static int 
+gcode_set_layer(const char *name, int group)
+{
+	int             idx = (group >= 0 && group < max_layer) ?
+	PCB->LayerGroups.Entries[group][0] : group;
+
+	if (name == 0) {
+		name = PCB->Data->Layer[idx].Name;
+	}
+	if (strcmp(name, "invisible") == 0) {
+		return 0;
+	}
+	is_drill = (SL_TYPE(idx) == SL_PDRILL || SL_TYPE(idx) == SL_UDRILL);
+	is_mask = (SL_TYPE(idx) == SL_MASK);
+
+	if (is_mask) {
+		/* Don't print masks */
+		return 0;
+	}
+	if (is_drill) {
+		/*
+		 * Print 'holes', so that we can fill gaps in the copper
+		 * layer
+		 */
+		return 1;
+	}
+	if (group == gcode_cur_group) {
+		return 1;
+	}
+	return 0;
+}
+
+static hidGC 
+gcode_make_gc(void)
+{
+	hidGC           rv = (hidGC) malloc(sizeof(struct hid_gc_struct));
+	rv->me_pointer = &gcode_hid;
+	rv->cap = Trace_Cap;
+	rv->width = 1;
+	rv->color = (struct color_struct *) malloc(sizeof(*rv->color));
+	rv->color->r = rv->color->g = rv->color->b = 0;
+	rv->color->c = 0;
+	return rv;
+}
+
+static void 
+gcode_destroy_gc(hidGC gc)
+{
+	free(gc);
+}
+
+static void 
+gcode_use_mask(int use_it)
+{
+	/* does nothing */
+}
+
+static void 
+gcode_set_color(hidGC gc, const char *name)
+{
+	if (gcode_im == NULL) {
+		return;
+	}
+	if (name == NULL) {
+		name = "#ff0000";
+	}
+	if (!strcmp(name, "drill")) {
+		gc->color = black;
+		gc->erase = 0;
+		return;
+	}
+	if (!strcmp(name, "erase")) {
+		/* FIXME -- should be background, not white */
+		gc->color = white;
+		gc->erase = 1;
+		return;
+	}
+	gc->color = black;
+	gc->erase = 0;
+	return;
+}
+
+static void
+gcode_set_line_cap(hidGC gc, EndCapStyle style)
+{
+	gc->cap = style;
+}
+
+static void
+gcode_set_line_width(hidGC gc, int width)
+{
+	gc->width = width;
+}
+
+static void
+gcode_set_draw_xor(hidGC gc, int xor)
+{
+	;
+}
+
+static void
+gcode_set_draw_faded(hidGC gc, int faded)
+{
+	gc->faded = faded;
+}
+
+static void
+gcode_set_line_cap_angle(hidGC gc, int x1, int y1, int x2, int y2)
+{
+	CRASH;
+}
+
+static void
+use_gc(hidGC gc)
+{
+	int             need_brush = 0;
+
+	if (gc->me_pointer != &gcode_hid) {
+		fprintf(stderr, "Fatal: GC from another HID passed to gcode HID\n");
+		abort();
+	}
+	if (linewidth != gc->width) {
+		/* Make sure the scaling doesn't erase lines completely */
+		/*
+	        if (SCALE (gc->width) == 0 && gc->width > 0)
+		  gdImageSetThickness (im, 1);
+	        else
+	        */
+		gdImageSetThickness(gcode_im, pcb_to_gcode(gc->width + 2*gcode_toolradius));
+		linewidth = gc->width;
+		need_brush = 1;
+	}
+	if (lastbrush != gc->brush || need_brush) {
+		static void    *bcache = 0;
+		hidval          bval;
+		char            name[256];
+		char            type;
+		int             r;
+
+		switch (gc->cap) {
+		case Round_Cap:
+		case Trace_Cap:
+			type = 'C';
+			r = pcb_to_gcode(gc->width / 2 + gcode_toolradius);
+			break;
+		default:
+		case Square_Cap:
+			r = pcb_to_gcode(gc->width+gcode_toolradius*2);
+			type = 'S';
+			break;
+		}
+		sprintf(name, "#%.2x%.2x%.2x_%c_%d", gc->color->r, gc->color->g,
+			gc->color->b, type, r);
+
+		if (hid_cache_color(0, name, &bval, &bcache)) {
+			gc->brush = bval.ptr;
+		} else {
+			int             bg, fg;
+			if (type == 'C')
+				gc->brush = gdImageCreate(2 * r + 1, 2 * r + 1);
+			else
+				gc->brush = gdImageCreate(r + 1, r + 1);
+			bg = gdImageColorAllocate(gc->brush, 255, 255, 255);
+			fg =
+				gdImageColorAllocate(gc->brush, gc->color->r, gc->color->g,
+						     gc->color->b);
+			gdImageColorTransparent(gc->brush, bg);
+
+			/*
+		         * if we shrunk to a radius/box width of zero, then just use
+		         * a single pixel to draw with.
+		         */
+			if (r == 0)
+				gdImageFilledRectangle(gc->brush, 0, 0, 0, 0, fg);
+			else {
+				if (type == 'C')
+					gdImageFilledEllipse(gc->brush, r, r, 2 * r, 2 * r, fg);
+				else
+					gdImageFilledRectangle(gc->brush, 0, 0, r, r, fg);
+			}
+			bval.ptr = gc->brush;
+			hid_cache_color(1, name, &bval, &bcache);
+		}
+
+		gdImageSetBrush(gcode_im, gc->brush);
+		lastbrush = gc->brush;
+
+	}
+#define CBLEND(gc) (((gc->r)<<24)|((gc->g)<<16)|((gc->b)<<8)|(gc->faded))
+	if (lastcolor != CBLEND(gc)) {
+		if (is_drill || is_mask) {
+#ifdef FIXME
+			fprintf(f, "%d gray\n", gc->erase ? 0 : 1);
+#endif
+			lastcolor = 0;
+		} else {
+			double          r, g, b;
+			r = gc->r;
+			g = gc->g;
+			b = gc->b;
+			if (gc->faded) {
+				r = 0.8 * 255 + 0.2 * r;
+				g = 0.8 * 255 + 0.2 * g;
+				b = 0.8 * 255 + 0.2 * b;
+			}
+#ifdef FIXME
+			if (gc->r == gc->g && gc->g == gc->b)
+				fprintf(f, "%g gray\n", r / 255.0);
+			else
+				fprintf(f, "%g %g %g rgb\n", r / 255.0, g / 255.0, b / 255.0);
+#endif
+			lastcolor = CBLEND(gc);
+		}
+	}
+}
+
+static void
+gcode_draw_rect(hidGC gc, int x1, int y1, int x2, int y2)
+{
+	use_gc(gc);
+	gdImageRectangle(gcode_im,
+			 pcb_to_gcode(x1-gcode_toolradius), pcb_to_gcode(y1-gcode_toolradius),
+			 pcb_to_gcode(x2+gcode_toolradius), pcb_to_gcode(y2+gcode_toolradius), gc->color->c);
+//	printf("Rect %d %d %d %d\n",x1,y1,x2,y2);
+}
+
+static void
+gcode_fill_rect(hidGC gc, int x1, int y1, int x2, int y2)
+{
+	use_gc(gc);
+	gdImageSetThickness(gcode_im, 0);
+	linewidth = 0;
+	gdImageFilledRectangle(gcode_im, 
+			  pcb_to_gcode(x1-gcode_toolradius), pcb_to_gcode(y1-gcode_toolradius),
+			  pcb_to_gcode(x2+gcode_toolradius), pcb_to_gcode(y2+gcode_toolradius), gc->color->c);
+//	printf("FillRect %d %d %d %d\n",x1,y1,x2,y2);
+}
+
+static void
+gcode_draw_line(hidGC gc, int x1, int y1, int x2, int y2)
+{
+	if (x1 == x2 && y1 == y2) {
+		int             w = gc->width / 2;
+		gcode_fill_rect(gc, x1 - w, y1 - w, x1 + w, y1 + w);
+		return;
+	}
+	use_gc(gc);
+
+	gdImageSetThickness(gcode_im, 0);
+	linewidth = 0;
+	gdImageLine(gcode_im, pcb_to_gcode(x1), pcb_to_gcode(y1),
+		    pcb_to_gcode(x2), pcb_to_gcode(y2), gdBrushed);
+}
+
+static void
+gcode_draw_arc(hidGC gc, int cx, int cy, int width, int height,
+	       int start_angle, int delta_angle)
+{
+	int             sa, ea;
+
+	/*
+	 * in gdImageArc, 0 degrees is to the right and +90 degrees is down
+	 * in pcb, 0 degrees is to the left and +90 degrees is down
+	 */
+	start_angle = 180 - start_angle;
+	delta_angle = -delta_angle;
+	if (delta_angle > 0) {
+		sa = start_angle;
+		ea = start_angle + delta_angle;
+	} else {
+		sa = start_angle + delta_angle;
+		ea = start_angle;
+	}
+
+	/*
+	 * make sure we start between 0 and 360 otherwise gd does strange
+	 * things
+	 */
+	while (sa < 0) {
+		sa += 360;
+		ea += 360;
+	}
+	while (sa >= 360) {
+		sa -= 360;
+		ea -= 360;
+	}
+
+#if 0
+	printf("draw_arc %d,%d %dx%d %d..%d %d..%d\n",
+	       cx, cy, width, height, start_angle, delta_angle, sa, ea);
+	printf("gdImageArc (%p, %d, %d, %d, %d, %d, %d, %d)\n",
+	       im, SCALE_X(cx), SCALE_Y(cy),
+	       SCALE(width), SCALE(height), sa, ea, gc->color->c);
+#endif
+	use_gc(gc);
+	gdImageSetThickness(gcode_im, 0);
+	linewidth = 0;
+	gdImageArc(gcode_im, pcb_to_gcode(cx), pcb_to_gcode(cy),
+		   pcb_to_gcode(2 * width + gcode_toolradius*2), pcb_to_gcode(2 * height + gcode_toolradius*2), sa, ea, gdBrushed);
+}
+
+static void
+gcode_fill_circle(hidGC gc, int cx, int cy, int radius)
+{
+	use_gc(gc);
+
+	gdImageSetThickness(gcode_im, 0);
+	linewidth = 0;
+	gdImageFilledEllipse(gcode_im, pcb_to_gcode(cx), pcb_to_gcode(cy),
+	  pcb_to_gcode(2 * radius + gcode_toolradius*2), pcb_to_gcode(2 * radius + gcode_toolradius*2), gc->color->c);
+	if(save_drill&&is_drill){
+		if(n_drill==nmax_drill){
+			drill=(struct drill_struct*) realloc(drill,(nmax_drill+100)*sizeof(struct drill_struct));
+			nmax_drill+=100;
+		}
+		drill[n_drill].x=(PCB->MaxWidth-cx)/pcb_unit;	//convert to inch, flip: will drill from bottom side
+		drill[n_drill].y=(PCB->MaxHeight-cy)/pcb_unit;	//PCB reverses y axis
+		n_drill++;
+//		printf("Circle %d %d\n",cx,cy);
+	}
+}
+
+static void
+gcode_fill_polygon(hidGC gc, int n_coords, int *x, int *y)
+{
+	int             i;
+	gdPoint        *points;
+
+	points = (gdPoint *) malloc(n_coords * sizeof(gdPoint));
+	if (points == NULL) {
+		fprintf(stderr, "ERROR:  gcode_fill_polygon():  malloc failed\n");
+		exit(1);
+	}
+	use_gc(gc);
+	for (i = 0; i < n_coords; i++) {
+		points[i].x = pcb_to_gcode(x[i]);
+		points[i].y = pcb_to_gcode(y[i]);
+	}
+	gdImageSetThickness(gcode_im, 0);
+	linewidth = 0;
+	gdImageFilledPolygon(gcode_im, points, n_coords, gc->color->c);
+	free(points);
+//	printf("FillPoly\n");
+}
+
+static void
+gcode_calibrate(double xval, double yval)
+{
+	CRASH;
+}
+
+static void
+gcode_set_crosshair(int x, int y, int a)
+{
+}
+
+/* *** Miscellaneous ******************************************************* */
+
+HID             gcode_hid = {
+	sizeof(HID),
+	"gcode",
+	"G-CODE export.",
+	0,			/* gui */
+	0,			/* printer */
+	1,			/* exporter */
+	1,			/* poly before */
+	0,			/* poly after */
+	0,			/* poly dicer */
+	gcode_get_export_options,
+	gcode_do_export,
+	gcode_parse_arguments,
+	0 /* gcode_invalidate_wh */ ,
+	0 /* gcode_invalidate_lr */ ,
+	0 /* gcode_invalidate_all */ ,
+	gcode_set_layer,
+	gcode_make_gc,
+	gcode_destroy_gc,
+	gcode_use_mask,
+	gcode_set_color,
+	gcode_set_line_cap,
+	gcode_set_line_width,
+	gcode_set_draw_xor,
+	gcode_set_draw_faded,
+	gcode_set_line_cap_angle,
+	gcode_draw_line,
+	gcode_draw_arc,
+	gcode_draw_rect,
+	gcode_fill_circle,
+	gcode_fill_polygon,
+	common_fill_pcb_polygon,
+	0 /* nelma_thindraw_pcb_polygon */ ,
+	gcode_fill_rect,
+	gcode_calibrate,
+	0 /* gcode_shift_is_pressed */ ,
+	0 /* gcode_control_is_pressed */ ,
+	0 /* gcode_mod1_is_pressed */ ,
+	0 /* gcode_get_coords */ ,
+	gcode_set_crosshair,
+	0 /* gcode_add_timer */ ,
+	0 /* gcode_stop_timer */ ,
+	0 /* gcode_watch_file */ ,
+	0 /* gcode_unwatch_file */ ,
+	0 /* gcode_add_block_hook */ ,
+	0 /* gcode_stop_block_hook */ ,
+	0 /* gcode_log */ ,
+	0 /* gcode_logv */ ,
+	0 /* gcode_confirm_dialog */ ,
+	0 /* gcode_close_confirm_dialog */ ,
+	0 /* gcode_report_dialog */ ,
+	0 /* gcode_prompt_for */ ,
+	0 /* gcode_fileselect */ ,
+	0 /* gcode_attribute_dialog */ ,
+	0 /* gcode_show_item */ ,
+	0 /* gcode_beep */ ,
+	0 /* gcode_progress */ ,
+	0 /* gcode_drc_gui */
+};
+
+#include "dolists.h"
+
+void
+hid_gcode_init()
+{
+	apply_default_hid(&gcode_hid, 0);
+	hid_register_hid(&gcode_hid);
+
+#include "gcode_lists.h"
+}
diff --git a/src/hid/gcode/gcode.h b/src/hid/gcode/gcode.h
new file mode 100644
index 0000000..352cbd9
--- /dev/null
+++ b/src/hid/gcode/gcode.h
@@ -0,0 +1,3 @@
+/* $Id: nelma.h,v 1.2 2007/04/20 11:31:15 danmc Exp $ */
+
+extern HID      gcode_hid;
diff --git a/src/hid/gcode/hid.conf b/src/hid/gcode/hid.conf
new file mode 100644
index 0000000..7be6c4c
--- /dev/null
+++ b/src/hid/gcode/hid.conf
@@ -0,0 +1 @@
+type=export
diff --git a/src/hid/gcode/lists.h b/src/hid/gcode/lists.h
new file mode 100644
index 0000000..931cbb0
--- /dev/null
+++ b/src/hid/gcode/lists.h
@@ -0,0 +1,286 @@
+/* Copyright (C) 2001-2007 Peter Selinger.
+   This file is part of Potrace. It is free software and it is covered
+   by the GNU General Public License. See the file COPYING for details. */
+
+/* $Id: lists.h 147 2007-04-09 00:44:09Z selinger $ */
+
+#ifndef _PS_LISTS_H
+#define _PS_LISTS_H
+
+/* here we define some general list macros. Because they are macros,
+   they should work on any datatype with a "->next" component. Some of
+   them use a "hook". If elt and list are of type t* then hook is of
+   type t**. A hook stands for an insertion point in the list, i.e.,
+   either before the first element, or between two elements, or after
+   the last element. If an operation "sets the hook" for an element,
+   then the hook is set to just before the element. One can insert
+   something at a hook. One can also unlink at a hook: this means,
+   unlink the element just after the hook. By "to unlink", we mean the
+   element is removed from the list, but not deleted. Thus, it and its
+   components still need to be freed. */
+
+/* Note: these macros are somewhat experimental. Only the ones that
+   are actually *used* have been tested. So be careful to test any
+   that you use. Looking at the output of the preprocessor, "gcc -E"
+   (possibly piped though "indent"), might help too. Also: these
+   macros define some internal (local) variables that start with
+   "_". */
+
+/* we enclose macro definitions whose body consists of more than one
+   statement in MACRO_BEGIN and MACRO_END, rather than '{' and '}'.  The
+   reason is that we want to be able to use the macro in a context
+   such as "if (...) macro(...); else ...". If we didn't use this obscure
+   trick, we'd have to omit the ";" in such cases. */
+
+#define MACRO_BEGIN do {
+#define MACRO_END   } while (0)
+
+/* ---------------------------------------------------------------------- */
+/* macros for singly-linked lists */
+
+/* traverse list. At the end, elt is set to NULL. */
+#define list_forall(elt, list)   for (elt=list; elt!=NULL; elt=elt->next)
+
+/* set elt to the first element of list satisfying boolean condition
+   c, or NULL if not found */
+#define list_find(elt, list, c) \
+  MACRO_BEGIN list_forall(elt, list) if (c) break; MACRO_END
+
+/* like forall, except also set hook for elt. */
+#define list_forall2(elt, list, hook) \
+  for (elt=list, hook=&list; elt!=NULL; hook=&elt->next, elt=elt->next)
+
+/* same as list_find, except also set hook for elt. */
+#define list_find2(elt, list, c, hook) \
+  MACRO_BEGIN list_forall2(elt, list, hook) if (c) break; MACRO_END
+
+/* same, except only use hook. */
+#define _list_forall_hook(list, hook) \
+  for (hook=&list; *hook!=NULL; hook=&(*hook)->next)
+
+/* same, except only use hook. Note: c may only refer to *hook, not elt. */
+#define _list_find_hook(list, c, hook) \
+  MACRO_BEGIN _list_forall_hook(list, hook) if (c) break; MACRO_END
+
+/* insert element after hook */
+#define list_insert_athook(elt, hook) \
+  MACRO_BEGIN elt->next = *hook; *hook = elt; MACRO_END
+
+/* insert element before hook */
+#define list_insert_beforehook(elt, hook) \
+  MACRO_BEGIN elt->next = *hook; *hook = elt; hook=&elt->next; MACRO_END
+
+/* unlink element after hook, let elt be unlinked element, or NULL.
+   hook remains. */
+#define list_unlink_athook(list, elt, hook) \
+  MACRO_BEGIN \
+  elt = hook ? *hook : NULL; if (elt) { *hook = elt->next; elt->next = NULL; }\
+  MACRO_END
+
+/* unlink the specific element, if it is in the list. Otherwise, set
+   elt to NULL */
+#define list_unlink(listtype, list, elt)      \
+  MACRO_BEGIN  	       	       	       	      \
+  listtype **_hook;			      \
+  _list_find_hook(list, *_hook==elt, _hook);  \
+  list_unlink_athook(list, elt, _hook);	      \
+  MACRO_END
+
+/* prepend elt to list */
+#define list_prepend(list, elt) \
+  MACRO_BEGIN elt->next = list; list = elt; MACRO_END
+
+/* append elt to list. */
+#define list_append(listtype, list, elt)     \
+  MACRO_BEGIN                                \
+  listtype **_hook;                          \
+  _list_forall_hook(list, _hook) {}          \
+  list_insert_athook(elt, _hook);            \
+  MACRO_END
+
+/* unlink the first element that satisfies the condition. */
+#define list_unlink_cond(listtype, list, elt, c)     \
+  MACRO_BEGIN                                        \
+  listtype **_hook;			  	     \
+  list_find2(elt, list, c, _hook);                   \
+  list_unlink_athook(list, elt, _hook);              \
+  MACRO_END
+
+/* let elt be the nth element of the list, starting to count from 0.
+   Return NULL if out of bounds.   */
+#define list_nth(elt, list, n)                                \
+  MACRO_BEGIN                                                 \
+  int _x;  /* only evaluate n once */                         \
+  for (_x=(n), elt=list; _x && elt; _x--, elt=elt->next) {}   \
+  MACRO_END
+
+/* let elt be the nth element of the list, starting to count from 0.
+   Return NULL if out of bounds.   */
+#define list_nth_hook(elt, list, n, hook)                     \
+  MACRO_BEGIN                                                 \
+  int _x;  /* only evaluate n once */                         \
+  for (_x=(n), elt=list, hook=&list; _x && elt; _x--, hook=&elt->next, elt=elt->next) {}   \
+  MACRO_END
+
+/* set n to the length of the list */
+#define list_length(listtype, list, n)                   \
+  MACRO_BEGIN          	       	       	       	       	 \
+  listtype *_elt;   			 		 \
+  n=0;					 		 \
+  list_forall(_elt, list) 		 		 \
+    n++;				 		 \
+  MACRO_END
+
+/* set n to the index of the first element satisfying cond, or -1 if
+   none found. Also set elt to the element, or NULL if none found. */
+#define list_index(list, n, elt, c)                      \
+  MACRO_BEGIN				 		 \
+  n=0;					 		 \
+  list_forall(elt, list) {		 		 \
+    if (c) break;			 		 \
+    n++;				 		 \
+  }					 		 \
+  if (!elt)				 		 \
+    n=-1;				 		 \
+  MACRO_END
+
+/* set n to the number of elements in the list that satisfy condition c */
+#define list_count(list, n, elt, c)                      \
+  MACRO_BEGIN				 		 \
+  n=0;					 		 \
+  list_forall(elt, list) {		 		 \
+    if (c) n++;				 		 \
+  }                                                      \
+  MACRO_END
+
+/* let elt be each element of the list, unlinked. At the end, set list=NULL. */
+#define list_forall_unlink(elt, list) \
+  for (elt=list; elt ? (list=elt->next, elt->next=NULL), 1 : 0; elt=list)
+
+/* reverse a list (efficient) */
+#define list_reverse(listtype, list)            \
+  MACRO_BEGIN				 	\
+  listtype *_list1=NULL, *elt;			\
+  list_forall_unlink(elt, list) 		\
+    list_prepend(_list1, elt);			\
+  list = _list1;				\
+  MACRO_END
+
+/* insert the element ELT just before the first element TMP of the
+   list for which COND holds. Here COND must be a condition of ELT and
+   TMP.  Typical usage is to insert an element into an ordered list:
+   for instance, list_insert_ordered(listtype, list, elt, tmp,
+   elt->size <= tmp->size).  Note: if we give a "less than or equal"
+   condition, the new element will be inserted just before a sequence
+   of equal elements. If we give a "less than" condition, the new
+   element will be inserted just after a list of equal elements.
+   Note: it is much more efficient to construct a list with
+   list_prepend and then order it with list_merge_sort, than to
+   construct it with list_insert_ordered. */
+#define list_insert_ordered(listtype, list, elt, tmp, cond) \
+  MACRO_BEGIN                                               \
+  listtype **_hook;                                         \
+  _list_find_hook(list, (tmp=*_hook, (cond)), _hook);       \
+  list_insert_athook(elt, _hook);                           \
+  MACRO_END
+
+/* sort the given list, according to the comparison condition.
+   Typical usage is list_sort(listtype, list, a, b, a->size <
+   b->size).  Note: if we give "less than or equal" condition, each
+   segment of equal elements will be reversed in order. If we give a
+   "less than" condition, each segment of equal elements will retain
+   the original order. The latter is slower but sometimes
+   prettier. Average running time: n*n/2. */
+#define list_sort(listtype, list, a, b, cond)            \
+  MACRO_BEGIN                                            \
+  listtype *_newlist=NULL;                               \
+  list_forall_unlink(a, list)                            \
+    list_insert_ordered(listtype, _newlist, a, b, cond); \
+  list = _newlist;                                       \
+  MACRO_END
+
+/* a much faster sort algorithm (merge sort, n log n worst case). It
+   is required that the list type has an additional, unused next1
+   component. Note there is no curious reversal of order of equal
+   elements as for list_sort. */
+
+#define list_mergesort(listtype, list, a, b, cond)              \
+  MACRO_BEGIN						        \
+  listtype *_elt, **_hook1;				    	\
+							    	\
+  for (_elt=list; _elt; _elt=_elt->next1) {			\
+    _elt->next1 = _elt->next;				    	\
+    _elt->next = NULL;					    	\
+  }							    	\
+  do {			                               	    	\
+    _hook1 = &(list);				    	    	\
+    while ((a = *_hook1) != NULL && (b = a->next1) != NULL ) {  \
+      _elt = b->next1;					    	\
+      _list_merge_cond(listtype, a, b, cond, *_hook1);      	\
+      _hook1 = &((*_hook1)->next1);			    	\
+      *_hook1 = _elt;				            	\
+    }							    	\
+  } while (_hook1 != &(list));                                 	\
+  MACRO_END
+
+/* merge two sorted lists. Store result at &result */
+#define _list_merge_cond(listtype, a, b, cond, result)   \
+  MACRO_BEGIN                                            \
+  listtype **_hook;					 \
+  _hook = &(result);					 \
+  while (1) {                                            \
+     if (a==NULL) {					 \
+       *_hook = b;					 \
+       break;						 \
+     } else if (b==NULL) {				 \
+       *_hook = a;					 \
+       break;						 \
+     } else if (cond) {					 \
+       *_hook = a;					 \
+       _hook = &(a->next);				 \
+       a = a->next;					 \
+     } else {						 \
+       *_hook = b;					 \
+       _hook = &(b->next);				 \
+       b = b->next;					 \
+     }							 \
+  }							 \
+  MACRO_END
+
+/* ---------------------------------------------------------------------- */
+/* macros for doubly-linked lists */
+
+#define dlist_append(head, end, elt)                    \
+  MACRO_BEGIN  	       	       	       	       	       	 \
+  elt->prev = end;					 \
+  elt->next = NULL;					 \
+  if (end) {						 \
+    end->next = elt;					 \
+  } else {  						 \
+    head = elt;						 \
+  }	    						 \
+  end = elt;						 \
+  MACRO_END
+
+/* let elt be each element of the list, unlinked. At the end, set list=NULL. */
+#define dlist_forall_unlink(elt, head, end) \
+  for (elt=head; elt ? (head=elt->next, elt->next=NULL, elt->prev=NULL), 1 : (end=NULL, 0); elt=head)
+
+/* unlink the first element of the list */
+#define dlist_unlink_first(head, end, elt)               \
+  MACRO_BEGIN				       	       	 \
+  elt = head;						 \
+  if (head) {						 \
+    head = head->next;					 \
+    if (head) {						 \
+      head->prev = NULL;				 \
+    } else {						 \
+      end = NULL;					 \
+    }    						 \
+    elt->prev = NULL;					 \
+    elt->next = NULL;					 \
+  }							 \
+  MACRO_END
+
+#endif /* _PS_LISTS_H */
+
diff --git a/src/hid/gcode/potracelib.h b/src/hid/gcode/potracelib.h
new file mode 100644
index 0000000..0b93d65
--- /dev/null
+++ b/src/hid/gcode/potracelib.h
@@ -0,0 +1,131 @@
+/* Copyright (C) 2001-2007 Peter Selinger.
+   This file is part of Potrace. It is free software and it is covered
+   by the GNU General Public License. See the file COPYING for details. */
+
+#ifndef POTRACELIB_H
+#define POTRACELIB_H
+
+/* this file defines the API for the core Potrace library. For a more
+   detailed description of the API, see doc/potracelib.txt */
+
+/* ---------------------------------------------------------------------- */
+/* tracing parameters */
+
+/* turn policies */
+#define POTRACE_TURNPOLICY_BLACK 0
+#define POTRACE_TURNPOLICY_WHITE 1
+#define POTRACE_TURNPOLICY_LEFT 2
+#define POTRACE_TURNPOLICY_RIGHT 3
+#define POTRACE_TURNPOLICY_MINORITY 4
+#define POTRACE_TURNPOLICY_MAJORITY 5
+#define POTRACE_TURNPOLICY_RANDOM 6
+
+/* structure to hold progress bar callback data */
+struct potrace_progress_s {
+  void (*callback)(double progress, void *privdata); /* callback fn */
+  void *data;          /* callback function's private data */
+  double min, max;     /* desired range of progress, e.g. 0.0 to 1.0 */
+  double epsilon;      /* granularity: can skip smaller increments */
+};
+typedef struct potrace_progress_s potrace_progress_t;
+
+/* structure to hold tracing parameters */
+struct potrace_param_s {
+  int turdsize;        /* area of largest path to be ignored */
+  int turnpolicy;      /* resolves ambiguous turns in path decomposition */
+  double alphamax;     /* corner threshold */
+  int opticurve;       /* use curve optimization? */
+  double opttolerance; /* curve optimization tolerance */
+  potrace_progress_t progress; /* progress callback function */
+};
+typedef struct potrace_param_s potrace_param_t;
+
+/* ---------------------------------------------------------------------- */
+/* bitmaps */
+
+/* native word size */
+typedef unsigned long potrace_word;
+
+/* Internal bitmap format. The n-th scanline starts at scanline(n) =
+   (map + n*dy). Raster data is stored as a sequence of potrace_words
+   (NOT bytes). The leftmost bit of scanline n is the most significant
+   bit of scanline(n)[0]. */
+struct potrace_bitmap_s {
+  int w, h;              /* width and height, in pixels */
+  int dy;                /* words per scanline (not bytes) */
+  potrace_word *map;     /* raw data, dy*h words */
+};
+typedef struct potrace_bitmap_s potrace_bitmap_t;
+
+/* ---------------------------------------------------------------------- */
+/* curves */
+
+/* point */
+struct potrace_dpoint_s {
+  double x, y;
+};
+typedef struct potrace_dpoint_s potrace_dpoint_t;
+
+/* segment tags */
+#define POTRACE_CURVETO 1
+#define POTRACE_CORNER 2
+
+/* closed curve segment */
+struct potrace_curve_s {
+  int n;                    /* number of segments */
+  int *tag;                 /* tag[n]: POTRACE_CURVETO or POTRACE_CORNER */
+  potrace_dpoint_t (*c)[3]; /* c[n][3]: control points. 
+			       c[n][0] is unused for tag[n]=POTRACE_CORNER */
+};
+typedef struct potrace_curve_s potrace_curve_t;
+
+/* Linked list of signed curve segments. Also carries a tree structure. */
+struct potrace_path_s {
+  int area;                         /* area of the bitmap path */
+  int sign;                         /* '+' or '-', depending on orientation */
+  potrace_curve_t curve;            /* this path's vector data */
+
+  struct potrace_path_s *next;      /* linked list structure */
+
+  struct potrace_path_s *childlist; /* tree structure */
+  struct potrace_path_s *sibling;   /* tree structure */
+
+  struct potrace_privpath_s *priv;  /* private state */
+};
+typedef struct potrace_path_s potrace_path_t;  
+
+/* ---------------------------------------------------------------------- */
+/* Potrace state */
+
+#define POTRACE_STATUS_OK         0
+#define POTRACE_STATUS_INCOMPLETE 1
+
+struct potrace_state_s {
+  int status;                       
+  potrace_path_t *plist;            /* vector data */
+
+  struct potrace_privstate_s *priv; /* private state */
+};
+typedef struct potrace_state_s potrace_state_t;
+
+/* ---------------------------------------------------------------------- */
+/* API functions */
+
+/* get default parameters */
+potrace_param_t *potrace_param_default(void);
+
+/* free parameter set */
+void potrace_param_free(potrace_param_t *p);
+
+/* trace a bitmap*/
+potrace_state_t *potrace_trace(const potrace_param_t *param, 
+			       const potrace_bitmap_t *bm);
+
+/* free a Potrace state */
+void potrace_state_free(potrace_state_t *st);
+
+/* return a static plain text version string identifying this version
+   of potracelib */
+char *potrace_version(void);
+
+#endif /* POTRACELIB_H */
diff --git a/src/hid/gcode/trace.c b/src/hid/gcode/trace.c
new file mode 100644
index 0000000..2c615e6
--- /dev/null
+++ b/src/hid/gcode/trace.c
@@ -0,0 +1,1246 @@
+/* This file was slightly modified by Alberto Maccioni to be used with PCB G-CODE exporter*/
+
+/* Copyright (C) 2001-2007 Peter Selinger.
+   This file is part of Potrace. It is free software and it is covered
+   by the GNU General Public License. See the file COPYING for details. */
+
+/* $Id: trace.c 147 2007-04-09 00:44:09Z selinger $ */
+/* transform jaggy paths into smooth curves */
+
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "potracelib.h"
+#include "curve.h"
+#include "lists.h"
+#include "auxiliary.h"
+#include "trace.h"
+//#include "progress.h"
+
+#define INFTY 10000000	/* it suffices that this is longer than any
+			   path; it need not be really infinite */
+#define COS179 -0.999847695156	 /* the cosine of 179 degrees */
+
+/* ---------------------------------------------------------------------- */
+#define SAFE_MALLOC(var, n, typ) \
+  if ((var = (typ *)malloc((n)*sizeof(typ))) == NULL) goto malloc_error 
+
+/* ---------------------------------------------------------------------- */
+/* auxiliary functions */
+
+/* return a direction that is 90 degrees counterclockwise from p2-p0,
+   but then restricted to one of the major wind directions (n, nw, w, etc) */
+static inline point_t dorth_infty(dpoint_t p0, dpoint_t p2) {
+  point_t r;
+  
+  r.y = sign(p2.x-p0.x);
+  r.x = -sign(p2.y-p0.y);
+
+  return r;
+}
+
+/* return (p1-p0)x(p2-p0), the area of the parallelogram */
+static inline double dpara(dpoint_t p0, dpoint_t p1, dpoint_t p2) {
+  double x1, y1, x2, y2;
+
+  x1 = p1.x-p0.x;
+  y1 = p1.y-p0.y;
+  x2 = p2.x-p0.x;
+  y2 = p2.y-p0.y;
+
+  return x1*y2 - x2*y1;
+}
+
+/* ddenom/dpara have the property that the square of radius 1 centered
+   at p1 intersects the line p0p2 iff |dpara(p0,p1,p2)| <= ddenom(p0,p2) */
+static inline double ddenom(dpoint_t p0, dpoint_t p2) {
+  point_t r = dorth_infty(p0, p2);
+
+  return r.y*(p2.x-p0.x) - r.x*(p2.y-p0.y);
+}
+
+/* return 1 if a <= b < c < a, in a cyclic sense (mod n) */
+static inline int cyclic(int a, int b, int c) {
+  if (a<=c) {
+    return (a<=b && b<c);
+  } else {
+    return (a<=b || b<c);
+  }
+}
+
+/* determine the center and slope of the line i..j. Assume i<j. Needs
+   "sum" components of p to be set. */
+static void pointslope(privpath_t *pp, int i, int j, dpoint_t *ctr, dpoint_t *dir) {
+  /* assume i<j */
+
+  int n = pp->len;
+  sums_t *sums = pp->sums;
+
+  double x, y, x2, xy, y2;
+  double k;
+  double a, b, c, lambda2, l;
+  int r=0; /* rotations from i to j */
+
+  while (j>=n) {
+    j-=n;
+    r+=1;
+  }
+  while (i>=n) {
+    i-=n;
+    r-=1;
+  }
+  while (j<0) {
+    j+=n;
+    r-=1;
+  }
+  while (i<0) {
+    i+=n;
+    r+=1;
+  }
+  
+  x = sums[j+1].x-sums[i].x+r*sums[n].x;
+  y = sums[j+1].y-sums[i].y+r*sums[n].y;
+  x2 = sums[j+1].x2-sums[i].x2+r*sums[n].x2;
+  xy = sums[j+1].xy-sums[i].xy+r*sums[n].xy;
+  y2 = sums[j+1].y2-sums[i].y2+r*sums[n].y2;
+  k = j+1-i+r*n;
+  
+  ctr->x = x/k;
+  ctr->y = y/k;
+
+  a = (x2-(double)x*x/k)/k;
+  b = (xy-(double)x*y/k)/k;
+  c = (y2-(double)y*y/k)/k;
+  
+  lambda2 = (a+c+sqrt((a-c)*(a-c)+4*b*b))/2; /* larger e.value */
+
+  /* now find e.vector for lambda2 */
+  a -= lambda2;
+  c -= lambda2;
+
+  if (fabs(a) >= fabs(c)) {
+    l = sqrt(a*a+b*b);
+    if (l!=0) {
+      dir->x = -b/l;
+      dir->y = a/l;
+    }
+  } else {
+    l = sqrt(c*c+b*b);
+    if (l!=0) {
+      dir->x = -c/l;
+      dir->y = b/l;
+    }
+  }
+  if (l==0) {
+    dir->x = dir->y = 0;   /* sometimes this can happen when k=4:
+			      the two eigenvalues coincide */
+  }
+}
+
+/* the type of (affine) quadratic forms, represented as symmetric 3x3
+   matrices.  The value of the quadratic form at a vector (x,y) is v^t
+   Q v, where v = (x,y,1)^t. */
+typedef double quadform_t[3][3];
+
+/* Apply quadratic form Q to vector w = (w.x,w.y) */
+static inline double quadform(quadform_t Q, dpoint_t w) {
+  double v[3];
+  int i, j;
+  double sum;
+
+  v[0] = w.x;
+  v[1] = w.y;
+  v[2] = 1;
+  sum = 0.0;
+
+  for (i=0; i<3; i++) {
+    for (j=0; j<3; j++) {
+      sum += v[i] * Q[i][j] * v[j];
+    }
+  }
+  return sum;
+}
+
+/* calculate p1 x p2 */
+static inline int xprod(point_t p1, point_t p2) {
+  return p1.x*p2.y - p1.y*p2.x;
+}
+
+/* calculate (p1-p0)x(p3-p2) */
+static inline double cprod(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
+  double x1, y1, x2, y2;
+
+  x1 = p1.x - p0.x;
+  y1 = p1.y - p0.y;
+  x2 = p3.x - p2.x;
+  y2 = p3.y - p2.y;
+
+  return x1*y2 - x2*y1;
+}
+
+/* calculate (p1-p0)*(p2-p0) */
+static inline double iprod(dpoint_t p0, dpoint_t p1, dpoint_t p2) {
+  double x1, y1, x2, y2;
+
+  x1 = p1.x - p0.x;
+  y1 = p1.y - p0.y;
+  x2 = p2.x - p0.x;
+  y2 = p2.y - p0.y;
+
+  return x1*x2 + y1*y2;
+}
+
+/* calculate (p1-p0)*(p3-p2) */
+static inline double iprod1(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
+  double x1, y1, x2, y2;
+
+  x1 = p1.x - p0.x;
+  y1 = p1.y - p0.y;
+  x2 = p3.x - p2.x;
+  y2 = p3.y - p2.y;
+
+  return x1*x2 + y1*y2;
+}
+
+/* calculate distance between two points */
+static inline double ddist(dpoint_t p, dpoint_t q) {
+  return sqrt(sq(p.x-q.x)+sq(p.y-q.y));
+}
+
+/* calculate point of a bezier curve */
+static inline dpoint_t bezier(double t, dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3) {
+  double s = 1-t;
+  dpoint_t res;
+
+  /* Note: a good optimizing compiler (such as gcc-3) reduces the
+     following to 16 multiplications, using common subexpression
+     elimination. */
+
+  res.x = s*s*s*p0.x + 3*(s*s*t)*p1.x + 3*(t*t*s)*p2.x + t*t*t*p3.x;
+  res.y = s*s*s*p0.y + 3*(s*s*t)*p1.y + 3*(t*t*s)*p2.y + t*t*t*p3.y;
+
+  return res;
+}
+
+/* calculate the point t in [0..1] on the (convex) bezier curve
+   (p0,p1,p2,p3) which is tangent to q1-q0. Return -1.0 if there is no
+   solution in [0..1]. */
+static double tangent(dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3, dpoint_t q0, dpoint_t q1) {
+  double A, B, C;   /* (1-t)^2 A + 2(1-t)t B + t^2 C = 0 */
+  double a, b, c;   /* a t^2 + b t + c = 0 */
+  double d, s, r1, r2;
+
+  A = cprod(p0, p1, q0, q1);
+  B = cprod(p1, p2, q0, q1);
+  C = cprod(p2, p3, q0, q1);
+
+  a = A - 2*B + C;
+  b = -2*A + 2*B;
+  c = A;
+  
+  d = b*b - 4*a*c;
+
+  if (a==0 || d<0) {
+    return -1.0;
+  }
+
+  s = sqrt(d);
+
+  r1 = (-b + s) / (2 * a);
+  r2 = (-b - s) / (2 * a);
+
+  if (r1 >= 0 && r1 <= 1) {
+    return r1;
+  } else if (r2 >= 0 && r2 <= 1) {
+    return r2;
+  } else {
+    return -1.0;
+  }
+}
+
+/* ---------------------------------------------------------------------- */
+/* Preparation: fill in the sum* fields of a path (used for later
+   rapid summing). Return 0 on success, 1 with errno set on
+   failure. */
+static int calc_sums(privpath_t *pp) {
+  int i, x, y;
+  int n = pp->len;
+
+  SAFE_MALLOC(pp->sums, pp->len+1, sums_t);
+
+  /* origin */
+  pp->x0 = pp->pt[0].x;
+  pp->y0 = pp->pt[0].y;
+
+  /* preparatory computation for later fast summing */
+  pp->sums[0].x2 = pp->sums[0].xy = pp->sums[0].y2 = pp->sums[0].x = pp->sums[0].y = 0;
+  for (i=0; i<n; i++) {
+    x = pp->pt[i].x - pp->x0;
+    y = pp->pt[i].y - pp->y0;
+    pp->sums[i+1].x = pp->sums[i].x + x;
+    pp->sums[i+1].y = pp->sums[i].y + y;
+    pp->sums[i+1].x2 = pp->sums[i].x2 + x*x;
+    pp->sums[i+1].xy = pp->sums[i].xy + x*y;
+    pp->sums[i+1].y2 = pp->sums[i].y2 + y*y;
+  }
+  return 0;  
+
+ malloc_error:
+  return 1;
+}
+
+/* ---------------------------------------------------------------------- */
+/* Stage 1: determine the straight subpaths (Sec. 2.2.1). Fill in the
+   "lon" component of a path object (based on pt/len).	For each i,
+   lon[i] is the furthest index such that a straight line can be drawn
+   from i to lon[i]. Return 1 on error with errno set, else 0. */
+
+/* this algorithm depends on the fact that the existence of straight
+   subpaths is a triplewise property. I.e., there exists a straight
+   line through squares i0,...,in iff there exists a straight line
+   through i,j,k, for all i0<=i<j<k<=in. (Proof?) */
+
+/* this implementation of calc_lon is O(n^2). It replaces an older
+   O(n^3) version. A "constraint" means that future points must
+   satisfy xprod(constraint[0], cur) >= 0 and xprod(constraint[1],
+   cur) <= 0. */
+
+/* Remark for Potrace 1.1: the current implementation of calc_lon is
+   more complex than the implementation found in Potrace 1.0, but it
+   is considerably faster. The introduction of the "nc" data structure
+   means that we only have to test the constraints for "corner"
+   points. On a typical input file, this speeds up the calc_lon
+   function by a factor of 31.2, thereby decreasing its time share
+   within the overall Potrace algorithm from 72.6% to 7.82%, and
+   speeding up the overall algorithm by a factor of 3.36. On another
+   input file, calc_lon was sped up by a factor of 6.7, decreasing its
+   time share from 51.4% to 13.61%, and speeding up the overall
+   algorithm by a factor of 1.78. In any case, the savings are
+   substantial. */
+
+/* returns 0 on success, 1 on error with errno set */
+static int calc_lon(privpath_t *pp) {
+  point_t *pt = pp->pt;
+  int n = pp->len;
+  int i, j, k, k1;
+  int ct[4], dir;
+  point_t constraint[2];
+  point_t cur;
+  point_t off;
+  int *pivk = NULL;  /* pivk[n] */
+  int *nc = NULL;    /* nc[n]: next corner */
+  point_t dk;  /* direction of k-k1 */
+  int a, b, c, d;
+
+  SAFE_MALLOC(pivk, n, int);
+  SAFE_MALLOC(nc, n, int);
+
+  /* initialize the nc data structure. Point from each point to the
+     furthest future point to which it is connected by a vertical or
+     horizontal segment. We take advantage of the fact that there is
+     always a direction change at 0 (due to the path decomposition
+     algorithm). But even if this were not so, there is no harm, as
+     in practice, correctness does not depend on the word "furthest"
+     above.  */
+  k = 0;
+  for (i=n-1; i>=0; i--) {
+    if (pt[i].x != pt[k].x && pt[i].y != pt[k].y) {
+      k = i+1;  /* necessarily i<n-1 in this case */
+    }
+    nc[i] = k;
+  }
+
+  SAFE_MALLOC(pp->lon, n, int);
+
+  /* determine pivot points: for each i, let pivk[i] be the furthest k
+     such that all j with i<j<k lie on a line connecting i,k. */
+  
+  for (i=n-1; i>=0; i--) {
+    ct[0] = ct[1] = ct[2] = ct[3] = 0;
+
+    /* keep track of "directions" that have occurred */
+    dir = (3+3*(pt[mod(i+1,n)].x-pt[i].x)+(pt[mod(i+1,n)].y-pt[i].y))/2;
+    ct[dir]++;
+
+    constraint[0].x = 0;
+    constraint[0].y = 0;
+    constraint[1].x = 0;
+    constraint[1].y = 0;
+
+    /* find the next k such that no straight line from i to k */
+    k = nc[i];
+    k1 = i;
+    while (1) {
+      
+      dir = (3+3*sign(pt[k].x-pt[k1].x)+sign(pt[k].y-pt[k1].y))/2;
+      ct[dir]++;
+
+      /* if all four "directions" have occurred, cut this path */
+      if (ct[0] && ct[1] && ct[2] && ct[3]) {
+	pivk[i] = k1;
+	goto foundk;
+      }
+
+      cur.x = pt[k].x - pt[i].x;
+      cur.y = pt[k].y - pt[i].y;
+
+      /* see if current constraint is violated */
+      if (xprod(constraint[0], cur) < 0 || xprod(constraint[1], cur) > 0) {
+	goto constraint_viol;
+      }
+
+      /* else, update constraint */
+      if (abs(cur.x) <= 1 && abs(cur.y) <= 1) {
+	/* no constraint */
+      } else {
+	off.x = cur.x + ((cur.y>=0 && (cur.y>0 || cur.x<0)) ? 1 : -1);
+	off.y = cur.y + ((cur.x<=0 && (cur.x<0 || cur.y<0)) ? 1 : -1);
+	if (xprod(constraint[0], off) >= 0) {
+	  constraint[0] = off;
+	}
+	off.x = cur.x + ((cur.y<=0 && (cur.y<0 || cur.x<0)) ? 1 : -1);
+	off.y = cur.y + ((cur.x>=0 && (cur.x>0 || cur.y<0)) ? 1 : -1);
+	if (xprod(constraint[1], off) <= 0) {
+	  constraint[1] = off;
+	}
+      }	
+      k1 = k;
+      k = nc[k1];
+      if (!cyclic(k,i,k1)) {
+	break;
+      }
+    }
+  constraint_viol:
+    /* k1 was the last "corner" satisfying the current constraint, and
+       k is the first one violating it. We now need to find the last
+       point along k1..k which satisfied the constraint. */
+    dk.x = sign(pt[k].x-pt[k1].x);
+    dk.y = sign(pt[k].y-pt[k1].y);
+    cur.x = pt[k1].x - pt[i].x;
+    cur.y = pt[k1].y - pt[i].y;
+    /* find largest integer j such that xprod(constraint[0], cur+j*dk)
+       >= 0 and xprod(constraint[1], cur+j*dk) <= 0. Use bilinearity
+       of xprod. */
+    a = xprod(constraint[0], cur);
+    b = xprod(constraint[0], dk);
+    c = xprod(constraint[1], cur);
+    d = xprod(constraint[1], dk);
+    /* find largest integer j such that a+j*b>=0 and c+j*d<=0. This
+       can be solved with integer arithmetic. */
+    j = INFTY;
+    if (b<0) {
+      j = floordiv(a,-b);
+    }
+    if (d>0) {
+      j = min(j, floordiv(-c,d));
+    }
+    pivk[i] = mod(k1+j,n);
+  foundk:
+    ;
+  } /* for i */
+
+  /* clean up: for each i, let lon[i] be the largest k such that for
+     all i' with i<=i'<k, i'<k<=pivk[i']. */
+
+  j=pivk[n-1];
+  pp->lon[n-1]=j;
+  for (i=n-2; i>=0; i--) {
+    if (cyclic(i+1,pivk[i],j)) {
+      j=pivk[i];
+    }
+    pp->lon[i]=j;
+  }
+
+  for (i=n-1; cyclic(mod(i+1,n),j,pp->lon[i]); i--) {
+    pp->lon[i] = j;
+  }
+
+  free(pivk);
+  free(nc);
+  return 0;
+
+ malloc_error:
+  free(pivk);
+  free(nc);
+  return 1;
+}
+
+
+/* ---------------------------------------------------------------------- */
+/* Stage 2: calculate the optimal polygon (Sec. 2.2.2-2.2.4). */ 
+
+/* Auxiliary function: calculate the penalty of an edge from i to j in
+   the given path. This needs the "lon" and "sum*" data. */
+
+static double penalty3(privpath_t *pp, int i, int j) {
+  int n = pp->len;
+  point_t *pt = pp->pt;
+  sums_t *sums = pp->sums;
+
+  /* assume 0<=i<j<=n  */
+  double x, y, x2, xy, y2;
+  double k;
+  double a, b, c, s;
+  double px, py, ex, ey;
+
+  int r=0; /* rotations from i to j */
+
+  if (j>=n) {
+    j-=n;
+    r+=1;
+  }
+  
+  x = sums[j+1].x-sums[i].x+r*sums[n].x;
+  y = sums[j+1].y-sums[i].y+r*sums[n].y;
+  x2 = sums[j+1].x2-sums[i].x2+r*sums[n].x2;
+  xy = sums[j+1].xy-sums[i].xy+r*sums[n].xy;
+  y2 = sums[j+1].y2-sums[i].y2+r*sums[n].y2;
+  k = j+1-i+r*n;
+  
+  px = (pt[i].x+pt[j].x)/2.0-pt[0].x;
+  py = (pt[i].y+pt[j].y)/2.0-pt[0].y;
+  ey = (pt[j].x-pt[i].x);
+  ex = -(pt[j].y-pt[i].y);
+
+  a = ((x2-2*x*px)/k+px*px);
+  b = ((xy-x*py-y*px)/k+px*py);
+  c = ((y2-2*y*py)/k+py*py);
+  
+  s = ex*ex*a + 2*ex*ey*b + ey*ey*c;
+
+  return sqrt(s);
+}
+
+/* find the optimal polygon. Fill in the m and po components. Return 1
+   on failure with errno set, else 0. Non-cyclic version: assumes i=0
+   is in the polygon. Fixme: ### implement cyclic version. */
+static int bestpolygon(privpath_t *pp)
+{
+  int i, j, m, k;     
+  int n = pp->len;
+  double *pen = NULL; /* pen[n+1]: penalty vector */
+  int *prev = NULL;   /* prev[n+1]: best path pointer vector */
+  int *clip0 = NULL;  /* clip0[n]: longest segment pointer, non-cyclic */
+  int *clip1 = NULL;  /* clip1[n+1]: backwards segment pointer, non-cyclic */
+  int *seg0 = NULL;    /* seg0[m+1]: forward segment bounds, m<=n */
+  int *seg1 = NULL;   /* seg1[m+1]: backward segment bounds, m<=n */
+  double thispen;
+  double best;
+  int c;
+
+  SAFE_MALLOC(pen, n+1, double);
+  SAFE_MALLOC(prev, n+1, int);
+  SAFE_MALLOC(clip0, n, int);
+  SAFE_MALLOC(clip1, n+1, int);
+  SAFE_MALLOC(seg0, n+1, int);
+  SAFE_MALLOC(seg1, n+1, int);
+
+  /* calculate clipped paths */
+  for (i=0; i<n; i++) {
+    c = mod(pp->lon[mod(i-1,n)]-1,n);
+    if (c == i) {
+      c = mod(i+1,n);
+    }
+    if (c < i) {
+      clip0[i] = n;
+    } else {
+      clip0[i] = c;
+    }
+  }
+
+  /* calculate backwards path clipping, non-cyclic. j <= clip0[i] iff
+     clip1[j] <= i, for i,j=0..n. */
+  j = 1;
+  for (i=0; i<n; i++) {
+    while (j <= clip0[i]) {
+      clip1[j] = i;
+      j++;
+    }
+  }
+
+  /* calculate seg0[j] = longest path from 0 with j segments */
+  i = 0;
+  for (j=0; i<n; j++) {
+    seg0[j] = i;
+    i = clip0[i];
+  }
+  seg0[j] = n;
+  m = j;
+
+  /* calculate seg1[j] = longest path to n with m-j segments */
+  i = n;
+  for (j=m; j>0; j--) {
+    seg1[j] = i;
+    i = clip1[i];
+  }
+  seg1[0] = 0;
+
+  /* now find the shortest path with m segments, based on penalty3 */
+  /* note: the outer 2 loops jointly have at most n interations, thus
+     the worst-case behavior here is quadratic. In practice, it is
+     close to linear since the inner loop tends to be short. */
+  pen[0]=0;
+  for (j=1; j<=m; j++) {
+    for (i=seg1[j]; i<=seg0[j]; i++) {
+      best = -1;
+      for (k=seg0[j-1]; k>=clip1[i]; k--) {
+	thispen = penalty3(pp, k, i) + pen[k];
+	if (best < 0 || thispen < best) {
+	  prev[i] = k;
+	  best = thispen;
+	}
+      }
+      pen[i] = best;
+    }
+  }
+
+  pp->m = m;
+  SAFE_MALLOC(pp->po, m, int);
+
+  /* read off shortest path */
+  for (i=n, j=m-1; i>0; j--) {
+    i = prev[i];
+    pp->po[j] = i;
+  }
+
+  free(pen);
+  free(prev);
+  free(clip0);
+  free(clip1);
+  free(seg0);
+  free(seg1);
+  return 0;
+  
+ malloc_error:
+  free(pen);
+  free(prev);
+  free(clip0);
+  free(clip1);
+  free(seg0);
+  free(seg1);
+  return 1;
+}
+
+/* ---------------------------------------------------------------------- */
+/* Stage 3: vertex adjustment (Sec. 2.3.1). */
+
+/* Adjust vertices of optimal polygon: calculate the intersection of
+   the two "optimal" line segments, then move it into the unit square
+   if it lies outside. Return 1 with errno set on error; 0 on
+   success. */
+
+static int adjust_vertices(privpath_t *pp) {
+  int m = pp->m;
+  int *po = pp->po;
+  int n = pp->len;
+  point_t *pt = pp->pt;
+  int x0 = pp->x0;
+  int y0 = pp->y0;
+
+  dpoint_t *ctr = NULL;      /* ctr[m] */
+  dpoint_t *dir = NULL;      /* dir[m] */
+  quadform_t *q = NULL;      /* q[m] */
+  double v[3];
+  double d;
+  int i, j, k, l;
+  dpoint_t s;
+  int r;
+
+  SAFE_MALLOC(ctr, m, dpoint_t);
+  SAFE_MALLOC(dir, m, dpoint_t);
+  SAFE_MALLOC(q, m, quadform_t);
+
+  r = privcurve_init(&pp->curve, m);
+  if (r) {
+    goto malloc_error;
+  }
+  
+  /* calculate "optimal" point-slope representation for each line
+     segment */
+  for (i=0; i<m; i++) {
+    j = po[mod(i+1,m)];
+    j = mod(j-po[i],n)+po[i];
+    pointslope(pp, po[i], j, &ctr[i], &dir[i]);
+  }
+
+  /* represent each line segment as a singular quadratic form; the
+     distance of a point (x,y) from the line segment will be
+     (x,y,1)Q(x,y,1)^t, where Q=q[i]. */
+  for (i=0; i<m; i++) {
+    d = sq(dir[i].x) + sq(dir[i].y);
+    if (d == 0.0) {
+      for (j=0; j<3; j++) {
+	for (k=0; k<3; k++) {
+	  q[i][j][k] = 0;
+	}
+      }
+    } else {
+      v[0] = dir[i].y;
+      v[1] = -dir[i].x;
+      v[2] = - v[1] * ctr[i].y - v[0] * ctr[i].x;
+      for (l=0; l<3; l++) {
+	for (k=0; k<3; k++) {
+	  q[i][l][k] = v[l] * v[k] / d;
+	}
+      }
+    }
+  }
+
+  /* now calculate the "intersections" of consecutive segments.
+     Instead of using the actual intersection, we find the point
+     within a given unit square which minimizes the square distance to
+     the two lines. */
+  for (i=0; i<m; i++) {
+    quadform_t Q;
+    dpoint_t w;
+    double dx, dy;
+    double det;
+    double min, cand; /* minimum and candidate for minimum of quad. form */
+    double xmin, ymin;	/* coordinates of minimum */
+    int z;
+
+    /* let s be the vertex, in coordinates relative to x0/y0 */
+    s.x = pt[po[i]].x-x0;
+    s.y = pt[po[i]].y-y0;
+
+    /* intersect segments i-1 and i */
+
+    j = mod(i-1,m);
+
+    /* add quadratic forms */
+    for (l=0; l<3; l++) {
+      for (k=0; k<3; k++) {
+	Q[l][k] = q[j][l][k] + q[i][l][k];
+      }
+    }
+    
+    while(1) {
+      /* minimize the quadratic form Q on the unit square */
+      /* find intersection */
+
+#ifdef HAVE_GCC_LOOP_BUG
+      /* work around gcc bug #12243 */
+      free(NULL);
+#endif
+      
+      det = Q[0][0]*Q[1][1] - Q[0][1]*Q[1][0];
+      if (det != 0.0) {
+	w.x = (-Q[0][2]*Q[1][1] + Q[1][2]*Q[0][1]) / det;
+	w.y = ( Q[0][2]*Q[1][0] - Q[1][2]*Q[0][0]) / det;
+	break;
+      }
+
+      /* matrix is singular - lines are parallel. Add another,
+	 orthogonal axis, through the center of the unit square */
+      if (Q[0][0]>Q[1][1]) {
+	v[0] = -Q[0][1];
+	v[1] = Q[0][0];
+      } else if (Q[1][1]) {
+	v[0] = -Q[1][1];
+	v[1] = Q[1][0];
+      } else {
+	v[0] = 1;
+	v[1] = 0;
+      }
+      d = sq(v[0]) + sq(v[1]);
+      v[2] = - v[1] * s.y - v[0] * s.x;
+      for (l=0; l<3; l++) {
+	for (k=0; k<3; k++) {
+	  Q[l][k] += v[l] * v[k] / d;
+	}
+      }
+    }
+    dx = fabs(w.x-s.x);
+    dy = fabs(w.y-s.y);
+    if (dx <= .5 && dy <= .5) {
+      pp->curve.vertex[i].x = w.x+x0;
+      pp->curve.vertex[i].y = w.y+y0;
+      continue;
+    }
+
+    /* the minimum was not in the unit square; now minimize quadratic
+       on boundary of square */
+    min = quadform(Q, s);
+    xmin = s.x;
+    ymin = s.y;
+
+    if (Q[0][0] == 0.0) {
+      goto fixx;
+    }
+    for (z=0; z<2; z++) {   /* value of the y-coordinate */
+      w.y = s.y-0.5+z;
+      w.x = - (Q[0][1] * w.y + Q[0][2]) / Q[0][0];
+      dx = fabs(w.x-s.x);
+      cand = quadform(Q, w);
+      if (dx <= .5 && cand < min) {
+	min = cand;
+	xmin = w.x;
+	ymin = w.y;
+      }
+    }
+  fixx:
+    if (Q[1][1] == 0.0) {
+      goto corners;
+    }
+    for (z=0; z<2; z++) {   /* value of the x-coordinate */
+      w.x = s.x-0.5+z;
+      w.y = - (Q[1][0] * w.x + Q[1][2]) / Q[1][1];
+      dy = fabs(w.y-s.y);
+      cand = quadform(Q, w);
+      if (dy <= .5 && cand < min) {
+	min = cand;
+	xmin = w.x;
+	ymin = w.y;
+      }
+    }
+  corners:
+    /* check four corners */
+    for (l=0; l<2; l++) {
+      for (k=0; k<2; k++) {
+	w.x = s.x-0.5+l;
+	w.y = s.y-0.5+k;
+	cand = quadform(Q, w);
+	if (cand < min) {
+	  min = cand;
+	  xmin = w.x;
+	  ymin = w.y;
+	}
+      }
+    }
+
+    pp->curve.vertex[i].x = xmin + x0;
+    pp->curve.vertex[i].y = ymin + y0;
+    continue;
+  }
+
+  free(ctr);
+  free(dir);
+  free(q);
+  return 0;
+
+ malloc_error:
+  free(ctr);
+  free(dir);
+  free(q);
+  return 1;
+}
+
+/* ---------------------------------------------------------------------- */
+/* Stage 4: smoothing and corner analysis (Sec. 2.3.3) */
+
+/* Always succeeds and returns 0 */
+static int smooth(privcurve_t *curve, int sign, double alphamax) {
+  int m = curve->n;
+
+  int i, j, k;
+  double dd, denom, alpha;
+  dpoint_t p2, p3, p4;
+
+  if (sign == '-') {
+    /* reverse orientation of negative paths */
+    for (i=0, j=m-1; i<j; i++, j--) {
+      dpoint_t tmp;
+      tmp = curve->vertex[i];
+      curve->vertex[i] = curve->vertex[j];
+      curve->vertex[j] = tmp;
+    }
+  }
+
+  /* examine each vertex and find its best fit */
+  for (i=0; i<m; i++) {
+    j = mod(i+1, m);
+    k = mod(i+2, m);
+    p4 = interval(1/2.0, curve->vertex[k], curve->vertex[j]);
+
+    denom = ddenom(curve->vertex[i], curve->vertex[k]);
+    if (denom != 0.0) {
+      dd = dpara(curve->vertex[i], curve->vertex[j], curve->vertex[k]) / denom;
+      dd = fabs(dd);
+      alpha = dd>1 ? (1 - 1.0/dd) : 0;
+      alpha = alpha / 0.75;
+    } else {
+      alpha = 4/3.0;
+    }
+    curve->alpha0[j] = alpha;	 /* remember "original" value of alpha */
+
+    if (alpha > alphamax) {  /* pointed corner */
+      curve->tag[j] = POTRACE_CORNER;
+      curve->c[j][1] = curve->vertex[j];
+      curve->c[j][2] = p4;
+    } else {
+      if (alpha < 0.55) {
+	alpha = 0.55;
+      } else if (alpha > 1) {
+	alpha = 1;
+      }
+      p2 = interval(.5+.5*alpha, curve->vertex[i], curve->vertex[j]);
+      p3 = interval(.5+.5*alpha, curve->vertex[k], curve->vertex[j]);
+      curve->tag[j] = POTRACE_CURVETO;
+      curve->c[j][0] = p2;
+      curve->c[j][1] = p3;
+      curve->c[j][2] = p4;
+    }
+    curve->alpha[j] = alpha;	/* store the "cropped" value of alpha */
+    curve->beta[j] = 0.5;
+  }
+  curve->alphacurve = 1;
+
+  return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+/* Stage 5: Curve optimization (Sec. 2.4) */
+
+/* a private type for the result of opti_penalty */
+struct opti_s {
+  double pen;	   /* penalty */
+  dpoint_t c[2];   /* curve parameters */
+  double t, s;	   /* curve parameters */
+  double alpha;	   /* curve parameter */
+};
+typedef struct opti_s opti_t;
+
+/* calculate best fit from i+.5 to j+.5.  Assume i<j (cyclically).
+   Return 0 and set badness and parameters (alpha, beta), if
+   possible. Return 1 if impossible. */
+static int opti_penalty(privpath_t *pp, int i, int j, opti_t *res, double opttolerance, int *convc, double *areac) {
+  int m = pp->curve.n;
+  int k, k1, k2, conv, i1;
+  double area, alpha, d, d1, d2;
+  dpoint_t p0, p1, p2, p3, pt;
+  double A, R, A1, A2, A3, A4;
+  double s, t;
+
+  /* check convexity, corner-freeness, and maximum bend < 179 degrees */
+
+  if (i==j) {  /* sanity - a full loop can never be an opticurve */
+    return 1;
+  }
+
+  k = i;
+  i1 = mod(i+1, m);
+  k1 = mod(k+1, m);
+  conv = convc[k1];
+  if (conv == 0) {
+    return 1;
+  }
+  d = ddist(pp->curve.vertex[i], pp->curve.vertex[i1]);
+  for (k=k1; k!=j; k=k1) {
+    k1 = mod(k+1, m);
+    k2 = mod(k+2, m);
+    if (convc[k1] != conv) {
+      return 1;
+    }
+    if (sign(cprod(pp->curve.vertex[i], pp->curve.vertex[i1], pp->curve.vertex[k1], pp->curve.vertex[k2])) != conv) {
+      return 1;
+    }
+    if (iprod1(pp->curve.vertex[i], pp->curve.vertex[i1], pp->curve.vertex[k1], pp->curve.vertex[k2]) < d * ddist(pp->curve.vertex[k1], pp->curve.vertex[k2]) * COS179) {
+      return 1;
+    }
+  }
+
+  /* the curve we're working in: */
+  p0 = pp->curve.c[mod(i,m)][2];
+  p1 = pp->curve.vertex[mod(i+1,m)];
+  p2 = pp->curve.vertex[mod(j,m)];
+  p3 = pp->curve.c[mod(j,m)][2];
+
+  /* determine its area */
+  area = areac[j] - areac[i];
+  area -= dpara(pp->curve.vertex[0], pp->curve.c[i][2], pp->curve.c[j][2])/2;
+  if (i>=j) {
+    area += areac[m];
+  }
+
+  /* find intersection o of p0p1 and p2p3. Let t,s such that o =
+     interval(t,p0,p1) = interval(s,p3,p2). Let A be the area of the
+     triangle (p0,o,p3). */
+
+  A1 = dpara(p0, p1, p2);
+  A2 = dpara(p0, p1, p3);
+  A3 = dpara(p0, p2, p3);
+  /* A4 = dpara(p1, p2, p3); */
+  A4 = A1+A3-A2;    
+  
+  if (A2 == A1) {  /* this should never happen */
+    return 1;
+  }
+
+  t = A3/(A3-A4);
+  s = A2/(A2-A1);
+  A = A2 * t / 2.0;
+  
+  if (A == 0.0) {  /* this should never happen */
+    return 1;
+  }
+
+  R = area / A;	 /* relative area */
+  alpha = 2 - sqrt(4 - R / 0.3);  /* overall alpha for p0-o-p3 curve */
+
+  res->c[0] = interval(t * alpha, p0, p1);
+  res->c[1] = interval(s * alpha, p3, p2);
+  res->alpha = alpha;
+  res->t = t;
+  res->s = s;
+
+  p1 = res->c[0];
+  p2 = res->c[1];  /* the proposed curve is now (p0,p1,p2,p3) */
+
+  res->pen = 0;
+
+  /* calculate penalty */
+  /* check tangency with edges */
+  for (k=mod(i+1,m); k!=j; k=k1) {
+    k1 = mod(k+1,m);
+    t = tangent(p0, p1, p2, p3, pp->curve.vertex[k], pp->curve.vertex[k1]);
+    if (t<-.5) {
+      return 1;
+    }
+    pt = bezier(t, p0, p1, p2, p3);
+    d = ddist(pp->curve.vertex[k], pp->curve.vertex[k1]);
+    if (d == 0.0) {  /* this should never happen */
+      return 1;
+    }
+    d1 = dpara(pp->curve.vertex[k], pp->curve.vertex[k1], pt) / d;
+    if (fabs(d1) > opttolerance) {
+      return 1;
+    }
+    if (iprod(pp->curve.vertex[k], pp->curve.vertex[k1], pt) < 0 || iprod(pp->curve.vertex[k1], pp->curve.vertex[k], pt) < 0) {
+      return 1;
+    }
+    res->pen += sq(d1);
+  }
+
+  /* check corners */
+  for (k=i; k!=j; k=k1) {
+    k1 = mod(k+1,m);
+    t = tangent(p0, p1, p2, p3, pp->curve.c[k][2], pp->curve.c[k1][2]);
+    if (t<-.5) {
+      return 1;
+    }
+    pt = bezier(t, p0, p1, p2, p3);
+    d = ddist(pp->curve.c[k][2], pp->curve.c[k1][2]);
+    if (d == 0.0) {  /* this should never happen */
+      return 1;
+    }
+    d1 = dpara(pp->curve.c[k][2], pp->curve.c[k1][2], pt) / d;
+    d2 = dpara(pp->curve.c[k][2], pp->curve.c[k1][2], pp->curve.vertex[k1]) / d;
+    d2 *= 0.75 * pp->curve.alpha[k1];
+    if (d2 < 0) {
+      d1 = -d1;
+      d2 = -d2;
+    }
+    if (d1 < d2 - opttolerance) {
+      return 1;
+    }
+    if (d1 < d2) {
+      res->pen += sq(d1 - d2);
+    }
+  }
+
+  return 0;
+}
+
+/* optimize the path p, replacing sequences of Bezier segments by a
+   single segment when possible. Return 0 on success, 1 with errno set
+   on failure. */
+static int opticurve(privpath_t *pp, double opttolerance) {
+  int m = pp->curve.n;
+  int *pt = NULL;     /* pt[m+1] */
+  double *pen = NULL; /* pen[m+1] */
+  int *len = NULL;    /* len[m+1] */
+  opti_t *opt = NULL; /* opt[m+1] */
+  int om;
+  int i,j,r;
+  opti_t o;
+  dpoint_t p0;
+  int i1;
+  double area;
+  double alpha;
+  double *s = NULL;
+  double *t = NULL;
+
+  int *convc = NULL; /* conv[m]: pre-computed convexities */
+  double *areac = NULL; /* cumarea[m+1]: cache for fast area computation */
+
+  SAFE_MALLOC(pt, m+1, int);
+  SAFE_MALLOC(pen, m+1, double);
+  SAFE_MALLOC(len, m+1, int);
+  SAFE_MALLOC(opt, m+1, opti_t);
+  SAFE_MALLOC(convc, m, int);
+  SAFE_MALLOC(areac, m+1, double);
+
+  /* pre-calculate convexity: +1 = right turn, -1 = left turn, 0 = corner */
+  for (i=0; i<m; i++) {
+    if (pp->curve.tag[i] == POTRACE_CURVETO) {
+      convc[i] = sign(dpara(pp->curve.vertex[mod(i-1,m)], pp->curve.vertex[i], pp->curve.vertex[mod(i+1,m)]));
+    } else {
+      convc[i] = 0;
+    }
+  }
+
+  /* pre-calculate areas */
+  area = 0.0;
+  areac[0] = 0.0;
+  p0 = pp->curve.vertex[0];
+  for (i=0; i<m; i++) {
+    i1 = mod(i+1, m);
+    if (pp->curve.tag[i1] == POTRACE_CURVETO) {
+      alpha = pp->curve.alpha[i1];
+      area += 0.3*alpha*(4-alpha)*dpara(pp->curve.c[i][2], pp->curve.vertex[i1], pp->curve.c[i1][2])/2;
+      area += dpara(p0, pp->curve.c[i][2], pp->curve.c[i1][2])/2;
+    }
+    areac[i+1] = area;
+  }
+
+  pt[0] = -1;
+  pen[0] = 0;
+  len[0] = 0;
+
+  /* Fixme: we always start from a fixed point -- should find the best
+     curve cyclically ### */
+
+  for (j=1; j<=m; j++) {
+    /* calculate best path from 0 to j */
+    pt[j] = j-1;
+    pen[j] = pen[j-1];
+    len[j] = len[j-1]+1;
+
+    for (i=j-2; i>=0; i--) {
+      r = opti_penalty(pp, i, mod(j,m), &o, opttolerance, convc, areac);
+      if (r) {
+	break;
+      }
+      if (len[j] > len[i]+1 || (len[j] == len[i]+1 && pen[j] > pen[i] + o.pen)) {
+	pt[j] = i;
+	pen[j] = pen[i] + o.pen;
+	len[j] = len[i] + 1;
+	opt[j] = o;
+      }
+    }
+  }
+  om = len[m];
+  r = privcurve_init(&pp->ocurve, om);
+  if (r) {
+    goto malloc_error;
+  }
+  SAFE_MALLOC(s, om, double);
+  SAFE_MALLOC(t, om, double);
+
+  j = m;
+  for (i=om-1; i>=0; i--) {
+    if (pt[j]==j-1) {
+      pp->ocurve.tag[i]     = pp->curve.tag[mod(j,m)];
+      pp->ocurve.c[i][0]    = pp->curve.c[mod(j,m)][0];
+      pp->ocurve.c[i][1]    = pp->curve.c[mod(j,m)][1];
+      pp->ocurve.c[i][2]    = pp->curve.c[mod(j,m)][2];
+      pp->ocurve.vertex[i]  = pp->curve.vertex[mod(j,m)];
+      pp->ocurve.alpha[i]   = pp->curve.alpha[mod(j,m)];
+      pp->ocurve.alpha0[i]  = pp->curve.alpha0[mod(j,m)];
+      pp->ocurve.beta[i]    = pp->curve.beta[mod(j,m)];
+      s[i] = t[i] = 1.0;
+    } else {
+      pp->ocurve.tag[i] = POTRACE_CURVETO;
+      pp->ocurve.c[i][0] = opt[j].c[0];
+      pp->ocurve.c[i][1] = opt[j].c[1];
+      pp->ocurve.c[i][2] = pp->curve.c[mod(j,m)][2];
+      pp->ocurve.vertex[i] = interval(opt[j].s, pp->curve.c[mod(j,m)][2], pp->curve.vertex[mod(j,m)]);
+      pp->ocurve.alpha[i] = opt[j].alpha;
+      pp->ocurve.alpha0[i] = opt[j].alpha;
+      s[i] = opt[j].s;
+      t[i] = opt[j].t;
+    }
+    j = pt[j];
+  }
+
+  /* calculate beta parameters */
+  for (i=0; i<om; i++) {
+    i1 = mod(i+1,om);
+    pp->ocurve.beta[i] = s[i] / (s[i] + t[i1]);
+  }
+  pp->ocurve.alphacurve = 1;
+
+  free(pt);
+  free(pen);
+  free(len);
+  free(opt);
+  free(s);
+  free(t);
+  free(convc);
+  free(areac);
+  return 0;
+
+ malloc_error:
+  free(pt);
+  free(pen);
+  free(len);
+  free(opt);
+  free(s);
+  free(t);
+  free(convc);
+  free(areac);
+  return 1;
+}
+
+/* ---------------------------------------------------------------------- */
+double plotpolygon(privpath_t *pp,FILE* f,double scale)
+{
+  int i;     
+  int m = pp->m;
+	if(!m) return 0;
+  int *po = pp->po;
+  int n = pp->len;
+  point_t *pt = pp->pt;
+  int x0 = pp->x0;
+  int y0 = pp->y0;
+	//double scale=1.0/dpi;
+	double dm=0;
+	fprintf(f,"G0 X%f Y%f    (start point)\n",pt[po[0]].x*scale,pt[po[0]].y*scale);
+	fprintf(f,"G1 Z#101\n");
+	for (i=1; i<m; i++) {
+		fprintf(f,"G1 X%f Y%f\n",pt[po[i]].x*scale,pt[po[i]].y*scale);
+		dm+=sqrt((pt[po[i]].x-pt[po[i-1]].x)*scale*(pt[po[i]].x-pt[po[i-1]].x)*scale+\
+			(pt[po[i]].y-pt[po[i-1]].y)*scale*(pt[po[i]].y-pt[po[i-1]].y)*scale);
+	}
+	fprintf(f,"G1 X%f Y%f\n",pt[po[0]].x*scale,pt[po[0]].y*scale);
+	fprintf(f,"G0 Z#100\n");
+	dm+=sqrt((pt[po[m-1]].x-pt[po[0]].x)*scale*(pt[po[m-1]].x-pt[po[0]].x)*scale+\
+		(pt[po[m-1]].y-pt[po[0]].y)*scale*(pt[po[m-1]].y-pt[po[0]].y)*scale);
+	fprintf(f,"(polygon end, distance %.2f)\n",dm);
+	return dm;
+}
+
+#define TRY(x) if (x) goto try_error
+
+/* return distance on success, -1 on error with errno set. */
+double process_path(path_t *plist, const potrace_param_t *param,const potrace_bitmap_t *bm,FILE *f,double scale) {
+  path_t *p;
+  double nn = 0, cn = 0;
+	double dm=0;
+	int n=0;
+  /* call downstream function with each path */
+  list_forall (p, plist) {
+    TRY(calc_sums(p->priv));
+    TRY(calc_lon(p->priv));
+    TRY(bestpolygon(p->priv));
+    TRY(adjust_vertices(p->priv));
+	fprintf(f,"(polygon %d)\n",++n);
+    dm+=plotpolygon(p->priv,f,scale);
+/*  No need to extract curves
+	TRY(smooth(&p->priv->curve, p->sign, param->alphamax));
+    if (param->opticurve) {
+      TRY(opticurve(p->priv, param->opttolerance));
+      p->priv->fcurve = &p->priv->ocurve;
+    } else {
+      p->priv->fcurve = &p->priv->curve;
+    }
+    privcurve_to_curve(p->priv->fcurve, &p->curve);*/
+  }
+//	fprintf(f,"(end, total distance %.2fmm = %.2fin)\n",25.4*dm,dm);
+  return dm;
+
+ try_error:
+  return -1;
+}
diff --git a/src/hid/gcode/trace.h b/src/hid/gcode/trace.h
new file mode 100644
index 0000000..4a9683c
--- /dev/null
+++ b/src/hid/gcode/trace.h
@@ -0,0 +1,14 @@
+/* Copyright (C) 2001-2007 Peter Selinger.
+   This file is part of Potrace. It is free software and it is covered
+   by the GNU General Public License. See the file COPYING for details. */
+
+/* $Id: trace.h 147 2007-04-09 00:44:09Z selinger $ */
+
+#ifndef TRACE_H
+#define TRACE_H
+
+#include "potracelib.h"
+
+double process_path(path_t *plist, const potrace_param_t *param,const potrace_bitmap_t *bm,FILE *f,double scale);
+
+#endif /* TRACE_H */




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs